blob: b1a74a4b09f154f97122eb677ff50ee6745e0e20 [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/*
njnc9539842002-10-02 13:26:35 +00008 This file is part of Valgrind, an extensible x86 protected-mode
9 emulator for monitoring program execution on x86-Unixes.
sewardjde4a1d02002-03-22 01:27:54 +000010
nethercotebb1c9912004-01-04 16:43:23 +000011 Copyright (C) 2000-2004 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000012 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
fitzhardingeb727d042004-01-06 00:18:21 +000034#include <stdlib.h>
35#include <sys/ptrace.h>
36#include <sys/signal.h>
37#include <sys/user.h>
38#include <sys/wait.h>
39#include <unistd.h>
40
sewardjde4a1d02002-03-22 01:27:54 +000041/* ---------------------------------------------------------------------
42 Compute offsets into baseBlock. See comments in vg_include.h.
43 ------------------------------------------------------------------ */
44
45/* The variables storing offsets. */
46
47#define INVALID_OFFSET (-1)
48
49Int VGOFF_(m_eax) = INVALID_OFFSET;
50Int VGOFF_(m_ecx) = INVALID_OFFSET;
51Int VGOFF_(m_edx) = INVALID_OFFSET;
52Int VGOFF_(m_ebx) = INVALID_OFFSET;
53Int VGOFF_(m_esp) = INVALID_OFFSET;
54Int VGOFF_(m_ebp) = INVALID_OFFSET;
55Int VGOFF_(m_esi) = INVALID_OFFSET;
56Int VGOFF_(m_edi) = INVALID_OFFSET;
57Int VGOFF_(m_eflags) = INVALID_OFFSET;
sewardjfa492d42002-12-08 18:20:01 +000058Int VGOFF_(m_dflag) = INVALID_OFFSET;
sewardjb91ae7f2003-04-29 23:50:00 +000059Int VGOFF_(m_ssestate) = INVALID_OFFSET;
sewardj92a59562002-09-30 00:53:10 +000060Int VGOFF_(ldt) = INVALID_OFFSET;
61Int VGOFF_(m_cs) = INVALID_OFFSET;
62Int VGOFF_(m_ss) = INVALID_OFFSET;
63Int VGOFF_(m_ds) = INVALID_OFFSET;
64Int VGOFF_(m_es) = INVALID_OFFSET;
65Int VGOFF_(m_fs) = INVALID_OFFSET;
66Int VGOFF_(m_gs) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000067Int VGOFF_(m_eip) = INVALID_OFFSET;
68Int VGOFF_(spillslots) = INVALID_OFFSET;
69Int VGOFF_(sh_eax) = INVALID_OFFSET;
70Int VGOFF_(sh_ecx) = INVALID_OFFSET;
71Int VGOFF_(sh_edx) = INVALID_OFFSET;
72Int VGOFF_(sh_ebx) = INVALID_OFFSET;
73Int VGOFF_(sh_esp) = INVALID_OFFSET;
74Int VGOFF_(sh_ebp) = INVALID_OFFSET;
75Int VGOFF_(sh_esi) = INVALID_OFFSET;
76Int VGOFF_(sh_edi) = INVALID_OFFSET;
77Int VGOFF_(sh_eflags) = INVALID_OFFSET;
njn25e49d8e72002-09-23 09:36:25 +000078
sewardjde4a1d02002-03-22 01:27:54 +000079Int VGOFF_(helper_idiv_64_32) = INVALID_OFFSET;
80Int VGOFF_(helper_div_64_32) = INVALID_OFFSET;
81Int VGOFF_(helper_idiv_32_16) = INVALID_OFFSET;
82Int VGOFF_(helper_div_32_16) = INVALID_OFFSET;
83Int VGOFF_(helper_idiv_16_8) = INVALID_OFFSET;
84Int VGOFF_(helper_div_16_8) = INVALID_OFFSET;
85Int VGOFF_(helper_imul_32_64) = INVALID_OFFSET;
86Int VGOFF_(helper_mul_32_64) = INVALID_OFFSET;
87Int VGOFF_(helper_imul_16_32) = INVALID_OFFSET;
88Int VGOFF_(helper_mul_16_32) = INVALID_OFFSET;
89Int VGOFF_(helper_imul_8_16) = INVALID_OFFSET;
90Int VGOFF_(helper_mul_8_16) = INVALID_OFFSET;
91Int VGOFF_(helper_CLD) = INVALID_OFFSET;
92Int VGOFF_(helper_STD) = INVALID_OFFSET;
93Int VGOFF_(helper_get_dirflag) = INVALID_OFFSET;
sewardj7d78e782002-06-02 00:04:00 +000094Int VGOFF_(helper_CLC) = INVALID_OFFSET;
95Int VGOFF_(helper_STC) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000096Int VGOFF_(helper_shldl) = INVALID_OFFSET;
97Int VGOFF_(helper_shldw) = INVALID_OFFSET;
98Int VGOFF_(helper_shrdl) = INVALID_OFFSET;
99Int VGOFF_(helper_shrdw) = INVALID_OFFSET;
daywalkerb18d2532003-09-27 20:15:01 +0000100Int VGOFF_(helper_IN) = INVALID_OFFSET;
101Int VGOFF_(helper_OUT) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +0000102Int VGOFF_(helper_RDTSC) = INVALID_OFFSET;
103Int VGOFF_(helper_CPUID) = INVALID_OFFSET;
104Int VGOFF_(helper_BSWAP) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +0000105Int VGOFF_(helper_bsf) = INVALID_OFFSET;
106Int VGOFF_(helper_bsr) = INVALID_OFFSET;
107Int VGOFF_(helper_fstsw_AX) = INVALID_OFFSET;
108Int VGOFF_(helper_SAHF) = INVALID_OFFSET;
njnd6251f12003-06-03 13:38:51 +0000109Int VGOFF_(helper_LAHF) = INVALID_OFFSET;
sewardj4d0ab1f2002-03-24 10:00:09 +0000110Int VGOFF_(helper_DAS) = INVALID_OFFSET;
sewardjfe8a1662002-03-24 11:54:07 +0000111Int VGOFF_(helper_DAA) = INVALID_OFFSET;
muellerf217c732004-01-02 22:42:29 +0000112Int VGOFF_(helper_cmpxchg8b) = INVALID_OFFSET;
sewardj51096432002-12-14 23:59:09 +0000113Int VGOFF_(helper_undefined_instruction) = INVALID_OFFSET;
njn25e49d8e72002-09-23 09:36:25 +0000114
115/* MAX_NONCOMPACT_HELPERS can be increased easily. If MAX_COMPACT_HELPERS is
116 * increased too much, they won't really be compact any more... */
117#define MAX_COMPACT_HELPERS 8
njnfedb7362003-02-24 10:21:45 +0000118#define MAX_NONCOMPACT_HELPERS 50
njn25e49d8e72002-09-23 09:36:25 +0000119
120UInt VG_(n_compact_helpers) = 0;
121UInt VG_(n_noncompact_helpers) = 0;
122
123Addr VG_(compact_helper_addrs) [MAX_COMPACT_HELPERS];
124Int VG_(compact_helper_offsets)[MAX_COMPACT_HELPERS];
125Addr VG_(noncompact_helper_addrs) [MAX_NONCOMPACT_HELPERS];
126Int VG_(noncompact_helper_offsets)[MAX_NONCOMPACT_HELPERS];
sewardjde4a1d02002-03-22 01:27:54 +0000127
128/* This is the actual defn of baseblock. */
129UInt VG_(baseBlock)[VG_BASEBLOCK_WORDS];
130
fitzhardinge98abfc72003-12-16 02:05:15 +0000131/* Client address space */
132Addr VG_(client_base); /* client address space limits */
133Addr VG_(client_end);
134Addr VG_(client_mapbase);
fitzhardinge92360792003-12-24 10:11:11 +0000135Addr VG_(client_trampoline_code);
fitzhardinge98abfc72003-12-16 02:05:15 +0000136Addr VG_(clstk_base);
137Addr VG_(clstk_end);
138Addr VG_(brk_base); /* start of brk */
139Addr VG_(brk_limit); /* current brk */
140Addr VG_(shadow_base); /* skin's shadow memory */
141Addr VG_(shadow_end);
142Addr VG_(valgrind_base); /* valgrind's address range */
143Addr VG_(valgrind_mmap_end); /* valgrind's mmaps are between valgrind_base and here */
144Addr VG_(valgrind_end);
145
146/* stage1 (main) executable */
fitzhardingea49f9b52003-12-16 22:26:45 +0000147Int VG_(vgexecfd) = -1;
148
149/* client executable */
150Int VG_(clexecfd) = -1;
fitzhardinge98abfc72003-12-16 02:05:15 +0000151
152/* Path to library directory */
153const Char *VG_(libdir) = VG_LIBDIR;
154
155/* our argc/argv */
156Int VG_(vg_argc);
157Char **VG_(vg_argv);
158
jsgf855d93d2003-10-13 22:26:55 +0000159/* PID of the main thread */
160Int VG_(main_pid);
161
162/* PGRP of process */
163Int VG_(main_pgrp);
njn25e49d8e72002-09-23 09:36:25 +0000164
fitzhardingef0046f22003-12-18 02:39:22 +0000165/* Maximum allowed application-visible file descriptor */
fitzhardingeb791a192003-12-18 07:22:44 +0000166Int VG_(max_fd) = -1;
fitzhardingef0046f22003-12-18 02:39:22 +0000167
sewardjde4a1d02002-03-22 01:27:54 +0000168/* Words. */
169static Int baB_off = 0;
170
jsgf855d93d2003-10-13 22:26:55 +0000171/* jmp_buf for fatal signals */
172Int VG_(fatal_sigNo) = -1;
173Bool VG_(fatal_signal_set) = False;
174jmp_buf VG_(fatal_signal_jmpbuf);
175
sewardjde4a1d02002-03-22 01:27:54 +0000176/* Returns the offset, in words. */
177static Int alloc_BaB ( Int words )
178{
179 Int off = baB_off;
180 baB_off += words;
181 if (baB_off >= VG_BASEBLOCK_WORDS)
njne427a662002-10-02 11:08:25 +0000182 VG_(core_panic)( "alloc_BaB: baseBlock is too small");
sewardjde4a1d02002-03-22 01:27:54 +0000183
184 return off;
185}
186
njn0c7a5b52003-04-30 09:00:33 +0000187/* Align offset, in *bytes* */
188static void align_BaB ( UInt align )
189{
190 vg_assert(2 == align || 4 == align || 8 == align || 16 == align);
191 baB_off += (align-1);
192 baB_off &= ~(align-1);
193}
194
sewardjde4a1d02002-03-22 01:27:54 +0000195/* Allocate 1 word in baseBlock and set it to the given value. */
daywalkerb106c422003-09-29 10:56:24 +0000196static Int alloc_BaB_1_set ( Addr a )
sewardjde4a1d02002-03-22 01:27:54 +0000197{
198 Int off = alloc_BaB(1);
199 VG_(baseBlock)[off] = (UInt)a;
200 return off;
201}
202
njn25e49d8e72002-09-23 09:36:25 +0000203/* Registers a function in compact_helper_addrs; compact_helper_offsets is
njn9b007f62003-04-07 14:40:25 +0000204 filled in later. */
njn25e49d8e72002-09-23 09:36:25 +0000205void VG_(register_compact_helper)(Addr a)
206{
207 if (MAX_COMPACT_HELPERS <= VG_(n_compact_helpers)) {
208 VG_(printf)("Can only register %d compact helpers\n",
209 MAX_COMPACT_HELPERS);
njne427a662002-10-02 11:08:25 +0000210 VG_(core_panic)("Too many compact helpers registered");
njn25e49d8e72002-09-23 09:36:25 +0000211 }
212 VG_(compact_helper_addrs)[VG_(n_compact_helpers)] = a;
213 VG_(n_compact_helpers)++;
214}
215
216/* Registers a function in noncompact_helper_addrs; noncompact_helper_offsets
217 * is filled in later.
218 */
219void VG_(register_noncompact_helper)(Addr a)
220{
221 if (MAX_NONCOMPACT_HELPERS <= VG_(n_noncompact_helpers)) {
222 VG_(printf)("Can only register %d non-compact helpers\n",
223 MAX_NONCOMPACT_HELPERS);
224 VG_(printf)("Try increasing MAX_NON_COMPACT_HELPERS\n");
njne427a662002-10-02 11:08:25 +0000225 VG_(core_panic)("Too many non-compact helpers registered");
njn25e49d8e72002-09-23 09:36:25 +0000226 }
227 VG_(noncompact_helper_addrs)[VG_(n_noncompact_helpers)] = a;
228 VG_(n_noncompact_helpers)++;
229}
230
231/* Allocate offsets in baseBlock for the skin helpers */
sewardj05bcdcb2003-05-18 10:05:38 +0000232static
233void assign_helpers_in_baseBlock(UInt n, Int offsets[], Addr addrs[])
njn25e49d8e72002-09-23 09:36:25 +0000234{
sewardj05bcdcb2003-05-18 10:05:38 +0000235 UInt i;
236 for (i = 0; i < n; i++)
daywalkerb106c422003-09-29 10:56:24 +0000237 offsets[i] = alloc_BaB_1_set( addrs[i] );
njn25e49d8e72002-09-23 09:36:25 +0000238}
sewardjde4a1d02002-03-22 01:27:54 +0000239
njnf4ce3d32003-02-10 10:17:26 +0000240Bool VG_(need_to_handle_esp_assignment)(void)
241{
fitzhardinge98abfc72003-12-16 02:05:15 +0000242 return ( VG_(defined_new_mem_stack_4)() ||
243 VG_(defined_die_mem_stack_4)() ||
244 VG_(defined_new_mem_stack_8)() ||
245 VG_(defined_die_mem_stack_8)() ||
246 VG_(defined_new_mem_stack_12)() ||
247 VG_(defined_die_mem_stack_12)() ||
248 VG_(defined_new_mem_stack_16)() ||
249 VG_(defined_die_mem_stack_16)() ||
250 VG_(defined_new_mem_stack_32)() ||
251 VG_(defined_die_mem_stack_32)() ||
252 VG_(defined_new_mem_stack)() ||
253 VG_(defined_die_mem_stack)()
njn9b007f62003-04-07 14:40:25 +0000254 );
njnf4ce3d32003-02-10 10:17:26 +0000255}
256
sewardjde4a1d02002-03-22 01:27:54 +0000257/* Here we assign actual offsets. It's important to get the most
258 popular referents within 128 bytes of the start, so we can take
259 advantage of short addressing modes relative to %ebp. Popularity
260 of offsets was measured on 22 Feb 02 running a KDE application, and
261 the slots rearranged accordingly, with a 1.5% reduction in total
262 size of translations. */
sewardjde4a1d02002-03-22 01:27:54 +0000263static void vg_init_baseBlock ( void )
264{
sewardjde4a1d02002-03-22 01:27:54 +0000265 /* Those with offsets under 128 are carefully chosen. */
266
267 /* WORD offsets in this column */
268 /* 0 */ VGOFF_(m_eax) = alloc_BaB(1);
269 /* 1 */ VGOFF_(m_ecx) = alloc_BaB(1);
270 /* 2 */ VGOFF_(m_edx) = alloc_BaB(1);
271 /* 3 */ VGOFF_(m_ebx) = alloc_BaB(1);
272 /* 4 */ VGOFF_(m_esp) = alloc_BaB(1);
273 /* 5 */ VGOFF_(m_ebp) = alloc_BaB(1);
274 /* 6 */ VGOFF_(m_esi) = alloc_BaB(1);
275 /* 7 */ VGOFF_(m_edi) = alloc_BaB(1);
276 /* 8 */ VGOFF_(m_eflags) = alloc_BaB(1);
277
njn25e49d8e72002-09-23 09:36:25 +0000278 if (VG_(needs).shadow_regs) {
279 /* 9 */ VGOFF_(sh_eax) = alloc_BaB(1);
280 /* 10 */ VGOFF_(sh_ecx) = alloc_BaB(1);
281 /* 11 */ VGOFF_(sh_edx) = alloc_BaB(1);
282 /* 12 */ VGOFF_(sh_ebx) = alloc_BaB(1);
283 /* 13 */ VGOFF_(sh_esp) = alloc_BaB(1);
284 /* 14 */ VGOFF_(sh_ebp) = alloc_BaB(1);
285 /* 15 */ VGOFF_(sh_esi) = alloc_BaB(1);
286 /* 16 */ VGOFF_(sh_edi) = alloc_BaB(1);
287 /* 17 */ VGOFF_(sh_eflags) = alloc_BaB(1);
288 }
sewardjde4a1d02002-03-22 01:27:54 +0000289
njn25e49d8e72002-09-23 09:36:25 +0000290 /* 9,10,11 or 18,19,20... depends on number whether shadow regs are used
291 * and on compact helpers registered */
njn4f9c9342002-04-29 16:03:24 +0000292
njn9b007f62003-04-07 14:40:25 +0000293 /* Make these most-frequently-called specialised ones compact, if they
294 are used. */
fitzhardinge98abfc72003-12-16 02:05:15 +0000295 if (VG_(defined_new_mem_stack_4)())
296 VG_(register_compact_helper)( (Addr) VG_(tool_interface).track_new_mem_stack_4);
sewardjde4a1d02002-03-22 01:27:54 +0000297
fitzhardinge98abfc72003-12-16 02:05:15 +0000298 if (VG_(defined_die_mem_stack_4)())
299 VG_(register_compact_helper)( (Addr) VG_(tool_interface).track_die_mem_stack_4);
njn9b007f62003-04-07 14:40:25 +0000300
301 /* (9 or 18) + n_compact_helpers */
njn25e49d8e72002-09-23 09:36:25 +0000302 /* Allocate slots for compact helpers */
303 assign_helpers_in_baseBlock(VG_(n_compact_helpers),
304 VG_(compact_helper_offsets),
305 VG_(compact_helper_addrs));
sewardjde4a1d02002-03-22 01:27:54 +0000306
njn25e49d8e72002-09-23 09:36:25 +0000307 /* (9/10 or 18/19) + n_compact_helpers */
sewardjde4a1d02002-03-22 01:27:54 +0000308 VGOFF_(m_eip) = alloc_BaB(1);
309
310 /* There are currently 24 spill slots */
njn25e49d8e72002-09-23 09:36:25 +0000311 /* (11+/20+ .. 32+/43+) + n_compact_helpers. This can overlap the magic
312 * boundary at >= 32 words, but most spills are to low numbered spill
313 * slots, so the ones above the boundary don't see much action. */
sewardjde4a1d02002-03-22 01:27:54 +0000314 VGOFF_(spillslots) = alloc_BaB(VG_MAX_SPILLSLOTS);
315
njn25e49d8e72002-09-23 09:36:25 +0000316 /* I gave up counting at this point. Since they're above the
sewardjde4a1d02002-03-22 01:27:54 +0000317 short-amode-boundary, there's no point. */
318
sewardjfa492d42002-12-08 18:20:01 +0000319 VGOFF_(m_dflag) = alloc_BaB(1);
320
sewardjb91ae7f2003-04-29 23:50:00 +0000321 /* The FPU/SSE state. This _must_ be 16-byte aligned. */
njn0c7a5b52003-04-30 09:00:33 +0000322 align_BaB(16);
sewardjb91ae7f2003-04-29 23:50:00 +0000323 VGOFF_(m_ssestate) = alloc_BaB(VG_SIZE_OF_SSESTATE_W);
324 vg_assert(
325 ( ((UInt)(& VG_(baseBlock)[VGOFF_(m_ssestate)]))
326 % 16 )
327 == 0
328 );
sewardjde4a1d02002-03-22 01:27:54 +0000329
sewardj92a59562002-09-30 00:53:10 +0000330 /* This thread's LDT pointer, and segment registers. */
331 VGOFF_(ldt) = alloc_BaB(1);
332 VGOFF_(m_cs) = alloc_BaB(1);
333 VGOFF_(m_ss) = alloc_BaB(1);
334 VGOFF_(m_ds) = alloc_BaB(1);
335 VGOFF_(m_es) = alloc_BaB(1);
336 VGOFF_(m_fs) = alloc_BaB(1);
337 VGOFF_(m_gs) = alloc_BaB(1);
338
sewardje1042472002-09-30 12:33:11 +0000339 VG_(register_noncompact_helper)( (Addr) & VG_(do_useseg) );
340
njn9b007f62003-04-07 14:40:25 +0000341#define REG(kind, size) \
fitzhardinge98abfc72003-12-16 02:05:15 +0000342 if (VG_(defined_##kind##_mem_stack##size)()) \
njn9b007f62003-04-07 14:40:25 +0000343 VG_(register_noncompact_helper)( \
fitzhardinge98abfc72003-12-16 02:05:15 +0000344 (Addr) VG_(tool_interface).track_##kind##_mem_stack##size );
njn9b007f62003-04-07 14:40:25 +0000345
346 REG(new, _8);
347 REG(new, _12);
348 REG(new, _16);
349 REG(new, _32);
350 REG(new, );
351 REG(die, _8);
352 REG(die, _12);
353 REG(die, _16);
354 REG(die, _32);
355 REG(die, );
356#undef REG
357
358 if (VG_(need_to_handle_esp_assignment)())
359 VG_(register_noncompact_helper)((Addr) VG_(unknown_esp_update));
360
sewardj92a59562002-09-30 00:53:10 +0000361 /* Helper functions. */
sewardjde4a1d02002-03-22 01:27:54 +0000362 VGOFF_(helper_idiv_64_32)
daywalkerb106c422003-09-29 10:56:24 +0000363 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_64_32));
sewardjde4a1d02002-03-22 01:27:54 +0000364 VGOFF_(helper_div_64_32)
daywalkerb106c422003-09-29 10:56:24 +0000365 = alloc_BaB_1_set( (Addr) & VG_(helper_div_64_32));
sewardjde4a1d02002-03-22 01:27:54 +0000366 VGOFF_(helper_idiv_32_16)
daywalkerb106c422003-09-29 10:56:24 +0000367 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_32_16));
sewardjde4a1d02002-03-22 01:27:54 +0000368 VGOFF_(helper_div_32_16)
daywalkerb106c422003-09-29 10:56:24 +0000369 = alloc_BaB_1_set( (Addr) & VG_(helper_div_32_16));
sewardjde4a1d02002-03-22 01:27:54 +0000370 VGOFF_(helper_idiv_16_8)
daywalkerb106c422003-09-29 10:56:24 +0000371 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_16_8));
sewardjde4a1d02002-03-22 01:27:54 +0000372 VGOFF_(helper_div_16_8)
daywalkerb106c422003-09-29 10:56:24 +0000373 = alloc_BaB_1_set( (Addr) & VG_(helper_div_16_8));
sewardjde4a1d02002-03-22 01:27:54 +0000374
375 VGOFF_(helper_imul_32_64)
daywalkerb106c422003-09-29 10:56:24 +0000376 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_32_64));
sewardjde4a1d02002-03-22 01:27:54 +0000377 VGOFF_(helper_mul_32_64)
daywalkerb106c422003-09-29 10:56:24 +0000378 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_32_64));
sewardjde4a1d02002-03-22 01:27:54 +0000379 VGOFF_(helper_imul_16_32)
daywalkerb106c422003-09-29 10:56:24 +0000380 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_16_32));
sewardjde4a1d02002-03-22 01:27:54 +0000381 VGOFF_(helper_mul_16_32)
daywalkerb106c422003-09-29 10:56:24 +0000382 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_16_32));
sewardjde4a1d02002-03-22 01:27:54 +0000383 VGOFF_(helper_imul_8_16)
daywalkerb106c422003-09-29 10:56:24 +0000384 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_8_16));
sewardjde4a1d02002-03-22 01:27:54 +0000385 VGOFF_(helper_mul_8_16)
daywalkerb106c422003-09-29 10:56:24 +0000386 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_8_16));
sewardjde4a1d02002-03-22 01:27:54 +0000387
388 VGOFF_(helper_CLD)
daywalkerb106c422003-09-29 10:56:24 +0000389 = alloc_BaB_1_set( (Addr) & VG_(helper_CLD));
sewardjde4a1d02002-03-22 01:27:54 +0000390 VGOFF_(helper_STD)
daywalkerb106c422003-09-29 10:56:24 +0000391 = alloc_BaB_1_set( (Addr) & VG_(helper_STD));
sewardjde4a1d02002-03-22 01:27:54 +0000392 VGOFF_(helper_get_dirflag)
daywalkerb106c422003-09-29 10:56:24 +0000393 = alloc_BaB_1_set( (Addr) & VG_(helper_get_dirflag));
sewardjde4a1d02002-03-22 01:27:54 +0000394
sewardj7d78e782002-06-02 00:04:00 +0000395 VGOFF_(helper_CLC)
daywalkerb106c422003-09-29 10:56:24 +0000396 = alloc_BaB_1_set( (Addr) & VG_(helper_CLC));
sewardj73cf3bc2002-11-03 03:20:15 +0000397 VGOFF_(helper_STC)
daywalkerb106c422003-09-29 10:56:24 +0000398 = alloc_BaB_1_set( (Addr) & VG_(helper_STC));
sewardj7d78e782002-06-02 00:04:00 +0000399
sewardjde4a1d02002-03-22 01:27:54 +0000400 VGOFF_(helper_shldl)
daywalkerb106c422003-09-29 10:56:24 +0000401 = alloc_BaB_1_set( (Addr) & VG_(helper_shldl));
sewardjde4a1d02002-03-22 01:27:54 +0000402 VGOFF_(helper_shldw)
daywalkerb106c422003-09-29 10:56:24 +0000403 = alloc_BaB_1_set( (Addr) & VG_(helper_shldw));
sewardjde4a1d02002-03-22 01:27:54 +0000404 VGOFF_(helper_shrdl)
daywalkerb106c422003-09-29 10:56:24 +0000405 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdl));
sewardjde4a1d02002-03-22 01:27:54 +0000406 VGOFF_(helper_shrdw)
daywalkerb106c422003-09-29 10:56:24 +0000407 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdw));
sewardjde4a1d02002-03-22 01:27:54 +0000408
409 VGOFF_(helper_RDTSC)
daywalkerb106c422003-09-29 10:56:24 +0000410 = alloc_BaB_1_set( (Addr) & VG_(helper_RDTSC));
sewardjde4a1d02002-03-22 01:27:54 +0000411 VGOFF_(helper_CPUID)
daywalkerb106c422003-09-29 10:56:24 +0000412 = alloc_BaB_1_set( (Addr) & VG_(helper_CPUID));
sewardjde4a1d02002-03-22 01:27:54 +0000413
sewardjde4a1d02002-03-22 01:27:54 +0000414 VGOFF_(helper_bsf)
daywalkerb106c422003-09-29 10:56:24 +0000415 = alloc_BaB_1_set( (Addr) & VG_(helper_bsf));
sewardjde4a1d02002-03-22 01:27:54 +0000416 VGOFF_(helper_bsr)
daywalkerb106c422003-09-29 10:56:24 +0000417 = alloc_BaB_1_set( (Addr) & VG_(helper_bsr));
sewardjde4a1d02002-03-22 01:27:54 +0000418
419 VGOFF_(helper_fstsw_AX)
daywalkerb106c422003-09-29 10:56:24 +0000420 = alloc_BaB_1_set( (Addr) & VG_(helper_fstsw_AX));
sewardjde4a1d02002-03-22 01:27:54 +0000421 VGOFF_(helper_SAHF)
daywalkerb106c422003-09-29 10:56:24 +0000422 = alloc_BaB_1_set( (Addr) & VG_(helper_SAHF));
njnd6251f12003-06-03 13:38:51 +0000423 VGOFF_(helper_LAHF)
daywalkerb106c422003-09-29 10:56:24 +0000424 = alloc_BaB_1_set( (Addr) & VG_(helper_LAHF));
sewardj4d0ab1f2002-03-24 10:00:09 +0000425 VGOFF_(helper_DAS)
daywalkerb106c422003-09-29 10:56:24 +0000426 = alloc_BaB_1_set( (Addr) & VG_(helper_DAS));
sewardjfe8a1662002-03-24 11:54:07 +0000427 VGOFF_(helper_DAA)
daywalkerb106c422003-09-29 10:56:24 +0000428 = alloc_BaB_1_set( (Addr) & VG_(helper_DAA));
daywalkerb18d2532003-09-27 20:15:01 +0000429 VGOFF_(helper_IN)
daywalkerb106c422003-09-29 10:56:24 +0000430 = alloc_BaB_1_set( (Addr) & VG_(helper_IN));
daywalkerb18d2532003-09-27 20:15:01 +0000431 VGOFF_(helper_OUT)
daywalkerb106c422003-09-29 10:56:24 +0000432 = alloc_BaB_1_set( (Addr) & VG_(helper_OUT));
muellerf217c732004-01-02 22:42:29 +0000433 VGOFF_(helper_cmpxchg8b)
434 = alloc_BaB_1_set( (Addr) & VG_(helper_cmpxchg8b));
njn25e49d8e72002-09-23 09:36:25 +0000435
sewardj51096432002-12-14 23:59:09 +0000436 VGOFF_(helper_undefined_instruction)
daywalkerb106c422003-09-29 10:56:24 +0000437 = alloc_BaB_1_set( (Addr) & VG_(helper_undefined_instruction));
sewardj51096432002-12-14 23:59:09 +0000438
sewardj92a59562002-09-30 00:53:10 +0000439 /* Allocate slots for noncompact helpers */
njn25e49d8e72002-09-23 09:36:25 +0000440 assign_helpers_in_baseBlock(VG_(n_noncompact_helpers),
441 VG_(noncompact_helper_offsets),
442 VG_(noncompact_helper_addrs));
njn25e49d8e72002-09-23 09:36:25 +0000443
njncc7bb472002-10-14 09:25:19 +0000444
445 /* Initialise slots that require it */
446 VG_(copy_m_state_static_to_baseBlock)();
447
448 /* Pretend the root thread has a completely empty LDT to start with. */
449 VG_(baseBlock)[VGOFF_(ldt)] = (UInt)NULL;
450
451 /* Initialise shadow regs */
njn25e49d8e72002-09-23 09:36:25 +0000452 if (VG_(needs).shadow_regs) {
njn25e49d8e72002-09-23 09:36:25 +0000453 VG_(baseBlock)[VGOFF_(sh_esp)] =
454 VG_(baseBlock)[VGOFF_(sh_ebp)] =
455 VG_(baseBlock)[VGOFF_(sh_eax)] =
456 VG_(baseBlock)[VGOFF_(sh_ecx)] =
457 VG_(baseBlock)[VGOFF_(sh_edx)] =
458 VG_(baseBlock)[VGOFF_(sh_ebx)] =
459 VG_(baseBlock)[VGOFF_(sh_esi)] =
njnd3040452003-05-19 15:04:06 +0000460 VG_(baseBlock)[VGOFF_(sh_edi)] = 0;
461 VG_(baseBlock)[VGOFF_(sh_eflags)] = 0;
462 VG_TRACK( post_regs_write_init );
njncc7bb472002-10-14 09:25:19 +0000463 }
sewardjde4a1d02002-03-22 01:27:54 +0000464}
465
466
467/* ---------------------------------------------------------------------
468 Global entities which are not referenced from generated code.
469 ------------------------------------------------------------------ */
470
sewardjde4a1d02002-03-22 01:27:54 +0000471/* Ditto our signal delivery stack. */
njn6eba4ef2003-05-01 08:06:41 +0000472UInt VG_(sigstack)[VG_SIGSTACK_SIZE_W];
sewardjde4a1d02002-03-22 01:27:54 +0000473
474/* Saving stuff across system calls. */
sewardjb91ae7f2003-04-29 23:50:00 +0000475__attribute__ ((aligned (16)))
476UInt VG_(real_sse_state_saved_over_syscall)[VG_SIZE_OF_SSESTATE_W];
sewardj43c356f2002-06-02 00:21:08 +0000477Addr VG_(esp_saved_over_syscall);
sewardjde4a1d02002-03-22 01:27:54 +0000478
479/* Counts downwards in vg_run_innerloop. */
480UInt VG_(dispatch_ctr);
481
sewardjde4a1d02002-03-22 01:27:54 +0000482
483/* 64-bit counter for the number of basic blocks done. */
484ULong VG_(bbs_done);
485/* 64-bit counter for the number of bbs to go before a debug exit. */
486ULong VG_(bbs_to_go);
487
sewardj7e87e382002-05-03 19:09:05 +0000488/* This is the ThreadId of the last thread the scheduler ran. */
489ThreadId VG_(last_run_tid) = 0;
490
njn25e49d8e72002-09-23 09:36:25 +0000491/* This is the argument to __NR_exit() supplied by the first thread to
492 call that syscall. We eventually pass that to __NR_exit() for
493 real. */
njn633de322003-05-12 20:40:13 +0000494Int VG_(exitcode) = 0;
njn25e49d8e72002-09-23 09:36:25 +0000495
sewardj73cf3bc2002-11-03 03:20:15 +0000496/* Tell the logging mechanism whether we are logging to a file
497 descriptor or a socket descriptor. */
498Bool VG_(logging_to_filedes) = True;
499
sewardjb91ae7f2003-04-29 23:50:00 +0000500/* Is this a SSE/SSE2-capable CPU? If so, we had better save/restore
501 the SSE state all over the place. This is set up very early, in
502 vg_startup.S. We have to determine it early since we can't even
503 correctly snapshot the startup machine state without it. */
504/* Initially True. Safer to err on the side of SSEness and get SIGILL
daywalker7e73e5f2003-07-04 16:18:15 +0000505 than to not notice for some reason that we have SSE and get weird
sewardjb91ae7f2003-04-29 23:50:00 +0000506 errors later on. */
507Bool VG_(have_ssestate) = True;
508
sewardjde4a1d02002-03-22 01:27:54 +0000509
510/* ---------------------------------------------------------------------
511 Counters, for informational purposes only.
512 ------------------------------------------------------------------ */
513
514/* Number of lookups which miss the fast tt helper. */
515UInt VG_(tt_fast_misses) = 0;
516
517
sewardjc0d8f682002-11-30 00:49:43 +0000518/* Counts for TT/TC informational messages. */
sewardjde4a1d02002-03-22 01:27:54 +0000519
sewardjde4a1d02002-03-22 01:27:54 +0000520/* Number and total o/t size of translations overall. */
521UInt VG_(overall_in_count) = 0;
522UInt VG_(overall_in_osize) = 0;
523UInt VG_(overall_in_tsize) = 0;
524/* Number and total o/t size of discards overall. */
525UInt VG_(overall_out_count) = 0;
526UInt VG_(overall_out_osize) = 0;
527UInt VG_(overall_out_tsize) = 0;
sewardjc0d8f682002-11-30 00:49:43 +0000528/* The number of discards of TT/TC. */
529UInt VG_(number_of_tc_discards) = 0;
sewardj22854b92002-11-30 14:00:47 +0000530/* Counts of chain and unchain operations done. */
531UInt VG_(bb_enchain_count) = 0;
532UInt VG_(bb_dechain_count) = 0;
533/* Number of unchained jumps performed. */
534UInt VG_(unchained_jumps_done) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000535
536
537/* Counts pertaining to the register allocator. */
538
539/* total number of uinstrs input to reg-alloc */
540UInt VG_(uinstrs_prealloc) = 0;
541
542/* total number of uinstrs added due to spill code */
543UInt VG_(uinstrs_spill) = 0;
544
545/* number of bbs requiring spill code */
546UInt VG_(translations_needing_spill) = 0;
547
548/* total of register ranks over all translations */
549UInt VG_(total_reg_rank) = 0;
550
551
sewardjde4a1d02002-03-22 01:27:54 +0000552/* Counts pertaining to internal sanity checking. */
sewardjde4a1d02002-03-22 01:27:54 +0000553UInt VG_(sanity_fast_count) = 0;
554UInt VG_(sanity_slow_count) = 0;
555
sewardj2e93c502002-04-12 11:12:52 +0000556/* Counts pertaining to the scheduler. */
557UInt VG_(num_scheduling_events_MINOR) = 0;
558UInt VG_(num_scheduling_events_MAJOR) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000559
560
561/* ---------------------------------------------------------------------
562 Values derived from command-line options.
563 ------------------------------------------------------------------ */
564
njn25e49d8e72002-09-23 09:36:25 +0000565/* Define, and set defaults. */
566Bool VG_(clo_error_limit) = True;
567Bool VG_(clo_GDB_attach) = False;
sewardj6024b212003-07-13 10:54:33 +0000568Char* VG_(clo_GDB_path) = GDB_PATH;
njn43c799e2003-04-08 00:08:52 +0000569Bool VG_(clo_gen_suppressions) = False;
njn25e49d8e72002-09-23 09:36:25 +0000570Int VG_(sanity_level) = 1;
571Int VG_(clo_verbosity) = 1;
572Bool VG_(clo_demangle) = True;
njn25e49d8e72002-09-23 09:36:25 +0000573Bool VG_(clo_trace_children) = False;
sewardj4cf05692002-10-27 20:28:29 +0000574
nethercotee1730692003-11-20 10:38:07 +0000575/* See big comment in vg_include.h for meaning of these three.
576 fd is initially stdout, for --help, but gets moved to stderr by default
577 immediately afterwards. */
sewardj4cf05692002-10-27 20:28:29 +0000578VgLogTo VG_(clo_log_to) = VgLogTo_Fd;
nethercotee1730692003-11-20 10:38:07 +0000579Int VG_(clo_logfile_fd) = 1;
sewardj4cf05692002-10-27 20:28:29 +0000580Char* VG_(clo_logfile_name) = NULL;
581
sewardj6024b212003-07-13 10:54:33 +0000582Int VG_(clo_input_fd) = 0; /* stdin */
njn25e49d8e72002-09-23 09:36:25 +0000583Int VG_(clo_n_suppressions) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000584Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
njn25e49d8e72002-09-23 09:36:25 +0000585Bool VG_(clo_profile) = False;
586Bool VG_(clo_single_step) = False;
587Bool VG_(clo_optimise) = True;
588UChar VG_(clo_trace_codegen) = 0; // 00000000b
589Bool VG_(clo_trace_syscalls) = False;
590Bool VG_(clo_trace_signals) = False;
591Bool VG_(clo_trace_symtab) = False;
njn25e49d8e72002-09-23 09:36:25 +0000592Bool VG_(clo_trace_sched) = False;
593Int VG_(clo_trace_pthread_level) = 0;
sewardj59438c02003-01-05 12:16:30 +0000594ULong VG_(clo_stop_after) = 1000000000000000LL;
njn25e49d8e72002-09-23 09:36:25 +0000595Int VG_(clo_dump_error) = 0;
596Int VG_(clo_backtrace_size) = 4;
597Char* VG_(clo_weird_hacks) = NULL;
sewardj858964b2002-10-05 14:15:43 +0000598Bool VG_(clo_run_libc_freeres) = True;
rjwalshf5f536f2003-11-17 17:45:00 +0000599Bool VG_(clo_track_fds) = False;
sewardj22854b92002-11-30 14:00:47 +0000600Bool VG_(clo_chain_bb) = True;
nethercote77eba602003-11-13 17:35:04 +0000601Bool VG_(clo_show_below_main) = False;
fitzhardinge98abfc72003-12-16 02:05:15 +0000602Bool VG_(clo_pointercheck) = True;
fitzhardinge462f4f92003-12-18 02:10:54 +0000603Bool VG_(clo_branchpred) = False;
sewardj2370f3b2002-11-30 15:01:01 +0000604
jsgf855d93d2003-10-13 22:26:55 +0000605static Bool VG_(clo_wait_for_gdb) = False;
606
607/* If we're doing signal routing, poll for signals every 50mS by
608 default. */
609Int VG_(clo_signal_polltime) = 50;
610
611/* These flags reduce thread wakeup latency on syscall completion and
612 signal delivery, respectively. The downside is possible unfairness. */
613Bool VG_(clo_lowlat_syscalls) = False; /* low-latency syscalls */
614Bool VG_(clo_lowlat_signals) = False; /* low-latency signals */
615
sewardjde4a1d02002-03-22 01:27:54 +0000616/* This Bool is needed by wrappers in vg_clientmalloc.c to decide how
617 to behave. Initially we say False. */
618Bool VG_(running_on_simd_CPU) = False;
619
620/* Holds client's %esp at the point we gained control. */
621Addr VG_(esp_at_startup);
622
sewardjd5815ec2003-04-06 12:23:27 +0000623/* Indicates presence, and holds address of client's sysinfo page, a
624 feature of some modern kernels used to provide vsyscalls, etc. */
625Bool VG_(sysinfo_page_exists) = False;
626Addr VG_(sysinfo_page_addr) = 0;
627
sewardjde4a1d02002-03-22 01:27:54 +0000628/* As deduced from VG_(esp_at_startup), the client's argc, argv[] and
629 envp[] as extracted from the client's stack at startup-time. */
630Int VG_(client_argc);
631Char** VG_(client_argv);
632Char** VG_(client_envp);
633
sewardjde4a1d02002-03-22 01:27:54 +0000634/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000635 Processing of command-line options.
636 ------------------------------------------------------------------ */
637
njn25e49d8e72002-09-23 09:36:25 +0000638void VG_(bad_option) ( Char* opt )
sewardjde4a1d02002-03-22 01:27:54 +0000639{
640 VG_(shutdown_logging)();
sewardj4cf05692002-10-27 20:28:29 +0000641 VG_(clo_log_to) = VgLogTo_Fd;
sewardjde4a1d02002-03-22 01:27:54 +0000642 VG_(clo_logfile_fd) = 2; /* stderr */
643 VG_(printf)("valgrind.so: Bad option `%s'; aborting.\n", opt);
644 VG_(exit)(1);
645}
646
647static void config_error ( Char* msg )
648{
649 VG_(shutdown_logging)();
sewardj4cf05692002-10-27 20:28:29 +0000650 VG_(clo_log_to) = VgLogTo_Fd;
sewardjde4a1d02002-03-22 01:27:54 +0000651 VG_(clo_logfile_fd) = 2; /* stderr */
sewardj19d81412002-06-03 01:10:40 +0000652 VG_(printf)(
fitzhardinge98abfc72003-12-16 02:05:15 +0000653 "valgrind: Startup or configuration error:\n %s\n", msg);
sewardj19d81412002-06-03 01:10:40 +0000654 VG_(printf)(
fitzhardinge98abfc72003-12-16 02:05:15 +0000655 "valgrind: Unable to start up properly. Giving up.\n");
sewardjde4a1d02002-03-22 01:27:54 +0000656 VG_(exit)(1);
657}
658
fitzhardinge98abfc72003-12-16 02:05:15 +0000659void VG_(usage) ( void )
njn7cf0bd32002-06-08 13:36:03 +0000660{
njn25e49d8e72002-09-23 09:36:25 +0000661 Char* usage1 =
662"usage: valgrind [options] prog-and-args\n"
663"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000664" common user options for all Valgrind tools, with defaults in [ ]:\n"
nethercote137bc552003-11-14 17:47:54 +0000665" --tool=<name> Use the Valgrind tool named <name> [memcheck]\n"
njn25e49d8e72002-09-23 09:36:25 +0000666" --help show this message\n"
667" --version show version\n"
njn25e49d8e72002-09-23 09:36:25 +0000668" -q --quiet run silently; only print error msgs\n"
669" -v --verbose be more verbose, incl counts of errors\n"
nethercote77eba602003-11-13 17:35:04 +0000670" --trace-children=no|yes Valgrind-ise child processes? [no]\n"
rjwalshf5f536f2003-11-17 17:45:00 +0000671" --track-fds=no|yes Track open file descriptors? [no]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000672"\n"
673" uncommon user options for all Valgrind tools:\n"
nethercote77eba602003-11-13 17:35:04 +0000674" --run-libc-freeres=no|yes Free up glibc memory at exit? [yes]\n"
675" --weird-hacks=hack1,hack2,... [none]\n"
sewardj3d652a32002-10-20 18:11:49 +0000676" recognised hacks are: ioctl-VTIME truncate-writes lax-ioctls\n"
jsgf855d93d2003-10-13 22:26:55 +0000677" --signal-polltime=<time> time, in mS, we should poll for signals.\n"
678" Only applies for older kernels which need\n"
679" signal routing [50]\n"
680" --lowlat-signals=no|yes improve wake-up latency when a thread receives\n"
681" a signal [no]\n"
682" --lowlat-syscalls=no|yes improve wake-up latency when a thread's\n"
683" syscall completes [no]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000684" --pointercheck=no|yes enforce client address space limits [yes]\n"
njn25e49d8e72002-09-23 09:36:25 +0000685"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000686" user options for Valgrind tools that report errors:\n"
687" --logfile-fd=<number> file descriptor for messages [2=stderr]\n"
688" --logfile=<file> log messages to <file>.pid<pid>\n"
689" --logsocket=ipaddr:port log messages to socket ipaddr:port\n"
690" --demangle=no|yes automatically demangle C++ names? [yes]\n"
691" --num-callers=<number> show <num> callers in stack traces [4]\n"
692" --error-limit=no|yes stop showing new errors if too many? [yes]\n"
693" --show-below-main=no|yes continue stack traces below main() [no]\n"
694" --suppressions=<filename> suppress errors described in <filename>\n"
695" --gen-suppressions=no|yes print suppressions for errors detected [no]\n"
njn7cf0bd32002-06-08 13:36:03 +0000696
nethercote2b0793f2003-12-02 10:41:18 +0000697" --gdb-attach=no|yes start GDB when errors detected? [no]\n"
698" --gdb-path=/path/to/gdb path to the GDB to use [/usr/bin/gdb]\n"
699" --input-fd=<number> file descriptor for (gdb) input [0=stdin]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000700"\n";
njn7cf0bd32002-06-08 13:36:03 +0000701
njn25e49d8e72002-09-23 09:36:25 +0000702 Char* usage2 =
703"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000704" debugging options for all Valgrind tools:\n"
njn25e49d8e72002-09-23 09:36:25 +0000705" --sanity-level=<number> level of sanity checking to do [1]\n"
706" --single-step=no|yes translate each instr separately? [no]\n"
707" --optimise=no|yes improve intermediate code? [yes]\n"
nethercote137bc552003-11-14 17:47:54 +0000708" --profile=no|yes profile? (tool must be built for it) [no]\n"
sewardj22854b92002-11-30 14:00:47 +0000709" --chain-bb=no|yes do basic-block chaining? [yes]\n"
fitzhardinge462f4f92003-12-18 02:10:54 +0000710" --branchpred=yes|no generate branch prediction hints [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000711" --trace-codegen=<XXXXX> show generated code? (X = 0|1) [00000]\n"
712" --trace-syscalls=no|yes show all system calls? [no]\n"
713" --trace-signals=no|yes show signal handling details? [no]\n"
714" --trace-symtab=no|yes show symbol table details? [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000715" --trace-sched=no|yes show thread scheduler details? [no]\n"
njn3e884182003-04-15 13:03:23 +0000716" --trace-pthread=none|some|all show pthread event details? [none]\n"
njn25e49d8e72002-09-23 09:36:25 +0000717" --stop-after=<number> switch to real CPU after executing\n"
718" <number> basic blocks [infinity]\n"
jsgf855d93d2003-10-13 22:26:55 +0000719" --wait-for-gdb=yes|no pause on startup to wait for gdb attach\n"
njn25e49d8e72002-09-23 09:36:25 +0000720"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000721" debugging options for Valgrind tools that report errors\n"
722" --dump-error=<number> show translation for basic block associated\n"
723" with <number>'th error context [0=show none]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000724"\n";
njn3e884182003-04-15 13:03:23 +0000725
726 Char* usage3 =
727"\n"
njn25e49d8e72002-09-23 09:36:25 +0000728" Extra options are read from env variable $VALGRIND_OPTS\n"
729"\n"
nethercotebb1c9912004-01-04 16:43:23 +0000730" Valgrind is Copyright (C) 2000-2004 Julian Seward\n"
njn25e49d8e72002-09-23 09:36:25 +0000731" and licensed under the GNU General Public License, version 2.\n"
732" Bug reports, feedback, admiration, abuse, etc, to: %s.\n"
njnd04b7c62002-10-03 14:05:52 +0000733"\n"
nethercote137bc552003-11-14 17:47:54 +0000734" Tools are copyright and licensed by their authors. See each\n"
735" tool's start-up message for more information.\n"
njn25e49d8e72002-09-23 09:36:25 +0000736"\n";
njn7cf0bd32002-06-08 13:36:03 +0000737
fitzhardinge98abfc72003-12-16 02:05:15 +0000738 VG_(printf)(usage1);
739 if (VG_(details).name) {
740 VG_(printf)(" user options for %s:\n", VG_(details).name);
741 /* Don't print skin string directly for security, ha! */
742 if (VG_(needs).command_line_options)
743 SK_(print_usage)();
744 else
745 VG_(printf)(" (none)\n");
746 }
747 VG_(printf)(usage2);
748
749 if (VG_(details).name) {
750 VG_(printf)(" debugging options for %s:\n", VG_(details).name);
751
752 if (VG_(needs).command_line_options)
753 SK_(print_debug_usage)();
754 else
755 VG_(printf)(" (none)\n");
756 }
nethercote421281e2003-11-20 16:20:55 +0000757 VG_(printf)(usage3, VG_BUGS_TO);
njn7cf0bd32002-06-08 13:36:03 +0000758
njn25e49d8e72002-09-23 09:36:25 +0000759 VG_(shutdown_logging)();
sewardj4cf05692002-10-27 20:28:29 +0000760 VG_(clo_log_to) = VgLogTo_Fd;
njn25e49d8e72002-09-23 09:36:25 +0000761 VG_(clo_logfile_fd) = 2; /* stderr */
762 VG_(exit)(1);
njn7cf0bd32002-06-08 13:36:03 +0000763}
sewardjde4a1d02002-03-22 01:27:54 +0000764
sewardj1c1b1162003-02-23 01:25:51 +0000765
fitzhardinge98abfc72003-12-16 02:05:15 +0000766static void process_cmd_line_options ( const KickstartParams *kp )
sewardj1c1b1162003-02-23 01:25:51 +0000767{
fitzhardinge98abfc72003-12-16 02:05:15 +0000768 Int argc;
769 Char **argv;
770 Int i, eventually_logfile_fd;
771 Int *auxp;
sewardjde4a1d02002-03-22 01:27:54 +0000772
773# define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
sewardjde4a1d02002-03-22 01:27:54 +0000774
nethercotee1730692003-11-20 10:38:07 +0000775 /* log to stderr by default, but usage message goes to stdout */
776 eventually_logfile_fd = 2;
sewardjde4a1d02002-03-22 01:27:54 +0000777
778 /* Once logging is started, we can safely send messages pertaining
779 to failures in initialisation. */
780 VG_(startup_logging)();
781
sewardj19d81412002-06-03 01:10:40 +0000782 /* Check for sane path in ./configure --prefix=... */
fitzhardinge98abfc72003-12-16 02:05:15 +0000783 if (VG_LIBDIR[0] != '/')
sewardj19d81412002-06-03 01:10:40 +0000784 config_error("Please use absolute paths in "
785 "./configure --prefix=... or --libdir=...");
sewardj38170912002-05-10 21:07:22 +0000786
fitzhardinge98abfc72003-12-16 02:05:15 +0000787 for(auxp = kp->client_auxv; auxp[0] != VKI_AT_NULL; auxp += 2) {
788 switch(auxp[0]) {
789 case VKI_AT_SYSINFO:
790 VG_(sysinfo_page_exists) = True;
fitzhardinge92360792003-12-24 10:11:11 +0000791 auxp[1] = (Int)(VG_(client_trampoline_code) + VG_(tramp_syscall_offset));
fitzhardinge98abfc72003-12-16 02:05:15 +0000792 VG_(sysinfo_page_addr) = auxp[1];
793 break;
sewardjde4a1d02002-03-22 01:27:54 +0000794 }
fitzhardinge98abfc72003-12-16 02:05:15 +0000795 }
sewardjde4a1d02002-03-22 01:27:54 +0000796
fitzhardinge98abfc72003-12-16 02:05:15 +0000797 VG_(client_envp) = kp->client_envp;
sewardjde4a1d02002-03-22 01:27:54 +0000798
fitzhardinge98abfc72003-12-16 02:05:15 +0000799 argc = kp->argc;
800 argv = kp->argv;
801
802 VG_(vg_argc) = argc;
803 VG_(vg_argv) = argv;
804
805 /* We know the initial ESP is pointing at argc/argv */
806 VG_(client_argc) = *(Int *)kp->client_esp;
807 VG_(client_argv) = (Char **)(kp->client_esp + sizeof(Int));
808
809 for (i = 1; i < argc; i++) {
810 /* Ignore these options - they've already been handled */
811 if (VG_CLO_STREQN(7, argv[i], "--tool=") ||
812 VG_CLO_STREQN(7, argv[i], "--skin="))
813 continue;
814 if (VG_CLO_STREQN(7, argv[i], "--exec="))
815 continue;
816
817 if ( VG_CLO_STREQ(argv[i], "--"))
818 continue;
819 else if (VG_CLO_STREQ(argv[i], "-v") ||
njn43c799e2003-04-08 00:08:52 +0000820 VG_CLO_STREQ(argv[i], "--verbose"))
sewardjde4a1d02002-03-22 01:27:54 +0000821 VG_(clo_verbosity)++;
njn43c799e2003-04-08 00:08:52 +0000822 else if (VG_CLO_STREQ(argv[i], "-q") ||
823 VG_CLO_STREQ(argv[i], "--quiet"))
sewardjde4a1d02002-03-22 01:27:54 +0000824 VG_(clo_verbosity)--;
825
njn43c799e2003-04-08 00:08:52 +0000826 else if (VG_CLO_STREQ(argv[i], "--error-limit=yes"))
sewardj2e432902002-06-13 20:44:00 +0000827 VG_(clo_error_limit) = True;
njn43c799e2003-04-08 00:08:52 +0000828 else if (VG_CLO_STREQ(argv[i], "--error-limit=no"))
sewardj2e432902002-06-13 20:44:00 +0000829 VG_(clo_error_limit) = False;
sewardj72f98ff2002-06-13 17:23:38 +0000830
njn43c799e2003-04-08 00:08:52 +0000831 else if (VG_CLO_STREQ(argv[i], "--gdb-attach=yes"))
sewardjde4a1d02002-03-22 01:27:54 +0000832 VG_(clo_GDB_attach) = True;
njn43c799e2003-04-08 00:08:52 +0000833 else if (VG_CLO_STREQ(argv[i], "--gdb-attach=no"))
sewardjde4a1d02002-03-22 01:27:54 +0000834 VG_(clo_GDB_attach) = False;
835
sewardj6024b212003-07-13 10:54:33 +0000836 else if (VG_CLO_STREQN(11,argv[i], "--gdb-path="))
837 VG_(clo_GDB_path) = &argv[i][11];
838
njn43c799e2003-04-08 00:08:52 +0000839 else if (VG_CLO_STREQ(argv[i], "--gen-suppressions=yes"))
840 VG_(clo_gen_suppressions) = True;
841 else if (VG_CLO_STREQ(argv[i], "--gen-suppressions=no"))
842 VG_(clo_gen_suppressions) = False;
843
nethercote77eba602003-11-13 17:35:04 +0000844 else if (VG_CLO_STREQ(argv[i], "--show-below-main=yes"))
845 VG_(clo_show_below_main) = True;
846 else if (VG_CLO_STREQ(argv[i], "--show-below-main=no"))
847 VG_(clo_show_below_main) = False;
848
fitzhardinge98abfc72003-12-16 02:05:15 +0000849 else if (VG_CLO_STREQ(argv[i], "--pointercheck=yes"))
850 VG_(clo_pointercheck) = True;
851 else if (VG_CLO_STREQ(argv[i], "--pointercheck=no"))
852 VG_(clo_pointercheck) = False;
853
njn43c799e2003-04-08 00:08:52 +0000854 else if (VG_CLO_STREQ(argv[i], "--demangle=yes"))
sewardjde4a1d02002-03-22 01:27:54 +0000855 VG_(clo_demangle) = True;
njn43c799e2003-04-08 00:08:52 +0000856 else if (VG_CLO_STREQ(argv[i], "--demangle=no"))
sewardjde4a1d02002-03-22 01:27:54 +0000857 VG_(clo_demangle) = False;
858
njn43c799e2003-04-08 00:08:52 +0000859 else if (VG_CLO_STREQ(argv[i], "--trace-children=yes"))
sewardjde4a1d02002-03-22 01:27:54 +0000860 VG_(clo_trace_children) = True;
njn43c799e2003-04-08 00:08:52 +0000861 else if (VG_CLO_STREQ(argv[i], "--trace-children=no"))
sewardjde4a1d02002-03-22 01:27:54 +0000862 VG_(clo_trace_children) = False;
863
njn43c799e2003-04-08 00:08:52 +0000864 else if (VG_CLO_STREQ(argv[i], "--run-libc-freeres=yes"))
sewardj858964b2002-10-05 14:15:43 +0000865 VG_(clo_run_libc_freeres) = True;
njn43c799e2003-04-08 00:08:52 +0000866 else if (VG_CLO_STREQ(argv[i], "--run-libc-freeres=no"))
sewardj858964b2002-10-05 14:15:43 +0000867 VG_(clo_run_libc_freeres) = False;
868
rjwalshf5f536f2003-11-17 17:45:00 +0000869 else if (VG_CLO_STREQ(argv[i], "--track-fds=yes"))
870 VG_(clo_track_fds) = True;
871 else if (VG_CLO_STREQ(argv[i], "--track-fds=no"))
872 VG_(clo_track_fds) = False;
873
njn43c799e2003-04-08 00:08:52 +0000874 else if (VG_CLO_STREQN(15, argv[i], "--sanity-level="))
sewardjde4a1d02002-03-22 01:27:54 +0000875 VG_(sanity_level) = (Int)VG_(atoll)(&argv[i][15]);
876
njn43c799e2003-04-08 00:08:52 +0000877 else if (VG_CLO_STREQN(13, argv[i], "--logfile-fd=")) {
sewardj4cf05692002-10-27 20:28:29 +0000878 VG_(clo_log_to) = VgLogTo_Fd;
879 VG_(clo_logfile_name) = NULL;
sewardjde4a1d02002-03-22 01:27:54 +0000880 eventually_logfile_fd = (Int)VG_(atoll)(&argv[i][13]);
sewardj4cf05692002-10-27 20:28:29 +0000881 }
882
njn43c799e2003-04-08 00:08:52 +0000883 else if (VG_CLO_STREQN(10, argv[i], "--logfile=")) {
sewardj4cf05692002-10-27 20:28:29 +0000884 VG_(clo_log_to) = VgLogTo_File;
885 VG_(clo_logfile_name) = &argv[i][10];
886 }
sewardjde4a1d02002-03-22 01:27:54 +0000887
njn43c799e2003-04-08 00:08:52 +0000888 else if (VG_CLO_STREQN(12, argv[i], "--logsocket=")) {
sewardj73cf3bc2002-11-03 03:20:15 +0000889 VG_(clo_log_to) = VgLogTo_Socket;
890 VG_(clo_logfile_name) = &argv[i][12];
891 }
892
sewardj6024b212003-07-13 10:54:33 +0000893 else if (VG_CLO_STREQN(11, argv[i], "--input-fd="))
894 VG_(clo_input_fd) = (Int)VG_(atoll)(&argv[i][11]);
895
njn43c799e2003-04-08 00:08:52 +0000896 else if (VG_CLO_STREQN(15, argv[i], "--suppressions=")) {
sewardjde4a1d02002-03-22 01:27:54 +0000897 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
njn25e49d8e72002-09-23 09:36:25 +0000898 VG_(message)(Vg_UserMsg, "Too many suppression files specified.");
sewardjde4a1d02002-03-22 01:27:54 +0000899 VG_(message)(Vg_UserMsg,
900 "Increase VG_CLO_MAX_SFILES and recompile.");
njn25e49d8e72002-09-23 09:36:25 +0000901 VG_(bad_option)(argv[i]);
sewardjde4a1d02002-03-22 01:27:54 +0000902 }
903 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &argv[i][15];
904 VG_(clo_n_suppressions)++;
905 }
njn43c799e2003-04-08 00:08:52 +0000906 else if (VG_CLO_STREQ(argv[i], "--profile=yes"))
njn25e49d8e72002-09-23 09:36:25 +0000907 VG_(clo_profile) = True;
njn43c799e2003-04-08 00:08:52 +0000908 else if (VG_CLO_STREQ(argv[i], "--profile=no"))
njn25e49d8e72002-09-23 09:36:25 +0000909 VG_(clo_profile) = False;
910
njn43c799e2003-04-08 00:08:52 +0000911 else if (VG_CLO_STREQ(argv[i], "--chain-bb=yes"))
sewardj22854b92002-11-30 14:00:47 +0000912 VG_(clo_chain_bb) = True;
njn43c799e2003-04-08 00:08:52 +0000913 else if (VG_CLO_STREQ(argv[i], "--chain-bb=no"))
sewardj22854b92002-11-30 14:00:47 +0000914 VG_(clo_chain_bb) = False;
915
fitzhardinge462f4f92003-12-18 02:10:54 +0000916 else if (VG_CLO_STREQ(argv[i], "--branchpred=yes"))
917 VG_(clo_branchpred) = True;
918 else if (VG_CLO_STREQ(argv[i], "--branchpred=no"))
919 VG_(clo_branchpred) = False;
920
njn43c799e2003-04-08 00:08:52 +0000921 else if (VG_CLO_STREQ(argv[i], "--single-step=yes"))
sewardjde4a1d02002-03-22 01:27:54 +0000922 VG_(clo_single_step) = True;
njn43c799e2003-04-08 00:08:52 +0000923 else if (VG_CLO_STREQ(argv[i], "--single-step=no"))
sewardjde4a1d02002-03-22 01:27:54 +0000924 VG_(clo_single_step) = False;
925
njn43c799e2003-04-08 00:08:52 +0000926 else if (VG_CLO_STREQ(argv[i], "--optimise=yes"))
sewardjde4a1d02002-03-22 01:27:54 +0000927 VG_(clo_optimise) = True;
njn43c799e2003-04-08 00:08:52 +0000928 else if (VG_CLO_STREQ(argv[i], "--optimise=no"))
sewardjde4a1d02002-03-22 01:27:54 +0000929 VG_(clo_optimise) = False;
930
njn25e49d8e72002-09-23 09:36:25 +0000931 /* "vwxyz" --> 000zyxwv (binary) */
njn43c799e2003-04-08 00:08:52 +0000932 else if (VG_CLO_STREQN(16, argv[i], "--trace-codegen=")) {
njn25e49d8e72002-09-23 09:36:25 +0000933 Int j;
934 char* opt = & argv[i][16];
935
936 if (5 != VG_(strlen)(opt)) {
937 VG_(message)(Vg_UserMsg,
938 "--trace-codegen argument must have 5 digits");
939 VG_(bad_option)(argv[i]);
940 }
941 for (j = 0; j < 5; j++) {
942 if ('0' == opt[j]) { /* do nothing */ }
943 else if ('1' == opt[j]) VG_(clo_trace_codegen) |= (1 << j);
944 else {
945 VG_(message)(Vg_UserMsg, "--trace-codegen argument can only "
946 "contain 0s and 1s");
947 VG_(bad_option)(argv[i]);
948 }
949 }
950 }
sewardjde4a1d02002-03-22 01:27:54 +0000951
njn43c799e2003-04-08 00:08:52 +0000952 else if (VG_CLO_STREQ(argv[i], "--trace-syscalls=yes"))
sewardjde4a1d02002-03-22 01:27:54 +0000953 VG_(clo_trace_syscalls) = True;
njn43c799e2003-04-08 00:08:52 +0000954 else if (VG_CLO_STREQ(argv[i], "--trace-syscalls=no"))
sewardjde4a1d02002-03-22 01:27:54 +0000955 VG_(clo_trace_syscalls) = False;
956
njn43c799e2003-04-08 00:08:52 +0000957 else if (VG_CLO_STREQ(argv[i], "--trace-signals=yes"))
sewardjde4a1d02002-03-22 01:27:54 +0000958 VG_(clo_trace_signals) = True;
njn43c799e2003-04-08 00:08:52 +0000959 else if (VG_CLO_STREQ(argv[i], "--trace-signals=no"))
sewardjde4a1d02002-03-22 01:27:54 +0000960 VG_(clo_trace_signals) = False;
961
njn43c799e2003-04-08 00:08:52 +0000962 else if (VG_CLO_STREQ(argv[i], "--trace-symtab=yes"))
sewardjde4a1d02002-03-22 01:27:54 +0000963 VG_(clo_trace_symtab) = True;
njn43c799e2003-04-08 00:08:52 +0000964 else if (VG_CLO_STREQ(argv[i], "--trace-symtab=no"))
sewardjde4a1d02002-03-22 01:27:54 +0000965 VG_(clo_trace_symtab) = False;
966
njn43c799e2003-04-08 00:08:52 +0000967 else if (VG_CLO_STREQ(argv[i], "--trace-sched=yes"))
sewardj8937c812002-04-12 20:12:20 +0000968 VG_(clo_trace_sched) = True;
njn43c799e2003-04-08 00:08:52 +0000969 else if (VG_CLO_STREQ(argv[i], "--trace-sched=no"))
sewardj8937c812002-04-12 20:12:20 +0000970 VG_(clo_trace_sched) = False;
971
njn43c799e2003-04-08 00:08:52 +0000972 else if (VG_CLO_STREQ(argv[i], "--trace-pthread=none"))
sewardj45b4b372002-04-16 22:50:32 +0000973 VG_(clo_trace_pthread_level) = 0;
njn43c799e2003-04-08 00:08:52 +0000974 else if (VG_CLO_STREQ(argv[i], "--trace-pthread=some"))
sewardj45b4b372002-04-16 22:50:32 +0000975 VG_(clo_trace_pthread_level) = 1;
njn43c799e2003-04-08 00:08:52 +0000976 else if (VG_CLO_STREQ(argv[i], "--trace-pthread=all"))
sewardj45b4b372002-04-16 22:50:32 +0000977 VG_(clo_trace_pthread_level) = 2;
sewardj8937c812002-04-12 20:12:20 +0000978
njn43c799e2003-04-08 00:08:52 +0000979 else if (VG_CLO_STREQN(14, argv[i], "--weird-hacks="))
sewardj8d365b52002-05-12 10:52:16 +0000980 VG_(clo_weird_hacks) = &argv[i][14];
sewardj3984b852002-05-12 03:00:17 +0000981
jsgf855d93d2003-10-13 22:26:55 +0000982 else if (VG_CLO_STREQN(17, argv[i], "--signal-polltime="))
983 VG_(clo_signal_polltime) = VG_(atoll)(&argv[i][17]);
984
985 else if (VG_CLO_STREQ(argv[i], "--lowlat-signals=yes"))
986 VG_(clo_lowlat_signals) = True;
987 else if (VG_CLO_STREQ(argv[i], "--lowlat-signals=no"))
988 VG_(clo_lowlat_signals) = False;
989
990 else if (VG_CLO_STREQ(argv[i], "--lowlat-syscalls=yes"))
991 VG_(clo_lowlat_syscalls) = True;
992 else if (VG_CLO_STREQ(argv[i], "--lowlat-syscalls=no"))
993 VG_(clo_lowlat_syscalls) = False;
994
njn43c799e2003-04-08 00:08:52 +0000995 else if (VG_CLO_STREQN(13, argv[i], "--stop-after="))
sewardjde4a1d02002-03-22 01:27:54 +0000996 VG_(clo_stop_after) = VG_(atoll)(&argv[i][13]);
997
njn43c799e2003-04-08 00:08:52 +0000998 else if (VG_CLO_STREQN(13, argv[i], "--dump-error="))
sewardjde4a1d02002-03-22 01:27:54 +0000999 VG_(clo_dump_error) = (Int)VG_(atoll)(&argv[i][13]);
1000
jsgf855d93d2003-10-13 22:26:55 +00001001 else if (VG_CLO_STREQ(argv[i], "--wait-for-gdb=yes"))
1002 VG_(clo_wait_for_gdb) = True;
1003 else if (VG_CLO_STREQ(argv[i], "--wait-for-gdb=no"))
1004 VG_(clo_wait_for_gdb) = False;
1005
njn43c799e2003-04-08 00:08:52 +00001006 else if (VG_CLO_STREQN(14, argv[i], "--num-callers=")) {
sewardjde4a1d02002-03-22 01:27:54 +00001007 /* Make sure it's sane. */
1008 VG_(clo_backtrace_size) = (Int)VG_(atoll)(&argv[i][14]);
njn6c846552003-09-16 07:41:43 +00001009 if (VG_(clo_backtrace_size) < 1)
1010 VG_(clo_backtrace_size) = 1;
sewardjde4a1d02002-03-22 01:27:54 +00001011 if (VG_(clo_backtrace_size) >= VG_DEEPEST_BACKTRACE)
1012 VG_(clo_backtrace_size) = VG_DEEPEST_BACKTRACE;
1013 }
1014
njn25e49d8e72002-09-23 09:36:25 +00001015 else if (VG_(needs).command_line_options) {
1016 Bool ok = SK_(process_cmd_line_option)(argv[i]);
1017 if (!ok)
fitzhardinge98abfc72003-12-16 02:05:15 +00001018 VG_(usage)();
njn25e49d8e72002-09-23 09:36:25 +00001019 }
sewardjde4a1d02002-03-22 01:27:54 +00001020 else
fitzhardinge98abfc72003-12-16 02:05:15 +00001021 VG_(usage)();
sewardjde4a1d02002-03-22 01:27:54 +00001022 }
1023
1024# undef ISSPACE
sewardjde4a1d02002-03-22 01:27:54 +00001025
njnf9ebf672003-05-12 21:41:30 +00001026 if (VG_(clo_verbosity) < 0)
sewardjde4a1d02002-03-22 01:27:54 +00001027 VG_(clo_verbosity) = 0;
1028
1029 if (VG_(clo_GDB_attach) && VG_(clo_trace_children)) {
1030 VG_(message)(Vg_UserMsg, "");
1031 VG_(message)(Vg_UserMsg,
1032 "--gdb-attach=yes conflicts with --trace-children=yes");
1033 VG_(message)(Vg_UserMsg,
1034 "Please choose one or the other, but not both.");
njn25e49d8e72002-09-23 09:36:25 +00001035 VG_(bad_option)("--gdb-attach=yes and --trace-children=yes");
sewardjde4a1d02002-03-22 01:27:54 +00001036 }
1037
sewardj4cf05692002-10-27 20:28:29 +00001038 /* Set up logging now. After this is done, VG_(clo_logfile_fd)
1039 should be connected to whatever sink has been selected, and we
1040 indiscriminately chuck stuff into it without worrying what the
1041 nature of it is. Oh the wonder of Unix streams. */
1042
nethercotee1730692003-11-20 10:38:07 +00001043 /* So far we should be still attached to stdout, so we can show on
sewardj4cf05692002-10-27 20:28:29 +00001044 the terminal any problems to do with processing command line
1045 opts. */
nethercotee1730692003-11-20 10:38:07 +00001046 vg_assert(VG_(clo_logfile_fd) == 1 /* stdout */);
sewardj73cf3bc2002-11-03 03:20:15 +00001047 vg_assert(VG_(logging_to_filedes) == True);
sewardj4cf05692002-10-27 20:28:29 +00001048
1049 switch (VG_(clo_log_to)) {
sewardj73cf3bc2002-11-03 03:20:15 +00001050
sewardj4cf05692002-10-27 20:28:29 +00001051 case VgLogTo_Fd:
1052 vg_assert(VG_(clo_logfile_name) == NULL);
1053 VG_(clo_logfile_fd) = eventually_logfile_fd;
1054 break;
sewardj73cf3bc2002-11-03 03:20:15 +00001055
sewardj4cf05692002-10-27 20:28:29 +00001056 case VgLogTo_File: {
1057 Char logfilename[1000];
jsgff3c3f1a2003-10-14 22:13:28 +00001058 Int seq = 0;
1059 Int pid = VG_(getpid)();
1060
sewardj4cf05692002-10-27 20:28:29 +00001061 vg_assert(VG_(clo_logfile_name) != NULL);
1062 vg_assert(VG_(strlen)(VG_(clo_logfile_name)) <= 900); /* paranoia */
jsgff3c3f1a2003-10-14 22:13:28 +00001063
1064 for(;;) {
1065 if (seq == 0)
1066 VG_(sprintf)(logfilename, "%s.pid%d",
1067 VG_(clo_logfile_name), pid );
1068 else
1069 VG_(sprintf)(logfilename, "%s.pid%d.%d",
1070 VG_(clo_logfile_name), pid, seq );
1071 seq++;
1072
1073 eventually_logfile_fd
1074 = VG_(open)(logfilename,
1075 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_EXCL|VKI_O_TRUNC,
1076 VKI_S_IRUSR|VKI_S_IWUSR);
1077 if (eventually_logfile_fd >= 0) {
fitzhardinge9b8c2f32004-01-06 00:15:26 +00001078 VG_(clo_logfile_fd) = VG_(safe_fd)(eventually_logfile_fd);
jsgff3c3f1a2003-10-14 22:13:28 +00001079 break;
1080 } else {
1081 if (eventually_logfile_fd != -VKI_EEXIST) {
1082 VG_(message)(Vg_UserMsg,
1083 "Can't create/open log file `%s.pid%d'; giving up!",
1084 VG_(clo_logfile_name), pid);
1085 VG_(bad_option)(
1086 "--logfile=<file> didn't work out for some reason.");
1087 break;
1088 }
1089 }
1090 }
sewardj4cf05692002-10-27 20:28:29 +00001091 break;
sewardj73cf3bc2002-11-03 03:20:15 +00001092 }
1093
1094 case VgLogTo_Socket: {
1095 vg_assert(VG_(clo_logfile_name) != NULL);
1096 vg_assert(VG_(strlen)(VG_(clo_logfile_name)) <= 900); /* paranoia */
1097 eventually_logfile_fd
1098 = VG_(connect_via_socket)( VG_(clo_logfile_name) );
1099 if (eventually_logfile_fd == -1) {
1100 VG_(message)(Vg_UserMsg,
1101 "Invalid --logsocket=ipaddr or --logsocket=ipaddr:port spec");
1102 VG_(message)(Vg_UserMsg,
1103 "of `%s'; giving up!", VG_(clo_logfile_name) );
1104 VG_(bad_option)(
1105 "--logsocket=");
sewardj4cf05692002-10-27 20:28:29 +00001106 }
sewardj73cf3bc2002-11-03 03:20:15 +00001107 if (eventually_logfile_fd == -2) {
1108 VG_(message)(Vg_UserMsg,
sewardj570f8902002-11-03 11:44:36 +00001109 "valgrind: failed to connect to logging server `%s'.",
sewardj73cf3bc2002-11-03 03:20:15 +00001110 VG_(clo_logfile_name) );
sewardj570f8902002-11-03 11:44:36 +00001111 VG_(message)(Vg_UserMsg,
1112 "Log messages will sent to stderr instead." );
1113 VG_(message)(Vg_UserMsg,
1114 "" );
1115 /* We don't change anything here. */
1116 } else {
1117 vg_assert(eventually_logfile_fd > 0);
1118 VG_(clo_logfile_fd) = eventually_logfile_fd;
1119 VG_(logging_to_filedes) = False;
1120 }
sewardj73cf3bc2002-11-03 03:20:15 +00001121 break;
1122 }
1123
sewardj4cf05692002-10-27 20:28:29 +00001124 }
1125
jsgf855d93d2003-10-13 22:26:55 +00001126 /* Move logfile_fd into the safe range, so it doesn't conflict with any app fds */
fitzhardingef0046f22003-12-18 02:39:22 +00001127 eventually_logfile_fd = VG_(fcntl)(VG_(clo_logfile_fd), VKI_F_DUPFD, VG_(max_fd)+1);
jsgf855d93d2003-10-13 22:26:55 +00001128 if (eventually_logfile_fd < 0)
1129 VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd into safe range");
1130 else {
1131 VG_(clo_logfile_fd) = eventually_logfile_fd;
1132 VG_(fcntl)(VG_(clo_logfile_fd), VKI_F_SETFD, VKI_FD_CLOEXEC);
1133 }
1134
sewardj4cf05692002-10-27 20:28:29 +00001135 /* Ok, the logging sink is running now. Print a suitable preamble.
1136 If logging to file or a socket, write details of parent PID and
1137 command line args, to help people trying to interpret the
1138 results of a run which encompasses multiple processes. */
sewardjde4a1d02002-03-22 01:27:54 +00001139
sewardj83adf412002-05-01 01:25:45 +00001140 if (VG_(clo_verbosity > 0)) {
njnd04b7c62002-10-03 14:05:52 +00001141 /* Skin details */
1142 VG_(message)(Vg_UserMsg, "%s%s%s, %s for x86-linux.",
1143 VG_(details).name,
1144 NULL == VG_(details).version ? "" : "-",
1145 NULL == VG_(details).version
1146 ? (Char*)"" : VG_(details).version,
1147 VG_(details).description);
1148 VG_(message)(Vg_UserMsg, "%s", VG_(details).copyright_author);
sewardj3b2736a2002-03-24 12:18:35 +00001149
njnd04b7c62002-10-03 14:05:52 +00001150 /* Core details */
1151 VG_(message)(Vg_UserMsg,
njn3e884182003-04-15 13:03:23 +00001152 "Using valgrind-%s, a program supervision framework for x86-linux.",
sewardj4aa62ba2002-10-05 15:49:27 +00001153 VERSION);
sewardjde4a1d02002-03-22 01:27:54 +00001154 VG_(message)(Vg_UserMsg,
nethercotebb1c9912004-01-04 16:43:23 +00001155 "Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward.");
njnd04b7c62002-10-03 14:05:52 +00001156 }
1157
nethercotec1e395d2003-11-10 13:26:49 +00001158 if (VG_(clo_verbosity) > 0 && VG_(clo_log_to) != VgLogTo_Fd) {
sewardj4cf05692002-10-27 20:28:29 +00001159 VG_(message)(Vg_UserMsg, "");
1160 VG_(message)(Vg_UserMsg,
1161 "My PID = %d, parent PID = %d. Prog and args are:",
1162 VG_(getpid)(), VG_(getppid)() );
1163 for (i = 0; i < VG_(client_argc); i++)
1164 VG_(message)(Vg_UserMsg, " %s", VG_(client_argv)[i]);
1165 }
1166
sewardjde4a1d02002-03-22 01:27:54 +00001167 if (VG_(clo_verbosity) > 1) {
sewardj4cf05692002-10-27 20:28:29 +00001168 if (VG_(clo_log_to) != VgLogTo_Fd)
1169 VG_(message)(Vg_UserMsg, "");
fitzhardinge98abfc72003-12-16 02:05:15 +00001170 VG_(message)(Vg_UserMsg, "Valgrind library directory: %s", VG_(libdir));
njn86dc2bc2003-09-09 07:26:21 +00001171 VG_(message)(Vg_UserMsg, "Command line");
1172 for (i = 0; i < VG_(client_argc); i++)
1173 VG_(message)(Vg_UserMsg, " %s", VG_(client_argv)[i]);
1174
sewardjde4a1d02002-03-22 01:27:54 +00001175 VG_(message)(Vg_UserMsg, "Startup, with flags:");
fitzhardinge98abfc72003-12-16 02:05:15 +00001176 for (i = 1; i < argc; i++) {
sewardjde4a1d02002-03-22 01:27:54 +00001177 VG_(message)(Vg_UserMsg, " %s", argv[i]);
1178 }
1179 }
1180
fitzhardinge98abfc72003-12-16 02:05:15 +00001181 if (VG_(clo_n_suppressions) < VG_CLO_MAX_SFILES-1 &&
njn25e49d8e72002-09-23 09:36:25 +00001182 (VG_(needs).core_errors || VG_(needs).skin_errors)) {
fitzhardinge98abfc72003-12-16 02:05:15 +00001183 /* If there are no suppression files specified and the skin
1184 needs one, load the default */
1185 static const Char default_supp[] = "default.supp";
1186 Int len = VG_(strlen)(VG_(libdir)) + 1 + sizeof(default_supp);
1187 Char *buf = VG_(arena_malloc)(VG_AR_CORE, len);
1188 VG_(sprintf)(buf, "%s/%s", VG_(libdir), default_supp);
1189 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = buf;
1190 VG_(clo_n_suppressions)++;
sewardjde4a1d02002-03-22 01:27:54 +00001191 }
sewardj4cf05692002-10-27 20:28:29 +00001192
njn6a230532003-07-21 10:38:23 +00001193 if (VG_(clo_gen_suppressions) &&
1194 !VG_(needs).core_errors && !VG_(needs).skin_errors) {
1195 config_error("Can't use --gen-suppressions=yes with this skin,\n"
1196 " as it doesn't generate errors.");
1197 }
1198
sewardjde4a1d02002-03-22 01:27:54 +00001199}
1200
sewardjde4a1d02002-03-22 01:27:54 +00001201/* ---------------------------------------------------------------------
1202 Copying to/from m_state_static.
1203 ------------------------------------------------------------------ */
1204
sewardjb91ae7f2003-04-29 23:50:00 +00001205/* See comment about this in vg_include.h. Change only with
1206 great care.
1207*/
1208__attribute__ ((aligned (16)))
sewardj92a59562002-09-30 00:53:10 +00001209UInt VG_(m_state_static) [6 /* segment regs, Intel order */
1210 + 8 /* int regs, in Intel order */
sewardjde4a1d02002-03-22 01:27:54 +00001211 + 1 /* %eflags */
1212 + 1 /* %eip */
sewardjb91ae7f2003-04-29 23:50:00 +00001213 + VG_SIZE_OF_SSESTATE_W /* FPU state */
sewardjde4a1d02002-03-22 01:27:54 +00001214 ];
1215
sewardjfa492d42002-12-08 18:20:01 +00001216UInt VG_(insertDflag)(UInt eflags, Int d)
1217{
1218 vg_assert(d == 1 || d == -1);
1219 eflags &= ~EFlagD;
1220
1221 if (d < 0)
1222 eflags |= EFlagD;
1223
1224 return eflags;
1225}
1226
1227Int VG_(extractDflag)(UInt eflags)
1228{
1229 Int ret;
1230
1231 if (eflags & EFlagD)
1232 ret = -1;
1233 else
1234 ret = 1;
1235
1236 return ret;
1237}
1238
sewardjde4a1d02002-03-22 01:27:54 +00001239void VG_(copy_baseBlock_to_m_state_static) ( void )
1240{
1241 Int i;
sewardj92a59562002-09-30 00:53:10 +00001242 VG_(m_state_static)[ 0/4] = VG_(baseBlock)[VGOFF_(m_cs)];
1243 VG_(m_state_static)[ 4/4] = VG_(baseBlock)[VGOFF_(m_ss)];
1244 VG_(m_state_static)[ 8/4] = VG_(baseBlock)[VGOFF_(m_ds)];
1245 VG_(m_state_static)[12/4] = VG_(baseBlock)[VGOFF_(m_es)];
1246 VG_(m_state_static)[16/4] = VG_(baseBlock)[VGOFF_(m_fs)];
1247 VG_(m_state_static)[20/4] = VG_(baseBlock)[VGOFF_(m_gs)];
sewardjde4a1d02002-03-22 01:27:54 +00001248
sewardj92a59562002-09-30 00:53:10 +00001249 VG_(m_state_static)[24/4] = VG_(baseBlock)[VGOFF_(m_eax)];
1250 VG_(m_state_static)[28/4] = VG_(baseBlock)[VGOFF_(m_ecx)];
1251 VG_(m_state_static)[32/4] = VG_(baseBlock)[VGOFF_(m_edx)];
1252 VG_(m_state_static)[36/4] = VG_(baseBlock)[VGOFF_(m_ebx)];
1253 VG_(m_state_static)[40/4] = VG_(baseBlock)[VGOFF_(m_esp)];
1254 VG_(m_state_static)[44/4] = VG_(baseBlock)[VGOFF_(m_ebp)];
1255 VG_(m_state_static)[48/4] = VG_(baseBlock)[VGOFF_(m_esi)];
1256 VG_(m_state_static)[52/4] = VG_(baseBlock)[VGOFF_(m_edi)];
1257
sewardjb91ae7f2003-04-29 23:50:00 +00001258 VG_(m_state_static)[56/4]
1259 = VG_(insertDflag)(VG_(baseBlock)[VGOFF_(m_eflags)],
1260 VG_(baseBlock)[VGOFF_(m_dflag)]);
sewardj92a59562002-09-30 00:53:10 +00001261 VG_(m_state_static)[60/4] = VG_(baseBlock)[VGOFF_(m_eip)];
sewardjde4a1d02002-03-22 01:27:54 +00001262
sewardjb91ae7f2003-04-29 23:50:00 +00001263 for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
sewardj92a59562002-09-30 00:53:10 +00001264 VG_(m_state_static)[64/4 + i]
sewardjb91ae7f2003-04-29 23:50:00 +00001265 = VG_(baseBlock)[VGOFF_(m_ssestate) + i];
sewardjde4a1d02002-03-22 01:27:54 +00001266}
1267
1268
1269void VG_(copy_m_state_static_to_baseBlock) ( void )
1270{
1271 Int i;
sewardj92a59562002-09-30 00:53:10 +00001272 VG_(baseBlock)[VGOFF_(m_cs)] = VG_(m_state_static)[ 0/4];
1273 VG_(baseBlock)[VGOFF_(m_ss)] = VG_(m_state_static)[ 4/4];
1274 VG_(baseBlock)[VGOFF_(m_ds)] = VG_(m_state_static)[ 8/4];
1275 VG_(baseBlock)[VGOFF_(m_es)] = VG_(m_state_static)[12/4];
1276 VG_(baseBlock)[VGOFF_(m_fs)] = VG_(m_state_static)[16/4];
1277 VG_(baseBlock)[VGOFF_(m_gs)] = VG_(m_state_static)[20/4];
sewardjde4a1d02002-03-22 01:27:54 +00001278
sewardj92a59562002-09-30 00:53:10 +00001279 VG_(baseBlock)[VGOFF_(m_eax)] = VG_(m_state_static)[24/4];
1280 VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(m_state_static)[28/4];
1281 VG_(baseBlock)[VGOFF_(m_edx)] = VG_(m_state_static)[32/4];
1282 VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(m_state_static)[36/4];
1283 VG_(baseBlock)[VGOFF_(m_esp)] = VG_(m_state_static)[40/4];
1284 VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(m_state_static)[44/4];
1285 VG_(baseBlock)[VGOFF_(m_esi)] = VG_(m_state_static)[48/4];
1286 VG_(baseBlock)[VGOFF_(m_edi)] = VG_(m_state_static)[52/4];
1287
sewardjb91ae7f2003-04-29 23:50:00 +00001288 VG_(baseBlock)[VGOFF_(m_eflags)]
1289 = VG_(m_state_static)[56/4] & ~EFlagD;
1290 VG_(baseBlock)[VGOFF_(m_dflag)]
1291 = VG_(extractDflag)(VG_(m_state_static)[56/4]);
sewardjfa492d42002-12-08 18:20:01 +00001292
sewardj92a59562002-09-30 00:53:10 +00001293 VG_(baseBlock)[VGOFF_(m_eip)] = VG_(m_state_static)[60/4];
sewardjde4a1d02002-03-22 01:27:54 +00001294
sewardjb91ae7f2003-04-29 23:50:00 +00001295 for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
1296 VG_(baseBlock)[VGOFF_(m_ssestate) + i]
sewardj92a59562002-09-30 00:53:10 +00001297 = VG_(m_state_static)[64/4 + i];
sewardjde4a1d02002-03-22 01:27:54 +00001298}
1299
njn25e49d8e72002-09-23 09:36:25 +00001300Addr VG_(get_stack_pointer) ( void )
1301{
1302 return VG_(baseBlock)[VGOFF_(m_esp)];
1303}
1304
sewardjde4a1d02002-03-22 01:27:54 +00001305/* ---------------------------------------------------------------------
1306 Show accumulated counts.
1307 ------------------------------------------------------------------ */
1308
njn25e49d8e72002-09-23 09:36:25 +00001309static __inline__ Int safe_idiv(Int a, Int b)
1310{
1311 return (b == 0 ? 0 : a / b);
1312}
1313
sewardjde4a1d02002-03-22 01:27:54 +00001314static void vg_show_counts ( void )
1315{
1316 VG_(message)(Vg_DebugMsg,
sewardjc0d8f682002-11-30 00:49:43 +00001317 " TT/TC: %d tc sectors discarded.",
1318 VG_(number_of_tc_discards) );
sewardjde4a1d02002-03-22 01:27:54 +00001319 VG_(message)(Vg_DebugMsg,
sewardj22854b92002-11-30 14:00:47 +00001320 " %d chainings, %d unchainings.",
1321 VG_(bb_enchain_count), VG_(bb_dechain_count) );
1322 VG_(message)(Vg_DebugMsg,
njn25e49d8e72002-09-23 09:36:25 +00001323 "translate: new %d (%d -> %d; ratio %d:10)",
sewardjde4a1d02002-03-22 01:27:54 +00001324 VG_(overall_in_count),
1325 VG_(overall_in_osize),
1326 VG_(overall_in_tsize),
njn25e49d8e72002-09-23 09:36:25 +00001327 safe_idiv(10*VG_(overall_in_tsize), VG_(overall_in_osize)));
1328 VG_(message)(Vg_DebugMsg,
1329 " discard %d (%d -> %d; ratio %d:10).",
sewardjde4a1d02002-03-22 01:27:54 +00001330 VG_(overall_out_count),
1331 VG_(overall_out_osize),
njn25e49d8e72002-09-23 09:36:25 +00001332 VG_(overall_out_tsize),
1333 safe_idiv(10*VG_(overall_out_tsize), VG_(overall_out_osize)));
sewardjde4a1d02002-03-22 01:27:54 +00001334 VG_(message)(Vg_DebugMsg,
njne0205ff2003-04-08 00:56:14 +00001335 " dispatch: %llu jumps (bb entries), of which %u (%lu%%) were unchained.",
sewardj22854b92002-11-30 14:00:47 +00001336 VG_(bbs_done),
1337 VG_(unchained_jumps_done),
1338 ((ULong)(100) * (ULong)(VG_(unchained_jumps_done)))
1339 / ( VG_(bbs_done)==0 ? 1 : VG_(bbs_done) )
1340 );
1341
1342 VG_(message)(Vg_DebugMsg,
1343 " %d/%d major/minor sched events. %d tt_fast misses.",
1344 VG_(num_scheduling_events_MAJOR),
sewardj2e93c502002-04-12 11:12:52 +00001345 VG_(num_scheduling_events_MINOR),
1346 VG_(tt_fast_misses));
sewardj22854b92002-11-30 14:00:47 +00001347
sewardjde4a1d02002-03-22 01:27:54 +00001348 VG_(message)(Vg_DebugMsg,
1349 "reg-alloc: %d t-req-spill, "
1350 "%d+%d orig+spill uis, %d total-reg-r.",
1351 VG_(translations_needing_spill),
1352 VG_(uinstrs_prealloc),
1353 VG_(uinstrs_spill),
1354 VG_(total_reg_rank) );
1355 VG_(message)(Vg_DebugMsg,
sewardjde4a1d02002-03-22 01:27:54 +00001356 " sanity: %d cheap, %d expensive checks.",
1357 VG_(sanity_fast_count),
1358 VG_(sanity_slow_count) );
njn25e49d8e72002-09-23 09:36:25 +00001359 VG_(print_ccall_stats)();
sewardjde4a1d02002-03-22 01:27:54 +00001360}
1361
1362
1363/* ---------------------------------------------------------------------
1364 Main!
1365 ------------------------------------------------------------------ */
1366
jsgf855d93d2003-10-13 22:26:55 +00001367/* Initialize the PID and PGRP of scheduler LWP; this is also called
1368 in any new children after fork. */
1369static void newpid(ThreadId unused)
1370{
1371 /* PID of scheduler LWP */
1372 VG_(main_pid) = VG_(getpid)();
1373 VG_(main_pgrp) = VG_(getpgrp)();
1374}
1375
sewardjde4a1d02002-03-22 01:27:54 +00001376/* Where we jump to once Valgrind has got control, and the real
1377 machine's state has been copied to the m_state_static. */
1378
fitzhardinge98abfc72003-12-16 02:05:15 +00001379void VG_(main) ( const KickstartParams *kp, void (*tool_init)(void), void *tool_dlhandle )
sewardjde4a1d02002-03-22 01:27:54 +00001380{
sewardj2e93c502002-04-12 11:12:52 +00001381 VgSchedReturnCode src;
fitzhardingef0046f22003-12-18 02:39:22 +00001382 struct vki_rlimit rl;
sewardjde4a1d02002-03-22 01:27:54 +00001383
fitzhardinge98abfc72003-12-16 02:05:15 +00001384 /* initial state */
1385 if (0)
1386 VG_(printf)("starting esp=%p eip=%p, esp=%p\n", kp->client_esp, kp->client_eip, &src);
1387 VG_(esp_at_startup) = kp->client_esp;
1388 VG_(memset)(&VG_(m_state_static), 0, sizeof(VG_(m_state_static)));
1389 VG_(m_state_static)[40/4] = kp->client_esp;
1390 VG_(m_state_static)[60/4] = kp->client_eip;
1391
1392 /* set up an initial FPU state (doesn't really matter what it is,
1393 so long as it's somewhat valid) */
1394 if (!VG_(have_ssestate))
1395 asm volatile("fwait; fnsave %0; fwait; frstor %0; fwait"
1396 : : "m" (VG_(m_state_static)[64/4]) : "cc", "memory");
1397 else
1398 asm volatile("fwait; fxsave %0; fwait; andl $0xffbf, %1; fxrstor %0; fwait"
1399 : : "m" (VG_(m_state_static)[64/4]), "m" (VG_(m_state_static)[(64+24)/4]) : "cc", "memory");
1400
1401 VG_(brk_base) = VG_(brk_limit) = kp->client_brkbase;
1402 VG_(client_base) = kp->client_base;
1403 VG_(client_end) = kp->client_end;
1404 VG_(client_mapbase) = kp->client_mapbase;
1405 VG_(clstk_base) = kp->clstk_base;
1406 VG_(clstk_end) = kp->clstk_end;
fitzhardinge92360792003-12-24 10:11:11 +00001407 vg_assert(VG_(clstk_end) == VG_(client_end));
fitzhardinge98abfc72003-12-16 02:05:15 +00001408
1409 VG_(shadow_base) = kp->shadow_base;
1410 VG_(shadow_end) = kp->shadow_end;
1411 VG_(valgrind_base) = kp->vg_base;
1412 VG_(valgrind_mmap_end) = kp->vg_mmap_end;
1413 VG_(valgrind_end) = kp->vg_end;
1414
1415 VG_(libdir) = kp->libdir;
1416
fitzhardinge92360792003-12-24 10:11:11 +00001417 VG_(client_trampoline_code) = kp->cl_tramp_code;
fitzhardinge98abfc72003-12-16 02:05:15 +00001418
njn0c7a5b52003-04-30 09:00:33 +00001419 if (0) {
1420 if (VG_(have_ssestate))
1421 VG_(printf)("Looks like a SSE-capable CPU\n");
1422 else
1423 VG_(printf)("Looks like a MMX-only CPU\n");
1424 }
sewardjb91ae7f2003-04-29 23:50:00 +00001425
jsgf855d93d2003-10-13 22:26:55 +00001426 VG_(atfork)(NULL, NULL, newpid);
1427 newpid(VG_INVALID_THREADID);
1428
fitzhardingef0046f22003-12-18 02:39:22 +00001429 /* Get the current file descriptor limits. */
1430 if (VG_(getrlimit)(VKI_RLIMIT_NOFILE, &rl) < 0) {
1431 rl.rlim_cur = 1024;
1432 rl.rlim_max = 1024;
1433 }
1434
1435 /* Work out where to move the soft limit to. */
1436 if (rl.rlim_cur + VG_N_RESERVED_FDS <= rl.rlim_max) {
1437 rl.rlim_cur = rl.rlim_cur + VG_N_RESERVED_FDS;
1438 } else {
1439 rl.rlim_cur = rl.rlim_max;
1440 }
1441
1442 /* Reserve some file descriptors for our use. */
1443 VG_(max_fd) = rl.rlim_cur - VG_N_RESERVED_FDS;
1444
1445 /* Update the soft limit. */
1446 VG_(setrlimit)(VKI_RLIMIT_NOFILE, &rl);
1447
fitzhardingeb791a192003-12-18 07:22:44 +00001448 if (kp->vgexecfd != -1)
1449 VG_(vgexecfd) = VG_(safe_fd)(kp->vgexecfd);
1450 if (kp->clexecfd != -1)
1451 VG_(clexecfd) = VG_(safe_fd)(kp->clexecfd);
1452
njn3e884182003-04-15 13:03:23 +00001453 /* Read /proc/self/maps into a buffer. Must be before:
1454 - SK_(pre_clo_init)(): so that if it calls VG_(malloc)(), any mmap'd
1455 superblocks are not erroneously identified as being owned by the
1456 client, which would be bad.
1457 - init_memory(): that's where the buffer is parsed
1458 - init_tt_tc(): so the anonymous mmaps for the translation table and
1459 translation cache aren't identified as part of the client, which would
1460 waste > 20M of virtual address space, and be bad.
1461 */
njnfa1016e2003-09-25 17:54:11 +00001462 VG_(read_procselfmaps)();
njn3e884182003-04-15 13:03:23 +00001463
njn25e49d8e72002-09-23 09:36:25 +00001464 /* Setup stuff that depends on the skin. Must be before:
1465 - vg_init_baseBlock(): to register helpers
1466 - process_cmd_line_options(): to register skin name and description,
1467 and turn on/off 'command_line_options' need
1468 - init_memory() (to setup memory event trackers).
njn3e884182003-04-15 13:03:23 +00001469 */
fitzhardinge98abfc72003-12-16 02:05:15 +00001470 (*tool_init)();
1471 VG_(tool_init_dlsym)(tool_dlhandle);
1472
njn810086f2002-11-14 12:42:47 +00001473 VG_(sanity_check_needs)();
njn25e49d8e72002-09-23 09:36:25 +00001474
fitzhardinge98abfc72003-12-16 02:05:15 +00001475 /* Process Valgrind's command-line opts */
1476 process_cmd_line_options(kp);
sewardjde4a1d02002-03-22 01:27:54 +00001477
jsgf855d93d2003-10-13 22:26:55 +00001478 /* Hook to delay things long enough so we can get the pid and
1479 attach GDB in another shell. */
1480 if (VG_(clo_wait_for_gdb)) {
1481 VG_(printf)("pid=%d\n", VG_(getpid)());
1482 /* do "jump *$eip" to skip this in gdb */
1483 VG_(do_syscall)(__NR_pause);
1484 }
1485
njn3e884182003-04-15 13:03:23 +00001486 /* Do post command-line processing initialisation. Must be before:
1487 - vg_init_baseBlock(): to register any more helpers
1488 */
njncc7bb472002-10-14 09:25:19 +00001489 SK_(post_clo_init)();
1490
njn3e884182003-04-15 13:03:23 +00001491 /* Set up baseBlock offsets and copy the saved machine's state into it. */
njncc7bb472002-10-14 09:25:19 +00001492 vg_init_baseBlock();
1493
rjwalshf5f536f2003-11-17 17:45:00 +00001494 /* Search for file descriptors that are inherited from our parent. */
1495 if (VG_(clo_track_fds))
1496 VG_(init_preopened_fds)();
1497
sewardj018f7622002-05-15 21:13:39 +00001498 /* Initialise the scheduler, and copy the client's state from
njn3e884182003-04-15 13:03:23 +00001499 baseBlock into VG_(threads)[1]. Must be before:
1500 - VG_(sigstartup_actions)()
1501 */
sewardj018f7622002-05-15 21:13:39 +00001502 VG_(scheduler_init)();
1503
jsgf855d93d2003-10-13 22:26:55 +00001504 /* Set up the ProxyLWP machinery */
1505 VG_(proxy_init)();
1506
sewardj018f7622002-05-15 21:13:39 +00001507 /* Initialise the signal handling subsystem, temporarily parking
1508 the saved blocking-mask in saved_sigmask. */
sewardjde4a1d02002-03-22 01:27:54 +00001509 VG_(sigstartup_actions)();
1510
sewardj018f7622002-05-15 21:13:39 +00001511 /* Perhaps we're profiling Valgrind? */
njn25e49d8e72002-09-23 09:36:25 +00001512 if (VG_(clo_profile))
1513 VGP_(init_profiling)();
sewardjde4a1d02002-03-22 01:27:54 +00001514
sewardj5f07b662002-04-23 16:52:51 +00001515 /* Start calibration of our RDTSC-based clock. */
1516 VG_(start_rdtsc_calibration)();
1517
njn3e884182003-04-15 13:03:23 +00001518 /* Parse /proc/self/maps to learn about startup segments. */
njn25e49d8e72002-09-23 09:36:25 +00001519 VGP_PUSHCC(VgpInitMem);
1520 VG_(init_memory)();
1521 VGP_POPCC(VgpInitMem);
1522
1523 /* Read the list of errors to suppress. This should be found in
1524 the file specified by vg_clo_suppressions. */
1525 if (VG_(needs).core_errors || VG_(needs).skin_errors)
1526 VG_(load_suppressions)();
sewardj18d75132002-05-16 11:06:21 +00001527
sewardj5f07b662002-04-23 16:52:51 +00001528 /* End calibration of our RDTSC-based clock, leaving it as long as
1529 we can. */
1530 VG_(end_rdtsc_calibration)();
1531
njn3e884182003-04-15 13:03:23 +00001532 /* Initialise translation table and translation cache. */
sewardj18d75132002-05-16 11:06:21 +00001533 VG_(init_tt_tc)();
sewardjde4a1d02002-03-22 01:27:54 +00001534
1535 if (VG_(clo_verbosity) == 1) {
1536 VG_(message)(Vg_UserMsg,
1537 "For more details, rerun with: -v");
1538 }
1539
sewardj25c7c3a2003-07-10 00:17:58 +00001540 /* Force a read of the debug info so that we can look for
1541 glibc entry points to intercept. */
sewardj25c7c3a2003-07-10 00:17:58 +00001542 VG_(setup_code_redirect_table)();
1543
sewardjde4a1d02002-03-22 01:27:54 +00001544 /* Now it is safe for malloc et al in vg_clientmalloc.c to act
1545 instrumented-ly. */
sewardjde4a1d02002-03-22 01:27:54 +00001546 if (VG_(clo_verbosity) > 0)
1547 VG_(message)(Vg_UserMsg, "");
1548
1549 VG_(bbs_to_go) = VG_(clo_stop_after);
sewardj2e93c502002-04-12 11:12:52 +00001550
fitzhardinge98abfc72003-12-16 02:05:15 +00001551 if (VG_(clo_pointercheck)) {
1552 vki_modify_ldt_t ldt = { VG_POINTERCHECK_SEGIDX,
1553 VG_(client_base),
1554 (VG_(client_end)-VG_(client_base)) / VKI_BYTES_PER_PAGE,
1555 1, /* 32 bit */
1556 0, /* contents: data, RW, non-expanding */
1557 0, /* not read-exec only */
1558 1, /* limit in pages */
1559 0, /* !seg not present */
1560 1, /* usable */
1561 };
1562 Int ret = VG_(do_syscall)(__NR_modify_ldt, 1, &ldt, sizeof(ldt));
1563
1564 if (ret < 0) {
1565 VG_(message)(Vg_UserMsg,
1566 "Warning: ignoring --pointercheck=yes, "
1567 "because modify_ldt failed (errno=%d)", -ret);
1568 VG_(clo_pointercheck) = False;
1569 }
1570 }
1571
sewardj018f7622002-05-15 21:13:39 +00001572 /* Run! */
njn25e49d8e72002-09-23 09:36:25 +00001573 VG_(running_on_simd_CPU) = True;
sewardj671ff542002-05-07 09:25:30 +00001574 VGP_PUSHCC(VgpSched);
jsgf855d93d2003-10-13 22:26:55 +00001575
1576 if (__builtin_setjmp(&VG_(fatal_signal_jmpbuf)) == 0) {
1577 VG_(fatal_signal_set) = True;
1578 src = VG_(scheduler)();
1579 } else
1580 src = VgSrc_FatalSig;
1581
njn25e49d8e72002-09-23 09:36:25 +00001582 VGP_POPCC(VgpSched);
1583 VG_(running_on_simd_CPU) = False;
sewardjde4a1d02002-03-22 01:27:54 +00001584
1585 if (VG_(clo_verbosity) > 0)
1586 VG_(message)(Vg_UserMsg, "");
1587
sewardj2e93c502002-04-12 11:12:52 +00001588 if (src == VgSrc_Deadlock) {
1589 VG_(message)(Vg_UserMsg,
1590 "Warning: pthread scheduler exited due to deadlock");
1591 }
1592
rjwalshf5f536f2003-11-17 17:45:00 +00001593 /* Print out file descriptor summary and stats. */
1594 if(VG_(clo_track_fds))
1595 VG_(fd_stats)();
1596
njn25e49d8e72002-09-23 09:36:25 +00001597 if (VG_(needs).core_errors || VG_(needs).skin_errors)
sewardjde4a1d02002-03-22 01:27:54 +00001598 VG_(show_all_errors)();
sewardj2e93c502002-04-12 11:12:52 +00001599
njn7d9f94d2003-04-22 21:41:40 +00001600 SK_(fini)( VG_(exitcode) );
njn4f9c9342002-04-29 16:03:24 +00001601
sewardj0c3b53f2002-05-01 01:58:35 +00001602 VG_(do_sanity_checks)( True /*include expensive checks*/ );
sewardjde4a1d02002-03-22 01:27:54 +00001603
1604 if (VG_(clo_verbosity) > 1)
1605 vg_show_counts();
1606
sewardjc0d8f682002-11-30 00:49:43 +00001607 if (VG_(clo_verbosity) > 3)
njn25e49d8e72002-09-23 09:36:25 +00001608 VG_(print_UInstr_histogram)();
1609
sewardjde4a1d02002-03-22 01:27:54 +00001610 if (0) {
1611 VG_(message)(Vg_DebugMsg, "");
1612 VG_(message)(Vg_DebugMsg,
1613 "------ Valgrind's internal memory use stats follow ------" );
1614 VG_(mallocSanityCheckAll)();
1615 VG_(show_all_arena_stats)();
1616 VG_(message)(Vg_DebugMsg,
1617 "------ Valgrind's ExeContext management stats follow ------" );
1618 VG_(show_ExeContext_stats)();
sewardjde4a1d02002-03-22 01:27:54 +00001619 }
1620
njn25e49d8e72002-09-23 09:36:25 +00001621 if (VG_(clo_profile))
1622 VGP_(done_profiling)();
sewardjde4a1d02002-03-22 01:27:54 +00001623
1624 VG_(shutdown_logging)();
1625
jsgf855d93d2003-10-13 22:26:55 +00001626 /* We're exiting, so nuke all the threads and clean up the proxy LWPs */
1627 vg_assert(src == VgSrc_FatalSig ||
1628 VG_(threads)[VG_(last_run_tid)].status == VgTs_Runnable ||
1629 VG_(threads)[VG_(last_run_tid)].status == VgTs_WaitJoiner);
1630 VG_(nuke_all_threads_except)(VG_INVALID_THREADID);
1631
sewardj7e87e382002-05-03 19:09:05 +00001632 /* Decide how to exit. This depends on what the scheduler
1633 returned. */
jsgf855d93d2003-10-13 22:26:55 +00001634
sewardj7e87e382002-05-03 19:09:05 +00001635 switch (src) {
1636 case VgSrc_ExitSyscall: /* the normal way out */
1637 vg_assert(VG_(last_run_tid) > 0
1638 && VG_(last_run_tid) < VG_N_THREADS);
jsgf855d93d2003-10-13 22:26:55 +00001639 VG_(proxy_shutdown)();
1640
njn25e49d8e72002-09-23 09:36:25 +00001641 /* The thread's %EBX at the time it did __NR_exit() will hold
1642 the arg to __NR_exit(), so we just do __NR_exit() with
1643 that arg. */
1644 VG_(exit)( VG_(exitcode) );
sewardj7e87e382002-05-03 19:09:05 +00001645 /* NOT ALIVE HERE! */
njne427a662002-10-02 11:08:25 +00001646 VG_(core_panic)("entered the afterlife in vg_main() -- ExitSyscall");
sewardj7e87e382002-05-03 19:09:05 +00001647 break; /* what the hell :) */
sewardjde4a1d02002-03-22 01:27:54 +00001648
sewardj7e87e382002-05-03 19:09:05 +00001649 case VgSrc_Deadlock:
1650 /* Just exit now. No point in continuing. */
jsgf855d93d2003-10-13 22:26:55 +00001651 VG_(proxy_shutdown)();
sewardj7e87e382002-05-03 19:09:05 +00001652 VG_(exit)(0);
njne427a662002-10-02 11:08:25 +00001653 VG_(core_panic)("entered the afterlife in vg_main() -- Deadlock");
sewardj7e87e382002-05-03 19:09:05 +00001654 break;
1655
1656 case VgSrc_BbsDone:
1657 /* Tricky; we have to try and switch back to the real CPU.
1658 This is all very dodgy and won't work at all in the
1659 presence of threads, or if the client happened to be
1660 running a signal handler. */
1661 /* Prepare to restore state to the real CPU. */
sewardj839299f2003-06-14 11:57:59 +00001662 VG_(sigshutdown_actions)();
sewardj7e87e382002-05-03 19:09:05 +00001663 VG_(load_thread_state)(1 /* root thread */ );
1664 VG_(copy_baseBlock_to_m_state_static)();
1665
jsgf855d93d2003-10-13 22:26:55 +00001666 VG_(proxy_shutdown)();
1667
sewardj7e87e382002-05-03 19:09:05 +00001668 /* This pushes a return address on the simulator's stack,
1669 which is abandoned. We call vg_sigshutdown_actions() at
1670 the end of vg_switch_to_real_CPU(), so as to ensure that
1671 the original stack and machine state is restored before
1672 the real signal mechanism is restored. */
1673 VG_(switch_to_real_CPU)();
1674
jsgf855d93d2003-10-13 22:26:55 +00001675 case VgSrc_FatalSig:
1676 /* We were killed by a fatal signal, so replicate the effect */
1677 vg_assert(VG_(fatal_sigNo) != -1);
1678 VG_(kill_self)(VG_(fatal_sigNo));
1679 VG_(core_panic)("vg_main(): signal was supposed to be fatal");
1680 break;
1681
sewardj7e87e382002-05-03 19:09:05 +00001682 default:
njne427a662002-10-02 11:08:25 +00001683 VG_(core_panic)("vg_main(): unexpected scheduler return code");
sewardj7e87e382002-05-03 19:09:05 +00001684 }
sewardjde4a1d02002-03-22 01:27:54 +00001685}
1686
1687
1688/* Debugging thing .. can be called from assembly with OYNK macro. */
1689void VG_(oynk) ( Int n )
1690{
1691 OINK(n);
1692}
1693
1694
fitzhardinge98abfc72003-12-16 02:05:15 +00001695/* Walk through a colon-separated environment variable, and remove the
1696 entries which matches file_pattern. It slides everything down over
1697 the removed entries, and pads the remaining space with '\0'. It
1698 modifies the entries in place (in the client address space), but it
1699 shouldn't matter too much, since we only do this just before an
1700 execve().
sewardj78e25c92002-05-20 23:38:33 +00001701
fitzhardinge98abfc72003-12-16 02:05:15 +00001702 This is also careful to mop up any excess ':'s, since empty strings
1703 delimited by ':' are considered to be '.' in a path.
sewardjde4a1d02002-03-22 01:27:54 +00001704*/
fitzhardinge98abfc72003-12-16 02:05:15 +00001705void VG_(mash_colon_env)(Char *varp, const Char *remove_pattern)
sewardj45b672d2003-07-25 19:58:11 +00001706{
fitzhardinge98abfc72003-12-16 02:05:15 +00001707 Char *const start = varp;
1708 Char *entry_start = varp;
1709 Char *output = varp;
sewardj45b672d2003-07-25 19:58:11 +00001710
fitzhardinge98abfc72003-12-16 02:05:15 +00001711 if (varp == NULL)
sewardjde4a1d02002-03-22 01:27:54 +00001712 return;
fitzhardinge98abfc72003-12-16 02:05:15 +00001713
1714 while(*varp) {
1715 if (*varp == ':') {
1716 Char prev;
1717 Bool match;
1718
1719 /* This is a bit subtle: we want to match against the entry
1720 we just copied, because it may have overlapped with
1721 itself, junking the original. */
1722
1723 prev = *output;
1724 *output = '\0';
1725
1726 match = VG_(string_match)(remove_pattern, entry_start);
1727
1728 *output = prev;
1729
1730 if (match) {
1731 output = entry_start;
1732 varp++; /* skip ':' after removed entry */
1733 } else
1734 entry_start = output+1; /* entry starts after ':' */
1735 }
1736
1737 *output++ = *varp++;
sewardj3e1eb1f2002-05-18 13:14:17 +00001738 }
1739
fitzhardinge98abfc72003-12-16 02:05:15 +00001740 /* match against the last entry */
1741 if (VG_(string_match)(remove_pattern, entry_start)) {
1742 output = entry_start;
1743 if (output > start) {
1744 /* remove trailing ':' */
1745 output--;
1746 vg_assert(*output == ':');
1747 }
1748 }
njn25e49d8e72002-09-23 09:36:25 +00001749
fitzhardinge98abfc72003-12-16 02:05:15 +00001750 /* pad out the left-overs with '\0' */
1751 while(output < varp)
1752 *output++ = '\0';
sewardjde4a1d02002-03-22 01:27:54 +00001753}
1754
fitzhardingeb727d042004-01-06 00:18:21 +00001755/* Start GDB and get it to attach to this process. Called if the user
1756 requests this service after an error has been shown, so she can
1757 poke around and look at parameters, memory, etc. You can't
1758 meaningfully get GDB to continue the program, though; to continue,
1759 quit GDB. */
1760void VG_(start_GDB) ( Int tid )
sewardjde4a1d02002-03-22 01:27:54 +00001761{
fitzhardingeb727d042004-01-06 00:18:21 +00001762 Int pid;
njn9315df32003-04-16 20:50:50 +00001763
fitzhardingeb727d042004-01-06 00:18:21 +00001764 if ((pid = fork()) == 0)
1765 {
1766 ptrace(PTRACE_TRACEME, 0, NULL, NULL);
1767 VG_(kkill)(VG_(getpid)(), VKI_SIGSTOP);
1768 }
1769 else if (pid > 0)
1770 {
1771 struct user_regs_struct regs;
1772 Int status;
1773 Int res;
1774
1775 if (VG_(is_running_thread)( tid )) {
1776 regs.xcs = VG_(baseBlock)[VGOFF_(m_cs)];
1777 regs.xss = VG_(baseBlock)[VGOFF_(m_ss)];
1778 regs.xds = VG_(baseBlock)[VGOFF_(m_ds)];
1779 regs.xes = VG_(baseBlock)[VGOFF_(m_es)];
1780 regs.xfs = VG_(baseBlock)[VGOFF_(m_fs)];
1781 regs.xgs = VG_(baseBlock)[VGOFF_(m_gs)];
1782 regs.eax = VG_(baseBlock)[VGOFF_(m_eax)];
1783 regs.ebx = VG_(baseBlock)[VGOFF_(m_ebx)];
1784 regs.ecx = VG_(baseBlock)[VGOFF_(m_ecx)];
1785 regs.edx = VG_(baseBlock)[VGOFF_(m_edx)];
1786 regs.esi = VG_(baseBlock)[VGOFF_(m_esi)];
1787 regs.edi = VG_(baseBlock)[VGOFF_(m_edi)];
1788 regs.ebp = VG_(baseBlock)[VGOFF_(m_ebp)];
1789 regs.esp = VG_(baseBlock)[VGOFF_(m_esp)];
1790 regs.eflags = VG_(baseBlock)[VGOFF_(m_eflags)];
1791 regs.eip = VG_(baseBlock)[VGOFF_(m_eip)];
1792 } else {
1793 ThreadState* tst = & VG_(threads)[ tid ];
1794
1795 regs.xcs = tst->m_cs;
1796 regs.xss = tst->m_ss;
1797 regs.xds = tst->m_ds;
1798 regs.xes = tst->m_es;
1799 regs.xfs = tst->m_fs;
1800 regs.xgs = tst->m_gs;
1801 regs.eax = tst->m_eax;
1802 regs.ebx = tst->m_ebx;
1803 regs.ecx = tst->m_ecx;
1804 regs.edx = tst->m_edx;
1805 regs.esi = tst->m_esi;
1806 regs.edi = tst->m_edi;
1807 regs.ebp = tst->m_ebp;
1808 regs.esp = tst->m_esp;
1809 regs.eflags = tst->m_eflags;
1810 regs.eip = tst->m_eip;
1811 }
1812
1813 if ((res = VG_(waitpid)(pid, &status, 0)) == pid &&
1814 WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP &&
1815 ptrace(PTRACE_SETREGS, pid, NULL, &regs) == 0 &&
1816 ptrace(PTRACE_DETACH, pid, NULL, SIGSTOP) == 0) {
1817 UChar buf[VG_(strlen)(VG_(clo_GDB_path)) + 100];
1818
1819 VG_(sprintf)(buf, "%s -nw /proc/%d/fd/%d %d",
1820 VG_(clo_GDB_path), VG_(main_pid), VG_(clexecfd), pid);
1821 VG_(message)(Vg_UserMsg, "starting GDB with cmd: %s", buf);
1822 res = VG_(system)(buf);
1823 if (res == 0) {
1824 VG_(message)(Vg_UserMsg, "");
1825 VG_(message)(Vg_UserMsg,
1826 "GDB has detached. Valgrind regains control. We continue.");
1827 } else {
1828 VG_(message)(Vg_UserMsg, "Apparently failed!");
1829 VG_(message)(Vg_UserMsg, "");
1830 }
1831 }
1832
1833 VG_(kkill)(pid, VKI_SIGKILL);
1834 VG_(waitpid)(pid, &status, 0);
sewardjde4a1d02002-03-22 01:27:54 +00001835 }
sewardjde4a1d02002-03-22 01:27:54 +00001836}
1837
1838
1839/* Print some helpful-ish text about unimplemented things, and give
1840 up. */
sewardjcfc39b22002-05-08 01:58:18 +00001841void VG_(unimplemented) ( Char* msg )
sewardjde4a1d02002-03-22 01:27:54 +00001842{
1843 VG_(message)(Vg_UserMsg, "");
1844 VG_(message)(Vg_UserMsg,
1845 "Valgrind detected that your program requires");
1846 VG_(message)(Vg_UserMsg,
1847 "the following unimplemented functionality:");
1848 VG_(message)(Vg_UserMsg, " %s", msg);
1849 VG_(message)(Vg_UserMsg,
1850 "This may be because the functionality is hard to implement,");
1851 VG_(message)(Vg_UserMsg,
1852 "or because no reasonable program would behave this way,");
1853 VG_(message)(Vg_UserMsg,
nethercote421281e2003-11-20 16:20:55 +00001854 "or because nobody has yet needed it. In any case, let us know at");
sewardjde4a1d02002-03-22 01:27:54 +00001855 VG_(message)(Vg_UserMsg,
nethercote421281e2003-11-20 16:20:55 +00001856 "%s and/or try to work around the problem, if you can.", VG_BUGS_TO);
sewardjde4a1d02002-03-22 01:27:54 +00001857 VG_(message)(Vg_UserMsg,
1858 "");
1859 VG_(message)(Vg_UserMsg,
1860 "Valgrind has to exit now. Sorry. Bye!");
1861 VG_(message)(Vg_UserMsg,
1862 "");
sewardj15a43e12002-04-17 19:35:12 +00001863 VG_(pp_sched_status)();
sewardjde4a1d02002-03-22 01:27:54 +00001864 VG_(exit)(1);
1865}
1866
1867
njn25e49d8e72002-09-23 09:36:25 +00001868/* ---------------------------------------------------------------------
1869 Sanity check machinery (permanently engaged).
1870 ------------------------------------------------------------------ */
1871
1872/* A fast sanity check -- suitable for calling circa once per
1873 millisecond. */
1874
1875void VG_(do_sanity_checks) ( Bool force_expensive )
1876{
njn37cea302002-09-30 11:24:00 +00001877 VGP_PUSHCC(VgpCoreCheapSanity);
1878
njn25e49d8e72002-09-23 09:36:25 +00001879 if (VG_(sanity_level) < 1) return;
1880
1881 /* --- First do all the tests that we can do quickly. ---*/
1882
1883 VG_(sanity_fast_count)++;
1884
njn25e49d8e72002-09-23 09:36:25 +00001885 /* Check stuff pertaining to the memory check system. */
1886
1887 /* Check that nobody has spuriously claimed that the first or
1888 last 16 pages of memory have become accessible [...] */
njn37cea302002-09-30 11:24:00 +00001889 if (VG_(needs).sanity_checks) {
1890 VGP_PUSHCC(VgpSkinCheapSanity);
njn25e49d8e72002-09-23 09:36:25 +00001891 vg_assert(SK_(cheap_sanity_check)());
njn37cea302002-09-30 11:24:00 +00001892 VGP_POPCC(VgpSkinCheapSanity);
1893 }
njn25e49d8e72002-09-23 09:36:25 +00001894
1895 /* --- Now some more expensive checks. ---*/
1896
1897 /* Once every 25 times, check some more expensive stuff. */
1898 if ( force_expensive
1899 || VG_(sanity_level) > 1
1900 || (VG_(sanity_level) == 1 && (VG_(sanity_fast_count) % 25) == 0)) {
1901
njn37cea302002-09-30 11:24:00 +00001902 VGP_PUSHCC(VgpCoreExpensiveSanity);
njn25e49d8e72002-09-23 09:36:25 +00001903 VG_(sanity_slow_count)++;
1904
jsgf855d93d2003-10-13 22:26:55 +00001905 VG_(proxy_sanity)();
1906
njn25e49d8e72002-09-23 09:36:25 +00001907# if 0
1908 { void zzzmemscan(void); zzzmemscan(); }
1909# endif
1910
1911 if ((VG_(sanity_fast_count) % 250) == 0)
1912 VG_(sanity_check_tc_tt)();
1913
1914 if (VG_(needs).sanity_checks) {
njn37cea302002-09-30 11:24:00 +00001915 VGP_PUSHCC(VgpSkinExpensiveSanity);
njn25e49d8e72002-09-23 09:36:25 +00001916 vg_assert(SK_(expensive_sanity_check)());
njn37cea302002-09-30 11:24:00 +00001917 VGP_POPCC(VgpSkinExpensiveSanity);
njn25e49d8e72002-09-23 09:36:25 +00001918 }
1919 /*
1920 if ((VG_(sanity_fast_count) % 500) == 0) VG_(mallocSanityCheckAll)();
1921 */
njn37cea302002-09-30 11:24:00 +00001922 VGP_POPCC(VgpCoreExpensiveSanity);
njn25e49d8e72002-09-23 09:36:25 +00001923 }
1924
1925 if (VG_(sanity_level) > 1) {
njn37cea302002-09-30 11:24:00 +00001926 VGP_PUSHCC(VgpCoreExpensiveSanity);
njn25e49d8e72002-09-23 09:36:25 +00001927 /* Check sanity of the low-level memory manager. Note that bugs
1928 in the client's code can cause this to fail, so we don't do
1929 this check unless specially asked for. And because it's
1930 potentially very expensive. */
1931 VG_(mallocSanityCheckAll)();
njn37cea302002-09-30 11:24:00 +00001932 VGP_POPCC(VgpCoreExpensiveSanity);
njn25e49d8e72002-09-23 09:36:25 +00001933 }
njn37cea302002-09-30 11:24:00 +00001934 VGP_POPCC(VgpCoreCheapSanity);
njn25e49d8e72002-09-23 09:36:25 +00001935}
sewardjde4a1d02002-03-22 01:27:54 +00001936/*--------------------------------------------------------------------*/
1937/*--- end vg_main.c ---*/
1938/*--------------------------------------------------------------------*/