blob: ceb2536dfbdb3f3190da6d7e3a0aa7ba16616615 [file] [log] [blame]
njn25e49d8e72002-09-23 09:36:25 +00001
2/*--------------------------------------------------------------------*/
3/*--- The only header your skin will ever need to #include... ---*/
4/*--- vg_skin.h ---*/
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.
njn25e49d8e72002-09-23 09:36:25 +000010
11 Copyright (C) 2000-2002 Julian Seward
12 jseward@acm.org
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30*/
31
32#ifndef __VG_SKIN_H
33#define __VG_SKIN_H
34
35#include <stdarg.h> /* ANSI varargs stuff */
36#include <setjmp.h> /* for jmp_buf */
37
38#include "vg_constants_skin.h"
39
40
41/*====================================================================*/
42/*=== Build options and table sizes. ===*/
43/*====================================================================*/
44
45/* You should be able to change these options or sizes, recompile, and
46 still have a working system. */
47
48/* The maximum number of pthreads that we support. This is
49 deliberately not very high since our implementation of some of the
50 scheduler algorithms is surely O(N) in the number of threads, since
51 that's simple, at least. And (in practice) we hope that most
52 programs do not need many threads. */
53#define VG_N_THREADS 50
54
55/* Maximum number of pthread keys available. Again, we start low until
56 the need for a higher number presents itself. */
57#define VG_N_THREAD_KEYS 50
58
59/* Total number of integer registers available for allocation -- all of
60 them except %esp, %ebp. %ebp permanently points at VG_(baseBlock).
61
62 If you change this you'll have to also change at least these:
njn4ba5a792002-09-30 10:23:54 +000063 - VG_(rank_to_realreg)()
64 - VG_(realreg_to_rank)()
njn25e49d8e72002-09-23 09:36:25 +000065 - ppRegsLiveness()
66 - the RegsLive type (maybe -- RegsLive type must have more than
67 VG_MAX_REALREGS bits)
68
69 Do not change this unless you really know what you are doing! */
70#define VG_MAX_REALREGS 6
71
72
73/*====================================================================*/
njn1a1dd8b2002-09-27 10:42:20 +000074/*=== Basic types, useful macros ===*/
njn25e49d8e72002-09-23 09:36:25 +000075/*====================================================================*/
76
njn25e49d8e72002-09-23 09:36:25 +000077typedef unsigned char UChar;
78typedef unsigned short UShort;
79typedef unsigned int UInt;
80typedef unsigned long long int ULong;
81
82typedef signed char Char;
83typedef signed short Short;
84typedef signed int Int;
85typedef signed long long int Long;
86
87typedef unsigned int Addr;
88
89typedef unsigned char Bool;
90#define False ((Bool)0)
91#define True ((Bool)1)
92
93
njn1a1dd8b2002-09-27 10:42:20 +000094#define mycat_wrk(aaa,bbb) aaa##bbb
95#define mycat(aaa,bbb) mycat_wrk(aaa,bbb)
96
97/* No, really. I _am_ that strange. */
98#define OINK(nnn) VG_(message)(Vg_DebugMsg, "OINK %d",nnn)
99
njn25e49d8e72002-09-23 09:36:25 +0000100/* ---------------------------------------------------------------------
101 Now the basic types are set up, we can haul in the kernel-interface
102 definitions.
103 ------------------------------------------------------------------ */
104
njn2574bb4762002-09-24 11:23:50 +0000105#include "../coregrind/vg_kerneliface.h"
njn25e49d8e72002-09-23 09:36:25 +0000106
107
108/*====================================================================*/
109/*=== Command-line options ===*/
110/*====================================================================*/
111
112/* Verbosity level: 0 = silent, 1 (default), > 1 = more verbose. */
113extern Int VG_(clo_verbosity);
114
115/* Profile? */
116extern Bool VG_(clo_profile);
117
njn25e49d8e72002-09-23 09:36:25 +0000118/* Call this if a recognised option was bad for some reason.
119 Note: don't use it just because an option was unrecognised -- return 'False'
120 from SKN_(process_cmd_line_option) to indicate that. */
121extern void VG_(bad_option) ( Char* opt );
122
123/* Client args */
124extern Int VG_(client_argc);
125extern Char** VG_(client_argv);
126
njnd5bb0a52002-09-27 10:24:48 +0000127/* Client environment. Can be inspected with VG_(getenv)() */
njn25e49d8e72002-09-23 09:36:25 +0000128extern Char** VG_(client_envp);
129
130
131/*====================================================================*/
132/*=== Printing messages for the user ===*/
133/*====================================================================*/
134
135/* Print a message prefixed by "??<pid>?? "; '?' depends on the VgMsgKind.
136 Should be used for all user output. */
137
138typedef
139 enum { Vg_UserMsg, /* '?' == '=' */
140 Vg_DebugMsg, /* '?' == '-' */
141 Vg_DebugExtraMsg /* '?' == '+' */
142 }
143 VgMsgKind;
144
145/* Functions for building a message from multiple parts. */
146extern void VG_(start_msg) ( VgMsgKind kind );
147extern void VG_(add_to_msg) ( Char* format, ... );
148/* Ends and prints the message. Appends a newline. */
149extern void VG_(end_msg) ( void );
150
njnd5bb0a52002-09-27 10:24:48 +0000151/* Send a single-part message. Appends a newline. */
njn25e49d8e72002-09-23 09:36:25 +0000152extern void VG_(message) ( VgMsgKind kind, Char* format, ... );
153
154
155/*====================================================================*/
156/*=== Profiling ===*/
157/*====================================================================*/
158
159/* Nb: VGP_(register_profile_event)() relies on VgpUnc being the first one */
160#define VGP_CORE_LIST \
161 /* These ones depend on the core */ \
162 VGP_PAIR(VgpUnc, "unclassified"), \
163 VGP_PAIR(VgpRun, "running"), \
164 VGP_PAIR(VgpSched, "scheduler"), \
165 VGP_PAIR(VgpMalloc, "low-lev malloc/free"), \
166 VGP_PAIR(VgpCliMalloc, "client malloc/free"), \
167 VGP_PAIR(VgpStack, "adjust-stack"), \
168 VGP_PAIR(VgpTranslate, "translate-main"), \
169 VGP_PAIR(VgpToUCode, "to-ucode"), \
170 VGP_PAIR(VgpFromUcode, "from-ucode"), \
171 VGP_PAIR(VgpImprove, "improve"), \
172 VGP_PAIR(VgpRegAlloc, "reg-alloc"), \
173 VGP_PAIR(VgpLiveness, "liveness-analysis"), \
174 VGP_PAIR(VgpDoLRU, "do-lru"), \
175 VGP_PAIR(VgpSlowFindT, "slow-search-transtab"), \
176 VGP_PAIR(VgpInitMem, "init-memory"), \
177 VGP_PAIR(VgpExeContext, "exe-context"), \
178 VGP_PAIR(VgpReadSyms, "read-syms"), \
179 VGP_PAIR(VgpSearchSyms, "search-syms"), \
180 VGP_PAIR(VgpAddToT, "add-to-transtab"), \
181 VGP_PAIR(VgpCoreSysWrap, "core-syscall-wrapper"), \
182 VGP_PAIR(VgpDemangle, "demangle"), \
njn37cea302002-09-30 11:24:00 +0000183 VGP_PAIR(VgpCoreCheapSanity, "core-cheap-sanity"), \
184 VGP_PAIR(VgpCoreExpensiveSanity, "core-expensive-sanity"), \
njn25e49d8e72002-09-23 09:36:25 +0000185 /* These ones depend on the skin */ \
186 VGP_PAIR(VgpPreCloInit, "pre-clo-init"), \
187 VGP_PAIR(VgpPostCloInit, "post-clo-init"), \
188 VGP_PAIR(VgpInstrument, "instrument"), \
189 VGP_PAIR(VgpSkinSysWrap, "skin-syscall-wrapper"), \
njn37cea302002-09-30 11:24:00 +0000190 VGP_PAIR(VgpSkinCheapSanity, "skin-cheap-sanity"), \
191 VGP_PAIR(VgpSkinExpensiveSanity, "skin-expensive-sanity"), \
njn25e49d8e72002-09-23 09:36:25 +0000192 VGP_PAIR(VgpFini, "fini")
193
194#define VGP_PAIR(n,name) n
195typedef enum { VGP_CORE_LIST } VgpCoreCC;
196#undef VGP_PAIR
197
198/* When registering skin profiling events, ensure that the 'n' value is in
199 * the range (VgpFini+1..) */
200extern void VGP_(register_profile_event) ( Int n, Char* name );
201
202extern void VGP_(pushcc) ( UInt cc );
203extern void VGP_(popcc) ( UInt cc );
204
205/* Define them only if they haven't already been defined by vg_profile.c */
206#ifndef VGP_PUSHCC
207# define VGP_PUSHCC(x)
208#endif
209#ifndef VGP_POPCC
210# define VGP_POPCC(x)
211#endif
212
213
214/*====================================================================*/
215/*=== Useful stuff to call from generated code ===*/
216/*====================================================================*/
217
218/* ------------------------------------------------------------------ */
219/* General stuff */
220
221/* Get the simulated %esp */
222extern Addr VG_(get_stack_pointer) ( void );
223
njnd5bb0a52002-09-27 10:24:48 +0000224/* Detect if an address is within Valgrind's stack or Valgrind's
225 m_state_static; useful for memory leak detectors to tell if a block
226 is used by Valgrind (and thus can be ignored). */
njn25e49d8e72002-09-23 09:36:25 +0000227extern Bool VG_(within_stack)(Addr a);
njn25e49d8e72002-09-23 09:36:25 +0000228extern Bool VG_(within_m_state_static)(Addr a);
229
230/* Check if an address is 4-byte aligned */
231#define IS_ALIGNED4_ADDR(aaa_p) (0 == (((UInt)(aaa_p)) & 3))
232
233
234/* ------------------------------------------------------------------ */
235/* Thread-related stuff */
236
237/* Special magic value for an invalid ThreadId. It corresponds to
238 LinuxThreads using zero as the initial value for
239 pthread_mutex_t.__m_owner and pthread_cond_t.__c_waiting. */
240#define VG_INVALID_THREADID ((ThreadId)(0))
241
242/* ThreadIds are simply indices into the vg_threads[] array. */
243typedef
244 UInt
245 ThreadId;
246
njnd5bb0a52002-09-27 10:24:48 +0000247/* struct _ThreadState defined elsewhere; ThreadState is abstract as its
248 definition is not important for skins. */
njn25e49d8e72002-09-23 09:36:25 +0000249typedef
250 struct _ThreadState
251 ThreadState;
252
253extern ThreadId VG_(get_current_tid_1_if_root) ( void );
254extern ThreadState* VG_(get_ThreadState) ( ThreadId tid );
255
256
257/*====================================================================*/
258/*=== Valgrind's version of libc ===*/
259/*====================================================================*/
260
261/* Valgrind doesn't use libc at all, for good reasons (trust us). So here
262 are its own versions of C library functions, but with VG_ prefixes. Note
263 that the types of some are slightly different to the real ones. Some
264 extra useful functions are provided too; descriptions of how they work
265 are given below. */
266
267#if !defined(NULL)
268# define NULL ((void*)0)
269#endif
270
271
272/* ------------------------------------------------------------------ */
273/* stdio.h
274 *
275 * Note that they all output to the file descriptor given by the
276 * --logfile-fd=N argument, which defaults to 2 (stderr). Hence no
277 * need for VG_(fprintf)().
njn25e49d8e72002-09-23 09:36:25 +0000278 */
279extern void VG_(printf) ( const char *format, ... );
280/* too noisy ... __attribute__ ((format (printf, 1, 2))) ; */
281extern void VG_(sprintf) ( Char* buf, Char *format, ... );
282extern void VG_(vprintf) ( void(*send)(Char),
283 const Char *format, va_list vargs );
284
285/* ------------------------------------------------------------------ */
286/* stdlib.h */
287
288extern void* VG_(malloc) ( Int nbytes );
njnd5bb0a52002-09-27 10:24:48 +0000289extern void VG_(free) ( void* p );
290extern void* VG_(calloc) ( Int n, Int nbytes );
291extern void* VG_(realloc) ( void* p, Int size );
292extern void* VG_(malloc_aligned) ( Int align_bytes, Int nbytes );
njn25e49d8e72002-09-23 09:36:25 +0000293
294extern void VG_(print_malloc_stats) ( void );
295
296
297extern void VG_(exit)( Int status )
298 __attribute__ ((__noreturn__));
njne427a662002-10-02 11:08:25 +0000299/* Prints a panic message (a constant string), appends newline and bug
300 reporting info, aborts. */
301__attribute__ ((__noreturn__))
302extern void VG_(skin_panic) ( Char* str );
njn25e49d8e72002-09-23 09:36:25 +0000303
njnd5bb0a52002-09-27 10:24:48 +0000304/* Looks up VG_(client_envp) */
njn25e49d8e72002-09-23 09:36:25 +0000305extern Char* VG_(getenv) ( Char* name );
306
307/* Crude stand-in for the glibc system() call. */
308extern Int VG_(system) ( Char* cmd );
309
njnd5bb0a52002-09-27 10:24:48 +0000310extern Long VG_(atoll) ( Char* str );
njn25e49d8e72002-09-23 09:36:25 +0000311
312/* Like atoll(), but converts a number of base 2..36 */
313extern Long VG_(atoll36) ( UInt base, Char* str );
314
315
316/* ------------------------------------------------------------------ */
njnd5bb0a52002-09-27 10:24:48 +0000317/* ctype.h */
njn25e49d8e72002-09-23 09:36:25 +0000318extern Bool VG_(isspace) ( Char c );
319extern Bool VG_(isdigit) ( Char c );
320extern Char VG_(toupper) ( Char c );
321
322
323/* ------------------------------------------------------------------ */
324/* string.h */
325extern Int VG_(strlen) ( const Char* str );
326extern Char* VG_(strcat) ( Char* dest, const Char* src );
327extern Char* VG_(strncat) ( Char* dest, const Char* src, Int n );
328extern Char* VG_(strpbrk) ( const Char* s, const Char* accept );
329extern Char* VG_(strcpy) ( Char* dest, const Char* src );
330extern Char* VG_(strncpy) ( Char* dest, const Char* src, Int ndest );
331extern Int VG_(strcmp) ( const Char* s1, const Char* s2 );
332extern Int VG_(strncmp) ( const Char* s1, const Char* s2, Int nmax );
333extern Char* VG_(strstr) ( const Char* haystack, Char* needle );
334extern Char* VG_(strchr) ( const Char* s, Char c );
335extern Char* VG_(strdup) ( const Char* s);
336
njnd5bb0a52002-09-27 10:24:48 +0000337/* Like strcmp() and strncmp(), but stop comparing at any whitespace. */
njn25e49d8e72002-09-23 09:36:25 +0000338extern Int VG_(strcmp_ws) ( const Char* s1, const Char* s2 );
njn25e49d8e72002-09-23 09:36:25 +0000339extern Int VG_(strncmp_ws) ( const Char* s1, const Char* s2, Int nmax );
340
njnd5bb0a52002-09-27 10:24:48 +0000341/* Like strncpy(), but if 'src' is longer than 'ndest' inserts a '\0' as the
342 last character. */
njn25e49d8e72002-09-23 09:36:25 +0000343extern void VG_(strncpy_safely) ( Char* dest, const Char* src, Int ndest );
344
345/* Mini-regexp function. Searches for 'pat' in 'str'. Supports
346 * meta-symbols '*' and '?'. '\' escapes meta-symbols. */
njn4ba5a792002-09-30 10:23:54 +0000347extern Bool VG_(string_match) ( Char* pat, Char* str );
njn25e49d8e72002-09-23 09:36:25 +0000348
349
350/* ------------------------------------------------------------------ */
351/* math.h */
njnd5bb0a52002-09-27 10:24:48 +0000352/* Returns the base-2 logarithm of x. */
njn25e49d8e72002-09-23 09:36:25 +0000353extern Int VG_(log2) ( Int x );
354
355
356/* ------------------------------------------------------------------ */
njnd5bb0a52002-09-27 10:24:48 +0000357/* unistd.h, fcntl.h, sys/stat.h */
358extern Int VG_(getpid) ( void );
359
njn4aca2d22002-10-04 10:29:38 +0000360extern Int VG_(open) ( const Char* pathname, Int flags, Int mode );
361extern Int VG_(read) ( Int fd, void* buf, Int count);
362extern Int VG_(write) ( Int fd, void* buf, Int count);
363extern void VG_(close) ( Int fd );
njnd5bb0a52002-09-27 10:24:48 +0000364
njn4aca2d22002-10-04 10:29:38 +0000365extern Int VG_(unlink) ( Char* file_name );
366extern Int VG_(stat) ( Char* file_name, struct vki_stat* buf );
njn25e49d8e72002-09-23 09:36:25 +0000367
368
369/* ------------------------------------------------------------------ */
370/* assert.h */
371/* Asserts permanently enabled -- no turning off with NDEBUG. Hurrah! */
372#define VG__STRING(__str) #__str
373
njne427a662002-10-02 11:08:25 +0000374#define sk_assert(expr) \
njn25e49d8e72002-09-23 09:36:25 +0000375 ((void) ((expr) ? 0 : \
njne427a662002-10-02 11:08:25 +0000376 (VG_(skin_assert_fail) (VG__STRING(expr), \
377 __FILE__, __LINE__, \
378 __PRETTY_FUNCTION__), 0)))
njn25e49d8e72002-09-23 09:36:25 +0000379
njne427a662002-10-02 11:08:25 +0000380__attribute__ ((__noreturn__))
381extern void VG_(skin_assert_fail) ( Char* expr, Char* file,
382 Int line, Char* fn );
njn25e49d8e72002-09-23 09:36:25 +0000383
384
385/* ------------------------------------------------------------------ */
njnd5bb0a52002-09-27 10:24:48 +0000386/* system/mman.h */
njn25e49d8e72002-09-23 09:36:25 +0000387extern void* VG_(mmap)( void* start, UInt length,
388 UInt prot, UInt flags, UInt fd, UInt offset );
389extern Int VG_(munmap)( void* start, Int length );
390
391/* Get memory by anonymous mmap. */
392extern void* VG_(get_memory_from_mmap) ( Int nBytes, Char* who );
393
394
395/* ------------------------------------------------------------------ */
396/* signal.h.
397
398 Note that these use the vk_ (kernel) structure
399 definitions, which are different in places from those that glibc
400 defines -- hence the 'k' prefix. Since we're operating right at the
401 kernel interface, glibc's view of the world is entirely irrelevant. */
402
403/* --- Signal set ops --- */
njnd5bb0a52002-09-27 10:24:48 +0000404extern Int VG_(ksigfillset) ( vki_ksigset_t* set );
405extern Int VG_(ksigemptyset) ( vki_ksigset_t* set );
njn25e49d8e72002-09-23 09:36:25 +0000406
njnd5bb0a52002-09-27 10:24:48 +0000407extern Bool VG_(kisfullsigset) ( vki_ksigset_t* set );
408extern Bool VG_(kisemptysigset) ( vki_ksigset_t* set );
njn25e49d8e72002-09-23 09:36:25 +0000409
njnd5bb0a52002-09-27 10:24:48 +0000410extern Int VG_(ksigaddset) ( vki_ksigset_t* set, Int signum );
411extern Int VG_(ksigdelset) ( vki_ksigset_t* set, Int signum );
njn25e49d8e72002-09-23 09:36:25 +0000412extern Int VG_(ksigismember) ( vki_ksigset_t* set, Int signum );
413
njnd5bb0a52002-09-27 10:24:48 +0000414extern void VG_(ksigaddset_from_set) ( vki_ksigset_t* dst, vki_ksigset_t* src );
415extern void VG_(ksigdelset_from_set) ( vki_ksigset_t* dst, vki_ksigset_t* src );
njn25e49d8e72002-09-23 09:36:25 +0000416
417/* --- Mess with the kernel's sig state --- */
njnd5bb0a52002-09-27 10:24:48 +0000418extern Int VG_(ksigprocmask) ( Int how, const vki_ksigset_t* set,
njn25e49d8e72002-09-23 09:36:25 +0000419 vki_ksigset_t* oldset );
njnd5bb0a52002-09-27 10:24:48 +0000420extern Int VG_(ksigaction) ( Int signum,
421 const vki_ksigaction* act,
422 vki_ksigaction* oldact );
njn25e49d8e72002-09-23 09:36:25 +0000423
njnd5bb0a52002-09-27 10:24:48 +0000424extern Int VG_(ksignal) ( Int signum, void (*sighandler)(Int) );
425extern Int VG_(ksigaltstack) ( const vki_kstack_t* ss, vki_kstack_t* oss );
njn25e49d8e72002-09-23 09:36:25 +0000426
sewardjdcaf3122002-09-30 23:12:33 +0000427extern Int VG_(kkill) ( Int pid, Int signo );
428extern Int VG_(ksigpending) ( vki_ksigset_t* set );
njn25e49d8e72002-09-23 09:36:25 +0000429
430
431/*====================================================================*/
432/*=== UCode definition ===*/
433/*====================================================================*/
434
sewardje1042472002-09-30 12:33:11 +0000435/* Tags which describe what operands are. Must fit into 4 bits, which
436 they clearly do. */
njn25e49d8e72002-09-23 09:36:25 +0000437typedef
sewardje1042472002-09-30 12:33:11 +0000438enum { TempReg =0, /* virtual temp-reg */
439 ArchReg =1, /* simulated integer reg */
440 ArchRegS =2, /* simulated segment reg */
441 RealReg =3, /* real machine's real reg */
442 SpillNo =4, /* spill slot location */
443 Literal =5, /* literal; .lit32 field has actual value */
444 Lit16 =6, /* literal; .val[123] field has actual value */
445 NoValue =7 /* operand not in use */
446 }
447 Tag;
njn25e49d8e72002-09-23 09:36:25 +0000448
njnd5bb0a52002-09-27 10:24:48 +0000449/* Invalid register numbers (can't be negative) */
njn25e49d8e72002-09-23 09:36:25 +0000450#define INVALID_TEMPREG 999999999
451#define INVALID_REALREG 999999999
452
453/* Microinstruction opcodes. */
454typedef
455 enum {
njnd5bb0a52002-09-27 10:24:48 +0000456 NOP, /* Null op */
njn25e49d8e72002-09-23 09:36:25 +0000457
njnd5bb0a52002-09-27 10:24:48 +0000458 /* Moving values around */
459 GET, PUT, /* simulated register <--> TempReg */
460 GETF, PUTF, /* simulated %eflags <--> TempReg */
461 LOAD, STORE, /* memory <--> TempReg */
462 MOV, /* TempReg <--> TempReg */
463 CMOV, /* Used for cmpxchg and cmov */
njn25e49d8e72002-09-23 09:36:25 +0000464
njnd5bb0a52002-09-27 10:24:48 +0000465 /* Arithmetic/logical ops */
466 ADD, ADC, SUB, SBB, /* Add/subtract (w/wo carry) */
467 AND, OR, XOR, NOT, /* Boolean ops */
468 SHL, SHR, SAR, ROL, ROR, RCL, RCR, /* Shift/rotate (w/wo carry) */
469 NEG, /* Negate */
470 INC, DEC, /* Increment/decrement */
471 BSWAP, /* Big-endian <--> little-endian */
472 CC2VAL, /* Condition code --> 0 or 1 */
473 WIDEN, /* Signed or unsigned widening */
njn25e49d8e72002-09-23 09:36:25 +0000474
njnd5bb0a52002-09-27 10:24:48 +0000475 /* Conditional or unconditional jump */
476 JMP,
477
478 /* FPU ops */
479 FPU, /* Doesn't touch memory */
480 FPU_R, FPU_W, /* Reads/writes memory */
481
482 /* Not strictly needed, but improve address calculation translations. */
njn25e49d8e72002-09-23 09:36:25 +0000483 LEA1, /* reg2 := const + reg1 */
484 LEA2, /* reg3 := const + reg1 + reg2 * 1,2,4 or 8 */
485
njnd5bb0a52002-09-27 10:24:48 +0000486 /* Hack for x86 REP insns. Jump to literal if TempReg/RealReg is zero. */
487 JIFZ,
njn25e49d8e72002-09-23 09:36:25 +0000488
njnd5bb0a52002-09-27 10:24:48 +0000489 /* Advance the simulated %eip by some small (< 128) number. */
490 INCEIP,
njn25e49d8e72002-09-23 09:36:25 +0000491
sewardje1042472002-09-30 12:33:11 +0000492 /* Dealing with segment registers */
493 GETSEG, PUTSEG, /* simulated segment register <--> TempReg */
494 USESEG, /* (LDT/GDT index, virtual addr) --> linear addr */
495
njnd5bb0a52002-09-27 10:24:48 +0000496 /* Not for translating x86 calls -- only to call helpers */
497 CALLM_S, CALLM_E, /* Mark start/end of CALLM push/pop sequence */
498 PUSH, POP, CLEAR, /* Add/remove/zap args for helpers */
499 CALLM, /* Call assembly-code helper */
500
501 /* Not for translating x86 calls -- only to call C helper functions of
502 up to three arguments (or two if the functions has a return value).
503 Arguments and return value must be word-sized. More arguments can
504 be faked with global variables (eg. use VG_(set_global_var)()).
505
506 Seven possibilities: 'arg[123]' show where args go, 'ret' shows
507 where return value goes (if present).
njn25e49d8e72002-09-23 09:36:25 +0000508
509 CCALL(-, -, - ) void f(void)
510 CCALL(arg1, -, - ) void f(UInt arg1)
511 CCALL(arg1, arg2, - ) void f(UInt arg1, UInt arg2)
512 CCALL(arg1, arg2, arg3) void f(UInt arg1, UInt arg2, UInt arg3)
513 CCALL(-, -, ret ) UInt f(UInt)
514 CCALL(arg1, -, ret ) UInt f(UInt arg1)
njnd5bb0a52002-09-27 10:24:48 +0000515 CCALL(arg1, arg2, ret ) UInt f(UInt arg1, UInt arg2) */
njn25e49d8e72002-09-23 09:36:25 +0000516 CCALL,
517
njnd5bb0a52002-09-27 10:24:48 +0000518 /* This opcode makes it easy for skins that extend UCode to do this to
519 avoid opcode overlap:
njn25e49d8e72002-09-23 09:36:25 +0000520
njnd5bb0a52002-09-27 10:24:48 +0000521 enum { EU_OP1 = DUMMY_FINAL_UOPCODE + 1, ... }
njn25e49d8e72002-09-23 09:36:25 +0000522
523 WARNING: Do not add new opcodes after this one! They can be added
524 before, though. */
525 DUMMY_FINAL_UOPCODE
526 }
527 Opcode;
528
529
njnd5bb0a52002-09-27 10:24:48 +0000530/* Condition codes, using the Intel encoding. CondAlways is an extra. */
njn25e49d8e72002-09-23 09:36:25 +0000531typedef
532 enum {
533 CondO = 0, /* overflow */
534 CondNO = 1, /* no overflow */
535 CondB = 2, /* below */
536 CondNB = 3, /* not below */
537 CondZ = 4, /* zero */
538 CondNZ = 5, /* not zero */
539 CondBE = 6, /* below or equal */
540 CondNBE = 7, /* not below or equal */
541 CondS = 8, /* negative */
sewardje1042472002-09-30 12:33:11 +0000542 CondNS = 9, /* not negative */
njn25e49d8e72002-09-23 09:36:25 +0000543 CondP = 10, /* parity even */
544 CondNP = 11, /* not parity even */
545 CondL = 12, /* jump less */
546 CondNL = 13, /* not less */
547 CondLE = 14, /* less or equal */
548 CondNLE = 15, /* not less or equal */
549 CondAlways = 16 /* Jump always */
550 }
551 Condcode;
552
553
554/* Descriptions of additional properties of *unconditional* jumps. */
555typedef
556 enum {
557 JmpBoring=0, /* boring unconditional jump */
558 JmpCall=1, /* jump due to an x86 call insn */
559 JmpRet=2, /* jump due to an x86 ret insn */
560 JmpSyscall=3, /* do a system call, then jump */
561 JmpClientReq=4 /* do a client request, then jump */
562 }
563 JmpKind;
564
565
566/* Flags. User-level code can only read/write O(verflow), S(ign),
567 Z(ero), A(ux-carry), C(arry), P(arity), and may also write
568 D(irection). That's a total of 7 flags. A FlagSet is a bitset,
569 thusly:
570 76543210
571 DOSZACP
572 and bit 7 must always be zero since it is unused.
573*/
574typedef UChar FlagSet;
575
576#define FlagD (1<<6)
577#define FlagO (1<<5)
578#define FlagS (1<<4)
579#define FlagZ (1<<3)
580#define FlagA (1<<2)
581#define FlagC (1<<1)
582#define FlagP (1<<0)
583
584#define FlagsOSZACP (FlagO | FlagS | FlagZ | FlagA | FlagC | FlagP)
585#define FlagsOSZAP (FlagO | FlagS | FlagZ | FlagA | FlagP)
586#define FlagsOSZCP (FlagO | FlagS | FlagZ | FlagC | FlagP)
587#define FlagsOSACP (FlagO | FlagS | FlagA | FlagC | FlagP)
588#define FlagsSZACP ( FlagS | FlagZ | FlagA | FlagC | FlagP)
589#define FlagsSZAP ( FlagS | FlagZ | FlagA | FlagP)
590#define FlagsZCP ( FlagZ | FlagC | FlagP)
591#define FlagsOC (FlagO | FlagC )
592#define FlagsAC ( FlagA | FlagC )
593
594#define FlagsALL (FlagsOSZACP | FlagD)
595#define FlagsEmpty (FlagSet)0
596
597
598/* Liveness of general purpose registers, useful for code generation.
599 Reg rank order 0..N-1 corresponds to bits 0..N-1, ie. first
600 reg's liveness in bit 0, last reg's in bit N-1. Note that
601 these rankings don't match the Intel register ordering. */
602typedef UInt RRegSet;
603
604#define ALL_RREGS_DEAD 0 /* 0000...00b */
njne7c258c2002-10-03 08:57:01 +0000605#define ALL_RREGS_LIVE ((1 << VG_MAX_REALREGS)-1) /* 0011...11b */
njn25e49d8e72002-09-23 09:36:25 +0000606#define UNIT_RREGSET(rank) (1 << (rank))
607
608#define IS_RREG_LIVE(rank,rregs_live) (rregs_live & UNIT_RREGSET(rank))
609#define SET_RREG_LIVENESS(rank,rregs_live,b) \
610 do { RRegSet unit = UNIT_RREGSET(rank); \
611 if (b) rregs_live |= unit; \
612 else rregs_live &= ~unit; \
613 } while(0)
614
615
616/* A Micro (u)-instruction. */
617typedef
618 struct {
619 /* word 1 */
620 UInt lit32; /* 32-bit literal */
621
622 /* word 2 */
623 UShort val1; /* first operand */
624 UShort val2; /* second operand */
625
626 /* word 3 */
627 UShort val3; /* third operand */
628 UChar opcode; /* opcode */
629 UChar size; /* data transfer size */
630
631 /* word 4 */
632 FlagSet flags_r; /* :: FlagSet */
633 FlagSet flags_w; /* :: FlagSet */
634 UChar tag1:4; /* first operand tag */
635 UChar tag2:4; /* second operand tag */
636 UChar tag3:4; /* third operand tag */
637 UChar extra4b:4; /* Spare field, used by WIDEN for src
638 -size, and by LEA2 for scale (1,2,4 or 8),
639 and by JMPs for original x86 instr size */
640
641 /* word 5 */
642 UChar cond; /* condition, for jumps */
643 Bool signed_widen:1; /* signed or unsigned WIDEN ? */
644 JmpKind jmpkind:3; /* additional properties of unconditional JMP */
645
646 /* Additional properties for UInstrs that call C functions:
647 - CCALL
648 - PUT (when %ESP is the target)
649 - possibly skin-specific UInstrs
650 */
651 UChar argc:2; /* Number of args, max 3 */
652 UChar regparms_n:2; /* Number of args passed in registers */
653 Bool has_ret_val:1; /* Function has return value? */
654
655 /* RealReg liveness; only sensical after reg alloc and liveness
656 analysis done. This info is a little bit arch-specific --
657 VG_MAX_REALREGS can vary on different architectures. Note that
658 to use this information requires converting between register ranks
njn4ba5a792002-09-30 10:23:54 +0000659 and the Intel register numbers, using VG_(realreg_to_rank)()
660 and/or VG_(rank_to_realreg)() */
njn25e49d8e72002-09-23 09:36:25 +0000661 RRegSet regs_live_after:VG_MAX_REALREGS;
662 }
663 UInstr;
664
665
666/* Expandable arrays of uinstrs. */
667typedef
668 struct {
669 Int used;
670 Int size;
671 UInstr* instrs;
672 Int nextTemp;
673 }
674 UCodeBlock;
675
676
677/*====================================================================*/
678/*=== Instrumenting UCode ===*/
679/*====================================================================*/
680
681/* A structure for communicating TempReg and RealReg uses of UInstrs. */
682typedef
683 struct {
684 Int num;
685 Bool isWrite;
686 }
687 RegUse;
688
689/* Find what this instruction does to its regs. Tag indicates whether we're
690 * considering TempRegs (pre-reg-alloc) or RealRegs (post-reg-alloc).
691 * Useful for analysis/optimisation passes. */
njn4ba5a792002-09-30 10:23:54 +0000692extern Int VG_(get_reg_usage) ( UInstr* u, Tag tag, RegUse* arr );
njn25e49d8e72002-09-23 09:36:25 +0000693
694
695/* ------------------------------------------------------------------ */
njnd5bb0a52002-09-27 10:24:48 +0000696/* Used to register helper functions to be called from generated code. A
697 limited number of compact helpers can be registered; the code generated
698 to call them is slightly shorter -- so register the mostly frequently
699 called helpers as compact. */
njn25e49d8e72002-09-23 09:36:25 +0000700extern void VG_(register_compact_helper) ( Addr a );
701extern void VG_(register_noncompact_helper) ( Addr a );
702
703
704/* ------------------------------------------------------------------ */
705/* Virtual register allocation */
706
707/* Get a new virtual register */
njn4ba5a792002-09-30 10:23:54 +0000708extern Int VG_(get_new_temp) ( UCodeBlock* cb );
njn25e49d8e72002-09-23 09:36:25 +0000709
710/* Get a new virtual shadow register */
njn4ba5a792002-09-30 10:23:54 +0000711extern Int VG_(get_new_shadow) ( UCodeBlock* cb );
njn25e49d8e72002-09-23 09:36:25 +0000712
713/* Get a virtual register's corresponding virtual shadow register */
714#define SHADOW(tempreg) ((tempreg)+1)
715
716
717/* ------------------------------------------------------------------ */
718/* Low-level UInstr builders */
njn4ba5a792002-09-30 10:23:54 +0000719extern void VG_(new_NOP) ( UInstr* u );
720extern void VG_(new_UInstr0) ( UCodeBlock* cb, Opcode opcode, Int sz );
721extern void VG_(new_UInstr1) ( UCodeBlock* cb, Opcode opcode, Int sz,
njn25e49d8e72002-09-23 09:36:25 +0000722 Tag tag1, UInt val1 );
njn4ba5a792002-09-30 10:23:54 +0000723extern void VG_(new_UInstr2) ( UCodeBlock* cb, Opcode opcode, Int sz,
njn25e49d8e72002-09-23 09:36:25 +0000724 Tag tag1, UInt val1,
725 Tag tag2, UInt val2 );
njn4ba5a792002-09-30 10:23:54 +0000726extern void VG_(new_UInstr3) ( UCodeBlock* cb, Opcode opcode, Int sz,
njn25e49d8e72002-09-23 09:36:25 +0000727 Tag tag1, UInt val1,
728 Tag tag2, UInt val2,
729 Tag tag3, UInt val3 );
njn25e49d8e72002-09-23 09:36:25 +0000730
njn4ba5a792002-09-30 10:23:54 +0000731extern void VG_(set_flag_RW) ( UInstr* u, FlagSet fr, FlagSet fw );
732extern void VG_(set_lit_field) ( UCodeBlock* cb, UInt lit32 );
733extern void VG_(set_ccall_fields) ( UCodeBlock* cb, Addr fn, UChar argc,
734 UChar regparms_n, Bool has_ret_val );
njn25e49d8e72002-09-23 09:36:25 +0000735
njn4ba5a792002-09-30 10:23:54 +0000736extern void VG_(copy_UInstr) ( UCodeBlock* cb, UInstr* instr );
737
738extern Bool VG_(any_flag_use)( UInstr* u );
njn25e49d8e72002-09-23 09:36:25 +0000739
njnac6c1762002-10-04 14:34:15 +0000740/* Macro versions of the above; just shorter to type. */
741#define uInstr0 VG_(new_UInstr0)
742#define uInstr1 VG_(new_UInstr1)
743#define uInstr2 VG_(new_UInstr2)
744#define uInstr3 VG_(new_UInstr3)
745#define uLiteral VG_(set_lit_field)
746#define uCCall VG_(set_ccall_fields)
747#define newTemp VG_(get_new_temp)
748#define newShadow VG_(get_new_shadow)
749
njn25e49d8e72002-09-23 09:36:25 +0000750/* Refer to `the last instruction stuffed in' (can be lvalue). */
751#define LAST_UINSTR(cb) (cb)->instrs[(cb)->used-1]
752
753
754/* ------------------------------------------------------------------ */
755/* Higher-level UInstr sequence builders */
njn4ba5a792002-09-30 10:23:54 +0000756extern void VG_(call_helper_0_0) ( UCodeBlock* cb, Addr f);
757extern void VG_(call_helper_1_0) ( UCodeBlock* cb, Addr f, UInt arg1,
758 UInt regparms_n);
759extern void VG_(call_helper_2_0) ( UCodeBlock* cb, Addr f, UInt arg1, UInt arg2,
760 UInt regparms_n);
njn25e49d8e72002-09-23 09:36:25 +0000761
762/* One way around the 3-arg C function limit is to pass args via global
763 * variables... ugly, but it works. */
njn4ba5a792002-09-30 10:23:54 +0000764extern void VG_(set_global_var) ( UCodeBlock* cb, Addr globvar_ptr, UInt val);
njn25e49d8e72002-09-23 09:36:25 +0000765
766/* ------------------------------------------------------------------ */
njnd5bb0a52002-09-27 10:24:48 +0000767/* Allocating/freeing basic blocks of UCode */
njn4ba5a792002-09-30 10:23:54 +0000768extern UCodeBlock* VG_(alloc_UCodeBlock) ( void );
769extern void VG_(free_UCodeBlock) ( UCodeBlock* cb );
njnd5bb0a52002-09-27 10:24:48 +0000770
771/* ------------------------------------------------------------------ */
772/* UCode pretty/ugly printing. Probably only useful to call from a skin
njn25e49d8e72002-09-23 09:36:25 +0000773 if VG_(needs).extended_UCode == True. */
774
775/* When True, all generated code is/should be printed. */
776extern Bool VG_(print_codegen);
777
njn4ba5a792002-09-30 10:23:54 +0000778/* Pretty/ugly printing functions */
779extern void VG_(pp_UCodeBlock) ( UCodeBlock* cb, Char* title );
780extern void VG_(pp_UInstr) ( Int instrNo, UInstr* u );
781extern void VG_(pp_UInstr_regs) ( Int instrNo, UInstr* u );
782extern void VG_(up_UInstr) ( Int instrNo, UInstr* u );
783extern Char* VG_(name_UOpcode) ( Bool upper, Opcode opc );
784extern void VG_(pp_UOperand) ( UInstr* u, Int operandNo,
785 Int sz, Bool parens );
njn25e49d8e72002-09-23 09:36:25 +0000786
njn25e49d8e72002-09-23 09:36:25 +0000787
788/*====================================================================*/
njnd5bb0a52002-09-27 10:24:48 +0000789/*=== Generating x86 code from UCode ===*/
njn25e49d8e72002-09-23 09:36:25 +0000790/*====================================================================*/
791
njnd5bb0a52002-09-27 10:24:48 +0000792/* All this only necessary for skins with VG_(needs).extends_UCode == True. */
njn25e49d8e72002-09-23 09:36:25 +0000793
sewardje1042472002-09-30 12:33:11 +0000794/* This is the Intel register encoding -- integer regs. */
njn25e49d8e72002-09-23 09:36:25 +0000795#define R_EAX 0
796#define R_ECX 1
797#define R_EDX 2
798#define R_EBX 3
799#define R_ESP 4
800#define R_EBP 5
801#define R_ESI 6
802#define R_EDI 7
803
804#define R_AL (0+R_EAX)
805#define R_CL (0+R_ECX)
806#define R_DL (0+R_EDX)
807#define R_BL (0+R_EBX)
808#define R_AH (4+R_EAX)
809#define R_CH (4+R_ECX)
810#define R_DH (4+R_EDX)
811#define R_BH (4+R_EBX)
812
sewardje1042472002-09-30 12:33:11 +0000813/* This is the Intel register encoding -- segment regs. */
814#define R_ES 0
815#define R_CS 1
816#define R_SS 2
817#define R_DS 3
818#define R_FS 4
819#define R_GS 5
820
njn25e49d8e72002-09-23 09:36:25 +0000821/* For pretty printing x86 code */
sewardje1042472002-09-30 12:33:11 +0000822extern Char* VG_(name_of_seg_reg) ( Int sreg );
njn4ba5a792002-09-30 10:23:54 +0000823extern Char* VG_(name_of_int_reg) ( Int size, Int reg );
824extern Char VG_(name_of_int_size) ( Int size );
njn25e49d8e72002-09-23 09:36:25 +0000825
njnac6c1762002-10-04 14:34:15 +0000826/* Shorter macros for convenience */
827#define nameIReg VG_(name_of_int_reg)
828#define nameISize VG_(name_of_int_size)
829#define nameSReg VG_(name_of_seg_reg)
830
njn25e49d8e72002-09-23 09:36:25 +0000831/* Randomly useful things */
832extern UInt VG_(extend_s_8to32) ( UInt x );
833
834/* Code emitters */
njn4ba5a792002-09-30 10:23:54 +0000835extern void VG_(emitB) ( UInt b );
836extern void VG_(emitW) ( UInt w );
837extern void VG_(emitL) ( UInt l );
838extern void VG_(new_emit) ( void );
njn25e49d8e72002-09-23 09:36:25 +0000839
840/* Finding offsets */
njn4ba5a792002-09-30 10:23:54 +0000841extern Int VG_(helper_offset) ( Addr a );
842extern Int VG_(shadow_reg_offset) ( Int arch );
843extern Int VG_(shadow_flags_offset) ( void );
njn25e49d8e72002-09-23 09:36:25 +0000844
njnd5bb0a52002-09-27 10:24:48 +0000845/* Convert reg ranks <-> Intel register ordering, for using register
846 liveness information. */
njn4ba5a792002-09-30 10:23:54 +0000847extern Int VG_(realreg_to_rank) ( Int realreg );
848extern Int VG_(rank_to_realreg) ( Int rank );
njn25e49d8e72002-09-23 09:36:25 +0000849
njnd5bb0a52002-09-27 10:24:48 +0000850/* Call a subroutine. Does no argument passing, stack manipulations, etc. */
njn4ba5a792002-09-30 10:23:54 +0000851extern void VG_(synth_call) ( Bool ensure_shortform, Int word_offset );
njn25e49d8e72002-09-23 09:36:25 +0000852
njnd5bb0a52002-09-27 10:24:48 +0000853/* For calling C functions -- saves caller save regs, pushes args, calls,
854 clears the stack, restores caller save regs. `fn' must be registered in
855 the baseBlock first. Acceptable tags are RealReg and Literal. Optimises
856 things, eg. by not preserving non-live caller-save registers.
njn25e49d8e72002-09-23 09:36:25 +0000857
njnd5bb0a52002-09-27 10:24:48 +0000858 WARNING: a UInstr should *not* be translated with synth_ccall() followed
859 by some other x86 assembly code; this will invalidate the results of
860 vg_realreg_liveness_analysis() and everything will fall over. */
njn4ba5a792002-09-30 10:23:54 +0000861extern void VG_(synth_ccall) ( Addr fn, Int argc, Int regparms_n, UInt argv[],
862 Tag tagv[], Int ret_reg,
863 RRegSet regs_live_before,
864 RRegSet regs_live_after );
njn25e49d8e72002-09-23 09:36:25 +0000865
866/* Addressing modes */
njn4ba5a792002-09-30 10:23:54 +0000867extern void VG_(emit_amode_offregmem_reg)( Int off, Int regmem, Int reg );
868extern void VG_(emit_amode_ereg_greg) ( Int e_reg, Int g_reg );
njn25e49d8e72002-09-23 09:36:25 +0000869
870/* v-size (4, or 2 with OSO) insn emitters */
njn4ba5a792002-09-30 10:23:54 +0000871extern void VG_(emit_movv_offregmem_reg) ( Int sz, Int off, Int areg, Int reg );
872extern void VG_(emit_movv_reg_offregmem) ( Int sz, Int reg, Int off, Int areg );
873extern void VG_(emit_movv_reg_reg) ( Int sz, Int reg1, Int reg2 );
874extern void VG_(emit_nonshiftopv_lit_reg)( Int sz, Opcode opc, UInt lit,
875 Int reg );
876extern void VG_(emit_shiftopv_lit_reg) ( Int sz, Opcode opc, UInt lit,
877 Int reg );
878extern void VG_(emit_nonshiftopv_reg_reg)( Int sz, Opcode opc,
879 Int reg1, Int reg2 );
880extern void VG_(emit_movv_lit_reg) ( Int sz, UInt lit, Int reg );
881extern void VG_(emit_unaryopv_reg) ( Int sz, Opcode opc, Int reg );
882extern void VG_(emit_pushv_reg) ( Int sz, Int reg );
883extern void VG_(emit_popv_reg) ( Int sz, Int reg );
njn25e49d8e72002-09-23 09:36:25 +0000884
njn4ba5a792002-09-30 10:23:54 +0000885extern void VG_(emit_pushl_lit32) ( UInt int32 );
886extern void VG_(emit_pushl_lit8) ( Int lit8 );
887extern void VG_(emit_cmpl_zero_reg) ( Int reg );
888extern void VG_(emit_swapl_reg_EAX) ( Int reg );
889extern void VG_(emit_movv_lit_offregmem) ( Int sz, UInt lit, Int off,
890 Int memreg );
njn25e49d8e72002-09-23 09:36:25 +0000891
892/* b-size (1 byte) instruction emitters */
njn4ba5a792002-09-30 10:23:54 +0000893extern void VG_(emit_movb_lit_offregmem) ( UInt lit, Int off, Int memreg );
894extern void VG_(emit_movb_reg_offregmem) ( Int reg, Int off, Int areg );
895extern void VG_(emit_unaryopb_reg) ( Opcode opc, Int reg );
896extern void VG_(emit_testb_lit_reg) ( UInt lit, Int reg );
njn25e49d8e72002-09-23 09:36:25 +0000897
898/* zero-extended load emitters */
njn4ba5a792002-09-30 10:23:54 +0000899extern void VG_(emit_movzbl_offregmem_reg) ( Int off, Int regmem, Int reg );
900extern void VG_(emit_movzwl_offregmem_reg) ( Int off, Int areg, Int reg );
njn25e49d8e72002-09-23 09:36:25 +0000901
902/* misc instruction emitters */
njn4ba5a792002-09-30 10:23:54 +0000903extern void VG_(emit_call_reg) ( Int reg );
904extern void VG_(emit_add_lit_to_esp) ( Int lit );
905extern void VG_(emit_jcondshort_delta) ( Condcode cond, Int delta );
906extern void VG_(emit_pushal) ( void );
907extern void VG_(emit_popal) ( void );
908extern void VG_(emit_AMD_prefetch_reg) ( Int reg );
njn25e49d8e72002-09-23 09:36:25 +0000909
910
911/*====================================================================*/
912/*=== Execution contexts ===*/
913/*====================================================================*/
914
915/* Generic resolution type used in a few different ways, such as deciding
916 how closely to compare two errors for equality. */
917typedef
918 enum { Vg_LowRes, Vg_MedRes, Vg_HighRes }
919 VgRes;
920
921typedef
922 struct _ExeContext
923 ExeContext;
924
njnd5bb0a52002-09-27 10:24:48 +0000925/* Compare two ExeContexts. Number of callers considered depends on `res':
926 Vg_LowRes: 2
927 Vg_MedRes: 4
928 Vg_HighRes: all */
njn25e49d8e72002-09-23 09:36:25 +0000929extern Bool VG_(eq_ExeContext) ( VgRes res,
930 ExeContext* e1, ExeContext* e2 );
931
932/* Print an ExeContext. */
933extern void VG_(pp_ExeContext) ( ExeContext* );
934
935/* Take a snapshot of the client's stack. Search our collection of
936 ExeContexts to see if we already have it, and if not, allocate a
937 new one. Either way, return a pointer to the context. */
938extern ExeContext* VG_(get_ExeContext) ( ThreadState *tst );
939
940
941/*====================================================================*/
942/*=== Error reporting ===*/
943/*====================================================================*/
944
945/* ------------------------------------------------------------------ */
946/* Suppressions describe errors which we want to suppress, ie, not
947 show the user, usually because it is caused by a problem in a library
948 which we can't fix, replace or work around. Suppressions are read from
njnd5bb0a52002-09-27 10:24:48 +0000949 a file at startup time. This gives flexibility so that new
njn25e49d8e72002-09-23 09:36:25 +0000950 suppressions can be added to the file as and when needed.
951*/
952
953typedef
954 Int /* Do not make this unsigned! */
955 SuppKind;
956
957/* An extensible (via the 'extra' field) suppression record. This holds
958 the suppression details of interest to a skin. Skins can use a normal
959 enum (with element values in the normal range (0..)) for `skind'.
960
961 If VG_(needs).report_errors==True, for each suppression read in by core
962 SKN_(recognised_suppression)() and SKN_(read_extra_suppression_info) will
963 be called. The `skind' field is filled in by the value returned in the
964 argument of the first function; the second function can fill in the
965 `string' and `extra' fields if it wants.
966*/
967typedef
968 struct {
969 /* What kind of suppression. Must use the range (0..) */
970 SuppKind skind;
971 /* String -- use is optional. NULL by default. */
972 Char* string;
973 /* Anything else -- use is optional. NULL by default. */
974 void* extra;
975 }
976 SkinSupp;
977
978
979/* ------------------------------------------------------------------ */
980/* Error records contain enough info to generate an error report. The idea
981 is that (typically) the same few points in the program generate thousands
njnd5bb0a52002-09-27 10:24:48 +0000982 of errors, and we don't want to spew out a fresh error message for each
983 one. Instead, we use these structures to common up duplicates.
njn25e49d8e72002-09-23 09:36:25 +0000984*/
985
986typedef
987 Int /* Do not make this unsigned! */
988 ErrorKind;
989
990/* An extensible (via the 'extra' field) error record. This holds
991 the error details of interest to a skin. Skins can use a normal
992 enum (with element values in the normal range (0..)) for `ekind'.
993
994 When errors are found and recorded with VG_(maybe_record_error)(), all
995 the skin must do is pass in the four parameters; core will
996 allocate/initialise the error record.
997*/
998typedef
999 struct {
1000 /* Used by ALL. Must be in the range (0..) */
1001 Int ekind;
1002 /* Used frequently */
1003 Addr addr;
1004 /* Used frequently */
1005 Char* string;
njnd5bb0a52002-09-27 10:24:48 +00001006 /* For any skin-specific extras */
njn25e49d8e72002-09-23 09:36:25 +00001007 void* extra;
1008 }
1009 SkinError;
1010
1011
1012/* ------------------------------------------------------------------ */
njnd5bb0a52002-09-27 10:24:48 +00001013/* Call this when an error occurs. It will be recorded if it hasn't been
njn25e49d8e72002-09-23 09:36:25 +00001014 seen before. If it has, the existing error record will have its count
1015 incremented.
1016
1017 If the error occurs in generated code, 'tst' should be NULL. If the
1018 error occurs in non-generated code, 'tst' should be non-NULL. The
1019 `extra' field can be stack-allocated; it will be copied (using
1020 SKN_(dup_extra_and_update)()) if needed. But it won't be copied
1021 if it's NULL.
njnd5bb0a52002-09-27 10:24:48 +00001022
1023 If no 'a', 's' or 'extra' of interest needs to be recorded, just use
1024 NULL for them.
njn25e49d8e72002-09-23 09:36:25 +00001025*/
1026extern void VG_(maybe_record_error) ( ThreadState* tst, ErrorKind ekind,
1027 Addr a, Char* s, void* extra );
1028
1029/* Gets a non-blank, non-comment line of at most nBuf chars from fd.
1030 Skips leading spaces on the line. Returns True if EOF was hit instead.
1031 Useful for reading in extra skin-specific suppression lines.
1032*/
njn4ba5a792002-09-30 10:23:54 +00001033extern Bool VG_(get_line) ( Int fd, Char* buf, Int nBuf );
njn25e49d8e72002-09-23 09:36:25 +00001034
1035
1036/*====================================================================*/
1037/*=== Obtaining debug information ===*/
1038/*====================================================================*/
1039
1040/* Get the file/function/line number of the instruction at address 'a'.
1041 For these four, if debug info for the address is found, it copies the
1042 info into the buffer/UInt and returns True. If not, it returns False and
1043 nothing is copied. VG_(get_fnname) always demangles C++ function names.
1044*/
1045extern Bool VG_(get_filename) ( Addr a, Char* filename, Int n_filename );
1046extern Bool VG_(get_fnname) ( Addr a, Char* fnname, Int n_fnname );
1047extern Bool VG_(get_linenum) ( Addr a, UInt* linenum );
1048
1049/* This one is more efficient if getting both filename and line number,
1050 because the two lookups are done together. */
1051extern Bool VG_(get_filename_linenum)
1052 ( Addr a, Char* filename, Int n_filename,
1053 UInt* linenum );
1054
1055/* Succeeds only if we find from debug info that 'a' is the address of the
1056 first instruction in a function -- as opposed to VG_(get_fnname) which
1057 succeeds if we find from debug info that 'a' is the address of any
1058 instruction in a function. Use this to instrument the start of
njnd5bb0a52002-09-27 10:24:48 +00001059 a particular function. Nb: if an executable/shared object is stripped
njn25e49d8e72002-09-23 09:36:25 +00001060 of its symbols, this function will not be able to recognise function
1061 entry points within it. */
1062extern Bool VG_(get_fnname_if_entry) ( Addr a, Char* filename, Int n_filename );
1063
1064/* Succeeds if the address is within a shared object or the main executable.
1065 It doesn't matter if debug info is present or not. */
1066extern Bool VG_(get_objname) ( Addr a, Char* objname, Int n_objname );
1067
1068
1069/*====================================================================*/
1070/*=== Shadow chunks and block-finding ===*/
1071/*====================================================================*/
1072
1073typedef
1074 enum {
1075 Vg_AllocMalloc = 0,
1076 Vg_AllocNew = 1,
1077 Vg_AllocNewVec = 2
1078 }
1079 VgAllocKind;
1080
1081/* Description of a malloc'd chunk. skin_extra[] part can be used by
1082 the skin; size of array is given by VG_(needs).sizeof_shadow_chunk. */
1083typedef
1084 struct _ShadowChunk {
1085 struct _ShadowChunk* next;
1086 UInt size : 30; /* size requested */
1087 VgAllocKind allockind : 2; /* which wrapper did the allocation */
1088 Addr data; /* ptr to actual block */
1089 UInt skin_extra[0]; /* extra skin-specific info */
1090 }
1091 ShadowChunk;
1092
1093/* Use this to free blocks if VG_(needs).alternative_free == True.
1094 It frees the ShadowChunk and the malloc'd block it points to. */
njn4ba5a792002-09-30 10:23:54 +00001095extern void VG_(free_ShadowChunk) ( ShadowChunk* sc );
njn25e49d8e72002-09-23 09:36:25 +00001096
1097/* Makes an array of pointers to all the shadow chunks of malloc'd blocks */
1098extern ShadowChunk** VG_(get_malloc_shadows) ( /*OUT*/ UInt* n_shadows );
1099
1100/* Determines if address 'a' is within the bounds of the block at start.
1101 Allows a little 'slop' round the edges. */
1102extern Bool VG_(addr_is_in_block) ( Addr a, Addr start, UInt size );
1103
1104/* Searches through currently malloc'd blocks until a matching one is found.
1105 Returns NULL if none match. Extra arguments can be implicitly passed to
njnd5bb0a52002-09-27 10:24:48 +00001106 p using nested functions; see memcheck/mc_errcontext.c for an example. */
njn25e49d8e72002-09-23 09:36:25 +00001107extern ShadowChunk* VG_(any_matching_mallocd_ShadowChunks)
1108 ( Bool (*p) ( ShadowChunk* ));
1109
1110/* Searches through all thread's stacks to see if any match. Returns
1111 * VG_INVALID_THREADID if none match. */
1112extern ThreadId VG_(any_matching_thread_stack)
1113 ( Bool (*p) ( Addr stack_min, Addr stack_max ));
1114
1115/*====================================================================*/
1116/*=== Skin-specific stuff ===*/
1117/*====================================================================*/
1118
njnd04b7c62002-10-03 14:05:52 +00001119/* ------------------------------------------------------------------ */
1120/* Details */
1121typedef
1122 struct {
1123 /* Information used in the startup message. `name' also determines the
1124 string used for identifying suppressions in a suppression file as
1125 belonging to this skin. `version' can be NULL, in which case (not
1126 surprisingly) no version info is printed; this mechanism is
1127 designed for skins distributed with Valgrind that share a version
1128 number with Valgrind. Other skins not distributed as part of
1129 Valgrind should probably have their own version number. */
1130 Char* name;
1131 Char* version;
1132 Char* description;
1133 Char* copyright_author;
1134
1135 /* String printed if an `sk_assert' assertion fails or VG_(skin_panic)
1136 is called. Should probably be an email address. */
1137 Char* bug_reports_to;
1138 }
1139 VgDetails;
1140
1141extern VgDetails VG_(details);
1142
1143/* ------------------------------------------------------------------ */
1144/* Needs */
1145
1146/* If new fields are added to this type, update:
njnd5bb0a52002-09-27 10:24:48 +00001147 * - vg_main.c:initialisation of VG_(needs)
njn25e49d8e72002-09-23 09:36:25 +00001148 * - vg_main.c:sanity_check_needs()
1149 *
1150 * If the name of this type or any of its fields change, update:
1151 * - dependent comments (just search for "VG_(needs)").
1152 */
1153typedef
1154 struct {
njnd5bb0a52002-09-27 10:24:48 +00001155 /* Booleans that decide core behaviour, but don't require extra
1156 operations to be defined if `True' */
1157
1158 /* Should __libc_freeres() be run? Bugs in it can crash the skin. */
njnd04b7c62002-10-03 14:05:52 +00001159 Bool libc_freeres;
njn25e49d8e72002-09-23 09:36:25 +00001160
1161 /* Want to have errors detected by Valgrind's core reported? Includes:
1162 - pthread API errors (many; eg. unlocking a non-locked mutex)
1163 - silly arguments to malloc() et al (eg. negative size)
1164 - invalid file descriptors to blocking syscalls read() and write()
1165 - bad signal numbers passed to sigaction()
1166 - attempt to install signal handler for SIGKILL or SIGSTOP */
1167 Bool core_errors;
njn25e49d8e72002-09-23 09:36:25 +00001168
1169 /* Booleans that indicate extra operations are defined; if these are
1170 True, the corresponding template functions (given below) must be
1171 defined. A lot like being a member of a type class. */
1172
njnd5bb0a52002-09-27 10:24:48 +00001173 /* Want to report errors from the skin? This implies use of
1174 suppressions, too. */
1175 Bool skin_errors;
1176
njn25e49d8e72002-09-23 09:36:25 +00001177 /* Is information kept about specific individual basic blocks? (Eg. for
njnd5bb0a52002-09-27 10:24:48 +00001178 cachegrind there are cost-centres for every instruction, stored at a
njn25e49d8e72002-09-23 09:36:25 +00001179 basic block level.) If so, it sometimes has to be discarded, because
1180 .so mmap/munmap-ping or self-modifying code (informed by the
1181 DISCARD_TRANSLATIONS user request) can cause one instruction address
njnd5bb0a52002-09-27 10:24:48 +00001182 to be used for more than one instruction in one program run... */
njn25e49d8e72002-09-23 09:36:25 +00001183 Bool basic_block_discards;
1184
njnd5bb0a52002-09-27 10:24:48 +00001185 /* Skin maintains information about each register? */
njn25e49d8e72002-09-23 09:36:25 +00001186 Bool shadow_regs;
1187
1188 /* Skin defines its own command line options? */
1189 Bool command_line_options;
1190 /* Skin defines its own client requests? */
1191 Bool client_requests;
1192
1193 /* Skin defines its own UInstrs? */
1194 Bool extended_UCode;
1195
1196 /* Skin does stuff before and/or after system calls? */
1197 Bool syscall_wrapper;
1198
1199 /* Size, in words, of extra info about malloc'd blocks recorded by
1200 skin. Be careful to get this right or you'll get seg faults! */
1201 UInt sizeof_shadow_block;
1202
1203 /* Skin does free()s itself? */
1204 Bool alternative_free;
1205
1206 /* Are skin-state sanity checks performed? */
1207 Bool sanity_checks;
1208 }
1209 VgNeeds;
1210
1211extern VgNeeds VG_(needs);
1212
1213
1214/* ------------------------------------------------------------------ */
1215/* Core events to track */
1216
1217/* Part of the core from which this call was made. Useful for determining
njnd5bb0a52002-09-27 10:24:48 +00001218 what kind of error message should be emitted. */
njn25e49d8e72002-09-23 09:36:25 +00001219typedef
1220 enum { Vg_CorePThread, Vg_CoreSignal, Vg_CoreSysCall, Vg_CoreTranslate }
1221 CorePart;
1222
1223/* Events happening in core to track. To be notified, assign a function
njnd5bb0a52002-09-27 10:24:48 +00001224 to the function pointer. To ignore an event, don't do anything
1225 (default assignment is to NULL in which case the call is skipped). */
njn25e49d8e72002-09-23 09:36:25 +00001226typedef
1227 struct {
1228 /* Memory events */
1229 void (*new_mem_startup)( Addr a, UInt len, Bool rr, Bool ww, Bool xx );
1230 void (*new_mem_heap) ( Addr a, UInt len, Bool is_inited );
1231 void (*new_mem_stack) ( Addr a, UInt len );
1232 void (*new_mem_stack_aligned) ( Addr a, UInt len );
1233 void (*new_mem_stack_signal) ( Addr a, UInt len );
1234 void (*new_mem_brk) ( Addr a, UInt len );
1235 void (*new_mem_mmap) ( Addr a, UInt len,
1236 Bool nn, Bool rr, Bool ww, Bool xx );
1237
1238 void (*copy_mem_heap) ( Addr from, Addr to, UInt len );
1239 void (*copy_mem_remap) ( Addr from, Addr to, UInt len );
1240 void (*change_mem_mprotect) ( Addr a, UInt len,
1241 Bool nn, Bool rr, Bool ww, Bool xx );
1242
njnd5bb0a52002-09-27 10:24:48 +00001243 /* Used on redzones around malloc'd blocks and at end of stack */
njn25e49d8e72002-09-23 09:36:25 +00001244 void (*ban_mem_heap) ( Addr a, UInt len );
1245 void (*ban_mem_stack) ( Addr a, UInt len );
1246
1247 void (*die_mem_heap) ( Addr a, UInt len );
1248 void (*die_mem_stack) ( Addr a, UInt len );
1249 void (*die_mem_stack_aligned) ( Addr a, UInt len );
1250 void (*die_mem_stack_signal) ( Addr a, UInt len );
1251 void (*die_mem_brk) ( Addr a, UInt len );
1252 void (*die_mem_munmap) ( Addr a, UInt len );
1253
1254 void (*bad_free) ( ThreadState* tst, Addr a );
1255 void (*mismatched_free) ( ThreadState* tst, Addr a );
1256
1257 void (*pre_mem_read) ( CorePart part, ThreadState* tst,
1258 Char* s, Addr a, UInt size );
1259 void (*pre_mem_read_asciiz) ( CorePart part, ThreadState* tst,
1260 Char* s, Addr a );
1261 void (*pre_mem_write) ( CorePart part, ThreadState* tst,
1262 Char* s, Addr a, UInt size );
1263 /* Not implemented yet -- have to add in lots of places, which is a
1264 pain. Won't bother unless/until there's a need. */
1265 /* void (*post_mem_read) ( ThreadState* tst, Char* s,
1266 Addr a, UInt size ); */
1267 void (*post_mem_write) ( Addr a, UInt size );
1268
1269
njnd5bb0a52002-09-27 10:24:48 +00001270 /* Scheduler events (not exhaustive) */
njn25e49d8e72002-09-23 09:36:25 +00001271 void (*thread_run) ( ThreadId tid );
1272
1273
njnd5bb0a52002-09-27 10:24:48 +00001274 /* Mutex events (not exhaustive) */
njn25e49d8e72002-09-23 09:36:25 +00001275 void (*post_mutex_lock) ( ThreadId tid,
1276 void* /*pthread_mutex_t* */ mutex );
1277 void (*post_mutex_unlock) ( ThreadId tid,
1278 void* /*pthread_mutex_t* */ mutex );
njn25e49d8e72002-09-23 09:36:25 +00001279
njnd5bb0a52002-09-27 10:24:48 +00001280
1281 /* Others... thread, condition variable, signal events... */
njn25e49d8e72002-09-23 09:36:25 +00001282 /* ... */
1283 }
1284 VgTrackEvents;
1285
1286/* Declare the struct instance */
1287extern VgTrackEvents VG_(track_events);
1288
1289
1290/* ------------------------------------------------------------------ */
1291/* Template functions */
1292
1293/* These are the parameterised functions in the core. The default definitions
njnd5bb0a52002-09-27 10:24:48 +00001294 are overridden by LD_PRELOADed skin version. At the very least, a skin
1295 must define the fundamental template functions. Depending on what needs
1296 are set, extra template functions will be used too. Functions are
1297 grouped under the needs that govern their use. */
njn25e49d8e72002-09-23 09:36:25 +00001298
1299
1300/* ------------------------------------------------------------------ */
1301/* Fundamental template functions */
1302
1303/* Initialise skin. Must do the following:
njnd04b7c62002-10-03 14:05:52 +00001304 - initialise the `details' struct
njn25e49d8e72002-09-23 09:36:25 +00001305 - register any helpers called by generated code
1306
1307 May do the following:
njnd04b7c62002-10-03 14:05:52 +00001308 - initialise the `needs' struct to indicate certain requirements
1309 - initialise the `track' struct to indicate core events of interest
njn25e49d8e72002-09-23 09:36:25 +00001310 - register any skin-specific profiling events
1311 - any other skin-specific initialisation
1312*/
njnd04b7c62002-10-03 14:05:52 +00001313extern void SK_(pre_clo_init) ( VgDetails* details, VgNeeds* needs,
1314 VgTrackEvents* track );
njn25e49d8e72002-09-23 09:36:25 +00001315
njnd5bb0a52002-09-27 10:24:48 +00001316/* Do initialisation that can only be done after command line processing. */
njn25e49d8e72002-09-23 09:36:25 +00001317extern void SK_(post_clo_init)( void );
1318
1319/* Instrument a basic block. Must be a true function, ie. the same input
1320 always results in the same output, because basic blocks can be
1321 retranslated. Unless you're doing something really strange...
1322 'orig_addr' is the address of the first instruction in the block. */
1323extern UCodeBlock* SK_(instrument) ( UCodeBlock* cb, Addr orig_addr );
1324
1325/* Finish up, print out any results, etc. */
1326extern void SK_(fini) ( void );
1327
1328
1329/* ------------------------------------------------------------------ */
1330/* VG_(needs).report_errors */
1331
1332/* Identify if two errors are equal, or equal enough. `res' indicates how
1333 close is "close enough". `res' should be passed on as necessary, eg. if
1334 the SkinError's extra field contains an ExeContext, `res' should be
1335 passed to VG_(eq_ExeContext)() if the ExeContexts are considered. Other
1336 than that, probably don't worry about it unless you have lots of very
1337 similar errors occurring.
1338 */
1339extern Bool SK_(eq_SkinError) ( VgRes res,
1340 SkinError* e1, SkinError* e2 );
1341
1342/* Print error context. The passed function pp_ExeContext() can be (and
1343 probably should be) used to print the location of the error. */
1344extern void SK_(pp_SkinError) ( SkinError* ec, void (*pp_ExeContext)(void) );
1345
1346/* Copy the ec->extra part and replace ec->extra with the new copy. This is
1347 necessary to move from a temporary stack copy to a permanent heap one.
1348
1349 Then fill in any details that could be postponed until after the decision
1350 whether to ignore the error (ie. details not affecting the result of
1351 SK_(eq_SkinError)()). This saves time when errors are ignored.
1352
1353 Yuk.
1354*/
1355extern void SK_(dup_extra_and_update)(SkinError* ec);
1356
1357/* Return value indicates recognition. If recognised, type goes in `skind'. */
1358extern Bool SK_(recognised_suppression) ( Char* name, SuppKind *skind );
1359
1360/* Read any extra info for this suppression kind. For filling up the
1361 `string' and `extra' fields in a `SkinSupp' struct if necessary. */
1362extern Bool SK_(read_extra_suppression_info) ( Int fd, Char* buf,
njnd5bb0a52002-09-27 10:24:48 +00001363 Int nBuf, SkinSupp *s );
njn25e49d8e72002-09-23 09:36:25 +00001364
1365/* This should just check the kinds match and maybe some stuff in the
1366 'extra' field if appropriate */
1367extern Bool SK_(error_matches_suppression)(SkinError* ec, SkinSupp* su);
1368
1369
1370/* ------------------------------------------------------------------ */
1371/* VG_(needs).basic_block_discards */
1372
njnd5bb0a52002-09-27 10:24:48 +00001373/* Should discard any information that pertains to specific basic blocks
1374 or instructions within the address range given. */
njn25e49d8e72002-09-23 09:36:25 +00001375extern void SK_(discard_basic_block_info) ( Addr a, UInt size );
1376
1377
1378/* ------------------------------------------------------------------ */
1379/* VG_(needs).shadow_regs */
1380
1381/* Valid values for general registers and EFLAGS register, for initialising
1382 and updating registers when written in certain places in core. */
1383extern void SK_(written_shadow_regs_values) ( UInt* gen_reg, UInt* eflags );
1384
1385
1386/* ------------------------------------------------------------------ */
1387/* VG_(needs).command_line_options */
1388
njnd5bb0a52002-09-27 10:24:48 +00001389/* Return True if option was recognised. Presumably sets some state to
1390 record the option as well. */
1391extern Bool SK_(process_cmd_line_option) ( Char* argv );
njn25e49d8e72002-09-23 09:36:25 +00001392
1393/* Print out command line usage for skin options */
1394extern Char* SK_(usage) ( void );
1395
1396
1397/* ------------------------------------------------------------------ */
1398/* VG_(needs).client_requests */
1399
1400extern UInt SK_(handle_client_request) ( ThreadState* tst, UInt* arg_block );
1401
1402
1403/* ------------------------------------------------------------------ */
1404/* VG_(needs).extends_UCode */
1405
njn4ba5a792002-09-30 10:23:54 +00001406/* Useful to use in VG_(get_Xreg_usage)() */
njnd5bb0a52002-09-27 10:24:48 +00001407#define VG_UINSTR_READS_REG(ono) \
njn25e49d8e72002-09-23 09:36:25 +00001408 { if (mycat(u->tag,ono) == tag) \
1409 { arr[n].num = mycat(u->val,ono); \
1410 arr[n].isWrite = False; \
1411 n++; \
1412 } \
1413 }
njnd5bb0a52002-09-27 10:24:48 +00001414#define VG_UINSTR_WRITES_REG(ono) \
1415 { if (mycat(u->tag,ono) == tag) \
1416 { arr[n].num = mycat(u->val,ono); \
1417 arr[n].isWrite = True; \
1418 n++; \
1419 } \
njn25e49d8e72002-09-23 09:36:25 +00001420 }
1421
njn4ba5a792002-09-30 10:23:54 +00001422/* 'X' prefix indicates eXtended UCode. */
1423extern Int SK_(get_Xreg_usage) ( UInstr* u, Tag tag, RegUse* arr );
1424extern void SK_(emit_XUInstr) ( UInstr* u, RRegSet regs_live_before );
1425extern Bool SK_(sane_XUInstr) ( Bool beforeRA, Bool beforeLiveness,
njn25e49d8e72002-09-23 09:36:25 +00001426 UInstr* u );
njn4ba5a792002-09-30 10:23:54 +00001427extern Char* SK_(name_XUOpcode) ( Opcode opc );
1428extern void SK_(pp_XUInstr) ( UInstr* u );
njn25e49d8e72002-09-23 09:36:25 +00001429
1430
1431/* ------------------------------------------------------------------ */
1432/* VG_(needs).syscall_wrapper */
1433
1434/* If either of the pre_ functions malloc() something to return, the
1435 * corresponding post_ function had better free() it!
1436 */
1437extern void* SK_( pre_syscall) ( ThreadId tid, UInt syscallno,
1438 Bool is_blocking );
1439extern void SK_(post_syscall) ( ThreadId tid, UInt syscallno,
1440 void* pre_result, Int res,
1441 Bool is_blocking );
1442
njnd5bb0a52002-09-27 10:24:48 +00001443
njn25e49d8e72002-09-23 09:36:25 +00001444/* ------------------------------------------------------------------ */
njnd5bb0a52002-09-27 10:24:48 +00001445/* VG_(needs).sizeof_shadow_chunk (if > 0) */
njn25e49d8e72002-09-23 09:36:25 +00001446
1447extern void SK_(complete_shadow_chunk) ( ShadowChunk* sc, ThreadState* tst );
1448
1449
1450/* ------------------------------------------------------------------ */
1451/* VG_(needs).alternative_free */
1452
1453extern void SK_(alt_free) ( ShadowChunk* sc, ThreadState* tst );
1454
njnd5bb0a52002-09-27 10:24:48 +00001455
njn25e49d8e72002-09-23 09:36:25 +00001456/* ---------------------------------------------------------------------
1457 VG_(needs).sanity_checks */
1458
njnd5bb0a52002-09-27 10:24:48 +00001459/* Can be useful for ensuring a skin's correctness. SK_(cheap_sanity_check)
1460 is called very frequently; SK_(expensive_sanity_check) is called less
1461 frequently and can be more involved. */
njn25e49d8e72002-09-23 09:36:25 +00001462extern Bool SK_(cheap_sanity_check) ( void );
1463extern Bool SK_(expensive_sanity_check) ( void );
1464
1465
1466#endif /* NDEF __VG_SKIN_H */
1467
1468/*--------------------------------------------------------------------*/
1469/*--- end vg_skin.h ---*/
1470/*--------------------------------------------------------------------*/
1471