blob: b409eea64d648c2a00dc4ac90427fe302ca2f276 [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
njn0e1b5142003-04-15 14:58:06 +000011 Copyright (C) 2000-2003 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
34/* ---------------------------------------------------------------------
35 Compute offsets into baseBlock. See comments in vg_include.h.
36 ------------------------------------------------------------------ */
37
38/* The variables storing offsets. */
39
40#define INVALID_OFFSET (-1)
41
42Int VGOFF_(m_eax) = INVALID_OFFSET;
43Int VGOFF_(m_ecx) = INVALID_OFFSET;
44Int VGOFF_(m_edx) = INVALID_OFFSET;
45Int VGOFF_(m_ebx) = INVALID_OFFSET;
46Int VGOFF_(m_esp) = INVALID_OFFSET;
47Int VGOFF_(m_ebp) = INVALID_OFFSET;
48Int VGOFF_(m_esi) = INVALID_OFFSET;
49Int VGOFF_(m_edi) = INVALID_OFFSET;
50Int VGOFF_(m_eflags) = INVALID_OFFSET;
sewardjfa492d42002-12-08 18:20:01 +000051Int VGOFF_(m_dflag) = INVALID_OFFSET;
sewardjb91ae7f2003-04-29 23:50:00 +000052Int VGOFF_(m_ssestate) = INVALID_OFFSET;
sewardj92a59562002-09-30 00:53:10 +000053Int VGOFF_(ldt) = INVALID_OFFSET;
54Int VGOFF_(m_cs) = INVALID_OFFSET;
55Int VGOFF_(m_ss) = INVALID_OFFSET;
56Int VGOFF_(m_ds) = INVALID_OFFSET;
57Int VGOFF_(m_es) = INVALID_OFFSET;
58Int VGOFF_(m_fs) = INVALID_OFFSET;
59Int VGOFF_(m_gs) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000060Int VGOFF_(m_eip) = INVALID_OFFSET;
61Int VGOFF_(spillslots) = INVALID_OFFSET;
62Int VGOFF_(sh_eax) = INVALID_OFFSET;
63Int VGOFF_(sh_ecx) = INVALID_OFFSET;
64Int VGOFF_(sh_edx) = INVALID_OFFSET;
65Int VGOFF_(sh_ebx) = INVALID_OFFSET;
66Int VGOFF_(sh_esp) = INVALID_OFFSET;
67Int VGOFF_(sh_ebp) = INVALID_OFFSET;
68Int VGOFF_(sh_esi) = INVALID_OFFSET;
69Int VGOFF_(sh_edi) = INVALID_OFFSET;
70Int VGOFF_(sh_eflags) = INVALID_OFFSET;
njn25e49d8e72002-09-23 09:36:25 +000071
sewardjde4a1d02002-03-22 01:27:54 +000072Int VGOFF_(helper_idiv_64_32) = INVALID_OFFSET;
73Int VGOFF_(helper_div_64_32) = INVALID_OFFSET;
74Int VGOFF_(helper_idiv_32_16) = INVALID_OFFSET;
75Int VGOFF_(helper_div_32_16) = INVALID_OFFSET;
76Int VGOFF_(helper_idiv_16_8) = INVALID_OFFSET;
77Int VGOFF_(helper_div_16_8) = INVALID_OFFSET;
78Int VGOFF_(helper_imul_32_64) = INVALID_OFFSET;
79Int VGOFF_(helper_mul_32_64) = INVALID_OFFSET;
80Int VGOFF_(helper_imul_16_32) = INVALID_OFFSET;
81Int VGOFF_(helper_mul_16_32) = INVALID_OFFSET;
82Int VGOFF_(helper_imul_8_16) = INVALID_OFFSET;
83Int VGOFF_(helper_mul_8_16) = INVALID_OFFSET;
84Int VGOFF_(helper_CLD) = INVALID_OFFSET;
85Int VGOFF_(helper_STD) = INVALID_OFFSET;
86Int VGOFF_(helper_get_dirflag) = INVALID_OFFSET;
sewardj7d78e782002-06-02 00:04:00 +000087Int VGOFF_(helper_CLC) = INVALID_OFFSET;
88Int VGOFF_(helper_STC) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000089Int VGOFF_(helper_shldl) = INVALID_OFFSET;
90Int VGOFF_(helper_shldw) = INVALID_OFFSET;
91Int VGOFF_(helper_shrdl) = INVALID_OFFSET;
92Int VGOFF_(helper_shrdw) = INVALID_OFFSET;
daywalkerb18d2532003-09-27 20:15:01 +000093Int VGOFF_(helper_IN) = INVALID_OFFSET;
94Int VGOFF_(helper_OUT) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000095Int VGOFF_(helper_RDTSC) = INVALID_OFFSET;
96Int VGOFF_(helper_CPUID) = INVALID_OFFSET;
97Int VGOFF_(helper_BSWAP) = INVALID_OFFSET;
sewardjde4a1d02002-03-22 01:27:54 +000098Int VGOFF_(helper_bsf) = INVALID_OFFSET;
99Int VGOFF_(helper_bsr) = INVALID_OFFSET;
100Int VGOFF_(helper_fstsw_AX) = INVALID_OFFSET;
101Int VGOFF_(helper_SAHF) = INVALID_OFFSET;
njnd6251f12003-06-03 13:38:51 +0000102Int VGOFF_(helper_LAHF) = INVALID_OFFSET;
sewardj4d0ab1f2002-03-24 10:00:09 +0000103Int VGOFF_(helper_DAS) = INVALID_OFFSET;
sewardjfe8a1662002-03-24 11:54:07 +0000104Int VGOFF_(helper_DAA) = INVALID_OFFSET;
sewardj51096432002-12-14 23:59:09 +0000105Int VGOFF_(helper_undefined_instruction) = INVALID_OFFSET;
njn25e49d8e72002-09-23 09:36:25 +0000106
107/* MAX_NONCOMPACT_HELPERS can be increased easily. If MAX_COMPACT_HELPERS is
108 * increased too much, they won't really be compact any more... */
109#define MAX_COMPACT_HELPERS 8
njnfedb7362003-02-24 10:21:45 +0000110#define MAX_NONCOMPACT_HELPERS 50
njn25e49d8e72002-09-23 09:36:25 +0000111
112UInt VG_(n_compact_helpers) = 0;
113UInt VG_(n_noncompact_helpers) = 0;
114
115Addr VG_(compact_helper_addrs) [MAX_COMPACT_HELPERS];
116Int VG_(compact_helper_offsets)[MAX_COMPACT_HELPERS];
117Addr VG_(noncompact_helper_addrs) [MAX_NONCOMPACT_HELPERS];
118Int VG_(noncompact_helper_offsets)[MAX_NONCOMPACT_HELPERS];
sewardjde4a1d02002-03-22 01:27:54 +0000119
120/* This is the actual defn of baseblock. */
121UInt VG_(baseBlock)[VG_BASEBLOCK_WORDS];
122
fitzhardinge98abfc72003-12-16 02:05:15 +0000123/* Client address space */
124Addr VG_(client_base); /* client address space limits */
125Addr VG_(client_end);
126Addr VG_(client_mapbase);
127Addr VG_(clstk_base);
128Addr VG_(clstk_end);
129Addr VG_(brk_base); /* start of brk */
130Addr VG_(brk_limit); /* current brk */
131Addr VG_(shadow_base); /* skin's shadow memory */
132Addr VG_(shadow_end);
133Addr VG_(valgrind_base); /* valgrind's address range */
134Addr VG_(valgrind_mmap_end); /* valgrind's mmaps are between valgrind_base and here */
135Addr VG_(valgrind_end);
136
137/* stage1 (main) executable */
fitzhardingea49f9b52003-12-16 22:26:45 +0000138Int VG_(vgexecfd) = -1;
139
140/* client executable */
141Int VG_(clexecfd) = -1;
fitzhardinge98abfc72003-12-16 02:05:15 +0000142
143/* Path to library directory */
144const Char *VG_(libdir) = VG_LIBDIR;
145
146/* our argc/argv */
147Int VG_(vg_argc);
148Char **VG_(vg_argv);
149
jsgf855d93d2003-10-13 22:26:55 +0000150/* PID of the main thread */
151Int VG_(main_pid);
152
153/* PGRP of process */
154Int VG_(main_pgrp);
njn25e49d8e72002-09-23 09:36:25 +0000155
sewardjde4a1d02002-03-22 01:27:54 +0000156/* Words. */
157static Int baB_off = 0;
158
jsgf855d93d2003-10-13 22:26:55 +0000159/* jmp_buf for fatal signals */
160Int VG_(fatal_sigNo) = -1;
161Bool VG_(fatal_signal_set) = False;
162jmp_buf VG_(fatal_signal_jmpbuf);
163
sewardjde4a1d02002-03-22 01:27:54 +0000164/* Returns the offset, in words. */
165static Int alloc_BaB ( Int words )
166{
167 Int off = baB_off;
168 baB_off += words;
169 if (baB_off >= VG_BASEBLOCK_WORDS)
njne427a662002-10-02 11:08:25 +0000170 VG_(core_panic)( "alloc_BaB: baseBlock is too small");
sewardjde4a1d02002-03-22 01:27:54 +0000171
172 return off;
173}
174
njn0c7a5b52003-04-30 09:00:33 +0000175/* Align offset, in *bytes* */
176static void align_BaB ( UInt align )
177{
178 vg_assert(2 == align || 4 == align || 8 == align || 16 == align);
179 baB_off += (align-1);
180 baB_off &= ~(align-1);
181}
182
sewardjde4a1d02002-03-22 01:27:54 +0000183/* Allocate 1 word in baseBlock and set it to the given value. */
daywalkerb106c422003-09-29 10:56:24 +0000184static Int alloc_BaB_1_set ( Addr a )
sewardjde4a1d02002-03-22 01:27:54 +0000185{
186 Int off = alloc_BaB(1);
187 VG_(baseBlock)[off] = (UInt)a;
188 return off;
189}
190
njn25e49d8e72002-09-23 09:36:25 +0000191/* Registers a function in compact_helper_addrs; compact_helper_offsets is
njn9b007f62003-04-07 14:40:25 +0000192 filled in later. */
njn25e49d8e72002-09-23 09:36:25 +0000193void VG_(register_compact_helper)(Addr a)
194{
195 if (MAX_COMPACT_HELPERS <= VG_(n_compact_helpers)) {
196 VG_(printf)("Can only register %d compact helpers\n",
197 MAX_COMPACT_HELPERS);
njne427a662002-10-02 11:08:25 +0000198 VG_(core_panic)("Too many compact helpers registered");
njn25e49d8e72002-09-23 09:36:25 +0000199 }
200 VG_(compact_helper_addrs)[VG_(n_compact_helpers)] = a;
201 VG_(n_compact_helpers)++;
202}
203
204/* Registers a function in noncompact_helper_addrs; noncompact_helper_offsets
205 * is filled in later.
206 */
207void VG_(register_noncompact_helper)(Addr a)
208{
209 if (MAX_NONCOMPACT_HELPERS <= VG_(n_noncompact_helpers)) {
210 VG_(printf)("Can only register %d non-compact helpers\n",
211 MAX_NONCOMPACT_HELPERS);
212 VG_(printf)("Try increasing MAX_NON_COMPACT_HELPERS\n");
njne427a662002-10-02 11:08:25 +0000213 VG_(core_panic)("Too many non-compact helpers registered");
njn25e49d8e72002-09-23 09:36:25 +0000214 }
215 VG_(noncompact_helper_addrs)[VG_(n_noncompact_helpers)] = a;
216 VG_(n_noncompact_helpers)++;
217}
218
219/* Allocate offsets in baseBlock for the skin helpers */
sewardj05bcdcb2003-05-18 10:05:38 +0000220static
221void assign_helpers_in_baseBlock(UInt n, Int offsets[], Addr addrs[])
njn25e49d8e72002-09-23 09:36:25 +0000222{
sewardj05bcdcb2003-05-18 10:05:38 +0000223 UInt i;
224 for (i = 0; i < n; i++)
daywalkerb106c422003-09-29 10:56:24 +0000225 offsets[i] = alloc_BaB_1_set( addrs[i] );
njn25e49d8e72002-09-23 09:36:25 +0000226}
sewardjde4a1d02002-03-22 01:27:54 +0000227
njnf4ce3d32003-02-10 10:17:26 +0000228Bool VG_(need_to_handle_esp_assignment)(void)
229{
fitzhardinge98abfc72003-12-16 02:05:15 +0000230 return ( VG_(defined_new_mem_stack_4)() ||
231 VG_(defined_die_mem_stack_4)() ||
232 VG_(defined_new_mem_stack_8)() ||
233 VG_(defined_die_mem_stack_8)() ||
234 VG_(defined_new_mem_stack_12)() ||
235 VG_(defined_die_mem_stack_12)() ||
236 VG_(defined_new_mem_stack_16)() ||
237 VG_(defined_die_mem_stack_16)() ||
238 VG_(defined_new_mem_stack_32)() ||
239 VG_(defined_die_mem_stack_32)() ||
240 VG_(defined_new_mem_stack)() ||
241 VG_(defined_die_mem_stack)()
njn9b007f62003-04-07 14:40:25 +0000242 );
njnf4ce3d32003-02-10 10:17:26 +0000243}
244
sewardjde4a1d02002-03-22 01:27:54 +0000245/* Here we assign actual offsets. It's important to get the most
246 popular referents within 128 bytes of the start, so we can take
247 advantage of short addressing modes relative to %ebp. Popularity
248 of offsets was measured on 22 Feb 02 running a KDE application, and
249 the slots rearranged accordingly, with a 1.5% reduction in total
250 size of translations. */
sewardjde4a1d02002-03-22 01:27:54 +0000251static void vg_init_baseBlock ( void )
252{
sewardjde4a1d02002-03-22 01:27:54 +0000253 /* Those with offsets under 128 are carefully chosen. */
254
255 /* WORD offsets in this column */
256 /* 0 */ VGOFF_(m_eax) = alloc_BaB(1);
257 /* 1 */ VGOFF_(m_ecx) = alloc_BaB(1);
258 /* 2 */ VGOFF_(m_edx) = alloc_BaB(1);
259 /* 3 */ VGOFF_(m_ebx) = alloc_BaB(1);
260 /* 4 */ VGOFF_(m_esp) = alloc_BaB(1);
261 /* 5 */ VGOFF_(m_ebp) = alloc_BaB(1);
262 /* 6 */ VGOFF_(m_esi) = alloc_BaB(1);
263 /* 7 */ VGOFF_(m_edi) = alloc_BaB(1);
264 /* 8 */ VGOFF_(m_eflags) = alloc_BaB(1);
265
njn25e49d8e72002-09-23 09:36:25 +0000266 if (VG_(needs).shadow_regs) {
267 /* 9 */ VGOFF_(sh_eax) = alloc_BaB(1);
268 /* 10 */ VGOFF_(sh_ecx) = alloc_BaB(1);
269 /* 11 */ VGOFF_(sh_edx) = alloc_BaB(1);
270 /* 12 */ VGOFF_(sh_ebx) = alloc_BaB(1);
271 /* 13 */ VGOFF_(sh_esp) = alloc_BaB(1);
272 /* 14 */ VGOFF_(sh_ebp) = alloc_BaB(1);
273 /* 15 */ VGOFF_(sh_esi) = alloc_BaB(1);
274 /* 16 */ VGOFF_(sh_edi) = alloc_BaB(1);
275 /* 17 */ VGOFF_(sh_eflags) = alloc_BaB(1);
276 }
sewardjde4a1d02002-03-22 01:27:54 +0000277
njn25e49d8e72002-09-23 09:36:25 +0000278 /* 9,10,11 or 18,19,20... depends on number whether shadow regs are used
279 * and on compact helpers registered */
njn4f9c9342002-04-29 16:03:24 +0000280
njn9b007f62003-04-07 14:40:25 +0000281 /* Make these most-frequently-called specialised ones compact, if they
282 are used. */
fitzhardinge98abfc72003-12-16 02:05:15 +0000283 if (VG_(defined_new_mem_stack_4)())
284 VG_(register_compact_helper)( (Addr) VG_(tool_interface).track_new_mem_stack_4);
sewardjde4a1d02002-03-22 01:27:54 +0000285
fitzhardinge98abfc72003-12-16 02:05:15 +0000286 if (VG_(defined_die_mem_stack_4)())
287 VG_(register_compact_helper)( (Addr) VG_(tool_interface).track_die_mem_stack_4);
njn9b007f62003-04-07 14:40:25 +0000288
289 /* (9 or 18) + n_compact_helpers */
njn25e49d8e72002-09-23 09:36:25 +0000290 /* Allocate slots for compact helpers */
291 assign_helpers_in_baseBlock(VG_(n_compact_helpers),
292 VG_(compact_helper_offsets),
293 VG_(compact_helper_addrs));
sewardjde4a1d02002-03-22 01:27:54 +0000294
njn25e49d8e72002-09-23 09:36:25 +0000295 /* (9/10 or 18/19) + n_compact_helpers */
sewardjde4a1d02002-03-22 01:27:54 +0000296 VGOFF_(m_eip) = alloc_BaB(1);
297
298 /* There are currently 24 spill slots */
njn25e49d8e72002-09-23 09:36:25 +0000299 /* (11+/20+ .. 32+/43+) + n_compact_helpers. This can overlap the magic
300 * boundary at >= 32 words, but most spills are to low numbered spill
301 * slots, so the ones above the boundary don't see much action. */
sewardjde4a1d02002-03-22 01:27:54 +0000302 VGOFF_(spillslots) = alloc_BaB(VG_MAX_SPILLSLOTS);
303
njn25e49d8e72002-09-23 09:36:25 +0000304 /* I gave up counting at this point. Since they're above the
sewardjde4a1d02002-03-22 01:27:54 +0000305 short-amode-boundary, there's no point. */
306
sewardjfa492d42002-12-08 18:20:01 +0000307 VGOFF_(m_dflag) = alloc_BaB(1);
308
sewardjb91ae7f2003-04-29 23:50:00 +0000309 /* The FPU/SSE state. This _must_ be 16-byte aligned. */
njn0c7a5b52003-04-30 09:00:33 +0000310 align_BaB(16);
sewardjb91ae7f2003-04-29 23:50:00 +0000311 VGOFF_(m_ssestate) = alloc_BaB(VG_SIZE_OF_SSESTATE_W);
312 vg_assert(
313 ( ((UInt)(& VG_(baseBlock)[VGOFF_(m_ssestate)]))
314 % 16 )
315 == 0
316 );
sewardjde4a1d02002-03-22 01:27:54 +0000317
sewardj92a59562002-09-30 00:53:10 +0000318 /* This thread's LDT pointer, and segment registers. */
319 VGOFF_(ldt) = alloc_BaB(1);
320 VGOFF_(m_cs) = alloc_BaB(1);
321 VGOFF_(m_ss) = alloc_BaB(1);
322 VGOFF_(m_ds) = alloc_BaB(1);
323 VGOFF_(m_es) = alloc_BaB(1);
324 VGOFF_(m_fs) = alloc_BaB(1);
325 VGOFF_(m_gs) = alloc_BaB(1);
326
sewardje1042472002-09-30 12:33:11 +0000327 VG_(register_noncompact_helper)( (Addr) & VG_(do_useseg) );
328
njn9b007f62003-04-07 14:40:25 +0000329#define REG(kind, size) \
fitzhardinge98abfc72003-12-16 02:05:15 +0000330 if (VG_(defined_##kind##_mem_stack##size)()) \
njn9b007f62003-04-07 14:40:25 +0000331 VG_(register_noncompact_helper)( \
fitzhardinge98abfc72003-12-16 02:05:15 +0000332 (Addr) VG_(tool_interface).track_##kind##_mem_stack##size );
njn9b007f62003-04-07 14:40:25 +0000333
334 REG(new, _8);
335 REG(new, _12);
336 REG(new, _16);
337 REG(new, _32);
338 REG(new, );
339 REG(die, _8);
340 REG(die, _12);
341 REG(die, _16);
342 REG(die, _32);
343 REG(die, );
344#undef REG
345
346 if (VG_(need_to_handle_esp_assignment)())
347 VG_(register_noncompact_helper)((Addr) VG_(unknown_esp_update));
348
sewardj92a59562002-09-30 00:53:10 +0000349 /* Helper functions. */
sewardjde4a1d02002-03-22 01:27:54 +0000350 VGOFF_(helper_idiv_64_32)
daywalkerb106c422003-09-29 10:56:24 +0000351 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_64_32));
sewardjde4a1d02002-03-22 01:27:54 +0000352 VGOFF_(helper_div_64_32)
daywalkerb106c422003-09-29 10:56:24 +0000353 = alloc_BaB_1_set( (Addr) & VG_(helper_div_64_32));
sewardjde4a1d02002-03-22 01:27:54 +0000354 VGOFF_(helper_idiv_32_16)
daywalkerb106c422003-09-29 10:56:24 +0000355 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_32_16));
sewardjde4a1d02002-03-22 01:27:54 +0000356 VGOFF_(helper_div_32_16)
daywalkerb106c422003-09-29 10:56:24 +0000357 = alloc_BaB_1_set( (Addr) & VG_(helper_div_32_16));
sewardjde4a1d02002-03-22 01:27:54 +0000358 VGOFF_(helper_idiv_16_8)
daywalkerb106c422003-09-29 10:56:24 +0000359 = alloc_BaB_1_set( (Addr) & VG_(helper_idiv_16_8));
sewardjde4a1d02002-03-22 01:27:54 +0000360 VGOFF_(helper_div_16_8)
daywalkerb106c422003-09-29 10:56:24 +0000361 = alloc_BaB_1_set( (Addr) & VG_(helper_div_16_8));
sewardjde4a1d02002-03-22 01:27:54 +0000362
363 VGOFF_(helper_imul_32_64)
daywalkerb106c422003-09-29 10:56:24 +0000364 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_32_64));
sewardjde4a1d02002-03-22 01:27:54 +0000365 VGOFF_(helper_mul_32_64)
daywalkerb106c422003-09-29 10:56:24 +0000366 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_32_64));
sewardjde4a1d02002-03-22 01:27:54 +0000367 VGOFF_(helper_imul_16_32)
daywalkerb106c422003-09-29 10:56:24 +0000368 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_16_32));
sewardjde4a1d02002-03-22 01:27:54 +0000369 VGOFF_(helper_mul_16_32)
daywalkerb106c422003-09-29 10:56:24 +0000370 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_16_32));
sewardjde4a1d02002-03-22 01:27:54 +0000371 VGOFF_(helper_imul_8_16)
daywalkerb106c422003-09-29 10:56:24 +0000372 = alloc_BaB_1_set( (Addr) & VG_(helper_imul_8_16));
sewardjde4a1d02002-03-22 01:27:54 +0000373 VGOFF_(helper_mul_8_16)
daywalkerb106c422003-09-29 10:56:24 +0000374 = alloc_BaB_1_set( (Addr) & VG_(helper_mul_8_16));
sewardjde4a1d02002-03-22 01:27:54 +0000375
376 VGOFF_(helper_CLD)
daywalkerb106c422003-09-29 10:56:24 +0000377 = alloc_BaB_1_set( (Addr) & VG_(helper_CLD));
sewardjde4a1d02002-03-22 01:27:54 +0000378 VGOFF_(helper_STD)
daywalkerb106c422003-09-29 10:56:24 +0000379 = alloc_BaB_1_set( (Addr) & VG_(helper_STD));
sewardjde4a1d02002-03-22 01:27:54 +0000380 VGOFF_(helper_get_dirflag)
daywalkerb106c422003-09-29 10:56:24 +0000381 = alloc_BaB_1_set( (Addr) & VG_(helper_get_dirflag));
sewardjde4a1d02002-03-22 01:27:54 +0000382
sewardj7d78e782002-06-02 00:04:00 +0000383 VGOFF_(helper_CLC)
daywalkerb106c422003-09-29 10:56:24 +0000384 = alloc_BaB_1_set( (Addr) & VG_(helper_CLC));
sewardj73cf3bc2002-11-03 03:20:15 +0000385 VGOFF_(helper_STC)
daywalkerb106c422003-09-29 10:56:24 +0000386 = alloc_BaB_1_set( (Addr) & VG_(helper_STC));
sewardj7d78e782002-06-02 00:04:00 +0000387
sewardjde4a1d02002-03-22 01:27:54 +0000388 VGOFF_(helper_shldl)
daywalkerb106c422003-09-29 10:56:24 +0000389 = alloc_BaB_1_set( (Addr) & VG_(helper_shldl));
sewardjde4a1d02002-03-22 01:27:54 +0000390 VGOFF_(helper_shldw)
daywalkerb106c422003-09-29 10:56:24 +0000391 = alloc_BaB_1_set( (Addr) & VG_(helper_shldw));
sewardjde4a1d02002-03-22 01:27:54 +0000392 VGOFF_(helper_shrdl)
daywalkerb106c422003-09-29 10:56:24 +0000393 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdl));
sewardjde4a1d02002-03-22 01:27:54 +0000394 VGOFF_(helper_shrdw)
daywalkerb106c422003-09-29 10:56:24 +0000395 = alloc_BaB_1_set( (Addr) & VG_(helper_shrdw));
sewardjde4a1d02002-03-22 01:27:54 +0000396
397 VGOFF_(helper_RDTSC)
daywalkerb106c422003-09-29 10:56:24 +0000398 = alloc_BaB_1_set( (Addr) & VG_(helper_RDTSC));
sewardjde4a1d02002-03-22 01:27:54 +0000399 VGOFF_(helper_CPUID)
daywalkerb106c422003-09-29 10:56:24 +0000400 = alloc_BaB_1_set( (Addr) & VG_(helper_CPUID));
sewardjde4a1d02002-03-22 01:27:54 +0000401
sewardjde4a1d02002-03-22 01:27:54 +0000402 VGOFF_(helper_bsf)
daywalkerb106c422003-09-29 10:56:24 +0000403 = alloc_BaB_1_set( (Addr) & VG_(helper_bsf));
sewardjde4a1d02002-03-22 01:27:54 +0000404 VGOFF_(helper_bsr)
daywalkerb106c422003-09-29 10:56:24 +0000405 = alloc_BaB_1_set( (Addr) & VG_(helper_bsr));
sewardjde4a1d02002-03-22 01:27:54 +0000406
407 VGOFF_(helper_fstsw_AX)
daywalkerb106c422003-09-29 10:56:24 +0000408 = alloc_BaB_1_set( (Addr) & VG_(helper_fstsw_AX));
sewardjde4a1d02002-03-22 01:27:54 +0000409 VGOFF_(helper_SAHF)
daywalkerb106c422003-09-29 10:56:24 +0000410 = alloc_BaB_1_set( (Addr) & VG_(helper_SAHF));
njnd6251f12003-06-03 13:38:51 +0000411 VGOFF_(helper_LAHF)
daywalkerb106c422003-09-29 10:56:24 +0000412 = alloc_BaB_1_set( (Addr) & VG_(helper_LAHF));
sewardj4d0ab1f2002-03-24 10:00:09 +0000413 VGOFF_(helper_DAS)
daywalkerb106c422003-09-29 10:56:24 +0000414 = alloc_BaB_1_set( (Addr) & VG_(helper_DAS));
sewardjfe8a1662002-03-24 11:54:07 +0000415 VGOFF_(helper_DAA)
daywalkerb106c422003-09-29 10:56:24 +0000416 = alloc_BaB_1_set( (Addr) & VG_(helper_DAA));
daywalkerb18d2532003-09-27 20:15:01 +0000417 VGOFF_(helper_IN)
daywalkerb106c422003-09-29 10:56:24 +0000418 = alloc_BaB_1_set( (Addr) & VG_(helper_IN));
daywalkerb18d2532003-09-27 20:15:01 +0000419 VGOFF_(helper_OUT)
daywalkerb106c422003-09-29 10:56:24 +0000420 = alloc_BaB_1_set( (Addr) & VG_(helper_OUT));
njn25e49d8e72002-09-23 09:36:25 +0000421
sewardj51096432002-12-14 23:59:09 +0000422 VGOFF_(helper_undefined_instruction)
daywalkerb106c422003-09-29 10:56:24 +0000423 = alloc_BaB_1_set( (Addr) & VG_(helper_undefined_instruction));
sewardj51096432002-12-14 23:59:09 +0000424
sewardj92a59562002-09-30 00:53:10 +0000425 /* Allocate slots for noncompact helpers */
njn25e49d8e72002-09-23 09:36:25 +0000426 assign_helpers_in_baseBlock(VG_(n_noncompact_helpers),
427 VG_(noncompact_helper_offsets),
428 VG_(noncompact_helper_addrs));
njn25e49d8e72002-09-23 09:36:25 +0000429
njncc7bb472002-10-14 09:25:19 +0000430
431 /* Initialise slots that require it */
432 VG_(copy_m_state_static_to_baseBlock)();
433
434 /* Pretend the root thread has a completely empty LDT to start with. */
435 VG_(baseBlock)[VGOFF_(ldt)] = (UInt)NULL;
436
437 /* Initialise shadow regs */
njn25e49d8e72002-09-23 09:36:25 +0000438 if (VG_(needs).shadow_regs) {
njn25e49d8e72002-09-23 09:36:25 +0000439 VG_(baseBlock)[VGOFF_(sh_esp)] =
440 VG_(baseBlock)[VGOFF_(sh_ebp)] =
441 VG_(baseBlock)[VGOFF_(sh_eax)] =
442 VG_(baseBlock)[VGOFF_(sh_ecx)] =
443 VG_(baseBlock)[VGOFF_(sh_edx)] =
444 VG_(baseBlock)[VGOFF_(sh_ebx)] =
445 VG_(baseBlock)[VGOFF_(sh_esi)] =
njnd3040452003-05-19 15:04:06 +0000446 VG_(baseBlock)[VGOFF_(sh_edi)] = 0;
447 VG_(baseBlock)[VGOFF_(sh_eflags)] = 0;
448 VG_TRACK( post_regs_write_init );
njncc7bb472002-10-14 09:25:19 +0000449 }
sewardjde4a1d02002-03-22 01:27:54 +0000450}
451
452
453/* ---------------------------------------------------------------------
454 Global entities which are not referenced from generated code.
455 ------------------------------------------------------------------ */
456
sewardjde4a1d02002-03-22 01:27:54 +0000457/* Ditto our signal delivery stack. */
njn6eba4ef2003-05-01 08:06:41 +0000458UInt VG_(sigstack)[VG_SIGSTACK_SIZE_W];
sewardjde4a1d02002-03-22 01:27:54 +0000459
460/* Saving stuff across system calls. */
sewardjb91ae7f2003-04-29 23:50:00 +0000461__attribute__ ((aligned (16)))
462UInt VG_(real_sse_state_saved_over_syscall)[VG_SIZE_OF_SSESTATE_W];
sewardj43c356f2002-06-02 00:21:08 +0000463Addr VG_(esp_saved_over_syscall);
sewardjde4a1d02002-03-22 01:27:54 +0000464
465/* Counts downwards in vg_run_innerloop. */
466UInt VG_(dispatch_ctr);
467
sewardjde4a1d02002-03-22 01:27:54 +0000468
469/* 64-bit counter for the number of basic blocks done. */
470ULong VG_(bbs_done);
471/* 64-bit counter for the number of bbs to go before a debug exit. */
472ULong VG_(bbs_to_go);
473
sewardj7e87e382002-05-03 19:09:05 +0000474/* This is the ThreadId of the last thread the scheduler ran. */
475ThreadId VG_(last_run_tid) = 0;
476
njn25e49d8e72002-09-23 09:36:25 +0000477/* This is the argument to __NR_exit() supplied by the first thread to
478 call that syscall. We eventually pass that to __NR_exit() for
479 real. */
njn633de322003-05-12 20:40:13 +0000480Int VG_(exitcode) = 0;
njn25e49d8e72002-09-23 09:36:25 +0000481
sewardj73cf3bc2002-11-03 03:20:15 +0000482/* Tell the logging mechanism whether we are logging to a file
483 descriptor or a socket descriptor. */
484Bool VG_(logging_to_filedes) = True;
485
sewardjb91ae7f2003-04-29 23:50:00 +0000486/* Is this a SSE/SSE2-capable CPU? If so, we had better save/restore
487 the SSE state all over the place. This is set up very early, in
488 vg_startup.S. We have to determine it early since we can't even
489 correctly snapshot the startup machine state without it. */
490/* Initially True. Safer to err on the side of SSEness and get SIGILL
daywalker7e73e5f2003-07-04 16:18:15 +0000491 than to not notice for some reason that we have SSE and get weird
sewardjb91ae7f2003-04-29 23:50:00 +0000492 errors later on. */
493Bool VG_(have_ssestate) = True;
494
sewardjde4a1d02002-03-22 01:27:54 +0000495
496/* ---------------------------------------------------------------------
497 Counters, for informational purposes only.
498 ------------------------------------------------------------------ */
499
500/* Number of lookups which miss the fast tt helper. */
501UInt VG_(tt_fast_misses) = 0;
502
503
sewardjc0d8f682002-11-30 00:49:43 +0000504/* Counts for TT/TC informational messages. */
sewardjde4a1d02002-03-22 01:27:54 +0000505
sewardjde4a1d02002-03-22 01:27:54 +0000506/* Number and total o/t size of translations overall. */
507UInt VG_(overall_in_count) = 0;
508UInt VG_(overall_in_osize) = 0;
509UInt VG_(overall_in_tsize) = 0;
510/* Number and total o/t size of discards overall. */
511UInt VG_(overall_out_count) = 0;
512UInt VG_(overall_out_osize) = 0;
513UInt VG_(overall_out_tsize) = 0;
sewardjc0d8f682002-11-30 00:49:43 +0000514/* The number of discards of TT/TC. */
515UInt VG_(number_of_tc_discards) = 0;
sewardj22854b92002-11-30 14:00:47 +0000516/* Counts of chain and unchain operations done. */
517UInt VG_(bb_enchain_count) = 0;
518UInt VG_(bb_dechain_count) = 0;
519/* Number of unchained jumps performed. */
520UInt VG_(unchained_jumps_done) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000521
522
523/* Counts pertaining to the register allocator. */
524
525/* total number of uinstrs input to reg-alloc */
526UInt VG_(uinstrs_prealloc) = 0;
527
528/* total number of uinstrs added due to spill code */
529UInt VG_(uinstrs_spill) = 0;
530
531/* number of bbs requiring spill code */
532UInt VG_(translations_needing_spill) = 0;
533
534/* total of register ranks over all translations */
535UInt VG_(total_reg_rank) = 0;
536
537
sewardjde4a1d02002-03-22 01:27:54 +0000538/* Counts pertaining to internal sanity checking. */
sewardjde4a1d02002-03-22 01:27:54 +0000539UInt VG_(sanity_fast_count) = 0;
540UInt VG_(sanity_slow_count) = 0;
541
sewardj2e93c502002-04-12 11:12:52 +0000542/* Counts pertaining to the scheduler. */
543UInt VG_(num_scheduling_events_MINOR) = 0;
544UInt VG_(num_scheduling_events_MAJOR) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000545
546
547/* ---------------------------------------------------------------------
548 Values derived from command-line options.
549 ------------------------------------------------------------------ */
550
njn25e49d8e72002-09-23 09:36:25 +0000551/* Define, and set defaults. */
552Bool VG_(clo_error_limit) = True;
553Bool VG_(clo_GDB_attach) = False;
sewardj6024b212003-07-13 10:54:33 +0000554Char* VG_(clo_GDB_path) = GDB_PATH;
njn43c799e2003-04-08 00:08:52 +0000555Bool VG_(clo_gen_suppressions) = False;
njn25e49d8e72002-09-23 09:36:25 +0000556Int VG_(sanity_level) = 1;
557Int VG_(clo_verbosity) = 1;
558Bool VG_(clo_demangle) = True;
njn25e49d8e72002-09-23 09:36:25 +0000559Bool VG_(clo_trace_children) = False;
sewardj4cf05692002-10-27 20:28:29 +0000560
nethercotee1730692003-11-20 10:38:07 +0000561/* See big comment in vg_include.h for meaning of these three.
562 fd is initially stdout, for --help, but gets moved to stderr by default
563 immediately afterwards. */
sewardj4cf05692002-10-27 20:28:29 +0000564VgLogTo VG_(clo_log_to) = VgLogTo_Fd;
nethercotee1730692003-11-20 10:38:07 +0000565Int VG_(clo_logfile_fd) = 1;
sewardj4cf05692002-10-27 20:28:29 +0000566Char* VG_(clo_logfile_name) = NULL;
567
sewardj6024b212003-07-13 10:54:33 +0000568Int VG_(clo_input_fd) = 0; /* stdin */
njn25e49d8e72002-09-23 09:36:25 +0000569Int VG_(clo_n_suppressions) = 0;
sewardjde4a1d02002-03-22 01:27:54 +0000570Char* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
njn25e49d8e72002-09-23 09:36:25 +0000571Bool VG_(clo_profile) = False;
572Bool VG_(clo_single_step) = False;
573Bool VG_(clo_optimise) = True;
574UChar VG_(clo_trace_codegen) = 0; // 00000000b
575Bool VG_(clo_trace_syscalls) = False;
576Bool VG_(clo_trace_signals) = False;
577Bool VG_(clo_trace_symtab) = False;
njn25e49d8e72002-09-23 09:36:25 +0000578Bool VG_(clo_trace_sched) = False;
579Int VG_(clo_trace_pthread_level) = 0;
sewardj59438c02003-01-05 12:16:30 +0000580ULong VG_(clo_stop_after) = 1000000000000000LL;
njn25e49d8e72002-09-23 09:36:25 +0000581Int VG_(clo_dump_error) = 0;
582Int VG_(clo_backtrace_size) = 4;
583Char* VG_(clo_weird_hacks) = NULL;
sewardj858964b2002-10-05 14:15:43 +0000584Bool VG_(clo_run_libc_freeres) = True;
rjwalshf5f536f2003-11-17 17:45:00 +0000585Bool VG_(clo_track_fds) = False;
sewardj22854b92002-11-30 14:00:47 +0000586Bool VG_(clo_chain_bb) = True;
nethercote77eba602003-11-13 17:35:04 +0000587Bool VG_(clo_show_below_main) = False;
fitzhardinge98abfc72003-12-16 02:05:15 +0000588Bool VG_(clo_pointercheck) = True;
sewardj2370f3b2002-11-30 15:01:01 +0000589
jsgf855d93d2003-10-13 22:26:55 +0000590static Bool VG_(clo_wait_for_gdb) = False;
591
592/* If we're doing signal routing, poll for signals every 50mS by
593 default. */
594Int VG_(clo_signal_polltime) = 50;
595
596/* These flags reduce thread wakeup latency on syscall completion and
597 signal delivery, respectively. The downside is possible unfairness. */
598Bool VG_(clo_lowlat_syscalls) = False; /* low-latency syscalls */
599Bool VG_(clo_lowlat_signals) = False; /* low-latency signals */
600
sewardjde4a1d02002-03-22 01:27:54 +0000601/* This Bool is needed by wrappers in vg_clientmalloc.c to decide how
602 to behave. Initially we say False. */
603Bool VG_(running_on_simd_CPU) = False;
604
605/* Holds client's %esp at the point we gained control. */
606Addr VG_(esp_at_startup);
607
sewardjd5815ec2003-04-06 12:23:27 +0000608/* Indicates presence, and holds address of client's sysinfo page, a
609 feature of some modern kernels used to provide vsyscalls, etc. */
610Bool VG_(sysinfo_page_exists) = False;
611Addr VG_(sysinfo_page_addr) = 0;
612
sewardjde4a1d02002-03-22 01:27:54 +0000613/* As deduced from VG_(esp_at_startup), the client's argc, argv[] and
614 envp[] as extracted from the client's stack at startup-time. */
615Int VG_(client_argc);
616Char** VG_(client_argv);
617Char** VG_(client_envp);
618
sewardjde4a1d02002-03-22 01:27:54 +0000619/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000620 Processing of command-line options.
621 ------------------------------------------------------------------ */
622
njn25e49d8e72002-09-23 09:36:25 +0000623void VG_(bad_option) ( Char* opt )
sewardjde4a1d02002-03-22 01:27:54 +0000624{
625 VG_(shutdown_logging)();
sewardj4cf05692002-10-27 20:28:29 +0000626 VG_(clo_log_to) = VgLogTo_Fd;
sewardjde4a1d02002-03-22 01:27:54 +0000627 VG_(clo_logfile_fd) = 2; /* stderr */
628 VG_(printf)("valgrind.so: Bad option `%s'; aborting.\n", opt);
629 VG_(exit)(1);
630}
631
632static void config_error ( Char* msg )
633{
634 VG_(shutdown_logging)();
sewardj4cf05692002-10-27 20:28:29 +0000635 VG_(clo_log_to) = VgLogTo_Fd;
sewardjde4a1d02002-03-22 01:27:54 +0000636 VG_(clo_logfile_fd) = 2; /* stderr */
sewardj19d81412002-06-03 01:10:40 +0000637 VG_(printf)(
fitzhardinge98abfc72003-12-16 02:05:15 +0000638 "valgrind: Startup or configuration error:\n %s\n", msg);
sewardj19d81412002-06-03 01:10:40 +0000639 VG_(printf)(
fitzhardinge98abfc72003-12-16 02:05:15 +0000640 "valgrind: Unable to start up properly. Giving up.\n");
sewardjde4a1d02002-03-22 01:27:54 +0000641 VG_(exit)(1);
642}
643
fitzhardinge98abfc72003-12-16 02:05:15 +0000644void VG_(usage) ( void )
njn7cf0bd32002-06-08 13:36:03 +0000645{
njn25e49d8e72002-09-23 09:36:25 +0000646 Char* usage1 =
647"usage: valgrind [options] prog-and-args\n"
648"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000649" common user options for all Valgrind tools, with defaults in [ ]:\n"
nethercote137bc552003-11-14 17:47:54 +0000650" --tool=<name> Use the Valgrind tool named <name> [memcheck]\n"
njn25e49d8e72002-09-23 09:36:25 +0000651" --help show this message\n"
652" --version show version\n"
njn25e49d8e72002-09-23 09:36:25 +0000653" -q --quiet run silently; only print error msgs\n"
654" -v --verbose be more verbose, incl counts of errors\n"
nethercote77eba602003-11-13 17:35:04 +0000655" --trace-children=no|yes Valgrind-ise child processes? [no]\n"
rjwalshf5f536f2003-11-17 17:45:00 +0000656" --track-fds=no|yes Track open file descriptors? [no]\n"
nethercote2b0793f2003-12-02 10:41:18 +0000657"\n"
658" uncommon user options for all Valgrind tools:\n"
nethercote77eba602003-11-13 17:35:04 +0000659" --run-libc-freeres=no|yes Free up glibc memory at exit? [yes]\n"
660" --weird-hacks=hack1,hack2,... [none]\n"
sewardj3d652a32002-10-20 18:11:49 +0000661" recognised hacks are: ioctl-VTIME truncate-writes lax-ioctls\n"
jsgf855d93d2003-10-13 22:26:55 +0000662" --signal-polltime=<time> time, in mS, we should poll for signals.\n"
663" Only applies for older kernels which need\n"
664" signal routing [50]\n"
665" --lowlat-signals=no|yes improve wake-up latency when a thread receives\n"
666" a signal [no]\n"
667" --lowlat-syscalls=no|yes improve wake-up latency when a thread's\n"
668" syscall completes [no]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000669" --pointercheck=no|yes enforce client address space limits [yes]\n"
njn25e49d8e72002-09-23 09:36:25 +0000670"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000671" user options for Valgrind tools that report errors:\n"
672" --logfile-fd=<number> file descriptor for messages [2=stderr]\n"
673" --logfile=<file> log messages to <file>.pid<pid>\n"
674" --logsocket=ipaddr:port log messages to socket ipaddr:port\n"
675" --demangle=no|yes automatically demangle C++ names? [yes]\n"
676" --num-callers=<number> show <num> callers in stack traces [4]\n"
677" --error-limit=no|yes stop showing new errors if too many? [yes]\n"
678" --show-below-main=no|yes continue stack traces below main() [no]\n"
679" --suppressions=<filename> suppress errors described in <filename>\n"
680" --gen-suppressions=no|yes print suppressions for errors detected [no]\n"
njn7cf0bd32002-06-08 13:36:03 +0000681
nethercote2b0793f2003-12-02 10:41:18 +0000682" --gdb-attach=no|yes start GDB when errors detected? [no]\n"
683" --gdb-path=/path/to/gdb path to the GDB to use [/usr/bin/gdb]\n"
684" --input-fd=<number> file descriptor for (gdb) input [0=stdin]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000685"\n";
njn7cf0bd32002-06-08 13:36:03 +0000686
njn25e49d8e72002-09-23 09:36:25 +0000687 Char* usage2 =
688"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000689" debugging options for all Valgrind tools:\n"
njn25e49d8e72002-09-23 09:36:25 +0000690" --sanity-level=<number> level of sanity checking to do [1]\n"
691" --single-step=no|yes translate each instr separately? [no]\n"
692" --optimise=no|yes improve intermediate code? [yes]\n"
nethercote137bc552003-11-14 17:47:54 +0000693" --profile=no|yes profile? (tool must be built for it) [no]\n"
sewardj22854b92002-11-30 14:00:47 +0000694" --chain-bb=no|yes do basic-block chaining? [yes]\n"
njn25e49d8e72002-09-23 09:36:25 +0000695" --trace-codegen=<XXXXX> show generated code? (X = 0|1) [00000]\n"
696" --trace-syscalls=no|yes show all system calls? [no]\n"
697" --trace-signals=no|yes show signal handling details? [no]\n"
698" --trace-symtab=no|yes show symbol table details? [no]\n"
njn25e49d8e72002-09-23 09:36:25 +0000699" --trace-sched=no|yes show thread scheduler details? [no]\n"
njn3e884182003-04-15 13:03:23 +0000700" --trace-pthread=none|some|all show pthread event details? [none]\n"
njn25e49d8e72002-09-23 09:36:25 +0000701" --stop-after=<number> switch to real CPU after executing\n"
702" <number> basic blocks [infinity]\n"
jsgf855d93d2003-10-13 22:26:55 +0000703" --wait-for-gdb=yes|no pause on startup to wait for gdb attach\n"
njn25e49d8e72002-09-23 09:36:25 +0000704"\n"
nethercote2b0793f2003-12-02 10:41:18 +0000705" debugging options for Valgrind tools that report errors\n"
706" --dump-error=<number> show translation for basic block associated\n"
707" with <number>'th error context [0=show none]\n"
fitzhardinge98abfc72003-12-16 02:05:15 +0000708"\n";
njn3e884182003-04-15 13:03:23 +0000709
710 Char* usage3 =
711"\n"
njn25e49d8e72002-09-23 09:36:25 +0000712" Extra options are read from env variable $VALGRIND_OPTS\n"
713"\n"
njn0e1b5142003-04-15 14:58:06 +0000714" Valgrind is Copyright (C) 2000-2003 Julian Seward\n"
njn25e49d8e72002-09-23 09:36:25 +0000715" and licensed under the GNU General Public License, version 2.\n"
716" Bug reports, feedback, admiration, abuse, etc, to: %s.\n"
njnd04b7c62002-10-03 14:05:52 +0000717"\n"
nethercote137bc552003-11-14 17:47:54 +0000718" Tools are copyright and licensed by their authors. See each\n"
719" tool's start-up message for more information.\n"
njn25e49d8e72002-09-23 09:36:25 +0000720"\n";
njn7cf0bd32002-06-08 13:36:03 +0000721
fitzhardinge98abfc72003-12-16 02:05:15 +0000722 VG_(printf)(usage1);
723 if (VG_(details).name) {
724 VG_(printf)(" user options for %s:\n", VG_(details).name);
725 /* Don't print skin string directly for security, ha! */
726 if (VG_(needs).command_line_options)
727 SK_(print_usage)();
728 else
729 VG_(printf)(" (none)\n");
730 }
731 VG_(printf)(usage2);
732
733 if (VG_(details).name) {
734 VG_(printf)(" debugging options for %s:\n", VG_(details).name);
735
736 if (VG_(needs).command_line_options)
737 SK_(print_debug_usage)();
738 else
739 VG_(printf)(" (none)\n");
740 }
nethercote421281e2003-11-20 16:20:55 +0000741 VG_(printf)(usage3, VG_BUGS_TO);
njn7cf0bd32002-06-08 13:36:03 +0000742
njn25e49d8e72002-09-23 09:36:25 +0000743 VG_(shutdown_logging)();
sewardj4cf05692002-10-27 20:28:29 +0000744 VG_(clo_log_to) = VgLogTo_Fd;
njn25e49d8e72002-09-23 09:36:25 +0000745 VG_(clo_logfile_fd) = 2; /* stderr */
746 VG_(exit)(1);
njn7cf0bd32002-06-08 13:36:03 +0000747}
sewardjde4a1d02002-03-22 01:27:54 +0000748
sewardj1c1b1162003-02-23 01:25:51 +0000749
fitzhardinge98abfc72003-12-16 02:05:15 +0000750static void process_cmd_line_options ( const KickstartParams *kp )
sewardj1c1b1162003-02-23 01:25:51 +0000751{
fitzhardinge98abfc72003-12-16 02:05:15 +0000752 Int argc;
753 Char **argv;
754 Int i, eventually_logfile_fd;
755 Int *auxp;
sewardjde4a1d02002-03-22 01:27:54 +0000756
757# define ISSPACE(cc) ((cc) == ' ' || (cc) == '\t' || (cc) == '\n')
sewardjde4a1d02002-03-22 01:27:54 +0000758
nethercotee1730692003-11-20 10:38:07 +0000759 /* log to stderr by default, but usage message goes to stdout */
760 eventually_logfile_fd = 2;
sewardjde4a1d02002-03-22 01:27:54 +0000761
762 /* Once logging is started, we can safely send messages pertaining
763 to failures in initialisation. */
764 VG_(startup_logging)();
765
sewardj19d81412002-06-03 01:10:40 +0000766 /* Check for sane path in ./configure --prefix=... */
fitzhardinge98abfc72003-12-16 02:05:15 +0000767 if (VG_LIBDIR[0] != '/')
sewardj19d81412002-06-03 01:10:40 +0000768 config_error("Please use absolute paths in "
769 "./configure --prefix=... or --libdir=...");
sewardj38170912002-05-10 21:07:22 +0000770
fitzhardinge98abfc72003-12-16 02:05:15 +0000771 for(auxp = kp->client_auxv; auxp[0] != VKI_AT_NULL; auxp += 2) {
772 switch(auxp[0]) {
773 case VKI_AT_SYSINFO:
774 VG_(sysinfo_page_exists) = True;
775 VG_(sysinfo_page_addr) = auxp[1];
776 break;
sewardjde4a1d02002-03-22 01:27:54 +0000777 }
fitzhardinge98abfc72003-12-16 02:05:15 +0000778 }
sewardjde4a1d02002-03-22 01:27:54 +0000779
fitzhardinge98abfc72003-12-16 02:05:15 +0000780 VG_(client_envp) = kp->client_envp;
sewardjde4a1d02002-03-22 01:27:54 +0000781
fitzhardinge98abfc72003-12-16 02:05:15 +0000782 argc = kp->argc;
783 argv = kp->argv;
784
785 VG_(vg_argc) = argc;
786 VG_(vg_argv) = argv;
787
788 /* We know the initial ESP is pointing at argc/argv */
789 VG_(client_argc) = *(Int *)kp->client_esp;
790 VG_(client_argv) = (Char **)(kp->client_esp + sizeof(Int));
791
792 for (i = 1; i < argc; i++) {
793 /* Ignore these options - they've already been handled */
794 if (VG_CLO_STREQN(7, argv[i], "--tool=") ||
795 VG_CLO_STREQN(7, argv[i], "--skin="))
796 continue;
797 if (VG_CLO_STREQN(7, argv[i], "--exec="))
798 continue;
799
800 if ( VG_CLO_STREQ(argv[i], "--"))
801 continue;
802 else if (VG_CLO_STREQ(argv[i], "-v") ||
njn43c799e2003-04-08 00:08:52 +0000803 VG_CLO_STREQ(argv[i], "--verbose"))
sewardjde4a1d02002-03-22 01:27:54 +0000804 VG_(clo_verbosity)++;
njn43c799e2003-04-08 00:08:52 +0000805 else if (VG_CLO_STREQ(argv[i], "-q") ||
806 VG_CLO_STREQ(argv[i], "--quiet"))
sewardjde4a1d02002-03-22 01:27:54 +0000807 VG_(clo_verbosity)--;
808
njn43c799e2003-04-08 00:08:52 +0000809 else if (VG_CLO_STREQ(argv[i], "--error-limit=yes"))
sewardj2e432902002-06-13 20:44:00 +0000810 VG_(clo_error_limit) = True;
njn43c799e2003-04-08 00:08:52 +0000811 else if (VG_CLO_STREQ(argv[i], "--error-limit=no"))
sewardj2e432902002-06-13 20:44:00 +0000812 VG_(clo_error_limit) = False;
sewardj72f98ff2002-06-13 17:23:38 +0000813
njn43c799e2003-04-08 00:08:52 +0000814 else if (VG_CLO_STREQ(argv[i], "--gdb-attach=yes"))
sewardjde4a1d02002-03-22 01:27:54 +0000815 VG_(clo_GDB_attach) = True;
njn43c799e2003-04-08 00:08:52 +0000816 else if (VG_CLO_STREQ(argv[i], "--gdb-attach=no"))
sewardjde4a1d02002-03-22 01:27:54 +0000817 VG_(clo_GDB_attach) = False;
818
sewardj6024b212003-07-13 10:54:33 +0000819 else if (VG_CLO_STREQN(11,argv[i], "--gdb-path="))
820 VG_(clo_GDB_path) = &argv[i][11];
821
njn43c799e2003-04-08 00:08:52 +0000822 else if (VG_CLO_STREQ(argv[i], "--gen-suppressions=yes"))
823 VG_(clo_gen_suppressions) = True;
824 else if (VG_CLO_STREQ(argv[i], "--gen-suppressions=no"))
825 VG_(clo_gen_suppressions) = False;
826
nethercote77eba602003-11-13 17:35:04 +0000827 else if (VG_CLO_STREQ(argv[i], "--show-below-main=yes"))
828 VG_(clo_show_below_main) = True;
829 else if (VG_CLO_STREQ(argv[i], "--show-below-main=no"))
830 VG_(clo_show_below_main) = False;
831
fitzhardinge98abfc72003-12-16 02:05:15 +0000832 else if (VG_CLO_STREQ(argv[i], "--pointercheck=yes"))
833 VG_(clo_pointercheck) = True;
834 else if (VG_CLO_STREQ(argv[i], "--pointercheck=no"))
835 VG_(clo_pointercheck) = False;
836
njn43c799e2003-04-08 00:08:52 +0000837 else if (VG_CLO_STREQ(argv[i], "--demangle=yes"))
sewardjde4a1d02002-03-22 01:27:54 +0000838 VG_(clo_demangle) = True;
njn43c799e2003-04-08 00:08:52 +0000839 else if (VG_CLO_STREQ(argv[i], "--demangle=no"))
sewardjde4a1d02002-03-22 01:27:54 +0000840 VG_(clo_demangle) = False;
841
njn43c799e2003-04-08 00:08:52 +0000842 else if (VG_CLO_STREQ(argv[i], "--trace-children=yes"))
sewardjde4a1d02002-03-22 01:27:54 +0000843 VG_(clo_trace_children) = True;
njn43c799e2003-04-08 00:08:52 +0000844 else if (VG_CLO_STREQ(argv[i], "--trace-children=no"))
sewardjde4a1d02002-03-22 01:27:54 +0000845 VG_(clo_trace_children) = False;
846
njn43c799e2003-04-08 00:08:52 +0000847 else if (VG_CLO_STREQ(argv[i], "--run-libc-freeres=yes"))
sewardj858964b2002-10-05 14:15:43 +0000848 VG_(clo_run_libc_freeres) = True;
njn43c799e2003-04-08 00:08:52 +0000849 else if (VG_CLO_STREQ(argv[i], "--run-libc-freeres=no"))
sewardj858964b2002-10-05 14:15:43 +0000850 VG_(clo_run_libc_freeres) = False;
851
rjwalshf5f536f2003-11-17 17:45:00 +0000852 else if (VG_CLO_STREQ(argv[i], "--track-fds=yes"))
853 VG_(clo_track_fds) = True;
854 else if (VG_CLO_STREQ(argv[i], "--track-fds=no"))
855 VG_(clo_track_fds) = False;
856
njn43c799e2003-04-08 00:08:52 +0000857 else if (VG_CLO_STREQN(15, argv[i], "--sanity-level="))
sewardjde4a1d02002-03-22 01:27:54 +0000858 VG_(sanity_level) = (Int)VG_(atoll)(&argv[i][15]);
859
njn43c799e2003-04-08 00:08:52 +0000860 else if (VG_CLO_STREQN(13, argv[i], "--logfile-fd=")) {
sewardj4cf05692002-10-27 20:28:29 +0000861 VG_(clo_log_to) = VgLogTo_Fd;
862 VG_(clo_logfile_name) = NULL;
sewardjde4a1d02002-03-22 01:27:54 +0000863 eventually_logfile_fd = (Int)VG_(atoll)(&argv[i][13]);
sewardj4cf05692002-10-27 20:28:29 +0000864 }
865
njn43c799e2003-04-08 00:08:52 +0000866 else if (VG_CLO_STREQN(10, argv[i], "--logfile=")) {
sewardj4cf05692002-10-27 20:28:29 +0000867 VG_(clo_log_to) = VgLogTo_File;
868 VG_(clo_logfile_name) = &argv[i][10];
869 }
sewardjde4a1d02002-03-22 01:27:54 +0000870
njn43c799e2003-04-08 00:08:52 +0000871 else if (VG_CLO_STREQN(12, argv[i], "--logsocket=")) {
sewardj73cf3bc2002-11-03 03:20:15 +0000872 VG_(clo_log_to) = VgLogTo_Socket;
873 VG_(clo_logfile_name) = &argv[i][12];
874 }
875
sewardj6024b212003-07-13 10:54:33 +0000876 else if (VG_CLO_STREQN(11, argv[i], "--input-fd="))
877 VG_(clo_input_fd) = (Int)VG_(atoll)(&argv[i][11]);
878
njn43c799e2003-04-08 00:08:52 +0000879 else if (VG_CLO_STREQN(15, argv[i], "--suppressions=")) {
sewardjde4a1d02002-03-22 01:27:54 +0000880 if (VG_(clo_n_suppressions) >= VG_CLO_MAX_SFILES) {
njn25e49d8e72002-09-23 09:36:25 +0000881 VG_(message)(Vg_UserMsg, "Too many suppression files specified.");
sewardjde4a1d02002-03-22 01:27:54 +0000882 VG_(message)(Vg_UserMsg,
883 "Increase VG_CLO_MAX_SFILES and recompile.");
njn25e49d8e72002-09-23 09:36:25 +0000884 VG_(bad_option)(argv[i]);
sewardjde4a1d02002-03-22 01:27:54 +0000885 }
886 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = &argv[i][15];
887 VG_(clo_n_suppressions)++;
888 }
njn43c799e2003-04-08 00:08:52 +0000889 else if (VG_CLO_STREQ(argv[i], "--profile=yes"))
njn25e49d8e72002-09-23 09:36:25 +0000890 VG_(clo_profile) = True;
njn43c799e2003-04-08 00:08:52 +0000891 else if (VG_CLO_STREQ(argv[i], "--profile=no"))
njn25e49d8e72002-09-23 09:36:25 +0000892 VG_(clo_profile) = False;
893
njn43c799e2003-04-08 00:08:52 +0000894 else if (VG_CLO_STREQ(argv[i], "--chain-bb=yes"))
sewardj22854b92002-11-30 14:00:47 +0000895 VG_(clo_chain_bb) = True;
njn43c799e2003-04-08 00:08:52 +0000896 else if (VG_CLO_STREQ(argv[i], "--chain-bb=no"))
sewardj22854b92002-11-30 14:00:47 +0000897 VG_(clo_chain_bb) = False;
898
njn43c799e2003-04-08 00:08:52 +0000899 else if (VG_CLO_STREQ(argv[i], "--single-step=yes"))
sewardjde4a1d02002-03-22 01:27:54 +0000900 VG_(clo_single_step) = True;
njn43c799e2003-04-08 00:08:52 +0000901 else if (VG_CLO_STREQ(argv[i], "--single-step=no"))
sewardjde4a1d02002-03-22 01:27:54 +0000902 VG_(clo_single_step) = False;
903
njn43c799e2003-04-08 00:08:52 +0000904 else if (VG_CLO_STREQ(argv[i], "--optimise=yes"))
sewardjde4a1d02002-03-22 01:27:54 +0000905 VG_(clo_optimise) = True;
njn43c799e2003-04-08 00:08:52 +0000906 else if (VG_CLO_STREQ(argv[i], "--optimise=no"))
sewardjde4a1d02002-03-22 01:27:54 +0000907 VG_(clo_optimise) = False;
908
njn25e49d8e72002-09-23 09:36:25 +0000909 /* "vwxyz" --> 000zyxwv (binary) */
njn43c799e2003-04-08 00:08:52 +0000910 else if (VG_CLO_STREQN(16, argv[i], "--trace-codegen=")) {
njn25e49d8e72002-09-23 09:36:25 +0000911 Int j;
912 char* opt = & argv[i][16];
913
914 if (5 != VG_(strlen)(opt)) {
915 VG_(message)(Vg_UserMsg,
916 "--trace-codegen argument must have 5 digits");
917 VG_(bad_option)(argv[i]);
918 }
919 for (j = 0; j < 5; j++) {
920 if ('0' == opt[j]) { /* do nothing */ }
921 else if ('1' == opt[j]) VG_(clo_trace_codegen) |= (1 << j);
922 else {
923 VG_(message)(Vg_UserMsg, "--trace-codegen argument can only "
924 "contain 0s and 1s");
925 VG_(bad_option)(argv[i]);
926 }
927 }
928 }
sewardjde4a1d02002-03-22 01:27:54 +0000929
njn43c799e2003-04-08 00:08:52 +0000930 else if (VG_CLO_STREQ(argv[i], "--trace-syscalls=yes"))
sewardjde4a1d02002-03-22 01:27:54 +0000931 VG_(clo_trace_syscalls) = True;
njn43c799e2003-04-08 00:08:52 +0000932 else if (VG_CLO_STREQ(argv[i], "--trace-syscalls=no"))
sewardjde4a1d02002-03-22 01:27:54 +0000933 VG_(clo_trace_syscalls) = False;
934
njn43c799e2003-04-08 00:08:52 +0000935 else if (VG_CLO_STREQ(argv[i], "--trace-signals=yes"))
sewardjde4a1d02002-03-22 01:27:54 +0000936 VG_(clo_trace_signals) = True;
njn43c799e2003-04-08 00:08:52 +0000937 else if (VG_CLO_STREQ(argv[i], "--trace-signals=no"))
sewardjde4a1d02002-03-22 01:27:54 +0000938 VG_(clo_trace_signals) = False;
939
njn43c799e2003-04-08 00:08:52 +0000940 else if (VG_CLO_STREQ(argv[i], "--trace-symtab=yes"))
sewardjde4a1d02002-03-22 01:27:54 +0000941 VG_(clo_trace_symtab) = True;
njn43c799e2003-04-08 00:08:52 +0000942 else if (VG_CLO_STREQ(argv[i], "--trace-symtab=no"))
sewardjde4a1d02002-03-22 01:27:54 +0000943 VG_(clo_trace_symtab) = False;
944
njn43c799e2003-04-08 00:08:52 +0000945 else if (VG_CLO_STREQ(argv[i], "--trace-sched=yes"))
sewardj8937c812002-04-12 20:12:20 +0000946 VG_(clo_trace_sched) = True;
njn43c799e2003-04-08 00:08:52 +0000947 else if (VG_CLO_STREQ(argv[i], "--trace-sched=no"))
sewardj8937c812002-04-12 20:12:20 +0000948 VG_(clo_trace_sched) = False;
949
njn43c799e2003-04-08 00:08:52 +0000950 else if (VG_CLO_STREQ(argv[i], "--trace-pthread=none"))
sewardj45b4b372002-04-16 22:50:32 +0000951 VG_(clo_trace_pthread_level) = 0;
njn43c799e2003-04-08 00:08:52 +0000952 else if (VG_CLO_STREQ(argv[i], "--trace-pthread=some"))
sewardj45b4b372002-04-16 22:50:32 +0000953 VG_(clo_trace_pthread_level) = 1;
njn43c799e2003-04-08 00:08:52 +0000954 else if (VG_CLO_STREQ(argv[i], "--trace-pthread=all"))
sewardj45b4b372002-04-16 22:50:32 +0000955 VG_(clo_trace_pthread_level) = 2;
sewardj8937c812002-04-12 20:12:20 +0000956
njn43c799e2003-04-08 00:08:52 +0000957 else if (VG_CLO_STREQN(14, argv[i], "--weird-hacks="))
sewardj8d365b52002-05-12 10:52:16 +0000958 VG_(clo_weird_hacks) = &argv[i][14];
sewardj3984b852002-05-12 03:00:17 +0000959
jsgf855d93d2003-10-13 22:26:55 +0000960 else if (VG_CLO_STREQN(17, argv[i], "--signal-polltime="))
961 VG_(clo_signal_polltime) = VG_(atoll)(&argv[i][17]);
962
963 else if (VG_CLO_STREQ(argv[i], "--lowlat-signals=yes"))
964 VG_(clo_lowlat_signals) = True;
965 else if (VG_CLO_STREQ(argv[i], "--lowlat-signals=no"))
966 VG_(clo_lowlat_signals) = False;
967
968 else if (VG_CLO_STREQ(argv[i], "--lowlat-syscalls=yes"))
969 VG_(clo_lowlat_syscalls) = True;
970 else if (VG_CLO_STREQ(argv[i], "--lowlat-syscalls=no"))
971 VG_(clo_lowlat_syscalls) = False;
972
njn43c799e2003-04-08 00:08:52 +0000973 else if (VG_CLO_STREQN(13, argv[i], "--stop-after="))
sewardjde4a1d02002-03-22 01:27:54 +0000974 VG_(clo_stop_after) = VG_(atoll)(&argv[i][13]);
975
njn43c799e2003-04-08 00:08:52 +0000976 else if (VG_CLO_STREQN(13, argv[i], "--dump-error="))
sewardjde4a1d02002-03-22 01:27:54 +0000977 VG_(clo_dump_error) = (Int)VG_(atoll)(&argv[i][13]);
978
jsgf855d93d2003-10-13 22:26:55 +0000979 else if (VG_CLO_STREQ(argv[i], "--wait-for-gdb=yes"))
980 VG_(clo_wait_for_gdb) = True;
981 else if (VG_CLO_STREQ(argv[i], "--wait-for-gdb=no"))
982 VG_(clo_wait_for_gdb) = False;
983
njn43c799e2003-04-08 00:08:52 +0000984 else if (VG_CLO_STREQN(14, argv[i], "--num-callers=")) {
sewardjde4a1d02002-03-22 01:27:54 +0000985 /* Make sure it's sane. */
986 VG_(clo_backtrace_size) = (Int)VG_(atoll)(&argv[i][14]);
njn6c846552003-09-16 07:41:43 +0000987 if (VG_(clo_backtrace_size) < 1)
988 VG_(clo_backtrace_size) = 1;
sewardjde4a1d02002-03-22 01:27:54 +0000989 if (VG_(clo_backtrace_size) >= VG_DEEPEST_BACKTRACE)
990 VG_(clo_backtrace_size) = VG_DEEPEST_BACKTRACE;
991 }
992
njn25e49d8e72002-09-23 09:36:25 +0000993 else if (VG_(needs).command_line_options) {
994 Bool ok = SK_(process_cmd_line_option)(argv[i]);
995 if (!ok)
fitzhardinge98abfc72003-12-16 02:05:15 +0000996 VG_(usage)();
njn25e49d8e72002-09-23 09:36:25 +0000997 }
sewardjde4a1d02002-03-22 01:27:54 +0000998 else
fitzhardinge98abfc72003-12-16 02:05:15 +0000999 VG_(usage)();
sewardjde4a1d02002-03-22 01:27:54 +00001000 }
1001
1002# undef ISSPACE
sewardjde4a1d02002-03-22 01:27:54 +00001003
njnf9ebf672003-05-12 21:41:30 +00001004 if (VG_(clo_verbosity) < 0)
sewardjde4a1d02002-03-22 01:27:54 +00001005 VG_(clo_verbosity) = 0;
1006
1007 if (VG_(clo_GDB_attach) && VG_(clo_trace_children)) {
1008 VG_(message)(Vg_UserMsg, "");
1009 VG_(message)(Vg_UserMsg,
1010 "--gdb-attach=yes conflicts with --trace-children=yes");
1011 VG_(message)(Vg_UserMsg,
1012 "Please choose one or the other, but not both.");
njn25e49d8e72002-09-23 09:36:25 +00001013 VG_(bad_option)("--gdb-attach=yes and --trace-children=yes");
sewardjde4a1d02002-03-22 01:27:54 +00001014 }
1015
sewardj4cf05692002-10-27 20:28:29 +00001016 /* Set up logging now. After this is done, VG_(clo_logfile_fd)
1017 should be connected to whatever sink has been selected, and we
1018 indiscriminately chuck stuff into it without worrying what the
1019 nature of it is. Oh the wonder of Unix streams. */
1020
nethercotee1730692003-11-20 10:38:07 +00001021 /* So far we should be still attached to stdout, so we can show on
sewardj4cf05692002-10-27 20:28:29 +00001022 the terminal any problems to do with processing command line
1023 opts. */
nethercotee1730692003-11-20 10:38:07 +00001024 vg_assert(VG_(clo_logfile_fd) == 1 /* stdout */);
sewardj73cf3bc2002-11-03 03:20:15 +00001025 vg_assert(VG_(logging_to_filedes) == True);
sewardj4cf05692002-10-27 20:28:29 +00001026
1027 switch (VG_(clo_log_to)) {
sewardj73cf3bc2002-11-03 03:20:15 +00001028
sewardj4cf05692002-10-27 20:28:29 +00001029 case VgLogTo_Fd:
1030 vg_assert(VG_(clo_logfile_name) == NULL);
1031 VG_(clo_logfile_fd) = eventually_logfile_fd;
1032 break;
sewardj73cf3bc2002-11-03 03:20:15 +00001033
sewardj4cf05692002-10-27 20:28:29 +00001034 case VgLogTo_File: {
1035 Char logfilename[1000];
jsgff3c3f1a2003-10-14 22:13:28 +00001036 Int seq = 0;
1037 Int pid = VG_(getpid)();
1038
sewardj4cf05692002-10-27 20:28:29 +00001039 vg_assert(VG_(clo_logfile_name) != NULL);
1040 vg_assert(VG_(strlen)(VG_(clo_logfile_name)) <= 900); /* paranoia */
jsgff3c3f1a2003-10-14 22:13:28 +00001041
1042 for(;;) {
1043 if (seq == 0)
1044 VG_(sprintf)(logfilename, "%s.pid%d",
1045 VG_(clo_logfile_name), pid );
1046 else
1047 VG_(sprintf)(logfilename, "%s.pid%d.%d",
1048 VG_(clo_logfile_name), pid, seq );
1049 seq++;
1050
1051 eventually_logfile_fd
1052 = VG_(open)(logfilename,
1053 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_EXCL|VKI_O_TRUNC,
1054 VKI_S_IRUSR|VKI_S_IWUSR);
1055 if (eventually_logfile_fd >= 0) {
1056 VG_(clo_logfile_fd) = eventually_logfile_fd;
1057 break;
1058 } else {
1059 if (eventually_logfile_fd != -VKI_EEXIST) {
1060 VG_(message)(Vg_UserMsg,
1061 "Can't create/open log file `%s.pid%d'; giving up!",
1062 VG_(clo_logfile_name), pid);
1063 VG_(bad_option)(
1064 "--logfile=<file> didn't work out for some reason.");
1065 break;
1066 }
1067 }
1068 }
sewardj4cf05692002-10-27 20:28:29 +00001069 break;
sewardj73cf3bc2002-11-03 03:20:15 +00001070 }
1071
1072 case VgLogTo_Socket: {
1073 vg_assert(VG_(clo_logfile_name) != NULL);
1074 vg_assert(VG_(strlen)(VG_(clo_logfile_name)) <= 900); /* paranoia */
1075 eventually_logfile_fd
1076 = VG_(connect_via_socket)( VG_(clo_logfile_name) );
1077 if (eventually_logfile_fd == -1) {
1078 VG_(message)(Vg_UserMsg,
1079 "Invalid --logsocket=ipaddr or --logsocket=ipaddr:port spec");
1080 VG_(message)(Vg_UserMsg,
1081 "of `%s'; giving up!", VG_(clo_logfile_name) );
1082 VG_(bad_option)(
1083 "--logsocket=");
sewardj4cf05692002-10-27 20:28:29 +00001084 }
sewardj73cf3bc2002-11-03 03:20:15 +00001085 if (eventually_logfile_fd == -2) {
1086 VG_(message)(Vg_UserMsg,
sewardj570f8902002-11-03 11:44:36 +00001087 "valgrind: failed to connect to logging server `%s'.",
sewardj73cf3bc2002-11-03 03:20:15 +00001088 VG_(clo_logfile_name) );
sewardj570f8902002-11-03 11:44:36 +00001089 VG_(message)(Vg_UserMsg,
1090 "Log messages will sent to stderr instead." );
1091 VG_(message)(Vg_UserMsg,
1092 "" );
1093 /* We don't change anything here. */
1094 } else {
1095 vg_assert(eventually_logfile_fd > 0);
1096 VG_(clo_logfile_fd) = eventually_logfile_fd;
1097 VG_(logging_to_filedes) = False;
1098 }
sewardj73cf3bc2002-11-03 03:20:15 +00001099 break;
1100 }
1101
sewardj4cf05692002-10-27 20:28:29 +00001102 }
1103
jsgf855d93d2003-10-13 22:26:55 +00001104 /* Move logfile_fd into the safe range, so it doesn't conflict with any app fds */
1105 eventually_logfile_fd = VG_(fcntl)(VG_(clo_logfile_fd), VKI_F_DUPFD, VG_MAX_FD+1);
1106 if (eventually_logfile_fd < 0)
1107 VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd into safe range");
1108 else {
1109 VG_(clo_logfile_fd) = eventually_logfile_fd;
1110 VG_(fcntl)(VG_(clo_logfile_fd), VKI_F_SETFD, VKI_FD_CLOEXEC);
1111 }
1112
sewardj4cf05692002-10-27 20:28:29 +00001113 /* Ok, the logging sink is running now. Print a suitable preamble.
1114 If logging to file or a socket, write details of parent PID and
1115 command line args, to help people trying to interpret the
1116 results of a run which encompasses multiple processes. */
sewardjde4a1d02002-03-22 01:27:54 +00001117
sewardj83adf412002-05-01 01:25:45 +00001118 if (VG_(clo_verbosity > 0)) {
njnd04b7c62002-10-03 14:05:52 +00001119 /* Skin details */
1120 VG_(message)(Vg_UserMsg, "%s%s%s, %s for x86-linux.",
1121 VG_(details).name,
1122 NULL == VG_(details).version ? "" : "-",
1123 NULL == VG_(details).version
1124 ? (Char*)"" : VG_(details).version,
1125 VG_(details).description);
1126 VG_(message)(Vg_UserMsg, "%s", VG_(details).copyright_author);
sewardj3b2736a2002-03-24 12:18:35 +00001127
njnd04b7c62002-10-03 14:05:52 +00001128 /* Core details */
1129 VG_(message)(Vg_UserMsg,
njn3e884182003-04-15 13:03:23 +00001130 "Using valgrind-%s, a program supervision framework for x86-linux.",
sewardj4aa62ba2002-10-05 15:49:27 +00001131 VERSION);
sewardjde4a1d02002-03-22 01:27:54 +00001132 VG_(message)(Vg_UserMsg,
njn0e1b5142003-04-15 14:58:06 +00001133 "Copyright (C) 2000-2003, and GNU GPL'd, by Julian Seward.");
njnd04b7c62002-10-03 14:05:52 +00001134 }
1135
nethercotec1e395d2003-11-10 13:26:49 +00001136 if (VG_(clo_verbosity) > 0 && VG_(clo_log_to) != VgLogTo_Fd) {
sewardj4cf05692002-10-27 20:28:29 +00001137 VG_(message)(Vg_UserMsg, "");
1138 VG_(message)(Vg_UserMsg,
1139 "My PID = %d, parent PID = %d. Prog and args are:",
1140 VG_(getpid)(), VG_(getppid)() );
1141 for (i = 0; i < VG_(client_argc); i++)
1142 VG_(message)(Vg_UserMsg, " %s", VG_(client_argv)[i]);
1143 }
1144
sewardjde4a1d02002-03-22 01:27:54 +00001145 if (VG_(clo_verbosity) > 1) {
sewardj4cf05692002-10-27 20:28:29 +00001146 if (VG_(clo_log_to) != VgLogTo_Fd)
1147 VG_(message)(Vg_UserMsg, "");
fitzhardinge98abfc72003-12-16 02:05:15 +00001148 VG_(message)(Vg_UserMsg, "Valgrind library directory: %s", VG_(libdir));
njn86dc2bc2003-09-09 07:26:21 +00001149 VG_(message)(Vg_UserMsg, "Command line");
1150 for (i = 0; i < VG_(client_argc); i++)
1151 VG_(message)(Vg_UserMsg, " %s", VG_(client_argv)[i]);
1152
sewardjde4a1d02002-03-22 01:27:54 +00001153 VG_(message)(Vg_UserMsg, "Startup, with flags:");
fitzhardinge98abfc72003-12-16 02:05:15 +00001154 for (i = 1; i < argc; i++) {
sewardjde4a1d02002-03-22 01:27:54 +00001155 VG_(message)(Vg_UserMsg, " %s", argv[i]);
1156 }
1157 }
1158
fitzhardinge98abfc72003-12-16 02:05:15 +00001159 if (VG_(clo_n_suppressions) < VG_CLO_MAX_SFILES-1 &&
njn25e49d8e72002-09-23 09:36:25 +00001160 (VG_(needs).core_errors || VG_(needs).skin_errors)) {
fitzhardinge98abfc72003-12-16 02:05:15 +00001161 /* If there are no suppression files specified and the skin
1162 needs one, load the default */
1163 static const Char default_supp[] = "default.supp";
1164 Int len = VG_(strlen)(VG_(libdir)) + 1 + sizeof(default_supp);
1165 Char *buf = VG_(arena_malloc)(VG_AR_CORE, len);
1166 VG_(sprintf)(buf, "%s/%s", VG_(libdir), default_supp);
1167 VG_(clo_suppressions)[VG_(clo_n_suppressions)] = buf;
1168 VG_(clo_n_suppressions)++;
sewardjde4a1d02002-03-22 01:27:54 +00001169 }
sewardj4cf05692002-10-27 20:28:29 +00001170
njn6a230532003-07-21 10:38:23 +00001171 if (VG_(clo_gen_suppressions) &&
1172 !VG_(needs).core_errors && !VG_(needs).skin_errors) {
1173 config_error("Can't use --gen-suppressions=yes with this skin,\n"
1174 " as it doesn't generate errors.");
1175 }
1176
sewardjde4a1d02002-03-22 01:27:54 +00001177}
1178
sewardjde4a1d02002-03-22 01:27:54 +00001179/* ---------------------------------------------------------------------
1180 Copying to/from m_state_static.
1181 ------------------------------------------------------------------ */
1182
sewardjb91ae7f2003-04-29 23:50:00 +00001183/* See comment about this in vg_include.h. Change only with
1184 great care.
1185*/
1186__attribute__ ((aligned (16)))
sewardj92a59562002-09-30 00:53:10 +00001187UInt VG_(m_state_static) [6 /* segment regs, Intel order */
1188 + 8 /* int regs, in Intel order */
sewardjde4a1d02002-03-22 01:27:54 +00001189 + 1 /* %eflags */
1190 + 1 /* %eip */
sewardjb91ae7f2003-04-29 23:50:00 +00001191 + VG_SIZE_OF_SSESTATE_W /* FPU state */
sewardjde4a1d02002-03-22 01:27:54 +00001192 ];
1193
sewardjfa492d42002-12-08 18:20:01 +00001194UInt VG_(insertDflag)(UInt eflags, Int d)
1195{
1196 vg_assert(d == 1 || d == -1);
1197 eflags &= ~EFlagD;
1198
1199 if (d < 0)
1200 eflags |= EFlagD;
1201
1202 return eflags;
1203}
1204
1205Int VG_(extractDflag)(UInt eflags)
1206{
1207 Int ret;
1208
1209 if (eflags & EFlagD)
1210 ret = -1;
1211 else
1212 ret = 1;
1213
1214 return ret;
1215}
1216
sewardjde4a1d02002-03-22 01:27:54 +00001217void VG_(copy_baseBlock_to_m_state_static) ( void )
1218{
1219 Int i;
sewardj92a59562002-09-30 00:53:10 +00001220 VG_(m_state_static)[ 0/4] = VG_(baseBlock)[VGOFF_(m_cs)];
1221 VG_(m_state_static)[ 4/4] = VG_(baseBlock)[VGOFF_(m_ss)];
1222 VG_(m_state_static)[ 8/4] = VG_(baseBlock)[VGOFF_(m_ds)];
1223 VG_(m_state_static)[12/4] = VG_(baseBlock)[VGOFF_(m_es)];
1224 VG_(m_state_static)[16/4] = VG_(baseBlock)[VGOFF_(m_fs)];
1225 VG_(m_state_static)[20/4] = VG_(baseBlock)[VGOFF_(m_gs)];
sewardjde4a1d02002-03-22 01:27:54 +00001226
sewardj92a59562002-09-30 00:53:10 +00001227 VG_(m_state_static)[24/4] = VG_(baseBlock)[VGOFF_(m_eax)];
1228 VG_(m_state_static)[28/4] = VG_(baseBlock)[VGOFF_(m_ecx)];
1229 VG_(m_state_static)[32/4] = VG_(baseBlock)[VGOFF_(m_edx)];
1230 VG_(m_state_static)[36/4] = VG_(baseBlock)[VGOFF_(m_ebx)];
1231 VG_(m_state_static)[40/4] = VG_(baseBlock)[VGOFF_(m_esp)];
1232 VG_(m_state_static)[44/4] = VG_(baseBlock)[VGOFF_(m_ebp)];
1233 VG_(m_state_static)[48/4] = VG_(baseBlock)[VGOFF_(m_esi)];
1234 VG_(m_state_static)[52/4] = VG_(baseBlock)[VGOFF_(m_edi)];
1235
sewardjb91ae7f2003-04-29 23:50:00 +00001236 VG_(m_state_static)[56/4]
1237 = VG_(insertDflag)(VG_(baseBlock)[VGOFF_(m_eflags)],
1238 VG_(baseBlock)[VGOFF_(m_dflag)]);
sewardj92a59562002-09-30 00:53:10 +00001239 VG_(m_state_static)[60/4] = VG_(baseBlock)[VGOFF_(m_eip)];
sewardjde4a1d02002-03-22 01:27:54 +00001240
sewardjb91ae7f2003-04-29 23:50:00 +00001241 for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
sewardj92a59562002-09-30 00:53:10 +00001242 VG_(m_state_static)[64/4 + i]
sewardjb91ae7f2003-04-29 23:50:00 +00001243 = VG_(baseBlock)[VGOFF_(m_ssestate) + i];
sewardjde4a1d02002-03-22 01:27:54 +00001244}
1245
1246
1247void VG_(copy_m_state_static_to_baseBlock) ( void )
1248{
1249 Int i;
sewardj92a59562002-09-30 00:53:10 +00001250 VG_(baseBlock)[VGOFF_(m_cs)] = VG_(m_state_static)[ 0/4];
1251 VG_(baseBlock)[VGOFF_(m_ss)] = VG_(m_state_static)[ 4/4];
1252 VG_(baseBlock)[VGOFF_(m_ds)] = VG_(m_state_static)[ 8/4];
1253 VG_(baseBlock)[VGOFF_(m_es)] = VG_(m_state_static)[12/4];
1254 VG_(baseBlock)[VGOFF_(m_fs)] = VG_(m_state_static)[16/4];
1255 VG_(baseBlock)[VGOFF_(m_gs)] = VG_(m_state_static)[20/4];
sewardjde4a1d02002-03-22 01:27:54 +00001256
sewardj92a59562002-09-30 00:53:10 +00001257 VG_(baseBlock)[VGOFF_(m_eax)] = VG_(m_state_static)[24/4];
1258 VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(m_state_static)[28/4];
1259 VG_(baseBlock)[VGOFF_(m_edx)] = VG_(m_state_static)[32/4];
1260 VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(m_state_static)[36/4];
1261 VG_(baseBlock)[VGOFF_(m_esp)] = VG_(m_state_static)[40/4];
1262 VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(m_state_static)[44/4];
1263 VG_(baseBlock)[VGOFF_(m_esi)] = VG_(m_state_static)[48/4];
1264 VG_(baseBlock)[VGOFF_(m_edi)] = VG_(m_state_static)[52/4];
1265
sewardjb91ae7f2003-04-29 23:50:00 +00001266 VG_(baseBlock)[VGOFF_(m_eflags)]
1267 = VG_(m_state_static)[56/4] & ~EFlagD;
1268 VG_(baseBlock)[VGOFF_(m_dflag)]
1269 = VG_(extractDflag)(VG_(m_state_static)[56/4]);
sewardjfa492d42002-12-08 18:20:01 +00001270
sewardj92a59562002-09-30 00:53:10 +00001271 VG_(baseBlock)[VGOFF_(m_eip)] = VG_(m_state_static)[60/4];
sewardjde4a1d02002-03-22 01:27:54 +00001272
sewardjb91ae7f2003-04-29 23:50:00 +00001273 for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
1274 VG_(baseBlock)[VGOFF_(m_ssestate) + i]
sewardj92a59562002-09-30 00:53:10 +00001275 = VG_(m_state_static)[64/4 + i];
sewardjde4a1d02002-03-22 01:27:54 +00001276}
1277
njn25e49d8e72002-09-23 09:36:25 +00001278Addr VG_(get_stack_pointer) ( void )
1279{
1280 return VG_(baseBlock)[VGOFF_(m_esp)];
1281}
1282
sewardjde4a1d02002-03-22 01:27:54 +00001283/* ---------------------------------------------------------------------
1284 Show accumulated counts.
1285 ------------------------------------------------------------------ */
1286
njn25e49d8e72002-09-23 09:36:25 +00001287static __inline__ Int safe_idiv(Int a, Int b)
1288{
1289 return (b == 0 ? 0 : a / b);
1290}
1291
sewardjde4a1d02002-03-22 01:27:54 +00001292static void vg_show_counts ( void )
1293{
1294 VG_(message)(Vg_DebugMsg,
sewardjc0d8f682002-11-30 00:49:43 +00001295 " TT/TC: %d tc sectors discarded.",
1296 VG_(number_of_tc_discards) );
sewardjde4a1d02002-03-22 01:27:54 +00001297 VG_(message)(Vg_DebugMsg,
sewardj22854b92002-11-30 14:00:47 +00001298 " %d chainings, %d unchainings.",
1299 VG_(bb_enchain_count), VG_(bb_dechain_count) );
1300 VG_(message)(Vg_DebugMsg,
njn25e49d8e72002-09-23 09:36:25 +00001301 "translate: new %d (%d -> %d; ratio %d:10)",
sewardjde4a1d02002-03-22 01:27:54 +00001302 VG_(overall_in_count),
1303 VG_(overall_in_osize),
1304 VG_(overall_in_tsize),
njn25e49d8e72002-09-23 09:36:25 +00001305 safe_idiv(10*VG_(overall_in_tsize), VG_(overall_in_osize)));
1306 VG_(message)(Vg_DebugMsg,
1307 " discard %d (%d -> %d; ratio %d:10).",
sewardjde4a1d02002-03-22 01:27:54 +00001308 VG_(overall_out_count),
1309 VG_(overall_out_osize),
njn25e49d8e72002-09-23 09:36:25 +00001310 VG_(overall_out_tsize),
1311 safe_idiv(10*VG_(overall_out_tsize), VG_(overall_out_osize)));
sewardjde4a1d02002-03-22 01:27:54 +00001312 VG_(message)(Vg_DebugMsg,
njne0205ff2003-04-08 00:56:14 +00001313 " dispatch: %llu jumps (bb entries), of which %u (%lu%%) were unchained.",
sewardj22854b92002-11-30 14:00:47 +00001314 VG_(bbs_done),
1315 VG_(unchained_jumps_done),
1316 ((ULong)(100) * (ULong)(VG_(unchained_jumps_done)))
1317 / ( VG_(bbs_done)==0 ? 1 : VG_(bbs_done) )
1318 );
1319
1320 VG_(message)(Vg_DebugMsg,
1321 " %d/%d major/minor sched events. %d tt_fast misses.",
1322 VG_(num_scheduling_events_MAJOR),
sewardj2e93c502002-04-12 11:12:52 +00001323 VG_(num_scheduling_events_MINOR),
1324 VG_(tt_fast_misses));
sewardj22854b92002-11-30 14:00:47 +00001325
sewardjde4a1d02002-03-22 01:27:54 +00001326 VG_(message)(Vg_DebugMsg,
1327 "reg-alloc: %d t-req-spill, "
1328 "%d+%d orig+spill uis, %d total-reg-r.",
1329 VG_(translations_needing_spill),
1330 VG_(uinstrs_prealloc),
1331 VG_(uinstrs_spill),
1332 VG_(total_reg_rank) );
1333 VG_(message)(Vg_DebugMsg,
sewardjde4a1d02002-03-22 01:27:54 +00001334 " sanity: %d cheap, %d expensive checks.",
1335 VG_(sanity_fast_count),
1336 VG_(sanity_slow_count) );
njn25e49d8e72002-09-23 09:36:25 +00001337 VG_(print_ccall_stats)();
sewardjde4a1d02002-03-22 01:27:54 +00001338}
1339
1340
1341/* ---------------------------------------------------------------------
1342 Main!
1343 ------------------------------------------------------------------ */
1344
jsgf855d93d2003-10-13 22:26:55 +00001345/* Initialize the PID and PGRP of scheduler LWP; this is also called
1346 in any new children after fork. */
1347static void newpid(ThreadId unused)
1348{
1349 /* PID of scheduler LWP */
1350 VG_(main_pid) = VG_(getpid)();
1351 VG_(main_pgrp) = VG_(getpgrp)();
1352}
1353
sewardjde4a1d02002-03-22 01:27:54 +00001354/* Where we jump to once Valgrind has got control, and the real
1355 machine's state has been copied to the m_state_static. */
1356
fitzhardinge98abfc72003-12-16 02:05:15 +00001357void VG_(main) ( const KickstartParams *kp, void (*tool_init)(void), void *tool_dlhandle )
sewardjde4a1d02002-03-22 01:27:54 +00001358{
sewardj2e93c502002-04-12 11:12:52 +00001359 VgSchedReturnCode src;
sewardjde4a1d02002-03-22 01:27:54 +00001360
fitzhardinge98abfc72003-12-16 02:05:15 +00001361 /* initial state */
1362 if (0)
1363 VG_(printf)("starting esp=%p eip=%p, esp=%p\n", kp->client_esp, kp->client_eip, &src);
1364 VG_(esp_at_startup) = kp->client_esp;
1365 VG_(memset)(&VG_(m_state_static), 0, sizeof(VG_(m_state_static)));
1366 VG_(m_state_static)[40/4] = kp->client_esp;
1367 VG_(m_state_static)[60/4] = kp->client_eip;
1368
1369 /* set up an initial FPU state (doesn't really matter what it is,
1370 so long as it's somewhat valid) */
1371 if (!VG_(have_ssestate))
1372 asm volatile("fwait; fnsave %0; fwait; frstor %0; fwait"
1373 : : "m" (VG_(m_state_static)[64/4]) : "cc", "memory");
1374 else
1375 asm volatile("fwait; fxsave %0; fwait; andl $0xffbf, %1; fxrstor %0; fwait"
1376 : : "m" (VG_(m_state_static)[64/4]), "m" (VG_(m_state_static)[(64+24)/4]) : "cc", "memory");
1377
1378 VG_(brk_base) = VG_(brk_limit) = kp->client_brkbase;
1379 VG_(client_base) = kp->client_base;
1380 VG_(client_end) = kp->client_end;
1381 VG_(client_mapbase) = kp->client_mapbase;
1382 VG_(clstk_base) = kp->clstk_base;
1383 VG_(clstk_end) = kp->clstk_end;
1384
1385 VG_(shadow_base) = kp->shadow_base;
1386 VG_(shadow_end) = kp->shadow_end;
1387 VG_(valgrind_base) = kp->vg_base;
1388 VG_(valgrind_mmap_end) = kp->vg_mmap_end;
1389 VG_(valgrind_end) = kp->vg_end;
1390
1391 VG_(libdir) = kp->libdir;
1392
1393 vg_assert(VG_(clstk_end) == VG_(client_end));
1394
fitzhardingea49f9b52003-12-16 22:26:45 +00001395 if (kp->vgexecfd != -1)
1396 VG_(vgexecfd) = VG_(safe_fd)(kp->vgexecfd);
1397 if (kp->clexecfd != -1)
1398 VG_(clexecfd) = VG_(safe_fd)(kp->clexecfd);
fitzhardinge98abfc72003-12-16 02:05:15 +00001399
njn0c7a5b52003-04-30 09:00:33 +00001400 if (0) {
1401 if (VG_(have_ssestate))
1402 VG_(printf)("Looks like a SSE-capable CPU\n");
1403 else
1404 VG_(printf)("Looks like a MMX-only CPU\n");
1405 }
sewardjb91ae7f2003-04-29 23:50:00 +00001406
jsgf855d93d2003-10-13 22:26:55 +00001407 VG_(atfork)(NULL, NULL, newpid);
1408 newpid(VG_INVALID_THREADID);
1409
njn3e884182003-04-15 13:03:23 +00001410 /* Read /proc/self/maps into a buffer. Must be before:
1411 - SK_(pre_clo_init)(): so that if it calls VG_(malloc)(), any mmap'd
1412 superblocks are not erroneously identified as being owned by the
1413 client, which would be bad.
1414 - init_memory(): that's where the buffer is parsed
1415 - init_tt_tc(): so the anonymous mmaps for the translation table and
1416 translation cache aren't identified as part of the client, which would
1417 waste > 20M of virtual address space, and be bad.
1418 */
njnfa1016e2003-09-25 17:54:11 +00001419 VG_(read_procselfmaps)();
njn3e884182003-04-15 13:03:23 +00001420
njn25e49d8e72002-09-23 09:36:25 +00001421 /* Setup stuff that depends on the skin. Must be before:
1422 - vg_init_baseBlock(): to register helpers
1423 - process_cmd_line_options(): to register skin name and description,
1424 and turn on/off 'command_line_options' need
1425 - init_memory() (to setup memory event trackers).
njn3e884182003-04-15 13:03:23 +00001426 */
fitzhardinge98abfc72003-12-16 02:05:15 +00001427 (*tool_init)();
1428 VG_(tool_init_dlsym)(tool_dlhandle);
1429
njn810086f2002-11-14 12:42:47 +00001430 VG_(sanity_check_needs)();
njn25e49d8e72002-09-23 09:36:25 +00001431
fitzhardinge98abfc72003-12-16 02:05:15 +00001432 /* Process Valgrind's command-line opts */
1433 process_cmd_line_options(kp);
sewardjde4a1d02002-03-22 01:27:54 +00001434
jsgf855d93d2003-10-13 22:26:55 +00001435 /* Hook to delay things long enough so we can get the pid and
1436 attach GDB in another shell. */
1437 if (VG_(clo_wait_for_gdb)) {
1438 VG_(printf)("pid=%d\n", VG_(getpid)());
1439 /* do "jump *$eip" to skip this in gdb */
1440 VG_(do_syscall)(__NR_pause);
1441 }
1442
njn3e884182003-04-15 13:03:23 +00001443 /* Do post command-line processing initialisation. Must be before:
1444 - vg_init_baseBlock(): to register any more helpers
1445 */
njncc7bb472002-10-14 09:25:19 +00001446 SK_(post_clo_init)();
1447
njn3e884182003-04-15 13:03:23 +00001448 /* Set up baseBlock offsets and copy the saved machine's state into it. */
njncc7bb472002-10-14 09:25:19 +00001449 vg_init_baseBlock();
1450
rjwalshf5f536f2003-11-17 17:45:00 +00001451 /* Search for file descriptors that are inherited from our parent. */
1452 if (VG_(clo_track_fds))
1453 VG_(init_preopened_fds)();
1454
sewardj018f7622002-05-15 21:13:39 +00001455 /* Initialise the scheduler, and copy the client's state from
njn3e884182003-04-15 13:03:23 +00001456 baseBlock into VG_(threads)[1]. Must be before:
1457 - VG_(sigstartup_actions)()
1458 */
sewardj018f7622002-05-15 21:13:39 +00001459 VG_(scheduler_init)();
1460
jsgf855d93d2003-10-13 22:26:55 +00001461 /* Set up the ProxyLWP machinery */
1462 VG_(proxy_init)();
1463
sewardj018f7622002-05-15 21:13:39 +00001464 /* Initialise the signal handling subsystem, temporarily parking
1465 the saved blocking-mask in saved_sigmask. */
sewardjde4a1d02002-03-22 01:27:54 +00001466 VG_(sigstartup_actions)();
1467
sewardj018f7622002-05-15 21:13:39 +00001468 /* Perhaps we're profiling Valgrind? */
njn25e49d8e72002-09-23 09:36:25 +00001469 if (VG_(clo_profile))
1470 VGP_(init_profiling)();
sewardjde4a1d02002-03-22 01:27:54 +00001471
sewardj5f07b662002-04-23 16:52:51 +00001472 /* Start calibration of our RDTSC-based clock. */
1473 VG_(start_rdtsc_calibration)();
1474
njn3e884182003-04-15 13:03:23 +00001475 /* Parse /proc/self/maps to learn about startup segments. */
njn25e49d8e72002-09-23 09:36:25 +00001476 VGP_PUSHCC(VgpInitMem);
1477 VG_(init_memory)();
1478 VGP_POPCC(VgpInitMem);
1479
1480 /* Read the list of errors to suppress. This should be found in
1481 the file specified by vg_clo_suppressions. */
1482 if (VG_(needs).core_errors || VG_(needs).skin_errors)
1483 VG_(load_suppressions)();
sewardj18d75132002-05-16 11:06:21 +00001484
sewardj5f07b662002-04-23 16:52:51 +00001485 /* End calibration of our RDTSC-based clock, leaving it as long as
1486 we can. */
1487 VG_(end_rdtsc_calibration)();
1488
njn3e884182003-04-15 13:03:23 +00001489 /* Initialise translation table and translation cache. */
sewardj18d75132002-05-16 11:06:21 +00001490 VG_(init_tt_tc)();
sewardjde4a1d02002-03-22 01:27:54 +00001491
1492 if (VG_(clo_verbosity) == 1) {
1493 VG_(message)(Vg_UserMsg,
1494 "For more details, rerun with: -v");
1495 }
1496
sewardj25c7c3a2003-07-10 00:17:58 +00001497 /* Force a read of the debug info so that we can look for
1498 glibc entry points to intercept. */
sewardj25c7c3a2003-07-10 00:17:58 +00001499 VG_(setup_code_redirect_table)();
1500
sewardjde4a1d02002-03-22 01:27:54 +00001501 /* Now it is safe for malloc et al in vg_clientmalloc.c to act
1502 instrumented-ly. */
sewardjde4a1d02002-03-22 01:27:54 +00001503 if (VG_(clo_verbosity) > 0)
1504 VG_(message)(Vg_UserMsg, "");
1505
1506 VG_(bbs_to_go) = VG_(clo_stop_after);
sewardj2e93c502002-04-12 11:12:52 +00001507
fitzhardinge98abfc72003-12-16 02:05:15 +00001508 if (VG_(clo_pointercheck)) {
1509 vki_modify_ldt_t ldt = { VG_POINTERCHECK_SEGIDX,
1510 VG_(client_base),
1511 (VG_(client_end)-VG_(client_base)) / VKI_BYTES_PER_PAGE,
1512 1, /* 32 bit */
1513 0, /* contents: data, RW, non-expanding */
1514 0, /* not read-exec only */
1515 1, /* limit in pages */
1516 0, /* !seg not present */
1517 1, /* usable */
1518 };
1519 Int ret = VG_(do_syscall)(__NR_modify_ldt, 1, &ldt, sizeof(ldt));
1520
1521 if (ret < 0) {
1522 VG_(message)(Vg_UserMsg,
1523 "Warning: ignoring --pointercheck=yes, "
1524 "because modify_ldt failed (errno=%d)", -ret);
1525 VG_(clo_pointercheck) = False;
1526 }
1527 }
1528
sewardj018f7622002-05-15 21:13:39 +00001529 /* Run! */
njn25e49d8e72002-09-23 09:36:25 +00001530 VG_(running_on_simd_CPU) = True;
sewardj671ff542002-05-07 09:25:30 +00001531 VGP_PUSHCC(VgpSched);
jsgf855d93d2003-10-13 22:26:55 +00001532
1533 if (__builtin_setjmp(&VG_(fatal_signal_jmpbuf)) == 0) {
1534 VG_(fatal_signal_set) = True;
1535 src = VG_(scheduler)();
1536 } else
1537 src = VgSrc_FatalSig;
1538
njn25e49d8e72002-09-23 09:36:25 +00001539 VGP_POPCC(VgpSched);
1540 VG_(running_on_simd_CPU) = False;
sewardjde4a1d02002-03-22 01:27:54 +00001541
1542 if (VG_(clo_verbosity) > 0)
1543 VG_(message)(Vg_UserMsg, "");
1544
sewardj2e93c502002-04-12 11:12:52 +00001545 if (src == VgSrc_Deadlock) {
1546 VG_(message)(Vg_UserMsg,
1547 "Warning: pthread scheduler exited due to deadlock");
1548 }
1549
rjwalshf5f536f2003-11-17 17:45:00 +00001550 /* Print out file descriptor summary and stats. */
1551 if(VG_(clo_track_fds))
1552 VG_(fd_stats)();
1553
njn25e49d8e72002-09-23 09:36:25 +00001554 if (VG_(needs).core_errors || VG_(needs).skin_errors)
sewardjde4a1d02002-03-22 01:27:54 +00001555 VG_(show_all_errors)();
sewardj2e93c502002-04-12 11:12:52 +00001556
njn7d9f94d2003-04-22 21:41:40 +00001557 SK_(fini)( VG_(exitcode) );
njn4f9c9342002-04-29 16:03:24 +00001558
sewardj0c3b53f2002-05-01 01:58:35 +00001559 VG_(do_sanity_checks)( True /*include expensive checks*/ );
sewardjde4a1d02002-03-22 01:27:54 +00001560
1561 if (VG_(clo_verbosity) > 1)
1562 vg_show_counts();
1563
sewardjc0d8f682002-11-30 00:49:43 +00001564 if (VG_(clo_verbosity) > 3)
njn25e49d8e72002-09-23 09:36:25 +00001565 VG_(print_UInstr_histogram)();
1566
sewardjde4a1d02002-03-22 01:27:54 +00001567 if (0) {
1568 VG_(message)(Vg_DebugMsg, "");
1569 VG_(message)(Vg_DebugMsg,
1570 "------ Valgrind's internal memory use stats follow ------" );
1571 VG_(mallocSanityCheckAll)();
1572 VG_(show_all_arena_stats)();
1573 VG_(message)(Vg_DebugMsg,
1574 "------ Valgrind's ExeContext management stats follow ------" );
1575 VG_(show_ExeContext_stats)();
sewardjde4a1d02002-03-22 01:27:54 +00001576 }
1577
njn25e49d8e72002-09-23 09:36:25 +00001578 if (VG_(clo_profile))
1579 VGP_(done_profiling)();
sewardjde4a1d02002-03-22 01:27:54 +00001580
1581 VG_(shutdown_logging)();
1582
jsgf855d93d2003-10-13 22:26:55 +00001583 /* We're exiting, so nuke all the threads and clean up the proxy LWPs */
1584 vg_assert(src == VgSrc_FatalSig ||
1585 VG_(threads)[VG_(last_run_tid)].status == VgTs_Runnable ||
1586 VG_(threads)[VG_(last_run_tid)].status == VgTs_WaitJoiner);
1587 VG_(nuke_all_threads_except)(VG_INVALID_THREADID);
1588
sewardj7e87e382002-05-03 19:09:05 +00001589 /* Decide how to exit. This depends on what the scheduler
1590 returned. */
jsgf855d93d2003-10-13 22:26:55 +00001591
sewardj7e87e382002-05-03 19:09:05 +00001592 switch (src) {
1593 case VgSrc_ExitSyscall: /* the normal way out */
1594 vg_assert(VG_(last_run_tid) > 0
1595 && VG_(last_run_tid) < VG_N_THREADS);
jsgf855d93d2003-10-13 22:26:55 +00001596 VG_(proxy_shutdown)();
1597
njn25e49d8e72002-09-23 09:36:25 +00001598 /* The thread's %EBX at the time it did __NR_exit() will hold
1599 the arg to __NR_exit(), so we just do __NR_exit() with
1600 that arg. */
1601 VG_(exit)( VG_(exitcode) );
sewardj7e87e382002-05-03 19:09:05 +00001602 /* NOT ALIVE HERE! */
njne427a662002-10-02 11:08:25 +00001603 VG_(core_panic)("entered the afterlife in vg_main() -- ExitSyscall");
sewardj7e87e382002-05-03 19:09:05 +00001604 break; /* what the hell :) */
sewardjde4a1d02002-03-22 01:27:54 +00001605
sewardj7e87e382002-05-03 19:09:05 +00001606 case VgSrc_Deadlock:
1607 /* Just exit now. No point in continuing. */
jsgf855d93d2003-10-13 22:26:55 +00001608 VG_(proxy_shutdown)();
sewardj7e87e382002-05-03 19:09:05 +00001609 VG_(exit)(0);
njne427a662002-10-02 11:08:25 +00001610 VG_(core_panic)("entered the afterlife in vg_main() -- Deadlock");
sewardj7e87e382002-05-03 19:09:05 +00001611 break;
1612
1613 case VgSrc_BbsDone:
1614 /* Tricky; we have to try and switch back to the real CPU.
1615 This is all very dodgy and won't work at all in the
1616 presence of threads, or if the client happened to be
1617 running a signal handler. */
1618 /* Prepare to restore state to the real CPU. */
sewardj839299f2003-06-14 11:57:59 +00001619 VG_(sigshutdown_actions)();
sewardj7e87e382002-05-03 19:09:05 +00001620 VG_(load_thread_state)(1 /* root thread */ );
1621 VG_(copy_baseBlock_to_m_state_static)();
1622
jsgf855d93d2003-10-13 22:26:55 +00001623 VG_(proxy_shutdown)();
1624
sewardj7e87e382002-05-03 19:09:05 +00001625 /* This pushes a return address on the simulator's stack,
1626 which is abandoned. We call vg_sigshutdown_actions() at
1627 the end of vg_switch_to_real_CPU(), so as to ensure that
1628 the original stack and machine state is restored before
1629 the real signal mechanism is restored. */
1630 VG_(switch_to_real_CPU)();
1631
jsgf855d93d2003-10-13 22:26:55 +00001632 case VgSrc_FatalSig:
1633 /* We were killed by a fatal signal, so replicate the effect */
1634 vg_assert(VG_(fatal_sigNo) != -1);
1635 VG_(kill_self)(VG_(fatal_sigNo));
1636 VG_(core_panic)("vg_main(): signal was supposed to be fatal");
1637 break;
1638
sewardj7e87e382002-05-03 19:09:05 +00001639 default:
njne427a662002-10-02 11:08:25 +00001640 VG_(core_panic)("vg_main(): unexpected scheduler return code");
sewardj7e87e382002-05-03 19:09:05 +00001641 }
sewardjde4a1d02002-03-22 01:27:54 +00001642}
1643
1644
1645/* Debugging thing .. can be called from assembly with OYNK macro. */
1646void VG_(oynk) ( Int n )
1647{
1648 OINK(n);
1649}
1650
1651
fitzhardinge98abfc72003-12-16 02:05:15 +00001652/* Walk through a colon-separated environment variable, and remove the
1653 entries which matches file_pattern. It slides everything down over
1654 the removed entries, and pads the remaining space with '\0'. It
1655 modifies the entries in place (in the client address space), but it
1656 shouldn't matter too much, since we only do this just before an
1657 execve().
sewardj78e25c92002-05-20 23:38:33 +00001658
fitzhardinge98abfc72003-12-16 02:05:15 +00001659 This is also careful to mop up any excess ':'s, since empty strings
1660 delimited by ':' are considered to be '.' in a path.
sewardjde4a1d02002-03-22 01:27:54 +00001661*/
fitzhardinge98abfc72003-12-16 02:05:15 +00001662void VG_(mash_colon_env)(Char *varp, const Char *remove_pattern)
sewardj45b672d2003-07-25 19:58:11 +00001663{
fitzhardinge98abfc72003-12-16 02:05:15 +00001664 Char *const start = varp;
1665 Char *entry_start = varp;
1666 Char *output = varp;
sewardj45b672d2003-07-25 19:58:11 +00001667
fitzhardinge98abfc72003-12-16 02:05:15 +00001668 if (varp == NULL)
sewardjde4a1d02002-03-22 01:27:54 +00001669 return;
fitzhardinge98abfc72003-12-16 02:05:15 +00001670
1671 while(*varp) {
1672 if (*varp == ':') {
1673 Char prev;
1674 Bool match;
1675
1676 /* This is a bit subtle: we want to match against the entry
1677 we just copied, because it may have overlapped with
1678 itself, junking the original. */
1679
1680 prev = *output;
1681 *output = '\0';
1682
1683 match = VG_(string_match)(remove_pattern, entry_start);
1684
1685 *output = prev;
1686
1687 if (match) {
1688 output = entry_start;
1689 varp++; /* skip ':' after removed entry */
1690 } else
1691 entry_start = output+1; /* entry starts after ':' */
1692 }
1693
1694 *output++ = *varp++;
sewardj3e1eb1f2002-05-18 13:14:17 +00001695 }
1696
fitzhardinge98abfc72003-12-16 02:05:15 +00001697 /* match against the last entry */
1698 if (VG_(string_match)(remove_pattern, entry_start)) {
1699 output = entry_start;
1700 if (output > start) {
1701 /* remove trailing ':' */
1702 output--;
1703 vg_assert(*output == ':');
1704 }
1705 }
njn25e49d8e72002-09-23 09:36:25 +00001706
fitzhardinge98abfc72003-12-16 02:05:15 +00001707 /* pad out the left-overs with '\0' */
1708 while(output < varp)
1709 *output++ = '\0';
sewardjde4a1d02002-03-22 01:27:54 +00001710}
1711
1712/* RUNS ON THE CLIENT'S STACK, but on the real CPU. Start GDB and get
1713 it to attach to this process. Called if the user requests this
1714 service after an error has been shown, so she can poke around and
1715 look at parameters, memory, etc. You can't meaningfully get GDB to
1716 continue the program, though; to continue, quit GDB. */
fitzhardingea49f9b52003-12-16 22:26:45 +00001717void VG_(start_GDB_whilst_on_client_stack) ( void )
sewardjde4a1d02002-03-22 01:27:54 +00001718{
sewardje6a25242002-04-21 22:03:07 +00001719 Int res;
sewardjde4a1d02002-03-22 01:27:54 +00001720 UChar buf[100];
njn9315df32003-04-16 20:50:50 +00001721
fitzhardingea49f9b52003-12-16 22:26:45 +00001722 VG_(sprintf)(buf, "%s -nw /proc/%d/fd/%d %d",
1723 VG_(clo_GDB_path), VG_(getpid)(), VG_(clexecfd), VG_(getpid)());
sewardje6a25242002-04-21 22:03:07 +00001724 VG_(message)(Vg_UserMsg, "starting GDB with cmd: %s", buf);
1725 res = VG_(system)(buf);
1726 if (res == 0) {
1727 VG_(message)(Vg_UserMsg, "");
1728 VG_(message)(Vg_UserMsg,
1729 "GDB has detached. Valgrind regains control. We continue.");
1730 } else {
1731 VG_(message)(Vg_UserMsg, "Apparently failed!");
1732 VG_(message)(Vg_UserMsg, "");
sewardjde4a1d02002-03-22 01:27:54 +00001733 }
sewardjde4a1d02002-03-22 01:27:54 +00001734}
1735
1736
1737/* Print some helpful-ish text about unimplemented things, and give
1738 up. */
sewardjcfc39b22002-05-08 01:58:18 +00001739void VG_(unimplemented) ( Char* msg )
sewardjde4a1d02002-03-22 01:27:54 +00001740{
1741 VG_(message)(Vg_UserMsg, "");
1742 VG_(message)(Vg_UserMsg,
1743 "Valgrind detected that your program requires");
1744 VG_(message)(Vg_UserMsg,
1745 "the following unimplemented functionality:");
1746 VG_(message)(Vg_UserMsg, " %s", msg);
1747 VG_(message)(Vg_UserMsg,
1748 "This may be because the functionality is hard to implement,");
1749 VG_(message)(Vg_UserMsg,
1750 "or because no reasonable program would behave this way,");
1751 VG_(message)(Vg_UserMsg,
nethercote421281e2003-11-20 16:20:55 +00001752 "or because nobody has yet needed it. In any case, let us know at");
sewardjde4a1d02002-03-22 01:27:54 +00001753 VG_(message)(Vg_UserMsg,
nethercote421281e2003-11-20 16:20:55 +00001754 "%s and/or try to work around the problem, if you can.", VG_BUGS_TO);
sewardjde4a1d02002-03-22 01:27:54 +00001755 VG_(message)(Vg_UserMsg,
1756 "");
1757 VG_(message)(Vg_UserMsg,
1758 "Valgrind has to exit now. Sorry. Bye!");
1759 VG_(message)(Vg_UserMsg,
1760 "");
sewardj15a43e12002-04-17 19:35:12 +00001761 VG_(pp_sched_status)();
sewardjde4a1d02002-03-22 01:27:54 +00001762 VG_(exit)(1);
1763}
1764
1765
njn25e49d8e72002-09-23 09:36:25 +00001766/* ---------------------------------------------------------------------
1767 Sanity check machinery (permanently engaged).
1768 ------------------------------------------------------------------ */
1769
1770/* A fast sanity check -- suitable for calling circa once per
1771 millisecond. */
1772
1773void VG_(do_sanity_checks) ( Bool force_expensive )
1774{
njn37cea302002-09-30 11:24:00 +00001775 VGP_PUSHCC(VgpCoreCheapSanity);
1776
njn25e49d8e72002-09-23 09:36:25 +00001777 if (VG_(sanity_level) < 1) return;
1778
1779 /* --- First do all the tests that we can do quickly. ---*/
1780
1781 VG_(sanity_fast_count)++;
1782
njn25e49d8e72002-09-23 09:36:25 +00001783 /* Check stuff pertaining to the memory check system. */
1784
1785 /* Check that nobody has spuriously claimed that the first or
1786 last 16 pages of memory have become accessible [...] */
njn37cea302002-09-30 11:24:00 +00001787 if (VG_(needs).sanity_checks) {
1788 VGP_PUSHCC(VgpSkinCheapSanity);
njn25e49d8e72002-09-23 09:36:25 +00001789 vg_assert(SK_(cheap_sanity_check)());
njn37cea302002-09-30 11:24:00 +00001790 VGP_POPCC(VgpSkinCheapSanity);
1791 }
njn25e49d8e72002-09-23 09:36:25 +00001792
1793 /* --- Now some more expensive checks. ---*/
1794
1795 /* Once every 25 times, check some more expensive stuff. */
1796 if ( force_expensive
1797 || VG_(sanity_level) > 1
1798 || (VG_(sanity_level) == 1 && (VG_(sanity_fast_count) % 25) == 0)) {
1799
njn37cea302002-09-30 11:24:00 +00001800 VGP_PUSHCC(VgpCoreExpensiveSanity);
njn25e49d8e72002-09-23 09:36:25 +00001801 VG_(sanity_slow_count)++;
1802
jsgf855d93d2003-10-13 22:26:55 +00001803 VG_(proxy_sanity)();
1804
njn25e49d8e72002-09-23 09:36:25 +00001805# if 0
1806 { void zzzmemscan(void); zzzmemscan(); }
1807# endif
1808
1809 if ((VG_(sanity_fast_count) % 250) == 0)
1810 VG_(sanity_check_tc_tt)();
1811
1812 if (VG_(needs).sanity_checks) {
njn37cea302002-09-30 11:24:00 +00001813 VGP_PUSHCC(VgpSkinExpensiveSanity);
njn25e49d8e72002-09-23 09:36:25 +00001814 vg_assert(SK_(expensive_sanity_check)());
njn37cea302002-09-30 11:24:00 +00001815 VGP_POPCC(VgpSkinExpensiveSanity);
njn25e49d8e72002-09-23 09:36:25 +00001816 }
1817 /*
1818 if ((VG_(sanity_fast_count) % 500) == 0) VG_(mallocSanityCheckAll)();
1819 */
njn37cea302002-09-30 11:24:00 +00001820 VGP_POPCC(VgpCoreExpensiveSanity);
njn25e49d8e72002-09-23 09:36:25 +00001821 }
1822
1823 if (VG_(sanity_level) > 1) {
njn37cea302002-09-30 11:24:00 +00001824 VGP_PUSHCC(VgpCoreExpensiveSanity);
njn25e49d8e72002-09-23 09:36:25 +00001825 /* Check sanity of the low-level memory manager. Note that bugs
1826 in the client's code can cause this to fail, so we don't do
1827 this check unless specially asked for. And because it's
1828 potentially very expensive. */
1829 VG_(mallocSanityCheckAll)();
njn37cea302002-09-30 11:24:00 +00001830 VGP_POPCC(VgpCoreExpensiveSanity);
njn25e49d8e72002-09-23 09:36:25 +00001831 }
njn37cea302002-09-30 11:24:00 +00001832 VGP_POPCC(VgpCoreCheapSanity);
njn25e49d8e72002-09-23 09:36:25 +00001833}
sewardjde4a1d02002-03-22 01:27:54 +00001834/*--------------------------------------------------------------------*/
1835/*--- end vg_main.c ---*/
1836/*--------------------------------------------------------------------*/