blob: 582b65249b3e7f9265205a803081a99e7b4f963f [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
njn25e49d8e72002-09-23 09:36:25 +000029 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000030*/
31
32#include "vg_include.h"
sewardjde4a1d02002-03-22 01:27:54 +000033
34/* ---------------------------------------------------------------------
35 Compute offsets into baseBlock. See comments in vg_include.h.
36 ------------------------------------------------------------------ */
37
38/* The variables storing offsets. */
39
40#define INVALID_OFFSET (-1)
41
42Int VGOFF_(m_eax) = INVALID_OFFSET;
43Int VGOFF_(m_ecx) = INVALID_OFFSET;
44Int VGOFF_(m_edx) = INVALID_OFFSET;
45Int VGOFF_(m_ebx) = INVALID_OFFSET;
46Int VGOFF_(m_esp) = INVALID_OFFSET;
47Int VGOFF_(m_ebp) = INVALID_OFFSET;
48Int VGOFF_(m_esi) = INVALID_OFFSET;
49Int VGOFF_(m_edi) = INVALID_OFFSET;
50Int VGOFF_(m_eflags) = INVALID_OFFSET;
51Int VGOFF_(m_fpustate) = INVALID_OFFSET;
52Int VGOFF_(m_eip) = INVALID_OFFSET;
53Int VGOFF_(spillslots) = INVALID_OFFSET;
54Int VGOFF_(sh_eax) = INVALID_OFFSET;
55Int VGOFF_(sh_ecx) = INVALID_OFFSET;
56Int VGOFF_(sh_edx) = INVALID_OFFSET;
57Int VGOFF_(sh_ebx) = INVALID_OFFSET;
58Int VGOFF_(sh_esp) = INVALID_OFFSET;
59Int VGOFF_(sh_ebp) = INVALID_OFFSET;
60Int VGOFF_(sh_esi) = INVALID_OFFSET;
61Int VGOFF_(sh_edi) = INVALID_OFFSET;
62Int VGOFF_(sh_eflags) = INVALID_OFFSET;
njn25e49d8e72002-09-23 09:36:25 +000063
sewardjde4a1d02002-03-22 01:27:54 +000064Int VGOFF_(helper_idiv_64_32) = INVALID_OFFSET;
65Int VGOFF_(helper_div_64_32) = INVALID_OFFSET;
66Int VGOFF_(helper_idiv_32_16) = INVALID_OFFSET;
67Int VGOFF_(helper_div_32_16) = INVALID_OFFSET;
68Int VGOFF_(helper_idiv_16_8) = INVALID_OFFSET;
69Int VGOFF_(helper_div_16_8) = INVALID_OFFSET;
70Int VGOFF_(helper_imul_32_64) = INVALID_OFFSET;
71Int VGOFF_(helper_mul_32_64) = INVALID_OFFSET;
72Int VGOFF_(helper_imul_16_32) = INVALID_OFFSET;
73Int VGOFF_(helper_mul_16_32) = INVALID_OFFSET;
74Int VGOFF_(helper_imul_8_16) = INVALID_OFFSET;
75Int VGOFF_(helper_mul_8_16) = INVALID_OFFSET;
76Int VGOFF_(helper_CLD) = INVALID_OFFSET;
77Int VGOFF_(helper_STD) = INVALID_OFFSET;
78Int VGOFF_(helper_get_dirflag) = INVALID_OFFSET;
sewardj7d78e782002-06-02 00:04:00 +000079Int VGOFF_(helper_CLC) = INVALID_OFFSET;
80Int VGOFF_(helper_STC) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000081Int VGOFF_(helper_shldl) = INVALID_OFFSET;
82Int VGOFF_(helper_shldw) = INVALID_OFFSET;
83Int VGOFF_(helper_shrdl) = INVALID_OFFSET;
84Int VGOFF_(helper_shrdw) = INVALID_OFFSET;
85Int VGOFF_(helper_RDTSC) = INVALID_OFFSET;
86Int VGOFF_(helper_CPUID) = INVALID_OFFSET;
87Int VGOFF_(helper_BSWAP) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000088Int VGOFF_(helper_bsf) = INVALID_OFFSET;
89Int VGOFF_(helper_bsr) = INVALID_OFFSET;
90Int VGOFF_(helper_fstsw_AX) = INVALID_OFFSET;
91Int VGOFF_(helper_SAHF) = INVALID_OFFSET;
sewardj4d0ab1f2002-03-24 10:00:09 +000092Int VGOFF_(helper_DAS) = INVALID_OFFSET;
sewardjfe8a1662002-03-24 11:54:07 +000093Int VGOFF_(helper_DAA) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000094Int VGOFF_(handle_esp_assignment) = INVALID_OFFSET;
njn25e49d8e72002-09-23 09:36:25 +000095
96/* MAX_NONCOMPACT_HELPERS can be increased easily. If MAX_COMPACT_HELPERS is
97 * increased too much, they won't really be compact any more... */
98#define MAX_COMPACT_HELPERS 8
99#define MAX_NONCOMPACT_HELPERS 8
100
101UInt VG_(n_compact_helpers) = 0;
102UInt VG_(n_noncompact_helpers) = 0;
103
104Addr VG_(compact_helper_addrs) [MAX_COMPACT_HELPERS];
105Int VG_(compact_helper_offsets)[MAX_COMPACT_HELPERS];
106Addr VG_(noncompact_helper_addrs) [MAX_NONCOMPACT_HELPERS];
107Int VG_(noncompact_helper_offsets)[MAX_NONCOMPACT_HELPERS];
sewardjde4a1d02002-03-22 01:27:54 +0000108
109/* This is the actual defn of baseblock. */
110UInt VG_(baseBlock)[VG_BASEBLOCK_WORDS];
111
njn25e49d8e72002-09-23 09:36:25 +0000112
sewardjde4a1d02002-03-22 01:27:54 +0000113/* Words. */
114static Int baB_off = 0;
115
116/* Returns the offset, in words. */
117static Int alloc_BaB ( Int words )
118{
119 Int off = baB_off;
120 baB_off += words;
121 if (baB_off >= VG_BASEBLOCK_WORDS)
122 VG_(panic)( "alloc_BaB: baseBlock is too small");
123
124 return off;
125}
126
127/* Allocate 1 word in baseBlock and set it to the given value. */
128static Int alloc_BaB_1_set ( Addr a )
129{
130 Int off = alloc_BaB(1);
131 VG_(baseBlock)[off] = (UInt)a;
132 return off;
133}
134
njn25e49d8e72002-09-23 09:36:25 +0000135/* Registers a function in compact_helper_addrs; compact_helper_offsets is
136 * filled in later.
137 */
138void VG_(register_compact_helper)(Addr a)
139{
140 if (MAX_COMPACT_HELPERS <= VG_(n_compact_helpers)) {
141 VG_(printf)("Can only register %d compact helpers\n",
142 MAX_COMPACT_HELPERS);
143 VG_(panic)("Too many compact helpers registered");
144 }
145 VG_(compact_helper_addrs)[VG_(n_compact_helpers)] = a;
146 VG_(n_compact_helpers)++;
147}
148
149/* Registers a function in noncompact_helper_addrs; noncompact_helper_offsets
150 * is filled in later.
151 */
152void VG_(register_noncompact_helper)(Addr a)
153{
154 if (MAX_NONCOMPACT_HELPERS <= VG_(n_noncompact_helpers)) {
155 VG_(printf)("Can only register %d non-compact helpers\n",
156 MAX_NONCOMPACT_HELPERS);
157 VG_(printf)("Try increasing MAX_NON_COMPACT_HELPERS\n");
158 VG_(panic)("Too many non-compact helpers registered");
159 }
160 VG_(noncompact_helper_addrs)[VG_(n_noncompact_helpers)] = a;
161 VG_(n_noncompact_helpers)++;
162}
163
164/* Allocate offsets in baseBlock for the skin helpers */
165static void assign_helpers_in_baseBlock(UInt n, Int offsets[], Addr addrs[])
166{
167 Int i;
168 for (i = 0; i < n; i++) offsets[i] = alloc_BaB_1_set( addrs[i] );
169}
sewardjde4a1d02002-03-22 01:27:54 +0000170
171/* Here we assign actual offsets. It's important to get the most
172 popular referents within 128 bytes of the start, so we can take
173 advantage of short addressing modes relative to %ebp. Popularity
174 of offsets was measured on 22 Feb 02 running a KDE application, and
175 the slots rearranged accordingly, with a 1.5% reduction in total
176 size of translations. */
177
178static void vg_init_baseBlock ( void )
179{
sewardjde4a1d02002-03-22 01:27:54 +0000180 /* Those with offsets under 128 are carefully chosen. */
181
182 /* WORD offsets in this column */
183 /* 0 */ VGOFF_(m_eax) = alloc_BaB(1);
184 /* 1 */ VGOFF_(m_ecx) = alloc_BaB(1);
185 /* 2 */ VGOFF_(m_edx) = alloc_BaB(1);
186 /* 3 */ VGOFF_(m_ebx) = alloc_BaB(1);
187 /* 4 */ VGOFF_(m_esp) = alloc_BaB(1);
188 /* 5 */ VGOFF_(m_ebp) = alloc_BaB(1);
189 /* 6 */ VGOFF_(m_esi) = alloc_BaB(1);
190 /* 7 */ VGOFF_(m_edi) = alloc_BaB(1);
191 /* 8 */ VGOFF_(m_eflags) = alloc_BaB(1);
192
njn25e49d8e72002-09-23 09:36:25 +0000193 if (VG_(needs).shadow_regs) {
194 /* 9 */ VGOFF_(sh_eax) = alloc_BaB(1);
195 /* 10 */ VGOFF_(sh_ecx) = alloc_BaB(1);
196 /* 11 */ VGOFF_(sh_edx) = alloc_BaB(1);
197 /* 12 */ VGOFF_(sh_ebx) = alloc_BaB(1);
198 /* 13 */ VGOFF_(sh_esp) = alloc_BaB(1);
199 /* 14 */ VGOFF_(sh_ebp) = alloc_BaB(1);
200 /* 15 */ VGOFF_(sh_esi) = alloc_BaB(1);
201 /* 16 */ VGOFF_(sh_edi) = alloc_BaB(1);
202 /* 17 */ VGOFF_(sh_eflags) = alloc_BaB(1);
203 }
sewardjde4a1d02002-03-22 01:27:54 +0000204
njn25e49d8e72002-09-23 09:36:25 +0000205 /* 9,10,11 or 18,19,20... depends on number whether shadow regs are used
206 * and on compact helpers registered */
njn4f9c9342002-04-29 16:03:24 +0000207
njn25e49d8e72002-09-23 09:36:25 +0000208 /* (9 or 18) + n_compact_helpers */
209 /* Register VG_(handle_esp_assignment) if needed. */
210 if (VG_(track_events).new_mem_stack_aligned ||
211 VG_(track_events).die_mem_stack_aligned)
212 VG_(register_compact_helper)( (Addr) & VG_(handle_esp_assignment) );
sewardjde4a1d02002-03-22 01:27:54 +0000213
njn25e49d8e72002-09-23 09:36:25 +0000214 /* Allocate slots for compact helpers */
215 assign_helpers_in_baseBlock(VG_(n_compact_helpers),
216 VG_(compact_helper_offsets),
217 VG_(compact_helper_addrs));
sewardjde4a1d02002-03-22 01:27:54 +0000218
njn25e49d8e72002-09-23 09:36:25 +0000219 /* (9/10 or 18/19) + n_compact_helpers */
sewardjde4a1d02002-03-22 01:27:54 +0000220 VGOFF_(m_eip) = alloc_BaB(1);
221
222 /* There are currently 24 spill slots */
njn25e49d8e72002-09-23 09:36:25 +0000223 /* (11+/20+ .. 32+/43+) + n_compact_helpers. This can overlap the magic
224 * boundary at >= 32 words, but most spills are to low numbered spill
225 * slots, so the ones above the boundary don't see much action. */
sewardjde4a1d02002-03-22 01:27:54 +0000226 VGOFF_(spillslots) = alloc_BaB(VG_MAX_SPILLSLOTS);
227
njn25e49d8e72002-09-23 09:36:25 +0000228 /* I gave up counting at this point. Since they're above the
sewardjde4a1d02002-03-22 01:27:54 +0000229 short-amode-boundary, there's no point. */
230
231 VGOFF_(m_fpustate) = alloc_BaB(VG_SIZE_OF_FPUSTATE_W);
232
233 VGOFF_(helper_idiv_64_32)
234 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_64_32) );
235 VGOFF_(helper_div_64_32)
236 = alloc_BaB_1_set( (Addr) & VG_(helper_div_64_32) );
237 VGOFF_(helper_idiv_32_16)
238 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_32_16) );
239 VGOFF_(helper_div_32_16)
240 = alloc_BaB_1_set( (Addr) & VG_(helper_div_32_16) );
241 VGOFF_(helper_idiv_16_8)
242 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_16_8) );
243 VGOFF_(helper_div_16_8)
244 = alloc_BaB_1_set( (Addr) & VG_(helper_div_16_8) );
245
246 VGOFF_(helper_imul_32_64)
247 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_32_64) );
248 VGOFF_(helper_mul_32_64)
249 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_32_64) );
250 VGOFF_(helper_imul_16_32)
251 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_16_32) );
252 VGOFF_(helper_mul_16_32)
253 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_16_32) );
254 VGOFF_(helper_imul_8_16)
255 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_8_16) );
256 VGOFF_(helper_mul_8_16)
257 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_8_16) );
258
259 VGOFF_(helper_CLD)
260 = alloc_BaB_1_set( (Addr) & VG_(helper_CLD) );
261 VGOFF_(helper_STD)
262 = alloc_BaB_1_set( (Addr) & VG_(helper_STD) );
263 VGOFF_(helper_get_dirflag)
264 = alloc_BaB_1_set( (Addr) & VG_(helper_get_dirflag) );
265
sewardj7d78e782002-06-02 00:04:00 +0000266 VGOFF_(helper_CLC)
267 = alloc_BaB_1_set( (Addr) & VG_(helper_CLC) );
268 VGOFF_(helper_STC)
269 = alloc_BaB_1_set( (Addr) & VG_(helper_STC) );
270
sewardjde4a1d02002-03-22 01:27:54 +0000271 VGOFF_(helper_shldl)
272 = alloc_BaB_1_set( (Addr) & VG_(helper_shldl) );
273 VGOFF_(helper_shldw)
274 = alloc_BaB_1_set( (Addr) & VG_(helper_shldw) );
275 VGOFF_(helper_shrdl)
276 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdl) );
277 VGOFF_(helper_shrdw)
278 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdw) );
279
280 VGOFF_(helper_RDTSC)
281 = alloc_BaB_1_set( (Addr) & VG_(helper_RDTSC) );
282 VGOFF_(helper_CPUID)
283 = alloc_BaB_1_set( (Addr) & VG_(helper_CPUID) );
284
sewardjde4a1d02002-03-22 01:27:54 +0000285 VGOFF_(helper_bsf)
286 = alloc_BaB_1_set( (Addr) & VG_(helper_bsf) );
287 VGOFF_(helper_bsr)
288 = alloc_BaB_1_set( (Addr) & VG_(helper_bsr) );
289
290 VGOFF_(helper_fstsw_AX)
291 = alloc_BaB_1_set( (Addr) & VG_(helper_fstsw_AX) );
292 VGOFF_(helper_SAHF)
293 = alloc_BaB_1_set( (Addr) & VG_(helper_SAHF) );
sewardj4d0ab1f2002-03-24 10:00:09 +0000294 VGOFF_(helper_DAS)
295 = alloc_BaB_1_set( (Addr) & VG_(helper_DAS) );
sewardjfe8a1662002-03-24 11:54:07 +0000296 VGOFF_(helper_DAA)
297 = alloc_BaB_1_set( (Addr) & VG_(helper_DAA) );
njn25e49d8e72002-09-23 09:36:25 +0000298
299 /* Allocate slots for compact helpers */
300 assign_helpers_in_baseBlock(VG_(n_noncompact_helpers),
301 VG_(noncompact_helper_offsets),
302 VG_(noncompact_helper_addrs));
303}
304
305static void vg_init_shadow_regs ( void )
306{
307 if (VG_(needs).shadow_regs) {
308 UInt eflags;
309
310 SK_(written_shadow_regs_values) ( & VG_(written_shadow_reg), & eflags );
311 VG_(baseBlock)[VGOFF_(sh_esp)] =
312 VG_(baseBlock)[VGOFF_(sh_ebp)] =
313 VG_(baseBlock)[VGOFF_(sh_eax)] =
314 VG_(baseBlock)[VGOFF_(sh_ecx)] =
315 VG_(baseBlock)[VGOFF_(sh_edx)] =
316 VG_(baseBlock)[VGOFF_(sh_ebx)] =
317 VG_(baseBlock)[VGOFF_(sh_esi)] =
318 VG_(baseBlock)[VGOFF_(sh_edi)] = VG_(written_shadow_reg);
319 VG_(baseBlock)[VGOFF_(sh_eflags)] = eflags;
320
321 } else
322 VG_(written_shadow_reg) = VG_UNUSED_SHADOW_REG_VALUE;
sewardjde4a1d02002-03-22 01:27:54 +0000323}
324
325
326/* ---------------------------------------------------------------------
327 Global entities which are not referenced from generated code.
328 ------------------------------------------------------------------ */
329
330/* The stack on which Valgrind runs. We can't use the same stack as
331 the simulatee -- that's an important design decision. */
332UInt VG_(stack)[10000];
333
334/* Ditto our signal delivery stack. */
335UInt VG_(sigstack)[10000];
336
337/* Saving stuff across system calls. */
sewardj43c356f2002-06-02 00:21:08 +0000338UInt VG_(real_fpu_state_saved_over_syscall)[VG_SIZE_OF_FPUSTATE_W];
339Addr VG_(esp_saved_over_syscall);
sewardjde4a1d02002-03-22 01:27:54 +0000340
341/* Counts downwards in vg_run_innerloop. */
342UInt VG_(dispatch_ctr);
343
sewardjde4a1d02002-03-22 01:27:54 +0000344
345/* 64-bit counter for the number of basic blocks done. */
346ULong VG_(bbs_done);
347/* 64-bit counter for the number of bbs to go before a debug exit. */
348ULong VG_(bbs_to_go);
349
sewardjde4a1d02002-03-22 01:27:54 +0000350/* The current LRU epoch. */
351UInt VG_(current_epoch) = 0;
352
sewardj7e87e382002-05-03 19:09:05 +0000353/* This is the ThreadId of the last thread the scheduler ran. */
354ThreadId VG_(last_run_tid) = 0;
355
njn25e49d8e72002-09-23 09:36:25 +0000356/* This is the argument to __NR_exit() supplied by the first thread to
357 call that syscall. We eventually pass that to __NR_exit() for
358 real. */
359UInt VG_(exitcode) = 0;
360
sewardjde4a1d02002-03-22 01:27:54 +0000361
362/* ---------------------------------------------------------------------
363 Counters, for informational purposes only.
364 ------------------------------------------------------------------ */
365
366/* Number of lookups which miss the fast tt helper. */
367UInt VG_(tt_fast_misses) = 0;
368
369
370/* Counts for LRU informational messages. */
371
372/* Number and total o/t size of new translations this epoch. */
373UInt VG_(this_epoch_in_count) = 0;
374UInt VG_(this_epoch_in_osize) = 0;
375UInt VG_(this_epoch_in_tsize) = 0;
376/* Number and total o/t size of discarded translations this epoch. */
377UInt VG_(this_epoch_out_count) = 0;
378UInt VG_(this_epoch_out_osize) = 0;
379UInt VG_(this_epoch_out_tsize) = 0;
380/* Number and total o/t size of translations overall. */
381UInt VG_(overall_in_count) = 0;
382UInt VG_(overall_in_osize) = 0;
383UInt VG_(overall_in_tsize) = 0;
384/* Number and total o/t size of discards overall. */
385UInt VG_(overall_out_count) = 0;
386UInt VG_(overall_out_osize) = 0;
387UInt VG_(overall_out_tsize) = 0;
388
389/* The number of LRU-clearings of TT/TC. */
390UInt VG_(number_of_lrus) = 0;
391
392
393/* Counts pertaining to the register allocator. */
394
395/* total number of uinstrs input to reg-alloc */
396UInt VG_(uinstrs_prealloc) = 0;
397
398/* total number of uinstrs added due to spill code */
399UInt VG_(uinstrs_spill) = 0;
400
401/* number of bbs requiring spill code */
402UInt VG_(translations_needing_spill) = 0;
403
404/* total of register ranks over all translations */
405UInt VG_(total_reg_rank) = 0;
406
407
sewardjde4a1d02002-03-22 01:27:54 +0000408/* Counts pertaining to internal sanity checking. */
sewardjde4a1d02002-03-22 01:27:54 +0000409UInt VG_(sanity_fast_count) = 0;
410UInt VG_(sanity_slow_count) = 0;
411
sewardj2e93c502002-04-12 11:12:52 +0000412/* Counts pertaining to the scheduler. */
413UInt VG_(num_scheduling_events_MINOR) = 0;
414UInt VG_(num_scheduling_events_MAJOR) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000415
416
417/* ---------------------------------------------------------------------
njn25e49d8e72002-09-23 09:36:25 +0000418 Skin data structure initialisation
419 ------------------------------------------------------------------ */
420
421/* Init with default values. */
422VgNeeds VG_(needs) = {
423 .name = NULL,
424 .description = NULL,
425
426 .core_errors = False,
427 .skin_errors = False,
428 .run_libc_freeres = False,
429
430 .sizeof_shadow_block = 0,
431
432 .basic_block_discards = False,
433 .shadow_regs = False,
434 .command_line_options = False,
435 .client_requests = False,
436 .extended_UCode = False,
437 .syscall_wrapper = False,
438 .alternative_free = False,
439 .sanity_checks = False,
440};
441
442VgTrackEvents VG_(track_events) = {
443 /* Memory events */
444 .new_mem_startup = NULL,
445 .new_mem_heap = NULL,
446 .new_mem_stack = NULL,
447 .new_mem_stack_aligned = NULL,
448 .new_mem_stack_signal = NULL,
449 .new_mem_brk = NULL,
450 .new_mem_mmap = NULL,
451
452 .copy_mem_heap = NULL,
453 .change_mem_mprotect = NULL,
454
455 .ban_mem_heap = NULL,
456 .ban_mem_stack = NULL,
457
458 .die_mem_heap = NULL,
459 .die_mem_stack = NULL,
460 .die_mem_stack_aligned = NULL,
461 .die_mem_stack_signal = NULL,
462 .die_mem_brk = NULL,
463 .die_mem_munmap = NULL,
464
465 .bad_free = NULL,
466 .mismatched_free = NULL,
467
468 .pre_mem_read = NULL,
469 .pre_mem_read_asciiz = NULL,
470 .pre_mem_write = NULL,
471 .post_mem_write = NULL,
472
473 /* Mutex events */
474 .post_mutex_lock = NULL,
475 .post_mutex_unlock = NULL,
476};
477
478static void sanity_check_needs ( void )
479{
480#define CHECK_NOT(var, value) \
481 if ((var)==(value)) { \
482 VG_(printf)("\n`%s' not initialised\n", VG__STRING(var)); \
483 VG_(skin_error)("Uninitialised needs field\n"); \
484 }
485
486 CHECK_NOT(VG_(needs).name, NULL);
487 CHECK_NOT(VG_(needs).description, NULL);
488
489#undef CHECK_NOT
490#undef INVALID_Bool
491}
492
493/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000494 Values derived from command-line options.
495 ------------------------------------------------------------------ */
496
njn25e49d8e72002-09-23 09:36:25 +0000497/* Define, and set defaults. */
498Bool VG_(clo_error_limit) = True;
499Bool VG_(clo_GDB_attach) = False;
500Int VG_(sanity_level) = 1;
501Int VG_(clo_verbosity) = 1;
502Bool VG_(clo_demangle) = True;
503Bool VG_(clo_sloppy_malloc) = False;
504Int VG_(clo_alignment) = 4;
505Bool VG_(clo_trace_children) = False;
506Int VG_(clo_logfile_fd) = 2;
507Int VG_(clo_n_suppressions) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000508Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
njn25e49d8e72002-09-23 09:36:25 +0000509Bool VG_(clo_profile) = False;
510Bool VG_(clo_single_step) = False;
511Bool VG_(clo_optimise) = True;
512UChar VG_(clo_trace_codegen) = 0; // 00000000b
513Bool VG_(clo_trace_syscalls) = False;
514Bool VG_(clo_trace_signals) = False;
515Bool VG_(clo_trace_symtab) = False;
516Bool VG_(clo_trace_malloc) = False;
517Bool VG_(clo_trace_sched) = False;
518Int VG_(clo_trace_pthread_level) = 0;
519ULong VG_(clo_stop_after) = 1000000000000LL;
520Int VG_(clo_dump_error) = 0;
521Int VG_(clo_backtrace_size) = 4;
522Char* VG_(clo_weird_hacks) = NULL;
sewardjde4a1d02002-03-22 01:27:54 +0000523
524/* This Bool is needed by wrappers in vg_clientmalloc.c to decide how
525 to behave. Initially we say False. */
526Bool VG_(running_on_simd_CPU) = False;
527
528/* Holds client's %esp at the point we gained control. */
529Addr VG_(esp_at_startup);
530
531/* As deduced from VG_(esp_at_startup), the client's argc, argv[] and
532 envp[] as extracted from the client's stack at startup-time. */
533Int VG_(client_argc);
534Char** VG_(client_argv);
535Char** VG_(client_envp);
536
537/* A place into which to copy the value of env var VG_ARGS, so we
538 don't have to modify the original. */
539static Char vg_cmdline_copy[M_VG_CMDLINE_STRLEN];
540
sewardjde4a1d02002-03-22 01:27:54 +0000541/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000542 Processing of command-line options.
543 ------------------------------------------------------------------ */
544
njn25e49d8e72002-09-23 09:36:25 +0000545void VG_(bad_option) ( Char* opt )
sewardjde4a1d02002-03-22 01:27:54 +0000546{
547 VG_(shutdown_logging)();
548 VG_(clo_logfile_fd) = 2; /* stderr */
549 VG_(printf)("valgrind.so: Bad option `%s'; aborting.\n", opt);
550 VG_(exit)(1);
551}
552
553static void config_error ( Char* msg )
554{
555 VG_(shutdown_logging)();
556 VG_(clo_logfile_fd) = 2; /* stderr */
sewardj19d81412002-06-03 01:10:40 +0000557 VG_(printf)(
558 "valgrind.so: Startup or configuration error:\n %s\n", msg);
559 VG_(printf)(
560 "valgrind.so: Unable to start up properly. Giving up.\n");
sewardjde4a1d02002-03-22 01:27:54 +0000561 VG_(exit)(1);
562}
563
sewardja1679dd2002-05-10 22:31:40 +0000564static void args_grok_error ( Char* msg )
565{
566 VG_(shutdown_logging)();
567 VG_(clo_logfile_fd) = 2; /* stderr */
568 VG_(printf)("valgrind.so: When searching for "
569 "client's argc/argc/envp:\n\t%s\n", msg);
570 config_error("couldn't find client's argc/argc/envp");
571}
572
njn25e49d8e72002-09-23 09:36:25 +0000573static void usage ( void )
njn7cf0bd32002-06-08 13:36:03 +0000574{
njn25e49d8e72002-09-23 09:36:25 +0000575 Char* usage1 =
576"usage: valgrind [options] prog-and-args\n"
577"\n"
578" core user options, with defaults in [ ], are:\n"
579" --help show this message\n"
580" --version show version\n"
581" --skin=<name> main task (skin to use) [Valgrind]\n"
582" -q --quiet run silently; only print error msgs\n"
583" -v --verbose be more verbose, incl counts of errors\n"
584" --gdb-attach=no|yes start GDB when errors detected? [no]\n"
585" --demangle=no|yes automatically demangle C++ names? [yes]\n"
586" --num-callers=<number> show <num> callers in stack traces [4]\n"
587" --error-limit=no|yes stop showing new errors if too many? [yes]\n"
588" --sloppy-malloc=no|yes round malloc sizes to next word? [no]\n"
589" --alignment=<number> set minimum alignment of allocations [4]\n"
590" --trace-children=no|yes Valgrind-ise child processes? [no]\n"
591" --logfile-fd=<number> file descriptor for messages [2=stderr]\n"
592" --suppressions=<filename> suppress errors described in\n"
593" suppressions file <filename>\n"
594" --weird-hacks=hack1,hack2,... [no hacks selected]\n"
595" recognised hacks are: ioctl-VTIME truncate-writes\n"
596"\n"
597" %s skin user options:\n";
njn7cf0bd32002-06-08 13:36:03 +0000598
njn7cf0bd32002-06-08 13:36:03 +0000599
njn25e49d8e72002-09-23 09:36:25 +0000600 Char* usage2 =
601"\n"
602" core options for debugging Valgrind itself are:\n"
603" --sanity-level=<number> level of sanity checking to do [1]\n"
604" --single-step=no|yes translate each instr separately? [no]\n"
605" --optimise=no|yes improve intermediate code? [yes]\n"
606" --profile=no|yes profile? (skin must be built for it) [no]\n"
607" --trace-codegen=<XXXXX> show generated code? (X = 0|1) [00000]\n"
608" --trace-syscalls=no|yes show all system calls? [no]\n"
609" --trace-signals=no|yes show signal handling details? [no]\n"
610" --trace-symtab=no|yes show symbol table details? [no]\n"
611" --trace-malloc=no|yes show client malloc details? [no]\n"
612" --trace-sched=no|yes show thread scheduler details? [no]\n"
613" --trace-pthread=none|some|all show pthread event details? [no]\n"
614" --stop-after=<number> switch to real CPU after executing\n"
615" <number> basic blocks [infinity]\n"
616" --dump-error=<number> show translation for basic block\n"
617" associated with <number>'th\n"
618" error context [0=don't show any]\n"
619"\n"
620" Extra options are read from env variable $VALGRIND_OPTS\n"
621"\n"
622" Valgrind is Copyright (C) 2000-2002 Julian Seward\n"
623" and licensed under the GNU General Public License, version 2.\n"
624" Bug reports, feedback, admiration, abuse, etc, to: %s.\n"
625"\n";
njn7cf0bd32002-06-08 13:36:03 +0000626
njn25e49d8e72002-09-23 09:36:25 +0000627 VG_(printf)(usage1, VG_(needs).name);
628 /* Don't print skin string directly for security, ha! */
629 if (VG_(needs).command_line_options)
630 VG_(printf)("%s", SK_(usage)());
631 else
632 VG_(printf)(" (none)\n");
633 VG_(printf)(usage2, VG_EMAIL_ADDR);
njn7cf0bd32002-06-08 13:36:03 +0000634
njn25e49d8e72002-09-23 09:36:25 +0000635 VG_(shutdown_logging)();
636 VG_(clo_logfile_fd) = 2; /* stderr */
637 VG_(exit)(1);
njn7cf0bd32002-06-08 13:36:03 +0000638}
sewardjde4a1d02002-03-22 01:27:54 +0000639
640static void process_cmd_line_options ( void )
641{
njn25e49d8e72002-09-23 09:36:25 +0000642 Char* argv[M_VG_CMDLINE_OPTS];
643 UInt argc;
644 Char* p;
645 Char* str;
646 Int i, eventually_logfile_fd, ctr;
sewardjde4a1d02002-03-22 01:27:54 +0000647
648# define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
649# define STREQ(s1,s2) (0==VG_(strcmp_ws)((s1),(s2)))
650# define STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn)))
651
sewardjde4a1d02002-03-22 01:27:54 +0000652 eventually_logfile_fd = VG_(clo_logfile_fd);
653
654 /* Once logging is started, we can safely send messages pertaining
655 to failures in initialisation. */
656 VG_(startup_logging)();
657
sewardj19d81412002-06-03 01:10:40 +0000658 /* Check for sane path in ./configure --prefix=... */
659 if (VG_(strlen)(VG_LIBDIR) < 1
660 || VG_LIBDIR[0] != '/')
661 config_error("Please use absolute paths in "
662 "./configure --prefix=... or --libdir=...");
sewardj38170912002-05-10 21:07:22 +0000663
sewardja1679dd2002-05-10 22:31:40 +0000664 /* (Suggested by Fabrice Bellard ... )
665 We look for the Linux ELF table and go down until we find the
njn7cf0bd32002-06-08 13:36:03 +0000666 envc & envp. It is not fool-proof, but these structures should
sewardj38170912002-05-10 21:07:22 +0000667 change less often than the libc ones. */
668 {
sewardja1679dd2002-05-10 22:31:40 +0000669 UInt* sp = 0; /* bogus init to keep gcc -O happy */
670
sewardj38170912002-05-10 21:07:22 +0000671 /* locate the top of the stack */
sewardja1679dd2002-05-10 22:31:40 +0000672 if (VG_STACK_MATCHES_BASE( VG_(esp_at_startup),
673 VG_STARTUP_STACK_BASE_1 )) {
674 sp = (UInt*)VG_STARTUP_STACK_BASE_1;
675 } else
676 if (VG_STACK_MATCHES_BASE( VG_(esp_at_startup),
677 VG_STARTUP_STACK_BASE_2 )) {
678 sp = (UInt*)VG_STARTUP_STACK_BASE_2;
daywalkera2562202002-07-15 19:39:51 +0000679 } else
680 if (VG_STACK_MATCHES_BASE( VG_(esp_at_startup),
681 VG_STARTUP_STACK_BASE_3 )) {
682 sp = (UInt*)VG_STARTUP_STACK_BASE_3;
njn25e49d8e72002-09-23 09:36:25 +0000683 } else
684 if (VG_STACK_MATCHES_BASE( VG_(esp_at_startup),
685 VG_STARTUP_STACK_BASE_4 )) {
686 sp = (UInt*)VG_STARTUP_STACK_BASE_4;
sewardja1679dd2002-05-10 22:31:40 +0000687 } else {
688 args_grok_error(
689 "startup %esp is not near any VG_STARTUP_STACK_BASE_*\n "
690 "constants defined in vg_include.h. You should investigate."
691 );
692 }
693
sewardj38170912002-05-10 21:07:22 +0000694 /* we locate: NEW_AUX_ENT(1, AT_PAGESZ, ELF_EXEC_PAGESIZE) in
695 the elf interpreter table */
696 sp -= 2;
sewardj38170912002-05-10 21:07:22 +0000697 while (sp[0] != VKI_AT_PAGESZ || sp[1] != 4096) {
sewardja1679dd2002-05-10 22:31:40 +0000698 /* VG_(printf)("trying %p\n", sp); */
sewardj38170912002-05-10 21:07:22 +0000699 sp--;
700 }
sewardj38170912002-05-10 21:07:22 +0000701
702 if (sp[2] == VKI_AT_BASE
703 && sp[0] == VKI_AT_PAGESZ
704 && sp[-2] == VKI_AT_PHNUM
705 && sp[-4] == VKI_AT_PHENT
sewardjd9c2d6d2002-05-18 11:55:05 +0000706 && sp[-6] == VKI_AT_PHDR
707 && sp[-6-1] == 0) {
sewardja1679dd2002-05-10 22:31:40 +0000708 if (0)
709 VG_(printf)("Looks like you've got a 2.2.X kernel here.\n");
sewardj38170912002-05-10 21:07:22 +0000710 sp -= 6;
sewardja1679dd2002-05-10 22:31:40 +0000711 } else
712 if (sp[2] == VKI_AT_CLKTCK
713 && sp[0] == VKI_AT_PAGESZ
sewardjd9c2d6d2002-05-18 11:55:05 +0000714 && sp[-2] == VKI_AT_HWCAP
715 && sp[-2-1] == 0) {
sewardja1679dd2002-05-10 22:31:40 +0000716 if (0)
717 VG_(printf)("Looks like you've got a 2.4.X kernel here.\n");
718 sp -= 2;
719 } else
sewardjd9c2d6d2002-05-18 11:55:05 +0000720 if (sp[2] == VKI_AT_CLKTCK
721 && sp[0] == VKI_AT_PAGESZ
722 && sp[-2] == VKI_AT_HWCAP
sewardjce61d052002-07-25 00:49:51 +0000723 && sp[-4] == VKI_AT_USER_AUX_SEGMENT
724 && sp[-4-1] == 0) {
725 if (0)
726 VG_(printf)("Looks like you've got a R-H Limbo 2.4.X "
727 "kernel here.\n");
728 sp -= 4;
729 } else
730 if (sp[2] == VKI_AT_CLKTCK
731 && sp[0] == VKI_AT_PAGESZ
732 && sp[-2] == VKI_AT_HWCAP
sewardjd9c2d6d2002-05-18 11:55:05 +0000733 && sp[-2-20-1] == 0) {
734 if (0)
735 VG_(printf)("Looks like you've got a early 2.4.X kernel here.\n");
736 sp -= 22;
737 } else
sewardja1679dd2002-05-10 22:31:40 +0000738 args_grok_error(
739 "ELF frame does not look like 2.2.X or 2.4.X.\n "
740 "See kernel sources linux/fs/binfmt_elf.c to make sense of this."
741 );
sewardj38170912002-05-10 21:07:22 +0000742
743 sp--;
sewardja1679dd2002-05-10 22:31:40 +0000744 if (*sp != 0)
745 args_grok_error("can't find NULL at end of env[]");
746
sewardj38170912002-05-10 21:07:22 +0000747 /* sp now points to NULL at the end of env[] */
sewardja1679dd2002-05-10 22:31:40 +0000748 ctr = 0;
sewardj38170912002-05-10 21:07:22 +0000749 while (True) {
750 sp --;
751 if (*sp == 0) break;
sewardja1679dd2002-05-10 22:31:40 +0000752 if (++ctr >= 1000)
753 args_grok_error(
754 "suspiciously many (1000) env[] entries; giving up");
755
sewardj38170912002-05-10 21:07:22 +0000756 }
757 /* sp now points to NULL at the end of argv[] */
sewardja1679dd2002-05-10 22:31:40 +0000758 VG_(client_envp) = (Char**)(sp+1);
sewardj38170912002-05-10 21:07:22 +0000759
sewardja1679dd2002-05-10 22:31:40 +0000760 ctr = 0;
sewardj38170912002-05-10 21:07:22 +0000761 VG_(client_argc) = 0;
762 while (True) {
763 sp--;
764 if (*sp == VG_(client_argc))
765 break;
766 VG_(client_argc)++;
sewardja1679dd2002-05-10 22:31:40 +0000767 if (++ctr >= 1000)
768 args_grok_error(
769 "suspiciously many (1000) argv[] entries; giving up");
sewardj38170912002-05-10 21:07:22 +0000770 }
771
sewardja1679dd2002-05-10 22:31:40 +0000772 VG_(client_argv) = (Char**)(sp+1);
sewardj38170912002-05-10 21:07:22 +0000773 }
774
sewardjde4a1d02002-03-22 01:27:54 +0000775 /* Now that VG_(client_envp) has been set, we can extract the args
776 for Valgrind itself. Copy into global var so that we don't have to
777 write zeroes to the getenv'd value itself. */
778 str = VG_(getenv)("VG_ARGS");
779 argc = 0;
780
781 if (!str) {
782 config_error("Can't read options from env var VG_ARGS.");
783 }
784
785 if (VG_(strlen)(str) >= M_VG_CMDLINE_STRLEN-1) {
786 config_error("Command line length exceeds M_CMDLINE_STRLEN.");
787 }
788 VG_(strcpy)(vg_cmdline_copy, str);
789 str = NULL;
790
791 p = &vg_cmdline_copy[0];
792 while (True) {
793 while (ISSPACE(*p)) { *p = 0; p++; }
794 if (*p == 0) break;
795 if (argc < M_VG_CMDLINE_OPTS-1) {
796 argv[argc] = p; argc++;
797 } else {
798 config_error(
799 "Found more than M_CMDLINE_OPTS command-line opts.");
800 }
801 while (*p != 0 && !ISSPACE(*p)) p++;
802 }
803
804 for (i = 0; i < argc; i++) {
805
njn25e49d8e72002-09-23 09:36:25 +0000806 if (STREQ(argv[i], "-v") || STREQ(argv[i], "--verbose"))
sewardjde4a1d02002-03-22 01:27:54 +0000807 VG_(clo_verbosity)++;
808 else if (STREQ(argv[i], "-q") || STREQ(argv[i], "--quiet"))
809 VG_(clo_verbosity)--;
810
sewardj2e432902002-06-13 20:44:00 +0000811 else if (STREQ(argv[i], "--error-limit=yes"))
812 VG_(clo_error_limit) = True;
813 else if (STREQ(argv[i], "--error-limit=no"))
814 VG_(clo_error_limit) = False;
sewardj72f98ff2002-06-13 17:23:38 +0000815
sewardjde4a1d02002-03-22 01:27:54 +0000816 else if (STREQ(argv[i], "--gdb-attach=yes"))
817 VG_(clo_GDB_attach) = True;
818 else if (STREQ(argv[i], "--gdb-attach=no"))
819 VG_(clo_GDB_attach) = False;
820
821 else if (STREQ(argv[i], "--demangle=yes"))
822 VG_(clo_demangle) = True;
823 else if (STREQ(argv[i], "--demangle=no"))
824 VG_(clo_demangle) = False;
825
sewardjde4a1d02002-03-22 01:27:54 +0000826 else if (STREQ(argv[i], "--sloppy-malloc=yes"))
827 VG_(clo_sloppy_malloc) = True;
828 else if (STREQ(argv[i], "--sloppy-malloc=no"))
829 VG_(clo_sloppy_malloc) = False;
830
sewardj246d4662002-06-14 10:17:05 +0000831 else if (STREQN(12, argv[i], "--alignment="))
832 VG_(clo_alignment) = (Int)VG_(atoll)(&argv[i][12]);
833
sewardjde4a1d02002-03-22 01:27:54 +0000834 else if (STREQ(argv[i], "--trace-children=yes"))
835 VG_(clo_trace_children) = True;
836 else if (STREQ(argv[i], "--trace-children=no"))
837 VG_(clo_trace_children) = False;
838
sewardjde4a1d02002-03-22 01:27:54 +0000839 else if (STREQN(15, argv[i], "--sanity-level="))
840 VG_(sanity_level) = (Int)VG_(atoll)(&argv[i][15]);
841
842 else if (STREQN(13, argv[i], "--logfile-fd="))
843 eventually_logfile_fd = (Int)VG_(atoll)(&argv[i][13]);
844
sewardjde4a1d02002-03-22 01:27:54 +0000845 else if (STREQN(15, argv[i], "--suppressions=")) {
846 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
njn25e49d8e72002-09-23 09:36:25 +0000847 VG_(message)(Vg_UserMsg, "Too many suppression files specified.");
sewardjde4a1d02002-03-22 01:27:54 +0000848 VG_(message)(Vg_UserMsg,
849 "Increase VG_CLO_MAX_SFILES and recompile.");
njn25e49d8e72002-09-23 09:36:25 +0000850 VG_(bad_option)(argv[i]);
sewardjde4a1d02002-03-22 01:27:54 +0000851 }
852 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &argv[i][15];
853 VG_(clo_n_suppressions)++;
854 }
njn25e49d8e72002-09-23 09:36:25 +0000855 else if (STREQ(argv[i], "--profile=yes"))
856 VG_(clo_profile) = True;
857 else if (STREQ(argv[i], "--profile=no"))
858 VG_(clo_profile) = False;
859
sewardjde4a1d02002-03-22 01:27:54 +0000860 else if (STREQ(argv[i], "--single-step=yes"))
861 VG_(clo_single_step) = True;
862 else if (STREQ(argv[i], "--single-step=no"))
863 VG_(clo_single_step) = False;
864
865 else if (STREQ(argv[i], "--optimise=yes"))
866 VG_(clo_optimise) = True;
867 else if (STREQ(argv[i], "--optimise=no"))
868 VG_(clo_optimise) = False;
869
njn25e49d8e72002-09-23 09:36:25 +0000870 /* "vwxyz" --> 000zyxwv (binary) */
871 else if (STREQN(16, argv[i], "--trace-codegen=")) {
872 Int j;
873 char* opt = & argv[i][16];
874
875 if (5 != VG_(strlen)(opt)) {
876 VG_(message)(Vg_UserMsg,
877 "--trace-codegen argument must have 5 digits");
878 VG_(bad_option)(argv[i]);
879 }
880 for (j = 0; j < 5; j++) {
881 if ('0' == opt[j]) { /* do nothing */ }
882 else if ('1' == opt[j]) VG_(clo_trace_codegen) |= (1 << j);
883 else {
884 VG_(message)(Vg_UserMsg, "--trace-codegen argument can only "
885 "contain 0s and 1s");
886 VG_(bad_option)(argv[i]);
887 }
888 }
889 }
sewardjde4a1d02002-03-22 01:27:54 +0000890
891 else if (STREQ(argv[i], "--trace-syscalls=yes"))
892 VG_(clo_trace_syscalls) = True;
893 else if (STREQ(argv[i], "--trace-syscalls=no"))
894 VG_(clo_trace_syscalls) = False;
895
896 else if (STREQ(argv[i], "--trace-signals=yes"))
897 VG_(clo_trace_signals) = True;
898 else if (STREQ(argv[i], "--trace-signals=no"))
899 VG_(clo_trace_signals) = False;
900
901 else if (STREQ(argv[i], "--trace-symtab=yes"))
902 VG_(clo_trace_symtab) = True;
903 else if (STREQ(argv[i], "--trace-symtab=no"))
904 VG_(clo_trace_symtab) = False;
905
906 else if (STREQ(argv[i], "--trace-malloc=yes"))
907 VG_(clo_trace_malloc) = True;
908 else if (STREQ(argv[i], "--trace-malloc=no"))
909 VG_(clo_trace_malloc) = False;
910
sewardj8937c812002-04-12 20:12:20 +0000911 else if (STREQ(argv[i], "--trace-sched=yes"))
912 VG_(clo_trace_sched) = True;
913 else if (STREQ(argv[i], "--trace-sched=no"))
914 VG_(clo_trace_sched) = False;
915
sewardj45b4b372002-04-16 22:50:32 +0000916 else if (STREQ(argv[i], "--trace-pthread=none"))
917 VG_(clo_trace_pthread_level) = 0;
918 else if (STREQ(argv[i], "--trace-pthread=some"))
919 VG_(clo_trace_pthread_level) = 1;
920 else if (STREQ(argv[i], "--trace-pthread=all"))
921 VG_(clo_trace_pthread_level) = 2;
sewardj8937c812002-04-12 20:12:20 +0000922
sewardj8d365b52002-05-12 10:52:16 +0000923 else if (STREQN(14, argv[i], "--weird-hacks="))
924 VG_(clo_weird_hacks) = &argv[i][14];
sewardj3984b852002-05-12 03:00:17 +0000925
sewardjde4a1d02002-03-22 01:27:54 +0000926 else if (STREQN(13, argv[i], "--stop-after="))
927 VG_(clo_stop_after) = VG_(atoll)(&argv[i][13]);
928
929 else if (STREQN(13, argv[i], "--dump-error="))
930 VG_(clo_dump_error) = (Int)VG_(atoll)(&argv[i][13]);
931
932 else if (STREQN(14, argv[i], "--num-callers=")) {
933 /* Make sure it's sane. */
934 VG_(clo_backtrace_size) = (Int)VG_(atoll)(&argv[i][14]);
935 if (VG_(clo_backtrace_size) < 2)
936 VG_(clo_backtrace_size) = 2;
937 if (VG_(clo_backtrace_size) >= VG_DEEPEST_BACKTRACE)
938 VG_(clo_backtrace_size) = VG_DEEPEST_BACKTRACE;
939 }
940
njn25e49d8e72002-09-23 09:36:25 +0000941 else if (VG_(needs).command_line_options) {
942 Bool ok = SK_(process_cmd_line_option)(argv[i]);
943 if (!ok)
944 usage();
945 }
sewardjde4a1d02002-03-22 01:27:54 +0000946 else
njn25e49d8e72002-09-23 09:36:25 +0000947 usage();
sewardjde4a1d02002-03-22 01:27:54 +0000948 }
949
950# undef ISSPACE
951# undef STREQ
952# undef STREQN
953
954 if (VG_(clo_verbosity < 0))
955 VG_(clo_verbosity) = 0;
956
sewardj246d4662002-06-14 10:17:05 +0000957 if (VG_(clo_alignment) < 4
958 || VG_(clo_alignment) > 4096
959 || VG_(log2)( VG_(clo_alignment) ) == -1 /* not a power of 2 */) {
960 VG_(message)(Vg_UserMsg, "");
961 VG_(message)(Vg_UserMsg,
962 "Invalid --alignment= setting. "
963 "Should be a power of 2, >= 4, <= 4096.");
njn25e49d8e72002-09-23 09:36:25 +0000964 VG_(bad_option)("--alignment");
sewardj246d4662002-06-14 10:17:05 +0000965 }
966
sewardjde4a1d02002-03-22 01:27:54 +0000967 if (VG_(clo_GDB_attach) && VG_(clo_trace_children)) {
968 VG_(message)(Vg_UserMsg, "");
969 VG_(message)(Vg_UserMsg,
970 "--gdb-attach=yes conflicts with --trace-children=yes");
971 VG_(message)(Vg_UserMsg,
972 "Please choose one or the other, but not both.");
njn25e49d8e72002-09-23 09:36:25 +0000973 VG_(bad_option)("--gdb-attach=yes and --trace-children=yes");
sewardjde4a1d02002-03-22 01:27:54 +0000974 }
975
sewardjde4a1d02002-03-22 01:27:54 +0000976 VG_(clo_logfile_fd) = eventually_logfile_fd;
977
sewardj83adf412002-05-01 01:25:45 +0000978 if (VG_(clo_verbosity > 0)) {
njn25e49d8e72002-09-23 09:36:25 +0000979 VG_(message)(Vg_UserMsg, "%s-%s, %s for x86 GNU/Linux.",
980 VG_(needs).name, VERSION, VG_(needs).description);
sewardj83adf412002-05-01 01:25:45 +0000981 }
sewardj3b2736a2002-03-24 12:18:35 +0000982
sewardjde4a1d02002-03-22 01:27:54 +0000983 if (VG_(clo_verbosity > 0))
984 VG_(message)(Vg_UserMsg,
985 "Copyright (C) 2000-2002, and GNU GPL'd, by Julian Seward.");
986 if (VG_(clo_verbosity) > 1) {
987 VG_(message)(Vg_UserMsg, "Startup, with flags:");
988 for (i = 0; i < argc; i++) {
989 VG_(message)(Vg_UserMsg, " %s", argv[i]);
990 }
991 }
992
njn25e49d8e72002-09-23 09:36:25 +0000993 if (VG_(clo_n_suppressions) == 0 &&
994 (VG_(needs).core_errors || VG_(needs).skin_errors)) {
sewardjde4a1d02002-03-22 01:27:54 +0000995 config_error("No error-suppression files were specified.");
996 }
997}
998
sewardjde4a1d02002-03-22 01:27:54 +0000999/* ---------------------------------------------------------------------
1000 Copying to/from m_state_static.
1001 ------------------------------------------------------------------ */
1002
1003UInt VG_(m_state_static) [8 /* int regs, in Intel order */
1004 + 1 /* %eflags */
1005 + 1 /* %eip */
1006 + VG_SIZE_OF_FPUSTATE_W /* FPU state */
1007 ];
1008
1009void VG_(copy_baseBlock_to_m_state_static) ( void )
1010{
1011 Int i;
1012 VG_(m_state_static)[ 0/4] = VG_(baseBlock)[VGOFF_(m_eax)];
1013 VG_(m_state_static)[ 4/4] = VG_(baseBlock)[VGOFF_(m_ecx)];
1014 VG_(m_state_static)[ 8/4] = VG_(baseBlock)[VGOFF_(m_edx)];
1015 VG_(m_state_static)[12/4] = VG_(baseBlock)[VGOFF_(m_ebx)];
1016 VG_(m_state_static)[16/4] = VG_(baseBlock)[VGOFF_(m_esp)];
1017 VG_(m_state_static)[20/4] = VG_(baseBlock)[VGOFF_(m_ebp)];
1018 VG_(m_state_static)[24/4] = VG_(baseBlock)[VGOFF_(m_esi)];
1019 VG_(m_state_static)[28/4] = VG_(baseBlock)[VGOFF_(m_edi)];
1020
1021 VG_(m_state_static)[32/4] = VG_(baseBlock)[VGOFF_(m_eflags)];
1022 VG_(m_state_static)[36/4] = VG_(baseBlock)[VGOFF_(m_eip)];
1023
1024 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
1025 VG_(m_state_static)[40/4 + i]
1026 = VG_(baseBlock)[VGOFF_(m_fpustate) + i];
1027}
1028
1029
1030void VG_(copy_m_state_static_to_baseBlock) ( void )
1031{
1032 Int i;
1033 VG_(baseBlock)[VGOFF_(m_eax)] = VG_(m_state_static)[ 0/4];
1034 VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(m_state_static)[ 4/4];
1035 VG_(baseBlock)[VGOFF_(m_edx)] = VG_(m_state_static)[ 8/4];
1036 VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(m_state_static)[12/4];
1037 VG_(baseBlock)[VGOFF_(m_esp)] = VG_(m_state_static)[16/4];
1038 VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(m_state_static)[20/4];
1039 VG_(baseBlock)[VGOFF_(m_esi)] = VG_(m_state_static)[24/4];
1040 VG_(baseBlock)[VGOFF_(m_edi)] = VG_(m_state_static)[28/4];
1041
1042 VG_(baseBlock)[VGOFF_(m_eflags)] = VG_(m_state_static)[32/4];
1043 VG_(baseBlock)[VGOFF_(m_eip)] = VG_(m_state_static)[36/4];
1044
1045 for (i = 0; i < VG_SIZE_OF_FPUSTATE_W; i++)
1046 VG_(baseBlock)[VGOFF_(m_fpustate) + i]
1047 = VG_(m_state_static)[40/4 + i];
1048}
1049
njn25e49d8e72002-09-23 09:36:25 +00001050Addr VG_(get_stack_pointer) ( void )
1051{
1052 return VG_(baseBlock)[VGOFF_(m_esp)];
1053}
1054
1055/* Some random tests needed for leak checking */
1056
1057Bool VG_(within_stack)(Addr a)
1058{
1059 if (a >= ((Addr)(&VG_(stack)))
1060 && a <= ((Addr)(&VG_(stack))) + sizeof(VG_(stack)))
1061 return True;
1062 else
1063 return False;
1064}
1065
1066Bool VG_(within_m_state_static)(Addr a)
1067{
1068 if (a >= ((Addr)(&VG_(m_state_static)))
1069 && a <= ((Addr)(&VG_(m_state_static))) + sizeof(VG_(m_state_static)))
1070 return True;
1071 else
1072 return False;
1073}
sewardjde4a1d02002-03-22 01:27:54 +00001074
1075/* ---------------------------------------------------------------------
1076 Show accumulated counts.
1077 ------------------------------------------------------------------ */
1078
njn25e49d8e72002-09-23 09:36:25 +00001079static __inline__ Int safe_idiv(Int a, Int b)
1080{
1081 return (b == 0 ? 0 : a / b);
1082}
1083
sewardjde4a1d02002-03-22 01:27:54 +00001084static void vg_show_counts ( void )
1085{
1086 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +00001087 " lru: %d epochs, %d clearings.",
1088 VG_(current_epoch),
1089 VG_(number_of_lrus) );
sewardjde4a1d02002-03-22 01:27:54 +00001090 VG_(message)(Vg_DebugMsg,
njn25e49d8e72002-09-23 09:36:25 +00001091 "translate: new %d (%d -> %d; ratio %d:10)",
sewardjde4a1d02002-03-22 01:27:54 +00001092 VG_(overall_in_count),
1093 VG_(overall_in_osize),
1094 VG_(overall_in_tsize),
njn25e49d8e72002-09-23 09:36:25 +00001095 safe_idiv(10*VG_(overall_in_tsize), VG_(overall_in_osize)));
1096 VG_(message)(Vg_DebugMsg,
1097 " discard %d (%d -> %d; ratio %d:10).",
sewardjde4a1d02002-03-22 01:27:54 +00001098 VG_(overall_out_count),
1099 VG_(overall_out_osize),
njn25e49d8e72002-09-23 09:36:25 +00001100 VG_(overall_out_tsize),
1101 safe_idiv(10*VG_(overall_out_tsize), VG_(overall_out_osize)));
sewardjde4a1d02002-03-22 01:27:54 +00001102 VG_(message)(Vg_DebugMsg,
sewardj2e93c502002-04-12 11:12:52 +00001103 " dispatch: %lu basic blocks, %d/%d sched events, %d tt_fast misses.",
1104 VG_(bbs_done), VG_(num_scheduling_events_MAJOR),
1105 VG_(num_scheduling_events_MINOR),
1106 VG_(tt_fast_misses));
sewardjde4a1d02002-03-22 01:27:54 +00001107 VG_(message)(Vg_DebugMsg,
1108 "reg-alloc: %d t-req-spill, "
1109 "%d+%d orig+spill uis, %d total-reg-r.",
1110 VG_(translations_needing_spill),
1111 VG_(uinstrs_prealloc),
1112 VG_(uinstrs_spill),
1113 VG_(total_reg_rank) );
1114 VG_(message)(Vg_DebugMsg,
sewardjde4a1d02002-03-22 01:27:54 +00001115 " sanity: %d cheap, %d expensive checks.",
1116 VG_(sanity_fast_count),
1117 VG_(sanity_slow_count) );
njn25e49d8e72002-09-23 09:36:25 +00001118 VG_(print_ccall_stats)();
sewardjde4a1d02002-03-22 01:27:54 +00001119}
1120
1121
1122/* ---------------------------------------------------------------------
1123 Main!
1124 ------------------------------------------------------------------ */
1125
1126/* Where we jump to once Valgrind has got control, and the real
1127 machine's state has been copied to the m_state_static. */
1128
1129void VG_(main) ( void )
1130{
sewardj2e93c502002-04-12 11:12:52 +00001131 Int i;
1132 VgSchedReturnCode src;
sewardj7e87e382002-05-03 19:09:05 +00001133 ThreadState* tst;
sewardjde4a1d02002-03-22 01:27:54 +00001134
1135 /* Set up our stack sanity-check words. */
1136 for (i = 0; i < 10; i++) {
1137 VG_(stack)[i] = (UInt)(&VG_(stack)[i]) ^ 0xA4B3C2D1;
1138 VG_(stack)[10000-1-i] = (UInt)(&VG_(stack)[10000-i-1]) ^ 0xABCD4321;
1139 }
1140
njn25e49d8e72002-09-23 09:36:25 +00001141 /* Setup stuff that depends on the skin. Must be before:
1142 - vg_init_baseBlock(): to register helpers
1143 - process_cmd_line_options(): to register skin name and description,
1144 and turn on/off 'command_line_options' need
1145 - init_memory() (to setup memory event trackers).
1146 */
1147 SK_(pre_clo_init) ( & VG_(needs), & VG_(track_events) );
1148 sanity_check_needs();
1149
1150 /* Set up baseBlock offsets and copy the saved machine's state into it. */
sewardjde4a1d02002-03-22 01:27:54 +00001151 vg_init_baseBlock();
1152 VG_(copy_m_state_static_to_baseBlock)();
njn25e49d8e72002-09-23 09:36:25 +00001153 vg_init_shadow_regs();
sewardjde4a1d02002-03-22 01:27:54 +00001154
1155 /* Process Valgrind's command-line opts (from env var VG_OPTS). */
1156 process_cmd_line_options();
1157
sewardj64039bb2002-06-03 00:58:18 +00001158 /* Hook to delay things long enough so we can get the pid and
1159 attach GDB in another shell. */
njn25e49d8e72002-09-23 09:36:25 +00001160#if 0
1161 {
sewardj64039bb2002-06-03 00:58:18 +00001162 Int p, q;
1163 for (p = 0; p < 50000; p++)
1164 for (q = 0; q < 50000; q++) ;
1165 }
njn25e49d8e72002-09-23 09:36:25 +00001166#endif
sewardj64039bb2002-06-03 00:58:18 +00001167
sewardj018f7622002-05-15 21:13:39 +00001168 /* Initialise the scheduler, and copy the client's state from
1169 baseBlock into VG_(threads)[1]. This has to come before signal
1170 initialisations. */
1171 VG_(scheduler_init)();
1172
1173 /* Initialise the signal handling subsystem, temporarily parking
1174 the saved blocking-mask in saved_sigmask. */
sewardjde4a1d02002-03-22 01:27:54 +00001175 VG_(sigstartup_actions)();
1176
sewardj018f7622002-05-15 21:13:39 +00001177 /* Perhaps we're profiling Valgrind? */
njn25e49d8e72002-09-23 09:36:25 +00001178 if (VG_(clo_profile))
1179 VGP_(init_profiling)();
sewardjde4a1d02002-03-22 01:27:54 +00001180
sewardj5f07b662002-04-23 16:52:51 +00001181 /* Start calibration of our RDTSC-based clock. */
1182 VG_(start_rdtsc_calibration)();
1183
njn25e49d8e72002-09-23 09:36:25 +00001184 /* Do this here just to give rdtsc calibration more time */
1185 SK_(post_clo_init)();
sewardjde4a1d02002-03-22 01:27:54 +00001186
njn25e49d8e72002-09-23 09:36:25 +00001187 /* Must come after SK_(init) so memory handler accompaniments (eg.
1188 * shadow memory) can be setup ok */
1189 VGP_PUSHCC(VgpInitMem);
1190 VG_(init_memory)();
1191 VGP_POPCC(VgpInitMem);
1192
1193 /* Read the list of errors to suppress. This should be found in
1194 the file specified by vg_clo_suppressions. */
1195 if (VG_(needs).core_errors || VG_(needs).skin_errors)
1196 VG_(load_suppressions)();
sewardj18d75132002-05-16 11:06:21 +00001197
sewardj5f07b662002-04-23 16:52:51 +00001198 /* End calibration of our RDTSC-based clock, leaving it as long as
1199 we can. */
1200 VG_(end_rdtsc_calibration)();
1201
njn25e49d8e72002-09-23 09:36:25 +00001202 /* This should come after init_memory_and_symbols(); otherwise the
1203 latter carefully sets up the permissions maps to cover the
1204 anonymous mmaps for the translation table and translation cache,
1205 which wastes > 20M of virtual address space. */
sewardj18d75132002-05-16 11:06:21 +00001206 VG_(init_tt_tc)();
sewardjde4a1d02002-03-22 01:27:54 +00001207
1208 if (VG_(clo_verbosity) == 1) {
1209 VG_(message)(Vg_UserMsg,
1210 "For more details, rerun with: -v");
1211 }
1212
1213 /* Now it is safe for malloc et al in vg_clientmalloc.c to act
1214 instrumented-ly. */
sewardjde4a1d02002-03-22 01:27:54 +00001215 if (VG_(clo_verbosity) > 0)
1216 VG_(message)(Vg_UserMsg, "");
1217
1218 VG_(bbs_to_go) = VG_(clo_stop_after);
sewardj2e93c502002-04-12 11:12:52 +00001219
njn25e49d8e72002-09-23 09:36:25 +00001220
sewardj018f7622002-05-15 21:13:39 +00001221 /* Run! */
njn25e49d8e72002-09-23 09:36:25 +00001222 VG_(running_on_simd_CPU) = True;
sewardj671ff542002-05-07 09:25:30 +00001223 VGP_PUSHCC(VgpSched);
sewardj2e93c502002-04-12 11:12:52 +00001224 src = VG_(scheduler)();
njn25e49d8e72002-09-23 09:36:25 +00001225 VGP_POPCC(VgpSched);
1226 VG_(running_on_simd_CPU) = False;
sewardjde4a1d02002-03-22 01:27:54 +00001227
1228 if (VG_(clo_verbosity) > 0)
1229 VG_(message)(Vg_UserMsg, "");
1230
sewardj2e93c502002-04-12 11:12:52 +00001231 if (src == VgSrc_Deadlock) {
1232 VG_(message)(Vg_UserMsg,
1233 "Warning: pthread scheduler exited due to deadlock");
1234 }
1235
njn25e49d8e72002-09-23 09:36:25 +00001236 if (VG_(needs).core_errors || VG_(needs).skin_errors)
sewardjde4a1d02002-03-22 01:27:54 +00001237 VG_(show_all_errors)();
sewardj2e93c502002-04-12 11:12:52 +00001238
njn25e49d8e72002-09-23 09:36:25 +00001239 SK_(fini)();
njn4f9c9342002-04-29 16:03:24 +00001240
sewardj0c3b53f2002-05-01 01:58:35 +00001241 VG_(do_sanity_checks)( True /*include expensive checks*/ );
sewardjde4a1d02002-03-22 01:27:54 +00001242
1243 if (VG_(clo_verbosity) > 1)
1244 vg_show_counts();
1245
njn25e49d8e72002-09-23 09:36:25 +00001246 if (VG_(clo_verbosity) > 2)
1247 VG_(print_UInstr_histogram)();
1248
sewardjde4a1d02002-03-22 01:27:54 +00001249 if (0) {
1250 VG_(message)(Vg_DebugMsg, "");
1251 VG_(message)(Vg_DebugMsg,
1252 "------ Valgrind's internal memory use stats follow ------" );
1253 VG_(mallocSanityCheckAll)();
1254 VG_(show_all_arena_stats)();
1255 VG_(message)(Vg_DebugMsg,
1256 "------ Valgrind's ExeContext management stats follow ------" );
1257 VG_(show_ExeContext_stats)();
sewardjde4a1d02002-03-22 01:27:54 +00001258 }
1259
njn25e49d8e72002-09-23 09:36:25 +00001260 if (VG_(clo_profile))
1261 VGP_(done_profiling)();
sewardjde4a1d02002-03-22 01:27:54 +00001262
1263 VG_(shutdown_logging)();
1264
sewardj3e1eb1f2002-05-18 13:14:17 +00001265 /* Remove valgrind.so from a LD_PRELOAD=... string so child
1266 processes don't get traced into. Also mess up $libdir/valgrind
1267 so that our libpthread.so disappears from view. */
sewardjde4a1d02002-03-22 01:27:54 +00001268 if (!VG_(clo_trace_children)) {
sewardj3e1eb1f2002-05-18 13:14:17 +00001269 VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH)(
1270 VG_(getenv)("LD_PRELOAD"),
1271 VG_(getenv)("LD_LIBRARY_PATH")
1272 );
sewardjde4a1d02002-03-22 01:27:54 +00001273 }
1274
sewardj7e87e382002-05-03 19:09:05 +00001275 /* Decide how to exit. This depends on what the scheduler
1276 returned. */
1277 switch (src) {
1278 case VgSrc_ExitSyscall: /* the normal way out */
1279 vg_assert(VG_(last_run_tid) > 0
1280 && VG_(last_run_tid) < VG_N_THREADS);
sewardj018f7622002-05-15 21:13:39 +00001281 tst = & VG_(threads)[VG_(last_run_tid)];
sewardj7e87e382002-05-03 19:09:05 +00001282 vg_assert(tst->status == VgTs_Runnable);
njn25e49d8e72002-09-23 09:36:25 +00001283 /* The thread's %EBX at the time it did __NR_exit() will hold
1284 the arg to __NR_exit(), so we just do __NR_exit() with
1285 that arg. */
1286 VG_(exit)( VG_(exitcode) );
sewardj7e87e382002-05-03 19:09:05 +00001287 /* NOT ALIVE HERE! */
1288 VG_(panic)("entered the afterlife in vg_main() -- ExitSyscall");
1289 break; /* what the hell :) */
sewardjde4a1d02002-03-22 01:27:54 +00001290
sewardj7e87e382002-05-03 19:09:05 +00001291 case VgSrc_Deadlock:
1292 /* Just exit now. No point in continuing. */
1293 VG_(exit)(0);
1294 VG_(panic)("entered the afterlife in vg_main() -- Deadlock");
1295 break;
1296
1297 case VgSrc_BbsDone:
1298 /* Tricky; we have to try and switch back to the real CPU.
1299 This is all very dodgy and won't work at all in the
1300 presence of threads, or if the client happened to be
1301 running a signal handler. */
1302 /* Prepare to restore state to the real CPU. */
1303 VG_(load_thread_state)(1 /* root thread */ );
1304 VG_(copy_baseBlock_to_m_state_static)();
1305
1306 /* This pushes a return address on the simulator's stack,
1307 which is abandoned. We call vg_sigshutdown_actions() at
1308 the end of vg_switch_to_real_CPU(), so as to ensure that
1309 the original stack and machine state is restored before
1310 the real signal mechanism is restored. */
1311 VG_(switch_to_real_CPU)();
1312
1313 default:
1314 VG_(panic)("vg_main(): unexpected scheduler return code");
1315 }
sewardjde4a1d02002-03-22 01:27:54 +00001316}
1317
1318
1319/* Debugging thing .. can be called from assembly with OYNK macro. */
1320void VG_(oynk) ( Int n )
1321{
1322 OINK(n);
1323}
1324
1325
1326/* Find "valgrind.so" in a LD_PRELOAD=... string, and convert it to
1327 "valgrinq.so", which doesn't do anything. This is used to avoid
1328 tracing into child processes. To make this work the build system
1329 also supplies a dummy file, "valgrinq.so".
sewardj78e25c92002-05-20 23:38:33 +00001330
njn25e49d8e72002-09-23 09:36:25 +00001331 Also replace "vgskin_<foo>.so" with whitespace, for the same reason;
1332 without it, child processes try to find valgrind.so symbols in the
1333 skin .so.
1334
sewardj78e25c92002-05-20 23:38:33 +00001335 Also look for $(libdir)/lib/valgrind in LD_LIBRARY_PATH and change
1336 it to $(libdir)/lib/valgrinq, so as to make our libpthread.so
1337 disappear.
sewardjde4a1d02002-03-22 01:27:54 +00001338*/
sewardj3e1eb1f2002-05-18 13:14:17 +00001339void VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH) ( Char* ld_preload_str,
1340 Char* ld_library_path_str )
sewardjde4a1d02002-03-22 01:27:54 +00001341{
njn25e49d8e72002-09-23 09:36:25 +00001342 Char* p_prel = NULL;
1343 Char* sk_prel = NULL;
1344 Char* p_path = NULL;
1345 Int what = 0;
sewardj78e25c92002-05-20 23:38:33 +00001346 if (ld_preload_str == NULL || ld_library_path_str == NULL)
1347 goto mutancy;
sewardj3e1eb1f2002-05-18 13:14:17 +00001348
sewardj78e25c92002-05-20 23:38:33 +00001349 /* VG_(printf)("%s %s\n", ld_preload_str, ld_library_path_str); */
1350
1351 p_prel = VG_(strstr)(ld_preload_str, "valgrind.so");
njn25e49d8e72002-09-23 09:36:25 +00001352 sk_prel = VG_(strstr)(ld_preload_str, "vgskin_");
sewardj78e25c92002-05-20 23:38:33 +00001353 p_path = VG_(strstr)(ld_library_path_str, VG_LIBDIR);
1354
njn25e49d8e72002-09-23 09:36:25 +00001355 what = 1;
sewardj78e25c92002-05-20 23:38:33 +00001356 if (p_prel == NULL) {
sewardj3e1eb1f2002-05-18 13:14:17 +00001357 /* perhaps already happened? */
sewardj78e25c92002-05-20 23:38:33 +00001358 if (VG_(strstr)(ld_preload_str, "valgrinq.so") == NULL)
1359 goto mutancy;
1360 if (VG_(strstr)(ld_library_path_str, "lib/valgrinq") == NULL)
1361 goto mutancy;
sewardjde4a1d02002-03-22 01:27:54 +00001362 return;
sewardj3e1eb1f2002-05-18 13:14:17 +00001363 }
1364
sewardj78e25c92002-05-20 23:38:33 +00001365 what = 2;
njn25e49d8e72002-09-23 09:36:25 +00001366 if (sk_prel == NULL) goto mutancy;
1367
1368 what = 3;
sewardj78e25c92002-05-20 23:38:33 +00001369 if (p_path == NULL) goto mutancy;
1370
njn25e49d8e72002-09-23 09:36:25 +00001371 what = 4;
1372 {
1373 /* Blank from "vgskin_" back to prev. LD_PRELOAD entry, or start */
1374 Char* p = sk_prel;
1375 while (*p != ':' && p > ld_preload_str) {
1376 *p = ' ';
1377 p--;
1378 }
1379 /* Blank from "vgskin_" to next LD_PRELOAD entry */
1380 while (*p != ':' && *p != '\0') {
1381 *p = ' ';
1382 p++;
1383 }
1384 if (*p == '\0') goto mutancy; /* valgrind.so has disappeared?! */
1385 *p = ' '; /* blank ending ':' */
1386 }
1387
sewardj78e25c92002-05-20 23:38:33 +00001388 /* in LD_PRELOAD, turn valgrind.so into valgrinq.so. */
njn25e49d8e72002-09-23 09:36:25 +00001389 what = 5;
sewardj78e25c92002-05-20 23:38:33 +00001390 if (p_prel[7] != 'd') goto mutancy;
1391 p_prel[7] = 'q';
sewardj3e1eb1f2002-05-18 13:14:17 +00001392
1393 /* in LD_LIBRARY_PATH, turn $libdir/valgrind (as configure'd) from
1394 .../lib/valgrind .../lib/valgrinq, which doesn't exist,
1395 so that our own libpthread.so goes out of scope. */
sewardj78e25c92002-05-20 23:38:33 +00001396 p_path += VG_(strlen)(VG_LIBDIR);
njn25e49d8e72002-09-23 09:36:25 +00001397 what = 6;
sewardj78e25c92002-05-20 23:38:33 +00001398 if (p_path[0] != '/') goto mutancy;
1399 p_path++; /* step over / */
njn25e49d8e72002-09-23 09:36:25 +00001400 what = 7;
sewardj78e25c92002-05-20 23:38:33 +00001401 if (p_path[7] != 'd') goto mutancy;
1402 p_path[7] = 'q';
1403 return;
1404
1405 mutancy:
1406 VG_(printf)(
1407 "\nVG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH): internal error:\n"
1408 " what = %d\n"
1409 " ld_preload_str = `%s'\n"
1410 " ld_library_path_str = `%s'\n"
1411 " p_prel = `%s'\n"
1412 " p_path = `%s'\n"
1413 " VG_LIBDIR = `%s'\n",
sewardj19d81412002-06-03 01:10:40 +00001414 what, ld_preload_str, ld_library_path_str,
1415 p_prel, p_path, VG_LIBDIR
1416 );
sewardjc26b4482002-07-13 12:20:35 +00001417 VG_(printf)(
1418 "\n"
1419 "Note that this is often caused by mis-installation of valgrind.\n"
1420 "Correct installation procedure is:\n"
1421 " ./configure --prefix=/install/dir\n"
1422 " make install\n"
1423 "And then use /install/dir/bin/valgrind\n"
1424 "Moving the installation directory elsewhere after 'make install'\n"
1425 "will cause the above error. Hand-editing the paths in the shell\n"
1426 "scripts is also likely to cause problems.\n"
1427 "\n"
1428 );
sewardj78e25c92002-05-20 23:38:33 +00001429 VG_(panic)("VG_(mash_LD_PRELOAD_and_LD_LIBRARY_PATH) failed\n");
sewardjde4a1d02002-03-22 01:27:54 +00001430}
1431
sewardj3e1eb1f2002-05-18 13:14:17 +00001432
sewardjde4a1d02002-03-22 01:27:54 +00001433/* RUNS ON THE CLIENT'S STACK, but on the real CPU. Start GDB and get
1434 it to attach to this process. Called if the user requests this
1435 service after an error has been shown, so she can poke around and
1436 look at parameters, memory, etc. You can't meaningfully get GDB to
1437 continue the program, though; to continue, quit GDB. */
1438extern void VG_(start_GDB_whilst_on_client_stack) ( void )
1439{
sewardje6a25242002-04-21 22:03:07 +00001440 Int res;
sewardjde4a1d02002-03-22 01:27:54 +00001441 UChar buf[100];
1442 VG_(sprintf)(buf,
1443 "/usr/bin/gdb -nw /proc/%d/exe %d",
1444 VG_(getpid)(), VG_(getpid)());
sewardje6a25242002-04-21 22:03:07 +00001445 VG_(message)(Vg_UserMsg, "starting GDB with cmd: %s", buf);
1446 res = VG_(system)(buf);
1447 if (res == 0) {
1448 VG_(message)(Vg_UserMsg, "");
1449 VG_(message)(Vg_UserMsg,
1450 "GDB has detached. Valgrind regains control. We continue.");
1451 } else {
1452 VG_(message)(Vg_UserMsg, "Apparently failed!");
1453 VG_(message)(Vg_UserMsg, "");
sewardjde4a1d02002-03-22 01:27:54 +00001454 }
sewardjde4a1d02002-03-22 01:27:54 +00001455}
1456
1457
1458/* Print some helpful-ish text about unimplemented things, and give
1459 up. */
sewardjcfc39b22002-05-08 01:58:18 +00001460void VG_(unimplemented) ( Char* msg )
sewardjde4a1d02002-03-22 01:27:54 +00001461{
1462 VG_(message)(Vg_UserMsg, "");
1463 VG_(message)(Vg_UserMsg,
1464 "Valgrind detected that your program requires");
1465 VG_(message)(Vg_UserMsg,
1466 "the following unimplemented functionality:");
1467 VG_(message)(Vg_UserMsg, " %s", msg);
1468 VG_(message)(Vg_UserMsg,
1469 "This may be because the functionality is hard to implement,");
1470 VG_(message)(Vg_UserMsg,
1471 "or because no reasonable program would behave this way,");
1472 VG_(message)(Vg_UserMsg,
1473 "or because nobody has yet needed it. In any case, let me know");
1474 VG_(message)(Vg_UserMsg,
1475 "(jseward@acm.org) and/or try to work around the problem, if you can.");
1476 VG_(message)(Vg_UserMsg,
1477 "");
1478 VG_(message)(Vg_UserMsg,
1479 "Valgrind has to exit now. Sorry. Bye!");
1480 VG_(message)(Vg_UserMsg,
1481 "");
sewardj15a43e12002-04-17 19:35:12 +00001482 VG_(pp_sched_status)();
sewardjde4a1d02002-03-22 01:27:54 +00001483 VG_(exit)(1);
1484}
1485
1486
sewardjcfc39b22002-05-08 01:58:18 +00001487void VG_(nvidia_moan) ( void)
1488{
1489 VG_(message)(Vg_UserMsg,
1490 "The following failure _might_ be caused by linking to NVidia's\n "
1491 "libGL.so, so avoiding it, if you can, _might_ help you. For example,\n "
1492 "re-build any Qt libraries you are using without OpenGL support.");
1493}
1494
1495
njn25e49d8e72002-09-23 09:36:25 +00001496/* ---------------------------------------------------------------------
1497 Sanity check machinery (permanently engaged).
1498 ------------------------------------------------------------------ */
1499
1500/* A fast sanity check -- suitable for calling circa once per
1501 millisecond. */
1502
1503void VG_(do_sanity_checks) ( Bool force_expensive )
1504{
1505 Int i;
1506
1507 if (VG_(sanity_level) < 1) return;
1508
1509 /* --- First do all the tests that we can do quickly. ---*/
1510
1511 VG_(sanity_fast_count)++;
1512
1513 /* Check that we haven't overrun our private stack. */
1514 for (i = 0; i < 10; i++) {
1515 vg_assert(VG_(stack)[i]
1516 == ((UInt)(&VG_(stack)[i]) ^ 0xA4B3C2D1));
1517 vg_assert(VG_(stack)[10000-1-i]
1518 == ((UInt)(&VG_(stack)[10000-i-1]) ^ 0xABCD4321));
1519 }
1520
1521 /* Check stuff pertaining to the memory check system. */
1522
1523 /* Check that nobody has spuriously claimed that the first or
1524 last 16 pages of memory have become accessible [...] */
1525 if (VG_(needs).sanity_checks)
1526 vg_assert(SK_(cheap_sanity_check)());
1527
1528 /* --- Now some more expensive checks. ---*/
1529
1530 /* Once every 25 times, check some more expensive stuff. */
1531 if ( force_expensive
1532 || VG_(sanity_level) > 1
1533 || (VG_(sanity_level) == 1 && (VG_(sanity_fast_count) % 25) == 0)) {
1534
1535 VG_(sanity_slow_count)++;
1536
1537# if 0
1538 { void zzzmemscan(void); zzzmemscan(); }
1539# endif
1540
1541 if ((VG_(sanity_fast_count) % 250) == 0)
1542 VG_(sanity_check_tc_tt)();
1543
1544 if (VG_(needs).sanity_checks) {
1545 vg_assert(SK_(expensive_sanity_check)());
1546 }
1547 /*
1548 if ((VG_(sanity_fast_count) % 500) == 0) VG_(mallocSanityCheckAll)();
1549 */
1550 }
1551
1552 if (VG_(sanity_level) > 1) {
1553 /* Check sanity of the low-level memory manager. Note that bugs
1554 in the client's code can cause this to fail, so we don't do
1555 this check unless specially asked for. And because it's
1556 potentially very expensive. */
1557 VG_(mallocSanityCheckAll)();
1558 }
1559}
sewardjde4a1d02002-03-22 01:27:54 +00001560/*--------------------------------------------------------------------*/
1561/*--- end vg_main.c ---*/
1562/*--------------------------------------------------------------------*/