2 /*--------------------------------------------------------------------*/
3 /*--- Types and macros for writing syscall wrappers. ---*/
4 /*--- priv_types_n_macros.h ---*/
5 /*--------------------------------------------------------------------*/
8 This file is part of Valgrind, a dynamic binary instrumentation
11 Copyright (C) 2000-2010 Julian Seward
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.
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.
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
29 The GNU General Public License is contained in the file COPYING.
32 #ifndef __PRIV_TYPES_N_MACROS_H
33 #define __PRIV_TYPES_N_MACROS_H
35 /* requires #include "pub_core_options.h" */
36 /* requires #include "pub_core_signals.h" */
38 /* This header defines types and macros which are useful for writing
39 syscall wrappers. It does not give prototypes for any such
40 headers, though: that is the job of the priv_syswrap-*.h headers.
41 This header gets included in any file which defines or declares
42 wrappers, and as such should only contain stuff which is relevant
46 /* ---------------------------------------------------------------------
47 Types that are used in syscall wrappers.
48 ------------------------------------------------------------------ */
50 /* Arguments for a syscall. */
65 /* Current status of a syscall being done on behalf of the client. */
67 struct SyscallStatus {
69 /* call is complete, result is in 'res' */
71 /* syscall not yet completed; must be handed to the kernel */
73 /* not currently handling a syscall for this thread */
76 SysRes sres; /* only meaningful for .what == SsComplete */
80 /* Guest state layout info for syscall args. */
83 // Note that, depending on the platform, arguments may be found in
84 // registers or on the stack. (See the comment at the top of
85 // syswrap-main.c for per-platform details.) For register arguments
86 // (which have o_arg field names) the o_arg value is the offset into
87 // the vex register state. For stack arguments (which have s_arg
88 // field names), the s_arg value is the offset from the stack pointer.
90 # if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
91 || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
92 || defined(VGP_arm_linux) || defined(VGP_s390x_linux)
101 # elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
110 # elif defined(VGP_x86_darwin)
119 # elif defined(VGP_amd64_darwin)
128 # elif defined(VGP_x86_l4re)
139 # error "Unknown platform"
144 /* Flags describing syscall wrappers */
145 #define SfMayBlock (1 << 1) /* may block */
146 #define SfPostOnFail (1 << 2) /* call POST() function on failure */
147 #define SfPollAfter (1 << 3) /* poll for signals on completion */
148 #define SfYieldAfter (1 << 4) /* yield on completion */
149 #define SfNoWriteResult (1 << 5) /* don't write result to guest state */
152 /* ---------------------------------------------------------------------
154 ------------------------------------------------------------------ */
158 void (*before) ( ThreadId,
161 /*OUT*/SyscallStatus*,
165 void (*after) ( ThreadId,
172 /* Syscall table entries bind __NR_xxx syscall numbers to the PRE/POST
173 wrappers for the relevant syscall used in the OS kernel for that
174 number. Note that the constant names don't always match the
175 wrapper names in a straightforward way. For example, on x86/Linux:
177 __NR_lchown --> sys_lchown16()
178 __NR_lchown32 --> sys_lchown()
179 __NR_select --> old_select()
180 __NR__newselect --> sys_select()
184 /* A function to find the syscall table entry for a given sysno. If
185 none is found, return NULL. This used to be done with a single
186 fixed sized table exposed to the caller, but that's too inflexible;
187 hence now use a function which can do arbitrary messing around to
188 find the required entry. */
189 #if defined(VGO_linux)
191 SyscallTableEntry* ML_(get_linux_syscall_entry)( UInt sysno );
193 #elif defined(VGP_ppc32_aix5)
194 /* Same scheme on AIX5. This is more complex than the simple fixed
195 table lookup typical for Linux, since the syscalls don't have fixed
198 SyscallTableEntry* ML_(get_ppc32_aix5_syscall_entry) ( UInt sysno );
200 #elif defined(VGP_ppc64_aix5)
202 SyscallTableEntry* ML_(get_ppc64_aix5_syscall_entry) ( UInt sysno );
204 #elif defined(VGO_darwin)
205 /* XXX: Darwin still uses the old scheme of exposing the table
206 array(s) and size(s) directly to syswrap-main.c. This should be
209 extern const SyscallTableEntry ML_(syscall_table)[];
210 extern const UInt ML_(syscall_table_size);
212 #elif defined(VGO_l4re)
213 extern const SyscallTableEntry ML_(syscall_table)[];
214 extern const UInt ML_(syscall_table_size);
220 /* ---------------------------------------------------------------------
221 Declaring and defining wrappers.
222 ------------------------------------------------------------------ */
224 /* Templates for generating the PRE and POST macros -- that is, the
225 formal parameter lists for the definitions of wrapper functions.
227 Since these names exist in the global namespace, 'auxstr' should
228 give an auxiliary string, eg, "generic", "x86_linux", "linux", etc,
229 that ensures the names won't clash with other wrappers.
231 You should create corresponding global declarations using
232 DECL_TEMPLATE (indirectly) below.
234 Note. The silly name "arrghs" is used rather than just "args"
235 because a few wrappers declare the name "args" themselves, and
236 renaming those decls can change the name that comes out in error
237 messages (on scalar arg checks). Hence rename this instead.
240 #define DEFN_PRE_TEMPLATE(auxstr, name) \
241 void vgSysWrap_##auxstr##_##name##_before \
243 SyscallArgLayout* layout, \
244 /*MOD*/SyscallArgs* arrghs, \
245 /*OUT*/SyscallStatus* status, \
246 /*OUT*/UWord* flags \
249 #define DEFN_POST_TEMPLATE(auxstr, name) \
250 void vgSysWrap_##auxstr##_##name##_after \
252 SyscallArgs* arrghs, \
253 SyscallStatus* status \
257 /* This macro generates declarations (prototypes) for wrappers. It
258 declares both the pre-wrapper and the post-wrapper, even though the
259 post-wrapper may not actually exist.
261 #define DECL_TEMPLATE(auxstr, name) \
263 void vgSysWrap_##auxstr##_##name##_before \
265 SyscallArgLayout* layout, \
266 /*MOD*/SyscallArgs* arrghs, \
267 /*OUT*/SyscallStatus* status, \
268 /*OUT*/UWord* flags \
271 void vgSysWrap_##auxstr##_##name##_after \
273 SyscallArgs* arrghs, \
274 SyscallStatus* status \
279 /* Macros for conveniently generating entries in the syscall
280 tables. This first pair are not used directly. */
282 #define WRAPPER_ENTRY_X_(auxstr, sysno, name) \
283 [sysno] = { vgSysWrap_##auxstr##_##name##_before, NULL }
284 #define WRAPPER_ENTRY_XY(auxstr, sysno, name) \
285 [sysno] = { vgSysWrap_##auxstr##_##name##_before, \
286 vgSysWrap_##auxstr##_##name##_after }
288 #define WRAPPER_PRE_NAME(auxstr, name) \
289 vgSysWrap_##auxstr##_##name##_before
290 #define WRAPPER_POST_NAME(auxstr, name) \
291 vgSysWrap_##auxstr##_##name##_after
293 /* Add a generic wrapper to a syscall table. */
294 #if defined(VGO_linux) || defined(VGO_aix5) || defined(VGO_l4re)
295 # define GENX_(sysno, name) WRAPPER_ENTRY_X_(generic, sysno, name)
296 # define GENXY(sysno, name) WRAPPER_ENTRY_XY(generic, sysno, name)
297 #elif defined(VGO_darwin)
298 # define GENX_(sysno, name) WRAPPER_ENTRY_X_(generic, VG_DARWIN_SYSNO_INDEX(sysno), name)
299 # define GENXY(sysno, name) WRAPPER_ENTRY_XY(generic, VG_DARWIN_SYSNO_INDEX(sysno), name)
304 /* Add a Linux-specific, arch-independent wrapper to a syscall
306 #define LINX_(sysno, name) WRAPPER_ENTRY_X_(linux, sysno, name)
307 #define LINXY(sysno, name) WRAPPER_ENTRY_XY(linux, sysno, name)
309 /* Add an AIX5-specific, arch-independent wrapper to a syscall
311 #define AIXXY(sysno, name) \
313 { & WRAPPER_PRE_NAME(aix5, name), \
314 & WRAPPER_POST_NAME(aix5, name) }}
316 #define AIXX_(sysno, name) \
318 { & WRAPPER_PRE_NAME(aix5, name), \
322 /* ---------------------------------------------------------------------
323 Macros useful for writing wrappers concisely. These refer to the
324 parameters declared by DEFN_{PRE,POST}_TEMPLATE and so in a way do
325 not help clarity of understanding. But they are just too useful to
327 ------------------------------------------------------------------ */
329 /* Reference to the syscall's arguments -- the ones which the
330 pre-wrapper may have modified, not the original copy. */
331 #define SYSNO (arrghs->sysno)
332 #define ARG1 (arrghs->arg1)
333 #define ARG2 (arrghs->arg2)
334 #define ARG3 (arrghs->arg3)
335 #define ARG4 (arrghs->arg4)
336 #define ARG5 (arrghs->arg5)
337 #define ARG6 (arrghs->arg6)
338 #define ARG7 (arrghs->arg7)
339 #define ARG8 (arrghs->arg8)
341 /* Reference to the syscall's current result status/value. General
342 paranoia all round. */
343 #define SUCCESS (status->what == SsComplete && !sr_isError(status->sres))
344 #define FAILURE (status->what == SsComplete && sr_isError(status->sres))
345 #define SWHAT (status->what)
346 #define RES (getRES(status))
347 #define RESHI (getRESHI(status))
348 #define ERR (getERR(status))
350 static inline UWord getRES ( SyscallStatus* st ) {
351 vg_assert(st->what == SsComplete);
352 vg_assert(!sr_isError(st->sres));
353 return sr_Res(st->sres);
356 static inline UWord getRESHI ( SyscallStatus* st ) {
357 vg_assert(st->what == SsComplete);
358 vg_assert(!sr_isError(st->sres));
359 return sr_ResHI(st->sres);
362 static inline UWord getERR ( SyscallStatus* st ) {
363 vg_assert(st->what == SsComplete);
364 vg_assert(sr_isError(st->sres));
365 return sr_Err(st->sres);
369 /* Set the current result status/value in various ways. */
370 #define SET_STATUS_Success(zzz) \
371 do { status->what = SsComplete; \
372 status->sres = VG_(mk_SysRes_Success)(zzz); \
375 #define SET_STATUS_Failure(zzz) \
376 do { Word wzz = (Word)(zzz); \
377 /* Catch out wildly bogus error values. */ \
378 vg_assert(wzz >= 0 && wzz < 10000); \
379 status->what = SsComplete; \
380 status->sres = VG_(mk_SysRes_Error)(wzz); \
383 #define SET_STATUS_from_SysRes(zzz) \
385 status->what = SsComplete; \
386 status->sres = (zzz); \
390 #define PRINT(format, args...) \
391 if (VG_(clo_trace_syscalls)) \
392 VG_(printf)(format, ## args)
396 /* Macros used to tell tools about uses of scalar arguments. Note,
397 these assume little-endianness. These can only be used in
398 pre-wrappers, and they refer to the layout parameter passed in. */
399 /* PRRSN == "pre-register-read-sysno"
400 PRRAn == "pre-register-read-argument"
401 PSRAn == "pre-stack-read-argument"
402 PRAn == "pre-read-argument"
405 #if defined(VGO_linux) || defined(VGO_l4re)
406 /* Up to 6 parameters, all in registers. */
407 # define PRA1(s,t,a) PRRAn(1,s,t,a)
408 # define PRA2(s,t,a) PRRAn(2,s,t,a)
409 # define PRA3(s,t,a) PRRAn(3,s,t,a)
410 # define PRA4(s,t,a) PRRAn(4,s,t,a)
411 # define PRA5(s,t,a) PRRAn(5,s,t,a)
412 # define PRA6(s,t,a) PRRAn(6,s,t,a)
414 #elif defined(VGO_aix5)
415 # error Need to fill this in for AIX5
417 #elif defined(VGP_x86_darwin)
418 /* Up to 8 parameters, all on the stack. */
419 # define PRA1(s,t,a) PSRAn(1,s,t,a)
420 # define PRA2(s,t,a) PSRAn(2,s,t,a)
421 # define PRA3(s,t,a) PSRAn(3,s,t,a)
422 # define PRA4(s,t,a) PSRAn(4,s,t,a)
423 # define PRA5(s,t,a) PSRAn(5,s,t,a)
424 # define PRA6(s,t,a) PSRAn(6,s,t,a)
425 # define PRA7(s,t,a) PSRAn(7,s,t,a)
426 # define PRA8(s,t,a) PSRAn(8,s,t,a)
428 #elif defined(VGP_amd64_darwin)
429 /* Up to 8 parameters, 6 in registers, 2 on the 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) PRRAn(5,s,t,a)
435 # define PRA6(s,t,a) PRRAn(6,s,t,a)
436 # define PRA7(s,t,a) PSRAn(7,s,t,a)
437 # define PRA8(s,t,a) PSRAn(8,s,t,a)
440 # error Unknown platform
444 /* Tell the tool that the syscall number is being read. */
446 VG_(tdict).track_pre_reg_read(Vg_CoreSysCall, tid, "(syscallno)", \
447 layout->o_sysno, sizeof(UWord));
449 /* REGISTER PARAMETERS */
451 /* PRRAn: Tell the tool that the register holding the n-th syscall
452 argument is being read, at type 't' which must be at most the size
453 of a register but can be smaller. In the latter case we need to be
454 careful about endianness. */
456 /* little-endian: the part of the guest state being read is
457 let here = offset_of_reg
458 in [here .. here + sizeof(t) - 1]
459 since the least significant parts of the guest register are stored
460 in memory at the lowest address.
462 #define PRRAn_LE(n,s,t,a) \
464 Int here = layout->o_arg##n; \
465 vg_assert(sizeof(t) <= sizeof(UWord)); \
466 vg_assert(here >= 0); \
467 VG_(tdict).track_pre_reg_read( \
468 Vg_CoreSysCall, tid, s"("#a")", \
473 /* big-endian: the part of the guest state being read is
474 let next = offset_of_reg + sizeof(reg)
475 in [next - sizeof(t) .. next - 1]
476 since the least significant parts of the guest register are stored
477 in memory at the highest address.
479 #define PRRAn_BE(n,s,t,a) \
481 Int here = layout->o_arg##n; \
482 Int next = layout->o_arg##n + sizeof(UWord); \
483 vg_assert(sizeof(t) <= sizeof(UWord)); \
484 vg_assert(here >= 0); \
485 VG_(tdict).track_pre_reg_read( \
486 Vg_CoreSysCall, tid, s"("#a")", \
487 next-sizeof(t), sizeof(t) \
491 #if defined(VG_BIGENDIAN)
492 # define PRRAn(n,s,t,a) PRRAn_BE(n,s,t,a)
493 #elif defined(VG_LITTLEENDIAN)
494 # define PRRAn(n,s,t,a) PRRAn_LE(n,s,t,a)
496 # error "Unknown endianness"
500 /* STACK PARAMETERS */
502 /* PSRAn: Tell the tool that the memory holding the n-th syscall
503 argument is being read, at type 't' which must be at most the size
504 of a register but can be smaller. In the latter case we need to be
505 careful about endianness. */
507 /* little-endian: the part of the guest state being read is
508 let here = offset_of_reg
509 in [here .. here + sizeof(t) - 1]
510 since the least significant parts of the guest register are stored
511 in memory at the lowest address.
513 #define PSRAn_LE(n,s,t,a) \
515 Addr here = layout->s_arg##n + VG_(get_SP)(tid); \
516 vg_assert(sizeof(t) <= sizeof(UWord)); \
517 VG_(tdict).track_pre_mem_read( \
518 Vg_CoreSysCallArgInMem, tid, s"("#a")", \
523 /* big-endian: the part of the guest state being read is
524 let next = offset_of_reg + sizeof(reg)
525 in [next - sizeof(t) .. next - 1]
526 since the least significant parts of the guest register are stored
527 in memory at the highest address.
529 #define PSRAn_BE(n,s,t,a) \
531 Addr next = layout->o_arg##n + sizeof(UWord) + \
532 VG_(threads)[tid].arch.vex.VG_STACK_PTR; \
533 vg_assert(sizeof(t) <= sizeof(UWord)); \
534 VG_(tdict).track_pre_mem_read( \
535 Vg_CoreSysCallArgInMem, tid, s"("#a")", \
536 next-sizeof(t), sizeof(t) \
540 #if defined(VG_BIGENDIAN)
541 # define PSRAn(n,s,t,a) PSRAn_BE(n,s,t,a)
542 #elif defined(VG_LITTLEENDIAN)
543 # define PSRAn(n,s,t,a) PSRAn_LE(n,s,t,a)
545 # error "Unknown endianness"
549 #define PRE_REG_READ0(tr, s) \
550 if (VG_(tdict).track_pre_reg_read) { \
553 #define PRE_REG_READ1(tr, s, t1, a1) \
554 if (VG_(tdict).track_pre_reg_read) { \
558 #define PRE_REG_READ2(tr, s, t1, a1, t2, a2) \
559 if (VG_(tdict).track_pre_reg_read) { \
561 PRA1(s,t1,a1); PRA2(s,t2,a2); \
563 #define PRE_REG_READ3(tr, s, t1, a1, t2, a2, t3, a3) \
564 if (VG_(tdict).track_pre_reg_read) { \
566 PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \
568 #define PRE_REG_READ4(tr, s, t1, a1, t2, a2, t3, a3, t4, a4) \
569 if (VG_(tdict).track_pre_reg_read) { \
571 PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \
574 #define PRE_REG_READ5(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5) \
575 if (VG_(tdict).track_pre_reg_read) { \
577 PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \
578 PRA4(s,t4,a4); PRA5(s,t5,a5); \
580 #define PRE_REG_READ6(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6) \
581 if (VG_(tdict).track_pre_reg_read) { \
583 PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \
584 PRA4(s,t4,a4); PRA5(s,t5,a5); PRA6(s,t6,a6); \
586 #define PRE_REG_READ7(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6, t7, a7) \
587 if (VG_(tdict).track_pre_reg_read) { \
589 PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \
590 PRA4(s,t4,a4); PRA5(s,t5,a5); PRA6(s,t6,a6); \
594 #define PRE_REG_READ8(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6, t7, a7, t8, a8) \
595 if (VG_(tdict).track_pre_reg_read) { \
597 PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \
598 PRA4(s,t4,a4); PRA5(s,t5,a5); PRA6(s,t6,a6); \
599 PRA7(s,t7,a7); PRA8(s,t8,a8); \
602 #define PRE_MEM_READ(zzname, zzaddr, zzlen) \
603 VG_TRACK( pre_mem_read, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen)
605 #define PRE_MEM_RASCIIZ(zzname, zzaddr) \
606 VG_TRACK( pre_mem_read_asciiz, Vg_CoreSysCall, tid, zzname, zzaddr)
608 #define PRE_MEM_WRITE(zzname, zzaddr, zzlen) \
609 VG_TRACK( pre_mem_write, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen)
611 #define POST_MEM_WRITE(zzaddr, zzlen) \
612 VG_TRACK( post_mem_write, Vg_CoreSysCall, tid, zzaddr, zzlen)
615 #define PRE_FIELD_READ(zzname, zzfield) \
616 PRE_MEM_READ(zzname, (UWord)&zzfield, sizeof(zzfield))
618 #define PRE_FIELD_WRITE(zzname, zzfield) \
619 PRE_MEM_WRITE(zzname, (UWord)&zzfield, sizeof(zzfield))
621 #define POST_FIELD_WRITE(zzfield) \
622 POST_MEM_WRITE((UWord)&zzfield, sizeof(zzfield))
625 #endif // __PRIV_TYPES_N_MACROS_H
627 /*--------------------------------------------------------------------*/
629 /*--------------------------------------------------------------------*/