1
2 /*--------------------------------------------------------------------*/
3 /*--- Types and macros for writing syscall wrappers. ---*/
4 /*--- priv_types_n_macros.h ---*/
5 /*--------------------------------------------------------------------*/
6
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
11 Copyright (C) 2000-2017 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 __PRIV_TYPES_N_MACROS_H
33 #define __PRIV_TYPES_N_MACROS_H
34
35 #include "pub_core_basics.h" // Addr
36
37 /* requires #include "pub_core_options.h" */
38 /* requires #include "pub_core_signals.h" */
39
40 /* This header defines types and macros which are useful for writing
41 syscall wrappers. It does not give prototypes for any such
42 headers, though: that is the job of the priv_syswrap-*.h headers.
43 This header gets included in any file which defines or declares
44 wrappers, and as such should only contain stuff which is relevant
45 to all such files.
46 */
47
48 /* ---------------------------------------------------------------------
49 Types that are used in syscall wrappers.
50 ------------------------------------------------------------------ */
51
52 /* Arguments for a syscall. */
53 typedef
54 struct SyscallArgs {
55 #if defined(VGO_dragonfly)
56 Word klass;
57 #endif
58 Word sysno;
59 RegWord arg1;
60 RegWord arg2;
61 RegWord arg3;
62 RegWord arg4;
63 RegWord arg5;
64 RegWord arg6;
65 RegWord arg7;
66 RegWord arg8;
67 }
68 SyscallArgs;
69
70 /* Current status of a syscall being done on behalf of the client. */
71 typedef
72 struct SyscallStatus {
73 enum {
74 /* call is complete, result is in 'res' */
75 SsComplete=1,
76 /* syscall not yet completed; must be handed to the kernel */
77 SsHandToKernel,
78 /* not currently handling a syscall for this thread */
79 SsIdle
80 } what;
81 SysRes sres; /* only meaningful for .what == SsComplete */
82 }
83 SyscallStatus;
84
85 /* Guest state layout info for syscall args. */
86 typedef
87 struct {
88 // Note that, depending on the platform, arguments may be found in
89 // registers or on the stack. (See the comment at the top of
90 // syswrap-main.c for per-platform details.) For register arguments
91 // (which have o_arg field names) the o_arg value is the offset into
92 // the vex register state. For stack arguments (which have s_arg
93 // field names), the s_arg value is the offset from the stack pointer.
94 Int o_sysno;
95 # if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
96 || defined(VGP_ppc32_linux) \
97 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
98 || defined(VGP_arm_linux) || defined(VGP_s390x_linux) \
99 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
100 Int o_arg1;
101 Int o_arg2;
102 Int o_arg3;
103 Int o_arg4;
104 Int o_arg5;
105 Int o_arg6;
106 Int uu_arg7;
107 Int uu_arg8;
108 # elif defined(VGP_x86_dragonfly)
109 Int s_arg1;
110 Int s_arg2;
111 Int s_arg3;
112 Int s_arg4;
113 Int s_arg5;
114 Int s_arg6;
115 Int s_arg7;
116 Int s_arg8;
117 # elif defined(VGP_amd64_dragonfly)
118 Int o_arg1;
119 Int o_arg2;
120 Int o_arg3;
121 Int o_arg4;
122 Int o_arg5;
123 Int o_arg6;
124 Int s_arg7;
125 Int s_arg8;
126 # elif defined(VGP_mips32_linux)
127 Int o_arg1;
128 Int o_arg2;
129 Int o_arg3;
130 Int o_arg4;
131 Int s_arg5;
132 Int s_arg6;
133 Int s_arg7;
134 Int uu_arg8;
135 # elif defined(VGP_x86_darwin) || defined(VGP_x86_solaris)
136 Int s_arg1;
137 Int s_arg2;
138 Int s_arg3;
139 Int s_arg4;
140 Int s_arg5;
141 Int s_arg6;
142 Int s_arg7;
143 Int s_arg8;
144 # elif defined(VGP_amd64_darwin) || defined(VGP_amd64_solaris)
145 Int o_arg1;
146 Int o_arg2;
147 Int o_arg3;
148 Int o_arg4;
149 Int o_arg5;
150 Int o_arg6;
151 Int s_arg7;
152 Int s_arg8;
153 # else
154 # error "Unknown platform"
155 # endif
156 }
157 SyscallArgLayout;
158
159 /* Flags describing syscall wrappers */
160 #define SfMayBlock (1 << 1) /* may block */
161 #define SfPostOnFail (1 << 2) /* call POST() function on failure */
162 #define SfPollAfter (1 << 3) /* poll for signals on completion */
163 #define SfYieldAfter (1 << 4) /* yield on completion */
164 #define SfNoWriteResult (1 << 5) /* don't write result to guest state */
165
166
167 /* ---------------------------------------------------------------------
168 The syscall table.
169 ------------------------------------------------------------------ */
170
171 typedef
172 struct {
173 void (*before) ( ThreadId,
174 SyscallArgLayout*,
175 /*MOD*/SyscallArgs*,
176 /*OUT*/SyscallStatus*,
177 /*OUT*/UWord*
178 );
179
180 void (*after) ( ThreadId,
181 SyscallArgs*,
182 SyscallStatus*
183 );
184 }
185 SyscallTableEntry;
186
187 /* Syscall table entries bind __NR_xxx syscall numbers to the PRE/POST
188 wrappers for the relevant syscall used in the OS kernel for that
189 number. Note that the constant names don't always match the
190 wrapper names in a straightforward way. For example, on x86/Linux:
191
192 __NR_lchown --> sys_lchown16()
193 __NR_lchown32 --> sys_lchown()
194 __NR_select --> old_select()
195 __NR__newselect --> sys_select()
196 */
197
198
199 /* A function to find the syscall table entry for a given sysno. If
200 none is found, return NULL. This used to be done with a single
201 fixed sized table exposed to the caller, but that's too inflexible;
202 hence now use a function which can do arbitrary messing around to
203 find the required entry. */
204
205 #if defined(VGO_linux)
206 extern
207 SyscallTableEntry* ML_(get_linux_syscall_entry)( UInt sysno );
208
209 #elif defined(VGO_darwin) || defined(VGO_dragonfly)
210 /* XXX: Darwin still uses the old scheme of exposing the table
211 array(s) and size(s) directly to syswrap-main.c. This should be
212 fixed. */
213
214 extern const SyscallTableEntry ML_(syscall_table)[];
215 extern const UInt ML_(syscall_table_size);
216
217 #elif defined(VGO_solaris)
218 extern
219 SyscallTableEntry* ML_(get_solaris_syscall_entry)( UInt sysno );
220
221 #else
222 # error Unknown OS
223 #endif
224
225 /* ---------------------------------------------------------------------
226 Declaring and defining wrappers.
227 ------------------------------------------------------------------ */
228
229 /* Templates for generating the PRE and POST macros -- that is, the
230 formal parameter lists for the definitions of wrapper functions.
231
232 Since these names exist in the global namespace, 'auxstr' should
233 give an auxiliary string, eg, "generic", "x86_linux", "linux", etc,
234 that ensures the names won't clash with other wrappers.
235
236 You should create corresponding global declarations using
237 DECL_TEMPLATE (indirectly) below.
238
239 Note. The silly name "arrghs" is used rather than just "args"
240 because a few wrappers declare the name "args" themselves, and
241 renaming those decls can change the name that comes out in error
242 messages (on scalar arg checks). Hence rename this instead.
243 */
244
245 #define DEFN_PRE_TEMPLATE(auxstr, name) \
246 void vgSysWrap_##auxstr##_##name##_before \
247 ( ThreadId tid, \
248 SyscallArgLayout* layout, \
249 /*MOD*/SyscallArgs* arrghs, \
250 /*OUT*/SyscallStatus* status, \
251 /*OUT*/UWord* flags \
252 )
253
254 #define DEFN_POST_TEMPLATE(auxstr, name) \
255 void vgSysWrap_##auxstr##_##name##_after \
256 ( ThreadId tid, \
257 SyscallArgs* arrghs, \
258 SyscallStatus* status \
259 )
260
261
262 /* This macro generates declarations (prototypes) for wrappers. It
263 declares both the pre-wrapper and the post-wrapper, even though the
264 post-wrapper may not actually exist.
265 */
266 #define DECL_TEMPLATE(auxstr, name) \
267 extern \
268 void vgSysWrap_##auxstr##_##name##_before \
269 ( ThreadId tid, \
270 SyscallArgLayout* layout, \
271 /*MOD*/SyscallArgs* arrghs, \
272 /*OUT*/SyscallStatus* status, \
273 /*OUT*/UWord* flags \
274 ); \
275 extern \
276 void vgSysWrap_##auxstr##_##name##_after \
277 ( ThreadId tid, \
278 SyscallArgs* arrghs, \
279 SyscallStatus* status \
280 );
281
282
283
284 /* Macros for conveniently generating entries in the syscall
285 tables. This first pair are not used directly. */
286
287 #define WRAPPER_ENTRY_X_(auxstr, sysno, name) \
288 [sysno] = { vgSysWrap_##auxstr##_##name##_before, NULL }
289 #define WRAPPER_ENTRY_XY(auxstr, sysno, name) \
290 [sysno] = { vgSysWrap_##auxstr##_##name##_before, \
291 vgSysWrap_##auxstr##_##name##_after }
292
293 #define WRAPPER_PRE_NAME(auxstr, name) \
294 vgSysWrap_##auxstr##_##name##_before
295 #define WRAPPER_POST_NAME(auxstr, name) \
296 vgSysWrap_##auxstr##_##name##_after
297
298 /* Add a generic wrapper to a syscall table. */
299 #if defined(VGO_linux) || defined(VGO_solaris)
300 # define GENX_(sysno, name) WRAPPER_ENTRY_X_(generic, sysno, name)
301 # define GENXY(sysno, name) WRAPPER_ENTRY_XY(generic, sysno, name)
302 #elif defined(VGO_dragonfly)
303 # define GENX_(sysno, name) WRAPPER_ENTRY_X_(generic, sysno, name)
304 # define GENXY(sysno, name) WRAPPER_ENTRY_XY(generic, sysno, name)
305 #elif defined(VGO_darwin)
306 # define GENX_(sysno, name) WRAPPER_ENTRY_X_(generic, VG_DARWIN_SYSNO_INDEX(sysno), name)
307 # define GENXY(sysno, name) WRAPPER_ENTRY_XY(generic, VG_DARWIN_SYSNO_INDEX(sysno), name)
308 #else
309 # error Unknown OS
310 #endif
311
312 /* Add a Linux-specific, arch-independent wrapper to a syscall
313 table. */
314 #define LINX_(sysno, name) WRAPPER_ENTRY_X_(linux, sysno, name)
315 #define LINXY(sysno, name) WRAPPER_ENTRY_XY(linux, sysno, name)
316
317 /* Add a Dragonfly-specific, arch-independent wrapper to a syscall
318 table. */
319 #define BSDX_(sysno, name) WRAPPER_ENTRY_X_(dragonfly, sysno, name)
320 #define BSDXY(sysno, name) WRAPPER_ENTRY_XY(dragonfly, sysno, name)
321
322
323 /* ---------------------------------------------------------------------
324 Macros useful for writing wrappers concisely. These refer to the
325 parameters declared by DEFN_{PRE,POST}_TEMPLATE and so in a way do
326 not help clarity of understanding. But they are just too useful to
327 omit.
328 ------------------------------------------------------------------ */
329
330 /* Reference to the syscall's arguments -- the ones which the
331 pre-wrapper may have modified, not the original copy. */
332 #define SYSNO (arrghs->sysno)
333 #define ARG1 (arrghs->arg1)
334 #define ARG2 (arrghs->arg2)
335 #define ARG3 (arrghs->arg3)
336 #define ARG4 (arrghs->arg4)
337 #define ARG5 (arrghs->arg5)
338 #define ARG6 (arrghs->arg6)
339 #define ARG7 (arrghs->arg7)
340 #define ARG8 (arrghs->arg8)
341
342 /* Provide signed versions of the argument values */
343 #define SARG1 ((Word)ARG1)
344 #define SARG2 ((Word)ARG2)
345 #define SARG3 ((Word)ARG3)
346 #define SARG4 ((Word)ARG4)
347 #define SARG5 ((Word)ARG5)
348 #define SARG6 ((Word)ARG6)
349 #define SARG7 ((Word)ARG7)
350 #define SARG8 ((Word)ARG8)
351
352 /* Reference to the syscall's current result status/value. General
353 paranoia all round. */
354 #define SUCCESS (status->what == SsComplete && !sr_isError(status->sres))
355 #define FAILURE (status->what == SsComplete && sr_isError(status->sres))
356 #define SWHAT (status->what)
357 #define RES (getRES(status))
358 #define RESHI (getRESHI(status))
359 #define ERR (getERR(status))
360
getRES(SyscallStatus * st)361 static inline UWord getRES ( SyscallStatus* st ) {
362 vg_assert(st->what == SsComplete);
363 vg_assert(!sr_isError(st->sres));
364 return sr_Res(st->sres);
365 }
366
367 #if defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_dragonfly)
getRESHI(SyscallStatus * st)368 static inline UWord getRESHI ( SyscallStatus* st ) {
369 vg_assert(st->what == SsComplete);
370 vg_assert(!sr_isError(st->sres));
371 return sr_ResHI(st->sres);
372 }
373 #endif
374
getERR(SyscallStatus * st)375 static inline UWord getERR ( SyscallStatus* st ) {
376 vg_assert(st->what == SsComplete);
377 vg_assert(sr_isError(st->sres));
378 return sr_Err(st->sres);
379 }
380
381
382 /* Set the current result status/value in various ways. */
383 #define SET_STATUS_Success(zzz) \
384 do { status->what = SsComplete; \
385 status->sres = VG_(mk_SysRes_Success)(zzz); \
386 } while (0)
387
388 #ifdef VGO_dragonfly
389 #define SET_STATUS_Success2(zzz, zzz2) \
390 do { status->what = SsComplete; \
391 status->sres = VG_(mk_SysRes_amd64_dragonfly)(zzz, zzz2, False); \
392 } while (0)
393 #endif
394
395 #define SET_STATUS_Failure(zzz) \
396 do { Word wzz = (Word)(zzz); \
397 /* Catch out wildly bogus error values. */ \
398 vg_assert(wzz >= 0 && wzz < 10000); \
399 status->what = SsComplete; \
400 status->sres = VG_(mk_SysRes_Error)(wzz); \
401 } while (0)
402
403 #define SET_STATUS_from_SysRes(zzz) \
404 do { \
405 status->what = SsComplete; \
406 status->sres = (zzz); \
407 } while (0)
408
409
410 #define PRINT(format, args...) \
411 if (VG_(clo_trace_syscalls)) \
412 VG_(printf)(format, ## args)
413
414 #define FUSE_COMPATIBLE_MAY_BLOCK() \
415 if (SimHintiS(SimHint_fuse_compatible, VG_(clo_sim_hints))) \
416 *flags |= SfMayBlock
417
418
419 /* Macros used to tell tools about uses of scalar arguments. Note,
420 these assume little-endianness. These can only be used in
421 pre-wrappers, and they refer to the layout parameter passed in. */
422 /* PRRSN == "pre-register-read-sysno"
423 PRRAn == "pre-register-read-argument"
424 PSRAn == "pre-stack-read-argument"
425 PRAn == "pre-read-argument"
426 */
427
428 #if defined(VGP_mips32_linux)
429 /* Up to 6 parameters, 4 in registers 2 on stack. */
430 # define PRA1(s,t,a) PRRAn(1,s,t,a)
431 # define PRA2(s,t,a) PRRAn(2,s,t,a)
432 # define PRA3(s,t,a) PRRAn(3,s,t,a)
433 # define PRA4(s,t,a) PRRAn(4,s,t,a)
434 # define PRA5(s,t,a) PSRAn(5,s,t,a)
435 # define PRA6(s,t,a) PSRAn(6,s,t,a)
436 # define PRA7(s,t,a) PSRAn(7,s,t,a)
437
438 #elif defined(VGO_linux) && !defined(VGP_mips32_linux)
439 /* Up to 6 parameters, all in registers. */
440 # define PRA1(s,t,a) PRRAn(1,s,t,a)
441 # define PRA2(s,t,a) PRRAn(2,s,t,a)
442 # define PRA3(s,t,a) PRRAn(3,s,t,a)
443 # define PRA4(s,t,a) PRRAn(4,s,t,a)
444 # define PRA5(s,t,a) PRRAn(5,s,t,a)
445 # define PRA6(s,t,a) PRRAn(6,s,t,a)
446
447 #elif defined(VGP_x86_dragonfly)
448 /* Up to 8 parameters, all on the stack. */
449 # define PRA1(s,t,a) PSRAn(1,s,t,a)
450 # define PRA2(s,t,a) PSRAn(2,s,t,a)
451 # define PRA3(s,t,a) PSRAn(3,s,t,a)
452 # define PRA4(s,t,a) PSRAn(4,s,t,a)
453 # define PRA5(s,t,a) PSRAn(5,s,t,a)
454 # define PRA6(s,t,a) PSRAn(6,s,t,a)
455 # define PRA7(s,t,a) PSRAn(7,s,t,a)
456 # define PRA8(s,t,a) PSRAn(8,s,t,a)
457
458 #elif defined(VGP_amd64_dragonfly)
459 /* Up to 8 parameters, 6 in registers, 2 on the stack. */
460 # define PRA1(s,t,a) PRRAn(1,s,t,a)
461 # define PRA2(s,t,a) PRRAn(2,s,t,a)
462 # define PRA3(s,t,a) PRRAn(3,s,t,a)
463 # define PRA4(s,t,a) PRRAn(4,s,t,a)
464 # define PRA5(s,t,a) PRRAn(5,s,t,a)
465 # define PRA6(s,t,a) PRRAn(6,s,t,a)
466 # define PRA7(s,t,a) PSRAn(7,s,t,a)
467 # define PRA8(s,t,a) PSRAn(8,s,t,a)
468
469 #elif defined(VGP_x86_darwin) || defined(VGP_x86_solaris)
470 /* Up to 8 parameters, all on the stack. */
471 # define PRA1(s,t,a) PSRAn(1,s,t,a)
472 # define PRA2(s,t,a) PSRAn(2,s,t,a)
473 # define PRA3(s,t,a) PSRAn(3,s,t,a)
474 # define PRA4(s,t,a) PSRAn(4,s,t,a)
475 # define PRA5(s,t,a) PSRAn(5,s,t,a)
476 # define PRA6(s,t,a) PSRAn(6,s,t,a)
477 # define PRA7(s,t,a) PSRAn(7,s,t,a)
478 # define PRA8(s,t,a) PSRAn(8,s,t,a)
479
480 #elif defined(VGP_amd64_darwin) || defined(VGP_amd64_solaris)
481 /* Up to 8 parameters, 6 in registers, 2 on the stack. */
482 # define PRA1(s,t,a) PRRAn(1,s,t,a)
483 # define PRA2(s,t,a) PRRAn(2,s,t,a)
484 # define PRA3(s,t,a) PRRAn(3,s,t,a)
485 # define PRA4(s,t,a) PRRAn(4,s,t,a)
486 # define PRA5(s,t,a) PRRAn(5,s,t,a)
487 # define PRA6(s,t,a) PRRAn(6,s,t,a)
488 # define PRA7(s,t,a) PSRAn(7,s,t,a)
489 # define PRA8(s,t,a) PSRAn(8,s,t,a)
490
491 #else
492 # error Unknown platform
493 #endif
494
495
496 /* Tell the tool that the syscall number is being read. */
497 #define PRRSN \
498 VG_(tdict).track_pre_reg_read(Vg_CoreSysCall, tid, "(syscallno)", \
499 layout->o_sysno, sizeof(RegWord));
500
501 /* REGISTER PARAMETERS */
502
503 /* PRRAn: Tell the tool that the register holding the n-th syscall
504 argument is being read, at type 't' which must be at most the size
505 of a register but can be smaller. In the latter case we need to be
506 careful about endianness. */
507
508 /* little-endian: the part of the guest state being read is
509 let here = offset_of_reg
510 in [here .. here + sizeof(t) - 1]
511 since the least significant parts of the guest register are stored
512 in memory at the lowest address.
513 */
514 #define PRRAn_LE(n,s,t,a) \
515 do { \
516 Int here = layout->o_arg##n; \
517 vg_assert(sizeof(t) <= sizeof(RegWord)); \
518 vg_assert(here >= 0); \
519 VG_(tdict).track_pre_reg_read( \
520 Vg_CoreSysCall, tid, s"("#a")", \
521 here, sizeof(t) \
522 ); \
523 } while (0)
524
525 /* big-endian: the part of the guest state being read is
526 let next = offset_of_reg + sizeof(reg)
527 in [next - sizeof(t) .. next - 1]
528 since the least significant parts of the guest register are stored
529 in memory at the highest address.
530 */
531 #define PRRAn_BE(n,s,t,a) \
532 do { \
533 Int here = layout->o_arg##n; \
534 Int next = layout->o_arg##n + sizeof(RegWord); \
535 vg_assert(sizeof(t) <= sizeof(RegWord)); \
536 vg_assert(here >= 0); \
537 VG_(tdict).track_pre_reg_read( \
538 Vg_CoreSysCall, tid, s"("#a")", \
539 next-sizeof(t), sizeof(t) \
540 ); \
541 } while (0)
542
543 #if defined(VG_BIGENDIAN)
544 # define PRRAn(n,s,t,a) PRRAn_BE(n,s,t,a)
545 #elif defined(VG_LITTLEENDIAN)
546 # define PRRAn(n,s,t,a) PRRAn_LE(n,s,t,a)
547 #else
548 # error "Unknown endianness"
549 #endif
550
551
552 /* STACK PARAMETERS */
553
554 /* PSRAn: Tell the tool that the memory holding the n-th syscall
555 argument is being read, at type 't' which must be at most the size
556 of a register but can be smaller. In the latter case we need to be
557 careful about endianness. */
558
559 /* little-endian: the part of the guest state being read is
560 let here = offset_of_reg
561 in [here .. here + sizeof(t) - 1]
562 since the least significant parts of the guest register are stored
563 in memory at the lowest address.
564 */
565 #define PSRAn_LE(n,s,t,a) \
566 do { \
567 Addr here = layout->s_arg##n + VG_(get_SP)(tid); \
568 vg_assert(sizeof(t) <= sizeof(RegWord)); \
569 VG_(tdict).track_pre_mem_read( \
570 Vg_CoreSysCallArgInMem, tid, s"("#a")", \
571 here, sizeof(t) \
572 ); \
573 } while (0)
574
575 /* big-endian: the part of the guest state being read is
576 let next = offset_of_reg + sizeof(reg)
577 in [next - sizeof(t) .. next - 1]
578 since the least significant parts of the guest register are stored
579 in memory at the highest address.
580 */
581 #if (defined(VGP_mips32_linux) && defined (_MIPSEB))
582 #define PSRAn_BE(n,s,t,a) \
583 do { \
584 Addr next = layout->s_arg##n + sizeof(RegWord) + \
585 VG_(get_SP)(tid); \
586 vg_assert(sizeof(t) <= sizeof(RegWord)); \
587 VG_(tdict).track_pre_mem_read( \
588 Vg_CoreSysCallArgInMem, tid, s"("#a")", \
589 next-sizeof(t), sizeof(t) \
590 ); \
591 } while (0)
592 #else
593 #define PSRAn_BE(n,s,t,a) \
594 do { \
595 Addr next = layout->o_arg##n + sizeof(RegWord) + \
596 VG_(threads)[tid].arch.vex.VG_STACK_PTR; \
597 vg_assert(sizeof(t) <= sizeof(RegWord)); \
598 VG_(tdict).track_pre_mem_read( \
599 Vg_CoreSysCallArgInMem, tid, s"("#a")", \
600 next-sizeof(t), sizeof(t) \
601 ); \
602 } while (0)
603 #endif
604
605 #if defined(VG_BIGENDIAN)
606 # define PSRAn(n,s,t,a) PSRAn_BE(n,s,t,a)
607 #elif defined(VG_LITTLEENDIAN)
608 # define PSRAn(n,s,t,a) PSRAn_LE(n,s,t,a)
609 #else
610 # error "Unknown endianness"
611 #endif
612
613
614 #define PRE_REG_READ0(tr, s) \
615 if (VG_(tdict).track_pre_reg_read) { \
616 PRRSN; \
617 }
618 #define PRE_REG_READ1(tr, s, t1, a1) \
619 if (VG_(tdict).track_pre_reg_read) { \
620 PRRSN; \
621 PRA1(s,t1,a1); \
622 }
623 #define PRE_REG_READ2(tr, s, t1, a1, t2, a2) \
624 if (VG_(tdict).track_pre_reg_read) { \
625 PRRSN; \
626 PRA1(s,t1,a1); PRA2(s,t2,a2); \
627 }
628 #define PRE_REG_READ3(tr, s, t1, a1, t2, a2, t3, a3) \
629 if (VG_(tdict).track_pre_reg_read) { \
630 PRRSN; \
631 PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \
632 }
633 #define PRE_REG_READ4(tr, s, t1, a1, t2, a2, t3, a3, t4, a4) \
634 if (VG_(tdict).track_pre_reg_read) { \
635 PRRSN; \
636 PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \
637 PRA4(s,t4,a4); \
638 }
639 #define PRE_REG_READ5(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5) \
640 if (VG_(tdict).track_pre_reg_read) { \
641 PRRSN; \
642 PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \
643 PRA4(s,t4,a4); PRA5(s,t5,a5); \
644 }
645 #define PRE_REG_READ6(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6) \
646 if (VG_(tdict).track_pre_reg_read) { \
647 PRRSN; \
648 PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \
649 PRA4(s,t4,a4); PRA5(s,t5,a5); PRA6(s,t6,a6); \
650 }
651 #define PRE_REG_READ7(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6, t7, a7) \
652 if (VG_(tdict).track_pre_reg_read) { \
653 PRRSN; \
654 PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \
655 PRA4(s,t4,a4); PRA5(s,t5,a5); PRA6(s,t6,a6); \
656 PRA7(s,t7,a7); \
657 }
658
659 #define PRE_REG_READ8(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6, t7, a7, t8, a8) \
660 if (VG_(tdict).track_pre_reg_read) { \
661 PRRSN; \
662 PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \
663 PRA4(s,t4,a4); PRA5(s,t5,a5); PRA6(s,t6,a6); \
664 PRA7(s,t7,a7); PRA8(s,t8,a8); \
665 }
666
667 #define PRE_MEM_READ(zzname, zzaddr, zzlen) \
668 VG_TRACK( pre_mem_read, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen)
669
670 #define PRE_MEM_RASCIIZ(zzname, zzaddr) \
671 VG_TRACK( pre_mem_read_asciiz, Vg_CoreSysCall, tid, zzname, zzaddr)
672
673 #define PRE_MEM_WRITE(zzname, zzaddr, zzlen) \
674 VG_TRACK( pre_mem_write, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen)
675
676 #define POST_MEM_WRITE(zzaddr, zzlen) \
677 VG_TRACK( post_mem_write, Vg_CoreSysCall, tid, zzaddr, zzlen)
678
679
680 #define PRE_FIELD_READ(zzname, zzfield) \
681 PRE_MEM_READ(zzname, (UWord)&zzfield, sizeof(zzfield))
682
683 #define PRE_FIELD_WRITE(zzname, zzfield) \
684 PRE_MEM_WRITE(zzname, (UWord)&zzfield, sizeof(zzfield))
685
686 #define POST_FIELD_WRITE(zzfield) \
687 POST_MEM_WRITE((UWord)&zzfield, sizeof(zzfield))
688
689 // Macros to support 64-bit syscall args split into two 32 bit values
690 #define LOHI64(lo,hi) ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
691 #if defined(VG_LITTLEENDIAN)
692 #define MERGE64(lo,hi) ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
693 #define MERGE64_FIRST(name) name##_low
694 #define MERGE64_SECOND(name) name##_high
695 #elif defined(VG_BIGENDIAN)
696 #define MERGE64(hi,lo) ( ((ULong)(lo)) | (((ULong)(hi)) << 32) )
697 #define MERGE64_FIRST(name) name##_high
698 #define MERGE64_SECOND(name) name##_low
699 #else
700 #error Unknown endianness
701 #endif
702
703 #endif // __PRIV_TYPES_N_MACROS_H
704
705 /*--------------------------------------------------------------------*/
706 /*--- end ---*/
707 /*--------------------------------------------------------------------*/
708