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