1
2 /*--------------------------------------------------------------------*/
3 /*--- AIX5-specific syscalls. syswrap-aix5.c ---*/
4 /*--------------------------------------------------------------------*/
5
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2006-2010 OpenWorks LLP
11 info@open-works.co.uk
12
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.
17
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.
22
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
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29
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.
34 */
35
36 #if defined(VGO_aix5)
37
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_core_libcbase.h"
49 #include "pub_core_libcassert.h"
50 #include "pub_core_libcfile.h"
51 #include "pub_core_libcprint.h"
52 #include "pub_core_libcproc.h"
53 #include "pub_core_libcsignal.h"
54 #include "pub_core_mallocfree.h"
55 #include "pub_core_tooliface.h"
56 #include "pub_core_options.h"
57 #include "pub_core_scheduler.h"
58 #include "pub_core_signals.h"
59 #include "pub_core_syscall.h"
60 #include "pub_core_sigframe.h" // VG_(sigframe_destroy)
61 #include "pub_core_syswrap.h"
62 #include "pub_core_stacktrace.h"
63
64 #include "priv_types_n_macros.h"
65 #include "priv_syswrap-aix5.h"
66
67
68
69 /* ---------------------------------------------------------------------
70 Misc helpers
71 ------------------------------------------------------------------ */
72
73 /* Allocate a stack for this thread, if it doesn't already have one.
74 They're allocated lazily, and never freed. Returns the initial stack
75 pointer value to use, or 0 if allocation failed. */
ML_(allocstack)76 Addr ML_(allocstack)(ThreadId tid)
77 {
78 ThreadState* tst = VG_(get_ThreadState)(tid);
79 VgStack* stack;
80 Addr initial_SP;
81
82 /* Either the stack_base and stack_init_SP are both zero (in which
83 case a stack hasn't been allocated) or they are both non-zero,
84 in which case it has. */
85
86 if (tst->os_state.valgrind_stack_base == 0)
87 vg_assert(tst->os_state.valgrind_stack_init_SP == 0);
88
89 if (tst->os_state.valgrind_stack_base != 0)
90 vg_assert(tst->os_state.valgrind_stack_init_SP != 0);
91
92 /* If no stack is present, allocate one. */
93 if (tst->os_state.valgrind_stack_base == 0) {
94 stack = VG_(am_alloc_VgStack)( &initial_SP );
95 if (stack) {
96 /* Leave some space above SP because AIX's ABI stores
97 stuff there. */
98 initial_SP -= 256;
99 vg_assert(initial_SP > (Addr)stack);
100 tst->os_state.valgrind_stack_base = (Addr)stack;
101 tst->os_state.valgrind_stack_init_SP = initial_SP;
102 } else {
103 return 0; /* allocation of stack failed */
104 }
105 }
106
107 if (0)
108 VG_(printf)( "stack for tid %d at %p; init_SP=%p\n",
109 tid,
110 (void*)tst->os_state.valgrind_stack_base,
111 (void*)tst->os_state.valgrind_stack_init_SP );
112
113 return tst->os_state.valgrind_stack_init_SP;
114 }
115
116
117 /* If we know or believe a module load/unload event has happened, get
118 aspacem to re-read /proc/../map to update its picture of what text
119 and data segments are present. This also notifies all the usual
120 parties that need to know about address space changes. */
121
ML_(aix5_rescan_procmap_after_load_or_unload)122 void ML_(aix5_rescan_procmap_after_load_or_unload) ( void )
123 {
124 AixCodeSegChange* changes;
125 Int changes_size, changes_used, i;
126
127 /* Find out how many AixCodeSegChange records we will need, and
128 acquire them. */
129 changes_size = VG_(am_aix5_reread_procmap_howmany_directives)();
130 changes = VG_(arena_malloc)(VG_AR_CORE, "syswrap-aix5.arpalou.1",
131 changes_size * sizeof(AixCodeSegChange));
132 vg_assert(changes);
133
134 /* Now re-read /proc/<pid>/map and acquire a change set */
135 VG_(am_aix5_reread_procmap)( changes, &changes_used );
136 vg_assert(changes_used >= 0 && changes_used <= changes_size);
137
138 /* And notify all parties of the changes. */
139 for (i = 0; i < changes_used; i++) {
140 ULong di_handle = VG_(di_aix5_notify_segchange)(
141 changes[i].code_start,
142 changes[i].code_len,
143 changes[i].data_start,
144 changes[i].data_len,
145 changes[i].file_name,
146 changes[i].mem_name,
147 changes[i].is_mainexe,
148 changes[i].acquire
149 );
150
151 if (changes[i].acquire) {
152 VG_TRACK( new_mem_mmap,
153 changes[i].code_start, changes[i].code_len,
154 /*r*/True, /*w*/False, /*x*/True, di_handle );
155 VG_TRACK( new_mem_mmap,
156 changes[i].data_start, changes[i].data_len,
157 /*r*/True, /*w*/True, /*x*/False, 0/*or di_handle?*/ );
158 } else {
159 VG_TRACK( die_mem_munmap,
160 changes[i].code_start, changes[i].code_len );
161 VG_TRACK( die_mem_munmap,
162 changes[i].data_start, changes[i].data_len );
163 VG_(discard_translations)(
164 changes[i].code_start, changes[i].code_len,
165 "POST(sys___loadx/sys__kload)(code)" );
166 VG_(discard_translations)(
167 changes[i].data_start, changes[i].data_len,
168 "POST(sys___loadx/sys__kload)(data)" );
169 }
170 }
171
172 VG_(arena_free)(VG_AR_CORE, changes);
173 }
174
175
176 /* Mess with the given thread's pc/toc so that it is entering
177 pthread_exit() with argument PTHREAD_CANCELED. Returns True if ok,
178 False if it failed to do so, due to not being able to find
179 pthread_exit() by searching symbol tables. */
ML_(aix5_force_thread_into_pthread_exit)180 Bool ML_(aix5_force_thread_into_pthread_exit)( ThreadId tid )
181 {
182 Addr ent = 0, toc = 0;
183 Bool found;
184 ThreadState* tst = VG_(get_ThreadState)(tid);
185 found = VG_(lookup_symbol_SLOW)("libpthread*.a(*.o)", "pthread_exit",
186 &ent, &toc);
187 if (found) {
188 if (0)
189 VG_(printf)("THREAD CANCELED, new cia,toc = %#lx,%#lx\n", ent, toc);
190 tst->arch.vex.guest_CIA = ent;
191 tst->arch.vex.guest_GPR2 = toc;
192 tst->arch.vex.guest_GPR3 = (Word)(-1); /* == PTHREAD_CANCELED */
193 /* If the thread is blocked in a syscall, we better bop it on
194 the head with SIGVGKILL in order to get it out of said
195 syscall. */
196 if (tst->status == VgTs_WaitSys) {
197 if (VG_(clo_trace_syscalls))
198 VG_(printf)("(sending SIGVGKILL to tid %d)", (Int)tid);
199 VG_(get_thread_out_of_syscall)( tid );
200 }
201 return True; /* ok */
202 } else {
203 // urk. Now we're hosed. Let the caller figure out what to do.
204 return False; /* failed */
205 }
206 }
207
208
209 /* For various reasons, on AIX we may have to just give up if
210 continuing is too difficult (eg, risk of future deadlock). This
211 sets up the process state to exit straight away, but does not
212 actually itself exit. */
ML_(aix5_set_threadstate_for_emergency_exit)213 void ML_(aix5_set_threadstate_for_emergency_exit)(ThreadId tid, HChar* why)
214 {
215 ThreadState* tst = VG_(get_ThreadState)(tid);
216 /* Set the thread's status to be exiting and taking out the
217 entire process, then claim that the syscall succeeded. */
218 tst->exitreason = VgSrc_ExitProcess;
219 tst->os_state.exitcode = 1;
220 if (!VG_(clo_xml)) {
221 VG_(message)(Vg_UserMsg,
222 "WARNING: AIX: %s\n", why);
223 VG_(message)(Vg_UserMsg,
224 "WARNING: (too difficult to continue past this point).\n");
225 VG_(get_and_pp_StackTrace)(tid, 10);
226 }
227 }
228
229
230 /* Update aspacem etc on conclusion of a successful sbrk/__libc_sbrk
231 call. 2006-08-24: this was not completed because I don't
232 understand what sbrk/__libc_sbrk are doing. */
233
handle_sbrk(Word delta)234 static void handle_sbrk ( Word delta )
235 {
236 return;
237 /*NOTREACHED*/
238 if (delta > 0) {
239 /* Map in VG_(brk_limit) for delta */
240 /* using notify_mmap ? */
241 VG_(brk_limit) += delta;
242 }
243 if (delta < 0) {
244 Addr tmp = VG_(brk_limit);
245 VG_(brk_limit) += delta;
246 /* Can't move below original starting point */
247 if (VG_(brk_limit) < VG_(brk_base))
248 VG_(brk_limit) = VG_(brk_base);
249 if (VG_(brk_limit) < tmp)
250 /* Unmap VG_(brk_limit) for tmp - VG_(brk_limit) */
251 /* using notify_munmap ? */
252 ;
253 }
254 if (VG_(clo_trace_syscalls))
255 VG_(printf)("new brk: 0x%010llx-0x%010llx (size %lld)\n",
256 (ULong)VG_(brk_base),
257 (ULong)VG_(brk_limit),
258 (ULong)VG_(brk_limit) - (ULong)VG_(brk_base));
259 }
260
261
262 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
263 #include <sys/thread.h>
264 #include <sys/poll.h>
265 #include <sys/times.h>
266 #include <sys/shm.h>
267 #include <semaphore.h>
268 #include <sys/statfs.h>
269 #include <sys/utsname.h>
270 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
271
ML_(aix5debugstuff_pc_to_fnname)272 HChar* ML_(aix5debugstuff_pc_to_fnname) ( Addr pc )
273 {
274 Bool ok;
275 static HChar name[100];
276 ok = VG_(get_fnname_w_offset)(pc, name, 100);
277 if (!ok) VG_(strcpy)(name, "???");
278 return &name[0];
279 }
280
aix5debugstuff_show_sigset(vki_sigset_t * set)281 static void aix5debugstuff_show_sigset ( vki_sigset_t* set )
282 {
283 Int i;
284 UChar* p = (UChar*)set;
285 for (i = 0; i < sizeof(vki_sigset_t); i++)
286 VG_(printf)("%02x", (Int)p[i]);
287 }
288
aix5debugstuff_name_of_tstate_flag(UWord flag)289 static HChar* aix5debugstuff_name_of_tstate_flag ( UWord flag )
290 {
291 Int i, nset;
292 nset = 0;
293 for (i = 0; i < 8*sizeof(UWord); i++)
294 if (flag & (1U << i))
295 nset++;
296 vg_assert(nset == 1);
297 switch (flag) {
298 case TSTATE_LOCAL: return "LOCAL";
299 case TSTATE_CANCEL_DEFER: return "CANCEL_DEFER";
300 case TSTATE_CANCEL_DISABLE: return "CANCEL_DISABLE";
301 case TSTATE_CANCEL_PENDING: return "CANCEL_PENDING";
302 case TSTATE_CANCEL_CHKPT: return "CANCEL_CHKPT";
303 case TSTATE_INTR: return "INTR";
304 case TSTATE_EXEMPT: return "EXEMPT";
305 #ifdef TSTATE_PROFILING_OFF
306 case TSTATE_PROFILING_OFF: return "PROFILING_OFF";
307 #endif
308 case TSTATE_SUSPEND: return "SUSPEND";
309 case TSTATE_CONT: return "CONT";
310 #ifdef TSTATE_CREDS
311 case TSTATE_CREDS: return "CREDS";
312 #endif
313 #ifdef TSTATE_PROCHANDLERS
314 case TSTATE_PROCHANDLERS: return "PROCHANDLERS";
315 #endif
316 case TSTATE_ADVH: return "ADVH";
317 case TSTATE_SYNCH: return "SYNCH";
318 case TSTATE_USCHED: return "USCHED";
319 case TSTATE_DEFAULT_SCHED: return "DEFAULT_SCHED";
320 #ifdef TSTATE_INHERIT_SCHED
321 case TSTATE_INHERIT_SCHED: return "INHERIT_SCHED";
322 #endif
323 #ifdef TSTATE_LOCAL_INIT
324 case TSTATE_LOCAL_INIT: return "LOCAL_INIT";
325 #endif
326 #ifdef TSTATE_LOCAL_TERM
327 case TSTATE_LOCAL_TERM: return "LOCAL_TERM";
328 #endif
329 #ifdef TSTATE_LOCAL_MCHANGE
330 case TSTATE_LOCAL_MCHANGE: return "LOCAL_MCHANGE";
331 #endif
332 case TSTATE_CHANGE_ALL: return "CHANGE_ALL";
333 #ifdef TSTATE_CHANGE_PTID
334 case TSTATE_CHANGE_PTID: return "CHANGE_PTID";
335 #endif
336 #ifdef TSTATE_CHANGE_PROFILE
337 case TSTATE_CHANGE_PROFILE: return "CHANGE_PROFILE";
338 #endif
339 #ifdef TSTATE_CHANGE_SSTACK
340 case TSTATE_CHANGE_SSTACK: return "CHANGE_SSTACK";
341 #endif
342 case TSTATE_CHANGE_ERRNOP: return "CHANGE_ERRNOP";
343 case TSTATE_CHANGE_SIGMASK: return "CHANGE_SIGMASK";
344 case TSTATE_CHANGE_PSIG: return "CHANGE_PSIG";
345 case TSTATE_CHANGE_SCHED: return "CHANGE_SCHED";
346 case TSTATE_CHANGE_FLAGS: return "CHANGE_FLAGS";
347 case TSTATE_CHANGE_USERDATA: return "CHANGE_USERDATA";
348 default: return "???";
349 }
350 }
351
ML_(aix5debugstuff_show_tstate_flags)352 void ML_(aix5debugstuff_show_tstate_flags) ( UWord w )
353 {
354 const Int step = 5;
355 Int i, j;
356 UWord m;
357 j = 0;
358 for (i = 0; i < 8*sizeof(UWord); i++) {
359 m = 1U << i;
360 if ((w & m) == 0)
361 continue;
362 if ((j % step) == 0)
363 VG_(printf)(" ");
364 VG_(printf)("%s ", aix5debugstuff_name_of_tstate_flag(w & m));
365 if ((j % step) == step-1 && j > 0)
366 VG_(printf)("\n");
367 j++;
368 }
369 if (((j-1) % step) != step-1 && j > 0)
370 VG_(printf)("\n");
371 }
372
ML_(aix5debugstuff_show_tstate)373 void ML_(aix5debugstuff_show_tstate) ( Addr tsA, HChar* who )
374 {
375 Int i;
376 const Int step = sizeof(void*)==8 ? 3 : 5;
377 struct tstate* ts = (struct tstate*)tsA;
378 VG_(printf)("\n{ ========= %s =========\n", who);
379 for (i = 0; i < _NGPRS; i++) {
380 if ((i % step) == 0)
381 VG_(printf)(" [%2d] ", i);
382 if (sizeof(void*)==8)
383 VG_(printf)("%016llx ", (ULong)ts->mst.gpr[i]);
384 else
385 VG_(printf)("%08llx ", (ULong)ts->mst.gpr[i]);
386 if ((i == _NGPRS-1) || ((i % step) == step-1 && i > 0))
387 VG_(printf)("\n");
388 }
389 VG_(printf)(" [iar] %#llx %s\n", (ULong)ts->mst.iar,
390 ML_(aix5debugstuff_pc_to_fnname)(ts->mst.iar));
391
392 VG_(printf)(" errnop_addr %p\n", ts->errnop_addr);
393
394 VG_(printf)(" sigmask ");
395 aix5debugstuff_show_sigset( (vki_sigset_t*)&ts->sigmask );
396 VG_(printf)("\n");
397
398 VG_(printf)(" psig ");
399 aix5debugstuff_show_sigset( (vki_sigset_t*)&ts->psig );
400 VG_(printf)("\n");
401
402 VG_(printf)(" policy %d\n", ts->policy);
403 VG_(printf)(" priority %d\n", ts->priority);
404 VG_(printf)(" flags 0x%x\n", ts->flags);
405 ML_(aix5debugstuff_show_tstate_flags)( (UWord)ts->flags );
406 VG_(printf)(" flagmask 0x%x\n", ts->flagmask);
407 VG_(printf)(" userdata %p\n", (void*)ts->userdata);
408 VG_(printf)(" fpinfo %d\n", ts->fpinfo);
409 VG_(printf)(" fpscrx %d\n", ts->fpscrx);
410 VG_(printf)(" sigaltstack ??\n");
411 VG_(printf)(" thread_control_p 0x%llx\n", (ULong)ts->thread_control_p);
412 // AIX 5.1 does not seem to have these members
413 // VG_(printf)(" prbase %p\n", (void*)ts->prbase);
414 // VG_(printf)(" credp %p\n", (void*)ts->credp);
415 // VG_(printf)(" ptid %d\n", (int)ts->ptid);
416 // VG_(printf)(" tct_clock %d\n", (int)ts->tct_clock);
417 UInt* p = (UInt*)tsA;
418 for (i = 0; i < sizeof(struct tstate)/sizeof(UInt); i++) {
419 HChar* s = ML_(aix5debugstuff_pc_to_fnname)( (Addr)p[i] );
420 if (0==VG_(strcmp)(s,"???"))
421 continue;
422 VG_(printf)(" [%d] %x %s\n", i, p[i], s);
423 }
424 VG_(printf)("}\n");
425 }
426
427 /* ---------------------------------------------------------------------
428 PRE/POST wrappers for arch-generic, AIX5-specific syscalls. Note:
429 in fact AIX5 doesn't share any wrappers with Linux since it's
430 difficult to get syswrap-generic.c to compile on AIX. Hence in
431 fact this file also serves the role of syswrap-generic.c for AIX.
432 This could probably be improved at the cost of some extra effort.
433 ------------------------------------------------------------------ */
434
435 // Nb: See the comment above the generic PRE/POST wrappers in
436 // m_syswrap/syswrap-generic.c for notes about how they work.
437
438 #define PRE(name) DEFN_PRE_TEMPLATE(aix5, name)
439 #define POST(name) DEFN_POST_TEMPLATE(aix5, name)
440
441
442 // How to make __libc_sbrk appear to fail, from libc's point of view:
443 // SysRes r;
444 // r.res = -1; /* significant to libc */
445 // r.err = VKI_ENOMEM; /* not significant to libc */
446 // SET_STATUS_from_SysRes( r );
447 // return;
448
PRE(sys___libc_sbrk)449 PRE(sys___libc_sbrk)
450 {
451 PRINT("__libc_sbrk (BOGUS HANDLER)( %#lx )",ARG1);
452 PRE_REG_READ1(long, "__libc_sbrk", long, arg1);
453 /* After a zero sbrk, disallow aspacem from doing sbrk, since libc
454 might rely on the value returned by this syscall. */
455 /* 1 Oct 06: not currently used (aspacemgr-aix5.c ignores it) */
456 VG_(am_aix5_sbrk_allowed) = toBool(ARG1 != 0);
457 /* Disallow libc from moving the brk backwards as that might trash
458 SkPreAlloc sections acquired by aspacem from previous uses of
459 sbrk. */
460 if (ARG1 < 0)
461 ARG1 = 0;
462 /* Do this as a sync syscall, so the sbrk_allowed flag gets turned
463 back on ASAP. Typically libc does sbrk(0) and then sbrk(x > 0)
464 in quick succession. Although surely it should hold some kind
465 of lock at that point, else it cannot safely use the result from
466 the first sbrk call to influence the second one? */
467 *flags &= ~SfMayBlock;
468 }
POST(sys___libc_sbrk)469 POST(sys___libc_sbrk)
470 {
471 vg_assert(SUCCESS);
472 handle_sbrk(ARG1);
473 }
474
475 /* __loadx is handled in the platform-specific files. */
476
PRE(sys___msleep)477 PRE(sys___msleep)
478 {
479 PRINT("__msleep (BOGUS HANDLER) ( %#lx )", ARG1);
480 PRE_REG_READ1(long, "msleep", void*, arg1);
481 }
482
483 /* __unload is handled in the platform-specific files. */
484
PRE(sys__clock_settime)485 PRE(sys__clock_settime)
486 {
487 PRINT("_clock_settime (UNDOCUMENTED) ( %ld, %#lx )", ARG1, ARG2);
488 PRE_REG_READ2(int, "_clock_settime", int, arg1, int, arg2);
489 }
490
PRE(sys__exit)491 PRE(sys__exit)
492 {
493 ThreadState* tst;
494 /* simple; just make this thread exit */
495 PRINT("_exit( %ld )", ARG1);
496 PRE_REG_READ1(void, "exit", int, exitcode);
497
498 tst = VG_(get_ThreadState)(tid);
499 /* Set the thread's status to be exiting and taking out the entire
500 process, then claim that the syscall succeeded. */
501 tst->exitreason = VgSrc_ExitProcess;
502 tst->os_state.exitcode = ARG1;
503 SET_STATUS_Success(0);
504 }
505
PRE(sys__fp_fpscrx_sc)506 PRE(sys__fp_fpscrx_sc)
507 {
508 PRINT("_fp_fpscrx_sc (BOGUS HANDLER)");
509 }
510
PRE(sys__getpgrp)511 PRE(sys__getpgrp)
512 {
513 PRINT("_getpgrp (BOGUS HANDLER)");
514 }
515
PRE(sys__getpid)516 PRE(sys__getpid)
517 {
518 PRINT("_getpid ( )");
519 }
520
PRE(sys__getppid)521 PRE(sys__getppid)
522 {
523 PRINT("_getppid ( )");
524 }
525
PRE(sys__getpriority)526 PRE(sys__getpriority)
527 {
528 PRINT("_getpriority (BOGUS HANDLER)");
529 }
530
PRE(sys__nsleep)531 PRE(sys__nsleep)
532 {
533 *flags |= SfMayBlock;
534 PRINT("_nsleep( %#lx, %#lx )", ARG1, ARG2);
535 PRE_REG_READ2(void, "_nsleep", struct timestruc_t*, arg1,
536 struct timestruc_t*, arg2);
537 /* In 64-bit mode, struct ends in 4 padding bytes. Hence: */
538 if (ARG1)
539 PRE_MEM_READ("_nsleep(arg1)",
540 ARG1,
541 sizeof(void*)==4 ? sizeof(struct timestruc_t)
542 : sizeof(struct timestruc_t)-4 );
543 if (ARG2)
544 PRE_MEM_WRITE("_nsleep(arg2)", ARG2, sizeof(struct timestruc_t));
545 }
POST(sys__nsleep)546 POST(sys__nsleep)
547 {
548 if (ARG2)
549 POST_MEM_WRITE(ARG2, sizeof(struct timestruc_t));
550 }
551
PRE(sys__pause)552 PRE(sys__pause)
553 {
554 *flags |= SfMayBlock;
555 PRINT("_pause ( )");
556 PRE_REG_READ0(long, "pause");
557 }
558
PRE(sys__poll)559 PRE(sys__poll)
560 {
561 UInt i;
562 struct pollfd* ufds = (struct pollfd *)ARG1;
563 *flags |= SfMayBlock;
564 PRINT("_poll ( %#lx, %ld, %ld )\n", ARG1,ARG2,ARG3);
565 PRE_REG_READ3(long, "_poll",
566 struct pollfd *, ufds, unsigned int, nfds, long, timeout);
567
568 for (i = 0; i < ARG2; i++) {
569 PRE_MEM_READ( "poll(ufds.fd)",
570 (Addr)(&ufds[i].fd), sizeof(ufds[i].fd) );
571 PRE_MEM_READ( "poll(ufds.events)",
572 (Addr)(&ufds[i].events), sizeof(ufds[i].events) );
573 PRE_MEM_WRITE( "poll(ufds.reventss)",
574 (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
575 }
576 }
POST(sys__poll)577 POST(sys__poll)
578 {
579 if (RES > 0) {
580 UInt i;
581 struct pollfd* ufds = (struct pollfd *)ARG1;
582 for (i = 0; i < ARG2; i++)
583 POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
584 }
585 }
586
PRE(sys__select)587 PRE(sys__select)
588 {
589 UInt nfds, nmqids;
590 *flags |= SfMayBlock;
591 /* XXX: copy of generic; I don't know if this is right or not. */
592 PRINT("_select ( %ld, %#lx, %#lx, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4,ARG5);
593 PRE_REG_READ5(long, "_select",
594 int, n, struct sellist *, readfds,
595 struct sellist *, writefds,
596 struct sellist *, exceptfds,
597 struct timeval *, timeout);
598 nfds = ((UInt)ARG1) & 0xFFFF;
599 nmqids = (((UInt)ARG1) >> 16) & 0xFFFF;
600
601 // XXX: this possibly understates how much memory is read.
602 if (ARG2 != 0)
603 PRE_MEM_READ( "select(readfds)",
604 ARG2, nfds/8 /* __FD_SETSIZE/8 */ );
605 if (ARG3 != 0)
606 PRE_MEM_READ( "select(writefds)",
607 ARG3, nfds/8 /* __FD_SETSIZE/8 */ );
608 if (ARG4 != 0)
609 PRE_MEM_READ( "select(exceptfds)",
610 ARG4, nfds/8 /* __FD_SETSIZE/8 */ );
611 if (ARG5 != 0)
612 PRE_MEM_READ( "select(timeout)", ARG5,
613 /* in 64-bit mode, struct timeval has 4 bytes of
614 padding at the end, which tend to not be
615 initialised. */
616 sizeof(void*)==4 ? sizeof(struct timeval)
617 : sizeof(struct timeval)-4
618 );
619 }
620
PRE(sys__sem_wait)621 PRE(sys__sem_wait)
622 {
623 *flags |= SfMayBlock;
624 PRINT("_sem_wait (BOGUS HANDLER) ( %#lx, %#lx, %ld )", ARG1, ARG2, ARG3);
625 PRE_REG_READ3(long, "_sem_wait", void*, arg1, void*, arg2, long, arg3 );
626 /* Not sure what the two pointer args are. Hence no proper handler.*/
627 }
628
PRE(sys__setpgid)629 PRE(sys__setpgid)
630 {
631 PRINT("setpgid ( %ld, %ld )", ARG1, ARG2);
632 PRE_REG_READ2(int, "setpgid", int, pid, int, pgid);
633 }
634
PRE(sys__setsid)635 PRE(sys__setsid)
636 {
637 PRINT("setsid ( )");
638 }
639
PRE(sys__sigaction)640 PRE(sys__sigaction) /* COL, more or less */
641 {
642 PRINT("_sigaction ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
643 PRE_REG_READ3(long, "_sigaction",
644 int, signum, const struct sigaction *, act,
645 struct sigaction *, oldact);
646
647 if (ARG2 != 0) {
648 struct vki_sigaction *sa = (struct vki_sigaction *)ARG2;
649 PRE_MEM_READ( "_sigaction(act->sa_handler)",
650 (Addr)&sa->ksa_handler, sizeof(sa->ksa_handler));
651 PRE_MEM_READ( "_sigaction(act->sa_mask)",
652 (Addr)&sa->sa_mask, sizeof(sa->sa_mask));
653 PRE_MEM_READ( "rt_sigaction(act->sa_flags)",
654 (Addr)&sa->sa_flags, sizeof(sa->sa_flags));
655 }
656 if (ARG3 != 0)
657 PRE_MEM_WRITE( "rt_sigaction(oldact)", ARG3, sizeof(struct vki_sigaction));
658
659 SET_STATUS_from_SysRes(
660 VG_(do_sys_sigaction)(ARG1, (const struct vki_sigaction *)ARG2,
661 (struct vki_sigaction *)ARG3)
662 );
663 }
POST(sys__sigaction)664 POST(sys__sigaction)
665 {
666 vg_assert(SUCCESS);
667 if (RES == 0 && ARG3 != 0)
668 POST_MEM_WRITE( ARG3, sizeof(struct vki_sigaction));
669 }
670
PRE(sys__thread_self)671 PRE(sys__thread_self)
672 {
673 PRINT("_thread_self ( )");
674 }
675
PRE(sys__thread_setsched)676 PRE(sys__thread_setsched)
677 {
678 PRINT("_thread_setsched ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
679 PRE_REG_READ3(long, "_thread_setsched", long, arg1, long, arg2, long, arg3);
680 }
681
PRE(sys_access)682 PRE(sys_access)
683 {
684 PRINT("access ( %#lx(%s), %ld )", ARG1,(Char*)ARG1, ARG2);
685 PRE_REG_READ2(int, "access", char*, pathname, int, mode);
686 PRE_MEM_RASCIIZ( "access(pathname)", ARG1 );
687 }
688
PRE(sys_accessx)689 PRE(sys_accessx)
690 {
691 PRINT("accessx ( %#lx(%s), %ld, %ld )", ARG1,(Char*)ARG1, ARG2, ARG3);
692 PRE_REG_READ3(int, "accessx", char*, pathname, int, mode, int, who);
693 PRE_MEM_RASCIIZ( "accessx(pathname)", ARG1 );
694 }
695
PRE(sys_appgetrlimit)696 PRE(sys_appgetrlimit)
697 {
698 /* Note: assumes kernel struct == libc struct */
699 PRINT("appgetrlimit ( %ld, %#lx )", ARG1, ARG2);
700 PRE_REG_READ2(int, "appgetrlimit", int, arg1, struct rlimit*, arg2);
701 PRE_MEM_WRITE( "appgetrlimit(buf)", ARG2, sizeof(struct rlimit) );
702 }
POST(sys_appgetrlimit)703 POST(sys_appgetrlimit)
704 {
705 POST_MEM_WRITE( ARG2, sizeof(struct rlimit) );
706 }
707
PRE(sys_appgetrusage)708 PRE(sys_appgetrusage)
709 {
710 /* Note: assumes kernel struct == libc struct */
711 PRINT("appgetrusage ( %ld, %#lx )", ARG1, ARG2);
712 PRE_REG_READ2(int, "appgetrusage", int, arg1, struct rusage*, arg2);
713 PRE_MEM_WRITE( "appgetrusage(buf)", ARG2, sizeof(struct rusage) );
714 }
POST(sys_appgetrusage)715 POST(sys_appgetrusage)
716 {
717 POST_MEM_WRITE( ARG2, sizeof(struct rusage) );
718 }
719
PRE(sys_apprestimer)720 PRE(sys_apprestimer)
721 {
722 PRINT("apprestimer (BOGUS HANDLER)");
723 }
724
PRE(sys_appsetrlimit)725 PRE(sys_appsetrlimit)
726 {
727 PRINT("appsetrlimit (BOGUS HANDLER)");
728 }
729
PRE(sys_appulimit)730 PRE(sys_appulimit)
731 {
732 PRINT("appulimit ( %ld, %ld )", ARG1, ARG2);
733 PRE_REG_READ2(long, "appulimit", long, arg1, long, arg2);
734 }
735
PRE(sys_bind)736 PRE(sys_bind)
737 {
738 PRINT("bind ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
739 PRE_REG_READ3(int, "bind", int, socket,
740 void*, address, int, addresslen);
741 /* Hmm. This isn't really right - see pre_mem_read_sockaddr. */
742 PRE_MEM_READ( "bind(address)", ARG2, ARG3 );
743 }
744
PRE(sys_chdir)745 PRE(sys_chdir)
746 {
747 PRINT("chdir ( %#lx(%s) )", ARG1,(Char*)ARG1);
748 PRE_REG_READ1(long, "chdir", const char *, path);
749 PRE_MEM_RASCIIZ( "chdir(path)", ARG1 );
750 }
751
PRE(sys_chmod)752 PRE(sys_chmod)
753 {
754 PRINT("chmod ( %#lx(%s), 0x%lx )", ARG1,(Char*)ARG1, ARG2 );
755 PRE_REG_READ2(int, "chmod", char*, path, int, mode);
756 PRE_MEM_RASCIIZ( "chmod(path)", ARG1 );
757 }
758
PRE(sys_chown)759 PRE(sys_chown)
760 {
761 PRINT("chown ( %#lx(%s), %ld, %ld )", ARG1,(Char*)ARG1, ARG2, ARG3 );
762 PRE_REG_READ3(int, "chown", char*, path, int, owner, int, group);
763 PRE_MEM_RASCIIZ( "chown(path)", ARG1 );
764 }
765
PRE(sys_close)766 PRE(sys_close)
767 {
768 PRINT("close ( %ld )", ARG1);
769 PRE_REG_READ1(void, "close", UInt, fd);
770 /* If doing -d style logging (which is to fd=2), don't allow that
771 to be closed. */
772 if (ARG1 == 2/*stderr*/ && VG_(debugLog_getLevel)() > 0)
773 SET_STATUS_Failure( VKI_EBADF );
774 }
775
PRE(sys_connext)776 PRE(sys_connext)
777 {
778 /* apparently undocumented. I don't know what it does. */
779 /* Although /usr/include/net/proto_uipc.h does mention it.
780 Args are apparently (int, caddr_t, int). I suspect the
781 first arg is a fd and the third a flags value. */
782 PRINT("connext (UNDOCUMENTED)( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
783 PRE_REG_READ3(int, "connext", int, arg1, caddr_t*, arg2, int, arg3);
784 }
785
786 //--- PRE(sys_execve) ---//
787 // Pre_read a char** argument.
pre_argv_envp(Addr a,ThreadId tid,Char * s1,Char * s2)788 static void pre_argv_envp(Addr a, ThreadId tid, Char* s1, Char* s2)
789 {
790 while (True) {
791 Addr a_deref;
792 Addr* a_p = (Addr*)a;
793 PRE_MEM_READ( s1, (Addr)a_p, sizeof(Addr) );
794 a_deref = *a_p;
795 if (0 == a_deref)
796 break;
797 PRE_MEM_RASCIIZ( s2, a_deref );
798 a += sizeof(char*);
799 }
800 }
simple_pre_exec_check(const HChar * exe_name,Bool trace_this_child)801 static SysRes simple_pre_exec_check ( const HChar* exe_name,
802 Bool trace_this_child )
803 {
804 Int fd, ret;
805 SysRes res;
806 Bool setuid_allowed;
807
808 // Check it's readable
809 res = VG_(open)(exe_name, VKI_O_RDONLY, 0);
810 if (res.isError) {
811 return res;
812 }
813 fd = res.res;
814 VG_(close)(fd);
815
816 // Check we have execute permissions. We allow setuid executables
817 // to be run only in the case when we are not simulating them, that
818 // is, they to be run natively.
819 setuid_allowed = trace_this_child ? False : True;
820 ret = VG_(check_executable)(NULL/*&is_setuid*/,
821 (HChar*)exe_name, setuid_allowed);
822 if (0 != ret) {
823 return VG_(mk_SysRes_Error)(ret);
824 }
825 return VG_(mk_SysRes_Success)(0);
826 }
PRE(sys_execve)827 PRE(sys_execve)
828 {
829 Char* path = NULL; /* path to executable */
830 Char** envp = NULL;
831 Char** argv = NULL;
832 Char** arg2copy;
833 Char* launcher_basename = NULL;
834 ThreadState* tst;
835 Int i, j, tot_args;
836 SysRes res;
837 Bool trace_this_child;
838
839 PRINT("sys_execve ( %#lx(%s), %#lx, %#lx )", ARG1, (Char*)ARG1, ARG2, ARG3);
840 PRE_REG_READ3(vki_off_t, "execve",
841 char *, filename, char **, argv, char **, envp);
842 PRE_MEM_RASCIIZ( "execve(filename)", ARG1 );
843 if (ARG2 != 0)
844 pre_argv_envp( ARG2, tid, "execve(argv)", "execve(argv[i])" );
845 if (ARG3 != 0)
846 pre_argv_envp( ARG3, tid, "execve(envp)", "execve(envp[i])" );
847
848 vg_assert(VG_(is_valid_tid)(tid));
849 tst = VG_(get_ThreadState)(tid);
850
851 /* Erk. If the exec fails, then the following will have made a
852 mess of things which makes it hard for us to continue. The
853 right thing to do is piece everything together again in
854 POST(execve), but that's close to impossible. Instead, we make
855 an effort to check that the execve will work before actually
856 doing it. */
857
858 /* Check that the name at least begins in client-accessible storage. */
859 /* XXX: causes execve to fail for non-memcheck tools, presumably
860 because ARG1 is thought to not to being in client-accessible
861 storage due to inadequate address space tracking. May or may
862 not be due to non-tracking of brk. */
863 //if (!VG_(am_is_valid_for_client)( ARG1, 1, VKI_PROT_READ )) {
864 // SET_STATUS_Failure( VKI_EFAULT );
865 // return;
866 //}
867 if (ARG1 == 0 /* obviously bogus */) {
868 SET_STATUS_Failure( VKI_EFAULT );
869 }
870
871 // Decide whether or not we want to follow along
872 trace_this_child = VG_(should_we_trace_this_child)( (HChar**)ARG2 );
873
874 // Do the important checks: it is a file, is executable, permissions are
875 // ok, etc.
876 res = simple_pre_exec_check( (const HChar*)ARG1, trace_this_child );
877 if (res.isError) {
878 SET_STATUS_Failure( res.err );
879 return;
880 }
881
882 /* If we're tracing the child, and the launcher name looks bogus
883 (possibly because launcher.c couldn't figure it out, see
884 comments therein) then we have no option but to fail. */
885 if (trace_this_child
886 && (VG_(name_of_launcher) == NULL
887 || VG_(name_of_launcher)[0] != '/')) {
888 SET_STATUS_Failure( VKI_ECHILD ); /* "No child processes" */
889 return;
890 }
891
892 /* After this point, we can't recover if the execve fails. */
893 VG_(debugLog)(1, "syswrap", "Exec of %s\n", (Char*)ARG1);
894
895 /* Resistance is futile. Nuke all other threads. POSIX mandates
896 this. (Really, nuke them all, since the new process will make
897 its own new thread.) */
898 VG_(nuke_all_threads_except)( tid, VgSrc_ExitThread );
899 VG_(reap_threads)(tid);
900
901 // Set up the child's exe path.
902 //
903 if (trace_this_child) {
904
905 // We want to exec the launcher. Get its pre-remembered path.
906 path = VG_(name_of_launcher);
907 // VG_(name_of_launcher) should have been acquired by m_main at
908 // startup.
909 vg_assert(path);
910
911 launcher_basename = VG_(strrchr)(path, '/');
912 if (launcher_basename == NULL || launcher_basename[1] == 0) {
913 launcher_basename = path; // hmm, tres dubious
914 } else {
915 launcher_basename++;
916 }
917
918 } else {
919 path = (Char*)ARG1;
920 }
921
922 // Set up the child's environment.
923 //
924 // Remove the valgrind-specific stuff from the environment so the
925 // child doesn't get vgpreload_core.so, vgpreload_<tool>.so, etc.
926 // This is done unconditionally, since if we are tracing the child,
927 // the child valgrind will set up the appropriate client environment.
928 // Nb: we make a copy of the environment before trying to mangle it
929 // as it might be in read-only memory (this was bug #101881).
930 //
931 // Then, if tracing the child, set VALGRIND_LIB for it.
932 //
933 if (ARG3 == 0) {
934 envp = NULL;
935 } else {
936 envp = VG_(env_clone)( (Char**)ARG3 );
937 if (envp == NULL) goto hosed;
938 VG_(env_remove_valgrind_env_stuff)( envp );
939 }
940
941 if (trace_this_child) {
942 // Set VALGRIND_LIB in ARG3 (the environment)
943 VG_(env_setenv)( &envp, VALGRIND_LIB, VG_(libdir));
944 }
945
946 // Set up the child's args. If not tracing it, they are
947 // simply ARG2. Otherwise, they are
948 //
949 // [launcher_basename] ++ VG_(args_for_valgrind) ++ [ARG1] ++ ARG2[1..]
950 //
951 // except that the first VG_(args_for_valgrind_noexecpass) args
952 // are omitted.
953 //
954 if (!trace_this_child) {
955 argv = (Char**)ARG2;
956 } else {
957 vg_assert( VG_(args_for_valgrind_noexecpass) >= 0 );
958 vg_assert( VG_(args_for_valgrind_noexecpass)
959 <= VG_(sizeXA)( VG_(args_for_valgrind) ) );
960 /* how many args in total will there be? */
961 // launcher basename
962 tot_args = 1;
963 // V's args
964 tot_args += VG_(sizeXA)( VG_(args_for_valgrind) );
965 tot_args -= VG_(args_for_valgrind_noexecpass);
966 // name of client exe
967 tot_args++;
968 // args for client exe, skipping [0]
969 arg2copy = (Char**)ARG2;
970 if (arg2copy && arg2copy[0]) {
971 for (i = 1; arg2copy[i]; i++)
972 tot_args++;
973 }
974 // allocate
975 argv = VG_(malloc)( "syswrap-aix5.pre_sys_execve.1",
976 (tot_args+1) * sizeof(HChar*) );
977 if (argv == 0) goto hosed;
978 // copy
979 j = 0;
980 argv[j++] = launcher_basename;
981 for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
982 if (i < VG_(args_for_valgrind_noexecpass))
983 continue;
984 argv[j++] = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
985 }
986 argv[j++] = (Char*)ARG1;
987 if (arg2copy && arg2copy[0])
988 for (i = 1; arg2copy[i]; i++)
989 argv[j++] = arg2copy[i];
990 argv[j++] = NULL;
991 // check
992 vg_assert(j == tot_args+1);
993 }
994
995 /* restore the DATA rlimit for the child */
996 VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
997
998 /*
999 Set the signal state up for exec.
1000
1001 We need to set the real signal state to make sure the exec'd
1002 process gets SIG_IGN properly.
1003
1004 Also set our real sigmask to match the client's sigmask so that
1005 the exec'd child will get the right mask. First we need to
1006 clear out any pending signals so they they don't get delivered,
1007 which would confuse things.
1008
1009 XXX This is a bug - the signals should remain pending, and be
1010 delivered to the new process after exec. There's also a
1011 race-condition, since if someone delivers us a signal between
1012 the sigprocmask and the execve, we'll still get the signal. Oh
1013 well.
1014 */
1015 {
1016 vki_sigset_t allsigs;
1017 vki_siginfo_t info;
1018
1019 for (i = 1; i < VG_(max_signal); i++) {
1020 struct vki_sigaction sa;
1021 VG_(do_sys_sigaction)(i, NULL, &sa);
1022 if (sa.ksa_handler == VKI_SIG_IGN)
1023 VG_(sigaction)(i, &sa, NULL);
1024 else {
1025 sa.ksa_handler = VKI_SIG_DFL;
1026 VG_(sigaction)(i, &sa, NULL);
1027 }
1028 }
1029
1030 VG_(sigfillset)(&allsigs);
1031 while(VG_(sigtimedwait_zero)(&allsigs, &info) > 0)
1032 ;
1033
1034 VG_(sigprocmask)(VKI_SIG_SETMASK, &tst->sig_mask, NULL);
1035 }
1036
1037 if (0) {
1038 Char **cpp;
1039 VG_(printf)("exec: %s\n", path);
1040 for (cpp = argv; cpp && *cpp; cpp++)
1041 VG_(printf)("argv: %s\n", *cpp);
1042 if (0)
1043 for (cpp = envp; cpp && *cpp; cpp++)
1044 VG_(printf)("env: %s\n", *cpp);
1045 }
1046
1047 SET_STATUS_from_SysRes(
1048 VG_(do_syscall3)(__NR_execve, (UWord)path, (UWord)argv, (UWord)envp)
1049 );
1050
1051 /* If we got here, then the execve failed. We've already made way
1052 too much of a mess to continue, so we have to abort. */
1053 hosed:
1054 vg_assert(FAILURE);
1055 VG_(message)(Vg_UserMsg, "execve(%#lx(%s), %#lx, %#lx) failed, errno %ld\n",
1056 ARG1, (Char*)ARG1, ARG2, ARG3, ERR);
1057 VG_(message)(Vg_UserMsg, "EXEC FAILED: I can't recover from "
1058 "execve() failing, so I'm dying.\n");
1059 VG_(message)(Vg_UserMsg, "Add more stringent tests in PRE(sys_execve), "
1060 "or work out how to recover.\n");
1061 VG_(exit)(101);
1062 }
1063
PRE(sys_finfo)1064 PRE(sys_finfo)
1065 {
1066 PRINT("finfo ( %#lx(%s), %ld, %#lx, %ld )",
1067 ARG1,(Char*)ARG1, ARG2, ARG3, ARG4);
1068 PRE_REG_READ4(int, "finfo",
1069 char*, Path1, int, cmd, void*, buffer, int, length);
1070 PRE_MEM_RASCIIZ( "finfo(Path1)", ARG1 );
1071 PRE_MEM_WRITE( "finfo(buffer)", ARG3, ARG4 );
1072 }
POST(sys_finfo)1073 POST(sys_finfo)
1074 {
1075 POST_MEM_WRITE( ARG3, ARG4 );
1076 }
1077
PRE(sys_fstatfs)1078 PRE(sys_fstatfs)
1079 {
1080 PRINT("sys_fstatfs ( %ld, %#lx )", ARG1, ARG2);
1081 PRE_REG_READ2(UWord, "fstatfs", UWord, fd, struct statfs *, buf);
1082 PRE_MEM_WRITE( "fstatfs(buf)", ARG2, sizeof(struct statfs) );
1083 }
POST(sys_fstatfs)1084 POST(sys_fstatfs)
1085 {
1086 POST_MEM_WRITE( ARG2, sizeof(struct statfs) );
1087 }
1088
PRE(sys_fstatx)1089 PRE(sys_fstatx)
1090 {
1091 PRINT("fstatx ( %ld, %#lx, %ld, %ld )", ARG1, ARG2, ARG3, ARG4 );
1092 PRE_REG_READ4(Word, "fstatx", UWord, fd, void*, buf,
1093 UWord, len, UWord, cmd);
1094 PRE_MEM_WRITE( "fstatx(buf)", ARG2, ARG3 );
1095 }
POST(sys_fstatx)1096 POST(sys_fstatx)
1097 {
1098 POST_MEM_WRITE( ARG2, ARG3 );
1099 }
1100
PRE(sys_fsync)1101 PRE(sys_fsync)
1102 {
1103 PRINT("fsync ( %ld )", ARG1);
1104 PRE_REG_READ1(int, "fsync", int, fd);
1105 }
1106
PRE(sys_getdirent)1107 PRE(sys_getdirent)
1108 {
1109 *flags |= SfMayBlock;
1110 /* this is pretty much like 'read':
1111 getdirent(fd, buffer, nbytes) -> # actually read */
1112 PRINT("getdirent ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
1113 PRE_REG_READ3(Word, "getdirent", UWord, fd, UChar*, buf, UWord, count);
1114 PRE_MEM_WRITE( "getdirent(buf)", ARG2, ARG3 );
1115 }
POST(sys_getdirent)1116 POST(sys_getdirent)
1117 {
1118 vg_assert(SUCCESS);
1119 POST_MEM_WRITE( ARG2, RES );
1120 }
1121
PRE(sys_getdirent64)1122 PRE(sys_getdirent64)
1123 {
1124 /* same as getdirent, from our point of view? */
1125 *flags |= SfMayBlock;
1126 /* this is pretty much like 'read':
1127 getdirent(fd, buffer, nbytes) -> # actually read */
1128 PRINT("getdirent64 ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
1129 PRE_REG_READ3(Word, "getdirent64", UWord, fd, UChar*, buf, UWord, count);
1130 PRE_MEM_WRITE( "getdirent64(buf)", ARG2, ARG3 );
1131 }
POST(sys_getdirent64)1132 POST(sys_getdirent64)
1133 {
1134 vg_assert(SUCCESS);
1135 POST_MEM_WRITE( ARG2, RES );
1136 }
1137
PRE(sys_getdomainname)1138 PRE(sys_getdomainname)
1139 {
1140 PRINT("getdomainname ( %#lx, %ld )", ARG1, ARG2 );
1141 PRE_MEM_WRITE( "getdomainname(buf)", ARG1, ARG2 );
1142 }
POST(sys_getdomainname)1143 POST(sys_getdomainname)
1144 {
1145 POST_MEM_WRITE( ARG1, ARG2 );
1146 }
1147
PRE(sys_getgidx)1148 PRE(sys_getgidx)
1149 {
1150 PRINT("getgidx ( %ld )", ARG1);
1151 PRE_REG_READ1(UInt, "getgidx", long, arg1);
1152 }
1153
PRE(sys_getgroups)1154 PRE(sys_getgroups)
1155 {
1156 PRINT("getgroups ( %ld, %#lx )", ARG1, ARG2);
1157 PRE_REG_READ2(long, "getgroups", int, size, gid_t *, list);
1158 if (ARG1 > 0)
1159 PRE_MEM_WRITE( "getgroups(list)", ARG2, ARG1 * sizeof(gid_t) );
1160 }
POST(sys_getgroups)1161 POST(sys_getgroups)
1162 {
1163 vg_assert(SUCCESS);
1164 if (ARG1 > 0 && RES > 0)
1165 POST_MEM_WRITE( ARG2, RES * sizeof(gid_t) );
1166 }
1167
PRE(sys_gethostname)1168 PRE(sys_gethostname)
1169 {
1170 PRINT("gethostname ( %#lx, %ld )", ARG1, ARG2);
1171 PRE_MEM_WRITE( "gethostname(buf)", ARG1, ARG2 );
1172 }
POST(sys_gethostname)1173 POST(sys_gethostname)
1174 {
1175 POST_MEM_WRITE( ARG1, ARG2 );
1176 }
1177
PRE(sys_getpriv)1178 PRE(sys_getpriv)
1179 {
1180 PRINT("getpriv (UNDOCUMENTED)(%ld, %#lx, %ld)", ARG1, ARG2, ARG3);
1181 PRE_REG_READ3(int, "getpriv", int, arg1, void*, arg2, int, arg3);
1182 PRE_MEM_WRITE( "getpriv(arg2)", ARG2, 8 );
1183 }
POST(sys_getpriv)1184 POST(sys_getpriv)
1185 {
1186 if (ARG2)
1187 POST_MEM_WRITE(ARG2, 8);
1188 }
1189
1190 /* Note that this is used for both sys_getprocs and sys_getprocs64. I
1191 think that's correct - from the man page, the calling conventions
1192 look identical. */
PRE(sys_getprocs)1193 PRE(sys_getprocs)
1194 {
1195 PRINT("getprocs ( %#lx, %ld, %#lx, %ld, %#lx, %ld )",
1196 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
1197 PRE_REG_READ6(int, "getprocs",
1198 void*, processbuffer, long, processize,
1199 void*, filebuffer, long, filesize,
1200 void*, indexpointer, long, count);
1201
1202 /* (processbuffer, processsize, filebuffer, filesize,
1203 indexpointer, count) */
1204 PRE_MEM_READ( "getprocs(IndexPointer)", ARG5, sizeof(UInt) );
1205 if (ARG1)
1206 PRE_MEM_WRITE( "getprocs(ProcessBuffer)", ARG1, ARG2 * ARG6 );
1207 if (ARG3)
1208 PRE_MEM_WRITE( "getprocs(FileBuffer)", ARG3, ARG4 * ARG6 );
1209 }
POST(sys_getprocs)1210 POST(sys_getprocs)
1211 {
1212 vg_assert(SUCCESS);
1213 if (ARG1)
1214 POST_MEM_WRITE( ARG1, ARG2 * ARG6 );
1215 if (ARG3)
1216 POST_MEM_WRITE( ARG3, ARG4 * ARG6 );
1217 }
1218
PRE(sys_getrpid)1219 PRE(sys_getrpid)
1220 {
1221 PRINT("getrpid ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
1222 PRE_REG_READ3(long, "getrpid", long, arg1, long, arg2, long, arg3);
1223 }
1224
PRE(sys_getsockopt)1225 PRE(sys_getsockopt)
1226 {
1227 PRINT("getsockopt ( %ld, %ld, %ld, %#lx, %#lx )",
1228 ARG1, ARG2, ARG3, ARG4, ARG5);
1229 PRE_REG_READ5(int, "getsockopt", int, socket, int, level,
1230 int, optionname,
1231 void*, optionval, int*, optionlen);
1232 if (ARG5) {
1233 PRE_MEM_READ( "getsockopt(optionlen)", ARG5, sizeof(UInt) );
1234 PRE_MEM_WRITE( "getsockopt(optionval)", ARG4, *(UInt*)ARG5 );
1235 }
1236 }
POST(sys_getsockopt)1237 POST(sys_getsockopt)
1238 {
1239 if (ARG5) {
1240 POST_MEM_WRITE( ARG5, sizeof(UInt) );
1241 POST_MEM_WRITE( ARG4, *(UInt*)ARG5 );
1242 }
1243 }
1244
PRE(sys_gettimerid)1245 PRE(sys_gettimerid)
1246 {
1247 PRINT("gettimerid ( %ld, %ld )", ARG1, ARG2);
1248 PRE_REG_READ2(int, "gettimerid", int, timertype, int, notifytype);
1249 }
1250
PRE(sys_getuidx)1251 PRE(sys_getuidx)
1252 {
1253 PRINT("getuidx ( %ld )", ARG1);
1254 PRE_REG_READ1(UInt, "getuidx", UInt, arg1);
1255 }
1256
PRE(sys_incinterval)1257 PRE(sys_incinterval)
1258 {
1259 PRINT("incinterval ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
1260 PRE_REG_READ3(int, "incinterval", int, timerid,
1261 struct itimerstruc_t*, value,
1262 struct itimerstruc_t*, ovalue);
1263 if (ARG2)
1264 PRE_MEM_READ( "incinterval(value)",
1265 ARG2, sizeof(struct itimerstruc_t));
1266 if (ARG3)
1267 PRE_MEM_WRITE( "incinterval(value)",
1268 ARG3, sizeof(struct itimerstruc_t));
1269 }
POST(sys_incinterval)1270 POST(sys_incinterval)
1271 {
1272 if (ARG3)
1273 POST_MEM_WRITE( ARG3, sizeof(struct itimerstruc_t));
1274 }
1275
PRE(sys_kfcntl)1276 PRE(sys_kfcntl)
1277 {
1278 *flags |= SfMayBlock;
1279 switch (ARG2) {
1280 // These ones ignore ARG3.
1281 case F_GETFD:
1282 case F_GETFL:
1283 case F_GETOWN:
1284 PRINT("kfcntl ( %ld, %ld )", ARG1,ARG2);
1285 PRE_REG_READ2(long, "fcntl", unsigned int, fd, unsigned int, cmd);
1286 break;
1287
1288 // These ones use ARG3 as "arg".
1289 case F_DUPFD:
1290 case F_SETFD:
1291 case F_SETFL:
1292 case F_SETOWN:
1293 PRINT("kfcntl[ARG3=='arg'] ( %ld, %ld, %ld )", ARG1,ARG2,ARG3);
1294 PRE_REG_READ3(long, "fcntl",
1295 unsigned int, fd, unsigned int, cmd, unsigned long, arg);
1296 break;
1297
1298 // These ones use ARG3 as "lock".
1299 # if !defined(VGP_ppc64_aix5)
1300 case F_GETLK:
1301 case F_SETLK:
1302 case F_SETLKW:
1303 # endif
1304 case F_GETLK64:
1305 case F_SETLK64:
1306 case F_SETLKW64:
1307 PRINT("kfcntl[ARG3=='lock'] ( %ld, %ld, %#lx )", ARG1,ARG2,ARG3);
1308 PRE_REG_READ3(long, "fcntl",
1309 unsigned int, fd, unsigned int, cmd,
1310 struct flock64 *, lock);
1311 if (ARG3 && (ARG2 == F_GETLK || ARG2 == F_GETLK64))
1312 PRE_MEM_READ( "kfcntl(F_GETLK)", ARG3, sizeof(struct flock64) );
1313 break;
1314 }
1315 }
POST(sys_kfcntl)1316 POST(sys_kfcntl)
1317 {
1318 // if (ARG2 == VKI_F_DUPFD) {
1319 // if (!ML_(fd_allowed)(RES, "fcntl(DUPFD)", tid, True)) {
1320 // VG_(close)(RES);
1321 // SET_STATUS_Failure( VKI_EMFILE );
1322 // } else {
1323 // if (VG_(clo_track_fds))
1324 // record_fd_open_named(tid, RES);
1325 // }
1326 // }
1327 if (ARG3 && (ARG2 == F_GETLK || ARG2 == F_GETLK64))
1328 POST_MEM_WRITE( ARG3, sizeof(struct flock64) );
1329 }
1330
1331 /* COG; can this be moved inside the pre-handler? */
1332 static vki_sigset_t fork_saved_mask;
PRE(sys_kfork)1333 PRE(sys_kfork) /* COPY OF GENERIC */
1334 {
1335 vki_sigset_t mask;
1336
1337 PRINT("kfork ( )");
1338 PRE_REG_READ0(long, "fork");
1339
1340 /* Block all signals during fork, so that we can fix things up in
1341 the child without being interrupted. */
1342 VG_(sigfillset)(&mask);
1343 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, &fork_saved_mask);
1344
1345 VG_(do_atfork_pre)(tid);
1346
1347 SET_STATUS_from_SysRes( VG_(do_syscall0)(__NR_fork) );
1348
1349 if (SUCCESS && RES == 0) {
1350 /* child */
1351 VG_(do_atfork_child)(tid);
1352
1353 /* restore signal mask */
1354 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
1355
1356 /* If --child-silent-after-fork=yes was specified, set the
1357 logging file descriptor to an 'impossible' value. This is
1358 noticed by send_bytes_to_logging_sink in m_libcprint.c, which
1359 duly stops writing any further logging output. */
1360 if (!VG_(logging_to_socket) && VG_(clo_child_silent_after_fork))
1361 VG_(clo_log_fd) = -1;
1362 }
1363 else
1364 if (SUCCESS && RES > 0) {
1365 /* parent */
1366 VG_(do_atfork_parent)(tid);
1367
1368 PRINT(" fork: process %d created child %lu\n", VG_(getpid)(), RES);
1369
1370 /* restore signal mask */
1371 VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
1372 }
1373 }
1374
PRE(sys_kftruncate)1375 PRE(sys_kftruncate)
1376 {
1377 PRINT("kftruncate (BOGUS HANDLER)");
1378 }
1379
PRE(sys_kgetsidx)1380 PRE(sys_kgetsidx)
1381 {
1382 PRINT("kgetsidx ( %ld )", ARG1);
1383 PRE_REG_READ1(Word, "kgetsidx", Word, arg1);
1384 }
1385
PRE(sys_kill)1386 PRE(sys_kill)
1387 {
1388 PRINT("kill ( %ld, %ld )", ARG1, ARG2);
1389 PRE_REG_READ2(int, "kill", int, pid, int, signal);
1390 }
1391
PRE(sys_kioctl)1392 PRE(sys_kioctl)
1393 {
1394 *flags |= SfMayBlock;
1395 PRINT("kioctl ( %ld, %#lx, %#lx, %#lx )", ARG1, ARG2, ARG3, ARG4);
1396 PRE_REG_READ4(Word, "ioctl", Word, fd,
1397 Word, command, Word, arg, Word, ext);
1398 switch (ARG2 /* request */) {
1399 case 0x5800/*TXISATTY*/:
1400 case 0x5801/*TXTTYNAME*/:
1401 break;
1402 case 0x412:/*no idea what any of these are*/
1403 case 0x430:
1404 case 0x431:
1405 case 0x432:
1406 case 0x441:
1407 case 0x442:
1408 case 0x462:
1409 case 0x480:
1410 case 0x482:
1411 case 0x738:
1412 case 0x736:
1413 case 0x73B:
1414 case 0x73C:
1415 case 0x73D:
1416 case 0x73E:
1417 case 0x5401:
1418 case 0x5403:
1419 case 0xFF01/*no_idea_at_all_what_this_is*/:
1420 break;
1421 /* We don't have any specific information on it, so
1422 try to do something reasonable based on direction and
1423 size bits.
1424
1425 According to Simon Hausmann, _IOC_READ means the kernel
1426 writes a value to the ioctl value passed from the user
1427 space and the other way around with _IOC_WRITE. */
1428 default: {
1429 UInt dir = _VKI_IOC_DIR(ARG2);
1430 UInt size = _VKI_IOC_SIZE(ARG2);
1431 if (VG_(strstr)(VG_(clo_sim_hints), "lax-ioctls") != NULL) {
1432 /*
1433 * Be very lax about ioctl handling; the only
1434 * assumption is that the size is correct. Doesn't
1435 * require the full buffer to be initialized when
1436 * writing. Without this, using some device
1437 * drivers with a large number of strange ioctl
1438 * commands becomes very tiresome.
1439 */
1440 } else if (/* size == 0 || */ dir == _VKI_IOC_NONE) {
1441 static Int moans = 5;
1442 if (moans > 0 && !VG_(clo_xml)) {
1443 moans--;
1444 VG_(message)(Vg_UserMsg,
1445 "Warning: noted but unhandled ioctl 0x%lx"
1446 " with no size/direction hints\n",
1447 ARG2);
1448 VG_(message)(Vg_UserMsg,
1449 " This could cause spurious value errors"
1450 " to appear.\n");
1451 VG_(message)(Vg_UserMsg,
1452 " See README_MISSING_SYSCALL_OR_IOCTL for "
1453 "guidance on writing a proper wrapper.\n" );
1454 }
1455 } else {
1456 if ((dir & _VKI_IOC_WRITE) && size > 0)
1457 PRE_MEM_READ( "ioctl(generic)", ARG3, size);
1458 if ((dir & _VKI_IOC_READ) && size > 0)
1459 PRE_MEM_WRITE( "ioctl(generic)", ARG3, size);
1460 }
1461 break;
1462 }
1463 } /* switch */
1464 }
POST(sys_kioctl)1465 POST(sys_kioctl)
1466 {
1467 switch (ARG2 /*request*/) {
1468 case 0xFF01:
1469 /* 100% kludge. I have no idea what this ioctl is. IOCINFO
1470 ? But at a guess I'd say it returns some kind of info
1471 from the kernel. */
1472 if (ARG3) POST_MEM_WRITE(ARG3, 16);
1473 break;
1474 case 0x738: /* Shows up in MPI applications. */
1475 if (ARG3) POST_MEM_WRITE(ARG3, 4*sizeof(Word));
1476 break;
1477 case 0x736: /* Shows up in MPI applications. */
1478 case 0x73B: /* Shows up in MPI applications. */
1479 case 0x73C: /* Shows up in MPI applications. */
1480 if (ARG3) POST_MEM_WRITE(ARG3, 16);
1481 /* in fact only 4 needed, but being conservative */
1482 break;
1483
1484 case 0x5401:
1485 /* some kind of tty thing */
1486 if (ARG3) POST_MEM_WRITE(ARG3, 32);
1487 break;
1488
1489 case 0x5801/*TXTTYNAME*/:
1490 /* who knows if this is right. Presumably an ascii string is
1491 written into the buffer specified by ARG3, but how long is
1492 that buffer? */
1493 if (ARG3) POST_MEM_WRITE(ARG3, 16);
1494 break;
1495
1496 case 0x412:
1497 case 0x430:
1498 case 0x431:
1499 case 0x432:
1500 case 0x441:
1501 case 0x442:
1502 case 0x462:
1503 case 0x480:
1504 case 0x482:
1505 case 0x73D:
1506 case 0x73E:
1507 case 0x5800/*TXISATTY*/:
1508 case 0x5403:
1509 break;
1510 /* We don't have any specific information on it, so
1511 try to do something reasonable based on direction and
1512 size bits.
1513
1514 According to Simon Hausmann, _IOC_READ means the kernel
1515 writes a value to the ioctl value passed from the user
1516 space and the other way around with _IOC_WRITE. */
1517 default: {
1518 UInt dir = _VKI_IOC_DIR(ARG2);
1519 UInt size = _VKI_IOC_SIZE(ARG2);
1520 if (size > 0 && (dir & _VKI_IOC_READ)
1521 && RES == 0
1522 && ARG3 != (Addr)NULL)
1523 POST_MEM_WRITE(ARG3, size);
1524 break;
1525 }
1526 }
1527 }
1528
PRE(sys_klseek)1529 PRE(sys_klseek)
1530 {
1531 PRINT("klseek ( %ld, %ld, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4);
1532 PRE_REG_READ4(long, "klseek",
1533 long, fd, long, offset, long, whence, void*, arg4);
1534 /* XXX: looks like 4th arg is a pointer to something. Is it
1535 read or written by the kernel? */
1536 }
1537
PRE(sys_knlist)1538 PRE(sys_knlist)
1539 {
1540 PRINT("knlist (BOGUS HANDLER)");
1541 }
1542
PRE(sys_kpread)1543 PRE(sys_kpread)
1544 {
1545 *flags |= SfMayBlock;
1546 PRINT("sys_kpread ( %ld, %#lx, %llu, %lld )",
1547 ARG1, ARG2, (ULong)ARG3, (ULong)ARG4);
1548 PRE_REG_READ4(ssize_t, "kpread",
1549 unsigned int, fd, char *, buf,
1550 vki_size_t, count, long, offset);
1551 PRE_MEM_WRITE( "kpread(buf)", ARG2, ARG3 );
1552 }
POST(sys_kpread)1553 POST(sys_kpread)
1554 {
1555 vg_assert(SUCCESS);
1556 if (RES > 0) {
1557 POST_MEM_WRITE( ARG2, RES );
1558 }
1559 }
1560
PRE(sys_kread)1561 PRE(sys_kread)
1562 {
1563 *flags |= SfMayBlock;
1564 PRINT("sys_read ( %ld, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
1565 PRE_REG_READ3(ssize_t, "read",
1566 unsigned int, fd, char *, buf, vki_size_t, count);
1567 //zz if (!ML_(fd_allowed)(ARG1, "read", tid, False))
1568 //zz SET_STATUS_Failure( VKI_EBADF );
1569 //zz else
1570 PRE_MEM_WRITE( "read(buf)", ARG2, ARG3 );
1571 }
POST(sys_kread)1572 POST(sys_kread)
1573 {
1574 vg_assert(SUCCESS);
1575 POST_MEM_WRITE( ARG2, RES );
1576 }
1577
PRE(sys_kreadv)1578 PRE(sys_kreadv)
1579 {
1580 Int i;
1581 struct vki_iovec * vec;
1582 *flags |= SfMayBlock;
1583 /* ssize_t readvx ( int fd, struct iovec*, int iovCount, int extension ) */
1584 PRINT("kreadv ( %ld, %#lx, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4);
1585 PRE_REG_READ4(ssize_t, "kreadv",
1586 unsigned long, fd, const struct iovec *, vector,
1587 unsigned long, iovCount, unsigned long, extension);
1588 //zz if (!ML_(fd_allowed)(ARG1, "readv", tid, False)) {
1589 //zz SET_STATUS_Failure( VKI_EBADF );
1590 //zz } else {
1591 PRE_MEM_READ( "kreadv(vector)", ARG2, ARG3 * sizeof(struct vki_iovec) );
1592 if (ARG2 != 0) {
1593 /* ToDo: don't do any of the following if the vector is invalid */
1594 vec = (struct vki_iovec *)ARG2;
1595 for (i = 0; i < (Int)ARG3; i++)
1596 PRE_MEM_WRITE( "kreadv(vector[...])",
1597 (Addr)vec[i].iov_base, vec[i].iov_len );
1598 }
1599 //zz }
1600 }
POST(sys_kreadv)1601 POST(sys_kreadv)
1602 {
1603 vg_assert(SUCCESS);
1604 if (RES > 0) {
1605 Int i;
1606 struct vki_iovec * vec = (struct vki_iovec *)ARG2;
1607 Int remains = RES;
1608
1609 /* RES holds the number of bytes read. */
1610 for (i = 0; i < (Int)ARG3; i++) {
1611 Int nReadThisBuf = vec[i].iov_len;
1612 if (nReadThisBuf > remains) nReadThisBuf = remains;
1613 POST_MEM_WRITE( (Addr)vec[i].iov_base, nReadThisBuf );
1614 remains -= nReadThisBuf;
1615 if (remains < 0) VG_(core_panic)("readv: remains < 0");
1616 }
1617 }
1618 }
1619
PRE(sys_kthread_ctl)1620 PRE(sys_kthread_ctl)
1621 {
1622 *flags |= SfMayBlock;
1623 PRINT("kthread_ctl (BOGUS HANDLER)");
1624 }
1625
PRE(sys_ktruncate)1626 PRE(sys_ktruncate)
1627 {
1628 PRINT("ktruncate( %#lx(%s), %lx, %lx )", ARG1,(Char*)ARG1, ARG2, ARG3 );
1629 PRE_REG_READ3(int, "ktruncate", char*, path, long, arg2, long, arg3 );
1630 PRE_MEM_RASCIIZ( "ktruncate(path)", ARG1 );
1631 }
1632
PRE(sys_kwaitpid)1633 PRE(sys_kwaitpid)
1634 {
1635 /* Note: args 1 and 2 (status, pid) opposite way round
1636 from generic handler */
1637 *flags |= SfMayBlock;
1638 PRINT("kwaitpid ( %#lx, %ld, %ld, %#lx, %#lx )", ARG1,ARG2,ARG3,ARG4,ARG5);
1639 PRE_REG_READ3(long, "waitpid",
1640 unsigned int *, status, int, pid, int, options);
1641
1642 if (ARG1 != (Addr)NULL)
1643 PRE_MEM_WRITE( "kwaitpid(status)", ARG1, sizeof(int) );
1644 }
POST(sys_kwaitpid)1645 POST(sys_kwaitpid)
1646 {
1647 if (ARG1 != (Addr)NULL)
1648 POST_MEM_WRITE( ARG1, sizeof(int) );
1649 }
1650
PRE(sys_kwrite)1651 PRE(sys_kwrite)
1652 {
1653 //zz Bool ok;
1654 *flags |= SfMayBlock;
1655 PRINT("sys_kwrite ( %ld, %#lx, %llu )", ARG1, ARG2, (ULong)ARG3);
1656 PRE_REG_READ3(ssize_t, "kwrite",
1657 unsigned int, fd, const char *, buf, vki_size_t, count);
1658 /* check to see if it is allowed. If not, try for an exemption from
1659 --sim-hints=enable-outer (used for self hosting). */
1660 //zz ok = ML_(fd_allowed)(ARG1, "write", tid, False);
1661 //zz if (!ok && ARG1 == 2/*stderr*/
1662 //zz && VG_(strstr)(VG_(clo_sim_hints),"enable-outer"))
1663 //zz ok = True;
1664 //zz if (!ok)
1665 //zz SET_STATUS_Failure( VKI_EBADF );
1666 //zz else
1667 PRE_MEM_READ( "write(buf)", ARG2, ARG3 );
1668 }
1669
PRE(sys_kwritev)1670 PRE(sys_kwritev)
1671 {
1672 PRINT("kwritev (BOGUS HANDLER)");
1673 }
1674
PRE(sys_listen)1675 PRE(sys_listen)
1676 {
1677 PRINT("listen (BOGUS HANDLER)");
1678 }
1679
PRE(sys_loadbind)1680 PRE(sys_loadbind)
1681 {
1682 PRINT("loadbind( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
1683 PRE_REG_READ3(int, "loadbind", int, flag,
1684 void*, ExportPointer, void*, ImportPointer);
1685 }
1686
PRE(sys_loadquery)1687 PRE(sys_loadquery)
1688 {
1689 /* loadquery ( int flags, void* buffer, unsigned int bufferlength ) */
1690 PRINT("loadquery ( %#lx, %#lx, %ld )", ARG1, ARG2, ARG3);
1691 PRE_MEM_WRITE( "loadquery(buf)", ARG2, ARG3 );
1692 }
POST(sys_loadquery)1693 POST(sys_loadquery)
1694 {
1695 vg_assert(SUCCESS);
1696 POST_MEM_WRITE( ARG2, ARG3 );
1697 }
1698
PRE(sys_lseek)1699 PRE(sys_lseek)
1700 {
1701 PRINT("lseek (%ld, %ld, %ld)", ARG1, ARG2, ARG3);
1702 PRE_REG_READ3(long, "lseek", long, fd, long, offset, long, whence);
1703 }
1704
PRE(sys_mkdir)1705 PRE(sys_mkdir)
1706 {
1707 PRINT("mkdir (%#lx(%s), %#lx)", ARG1,(Char*)ARG1, ARG2);
1708 PRE_REG_READ2(int, "mkdir", char*, path, int, mode);
1709 PRE_MEM_RASCIIZ( "mkdir(path)", ARG1 );
1710 }
1711
PRE(sys_mmap)1712 PRE(sys_mmap)
1713 {
1714 PRINT("mmap ( %#lx, %ld, %#lx, %#lx, %ld, %ld )",
1715 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1716 PRE_REG_READ6(void*, "mmap", void*, addr, int, len,
1717 int, prot, int, flags, int, fd, int, off);
1718 }
POST(sys_mmap)1719 POST(sys_mmap)
1720 {
1721 vg_assert(SUCCESS);
1722 Addr addr = (Addr)RES;
1723 UWord len = (UWord)ARG2;
1724 UWord prot = (UWord)ARG3;
1725 UWord flags = (UWord)ARG4;
1726 Bool r = (prot & VKI_PROT_READ) > 0;
1727 Bool w = (prot & VKI_PROT_WRITE) > 0;
1728 Bool x = (prot & VKI_PROT_EXEC) > 0;
1729 VG_TRACK( new_mem_mmap, addr, len, r,w,x, 0/*di_handle*/ );
1730 Bool d = VG_(am_notify_client_mmap)( addr, len, prot, flags,
1731 0/*fake fd*/, 0/*fake offset*/);
1732 if (d)
1733 VG_(discard_translations)( addr, len, "POST(sys_mmap)" );
1734 }
1735
PRE(sys_mntctl)1736 PRE(sys_mntctl)
1737 {
1738 PRINT("mntctl ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3 );
1739 PRE_REG_READ3(long, "mntctl", long, command, long, size, char*, buffer);
1740 PRE_MEM_WRITE( "mntctl(buffer)", ARG3, ARG2 );
1741 }
POST(sys_mntctl)1742 POST(sys_mntctl)
1743 {
1744 vg_assert(SUCCESS);
1745 if (RES == 0) {
1746 /* Buffer too small. First word is the real required size. */
1747 POST_MEM_WRITE( ARG3, sizeof(Word) );
1748 } else {
1749 /* RES is the number of struct vmount's written to the buf. But
1750 these are variable length and to find the end would require
1751 inspecting each in turn. So be simple and just mark the
1752 entire buffer as defined. */
1753 POST_MEM_WRITE( ARG3, ARG2 );
1754 }
1755 }
1756
PRE(sys_mprotect)1757 PRE(sys_mprotect)
1758 {
1759 PRINT("mprotect (BOGUS HANDLER)( %#lx, %ld, %#lx )", ARG1, ARG2, ARG3);
1760 PRE_REG_READ3(int, "mprotect", void*, addr, long, len, long, prot);
1761 }
POST(sys_mprotect)1762 POST(sys_mprotect)
1763 {
1764 Bool d;
1765 vg_assert(SUCCESS);
1766 Addr addr = ARG1;
1767 UWord len = ARG2;
1768 UWord prot = ARG3;
1769 d = VG_(am_notify_mprotect)( addr, len, prot );
1770 if (d)
1771 VG_(discard_translations)( addr, len, "POST(sys_mprotect)" );
1772 }
1773
PRE(sys_munmap)1774 PRE(sys_munmap)
1775 {
1776 PRINT("munmap ( %#lx, %ld )", ARG1, ARG2);
1777 PRE_REG_READ2(int, "munmap", void*, addr, long, len);
1778 }
POST(sys_munmap)1779 POST(sys_munmap)
1780 {
1781 Bool d;
1782 vg_assert(SUCCESS);
1783 Addr addr = ARG1;
1784 UWord len = ARG2;
1785 VG_TRACK( die_mem_munmap, addr, len );
1786 d = VG_(am_notify_munmap)( addr, len );
1787 if (d)
1788 VG_(discard_translations)( addr, len, "POST(sys_munmap)" );
1789 }
1790
PRE(sys_naccept)1791 PRE(sys_naccept)
1792 {
1793 PRINT("naccept (%ld, %#lx, %#lx)", ARG1, ARG2, ARG3);
1794 PRE_REG_READ3(int, "naccept", int, socket, char*, addr, int*, addrlen);
1795 PRE_MEM_READ( "naccept(addrlen)", ARG3, sizeof(UInt) );
1796 PRE_MEM_WRITE( "naccept(addr)", ARG2, *(UInt*)ARG3 );
1797 }
POST(sys_naccept)1798 POST(sys_naccept)
1799 {
1800 POST_MEM_WRITE( ARG3, sizeof(UInt) );
1801 POST_MEM_WRITE( ARG2, *(UInt*)ARG3 );
1802 }
1803
PRE(sys_ngetpeername)1804 PRE(sys_ngetpeername)
1805 {
1806 PRINT("ngetpeername ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
1807 PRE_REG_READ3(int, "ngetpeername", int, fd, char*, name, int*, namelen);
1808 PRE_MEM_READ( "ngetpeername(namelen)", ARG3, sizeof(UInt) );
1809 PRE_MEM_WRITE( "ngetpeername(name)", ARG2, *(UInt*)ARG3 );
1810 }
POST(sys_ngetpeername)1811 POST(sys_ngetpeername)
1812 {
1813 POST_MEM_WRITE( ARG3, sizeof(UInt) );
1814 POST_MEM_WRITE( ARG2, *(UInt*)ARG3 );
1815 }
1816
PRE(sys_ngetsockname)1817 PRE(sys_ngetsockname)
1818 {
1819 PRINT("ngetsockname ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
1820 PRE_REG_READ3(int, "ngetsockname", int, fd, char*, name, int*, namelen);
1821 PRE_MEM_READ( "ngetsockname(namelen)", ARG3, sizeof(UInt) );
1822 PRE_MEM_WRITE( "ngetsockname(name)", ARG2, *(UInt*)ARG3 );
1823 }
POST(sys_ngetsockname)1824 POST(sys_ngetsockname)
1825 {
1826 POST_MEM_WRITE( ARG3, sizeof(UInt) );
1827 POST_MEM_WRITE( ARG2, *(UInt*)ARG3 );
1828 }
1829
PRE(sys_nrecvfrom)1830 PRE(sys_nrecvfrom)
1831 {
1832 *flags |= SfMayBlock;
1833 PRINT("nrecvfrom ( %ld, %#lx, %ld, %ld, %#lx, %#lx )",
1834 ARG1, ARG2, ARG3, ARG4, ARG5, ARG6 );
1835 PRE_REG_READ6(ssize_t, "nrecvfrom",
1836 int, s, void*, buf, size_t, len, int, flags,
1837 void*, from, UInt*, fromlen);
1838 PRE_MEM_WRITE( "nrecvfrom(buf)", ARG2, ARG3 );
1839 if (ARG5) {
1840 PRE_MEM_READ( "nrecvfrom(fromlen)", ARG6, sizeof(UInt) );
1841 PRE_MEM_WRITE( "nrecvfrom(from)", ARG5, *(UInt*)ARG6 );
1842 }
1843 }
POST(sys_nrecvfrom)1844 POST(sys_nrecvfrom)
1845 {
1846 POST_MEM_WRITE( ARG2, RES );
1847 if (ARG5) {
1848 POST_MEM_WRITE(ARG6, sizeof(UInt));
1849 POST_MEM_WRITE(ARG5, *(UInt*)ARG6);
1850 }
1851 }
1852
PRE(sys_nrecvmsg)1853 PRE(sys_nrecvmsg)
1854 {
1855 *flags |= SfMayBlock;
1856 PRINT("nrecvmsg(BOGUS HANDLER)( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
1857 PRE_REG_READ3(long, "nrecvmsg", long, arg1, void*, arg2, long, arg3);
1858 }
1859
PRE(sys_nsendmsg)1860 PRE(sys_nsendmsg)
1861 {
1862 *flags |= SfMayBlock;
1863 PRINT("nsendmsg(BOGUS HANDLER)( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
1864 }
1865
PRE(sys_open)1866 PRE(sys_open) /* XXX CoG */
1867 {
1868 //zz HChar name[30];
1869 //zz SysRes sres;
1870
1871 if (ARG2 & VKI_O_CREAT) {
1872 // 3-arg version
1873 PRINT("sys_open ( %#lx(%s), %#lx, %ld )",ARG1,(Char*)ARG1,ARG2,ARG3);
1874 PRE_REG_READ3(long, "open",
1875 const char *, filename, int, flags, int, mode);
1876 } else {
1877 // 2-arg version
1878 PRINT("sys_open ( %#lx(%s), %#lx )",ARG1,(Char*)ARG1,ARG2);
1879 PRE_REG_READ2(long, "open",
1880 const char *, filename, int, flags);
1881 }
1882 PRE_MEM_RASCIIZ( "open(filename)", ARG1 );
1883
1884 //zz /* Handle the case where the open is of /proc/self/cmdline or
1885 //zz /proc/<pid>/cmdline, and just give it a copy of the fd for the
1886 //zz fake file we cooked up at startup (in m_main). Also, seek the
1887 //zz cloned fd back to the start. */
1888 //zz
1889 //zz VG_(sprintf)(name, "/proc/%d/cmdline", VG_(getpid)());
1890 //zz if (ML_(safe_to_deref)( (void*)ARG1, 1 )
1891 //zz && (VG_(strcmp)((Char *)ARG1, name) == 0
1892 //zz || VG_(strcmp)((Char *)ARG1, "/proc/self/cmdline") == 0)) {
1893 //zz sres = VG_(dup)( VG_(cl_cmdline_fd) );
1894 //zz SET_STATUS_from_SysRes( sres );
1895 //zz if (!sres.isError) {
1896 //zz OffT off = VG_(lseek)( sres.res, 0, VKI_SEEK_SET );
1897 //zz if (off < 0)
1898 //zz SET_STATUS_Failure( VKI_EMFILE );
1899 //zz }
1900 //zz return;
1901 //zz }
1902
1903 /* Otherwise handle normally */
1904 *flags |= SfMayBlock;
1905 }
POST(sys_open)1906 POST(sys_open)
1907 {
1908 vg_assert(SUCCESS);
1909 //zz if (!ML_(fd_allowed)(RES, "open", tid, True)) {
1910 //zz VG_(close)(RES);
1911 //zz SET_STATUS_Failure( VKI_EMFILE );
1912 //zz } else {
1913 //zz if (VG_(clo_track_fds))
1914 //zz ML_(record_fd_open_with_given_name)(tid, RES, (Char*)ARG1);
1915 //zz }
1916 }
1917
PRE(sys_pipe)1918 PRE(sys_pipe)
1919 {
1920 PRINT("sys_pipe ( %#lx )", ARG1);
1921 PRE_REG_READ1(int, "pipe", int *, filedes);
1922 PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
1923 }
POST(sys_pipe)1924 POST(sys_pipe)
1925 {
1926 //zz Int *p = (Int *)ARG1;
1927
1928 //zz if (!ML_(fd_allowed)(p[0], "pipe", tid, True) ||
1929 //zz !ML_(fd_allowed)(p[1], "pipe", tid, True)) {
1930 //zz VG_(close)(p[0]);
1931 //zz VG_(close)(p[1]);
1932 //zz SET_STATUS_Failure( VKI_EMFILE );
1933 //zz } else {
1934 POST_MEM_WRITE( ARG1, 2*sizeof(int) );
1935 //zz if (VG_(clo_track_fds)) {
1936 //zz ML_(record_fd_open_nameless)(tid, p[0]);
1937 //zz ML_(record_fd_open_nameless)(tid, p[1]);
1938 //zz }
1939 //zz }
1940 }
1941
PRE(sys_privcheck)1942 PRE(sys_privcheck)
1943 {
1944 PRINT("privcheck ( %ld )", ARG1);
1945 PRE_REG_READ1(int, "privcheck", int, arg1);
1946 }
1947
PRE(sys_readlink)1948 PRE(sys_readlink)
1949 {
1950 PRINT("readlink ( 0x%lx(%s),0x%lx,%ld )", ARG1,(Char*)ARG1, ARG2, ARG3);
1951 PRE_REG_READ3(long, "readlink",
1952 const char *, path, char *, buf, int, bufsiz);
1953 PRE_MEM_RASCIIZ( "readlink(path)", ARG1 );
1954 PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 );
1955 }
POST(sys_readlink)1956 POST(sys_readlink)
1957 {
1958 POST_MEM_WRITE( ARG2, RES + 1 );
1959 }
1960
PRE(sys_recv)1961 PRE(sys_recv)
1962 {
1963 *flags |= SfMayBlock;
1964 PRINT("recv ( %ld, %#lx, %ld, %ld )",
1965 ARG1, ARG2, ARG3, ARG4);
1966 PRE_REG_READ4(int, "recv", int, fd, void*, buf, int, len, int, flags);
1967 PRE_MEM_WRITE( "recv(buf)", ARG2, ARG3);
1968 }
POST(sys_recv)1969 POST(sys_recv)
1970 {
1971 if (RES > 0)
1972 POST_MEM_WRITE(ARG2, RES);
1973 }
1974
PRE(sys_rename)1975 PRE(sys_rename)
1976 {
1977 *flags |= SfMayBlock;
1978 PRINT( "rename ( %#lx(%s), %#lx(%s) )", ARG1,(Char*)ARG1, ARG2,(Char*)ARG2 );
1979 PRE_REG_READ2(int, "rename", char*, frompath, char*, topath);
1980 PRE_MEM_RASCIIZ( "rename(frompath)", ARG1 );
1981 PRE_MEM_RASCIIZ( "rename(topath)", ARG2 );
1982 }
1983
PRE(sys_sbrk)1984 PRE(sys_sbrk)
1985 {
1986 PRINT("sbrk (BOGUS HANDLER)( %#lx )", ARG1);
1987 PRE_REG_READ1(long, "sbrk", long, arg1);
1988 /* After a zero sbrk, disallow aspacem from doing sbrk, since libc
1989 might rely on the value returned by this syscall. */
1990 /* 1 Oct 06: not currently used (aspacemgr-aix5.c ignores it) */
1991 VG_(am_aix5_sbrk_allowed) = toBool(ARG1 != 0);
1992 /* Disallow libc from moving the brk backwards as that might trash
1993 SkPreAlloc sections acquired by aspacem from previous uses of
1994 sbrk. */
1995 if (ARG1 < 0)
1996 ARG1 = 0;
1997 /* Do this as a sync syscall, so the sbrk_allowed flag gets turned
1998 back on ASAP. Typically libc does sbrk(0) and then sbrk(x > 0)
1999 in quick succession. Although surely it should hold some kind
2000 of lock at that point, else it cannot safely use the result from
2001 the first sbrk call to influence the second one? */
2002 *flags &= ~SfMayBlock;
2003 }
POST(sys_sbrk)2004 POST(sys_sbrk)
2005 {
2006 vg_assert(SUCCESS);
2007 handle_sbrk(ARG1);
2008 }
2009
PRE(sys_sched_get_priority_max)2010 PRE(sys_sched_get_priority_max)
2011 {
2012 PRINT("sched_get_priority_max ( %ld )", ARG1);
2013 PRE_REG_READ1(int, "sched_get_priority_max", int, arg1);
2014 }
2015
PRE(sys_sem_destroy)2016 PRE(sys_sem_destroy)
2017 {
2018 PRINT("sem_destroy ( %#lx )", ARG1);
2019 PRE_REG_READ1(int, "sem_destroy", sem_t*, sem);
2020 PRE_MEM_READ( "sem_destroy(sem)", ARG1, sizeof(sem_t) );
2021 }
2022
PRE(sys_sem_init)2023 PRE(sys_sem_init)
2024 {
2025 PRINT("sem_init ( %#lx, %ld, %ld )", ARG1, ARG2, ARG3);
2026 PRE_REG_READ3(int, "sem_init", sem_t*, sem, int, pshared, int, value);
2027 PRE_MEM_WRITE( "sem_init(sem)", ARG1, sizeof(sem_t) );
2028 }
POST(sys_sem_init)2029 POST(sys_sem_init)
2030 {
2031 POST_MEM_WRITE( ARG1, sizeof(sem_t) );
2032 }
2033
PRE(sys_sem_post)2034 PRE(sys_sem_post)
2035 {
2036 PRINT("sem_post ( %#lx )", ARG1);
2037 PRE_REG_READ1(int, "sem_post", sem_t*, sem);
2038 PRE_MEM_READ("sem_post(sem)", ARG1, sizeof(sem_t));
2039 }
POST(sys_sem_post)2040 POST(sys_sem_post)
2041 {
2042 POST_MEM_WRITE(ARG1, sizeof(sem_t));
2043 }
2044
PRE(sys_send)2045 PRE(sys_send)
2046 {
2047 *flags |= SfMayBlock;
2048 PRINT("send (BOGUS HANDLER)( %ld, %#lx, %ld, %ld )",
2049 ARG1, ARG2, ARG3, ARG4);
2050 }
2051
PRE(sys_setgid)2052 PRE(sys_setgid)
2053 {
2054 PRINT("setgid ( %ld )", ARG1);
2055 PRE_REG_READ1(void, "setgid", int, uid);
2056 }
2057
PRE(sys_setsockopt)2058 PRE(sys_setsockopt)
2059 {
2060 PRINT("setsockopt ( %ld, %ld, %ld, %#lx, %ld )",
2061 ARG1,ARG2,ARG3,ARG4,ARG5 );
2062 PRE_REG_READ5(long, "setsockopt",
2063 long, socket, long, level, long, optionname,
2064 void*, optionvalue, long, optlen);
2065 if (ARG4)
2066 PRE_MEM_READ( "setsockopt(optionvalue)", ARG4, ARG5 );
2067 }
2068
PRE(sys_setuid)2069 PRE(sys_setuid)
2070 {
2071 PRINT("setuid ( %ld )", ARG1);
2072 PRE_REG_READ1(void, "setuid", int, uid);
2073 }
2074
get_shm_size(Word shmid)2075 static UWord get_shm_size ( Word shmid )
2076 {
2077 SysRes res;
2078 struct shmid_ds buf;
2079 vg_assert(__NR_AIX5_shmctl != __NR_AIX5_UNKNOWN);
2080 res = VG_(do_syscall3)(__NR_AIX5_shmctl, shmid, IPC_STAT, (UWord)&buf);
2081 if (0)
2082 VG_(printf)("XXX: shm_size(%ld) = %ld %ld\n", shmid, res.res, res.err);
2083 if (res.isError) {
2084 if (0)
2085 VG_(printf)("XXX: shm_size(shmid = %ld): FAILED\n", shmid);
2086 return 0* 4096;
2087 } else {
2088 return buf.shm_segsz;
2089 }
2090 /* fails with 22 and 13 (22 = EINVAL, Invalid argument,
2091 13 = EACCES, Permission denied) */
2092 /* shmat (4, 0x0, 0x1800) --> Success(0x40000000)
2093 XXX: shm_size(4) = -1 22
2094 shmat: seg size = 0
2095 XXX: shm_size(4) = -1 22
2096
2097 shmat (5, 0x0, 0x1800) --> Success(0x50000000)
2098 XXX: shm_size(5) = -1 13
2099 shmat: seg size = 0
2100 XXX: shm_size(5) = -1 13
2101
2102 shmat (4, 0x0, 0x1800) --> Success(0x40000000)
2103 XXX: shm_size(4) = -1 22
2104 shmat: seg size = 0
2105 XXX: shm_size(4) = -1 22
2106 */
2107 }
PRE(sys_shmat)2108 PRE(sys_shmat)
2109 {
2110 UWord segmentSize;
2111 /* void* shmat ( int shmid, const void* shmaddr, int flags ) */
2112 PRINT("shmat (%ld, %#lx, %#lx)", ARG1, ARG2, ARG3);
2113 PRE_REG_READ3(void*, "shmat", int, shmid, void*, shmaddr, int, flags);
2114 segmentSize = get_shm_size( ARG1 );
2115 if (0) VG_(printf)("shmat: seg size = %lu\n", segmentSize);
2116 }
POST(sys_shmat)2117 POST(sys_shmat)
2118 {
2119 UInt segmentSize;
2120 vg_assert(SUCCESS);
2121 vg_assert(RES != -1L);
2122 segmentSize = get_shm_size ( ARG1 );
2123 if ( segmentSize > 0 ) {
2124 UInt prot = VKI_PROT_READ|VKI_PROT_WRITE;
2125 Bool d;
2126
2127 if (ARG2 & SHM_RDONLY)
2128 prot &= ~VKI_PROT_WRITE;
2129
2130 d = VG_(am_notify_client_shmat)( RES, VG_PGROUNDUP(segmentSize), prot );
2131
2132 /* we don't distinguish whether it's read-only or
2133 * read-write -- it doesn't matter really. */
2134 VG_TRACK( new_mem_mmap, RES, segmentSize, True, True, False, 0/*di_handle*/ );
2135 if (d)
2136 VG_(discard_translations)( (Addr64)RES,
2137 (ULong)VG_PGROUNDUP(segmentSize),
2138 "ML_(generic_POST_sys_shmat)" );
2139 }
2140 }
2141
PRE(sys_shmctl)2142 PRE(sys_shmctl)
2143 {
2144 PRINT("shmctl ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3 );
2145 PRE_REG_READ3(int, "shmctl", int, shmid, int, command, void*, buffer);
2146 if (ARG3)
2147 PRE_MEM_WRITE( "shmctl(buffer)", ARG3, sizeof(struct shmid_ds) );
2148 }
POST(sys_shmctl)2149 POST(sys_shmctl)
2150 {
2151 if ((ARG3) && ARG2 == IPC_STAT)
2152 POST_MEM_WRITE( ARG3, sizeof(struct shmid_ds) );
2153 }
2154
PRE(sys_shmdt)2155 PRE(sys_shmdt)
2156 {
2157 PRINT("shmdt ( %#lx )", ARG1);
2158 PRE_REG_READ1(long, "shmdt", void*, address);
2159 }
POST(sys_shmdt)2160 POST(sys_shmdt)
2161 {
2162 NSegment const*const s = VG_(am_find_nsegment)(ARG1);
2163
2164 if (s != NULL) {
2165 Addr s_start = s->start;
2166 SizeT s_len = s->end+1 - s->start;
2167 Bool d;
2168
2169 vg_assert(s->kind == SkShmC && s->start == ARG1);
2170
2171 d = VG_(am_notify_munmap)(s_start, s_len);
2172 /* s is now invalid; do not use after here */
2173 VG_TRACK( die_mem_munmap, s_start, s_len );
2174 if (d)
2175 VG_(discard_translations)( (Addr64)s_start,
2176 (ULong)s_len,
2177 "ML_(generic_POST_sys_shmdt)" );
2178 }
2179 }
2180
PRE(sys_shmget)2181 PRE(sys_shmget)
2182 {
2183 PRINT("shmget ( %ld, %ld, %ld )", ARG1, ARG2, ARG3 );
2184 PRE_REG_READ3(int, "shmget", key_t, key, size_t, size, int, shmFlag);
2185 }
2186
PRE(sys_shutdown)2187 PRE(sys_shutdown)
2188 {
2189 PRINT("shutdown (BOGUS HANDLER)");
2190 }
2191
PRE(sys_sigcleanup)2192 PRE(sys_sigcleanup)
2193 {
2194 PRINT("sigcleanup (UNDOCUMENTED)");
2195 }
2196
PRE(sys_sigprocmask)2197 PRE(sys_sigprocmask)
2198 {
2199 PRINT("sigprocmask ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
2200 PRE_REG_READ3(long, "sigprocmask",
2201 int, how, vki_sigset_t *, set, vki_sigset_t *, oldset);
2202 if (ARG2 != 0)
2203 PRE_MEM_READ( "sigprocmask(set)", ARG2, sizeof(vki_sigset_t));
2204 if (ARG3 != 0)
2205 PRE_MEM_WRITE( "sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
2206
2207 SET_STATUS_from_SysRes(
2208 VG_(do_sys_sigprocmask) ( tid, ARG1, (vki_sigset_t*)ARG2,
2209 (vki_sigset_t*)ARG3 )
2210 );
2211
2212 if (SUCCESS)
2213 *flags |= SfPollAfter;
2214 }
POST(sys_sigprocmask)2215 POST(sys_sigprocmask)
2216 {
2217 vg_assert(SUCCESS);
2218 if (RES == 0 && ARG3 != 0)
2219 POST_MEM_WRITE( ARG3, sizeof(vki_sigset_t));
2220 }
2221
PRE(sys_socket)2222 PRE(sys_socket)
2223 {
2224 PRINT("socket ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
2225 PRE_REG_READ3(int, "socket", int, domain, int, type, int, protocol);
2226 }
2227
PRE(sys_statfs)2228 PRE(sys_statfs)
2229 {
2230 PRINT("sys_statfs ( %#lx(%s), %#lx )",ARG1,(Char*)ARG1,ARG2);
2231 PRE_REG_READ2(long, "statfs", const char *, path, struct statfs *, buf);
2232 PRE_MEM_RASCIIZ( "statfs(path)", ARG1 );
2233 PRE_MEM_WRITE( "statfs(buf)", ARG2, sizeof(struct statfs) );
2234 }
POST(sys_statfs)2235 POST(sys_statfs)
2236 {
2237 POST_MEM_WRITE( ARG2, sizeof(struct statfs) );
2238 }
2239
PRE(sys_statx)2240 PRE(sys_statx)
2241 {
2242 PRINT("statx ( %#lx(%s), %#lx, %ld, %ld )", ARG1,(Char*)ARG1,ARG2,ARG3,ARG4);
2243 PRE_MEM_RASCIIZ( "statx(file_name)", ARG1 );
2244 PRE_REG_READ4(Word, "statx", UWord, fd, void*, buf,
2245 UWord, len, UWord, cmd);
2246 PRE_MEM_WRITE( "statx(buf)", ARG2, ARG3 );
2247 }
POST(sys_statx)2248 POST(sys_statx)
2249 {
2250 POST_MEM_WRITE( ARG2, ARG3 );
2251 }
2252
PRE(sys_symlink)2253 PRE(sys_symlink)
2254 {
2255 PRINT("symlink (BOGUS HANDLER)");
2256 }
2257
PRE(sys_sys_parm)2258 PRE(sys_sys_parm)
2259 {
2260 PRINT("sys_parm (%ld, %ld, %#lx)", ARG1, ARG2, ARG3);
2261 PRE_REG_READ3(int, "sys_parm", int, cmd, int, cmdflag,
2262 struct vario*, parmp);
2263 /* this is a bit of a kludge, but if parmp has uninitialised areas
2264 and we're doing SYSP_SET, lots of errors will be tiresomely
2265 reported. Hence just ignore the definedness of the area and
2266 only check addressability. */
2267 PRE_MEM_WRITE( "sys_parm(parmp)", ARG3, sizeof(struct vario));
2268 }
POST(sys_sys_parm)2269 POST(sys_sys_parm)
2270 {
2271 if (ARG1 == SYSP_GET)
2272 POST_MEM_WRITE( ARG3, sizeof(struct vario) );
2273 }
2274
PRE(sys_sysconfig)2275 PRE(sys_sysconfig)
2276 {
2277 PRINT("sysconfig ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
2278 PRE_REG_READ3(int, "sysconfig", int, cmd, void*, parmp, int, parmlen);
2279 /* It may be that the area is read sometimes as well as written,
2280 but for the same reasons as sys_parm, just check addressibility,
2281 not definedness. */
2282 PRE_MEM_WRITE( "sysconfig(parmp)", ARG2, ARG3 );
2283 }
POST(sys_sysconfig)2284 POST(sys_sysconfig)
2285 {
2286 POST_MEM_WRITE( ARG2, ARG3 );
2287 }
2288
PRE(sys_thread_create)2289 PRE(sys_thread_create)
2290 {
2291 *flags |= SfMayBlock;
2292 PRINT("thread_create ( )");
2293 }
POST(sys_thread_create)2294 POST(sys_thread_create)
2295 {
2296 vg_assert(SUCCESS);
2297 if (0) VG_(printf)("new lwpid is %ld\n", RES);
2298
2299 /* Allocate a new thread slot (which sets it to VgTs_Init), and
2300 record the lwpid in it, so can later find it again when handling
2301 sys_thread_setstate for that lwpid. */
2302
2303 ThreadId ctid = VG_(alloc_ThreadState)();
2304 ThreadState* ctst = VG_(get_ThreadState)(ctid);
2305
2306 vg_assert(ctst->status == VgTs_Init);
2307
2308 { /* Clear all os_state fields except for the vg stack ones, so any
2309 existing stack gets reused. */
2310 Addr v_s_b = ctst->os_state.valgrind_stack_base;
2311 Addr v_s_i_SP = ctst->os_state.valgrind_stack_init_SP;
2312 VG_(memset)(&ctst->os_state, 0, sizeof(ThreadOSstate));
2313 ctst->os_state.valgrind_stack_base = v_s_b;
2314 ctst->os_state.valgrind_stack_init_SP = v_s_i_SP;
2315 }
2316 ctst->os_state.lwpid = RES;
2317 }
2318
PRE(sys_thread_init)2319 PRE(sys_thread_init)
2320 {
2321 *flags |= SfMayBlock;
2322 PRE_REG_READ2(long, "thread_init", long, arg1, long, arg2);
2323 PRINT("thread_init (BOGUS HANDLER) ( %#lx, %#lx )", ARG1, ARG2);
2324 }
2325
PRE(sys_thread_kill)2326 PRE(sys_thread_kill)
2327 {
2328 Int target_lwpid, my_lwpid;
2329 PRINT("thread_kill ( %ld, %ld )", ARG1, ARG2);
2330
2331 if ( ((Word)ARG1) == (Word)(-1)
2332 && ARG2 == VKI_SIGSEGV ) {
2333 /* too difficult to continue; give up. */
2334 ML_(aix5_set_threadstate_for_emergency_exit)
2335 (tid, "exiting due to thread_kill(..,SIGSEGV) to process");
2336 SET_STATUS_Success(0);
2337 return;
2338 }
2339
2340 /* Check to see if this kill gave us a pending signal */
2341 *flags |= SfPollAfter;
2342
2343 target_lwpid = (Int)ARG1;
2344 my_lwpid = VG_(gettid)();
2345 /* we still hold the lock. Do deadlock-avoidance stuff. */
2346 if (target_lwpid == my_lwpid) {
2347 /* sending a signal to myself, which may be fatal. Therefore
2348 drop the lock so that if the signal kills me, some other
2349 thread can pick it up. */
2350 *flags |= SfMayBlock;
2351 } else {
2352 /* sending a signal to some other thread, which may kill it;
2353 therefore I'd better hold on to the lock to ensure that the
2354 target doesn't get killed whilst holding it. */
2355 }
2356 }
2357
2358 /* thread_setmymask_fast is handled on a per platform basis */
2359
PRE(sys_thread_setmystate)2360 PRE(sys_thread_setmystate)
2361 {
2362 *flags |= SfMayBlock;
2363 /* args: struct tstate *, struct tstate *
2364 I assume: first is new state, if not NULL.
2365 Second is place to write the previous state, if not NULL.
2366 (in the style of sigaction) */
2367 PRINT("thread_setmystate (BOGUS HANDLER) ( %#lx, %#lx )",
2368 ARG1, ARG2 );
2369 PRE_REG_READ2(long, "thread_setmystate",
2370 struct tstate *, newstate,
2371 struct tstate *, oldstate );
2372 if (ARG1)
2373 PRE_MEM_READ( "thread_setmystate(arg1)", ARG1, sizeof(struct tstate) );
2374 if (ARG2)
2375 PRE_MEM_WRITE( "thread_setmystate(arg2)", ARG2, sizeof(struct tstate) );
2376 if (1 && VG_(clo_trace_syscalls) && ARG1)
2377 ML_(aix5debugstuff_show_tstate)(ARG1, "thread_setmystate (NEW)");
2378
2379 struct tstate* newts = (struct tstate*)ARG1;
2380 struct tstate* oldts = (struct tstate*)ARG2;
2381
2382 /* Are we just messing with the signal mask? If so intercept it
2383 and do it ourselves. Same idea as handling for
2384 thread_setmymask_fast in 32-bit mode. */
2385 if (newts && newts->flags == TSTATE_CHANGE_SIGMASK) {
2386 vki_sigset_t* newset = newts ? (vki_sigset_t*)&newts->sigmask : NULL;
2387 vki_sigset_t* oldset = oldts ? (vki_sigset_t*)&oldts->sigmask : NULL;
2388 SET_STATUS_from_SysRes(
2389 VG_(do_sys_sigprocmask) ( tid, VKI_SIG_SETMASK, newset, oldset )
2390 );
2391 *flags &= ~SfMayBlock;
2392 return;
2393 }
2394 }
POST(sys_thread_setmystate)2395 POST(sys_thread_setmystate)
2396 {
2397 if (ARG2)
2398 POST_MEM_WRITE( ARG2, sizeof(struct tstate) );
2399 if (0 && VG_(clo_trace_syscalls) && ARG2)
2400 ML_(aix5debugstuff_show_tstate)(ARG2, "thread_setmystate (OLD)");
2401 }
2402
PRE(sys_thread_setmystate_fast)2403 PRE(sys_thread_setmystate_fast)
2404 {
2405 UWord how = ARG1;
2406 /* args: ?? */
2407 PRINT("thread_setmystate_fast (BOGUS HANDLER)"
2408 "(%#lx,%#lx(%s),%#lx(%s))",
2409 ARG1,
2410 ARG2, ML_(aix5debugstuff_pc_to_fnname)(ARG2),
2411 ARG3, ML_(aix5debugstuff_pc_to_fnname)(ARG3)
2412 );
2413 PRE_REG_READ3(long, "thread_setmystate_fast",
2414 long, arg1, long, arg2, long, arg3);
2415 if (1 && VG_(clo_trace_syscalls))
2416 ML_(aix5debugstuff_show_tstate_flags)( how );
2417
2418 if (how & TSTATE_CHANGE_FLAGS) {
2419 /* Messing with cancellation type/state. Pay attention. */
2420 Bool async = (how & TSTATE_CANCEL_DEFER) == 0;
2421 Bool disabled = (how & TSTATE_CANCEL_DISABLE) > 0;
2422 ThreadState* tst = VG_(get_ThreadState)(tid);
2423 if (VG_(clo_trace_syscalls))
2424 VG_(printf)("(cancellation state -> %s %s)",
2425 async ? "ASYNC" : "DEFER",
2426 disabled ? "DISABLED" : " ENABLED");
2427 tst->os_state.cancel_async = async;
2428 tst->os_state.cancel_disabled = disabled;
2429 /* If cancellation has been enabled for this thread and there is
2430 a request outstanding, honour it now. */
2431 if ((!disabled)
2432 && tst->os_state.cancel_progress == Canc_Requested) {
2433 if (VG_(clo_trace_syscalls))
2434 VG_(printf)("(honouring previous cancellation request)");
2435 tst->os_state.cancel_progress = Canc_Actioned;
2436 Bool ok = ML_(aix5_force_thread_into_pthread_exit)(tid);
2437 if (!ok) {
2438 /* now at serious risk of deadlock/livelock. Give up
2439 rather than continue. */
2440 ML_(aix5_set_threadstate_for_emergency_exit)
2441 (tid, "pthread_cancel(case1): "
2442 "cannot find pthread_exit; aborting");
2443 SET_STATUS_Success(0);
2444 return;
2445 }
2446 }
2447 SET_STATUS_Success(0);
2448 return;
2449 }
2450
2451 /* In all other cases, hand to kernel. */
2452 *flags |= SfMayBlock;
2453 }
2454
2455 /* thread_setstate is handled in syswrap-ppc{32,64}-aix5.c. */
2456
PRE(sys_thread_terminate_unlock)2457 PRE(sys_thread_terminate_unlock)
2458 {
2459 ThreadState* tst;
2460 /* simple; just make this thread exit */
2461 PRINT("thread_terminate_unlock( %#lx )", ARG1);
2462 PRE_REG_READ1(void, "thread_terminate_unlock", void*, exitcode);
2463 tst = VG_(get_ThreadState)(tid);
2464 /* Drop the lock we were holding, since we're not really going to
2465 exit the host thread with thread_terminate_unlock. */
2466 if (0) VG_(printf)("XXXXX dropping lock\n");
2467 if (1) VG_(do_syscall1)(__NR_AIX5_thread_unlock, ARG1);
2468 /* Set the thread's status to be exiting, then claim that the
2469 syscall succeeded. */
2470 tst->exitreason = VgSrc_ExitThread;
2471 tst->os_state.exitcode = 0;
2472 SET_STATUS_Success(0);
2473 }
2474
PRE(sys_thread_tsleep)2475 PRE(sys_thread_tsleep)
2476 {
2477 *flags |= SfMayBlock;
2478 PRINT("thread_tsleep (BOGUS HANDLER)( %ld, %#lx, %#lx, %#lx )",
2479 ARG1, ARG2, ARG3, ARG4 );
2480 }
2481
PRE(sys_thread_tsleep_event)2482 PRE(sys_thread_tsleep_event)
2483 {
2484 *flags |= SfMayBlock;
2485 PRINT("thread_tsleep_event (UNDOCUMENTED)( %#lx, %#lx, %ld, %#lx )",
2486 ARG1, ARG2, ARG3, ARG4 );
2487 }
2488
PRE(sys_thread_twakeup)2489 PRE(sys_thread_twakeup)
2490 {
2491 *flags |= SfMayBlock;
2492 PRINT("thread_twakeup (BOGUS HANDLER)( tid=%ld, val=%#lx )", ARG1, ARG2 );
2493 }
2494
PRE(sys_thread_twakeup_event)2495 PRE(sys_thread_twakeup_event)
2496 {
2497 *flags |= SfMayBlock;
2498 PRINT("thread_twakeup_event (BOGUS HANDLER)( %#lx, %ld, %ld )",
2499 ARG1, ARG2, ARG3 );
2500 }
2501
PRE(sys_thread_unlock)2502 PRE(sys_thread_unlock)
2503 {
2504 *flags |= SfMayBlock;
2505 PRINT("thread_unlock (BOGUS HANDLER)" );
2506 }
2507
PRE(sys_thread_waitlock)2508 PRE(sys_thread_waitlock)
2509 {
2510 *flags |= SfMayBlock;
2511 PRINT("thread_waitlock (BOGUS HANDLER)" );
2512 }
2513
PRE(sys_thread_waitlock_)2514 PRE(sys_thread_waitlock_)
2515 {
2516 *flags |= SfMayBlock;
2517 PRINT("thread_waitlock_ (BOGUS HANDLER)" );
2518 }
2519
PRE(sys_times)2520 PRE(sys_times)
2521 {
2522 PRINT("times ( %#lx )", ARG1);
2523 PRE_REG_READ1(long, "times", struct tms *, buffer);
2524 PRE_MEM_WRITE("times(buf)", ARG1, sizeof(struct tms) );
2525 }
POST(sys_times)2526 POST(sys_times)
2527 {
2528 POST_MEM_WRITE( ARG1, sizeof(struct tms) );
2529 }
2530
PRE(sys_umask)2531 PRE(sys_umask)
2532 {
2533 PRINT("umask (BOGUS HANDLER)");
2534 }
2535
PRE(sys_uname)2536 PRE(sys_uname)
2537 {
2538 PRINT("uname ( %#lx )", ARG1);
2539 PRE_MEM_WRITE( "uname(Name)", ARG1, sizeof(struct utsname));
2540 }
POST(sys_uname)2541 POST(sys_uname)
2542 {
2543 vg_assert(SUCCESS);
2544 POST_MEM_WRITE( ARG1, sizeof(struct utsname));
2545 }
2546
PRE(sys_unlink)2547 PRE(sys_unlink)
2548 {
2549 PRINT("unlink ( %#lx(%s) )", ARG1, (Char*)ARG1 );
2550 PRE_REG_READ1(int, "unlink", char*, path);
2551 PRE_MEM_RASCIIZ( "unlink(path)", ARG1 );
2552 }
2553
PRE(sys_utimes)2554 PRE(sys_utimes)
2555 {
2556 PRINT("utimes ( %#lx(%s), %#lx )", ARG1,(Char*)ARG1, ARG2);
2557 PRE_REG_READ2(int, "utimes", char*, path, struct timeval*, times);
2558 PRE_MEM_RASCIIZ( "utimes(path)", ARG1 );
2559 PRE_MEM_READ( "utimes(times)", ARG2, 2 * sizeof(struct vki_timeval) );
2560 }
2561
PRE(sys_vmgetinfo)2562 PRE(sys_vmgetinfo)
2563 {
2564 PRINT("vmgetinfo ( %#lx, %ld, %ld )", ARG1, ARG2, ARG3 );
2565 PRE_REG_READ3(int, "vmgetinfo", void*, out, int, command, int, arg);
2566 /* It looks like libc's vmgetinfo just hands stuff through to the
2567 syscall. The man page says that the interpretation of ARG3(arg)
2568 depends on ARG2(cmd); nevertheless in all cases basically this
2569 writes the buffer (ARG1, ARG3). */
2570 PRE_MEM_WRITE("vmgetinfo(buf)", ARG1, ARG3);
2571 }
POST(sys_vmgetinfo)2572 POST(sys_vmgetinfo)
2573 {
2574 vg_assert(SUCCESS);
2575 POST_MEM_WRITE(ARG1, ARG3);
2576 }
2577
PRE(sys_yield)2578 PRE(sys_yield)
2579 {
2580 *flags |= SfMayBlock;
2581 PRINT("yield ( )");
2582 }
2583
2584 #undef PRE
2585 #undef POST
2586
2587 #endif // defined(VGO_aix5)
2588
2589 /*--------------------------------------------------------------------*/
2590 /*--- end ---*/
2591 /*--------------------------------------------------------------------*/
2592