2 /*--------------------------------------------------------------------*/
3 /*--- AIX5-specific syscalls. syswrap-aix5.c ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2006-2010 OpenWorks LLP
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 The GNU General Public License is contained in the file COPYING.
30 Neither the names of the U.S. Department of Energy nor the
31 University of California nor the names of its contributors may be
32 used to endorse or promote products derived from this software
33 without prior written permission.
38 #include "pub_core_basics.h"
39 #include "pub_core_vki.h"
40 #include "pub_core_vkiscnums.h"
41 #include "pub_core_threadstate.h"
42 #include "pub_core_aspacemgr.h"
43 #include "pub_core_debuginfo.h" // VG_(di_notify_*)
44 #include "pub_core_transtab.h" // VG_(discard_translations)
45 #include "pub_core_xarray.h"
46 #include "pub_core_clientstate.h"
47 #include "pub_core_debuglog.h"
48 #include "pub_tool_gdbserver.h" // VG_(gdbserver)
49 #include "pub_core_libcbase.h"
50 #include "pub_core_libcassert.h"
51 #include "pub_core_libcfile.h"
52 #include "pub_core_libcprint.h"
53 #include "pub_core_libcproc.h"
54 #include "pub_core_libcsignal.h"
55 #include "pub_core_mallocfree.h"
56 #include "pub_core_tooliface.h"
57 #include "pub_core_options.h"
58 #include "pub_core_scheduler.h"
59 #include "pub_core_signals.h"
60 #include "pub_core_syscall.h"
61 #include "pub_core_sigframe.h" // VG_(sigframe_destroy)
62 #include "pub_core_syswrap.h"
63 #include "pub_core_stacktrace.h"
65 #include "priv_types_n_macros.h"
66 #include "priv_syswrap-aix5.h"
70 /* ---------------------------------------------------------------------
72 ------------------------------------------------------------------ */
74 /* Allocate a stack for this thread, if it doesn't already have one.
75 They're allocated lazily, and never freed. Returns the initial stack
76 pointer value to use, or 0 if allocation failed. */
77 Addr ML_(allocstack)(ThreadId tid)
79 ThreadState* tst = VG_(get_ThreadState)(tid);
83 /* Either the stack_base and stack_init_SP are both zero (in which
84 case a stack hasn't been allocated) or they are both non-zero,
85 in which case it has. */
87 if (tst->os_state.valgrind_stack_base == 0)
88 vg_assert(tst->os_state.valgrind_stack_init_SP == 0);
90 if (tst->os_state.valgrind_stack_base != 0)
91 vg_assert(tst->os_state.valgrind_stack_init_SP != 0);
93 /* If no stack is present, allocate one. */
94 if (tst->os_state.valgrind_stack_base == 0) {
95 stack = VG_(am_alloc_VgStack)( &initial_SP );
97 /* Leave some space above SP because AIX's ABI stores
100 vg_assert(initial_SP > (Addr)stack);
101 tst->os_state.valgrind_stack_base = (Addr)stack;
102 tst->os_state.valgrind_stack_init_SP = initial_SP;
104 return 0; /* allocation of stack failed */
109 VG_(printf)( "stack for tid %d at %p; init_SP=%p\n",
111 (void*)tst->os_state.valgrind_stack_base,
112 (void*)tst->os_state.valgrind_stack_init_SP );
114 return tst->os_state.valgrind_stack_init_SP;
118 /* If we know or believe a module load/unload event has happened, get
119 aspacem to re-read /proc/../map to update its picture of what text
120 and data segments are present. This also notifies all the usual
121 parties that need to know about address space changes. */
123 void ML_(aix5_rescan_procmap_after_load_or_unload) ( void )
125 AixCodeSegChange* changes;
126 Int changes_size, changes_used, i;
128 /* Find out how many AixCodeSegChange records we will need, and
130 changes_size = VG_(am_aix5_reread_procmap_howmany_directives)();
131 changes = VG_(arena_malloc)(VG_AR_CORE, "syswrap-aix5.arpalou.1",
132 changes_size * sizeof(AixCodeSegChange));
135 /* Now re-read /proc/<pid>/map and acquire a change set */
136 VG_(am_aix5_reread_procmap)( changes, &changes_used );
137 vg_assert(changes_used >= 0 && changes_used <= changes_size);
139 /* And notify all parties of the changes. */
140 for (i = 0; i < changes_used; i++) {
141 ULong di_handle = VG_(di_aix5_notify_segchange)(
142 changes[i].code_start,
144 changes[i].data_start,
146 changes[i].file_name,
148 changes[i].is_mainexe,
152 if (changes[i].acquire) {
153 VG_TRACK( new_mem_mmap,
154 changes[i].code_start, changes[i].code_len,
155 /*r*/True, /*w*/False, /*x*/True, di_handle );
156 VG_TRACK( new_mem_mmap,
157 changes[i].data_start, changes[i].data_len,
158 /*r*/True, /*w*/True, /*x*/False, 0/*or di_handle?*/ );
160 VG_TRACK( die_mem_munmap,
161 changes[i].code_start, changes[i].code_len );
162 VG_TRACK( die_mem_munmap,
163 changes[i].data_start, changes[i].data_len );
164 VG_(discard_translations)(
165 changes[i].code_start, changes[i].code_len,
166 "POST(sys___loadx/sys__kload)(code)" );
167 VG_(discard_translations)(
168 changes[i].data_start, changes[i].data_len,
169 "POST(sys___loadx/sys__kload)(data)" );
173 VG_(arena_free)(VG_AR_CORE, changes);
177 /* Mess with the given thread's pc/toc so that it is entering
178 pthread_exit() with argument PTHREAD_CANCELED. Returns True if ok,
179 False if it failed to do so, due to not being able to find
180 pthread_exit() by searching symbol tables. */
181 Bool ML_(aix5_force_thread_into_pthread_exit)( ThreadId tid )
183 Addr ent = 0, toc = 0;
185 ThreadState* tst = VG_(get_ThreadState)(tid);
186 found = VG_(lookup_symbol_SLOW)("libpthread*.a(*.o)", "pthread_exit",
190 VG_(printf)("THREAD CANCELED, new cia,toc = %#lx,%#lx\n", ent, toc);
191 tst->arch.vex.guest_CIA = ent;
192 tst->arch.vex.guest_GPR2 = toc;
193 tst->arch.vex.guest_GPR3 = (Word)(-1); /* == PTHREAD_CANCELED */
194 /* If the thread is blocked in a syscall, we better bop it on
195 the head with SIGVGKILL in order to get it out of said
197 if (tst->status == VgTs_WaitSys) {
198 if (VG_(clo_trace_syscalls))
199 VG_(printf)("(sending SIGVGKILL to tid %d)", (Int)tid);
200 VG_(get_thread_out_of_syscall)( tid );
202 return True; /* ok */
204 // urk. Now we're hosed. Let the caller figure out what to do.
205 return False; /* failed */
210 /* For various reasons, on AIX we may have to just give up if
211 continuing is too difficult (eg, risk of future deadlock). This
212 sets up the process state to exit straight away, but does not
213 actually itself exit. */
214 void ML_(aix5_set_threadstate_for_emergency_exit)(ThreadId tid, HChar* why)
216 ThreadState* tst = VG_(get_ThreadState)(tid);
217 /* Set the thread's status to be exiting and taking out the
218 entire process, then claim that the syscall succeeded. */
219 tst->exitreason = VgSrc_ExitProcess;
220 tst->os_state.exitcode = 1;
222 VG_(message)(Vg_UserMsg,
223 "WARNING: AIX: %s\n", why);
224 VG_(message)(Vg_UserMsg,
225 "WARNING: (too difficult to continue past this point).\n");
226 VG_(get_and_pp_StackTrace)(tid, 10);
231 /* Update aspacem etc on conclusion of a successful sbrk/__libc_sbrk
232 call. 2006-08-24: this was not completed because I don't
233 understand what sbrk/__libc_sbrk are doing. */
235 static void handle_sbrk ( Word delta )
240 /* Map in VG_(brk_limit) for delta */
241 /* using notify_mmap ? */
242 VG_(brk_limit) += delta;
245 Addr tmp = VG_(brk_limit);
246 VG_(brk_limit) += delta;
247 /* Can't move below original starting point */
248 if (VG_(brk_limit) < VG_(brk_base))
249 VG_(brk_limit) = VG_(brk_base);
250 if (VG_(brk_limit) < tmp)
251 /* Unmap VG_(brk_limit) for tmp - VG_(brk_limit) */
252 /* using notify_munmap ? */
255 if (VG_(clo_trace_syscalls))
256 VG_(printf)("new brk: 0x%010llx-0x%010llx (size %lld)\n",
257 (ULong)VG_(brk_base),
258 (ULong)VG_(brk_limit),
259 (ULong)VG_(brk_limit) - (ULong)VG_(brk_base));
263 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
264 #include <sys/thread.h>
265 #include <sys/poll.h>
266 #include <sys/times.h>
268 #include <semaphore.h>
269 #include <sys/statfs.h>
270 #include <sys/utsname.h>
271 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
273 HChar* ML_(aix5debugstuff_pc_to_fnname) ( Addr pc )
276 static HChar name[100];
277 ok = VG_(get_fnname_w_offset)(pc, name, 100);
278 if (!ok) VG_(strcpy)(name, "???");
282 static void aix5debugstuff_show_sigset ( vki_sigset_t* set )
285 UChar* p = (UChar*)set;
286 for (i = 0; i < sizeof(vki_sigset_t); i++)
287 VG_(printf)("%02x", (Int)p[i]);
290 static HChar* aix5debugstuff_name_of_tstate_flag ( UWord flag )
294 for (i = 0; i < 8*sizeof(UWord); i++)
295 if (flag & (1U << i))
297 vg_assert(nset == 1);
299 case TSTATE_LOCAL: return "LOCAL";
300 case TSTATE_CANCEL_DEFER: return "CANCEL_DEFER";
301 case TSTATE_CANCEL_DISABLE: return "CANCEL_DISABLE";
302 case TSTATE_CANCEL_PENDING: return "CANCEL_PENDING";
303 case TSTATE_CANCEL_CHKPT: return "CANCEL_CHKPT";
304 case TSTATE_INTR: return "INTR";
305 case TSTATE_EXEMPT: return "EXEMPT";
306 #ifdef TSTATE_PROFILING_OFF
307 case TSTATE_PROFILING_OFF: return "PROFILING_OFF";
309 case TSTATE_SUSPEND: return "SUSPEND";
310 case TSTATE_CONT: return "CONT";
312 case TSTATE_CREDS: return "CREDS";
314 #ifdef TSTATE_PROCHANDLERS
315 case TSTATE_PROCHANDLERS: return "PROCHANDLERS";
317 case TSTATE_ADVH: return "ADVH";
318 case TSTATE_SYNCH: return "SYNCH";
319 case TSTATE_USCHED: return "USCHED";
320 case TSTATE_DEFAULT_SCHED: return "DEFAULT_SCHED";
321 #ifdef TSTATE_INHERIT_SCHED
322 case TSTATE_INHERIT_SCHED: return "INHERIT_SCHED";
324 #ifdef TSTATE_LOCAL_INIT
325 case TSTATE_LOCAL_INIT: return "LOCAL_INIT";
327 #ifdef TSTATE_LOCAL_TERM
328 case TSTATE_LOCAL_TERM: return "LOCAL_TERM";
330 #ifdef TSTATE_LOCAL_MCHANGE
331 case TSTATE_LOCAL_MCHANGE: return "LOCAL_MCHANGE";
333 case TSTATE_CHANGE_ALL: return "CHANGE_ALL";
334 #ifdef TSTATE_CHANGE_PTID
335 case TSTATE_CHANGE_PTID: return "CHANGE_PTID";
337 #ifdef TSTATE_CHANGE_PROFILE
338 case TSTATE_CHANGE_PROFILE: return "CHANGE_PROFILE";
340 #ifdef TSTATE_CHANGE_SSTACK
341 case TSTATE_CHANGE_SSTACK: return "CHANGE_SSTACK";
343 case TSTATE_CHANGE_ERRNOP: return "CHANGE_ERRNOP";
344 case TSTATE_CHANGE_SIGMASK: return "CHANGE_SIGMASK";
345 case TSTATE_CHANGE_PSIG: return "CHANGE_PSIG";
346 case TSTATE_CHANGE_SCHED: return "CHANGE_SCHED";
347 case TSTATE_CHANGE_FLAGS: return "CHANGE_FLAGS";
348 case TSTATE_CHANGE_USERDATA: return "CHANGE_USERDATA";
349 default: return "???";
353 void ML_(aix5debugstuff_show_tstate_flags) ( UWord w )
359 for (i = 0; i < 8*sizeof(UWord); i++) {
365 VG_(printf)("%s ", aix5debugstuff_name_of_tstate_flag(w & m));
366 if ((j % step) == step-1 && j > 0)
370 if (((j-1) % step) != step-1 && j > 0)
374 void ML_(aix5debugstuff_show_tstate) ( Addr tsA, HChar* who )
377 const Int step = sizeof(void*)==8 ? 3 : 5;
378 struct tstate* ts = (struct tstate*)tsA;
379 VG_(printf)("\n{ ========= %s =========\n", who);
380 for (i = 0; i < _NGPRS; i++) {
382 VG_(printf)(" [%2d] ", i);
383 if (sizeof(void*)==8)
384 VG_(printf)("%016llx ", (ULong)ts->mst.gpr[i]);
386 VG_(printf)("%08llx ", (ULong)ts->mst.gpr[i]);
387 if ((i == _NGPRS-1) || ((i % step) == step-1 && i > 0))
390 VG_(printf)(" [iar] %#llx %s\n", (ULong)ts->mst.iar,
391 ML_(aix5debugstuff_pc_to_fnname)(ts->mst.iar));
393 VG_(printf)(" errnop_addr %p\n", ts->errnop_addr);
395 VG_(printf)(" sigmask ");
396 aix5debugstuff_show_sigset( (vki_sigset_t*)&ts->sigmask );
399 VG_(printf)(" psig ");
400 aix5debugstuff_show_sigset( (vki_sigset_t*)&ts->psig );
403 VG_(printf)(" policy %d\n", ts->policy);
404 VG_(printf)(" priority %d\n", ts->priority);
405 VG_(printf)(" flags 0x%x\n", ts->flags);
406 ML_(aix5debugstuff_show_tstate_flags)( (UWord)ts->flags );
407 VG_(printf)(" flagmask 0x%x\n", ts->flagmask);
408 VG_(printf)(" userdata %p\n", (void*)ts->userdata);
409 VG_(printf)(" fpinfo %d\n", ts->fpinfo);
410 VG_(printf)(" fpscrx %d\n", ts->fpscrx);
411 VG_(printf)(" sigaltstack ??\n");
412 VG_(printf)(" thread_control_p 0x%llx\n", (ULong)ts->thread_control_p);
413 // AIX 5.1 does not seem to have these members
414 // VG_(printf)(" prbase %p\n", (void*)ts->prbase);
415 // VG_(printf)(" credp %p\n", (void*)ts->credp);
416 // VG_(printf)(" ptid %d\n", (int)ts->ptid);
417 // VG_(printf)(" tct_clock %d\n", (int)ts->tct_clock);
418 UInt* p = (UInt*)tsA;
419 for (i = 0; i < sizeof(struct tstate)/sizeof(UInt); i++) {
420 HChar* s = ML_(aix5debugstuff_pc_to_fnname)( (Addr)p[i] );
421 if (0==VG_(strcmp)(s,"???"))
423 VG_(printf)(" [%d] %x %s\n", i, p[i], s);
428 /* ---------------------------------------------------------------------
429 PRE/POST wrappers for arch-generic, AIX5-specific syscalls. Note:
430 in fact AIX5 doesn't share any wrappers with Linux since it's
431 difficult to get syswrap-generic.c to compile on AIX. Hence in
432 fact this file also serves the role of syswrap-generic.c for AIX.
433 This could probably be improved at the cost of some extra effort.
434 ------------------------------------------------------------------ */
436 // Nb: See the comment above the generic PRE/POST wrappers in
437 // m_syswrap/syswrap-generic.c for notes about how they work.
439 #define PRE(name) DEFN_PRE_TEMPLATE(aix5, name)
440 #define POST(name) DEFN_POST_TEMPLATE(aix5, name)
443 // How to make __libc_sbrk appear to fail, from libc's point of view:
445 // r.res = -1; /* significant to libc */
446 // r.err = VKI_ENOMEM; /* not significant to libc */
447 // SET_STATUS_from_SysRes( r );
452 PRINT("__libc_sbrk (BOGUS HANDLER)( %#lx )",ARG1);
453 PRE_REG_READ1(long, "__libc_sbrk", long, arg1);
454 /* After a zero sbrk, disallow aspacem from doing sbrk, since libc
455 might rely on the value returned by this syscall. */
456 /* 1 Oct 06: not currently used (aspacemgr-aix5.c ignores it) */
457 VG_(am_aix5_sbrk_allowed) = toBool(ARG1 != 0);
458 /* Disallow libc from moving the brk backwards as that might trash
459 SkPreAlloc sections acquired by aspacem from previous uses of
463 /* Do this as a sync syscall, so the sbrk_allowed flag gets turned
464 back on ASAP. Typically libc does sbrk(0) and then sbrk(x > 0)
465 in quick succession. Although surely it should hold some kind
466 of lock at that point, else it cannot safely use the result from
467 the first sbrk call to influence the second one? */
468 *flags &= ~SfMayBlock;
470 POST(sys___libc_sbrk)
476 /* __loadx is handled in the platform-specific files. */
480 PRINT("__msleep (BOGUS HANDLER) ( %#lx )", ARG1);
481 PRE_REG_READ1(long, "msleep", void*, arg1);
484 /* __unload is handled in the platform-specific files. */
486 PRE(sys__clock_settime)
488 PRINT("_clock_settime (UNDOCUMENTED) ( %ld, %#lx )", ARG1, ARG2);
489 PRE_REG_READ2(int, "_clock_settime", int, arg1, int, arg2);
495 /* simple; just make this thread exit */
496 PRINT("_exit( %ld )", ARG1);
497 PRE_REG_READ1(void, "exit", int, exitcode);
499 tst = VG_(get_ThreadState)(tid);
500 /* Set the thread's status to be exiting and taking out the entire
501 process, then claim that the syscall succeeded. */
502 tst->exitreason = VgSrc_ExitProcess;
503 tst->os_state.exitcode = ARG1;
504 SET_STATUS_Success(0);
507 PRE(sys__fp_fpscrx_sc)
509 PRINT("_fp_fpscrx_sc (BOGUS HANDLER)");
514 PRINT("_getpgrp (BOGUS HANDLER)");
519 PRINT("_getpid ( )");
524 PRINT("_getppid ( )");
527 PRE(sys__getpriority)
529 PRINT("_getpriority (BOGUS HANDLER)");
534 *flags |= SfMayBlock;
535 PRINT("_nsleep( %#lx, %#lx )", ARG1, ARG2);
536 PRE_REG_READ2(void, "_nsleep", struct timestruc_t*, arg1,
537 struct timestruc_t*, arg2);
538 /* In 64-bit mode, struct ends in 4 padding bytes. Hence: */
540 PRE_MEM_READ("_nsleep(arg1)",
542 sizeof(void*)==4 ? sizeof(struct timestruc_t)
543 : sizeof(struct timestruc_t)-4 );
545 PRE_MEM_WRITE("_nsleep(arg2)", ARG2, sizeof(struct timestruc_t));
550 POST_MEM_WRITE(ARG2, sizeof(struct timestruc_t));
555 *flags |= SfMayBlock;
557 PRE_REG_READ0(long, "pause");
563 struct pollfd* ufds = (struct pollfd *)ARG1;
564 *flags |= SfMayBlock;
565 PRINT("_poll ( %#lx, %ld, %ld )\n", ARG1,ARG2,ARG3);
566 PRE_REG_READ3(long, "_poll",
567 struct pollfd *, ufds, unsigned int, nfds, long, timeout);
569 for (i = 0; i < ARG2; i++) {
570 PRE_MEM_READ( "poll(ufds.fd)",
571 (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
572 PRE_MEM_READ( "poll(ufds.events)",
573 (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
574 PRE_MEM_WRITE( "poll(ufds.reventss)",
575 (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
582 struct pollfd* ufds = (struct pollfd *)ARG1;
583 for (i = 0; i < ARG2; i++)
584 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
591 *flags |= SfMayBlock;
592 /* XXX: copy of generic; I don't know if this is right or not. */
593 PRINT("_select ( %ld, %#lx, %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4,ARG5);
594 PRE_REG_READ5(long, "_select",
595 int, n, struct sellist *, readfds,
596 struct sellist *, writefds,
597 struct sellist *, exceptfds,
598 struct timeval *, timeout);
599 nfds = ((UInt)ARG1) & 0xFFFF;
600 nmqids = (((UInt)ARG1) >> 16) & 0xFFFF;
602 // XXX: this possibly understates how much memory is read.
604 PRE_MEM_READ( "select(readfds)",
605 ARG2, nfds/8 /* __FD_SETSIZE/8 */ );
607 PRE_MEM_READ( "select(writefds)",
608 ARG3, nfds/8 /* __FD_SETSIZE/8 */ );
610 PRE_MEM_READ( "select(exceptfds)",
611 ARG4, nfds/8 /* __FD_SETSIZE/8 */ );
613 PRE_MEM_READ( "select(timeout)", ARG5,
614 /* in 64-bit mode, struct timeval has 4 bytes of
615 padding at the end, which tend to not be
617 sizeof(void*)==4 ? sizeof(struct timeval)
618 : sizeof(struct timeval)-4
624 *flags |= SfMayBlock;
625 PRINT("_sem_wait (BOGUS HANDLER) ( %#lx, %#lx, %ld )", ARG1, ARG2, ARG3);
626 PRE_REG_READ3(long, "_sem_wait", void*, arg1, void*, arg2, long, arg3 );
627 /* Not sure what the two pointer args are. Hence no proper handler.*/
632 PRINT("setpgid ( %ld, %ld )", ARG1, ARG2);
633 PRE_REG_READ2(int, "setpgid", int, pid, int, pgid);
641 PRE(sys__sigaction) /* COL, more or less */
643 PRINT("_sigaction ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
644 PRE_REG_READ3(long, "_sigaction",
645 int, signum, const struct sigaction *, act,
646 struct sigaction *, oldact);
649 struct vki_sigaction *sa = (struct vki_sigaction *)ARG2;
650 PRE_MEM_READ( "_sigaction(act->sa_handler)",
651 (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
652 PRE_MEM_READ( "_sigaction(act->sa_mask)",
653 (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
654 PRE_MEM_READ( "rt_sigaction(act->sa_flags)",
655 (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
658 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(struct vki_sigaction));
660 SET_STATUS_from_SysRes(
661 VG_(do_sys_sigaction)(ARG1, (const struct vki_sigaction *)ARG2,
662 (struct vki_sigaction *)ARG3)
668 if (RES == 0 && ARG3 != 0)
669 POST_MEM_WRITE( ARG3, sizeof(struct vki_sigaction));
672 PRE(sys__thread_self)
674 PRINT("_thread_self ( )");
677 PRE(sys__thread_setsched)
679 PRINT("_thread_setsched ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
680 PRE_REG_READ3(long, "_thread_setsched", long, arg1, long, arg2, long, arg3);
685 PRINT("access ( %#lx(%s), %ld )", ARG1,(Char*)ARG1, ARG2);
686 PRE_REG_READ2(int, "access", char*, pathname, int, mode);
687 PRE_MEM_RASCIIZ( "access(pathname)", ARG1 );
692 PRINT("accessx ( %#lx(%s), %ld, %ld )", ARG1,(Char*)ARG1, ARG2, ARG3);
693 PRE_REG_READ3(int, "accessx", char*, pathname, int, mode, int, who);
694 PRE_MEM_RASCIIZ( "accessx(pathname)", ARG1 );
697 PRE(sys_appgetrlimit)
699 /* Note: assumes kernel struct == libc struct */
700 PRINT("appgetrlimit ( %ld, %#lx )", ARG1, ARG2);
701 PRE_REG_READ2(int, "appgetrlimit", int, arg1, struct rlimit*, arg2);
702 PRE_MEM_WRITE( "appgetrlimit(buf)", ARG2, sizeof(struct rlimit) );
704 POST(sys_appgetrlimit)
706 POST_MEM_WRITE( ARG2, sizeof(struct rlimit) );
709 PRE(sys_appgetrusage)
711 /* Note: assumes kernel struct == libc struct */
712 PRINT("appgetrusage ( %ld, %#lx )", ARG1, ARG2);
713 PRE_REG_READ2(int, "appgetrusage", int, arg1, struct rusage*, arg2);
714 PRE_MEM_WRITE( "appgetrusage(buf)", ARG2, sizeof(struct rusage) );
716 POST(sys_appgetrusage)
718 POST_MEM_WRITE( ARG2, sizeof(struct rusage) );
723 PRINT("apprestimer (BOGUS HANDLER)");
726 PRE(sys_appsetrlimit)
728 PRINT("appsetrlimit (BOGUS HANDLER)");
733 PRINT("appulimit ( %ld, %ld )", ARG1, ARG2);
734 PRE_REG_READ2(long, "appulimit", long, arg1, long, arg2);
739 PRINT("bind ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
740 PRE_REG_READ3(int, "bind", int, socket,
741 void*, address, int, addresslen);
742 /* Hmm. This isn't really right - see pre_mem_read_sockaddr. */
743 PRE_MEM_READ( "bind(address)", ARG2, ARG3 );
748 PRINT("chdir ( %#lx(%s) )", ARG1,(Char*)ARG1);
749 PRE_REG_READ1(long, "chdir", const char *, path);
750 PRE_MEM_RASCIIZ( "chdir(path)", ARG1 );
755 PRINT("chmod ( %#lx(%s), 0x%lx )", ARG1,(Char*)ARG1, ARG2 );
756 PRE_REG_READ2(int, "chmod", char*, path, int, mode);
757 PRE_MEM_RASCIIZ( "chmod(path)", ARG1 );
762 PRINT("chown ( %#lx(%s), %ld, %ld )", ARG1,(Char*)ARG1, ARG2, ARG3 );
763 PRE_REG_READ3(int, "chown", char*, path, int, owner, int, group);
764 PRE_MEM_RASCIIZ( "chown(path)", ARG1 );
769 PRINT("close ( %ld )", ARG1);
770 PRE_REG_READ1(void, "close", UInt, fd);
771 /* If doing -d style logging (which is to fd=2), don't allow that
773 if (ARG1 == 2/*stderr*/ && VG_(debugLog_getLevel)() > 0)
774 SET_STATUS_Failure( VKI_EBADF );
779 /* apparently undocumented. I don't know what it does. */
780 /* Although /usr/include/net/proto_uipc.h does mention it.
781 Args are apparently (int, caddr_t, int). I suspect the
782 first arg is a fd and the third a flags value. */
783 PRINT("connext (UNDOCUMENTED)( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
784 PRE_REG_READ3(int, "connext", int, arg1, caddr_t*, arg2, int, arg3);
787 //--- PRE(sys_execve) ---//
788 // Pre_read a char** argument.
789 static void pre_argv_envp(Addr a, ThreadId tid, Char* s1, Char* s2)
793 Addr* a_p = (Addr*)a;
794 PRE_MEM_READ( s1, (Addr)a_p, sizeof(Addr) );
798 PRE_MEM_RASCIIZ( s2, a_deref );
802 static SysRes simple_pre_exec_check ( const HChar* exe_name,
803 Bool trace_this_child )
809 // Check it's readable
810 res = VG_(open)(exe_name, VKI_O_RDONLY, 0);
817 // Check we have execute permissions. We allow setuid executables
818 // to be run only in the case when we are not simulating them, that
819 // is, they to be run natively.
820 setuid_allowed = trace_this_child ? False : True;
821 ret = VG_(check_executable)(NULL/*&is_setuid*/,
822 (HChar*)exe_name, setuid_allowed);
824 return VG_(mk_SysRes_Error)(ret);
826 return VG_(mk_SysRes_Success)(0);
830 Char* path = NULL; /* path to executable */
834 Char* launcher_basename = NULL;
838 Bool trace_this_child;
840 PRINT("sys_execve ( %#lx(%s), %#lx, %#lx )", ARG1, (Char*)ARG1, ARG2, ARG3);
841 PRE_REG_READ3(vki_off_t, "execve",
842 char *, filename, char **, argv, char **, envp);
843 PRE_MEM_RASCIIZ( "execve(filename)", ARG1 );
845 pre_argv_envp( ARG2, tid, "execve(argv)", "execve(argv[i])" );
847 pre_argv_envp( ARG3, tid, "execve(envp)", "execve(envp[i])" );
849 vg_assert(VG_(is_valid_tid)(tid));
850 tst = VG_(get_ThreadState)(tid);
852 /* Erk. If the exec fails, then the following will have made a
853 mess of things which makes it hard for us to continue. The
854 right thing to do is piece everything together again in
855 POST(execve), but that's close to impossible. Instead, we make
856 an effort to check that the execve will work before actually
859 /* Check that the name at least begins in client-accessible storage. */
860 /* XXX: causes execve to fail for non-memcheck tools, presumably
861 because ARG1 is thought to not to being in client-accessible
862 storage due to inadequate address space tracking. May or may
863 not be due to non-tracking of brk. */
864 //if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
865 // SET_STATUS_Failure( VKI_EFAULT );
868 if (ARG1 == 0 /* obviously bogus */) {
869 SET_STATUS_Failure( VKI_EFAULT );
872 // Decide whether or not we want to follow along
873 trace_this_child = VG_(should_we_trace_this_child)( (HChar*)ARG1 );
875 // Do the important checks: it is a file, is executable, permissions are
877 res = simple_pre_exec_check( (const HChar*)ARG1, trace_this_child );
879 SET_STATUS_Failure( res.err );
883 /* If we're tracing the child, and the launcher name looks bogus
884 (possibly because launcher.c couldn't figure it out, see
885 comments therein) then we have no option but to fail. */
887 && (VG_(name_of_launcher) == NULL
888 || VG_(name_of_launcher)[0] != '/')) {
889 SET_STATUS_Failure( VKI_ECHILD ); /* "No child processes" */
893 /* After this point, we can't recover if the execve fails. */
894 VG_(debugLog)(1, "syswrap", "Exec of %s\n", (Char*)ARG1);
896 // Terminate gdbserver if it is active.
897 if (VG_(clo_vgdb) != Vg_VgdbNo) {
898 // If the child will not be traced, we need to terminate gdbserver
899 // to cleanup the gdbserver resources (e.g. the FIFO files).
900 // If child will be traced, we also terminate gdbserver: the new
901 // Valgrind will start a fresh gdbserver after exec.
905 /* Resistance is futile. Nuke all other threads. POSIX mandates
906 this. (Really, nuke them all, since the new process will make
907 its own new thread.) */
908 VG_(nuke_all_threads_except)( tid, VgSrc_ExitThread );
909 VG_(reap_threads)(tid);
911 // Set up the child's exe path.
913 if (trace_this_child) {
915 // We want to exec the launcher. Get its pre-remembered path.
916 path = VG_(name_of_launcher);
917 // VG_(name_of_launcher) should have been acquired by m_main at
921 launcher_basename = VG_(strrchr)(path, '/');
922 if (launcher_basename == NULL || launcher_basename[1] == 0) {
923 launcher_basename = path; // hmm, tres dubious
932 // Set up the child's environment.
934 // Remove the valgrind-specific stuff from the environment so the
935 // child doesn't get vgpreload_core.so, vgpreload_<tool>.so, etc.
936 // This is done unconditionally, since if we are tracing the child,
937 // the child valgrind will set up the appropriate client environment.
938 // Nb: we make a copy of the environment before trying to mangle it
939 // as it might be in read-only memory (this was bug #101881).
941 // Then, if tracing the child, set VALGRIND_LIB for it.
946 envp = VG_(env_clone)( (Char**)ARG3 );
947 if (envp == NULL) goto hosed;
948 VG_(env_remove_valgrind_env_stuff)( envp );
951 if (trace_this_child) {
952 // Set VALGRIND_LIB in ARG3 (the environment)
953 VG_(env_setenv)( &envp, VALGRIND_LIB, VG_(libdir));
956 // Set up the child's args. If not tracing it, they are
957 // simply ARG2. Otherwise, they are
959 // [launcher_basename] ++ VG_(args_for_valgrind) ++ [ARG1] ++ ARG2[1..]
961 // except that the first VG_(args_for_valgrind_noexecpass) args
964 if (!trace_this_child) {
967 vg_assert( VG_(args_for_valgrind_noexecpass) >= 0 );
968 vg_assert( VG_(args_for_valgrind_noexecpass)
969 <= VG_(sizeXA)( VG_(args_for_valgrind) ) );
970 /* how many args in total will there be? */
974 tot_args += VG_(sizeXA)( VG_(args_for_valgrind) );
975 tot_args -= VG_(args_for_valgrind_noexecpass);
976 // name of client exe
978 // args for client exe, skipping [0]
979 arg2copy = (Char**)ARG2;
980 if (arg2copy && arg2copy[0]) {
981 for (i = 1; arg2copy[i]; i++)
985 argv = VG_(malloc)( "syswrap-aix5.pre_sys_execve.1",
986 (tot_args+1) * sizeof(HChar*) );
987 if (argv == 0) goto hosed;
990 argv[j++] = launcher_basename;
991 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
992 if (i < VG_(args_for_valgrind_noexecpass))
994 argv[j++] = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
996 argv[j++] = (Char*)ARG1;
997 if (arg2copy && arg2copy[0])
998 for (i = 1; arg2copy[i]; i++)
999 argv[j++] = arg2copy[i];
1002 vg_assert(j == tot_args+1);
1005 /* restore the DATA rlimit for the child */
1006 VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
1009 Set the signal state up for exec.
1011 We need to set the real signal state to make sure the exec'd
1012 process gets SIG_IGN properly.
1014 Also set our real sigmask to match the client's sigmask so that
1015 the exec'd child will get the right mask. First we need to
1016 clear out any pending signals so they they don't get delivered,
1017 which would confuse things.
1019 XXX This is a bug - the signals should remain pending, and be
1020 delivered to the new process after exec. There's also a
1021 race-condition, since if someone delivers us a signal between
1022 the sigprocmask and the execve, we'll still get the signal. Oh
1026 vki_sigset_t allsigs;
1029 for (i = 1; i < VG_(max_signal); i++) {
1030 struct vki_sigaction sa;
1031 VG_(do_sys_sigaction)(i, NULL, &sa);
1032 if (sa.ksa_handler == VKI_SIG_IGN)
1033 VG_(sigaction)(i, &sa, NULL);
1035 sa.ksa_handler = VKI_SIG_DFL;
1036 VG_(sigaction)(i, &sa, NULL);
1040 VG_(sigfillset)(&allsigs);
1041 while(VG_(sigtimedwait_zero)(&allsigs, &info) > 0)
1044 VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
1049 VG_(printf)("exec: %s\n", path);
1050 for (cpp = argv; cpp && *cpp; cpp++)
1051 VG_(printf)("argv: %s\n", *cpp);
1053 for (cpp = envp; cpp && *cpp; cpp++)
1054 VG_(printf)("env: %s\n", *cpp);
1057 SET_STATUS_from_SysRes(
1058 VG_(do_syscall3)(__NR_execve, (UWord)path, (UWord)argv, (UWord)envp)
1061 /* If we got here, then the execve failed. We've already made way
1062 too much of a mess to continue, so we have to abort. */
1065 VG_(message)(Vg_UserMsg, "execve(%#lx(%s), %#lx, %#lx) failed, errno %ld\n",
1066 ARG1, (Char*)ARG1, ARG2, ARG3, ERR);
1067 VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from "
1068 "execve() failing, so I'm dying.\n");
1069 VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(sys_execve), "
1070 "or work out how to recover.\n");
1076 PRINT("finfo ( %#lx(%s), %ld, %#lx, %ld )",
1077 ARG1,(Char*)ARG1, ARG2, ARG3, ARG4);
1078 PRE_REG_READ4(int, "finfo",
1079 char*, Path1, int, cmd, void*, buffer, int, length);
1080 PRE_MEM_RASCIIZ( "finfo(Path1)", ARG1 );
1081 PRE_MEM_WRITE( "finfo(buffer)", ARG3, ARG4 );
1085 POST_MEM_WRITE( ARG3, ARG4 );
1090 PRINT("sys_fstatfs ( %ld, %#lx )", ARG1, ARG2);
1091 PRE_REG_READ2(UWord, "fstatfs", UWord, fd, struct statfs *, buf);
1092 PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct statfs) );
1096 POST_MEM_WRITE( ARG2, sizeof(struct statfs) );
1101 PRINT("fstatx ( %ld, %#lx, %ld, %ld )", ARG1, ARG2, ARG3, ARG4 );
1102 PRE_REG_READ4(Word, "fstatx", UWord, fd, void*, buf,
1103 UWord, len, UWord, cmd);
1104 PRE_MEM_WRITE( "fstatx(buf)", ARG2, ARG3 );
1108 POST_MEM_WRITE( ARG2, ARG3 );
1113 PRINT("fsync ( %ld )", ARG1);
1114 PRE_REG_READ1(int, "fsync", int, fd);
1119 *flags |= SfMayBlock;
1120 /* this is pretty much like 'read':
1121 getdirent(fd, buffer, nbytes) -> # actually read */
1122 PRINT("getdirent ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
1123 PRE_REG_READ3(Word, "getdirent", UWord, fd, UChar*, buf, UWord, count);
1124 PRE_MEM_WRITE( "getdirent(buf)", ARG2, ARG3 );
1129 POST_MEM_WRITE( ARG2, RES );
1132 PRE(sys_getdirent64)
1134 /* same as getdirent, from our point of view? */
1135 *flags |= SfMayBlock;
1136 /* this is pretty much like 'read':
1137 getdirent(fd, buffer, nbytes) -> # actually read */
1138 PRINT("getdirent64 ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
1139 PRE_REG_READ3(Word, "getdirent64", UWord, fd, UChar*, buf, UWord, count);
1140 PRE_MEM_WRITE( "getdirent64(buf)", ARG2, ARG3 );
1142 POST(sys_getdirent64)
1145 POST_MEM_WRITE( ARG2, RES );
1148 PRE(sys_getdomainname)
1150 PRINT("getdomainname ( %#lx, %ld )", ARG1, ARG2 );
1151 PRE_MEM_WRITE( "getdomainname(buf)", ARG1, ARG2 );
1153 POST(sys_getdomainname)
1155 POST_MEM_WRITE( ARG1, ARG2 );
1160 PRINT("getgidx ( %ld )", ARG1);
1161 PRE_REG_READ1(UInt, "getgidx", long, arg1);
1166 PRINT("getgroups ( %ld, %#lx )", ARG1, ARG2);
1167 PRE_REG_READ2(long, "getgroups", int, size, gid_t *, list);
1169 PRE_MEM_WRITE( "getgroups(list)", ARG2, ARG1 * sizeof(gid_t) );
1174 if (ARG1 > 0 && RES > 0)
1175 POST_MEM_WRITE( ARG2, RES * sizeof(gid_t) );
1178 PRE(sys_gethostname)
1180 PRINT("gethostname ( %#lx, %ld )", ARG1, ARG2);
1181 PRE_MEM_WRITE( "gethostname(buf)", ARG1, ARG2 );
1183 POST(sys_gethostname)
1185 POST_MEM_WRITE( ARG1, ARG2 );
1190 PRINT("getpriv (UNDOCUMENTED)(%ld, %#lx, %ld)", ARG1, ARG2, ARG3);
1191 PRE_REG_READ3(int, "getpriv", int, arg1, void*, arg2, int, arg3);
1192 PRE_MEM_WRITE( "getpriv(arg2)", ARG2, 8 );
1197 POST_MEM_WRITE(ARG2, 8);
1200 /* Note that this is used for both sys_getprocs and sys_getprocs64. I
1201 think that's correct - from the man page, the calling conventions
1205 PRINT("getprocs ( %#lx, %ld, %#lx, %ld, %#lx, %ld )",
1206 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
1207 PRE_REG_READ6(int, "getprocs",
1208 void*, processbuffer, long, processize,
1209 void*, filebuffer, long, filesize,
1210 void*, indexpointer, long, count);
1212 /* (processbuffer, processsize, filebuffer, filesize,
1213 indexpointer, count) */
1214 PRE_MEM_READ( "getprocs(IndexPointer)", ARG5, sizeof(UInt) );
1216 PRE_MEM_WRITE( "getprocs(ProcessBuffer)", ARG1, ARG2 * ARG6 );
1218 PRE_MEM_WRITE( "getprocs(FileBuffer)", ARG3, ARG4 * ARG6 );
1224 POST_MEM_WRITE( ARG1, ARG2 * ARG6 );
1226 POST_MEM_WRITE( ARG3, ARG4 * ARG6 );
1231 PRINT("getrpid ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
1232 PRE_REG_READ3(long, "getrpid", long, arg1, long, arg2, long, arg3);
1237 PRINT("getsockopt ( %ld, %ld, %ld, %#lx, %#lx )",
1238 ARG1, ARG2, ARG3, ARG4, ARG5);
1239 PRE_REG_READ5(int, "getsockopt", int, socket, int, level,
1241 void*, optionval, int*, optionlen);
1243 PRE_MEM_READ( "getsockopt(optionlen)", ARG5, sizeof(UInt) );
1244 PRE_MEM_WRITE( "getsockopt(optionval)", ARG4, *(UInt*)ARG5 );
1247 POST(sys_getsockopt)
1250 POST_MEM_WRITE( ARG5, sizeof(UInt) );
1251 POST_MEM_WRITE( ARG4, *(UInt*)ARG5 );
1257 PRINT("gettimerid ( %ld, %ld )", ARG1, ARG2);
1258 PRE_REG_READ2(int, "gettimerid", int, timertype, int, notifytype);
1263 PRINT("getuidx ( %ld )", ARG1);
1264 PRE_REG_READ1(UInt, "getuidx", UInt, arg1);
1267 PRE(sys_incinterval)
1269 PRINT("incinterval ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
1270 PRE_REG_READ3(int, "incinterval", int, timerid,
1271 struct itimerstruc_t*, value,
1272 struct itimerstruc_t*, ovalue);
1274 PRE_MEM_READ( "incinterval(value)",
1275 ARG2, sizeof(struct itimerstruc_t));
1277 PRE_MEM_WRITE( "incinterval(value)",
1278 ARG3, sizeof(struct itimerstruc_t));
1280 POST(sys_incinterval)
1283 POST_MEM_WRITE( ARG3, sizeof(struct itimerstruc_t));
1288 *flags |= SfMayBlock;
1290 // These ones ignore ARG3.
1294 PRINT("kfcntl ( %ld, %ld )", ARG1,ARG2);
1295 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
1298 // These ones use ARG3 as "arg".
1303 PRINT("kfcntl[ARG3=='arg'] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
1304 PRE_REG_READ3(long, "fcntl",
1305 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
1308 // These ones use ARG3 as "lock".
1309 # if !defined(VGP_ppc64_aix5)
1317 PRINT("kfcntl[ARG3=='lock'] ( %ld, %ld, %#lx )", ARG1,ARG2,ARG3);
1318 PRE_REG_READ3(long, "fcntl",
1319 unsigned int, fd, unsigned int, cmd,
1320 struct flock64 *, lock);
1321 if (ARG3 && (ARG2 == F_GETLK || ARG2 == F_GETLK64))
1322 PRE_MEM_READ( "kfcntl(F_GETLK)", ARG3, sizeof(struct flock64) );
1328 // if (ARG2 == VKI_F_DUPFD) {
1329 // if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
1331 // SET_STATUS_Failure( VKI_EMFILE );
1333 // if (VG_(clo_track_fds))
1334 // record_fd_open_named(tid, RES);
1337 if (ARG3 && (ARG2 == F_GETLK || ARG2 == F_GETLK64))
1338 POST_MEM_WRITE( ARG3, sizeof(struct flock64) );
1341 /* COG; can this be moved inside the pre-handler? */
1342 static vki_sigset_t fork_saved_mask;
1343 PRE(sys_kfork) /* COPY OF GENERIC */
1348 PRE_REG_READ0(long, "fork");
1350 /* Block all signals during fork, so that we can fix things up in
1351 the child without being interrupted. */
1352 VG_(sigfillset)(&mask);
1353 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
1355 VG_(do_atfork_pre)(tid);
1357 SET_STATUS_from_SysRes( VG_(do_syscall0)(__NR_fork) );
1359 if (SUCCESS && RES == 0) {
1361 VG_(do_atfork_child)(tid);
1363 /* restore signal mask */
1364 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
1366 /* If --child-silent-after-fork=yes was specified, set the
1367 logging file descriptor to an 'impossible' value. This is
1368 noticed by send_bytes_to_logging_sink in m_libcprint.c, which
1369 duly stops writing any further logging output. */
1370 if (!VG_(logging_to_socket) && VG_(clo_child_silent_after_fork))
1371 VG_(clo_log_fd) = -1;
1374 if (SUCCESS && RES > 0) {
1376 VG_(do_atfork_parent)(tid);
1378 PRINT(" fork: process %d created child %lu\n", VG_(getpid)(), RES);
1380 /* restore signal mask */
1381 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
1387 PRINT("kftruncate (BOGUS HANDLER)");
1392 PRINT("kgetsidx ( %ld )", ARG1);
1393 PRE_REG_READ1(Word, "kgetsidx", Word, arg1);
1398 PRINT("kill ( %ld, %ld )", ARG1, ARG2);
1399 PRE_REG_READ2(int, "kill", int, pid, int, signal);
1404 *flags |= SfMayBlock;
1405 PRINT("kioctl ( %ld, %#lx, %#lx, %#lx )", ARG1, ARG2, ARG3, ARG4);
1406 PRE_REG_READ4(Word, "ioctl", Word, fd,
1407 Word, command, Word, arg, Word, ext);
1408 switch (ARG2 /* request */) {
1409 case 0x5800/*TXISATTY*/:
1410 case 0x5801/*TXTTYNAME*/:
1412 case 0x412:/*no idea what any of these are*/
1429 case 0xFF01/*no_idea_at_all_what_this_is*/:
1431 /* We don't have any specific information on it, so
1432 try to do something reasonable based on direction and
1435 According to Simon Hausmann, _IOC_READ means the kernel
1436 writes a value to the ioctl value passed from the user
1437 space and the other way around with _IOC_WRITE. */
1439 UInt dir = _VKI_IOC_DIR(ARG2);
1440 UInt size = _VKI_IOC_SIZE(ARG2);
1441 if (VG_(strstr)(VG_(clo_sim_hints), "lax-ioctls") != NULL) {
1443 * Be very lax about ioctl handling; the only
1444 * assumption is that the size is correct. Doesn't
1445 * require the full buffer to be initialized when
1446 * writing. Without this, using some device
1447 * drivers with a large number of strange ioctl
1448 * commands becomes very tiresome.
1450 } else if (/* size == 0 || */ dir == _VKI_IOC_NONE) {
1451 static Int moans = 5;
1452 if (moans > 0 && !VG_(clo_xml)) {
1454 VG_(message)(Vg_UserMsg,
1455 "Warning: noted but unhandled ioctl 0x%lx"
1456 " with no size/direction hints\n",
1458 VG_(message)(Vg_UserMsg,
1459 " This could cause spurious value errors"
1461 VG_(message)(Vg_UserMsg,
1462 " See README_MISSING_SYSCALL_OR_IOCTL for "
1463 "guidance on writing a proper wrapper.\n" );
1466 if ((dir & _VKI_IOC_WRITE) && size > 0)
1467 PRE_MEM_READ( "ioctl(generic)", ARG3, size);
1468 if ((dir & _VKI_IOC_READ) && size > 0)
1469 PRE_MEM_WRITE( "ioctl(generic)", ARG3, size);
1477 switch (ARG2 /*request*/) {
1479 /* 100% kludge. I have no idea what this ioctl is. IOCINFO
1480 ? But at a guess I'd say it returns some kind of info
1482 if (ARG3) POST_MEM_WRITE(ARG3, 16);
1484 case 0x738: /* Shows up in MPI applications. */
1485 if (ARG3) POST_MEM_WRITE(ARG3, 4*sizeof(Word));
1487 case 0x736: /* Shows up in MPI applications. */
1488 case 0x73B: /* Shows up in MPI applications. */
1489 case 0x73C: /* Shows up in MPI applications. */
1490 if (ARG3) POST_MEM_WRITE(ARG3, 16);
1491 /* in fact only 4 needed, but being conservative */
1495 /* some kind of tty thing */
1496 if (ARG3) POST_MEM_WRITE(ARG3, 32);
1499 case 0x5801/*TXTTYNAME*/:
1500 /* who knows if this is right. Presumably an ascii string is
1501 written into the buffer specified by ARG3, but how long is
1503 if (ARG3) POST_MEM_WRITE(ARG3, 16);
1517 case 0x5800/*TXISATTY*/:
1520 /* We don't have any specific information on it, so
1521 try to do something reasonable based on direction and
1524 According to Simon Hausmann, _IOC_READ means the kernel
1525 writes a value to the ioctl value passed from the user
1526 space and the other way around with _IOC_WRITE. */
1528 UInt dir = _VKI_IOC_DIR(ARG2);
1529 UInt size = _VKI_IOC_SIZE(ARG2);
1530 if (size > 0 && (dir & _VKI_IOC_READ)
1532 && ARG3 != (Addr)NULL)
1533 POST_MEM_WRITE(ARG3, size);
1541 PRINT("klseek ( %ld, %ld, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4);
1542 PRE_REG_READ4(long, "klseek",
1543 long, fd, long, offset, long, whence, void*, arg4);
1544 /* XXX: looks like 4th arg is a pointer to something. Is it
1545 read or written by the kernel? */
1550 PRINT("knlist (BOGUS HANDLER)");
1555 *flags |= SfMayBlock;
1556 PRINT("sys_kpread ( %ld, %#lx, %llu, %lld )",
1557 ARG1, ARG2, (ULong)ARG3, (ULong)ARG4);
1558 PRE_REG_READ4(ssize_t, "kpread",
1559 unsigned int, fd, char *, buf,
1560 vki_size_t, count, long, offset);
1561 PRE_MEM_WRITE( "kpread(buf)", ARG2, ARG3 );
1567 POST_MEM_WRITE( ARG2, RES );
1573 *flags |= SfMayBlock;
1574 PRINT("sys_read ( %ld, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
1575 PRE_REG_READ3(ssize_t, "read",
1576 unsigned int, fd, char *, buf, vki_size_t, count);
1577 //zz if (!ML_(fd_allowed)(ARG1, "read", tid, False))
1578 //zz SET_STATUS_Failure( VKI_EBADF );
1580 PRE_MEM_WRITE( "read(buf)", ARG2, ARG3 );
1585 POST_MEM_WRITE( ARG2, RES );
1591 struct vki_iovec * vec;
1592 *flags |= SfMayBlock;
1593 /* ssize_t readvx ( int fd, struct iovec*, int iovCount, int extension ) */
1594 PRINT("kreadv ( %ld, %#lx, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4);
1595 PRE_REG_READ4(ssize_t, "kreadv",
1596 unsigned long, fd, const struct iovec *, vector,
1597 unsigned long, iovCount, unsigned long, extension);
1598 //zz if (!ML_(fd_allowed)(ARG1, "readv", tid, False)) {
1599 //zz SET_STATUS_Failure( VKI_EBADF );
1601 PRE_MEM_READ( "kreadv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
1603 /* ToDo: don't do any of the following if the vector is invalid */
1604 vec = (struct vki_iovec *)ARG2;
1605 for (i = 0; i < (Int)ARG3; i++)
1606 PRE_MEM_WRITE( "kreadv(vector[...])",
1607 (Addr)vec[i].iov_base, vec[i].iov_len );
1616 struct vki_iovec * vec = (struct vki_iovec *)ARG2;
1619 /* RES holds the number of bytes read. */
1620 for (i = 0; i < (Int)ARG3; i++) {
1621 Int nReadThisBuf = vec[i].iov_len;
1622 if (nReadThisBuf > remains) nReadThisBuf = remains;
1623 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
1624 remains -= nReadThisBuf;
1625 if (remains < 0) VG_(core_panic)("readv: remains < 0");
1630 PRE(sys_kthread_ctl)
1632 *flags |= SfMayBlock;
1633 PRINT("kthread_ctl (BOGUS HANDLER)");
1638 PRINT("ktruncate( %#lx(%s), %lx, %lx )", ARG1,(Char*)ARG1, ARG2, ARG3 );
1639 PRE_REG_READ3(int, "ktruncate", char*, path, long, arg2, long, arg3 );
1640 PRE_MEM_RASCIIZ( "ktruncate(path)", ARG1 );
1645 /* Note: args 1 and 2 (status, pid) opposite way round
1646 from generic handler */
1647 *flags |= SfMayBlock;
1648 PRINT("kwaitpid ( %#lx, %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4,ARG5);
1649 PRE_REG_READ3(long, "waitpid",
1650 unsigned int *, status, int, pid, int, options);
1652 if (ARG1 != (Addr)NULL)
1653 PRE_MEM_WRITE( "kwaitpid(status)", ARG1, sizeof(int) );
1657 if (ARG1 != (Addr)NULL)
1658 POST_MEM_WRITE( ARG1, sizeof(int) );
1664 *flags |= SfMayBlock;
1665 PRINT("sys_kwrite ( %ld, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
1666 PRE_REG_READ3(ssize_t, "kwrite",
1667 unsigned int, fd, const char *, buf, vki_size_t, count);
1668 /* check to see if it is allowed. If not, try for an exemption from
1669 --sim-hints=enable-outer (used for self hosting). */
1670 //zz ok = ML_(fd_allowed)(ARG1, "write", tid, False);
1671 //zz if (!ok && ARG1 == 2/*stderr*/
1672 //zz && VG_(strstr)(VG_(clo_sim_hints),"enable-outer"))
1675 //zz SET_STATUS_Failure( VKI_EBADF );
1677 PRE_MEM_READ( "write(buf)", ARG2, ARG3 );
1682 PRINT("kwritev (BOGUS HANDLER)");
1687 PRINT("listen (BOGUS HANDLER)");
1692 PRINT("loadbind( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
1693 PRE_REG_READ3(int, "loadbind", int, flag,
1694 void*, ExportPointer, void*, ImportPointer);
1699 /* loadquery ( int flags, void* buffer, unsigned int bufferlength ) */
1700 PRINT("loadquery ( %#lx, %#lx, %ld )", ARG1, ARG2, ARG3);
1701 PRE_MEM_WRITE( "loadquery(buf)", ARG2, ARG3 );
1706 POST_MEM_WRITE( ARG2, ARG3 );
1711 PRINT("lseek (%ld, %ld, %ld)", ARG1, ARG2, ARG3);
1712 PRE_REG_READ3(long, "lseek", long, fd, long, offset, long, whence);
1717 PRINT("mkdir (%#lx(%s), %#lx)", ARG1,(Char*)ARG1, ARG2);
1718 PRE_REG_READ2(int, "mkdir", char*, path, int, mode);
1719 PRE_MEM_RASCIIZ( "mkdir(path)", ARG1 );
1724 PRINT("mmap ( %#lx, %ld, %#lx, %#lx, %ld, %ld )",
1725 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1726 PRE_REG_READ6(void*, "mmap", void*, addr, int, len,
1727 int, prot, int, flags, int, fd, int, off);
1732 Addr addr = (Addr)RES;
1733 UWord len = (UWord)ARG2;
1734 UWord prot = (UWord)ARG3;
1735 UWord flags = (UWord)ARG4;
1736 Bool r = (prot & VKI_PROT_READ) > 0;
1737 Bool w = (prot & VKI_PROT_WRITE) > 0;
1738 Bool x = (prot & VKI_PROT_EXEC) > 0;
1739 VG_TRACK( new_mem_mmap, addr, len, r,w,x, 0/*di_handle*/ );
1740 Bool d = VG_(am_notify_client_mmap)( addr, len, prot, flags,
1741 0/*fake fd*/, 0/*fake offset*/);
1743 VG_(discard_translations)( addr, len, "POST(sys_mmap)" );
1748 PRINT("mntctl ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3 );
1749 PRE_REG_READ3(long, "mntctl", long, command, long, size, char*, buffer);
1750 PRE_MEM_WRITE( "mntctl(buffer)", ARG3, ARG2 );
1756 /* Buffer too small. First word is the real required size. */
1757 POST_MEM_WRITE( ARG3, sizeof(Word) );
1759 /* RES is the number of struct vmount's written to the buf. But
1760 these are variable length and to find the end would require
1761 inspecting each in turn. So be simple and just mark the
1762 entire buffer as defined. */
1763 POST_MEM_WRITE( ARG3, ARG2 );
1769 PRINT("mprotect (BOGUS HANDLER)( %#lx, %ld, %#lx )", ARG1, ARG2, ARG3);
1770 PRE_REG_READ3(int, "mprotect", void*, addr, long, len, long, prot);
1779 d = VG_(am_notify_mprotect)( addr, len, prot );
1781 VG_(discard_translations)( addr, len, "POST(sys_mprotect)" );
1786 PRINT("munmap ( %#lx, %ld )", ARG1, ARG2);
1787 PRE_REG_READ2(int, "munmap", void*, addr, long, len);
1795 VG_TRACK( die_mem_munmap, addr, len );
1796 d = VG_(am_notify_munmap)( addr, len );
1798 VG_(discard_translations)( addr, len, "POST(sys_munmap)" );
1803 PRINT("naccept (%ld, %#lx, %#lx)", ARG1, ARG2, ARG3);
1804 PRE_REG_READ3(int, "naccept", int, socket, char*, addr, int*, addrlen);
1805 PRE_MEM_READ( "naccept(addrlen)", ARG3, sizeof(UInt) );
1806 PRE_MEM_WRITE( "naccept(addr)", ARG2, *(UInt*)ARG3 );
1810 POST_MEM_WRITE( ARG3, sizeof(UInt) );
1811 POST_MEM_WRITE( ARG2, *(UInt*)ARG3 );
1814 PRE(sys_ngetpeername)
1816 PRINT("ngetpeername ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
1817 PRE_REG_READ3(int, "ngetpeername", int, fd, char*, name, int*, namelen);
1818 PRE_MEM_READ( "ngetpeername(namelen)", ARG3, sizeof(UInt) );
1819 PRE_MEM_WRITE( "ngetpeername(name)", ARG2, *(UInt*)ARG3 );
1821 POST(sys_ngetpeername)
1823 POST_MEM_WRITE( ARG3, sizeof(UInt) );
1824 POST_MEM_WRITE( ARG2, *(UInt*)ARG3 );
1827 PRE(sys_ngetsockname)
1829 PRINT("ngetsockname ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
1830 PRE_REG_READ3(int, "ngetsockname", int, fd, char*, name, int*, namelen);
1831 PRE_MEM_READ( "ngetsockname(namelen)", ARG3, sizeof(UInt) );
1832 PRE_MEM_WRITE( "ngetsockname(name)", ARG2, *(UInt*)ARG3 );
1834 POST(sys_ngetsockname)
1836 POST_MEM_WRITE( ARG3, sizeof(UInt) );
1837 POST_MEM_WRITE( ARG2, *(UInt*)ARG3 );
1842 *flags |= SfMayBlock;
1843 PRINT("nrecvfrom ( %ld, %#lx, %ld, %ld, %#lx, %#lx )",
1844 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
1845 PRE_REG_READ6(ssize_t, "nrecvfrom",
1846 int, s, void*, buf, size_t, len, int, flags,
1847 void*, from, UInt*, fromlen);
1848 PRE_MEM_WRITE( "nrecvfrom(buf)", ARG2, ARG3 );
1850 PRE_MEM_READ( "nrecvfrom(fromlen)", ARG6, sizeof(UInt) );
1851 PRE_MEM_WRITE( "nrecvfrom(from)", ARG5, *(UInt*)ARG6 );
1856 POST_MEM_WRITE( ARG2, RES );
1858 POST_MEM_WRITE(ARG6, sizeof(UInt));
1859 POST_MEM_WRITE(ARG5, *(UInt*)ARG6);
1865 *flags |= SfMayBlock;
1866 PRINT("nrecvmsg(BOGUS HANDLER)( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
1867 PRE_REG_READ3(long, "nrecvmsg", long, arg1, void*, arg2, long, arg3);
1872 *flags |= SfMayBlock;
1873 PRINT("nsendmsg(BOGUS HANDLER)( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
1876 PRE(sys_open) /* XXX CoG */
1878 //zz HChar name[30];
1881 if (ARG2 & VKI_O_CREAT) {
1883 PRINT("sys_open ( %#lx(%s), %#lx, %ld )",ARG1,(Char*)ARG1,ARG2,ARG3);
1884 PRE_REG_READ3(long, "open",
1885 const char *, filename, int, flags, int, mode);
1888 PRINT("sys_open ( %#lx(%s), %#lx )",ARG1,(Char*)ARG1,ARG2);
1889 PRE_REG_READ2(long, "open",
1890 const char *, filename, int, flags);
1892 PRE_MEM_RASCIIZ( "open(filename)", ARG1 );
1894 //zz /* Handle the case where the open is of /proc/self/cmdline or
1895 //zz /proc/<pid>/cmdline, and just give it a copy of the fd for the
1896 //zz fake file we cooked up at startup (in m_main). Also, seek the
1897 //zz cloned fd back to the start. */
1899 //zz VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
1900 //zz if (ML_(safe_to_deref)( (void*)ARG1, 1 )
1901 //zz && (VG_(strcmp)((Char *)ARG1, name) == 0
1902 //zz || VG_(strcmp)((Char *)ARG1, "/proc/self/cmdline") == 0)) {
1903 //zz sres = VG_(dup)( VG_(cl_cmdline_fd) );
1904 //zz SET_STATUS_from_SysRes( sres );
1905 //zz if (!sres.isError) {
1906 //zz OffT off = VG_(lseek)( sres.res, 0, VKI_SEEK_SET );
1908 //zz SET_STATUS_Failure( VKI_EMFILE );
1913 /* Otherwise handle normally */
1914 *flags |= SfMayBlock;
1919 //zz if (!ML_(fd_allowed)(RES, "open", tid, True)) {
1920 //zz VG_(close)(RES);
1921 //zz SET_STATUS_Failure( VKI_EMFILE );
1923 //zz if (VG_(clo_track_fds))
1924 //zz ML_(record_fd_open_with_given_name)(tid, RES, (Char*)ARG1);
1930 PRINT("sys_pipe ( %#lx )", ARG1);
1931 PRE_REG_READ1(int, "pipe", int *, filedes);
1932 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
1936 //zz Int *p = (Int *)ARG1;
1938 //zz if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
1939 //zz !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
1940 //zz VG_(close)(p[0]);
1941 //zz VG_(close)(p[1]);
1942 //zz SET_STATUS_Failure( VKI_EMFILE );
1944 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
1945 //zz if (VG_(clo_track_fds)) {
1946 //zz ML_(record_fd_open_nameless)(tid, p[0]);
1947 //zz ML_(record_fd_open_nameless)(tid, p[1]);
1954 PRINT("privcheck ( %ld )", ARG1);
1955 PRE_REG_READ1(int, "privcheck", int, arg1);
1960 PRINT("readlink ( 0x%lx(%s),0x%lx,%ld )", ARG1,(Char*)ARG1, ARG2, ARG3);
1961 PRE_REG_READ3(long, "readlink",
1962 const char *, path, char *, buf, int, bufsiz);
1963 PRE_MEM_RASCIIZ( "readlink(path)", ARG1 );
1964 PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 );
1968 POST_MEM_WRITE( ARG2, RES + 1 );
1973 *flags |= SfMayBlock;
1974 PRINT("recv ( %ld, %#lx, %ld, %ld )",
1975 ARG1, ARG2, ARG3, ARG4);
1976 PRE_REG_READ4(int, "recv", int, fd, void*, buf, int, len, int, flags);
1977 PRE_MEM_WRITE( "recv(buf)", ARG2, ARG3);
1982 POST_MEM_WRITE(ARG2, RES);
1987 *flags |= SfMayBlock;
1988 PRINT( "rename ( %#lx(%s), %#lx(%s) )", ARG1,(Char*)ARG1, ARG2,(Char*)ARG2 );
1989 PRE_REG_READ2(int, "rename", char*, frompath, char*, topath);
1990 PRE_MEM_RASCIIZ( "rename(frompath)", ARG1 );
1991 PRE_MEM_RASCIIZ( "rename(topath)", ARG2 );
1996 PRINT("sbrk (BOGUS HANDLER)( %#lx )", ARG1);
1997 PRE_REG_READ1(long, "sbrk", long, arg1);
1998 /* After a zero sbrk, disallow aspacem from doing sbrk, since libc
1999 might rely on the value returned by this syscall. */
2000 /* 1 Oct 06: not currently used (aspacemgr-aix5.c ignores it) */
2001 VG_(am_aix5_sbrk_allowed) = toBool(ARG1 != 0);
2002 /* Disallow libc from moving the brk backwards as that might trash
2003 SkPreAlloc sections acquired by aspacem from previous uses of
2007 /* Do this as a sync syscall, so the sbrk_allowed flag gets turned
2008 back on ASAP. Typically libc does sbrk(0) and then sbrk(x > 0)
2009 in quick succession. Although surely it should hold some kind
2010 of lock at that point, else it cannot safely use the result from
2011 the first sbrk call to influence the second one? */
2012 *flags &= ~SfMayBlock;
2020 PRE(sys_sched_get_priority_max)
2022 PRINT("sched_get_priority_max ( %ld )", ARG1);
2023 PRE_REG_READ1(int, "sched_get_priority_max", int, arg1);
2026 PRE(sys_sem_destroy)
2028 PRINT("sem_destroy ( %#lx )", ARG1);
2029 PRE_REG_READ1(int, "sem_destroy", sem_t*, sem);
2030 PRE_MEM_READ( "sem_destroy(sem)", ARG1, sizeof(sem_t) );
2035 PRINT("sem_init ( %#lx, %ld, %ld )", ARG1, ARG2, ARG3);
2036 PRE_REG_READ3(int, "sem_init", sem_t*, sem, int, pshared, int, value);
2037 PRE_MEM_WRITE( "sem_init(sem)", ARG1, sizeof(sem_t) );
2041 POST_MEM_WRITE( ARG1, sizeof(sem_t) );
2046 PRINT("sem_post ( %#lx )", ARG1);
2047 PRE_REG_READ1(int, "sem_post", sem_t*, sem);
2048 PRE_MEM_READ("sem_post(sem)", ARG1, sizeof(sem_t));
2052 POST_MEM_WRITE(ARG1, sizeof(sem_t));
2057 *flags |= SfMayBlock;
2058 PRINT("send (BOGUS HANDLER)( %ld, %#lx, %ld, %ld )",
2059 ARG1, ARG2, ARG3, ARG4);
2064 PRINT("setgid ( %ld )", ARG1);
2065 PRE_REG_READ1(void, "setgid", int, uid);
2070 PRINT("setsockopt ( %ld, %ld, %ld, %#lx, %ld )",
2071 ARG1,ARG2,ARG3,ARG4,ARG5 );
2072 PRE_REG_READ5(long, "setsockopt",
2073 long, socket, long, level, long, optionname,
2074 void*, optionvalue, long, optlen);
2076 PRE_MEM_READ( "setsockopt(optionvalue)", ARG4, ARG5 );
2081 PRINT("setuid ( %ld )", ARG1);
2082 PRE_REG_READ1(void, "setuid", int, uid);
2085 static UWord get_shm_size ( Word shmid )
2088 struct shmid_ds buf;
2089 vg_assert(__NR_AIX5_shmctl != __NR_AIX5_UNKNOWN);
2090 res = VG_(do_syscall3)(__NR_AIX5_shmctl, shmid, IPC_STAT, (UWord)&buf);
2092 VG_(printf)("XXX: shm_size(%ld) = %ld %ld\n", shmid, res.res, res.err);
2095 VG_(printf)("XXX: shm_size(shmid = %ld): FAILED\n", shmid);
2098 return buf.shm_segsz;
2100 /* fails with 22 and 13 (22 = EINVAL, Invalid argument,
2101 13 = EACCES, Permission denied) */
2102 /* shmat (4, 0x0, 0x1800) --> Success(0x40000000)
2103 XXX: shm_size(4) = -1 22
2105 XXX: shm_size(4) = -1 22
2107 shmat (5, 0x0, 0x1800) --> Success(0x50000000)
2108 XXX: shm_size(5) = -1 13
2110 XXX: shm_size(5) = -1 13
2112 shmat (4, 0x0, 0x1800) --> Success(0x40000000)
2113 XXX: shm_size(4) = -1 22
2115 XXX: shm_size(4) = -1 22
2121 /* void* shmat ( int shmid, const void* shmaddr, int flags ) */
2122 PRINT("shmat (%ld, %#lx, %#lx)", ARG1, ARG2, ARG3);
2123 PRE_REG_READ3(void*, "shmat", int, shmid, void*, shmaddr, int, flags);
2124 segmentSize = get_shm_size( ARG1 );
2125 if (0) VG_(printf)("shmat: seg size = %lu\n", segmentSize);
2131 vg_assert(RES != -1L);
2132 segmentSize = get_shm_size ( ARG1 );
2133 if ( segmentSize > 0 ) {
2134 UInt prot = VKI_PROT_READ|VKI_PROT_WRITE;
2137 if (ARG2 & SHM_RDONLY)
2138 prot &= ~VKI_PROT_WRITE;
2140 d = VG_(am_notify_client_shmat)( RES, VG_PGROUNDUP(segmentSize), prot );
2142 /* we don't distinguish whether it's read-only or
2143 * read-write -- it doesn't matter really. */
2144 VG_TRACK( new_mem_mmap, RES, segmentSize, True, True, False, 0/*di_handle*/ );
2146 VG_(discard_translations)( (Addr64)RES,
2147 (ULong)VG_PGROUNDUP(segmentSize),
2148 "ML_(generic_POST_sys_shmat)" );
2154 PRINT("shmctl ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3 );
2155 PRE_REG_READ3(int, "shmctl", int, shmid, int, command, void*, buffer);
2157 PRE_MEM_WRITE( "shmctl(buffer)", ARG3, sizeof(struct shmid_ds) );
2161 if ((ARG3) && ARG2 == IPC_STAT)
2162 POST_MEM_WRITE( ARG3, sizeof(struct shmid_ds) );
2167 PRINT("shmdt ( %#lx )", ARG1);
2168 PRE_REG_READ1(long, "shmdt", void*, address);
2172 NSegment const*const s = VG_(am_find_nsegment)(ARG1);
2175 Addr s_start = s->start;
2176 SizeT s_len = s->end+1 - s->start;
2179 vg_assert(s->kind == SkShmC && s->start == ARG1);
2181 d = VG_(am_notify_munmap)(s_start, s_len);
2182 /* s is now invalid; do not use after here */
2183 VG_TRACK( die_mem_munmap, s_start, s_len );
2185 VG_(discard_translations)( (Addr64)s_start,
2187 "ML_(generic_POST_sys_shmdt)" );
2193 PRINT("shmget ( %ld, %ld, %ld )", ARG1, ARG2, ARG3 );
2194 PRE_REG_READ3(int, "shmget", key_t, key, size_t, size, int, shmFlag);
2199 PRINT("shutdown (BOGUS HANDLER)");
2204 PRINT("sigcleanup (UNDOCUMENTED)");
2207 PRE(sys_sigprocmask)
2209 PRINT("sigprocmask ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
2210 PRE_REG_READ3(long, "sigprocmask",
2211 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset);
2213 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
2215 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
2217 SET_STATUS_from_SysRes(
2218 VG_(do_sys_sigprocmask) ( tid, ARG1, (vki_sigset_t*)ARG2,
2219 (vki_sigset_t*)ARG3 )
2223 *flags |= SfPollAfter;
2225 POST(sys_sigprocmask)
2228 if (RES == 0 && ARG3 != 0)
2229 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
2234 PRINT("socket ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
2235 PRE_REG_READ3(int, "socket", int, domain, int, type, int, protocol);
2240 PRINT("sys_statfs ( %#lx(%s), %#lx )",ARG1,(Char*)ARG1,ARG2);
2241 PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
2242 PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
2243 PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct statfs) );
2247 POST_MEM_WRITE( ARG2, sizeof(struct statfs) );
2252 PRINT("statx ( %#lx(%s), %#lx, %ld, %ld )", ARG1,(Char*)ARG1,ARG2,ARG3,ARG4);
2253 PRE_MEM_RASCIIZ( "statx(file_name)", ARG1 );
2254 PRE_REG_READ4(Word, "statx", UWord, fd, void*, buf,
2255 UWord, len, UWord, cmd);
2256 PRE_MEM_WRITE( "statx(buf)", ARG2, ARG3 );
2260 POST_MEM_WRITE( ARG2, ARG3 );
2265 PRINT("symlink (BOGUS HANDLER)");
2270 PRINT("sys_parm (%ld, %ld, %#lx)", ARG1, ARG2, ARG3);
2271 PRE_REG_READ3(int, "sys_parm", int, cmd, int, cmdflag,
2272 struct vario*, parmp);
2273 /* this is a bit of a kludge, but if parmp has uninitialised areas
2274 and we're doing SYSP_SET, lots of errors will be tiresomely
2275 reported. Hence just ignore the definedness of the area and
2276 only check addressability. */
2277 PRE_MEM_WRITE( "sys_parm(parmp)", ARG3, sizeof(struct vario));
2281 if (ARG1 == SYSP_GET)
2282 POST_MEM_WRITE( ARG3, sizeof(struct vario) );
2287 PRINT("sysconfig ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
2288 PRE_REG_READ3(int, "sysconfig", int, cmd, void*, parmp, int, parmlen);
2289 /* It may be that the area is read sometimes as well as written,
2290 but for the same reasons as sys_parm, just check addressibility,
2292 PRE_MEM_WRITE( "sysconfig(parmp)", ARG2, ARG3 );
2296 POST_MEM_WRITE( ARG2, ARG3 );
2299 PRE(sys_thread_create)
2301 *flags |= SfMayBlock;
2302 PRINT("thread_create ( )");
2304 POST(sys_thread_create)
2307 if (0) VG_(printf)("new lwpid is %ld\n", RES);
2309 /* Allocate a new thread slot (which sets it to VgTs_Init), and
2310 record the lwpid in it, so can later find it again when handling
2311 sys_thread_setstate for that lwpid. */
2313 ThreadId ctid = VG_(alloc_ThreadState)();
2314 ThreadState* ctst = VG_(get_ThreadState)(ctid);
2316 vg_assert(ctst->status == VgTs_Init);
2318 { /* Clear all os_state fields except for the vg stack ones, so any
2319 existing stack gets reused. */
2320 Addr v_s_b = ctst->os_state.valgrind_stack_base;
2321 Addr v_s_i_SP = ctst->os_state.valgrind_stack_init_SP;
2322 VG_(memset)(&ctst->os_state, 0, sizeof(ThreadOSstate));
2323 ctst->os_state.valgrind_stack_base = v_s_b;
2324 ctst->os_state.valgrind_stack_init_SP = v_s_i_SP;
2326 ctst->os_state.lwpid = RES;
2329 PRE(sys_thread_init)
2331 *flags |= SfMayBlock;
2332 PRE_REG_READ2(long, "thread_init", long, arg1, long, arg2);
2333 PRINT("thread_init (BOGUS HANDLER) ( %#lx, %#lx )", ARG1, ARG2);
2336 PRE(sys_thread_kill)
2338 Int target_lwpid, my_lwpid;
2339 PRINT("thread_kill ( %ld, %ld )", ARG1, ARG2);
2341 if ( ((Word)ARG1) == (Word)(-1)
2342 && ARG2 == VKI_SIGSEGV ) {
2343 /* too difficult to continue; give up. */
2344 ML_(aix5_set_threadstate_for_emergency_exit)
2345 (tid, "exiting due to thread_kill(..,SIGSEGV) to process");
2346 SET_STATUS_Success(0);
2350 /* Check to see if this kill gave us a pending signal */
2351 *flags |= SfPollAfter;
2353 target_lwpid = (Int)ARG1;
2354 my_lwpid = VG_(gettid)();
2355 /* we still hold the lock. Do deadlock-avoidance stuff. */
2356 if (target_lwpid == my_lwpid) {
2357 /* sending a signal to myself, which may be fatal. Therefore
2358 drop the lock so that if the signal kills me, some other
2359 thread can pick it up. */
2360 *flags |= SfMayBlock;
2362 /* sending a signal to some other thread, which may kill it;
2363 therefore I'd better hold on to the lock to ensure that the
2364 target doesn't get killed whilst holding it. */
2368 /* thread_setmymask_fast is handled on a per platform basis */
2370 PRE(sys_thread_setmystate)
2372 *flags |= SfMayBlock;
2373 /* args: struct tstate *, struct tstate *
2374 I assume: first is new state, if not NULL.
2375 Second is place to write the previous state, if not NULL.
2376 (in the style of sigaction) */
2377 PRINT("thread_setmystate (BOGUS HANDLER) ( %#lx, %#lx )",
2379 PRE_REG_READ2(long, "thread_setmystate",
2380 struct tstate *, newstate,
2381 struct tstate *, oldstate );
2383 PRE_MEM_READ( "thread_setmystate(arg1)", ARG1, sizeof(struct tstate) );
2385 PRE_MEM_WRITE( "thread_setmystate(arg2)", ARG2, sizeof(struct tstate) );
2386 if (1 && VG_(clo_trace_syscalls) && ARG1)
2387 ML_(aix5debugstuff_show_tstate)(ARG1, "thread_setmystate (NEW)");
2389 struct tstate* newts = (struct tstate*)ARG1;
2390 struct tstate* oldts = (struct tstate*)ARG2;
2392 /* Are we just messing with the signal mask? If so intercept it
2393 and do it ourselves. Same idea as handling for
2394 thread_setmymask_fast in 32-bit mode. */
2395 if (newts && newts->flags == TSTATE_CHANGE_SIGMASK) {
2396 vki_sigset_t* newset = newts ? (vki_sigset_t*)&newts->sigmask : NULL;
2397 vki_sigset_t* oldset = oldts ? (vki_sigset_t*)&oldts->sigmask : NULL;
2398 SET_STATUS_from_SysRes(
2399 VG_(do_sys_sigprocmask) ( tid, VKI_SIG_SETMASK, newset, oldset )
2401 *flags &= ~SfMayBlock;
2405 POST(sys_thread_setmystate)
2408 POST_MEM_WRITE( ARG2, sizeof(struct tstate) );
2409 if (0 && VG_(clo_trace_syscalls) && ARG2)
2410 ML_(aix5debugstuff_show_tstate)(ARG2, "thread_setmystate (OLD)");
2413 PRE(sys_thread_setmystate_fast)
2417 PRINT("thread_setmystate_fast (BOGUS HANDLER)"
2418 "(%#lx,%#lx(%s),%#lx(%s))",
2420 ARG2, ML_(aix5debugstuff_pc_to_fnname)(ARG2),
2421 ARG3, ML_(aix5debugstuff_pc_to_fnname)(ARG3)
2423 PRE_REG_READ3(long, "thread_setmystate_fast",
2424 long, arg1, long, arg2, long, arg3);
2425 if (1 && VG_(clo_trace_syscalls))
2426 ML_(aix5debugstuff_show_tstate_flags)( how );
2428 if (how & TSTATE_CHANGE_FLAGS) {
2429 /* Messing with cancellation type/state. Pay attention. */
2430 Bool async = (how & TSTATE_CANCEL_DEFER) == 0;
2431 Bool disabled = (how & TSTATE_CANCEL_DISABLE) > 0;
2432 ThreadState* tst = VG_(get_ThreadState)(tid);
2433 if (VG_(clo_trace_syscalls))
2434 VG_(printf)("(cancellation state -> %s %s)",
2435 async ? "ASYNC" : "DEFER",
2436 disabled ? "DISABLED" : " ENABLED");
2437 tst->os_state.cancel_async = async;
2438 tst->os_state.cancel_disabled = disabled;
2439 /* If cancellation has been enabled for this thread and there is
2440 a request outstanding, honour it now. */
2442 && tst->os_state.cancel_progress == Canc_Requested) {
2443 if (VG_(clo_trace_syscalls))
2444 VG_(printf)("(honouring previous cancellation request)");
2445 tst->os_state.cancel_progress = Canc_Actioned;
2446 Bool ok = ML_(aix5_force_thread_into_pthread_exit)(tid);
2448 /* now at serious risk of deadlock/livelock. Give up
2449 rather than continue. */
2450 ML_(aix5_set_threadstate_for_emergency_exit)
2451 (tid, "pthread_cancel(case1): "
2452 "cannot find pthread_exit; aborting");
2453 SET_STATUS_Success(0);
2457 SET_STATUS_Success(0);
2461 /* In all other cases, hand to kernel. */
2462 *flags |= SfMayBlock;
2465 /* thread_setstate is handled in syswrap-ppc{32,64}-aix5.c. */
2467 PRE(sys_thread_terminate_unlock)
2470 /* simple; just make this thread exit */
2471 PRINT("thread_terminate_unlock( %#lx )", ARG1);
2472 PRE_REG_READ1(void, "thread_terminate_unlock", void*, exitcode);
2473 tst = VG_(get_ThreadState)(tid);
2474 /* Drop the lock we were holding, since we're not really going to
2475 exit the host thread with thread_terminate_unlock. */
2476 if (0) VG_(printf)("XXXXX dropping lock\n");
2477 if (1) VG_(do_syscall1)(__NR_AIX5_thread_unlock, ARG1);
2478 /* Set the thread's status to be exiting, then claim that the
2479 syscall succeeded. */
2480 tst->exitreason = VgSrc_ExitThread;
2481 tst->os_state.exitcode = 0;
2482 SET_STATUS_Success(0);
2485 PRE(sys_thread_tsleep)
2487 *flags |= SfMayBlock;
2488 PRINT("thread_tsleep (BOGUS HANDLER)( %ld, %#lx, %#lx, %#lx )",
2489 ARG1, ARG2, ARG3, ARG4 );
2492 PRE(sys_thread_tsleep_event)
2494 *flags |= SfMayBlock;
2495 PRINT("thread_tsleep_event (UNDOCUMENTED)( %#lx, %#lx, %ld, %#lx )",
2496 ARG1, ARG2, ARG3, ARG4 );
2499 PRE(sys_thread_twakeup)
2501 *flags |= SfMayBlock;
2502 PRINT("thread_twakeup (BOGUS HANDLER)( tid=%ld, val=%#lx )", ARG1, ARG2 );
2505 PRE(sys_thread_twakeup_event)
2507 *flags |= SfMayBlock;
2508 PRINT("thread_twakeup_event (BOGUS HANDLER)( %#lx, %ld, %ld )",
2512 PRE(sys_thread_unlock)
2514 *flags |= SfMayBlock;
2515 PRINT("thread_unlock (BOGUS HANDLER)" );
2518 PRE(sys_thread_waitlock)
2520 *flags |= SfMayBlock;
2521 PRINT("thread_waitlock (BOGUS HANDLER)" );
2524 PRE(sys_thread_waitlock_)
2526 *flags |= SfMayBlock;
2527 PRINT("thread_waitlock_ (BOGUS HANDLER)" );
2532 PRINT("times ( %#lx )", ARG1);
2533 PRE_REG_READ1(long, "times", struct tms *, buffer);
2534 PRE_MEM_WRITE("times(buf)", ARG1, sizeof(struct tms) );
2538 POST_MEM_WRITE( ARG1, sizeof(struct tms) );
2543 PRINT("umask (BOGUS HANDLER)");
2548 PRINT("uname ( %#lx )", ARG1);
2549 PRE_MEM_WRITE( "uname(Name)", ARG1, sizeof(struct utsname));
2554 POST_MEM_WRITE( ARG1, sizeof(struct utsname));
2559 PRINT("unlink ( %#lx(%s) )", ARG1, (Char*)ARG1 );
2560 PRE_REG_READ1(int, "unlink", char*, path);
2561 PRE_MEM_RASCIIZ( "unlink(path)", ARG1 );
2566 PRINT("utimes ( %#lx(%s), %#lx )", ARG1,(Char*)ARG1, ARG2);
2567 PRE_REG_READ2(int, "utimes", char*, path, struct timeval*, times);
2568 PRE_MEM_RASCIIZ( "utimes(path)", ARG1 );
2569 PRE_MEM_READ( "utimes(times)", ARG2, 2 * sizeof(struct vki_timeval) );
2574 PRINT("vmgetinfo ( %#lx, %ld, %ld )", ARG1, ARG2, ARG3 );
2575 PRE_REG_READ3(int, "vmgetinfo", void*, out, int, command, int, arg);
2576 /* It looks like libc's vmgetinfo just hands stuff through to the
2577 syscall. The man page says that the interpretation of ARG3(arg)
2578 depends on ARG2(cmd); nevertheless in all cases basically this
2579 writes the buffer (ARG1, ARG3). */
2580 PRE_MEM_WRITE("vmgetinfo(buf)", ARG1, ARG3);
2585 POST_MEM_WRITE(ARG1, ARG3);
2590 *flags |= SfMayBlock;
2597 #endif // defined(VGO_aix5)
2599 /*--------------------------------------------------------------------*/
2601 /*--------------------------------------------------------------------*/