2 /*--------------------------------------------------------------------*/
3 /*--- Solaris-specific syscalls, etc. syswrap-solaris.c ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2011-2017 Petr Pavlu
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, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
29 /* Copyright 2013-2017, Ivo Raisr <ivosh@ivosh.net>. */
31 /* Copyright 2015-2017, Tomas Jedlicka <jedlickat@gmail.com>. */
33 /* Copyright 2013, OmniTI Computer Consulting, Inc. All rights reserved. */
35 #if defined(VGO_solaris)
37 #include "libvex_guest_offsets.h"
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_debuglog.h"
45 #include "pub_core_clientstate.h"
46 #include "pub_core_gdbserver.h"
47 #include "pub_core_inner.h"
48 #include "pub_core_libcassert.h"
49 #include "pub_core_libcbase.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_machine.h" // VG_(get_SP)
55 #include "pub_core_mallocfree.h"
56 #include "pub_core_options.h"
57 #include "pub_core_tooliface.h"
58 #include "pub_core_transtab.h" // VG_(discard_translations)
59 #include "pub_core_scheduler.h"
60 #include "pub_core_sigframe.h"
61 #include "pub_core_signals.h"
62 #include "pub_core_stacks.h"
63 #include "pub_core_syscall.h"
64 #include "pub_core_syswrap.h"
65 #include "pub_core_ume.h"
66 #if defined(ENABLE_INNER_CLIENT_REQUEST)
67 #include "pub_core_clreq.h"
70 #include "priv_types_n_macros.h"
71 #include "priv_syswrap-generic.h"
72 #include "priv_syswrap-main.h"
73 #include "priv_syswrap-solaris.h"
75 /* Return the number of non-dead and daemon threads.
76 count_daemon == True: count daemon threads
77 count_daemon == False: count non-daemon threads */
78 static UInt
count_living_daemon_threads(Bool count_daemon
)
81 for (ThreadId tid
= 1; tid
< VG_N_THREADS
; tid
++)
82 if (VG_(threads
)[tid
].status
!= VgTs_Empty
&&
83 VG_(threads
)[tid
].status
!= VgTs_Zombie
&&
84 VG_(threads
)[tid
].os_state
.daemon_thread
== count_daemon
)
90 /* Note: The following functions (thread_wrapper, run_a_thread_NORETURN,
91 ML_(start_thread_NORETURN), ML_(allocstack) and
92 VG_(main_thread_wrapper_NORETURN)) are based on the code in
93 syswrap-linux.c. Keep them synchronized! */
95 /* Run a thread from beginning to end and return the thread's
96 scheduler-return-code. */
97 static VgSchedReturnCode
thread_wrapper(Word
/*ThreadId*/ tidW
)
99 VgSchedReturnCode ret
;
100 ThreadId tid
= (ThreadId
)tidW
;
101 Int lwpid
= VG_(gettid
)();
102 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
104 VG_(debugLog
)(1, "syswrap-solaris",
105 "thread_wrapper(tid=%u,lwpid=%d): entry\n",
108 vg_assert(tst
->status
== VgTs_Init
);
110 /* Make sure we get the CPU lock before doing anything significant. */
111 VG_(acquire_BigLock
)(tid
, "thread_wrapper(starting new thread)");
114 VG_(printf
)("thread tid %u started: stack = %p\n", tid
, (void *)&tid
);
116 /* Make sure error reporting is enabled in the new thread. */
117 tst
->err_disablement_level
= 0;
120 VG_TRACK(pre_thread_first_insn
, tid
);
122 /* For newly created threads, VG_TRACK(pre_thread_first_insn, tid) is
123 invoked later from PRE(sys_getsetcontext)() when setucontext()
124 called from _thrp_setup() concludes new thread setup. Invoking it
125 here would be way too early - new thread has no stack, yet. */
128 tst
->os_state
.lwpid
= lwpid
;
129 tst
->os_state
.threadgroup
= VG_(getpid
)();
131 /* Thread created with all signals blocked; scheduler will set the
134 ret
= VG_(scheduler
)(tid
);
136 vg_assert(VG_(is_exiting
)(tid
));
138 vg_assert(tst
->status
== VgTs_Runnable
);
139 vg_assert(VG_(is_running_thread
)(tid
));
141 VG_(debugLog
)(1, "syswrap-solaris",
142 "thread_wrapper(tid=%u,lwpid=%d): exit, schedreturncode %s\n",
143 tid
, lwpid
, VG_(name_of_VgSchedReturnCode
)(ret
));
145 /* Return to caller, still holding the lock. */
149 /* Run a thread all the way to the end, then do appropriate exit actions
150 (this is the last-one-out-turn-off-the-lights bit). */
151 static void run_a_thread_NORETURN(Word tidW
)
153 ThreadId tid
= (ThreadId
)tidW
;
154 VgSchedReturnCode src
;
157 #ifdef ENABLE_INNER_CLIENT_REQUEST
158 Int registered_vgstack_id
;
161 VG_(debugLog
)(1, "syswrap-solaris",
162 "run_a_thread_NORETURN(tid=%u): pre-thread_wrapper\n",
165 tst
= VG_(get_ThreadState
)(tid
);
168 /* A thread has two stacks:
169 * the simulated stack (used by the synthetic cpu. Guest process
170 is using this stack).
171 * the valgrind stack (used by the real cpu. Valgrind code is running
173 When Valgrind runs as an inner, it must signal that its (real) stack
174 is the stack to use by the outer to e.g. do stacktraces.
177 (registered_vgstack_id
178 = VALGRIND_STACK_REGISTER(tst
->os_state
.valgrind_stack_base
,
179 tst
->os_state
.valgrind_stack_init_SP
));
181 /* Run the thread all the way through. */
182 src
= thread_wrapper(tid
);
184 VG_(debugLog
)(1, "syswrap-solaris",
185 "run_a_thread_NORETURN(tid=%u): post-thread_wrapper\n",
188 c
= count_living_daemon_threads(False
);
189 vg_assert(c
>= 1); /* Stay sane. */
191 /* Tell the tool that schedctl data belonging to this thread are gone. */
192 Addr a
= tst
->os_state
.schedctl_data
;
194 VG_TRACK(die_mem_munmap
, a
, sizeof(struct vki_sc_shared
));
196 /* Deregister thread's stack. */
197 if (tst
->os_state
.stk_id
!= NULL_STK_ID
)
198 VG_(deregister_stack
)(tst
->os_state
.stk_id
);
200 /* Tell the tool this thread is exiting. */
201 VG_TRACK(pre_thread_ll_exit
, tid
);
203 /* If the thread is exiting with errors disabled, complain loudly;
204 doing so is bad (does the user know this has happened?) Also, in all
205 cases, be paranoid and clear the flag anyway so that the thread slot is
206 safe in this respect if later reallocated. This should be unnecessary
207 since the flag should be cleared when the slot is reallocated, in
209 if (tst
->err_disablement_level
> 0) {
211 "WARNING: exiting thread has error reporting disabled.\n"
212 "WARNING: possibly as a result of some mistake in the use\n"
213 "WARNING: of the VALGRIND_DISABLE_ERROR_REPORTING macros.\n"
216 1, "syswrap-solaris",
217 "run_a_thread_NORETURN(tid=%u): "
218 "WARNING: exiting thread has err_disablement_level = %u\n",
219 tid
, tst
->err_disablement_level
222 tst
->err_disablement_level
= 0;
225 UInt daemon_threads
= count_living_daemon_threads(True
);
226 if (daemon_threads
== 0)
227 VG_(debugLog
)(1, "syswrap-solaris",
228 "run_a_thread_NORETURN(tid=%u): "
229 "last one standing\n",
232 VG_(debugLog
)(1, "syswrap-solaris",
233 "run_a_thread_NORETURN(tid=%u): "
234 "last non-daemon thread standing "
235 "[daemon threads=%u]\n",
236 tid
, daemon_threads
);
238 /* We are the last non-daemon thread standing. Keep hold of the lock and
239 carry on to show final tool results, then exit the entire system.
240 Use the continuation pointer set at startup in m_main. */
241 if ((src
== VgSrc_ExitThread
) && (daemon_threads
> 0))
242 src
= VgSrc_ExitProcess
;
243 (*VG_(address_of_m_main_shutdown_actions_NORETURN
))(tid
, src
);
246 VG_(debugLog
)(1, "syswrap-solaris",
247 "run_a_thread_NORETURN(tid=%u): "
248 "not last one standing\n",
251 /* OK, thread is dead, but others still exist. Just exit. */
253 /* This releases the run lock. */
254 VG_(exit_thread
)(tid
);
255 vg_assert(tst
->status
== VgTs_Zombie
);
256 vg_assert(sizeof(tst
->status
) == 4);
258 INNER_REQUEST(VALGRIND_STACK_DEREGISTER(registered_vgstack_id
));
260 /* We have to use this sequence to terminate the thread to
261 prevent a subtle race. If VG_(exit_thread)() had left the
262 ThreadState as Empty, then it could have been reallocated, reusing
263 the stack while we're doing these last cleanups. Instead,
264 VG_(exit_thread) leaves it as Zombie to prevent reallocation. We
265 need to make sure we don't touch the stack between marking it Empty
266 and exiting. Hence the assembler. */
267 #if defined(VGP_x86_solaris)
268 /* Luckily lwp_exit doesn't take any arguments so we don't have to mess
270 __asm__
__volatile__ (
271 "movl %[EMPTY], %[status]\n" /* set tst->status = VgTs_Empty */
272 "movl $"VG_STRINGIFY(__NR_lwp_exit
)", %%eax\n"
273 "int $0x91\n" /* lwp_exit() */
274 : [status
] "=m" (tst
->status
)
275 : [EMPTY
] "n" (VgTs_Empty
)
276 : "eax", "edx", "cc", "memory");
277 #elif defined(VGP_amd64_solaris)
278 __asm__
__volatile__ (
279 "movl %[EMPTY], %[status]\n" /* set tst->status = VgTs_Empty */
280 "movq $"VG_STRINGIFY(__NR_lwp_exit
)", %%rax\n"
281 "syscall\n" /* lwp_exit() */
282 : [status
] "=m" (tst
->status
)
283 : [EMPTY
] "n" (VgTs_Empty
)
284 : "rax", "rdx", "cc", "memory");
286 # error "Unknown platform"
289 VG_(core_panic
)("Thread exit failed?\n");
296 Word
ML_(start_thread_NORETURN
)(void *arg
)
298 ThreadState
*tst
= (ThreadState
*)arg
;
299 ThreadId tid
= tst
->tid
;
301 run_a_thread_NORETURN((Word
)tid
);
306 /* Allocate a stack for this thread, if it doesn't already have one.
307 They're allocated lazily, and never freed. Returns the initial stack
308 pointer value to use, or 0 if allocation failed. */
309 Addr
ML_(allocstack
)(ThreadId tid
)
311 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
315 /* Either the stack_base and stack_init_SP are both zero (in which
316 case a stack hasn't been allocated) or they are both non-zero,
317 in which case it has. */
319 if (tst
->os_state
.valgrind_stack_base
== 0)
320 vg_assert(tst
->os_state
.valgrind_stack_init_SP
== 0);
322 if (tst
->os_state
.valgrind_stack_base
!= 0)
323 vg_assert(tst
->os_state
.valgrind_stack_init_SP
!= 0);
325 /* If no stack is present, allocate one. */
327 if (tst
->os_state
.valgrind_stack_base
== 0) {
328 stack
= VG_(am_alloc_VgStack
)( &initial_SP
);
330 tst
->os_state
.valgrind_stack_base
= (Addr
)stack
;
331 tst
->os_state
.valgrind_stack_init_SP
= initial_SP
;
336 VG_(printf
)("stack for tid %u at %p; init_SP=%p\n",
338 (void*)tst
->os_state
.valgrind_stack_base
,
339 (void*)tst
->os_state
.valgrind_stack_init_SP
);
341 return tst
->os_state
.valgrind_stack_init_SP
;
344 /* Allocate a stack for the main thread, and run it all the way to the
345 end. Although we already have a working VgStack (VG_(interim_stack)) it's
346 better to allocate a new one, so that overflow detection works uniformly
347 for all threads. Also initialize the GDT (for normal threads, this is done
348 in the PRE wrapper of lwp_create). */
349 void VG_(main_thread_wrapper_NORETURN
)(ThreadId tid
)
353 VG_(debugLog
)(1, "syswrap-solaris",
354 "entering VG_(main_thread_wrapper_NORETURN)\n");
356 sp
= ML_(allocstack
)(tid
);
357 #if defined(ENABLE_INNER_CLIENT_REQUEST)
359 // we must register the main thread stack before the call
360 // to ML_(call_on_new_stack_0_1), otherwise the outer valgrind
361 // reports 'write error' on the non registered stack.
362 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
365 VALGRIND_STACK_REGISTER(tst
->os_state
.valgrind_stack_base
,
366 tst
->os_state
.valgrind_stack_init_SP
));
370 #if defined(VGP_x86_solaris)
372 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
373 ML_(setup_gdt
)(&tst
->arch
.vex
);
374 ML_(update_gdt_lwpgs
)(tid
);
376 #elif defined(VGP_amd64_solaris)
379 # error "Unknown platform"
382 /* If we can't even allocate the first thread's stack, we're hosed.
384 vg_assert2(sp
!= 0, "Cannot allocate main thread's stack.");
386 /* Shouldn't be any other threads around yet. */
387 vg_assert(VG_(count_living_threads
)() == 1);
389 ML_(call_on_new_stack_0_1
)(
390 (Addr
)sp
, /* stack */
391 0, /* bogus return address */
392 run_a_thread_NORETURN
, /* fn to call */
393 (Word
)tid
/* arg to give it */
400 /* Deallocate the GDT for a thread. */
401 void VG_(cleanup_thread
)(ThreadArchState
*arch
)
403 #if defined(VGP_x86_solaris)
404 ML_(cleanup_gdt
)(&arch
->vex
);
405 #elif defined(VGP_amd64_solaris)
408 # error "Unknown platform"
413 * Notify core about spring cleaning of schedctl data pages for all threads
414 * in child post-fork handler. Libc will issue new schedctl syscalls for threads
415 * in the child when needs arise.
417 * See also POST(schedctl) and run_a_thread_NORETURN() when a thread exits.
419 static void clean_schedctl_data(ThreadId tid
)
422 for (i
= 0; i
< VG_N_THREADS
; i
++) {
423 ThreadState
*tst
= &VG_(threads
)[i
];
424 if (tst
->status
!= VgTs_Empty
) {
425 Addr a
= tst
->os_state
.schedctl_data
;
427 tst
->os_state
.schedctl_data
= 0;
429 if (VG_(am_find_anon_segment
)(a
))
430 VG_(am_notify_munmap
)(a
, VKI_PAGE_SIZE
);
436 void VG_(syswrap_init
)(void)
438 VG_(atfork
)(NULL
, NULL
, clean_schedctl_data
);
441 /* Changes ownership of a memory mapping shared between kernel and the client
442 process. This mapping should have already been pre-arranged during process
443 address space initialization happening in kernel. Valgrind on startup created
444 a segment for this mapping categorized as Valgrind's owned anonymous.
445 Size of this mapping typically varies among Solaris versions but should be
447 If 'once_only' is 'True', it is expected this function is called once only
448 and the mapping ownership has not been changed, yet [useful during
449 initialization]. If 'False', this function can be called many times but does
450 change ownership only upon the first invocation [useful in syscall wrappers].
452 void VG_(change_mapping_ownership
)(Addr addr
, Bool once_only
)
454 const NSegment
*seg
= VG_(am_find_anon_segment
)(addr
);
455 vg_assert(seg
!= NULL
);
456 vg_assert(seg
->start
== addr
);
457 vg_assert(VG_IS_PAGE_ALIGNED(seg
->start
));
458 vg_assert(VG_IS_PAGE_ALIGNED(seg
->end
+ 1));
459 SizeT size
= seg
->end
- seg
->start
+ 1;
462 Bool do_change
= False
;
464 vg_assert(VG_(am_is_valid_for_valgrind
)(addr
, size
, VKI_PROT_READ
));
467 if (!VG_(am_is_valid_for_client
)(addr
, size
, VKI_PROT_READ
))
472 Bool change_ownership_OK
= VG_(am_change_ownership_v_to_c
)(addr
, size
);
473 vg_assert(change_ownership_OK
);
475 /* Tell the tool about just discovered mapping. */
476 VG_TRACK(new_mem_startup
,
478 True
/* readable? */,
479 False
/* writable? */,
480 False
/* executable? */,
485 /* Calculate the Fletcher-32 checksum of a given buffer. */
486 UInt
ML_(fletcher32
)(UShort
*buf
, SizeT blocks
)
492 for (i
= 0; i
< blocks
; i
++) {
493 sum1
= (sum1
+ buf
[i
]) % 0xffff;
494 sum2
= (sum2
+ sum1
) % 0xffff;
497 return (sum2
<< 16) | sum1
;
500 /* Calculate the Fletcher-64 checksum of a given buffer. */
501 ULong
ML_(fletcher64
)(UInt
*buf
, SizeT blocks
)
507 for (i
= 0; i
< blocks
; i
++) {
508 sum1
= (sum1
+ buf
[i
]) % 0xffffffff;
509 sum2
= (sum2
+ sum1
) % 0xffffffff;
511 return (sum2
<< 32) | sum1
;
514 /* Save a complete context (VCPU state, sigmask) of a given client thread
515 into the vki_ucontext_t structure. This structure is supposed to be
516 allocated in the client memory, a caller must make sure that the memory can
517 be dereferenced. The active tool is informed about the save. */
518 void VG_(save_context
)(ThreadId tid
, vki_ucontext_t
*uc
, CorePart part
)
520 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
522 VG_TRACK(pre_mem_write
, part
, tid
, "save_context(uc)", (Addr
)uc
,
525 uc
->uc_flags
= VKI_UC_ALL
;
526 VG_TRACK(post_mem_write
, part
, tid
, (Addr
)&uc
->uc_flags
,
527 sizeof(uc
->uc_flags
));
530 uc
->uc_link
= tst
->os_state
.oldcontext
;
531 VG_TRACK(post_mem_write
, part
, tid
, (Addr
)&uc
->uc_link
,
532 sizeof(uc
->uc_link
));
534 /* Clear uc->vki_uc_signo. This slot is used by the signal machinery to
535 store a signal number. */
536 VKI_UC_SIGNO(uc
) = 0;
539 uc
->uc_sigmask
= tst
->sig_mask
;
540 VG_TRACK(post_mem_write
, part
, tid
, (Addr
)&uc
->uc_sigmask
,
541 sizeof(uc
->uc_sigmask
));
545 if (tst
->os_state
.ustack
546 && ML_(safe_to_deref
)(tst
->os_state
.ustack
, sizeof(vki_stack_t
))
547 && tst
->os_state
.ustack
->ss_size
) {
548 /* If ustack points to a valid stack copy it to ucontext. */
549 uc
->uc_stack
= *tst
->os_state
.ustack
;
552 /* Ustack is not valid. A correct stack has to be figured out
555 vki_stack_t altstack
;
557 /* Get information about alternate stack. */
558 res
= VG_(do_sys_sigaltstack
)(tid
, NULL
, &altstack
);
559 vg_assert(!sr_isError(res
));
561 if (altstack
.ss_flags
== VKI_SS_ONSTACK
) {
562 /* If the alternate stack is active copy it to ucontext. */
563 uc
->uc_stack
= altstack
;
566 /* No information about stack is present, save information about
567 current main stack to ucontext. This branch should be reached
568 only by the main thread. */
569 ThreadState
*tst2
= VG_(get_ThreadState
)(1);
570 uc
->uc_stack
.ss_sp
= (void*)(tst2
->client_stack_highest_byte
+ 1
571 - tst2
->client_stack_szB
);
572 uc
->uc_stack
.ss_size
= tst2
->client_stack_szB
;
573 uc
->uc_stack
.ss_flags
= 0;
577 VG_TRACK(post_mem_write
, part
, tid
, (Addr
)&uc
->uc_stack
,
578 sizeof(uc
->uc_stack
));
581 /* Save the architecture-specific part of the context. */
582 ML_(save_machine_context
)(tid
, uc
, part
);
585 /* Set a complete context (VCPU state, sigmask) of a given client thread
586 according to values passed in the vki_ucontext_t structure. This structure
587 is supposed to be allocated in the client memory, a caller must make sure
588 that the memory can be dereferenced. The active tool is informed about
589 what parts of the structure are read.
591 This function is a counterpart to VG_(save_context)(). */
592 void VG_(restore_context
)(ThreadId tid
, vki_ucontext_t
*uc
, CorePart part
,
595 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
596 Addr old_esp
= VG_(get_SP
)(tid
);
598 VG_TRACK(pre_mem_read
, part
, tid
, "restore_context(uc->uc_flags)",
599 (Addr
)&uc
->uc_flags
, sizeof(uc
->uc_flags
));
602 VG_TRACK(pre_mem_read
, part
, tid
, "restore_context(uc->uc_link)",
603 (Addr
)&uc
->uc_link
, sizeof(uc
->uc_link
));
604 tst
->os_state
.oldcontext
= uc
->uc_link
;
607 if (uc
->uc_flags
& VKI_UC_SIGMASK
) {
610 VG_TRACK(pre_mem_read
, part
, tid
, "restore_context(uc->uc_sigmask)",
611 (Addr
)&uc
->uc_sigmask
, sizeof(uc
->uc_sigmask
));
612 res
= VG_(do_sys_sigprocmask
)(tid
, VKI_SIG_SETMASK
, &uc
->uc_sigmask
,
614 /* Setting signal mask should never fail. */
615 vg_assert(!sr_isError(res
));
619 if (uc
->uc_flags
& VKI_UC_STACK
) {
620 VG_TRACK(pre_mem_read
, part
, tid
, "restore_context(uc->uc_stack)",
621 (Addr
)&uc
->uc_stack
, sizeof(uc
->uc_stack
));
623 if (uc
->uc_stack
.ss_flags
== VKI_SS_ONSTACK
) {
624 /* This seems to be a little bit dangerous but it is what the kernel
626 if (VG_(clo_trace_signals
))
627 VG_(dmsg
)("restore_context, sigaltstack: tid %u, "
628 "ss %p{%p,sz=%lu,flags=%#x}\n",
629 tid
, &uc
->uc_stack
, uc
->uc_stack
.ss_sp
,
630 (SizeT
)uc
->uc_stack
.ss_size
, (UInt
)uc
->uc_stack
.ss_flags
);
632 tst
->altstack
.ss_sp
= uc
->uc_stack
.ss_sp
;
633 tst
->altstack
.ss_size
= uc
->uc_stack
.ss_size
;
634 /* Do not copy ss_flags, they are calculated dynamically by
638 /* Copyout the new stack. */
639 if (tst
->os_state
.ustack
640 && VG_(am_is_valid_for_client
)((Addr
)tst
->os_state
.ustack
,
641 sizeof(*tst
->os_state
.ustack
),
643 *tst
->os_state
.ustack
= uc
->uc_stack
;
644 VG_TRACK(post_mem_write
, part
, tid
, (Addr
)&tst
->os_state
.ustack
,
645 sizeof(tst
->os_state
.ustack
));
649 /* Restore the architecture-specific part of the context. */
650 ML_(restore_machine_context
)(tid
, uc
, part
, esp_is_thrptr
);
652 /* If the thread stack is already known, kill the deallocated stack area.
653 This is important when returning from a signal handler. */
654 if (tst
->client_stack_highest_byte
&& tst
->client_stack_szB
) {
655 Addr end
= tst
->client_stack_highest_byte
;
656 Addr start
= end
+ 1 - tst
->client_stack_szB
;
657 Addr new_esp
= VG_(get_SP
)(tid
);
659 /* Make sure that the old and new stack pointer are on the same (active)
660 stack. Alternate stack is currently never affected by this code. */
661 if (start
<= old_esp
&& old_esp
<= end
662 && start
<= new_esp
&& new_esp
<= end
663 && new_esp
> old_esp
)
664 VG_TRACK(die_mem_stack
, old_esp
- VG_STACK_REDZONE_SZB
,
665 (new_esp
- old_esp
) + VG_STACK_REDZONE_SZB
);
669 /* Set a client stack associated with a given thread id according to values
670 passed in the vki_stack_t structure. */
671 static void set_stack(ThreadId tid
, vki_stack_t
*st
)
673 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
674 Addr new_start
, new_end
;
679 VG_(debugLog
)(2, "syswrap-solaris",
680 "set stack: sp=%#lx, size=%#lx.\n",
681 (Addr
)st
->ss_sp
, (SizeT
)st
->ss_size
);
684 vg_assert(st
->ss_flags
== 0);
686 new_start
= (Addr
)st
->ss_sp
;
687 new_end
= new_start
+ st
->ss_size
- 1;
688 new_size
= st
->ss_size
;
689 cur_start
= tst
->client_stack_highest_byte
+ 1
690 - tst
->client_stack_szB
;
691 cur_size
= tst
->client_stack_szB
;
693 if (new_start
== cur_start
&& new_size
== cur_size
) {
694 /* No change is requested, bail out. */
698 if (tid
== 1 && (new_size
== 0 || new_size
> VG_(clstk_max_size
))) {
699 /* The main thread requests to use a stack without any size checking, or
700 too big stack. Fallback to the maximum allocated client stack. */
702 /* TODO I think it is possible to give up on setting main stack anyway.
703 Valgrind knows where it is located and it is already registered as
706 new_size
= VG_(clstk_max_size
);
707 new_end
= tst
->client_stack_highest_byte
;
708 new_start
= new_end
+ 1 - new_size
;
711 if (tst
->os_state
.stk_id
== NULL_STK_ID
) {
712 /* This thread doesn't have a stack set yet. */
713 VG_(debugLog
)(2, "syswrap-solaris",
714 "Stack set to %#lx-%#lx (new) for thread %u.\n",
715 new_start
, new_end
, tid
);
716 tst
->os_state
.stk_id
= VG_(register_stack
)(new_start
, new_end
);
718 /* Change a thread stack. */
719 VG_(debugLog
)(2, "syswrap-solaris",
720 "Stack set to %#lx-%#lx (change) for thread %u.\n",
721 new_start
, new_end
, tid
);
722 VG_(change_stack
)(tst
->os_state
.stk_id
, new_start
, new_end
);
724 tst
->client_stack_highest_byte
= new_end
;
725 tst
->client_stack_szB
= new_size
;
728 /* ---------------------------------------------------------------------
729 Door tracking. Used mainly for server side where door_return()
730 parameters alone do not contain sufficient information.
731 Also used on client side when new door descriptors are passed via
732 door_call() in desc_ptr. Not used for tracking door descriptors
733 explicitly open()'ed [generic fd tracking is used in that case].
734 ------------------------------------------------------------------ */
736 /* One of these is allocated for each created door. */
737 typedef struct OpenDoor
739 Bool server
; /* TRUE = server door, FALSE = client door */
740 Int fd
; /* The file descriptor. */
744 Addr server_procedure
; /* The door server procedure. */
745 HChar
*pathname
; /* NULL if unknown. */
749 /* Hook called during PRE door_call()
750 to check contents of params->data_ptr. */
751 void (*pre_mem_hook
)(ThreadId tid
, Int fd
,
752 void *data_ptr
, SizeT data_size
);
753 /* Hook called during POST door_call()
754 to define contents of params->rbuf. */
755 void (*post_mem_hook
)(ThreadId tid
, Int fd
,
756 void *rbuf
, SizeT rsize
);
759 struct OpenDoor
*next
, *prev
;
762 /* List of allocated door fds. */
763 static OpenDoor
*doors_recorded
= NULL
;
764 static UInt nr_doors_recorded
= 0;
766 static OpenDoor
*door_record_create(void)
768 OpenDoor
*d
= VG_(malloc
)("syswrap.door_record_create.1", sizeof(OpenDoor
));
770 d
->next
= doors_recorded
;
771 if (doors_recorded
!= NULL
)
772 doors_recorded
->prev
= d
;
774 nr_doors_recorded
+= 1;
779 /* Records a server door. */
780 static void door_record_server(ThreadId tid
, Addr server_procedure
, Int fd
)
782 OpenDoor
*d
= doors_recorded
;
785 if ((d
->server
== TRUE
) && (d
->server_procedure
== server_procedure
)) {
787 VG_(free
)(d
->pathname
);
795 d
= door_record_create();
796 vg_assert(d
!= NULL
);
800 d
->server_procedure
= server_procedure
;
804 /* Records a client door. */
805 static void door_record_client(ThreadId tid
, Int fd
,
806 void (*pre_mem_hook
)(ThreadId tid
, Int fd
, void *data_ptr
, SizeT data_size
),
807 void (*post_mem_hook
)(ThreadId tid
, Int fd
, void *rbuf
, SizeT rsize
))
809 OpenDoor
*d
= doors_recorded
;
812 if ((d
->server
== FALSE
) && (d
->fd
== fd
))
818 d
= door_record_create();
819 vg_assert(d
!= NULL
);
823 d
->pre_mem_hook
= pre_mem_hook
;
824 d
->post_mem_hook
= post_mem_hook
;
827 /* Revokes an open door, be it server side or client side. */
828 static void door_record_revoke(ThreadId tid
, Int fd
)
830 OpenDoor
*d
= doors_recorded
;
835 d
->prev
->next
= d
->next
;
837 doors_recorded
= d
->next
;
839 d
->next
->prev
= d
->prev
;
841 if ((d
->server
== TRUE
) && (d
->pathname
!= NULL
))
842 VG_(free
)(d
->pathname
);
844 nr_doors_recorded
-= 1;
851 /* Attaches a server door to a filename. */
852 static void door_record_server_fattach(Int fd
, HChar
*pathname
)
854 OpenDoor
*d
= doors_recorded
;
858 vg_assert(d
->server
== TRUE
);
860 if (d
->pathname
!= NULL
)
861 VG_(free
)(d
->pathname
);
862 d
->pathname
= VG_(strdup
)("syswrap.door_server_fattach.1", pathname
);
869 /* Finds a server door based on server procedure. */
870 static const OpenDoor
*door_find_by_proc(Addr server_procedure
)
872 OpenDoor
*d
= doors_recorded
;
875 if ((d
->server
) && (d
->server_procedure
== server_procedure
))
883 /* Finds a client door based on fd. */
884 static const OpenDoor
*door_find_by_fd(Int fd
)
886 OpenDoor
*d
= doors_recorded
;
889 if ((d
->server
== FALSE
) && (d
->fd
== fd
))
897 /* ---------------------------------------------------------------------
898 PRE/POST wrappers for Solaris-specific syscalls
899 ------------------------------------------------------------------ */
901 #define PRE(name) DEFN_PRE_TEMPLATE(solaris, name)
902 #define POST(name) DEFN_POST_TEMPLATE(solaris, name)
905 DECL_TEMPLATE(solaris
, sys_exit
);
906 #if defined(SOLARIS_SPAWN_SYSCALL)
907 DECL_TEMPLATE(solaris
, sys_spawn
);
908 #endif /* SOLARIS_SPAWN_SYSCALL */
909 #if defined(SOLARIS_OLD_SYSCALLS)
910 DECL_TEMPLATE(solaris
, sys_open
);
911 #endif /* SOLARIS_OLD_SYSCALLS */
912 DECL_TEMPLATE(solaris
, sys_close
);
913 DECL_TEMPLATE(solaris
, sys_linkat
);
914 DECL_TEMPLATE(solaris
, sys_symlinkat
);
915 DECL_TEMPLATE(solaris
, sys_time
);
916 DECL_TEMPLATE(solaris
, sys_brk
);
917 DECL_TEMPLATE(solaris
, sys_stat
);
918 DECL_TEMPLATE(solaris
, sys_lseek
);
919 DECL_TEMPLATE(solaris
, sys_mount
);
920 DECL_TEMPLATE(solaris
, sys_readlinkat
);
921 DECL_TEMPLATE(solaris
, sys_stime
);
922 DECL_TEMPLATE(solaris
, sys_fstat
);
923 #if defined(SOLARIS_FREALPATHAT_SYSCALL)
924 DECL_TEMPLATE(solaris
, sys_frealpathat
);
925 #endif /* SOLARIS_FREALPATHAT_SYSCALL */
926 DECL_TEMPLATE(solaris
, sys_stty
);
927 DECL_TEMPLATE(solaris
, sys_gtty
);
928 DECL_TEMPLATE(solaris
, sys_pgrpsys
);
929 DECL_TEMPLATE(solaris
, sys_pipe
);
930 DECL_TEMPLATE(solaris
, sys_faccessat
);
931 DECL_TEMPLATE(solaris
, sys_mknodat
);
932 DECL_TEMPLATE(solaris
, sys_sysi86
);
933 DECL_TEMPLATE(solaris
, sys_shmsys
);
934 DECL_TEMPLATE(solaris
, sys_semsys
);
935 DECL_TEMPLATE(solaris
, sys_ioctl
);
936 DECL_TEMPLATE(solaris
, sys_fchownat
);
937 DECL_TEMPLATE(solaris
, sys_fdsync
);
938 DECL_TEMPLATE(solaris
, sys_execve
);
939 DECL_TEMPLATE(solaris
, sys_fcntl
);
940 DECL_TEMPLATE(solaris
, sys_renameat
);
941 DECL_TEMPLATE(solaris
, sys_unlinkat
);
942 DECL_TEMPLATE(solaris
, sys_fstatat
);
943 DECL_TEMPLATE(solaris
, sys_openat
);
944 DECL_TEMPLATE(solaris
, sys_tasksys
);
945 DECL_TEMPLATE(solaris
, sys_getpagesizes
);
946 DECL_TEMPLATE(solaris
, sys_lwp_park
);
947 DECL_TEMPLATE(solaris
, sys_sendfilev
);
948 #if defined(SOLARIS_LWP_NAME_SYSCALL)
949 DECL_TEMPLATE(solaris
, sys_lwp_name
);
950 #endif /* SOLARIS_LWP_NAME_SYSCALL */
951 DECL_TEMPLATE(solaris
, sys_privsys
);
952 DECL_TEMPLATE(solaris
, sys_ucredsys
);
953 DECL_TEMPLATE(solaris
, sys_sysfs
);
954 DECL_TEMPLATE(solaris
, sys_getmsg
);
955 DECL_TEMPLATE(solaris
, sys_putmsg
);
956 DECL_TEMPLATE(solaris
, sys_lstat
);
957 DECL_TEMPLATE(solaris
, sys_sigprocmask
);
958 DECL_TEMPLATE(solaris
, sys_sigsuspend
);
959 DECL_TEMPLATE(solaris
, sys_sigaction
);
960 DECL_TEMPLATE(solaris
, sys_sigpending
);
961 DECL_TEMPLATE(solaris
, sys_getsetcontext
);
962 DECL_TEMPLATE(solaris
, sys_fchmodat
);
963 DECL_TEMPLATE(solaris
, sys_mkdirat
);
964 DECL_TEMPLATE(solaris
, sys_statvfs
);
965 DECL_TEMPLATE(solaris
, sys_fstatvfs
);
966 DECL_TEMPLATE(solaris
, sys_nfssys
);
967 DECL_TEMPLATE(solaris
, sys_waitid
);
968 DECL_TEMPLATE(solaris
, sys_sigsendsys
);
969 #if defined(SOLARIS_UTIMESYS_SYSCALL)
970 DECL_TEMPLATE(solaris
, sys_utimesys
);
971 #endif /* SOLARIS_UTIMESYS_SYSCALL */
972 #if defined(SOLARIS_UTIMENSAT_SYSCALL)
973 DECL_TEMPLATE(solaris
, sys_utimensat
);
974 #endif /* SOLARIS_UTIMENSAT_SYSCALL */
975 DECL_TEMPLATE(solaris
, sys_sigresend
);
976 DECL_TEMPLATE(solaris
, sys_priocntlsys
);
977 DECL_TEMPLATE(solaris
, sys_pathconf
);
978 DECL_TEMPLATE(solaris
, sys_mmap
);
979 #if defined(SOLARIS_UUIDSYS_SYSCALL)
980 DECL_TEMPLATE(solaris
, sys_uuidsys
);
981 #endif /* SOLARIS_UUIDSYS_SYSCALL */
982 DECL_TEMPLATE(solaris
, sys_mmapobj
);
983 DECL_TEMPLATE(solaris
, sys_memcntl
);
984 DECL_TEMPLATE(solaris
, sys_getpmsg
);
985 DECL_TEMPLATE(solaris
, sys_putpmsg
);
986 #if defined(SOLARIS_OLD_SYSCALLS)
987 DECL_TEMPLATE(solaris
, sys_rename
);
988 #endif /* SOLARIS_OLD_SYSCALLS */
989 DECL_TEMPLATE(solaris
, sys_uname
);
990 DECL_TEMPLATE(solaris
, sys_setegid
);
991 DECL_TEMPLATE(solaris
, sys_sysconfig
);
992 DECL_TEMPLATE(solaris
, sys_systeminfo
);
993 DECL_TEMPLATE(solaris
, sys_seteuid
);
994 DECL_TEMPLATE(solaris
, sys_forksys
);
995 #if defined(SOLARIS_GETRANDOM_SYSCALL)
996 DECL_TEMPLATE(solaris
, sys_getrandom
);
997 #endif /* SOLARIS_GETRANDOM_SYSCALL */
998 DECL_TEMPLATE(solaris
, sys_sigtimedwait
);
999 DECL_TEMPLATE(solaris
, sys_yield
);
1000 DECL_TEMPLATE(solaris
, sys_lwp_sema_post
);
1001 DECL_TEMPLATE(solaris
, sys_lwp_sema_trywait
);
1002 DECL_TEMPLATE(solaris
, sys_lwp_detach
);
1003 DECL_TEMPLATE(solaris
, sys_modctl
);
1004 DECL_TEMPLATE(solaris
, sys_fchroot
);
1005 #if defined(SOLARIS_SYSTEM_STATS_SYSCALL)
1006 DECL_TEMPLATE(solaris
, sys_system_stats
);
1007 #endif /* SOLARIS_SYSTEM_STATS_SYSCALL */
1008 DECL_TEMPLATE(solaris
, sys_gettimeofday
);
1009 DECL_TEMPLATE(solaris
, sys_lwp_create
);
1010 DECL_TEMPLATE(solaris
, sys_lwp_exit
);
1011 DECL_TEMPLATE(solaris
, sys_lwp_suspend
);
1012 DECL_TEMPLATE(solaris
, sys_lwp_continue
);
1013 #if defined(SOLARIS_LWP_SIGQUEUE_SYSCALL)
1014 DECL_TEMPLATE(solaris
, sys_lwp_sigqueue
);
1016 DECL_TEMPLATE(solaris
, sys_lwp_kill
);
1017 #endif /* SOLARIS_LWP_SIGQUEUE_SYSCALL */
1018 DECL_TEMPLATE(solaris
, sys_lwp_self
);
1019 DECL_TEMPLATE(solaris
, sys_lwp_sigmask
);
1020 DECL_TEMPLATE(solaris
, sys_lwp_private
);
1021 DECL_TEMPLATE(solaris
, sys_lwp_wait
);
1022 DECL_TEMPLATE(solaris
, sys_lwp_mutex_wakeup
);
1023 DECL_TEMPLATE(solaris
, sys_lwp_cond_wait
);
1024 DECL_TEMPLATE(solaris
, sys_lwp_cond_signal
);
1025 DECL_TEMPLATE(solaris
, sys_lwp_cond_broadcast
);
1026 DECL_TEMPLATE(solaris
, sys_pread
);
1027 DECL_TEMPLATE(solaris
, sys_pwrite
);
1028 DECL_TEMPLATE(solaris
, sys_lgrpsys
);
1029 DECL_TEMPLATE(solaris
, sys_rusagesys
);
1030 DECL_TEMPLATE(solaris
, sys_port
);
1031 DECL_TEMPLATE(solaris
, sys_pollsys
);
1032 DECL_TEMPLATE(solaris
, sys_labelsys
);
1033 DECL_TEMPLATE(solaris
, sys_acl
);
1034 DECL_TEMPLATE(solaris
, sys_auditsys
);
1035 DECL_TEMPLATE(solaris
, sys_p_online
);
1036 DECL_TEMPLATE(solaris
, sys_sigqueue
);
1037 DECL_TEMPLATE(solaris
, sys_clock_gettime
);
1038 DECL_TEMPLATE(solaris
, sys_clock_settime
);
1039 DECL_TEMPLATE(solaris
, sys_clock_getres
);
1040 DECL_TEMPLATE(solaris
, sys_timer_create
);
1041 DECL_TEMPLATE(solaris
, sys_timer_delete
);
1042 DECL_TEMPLATE(solaris
, sys_timer_settime
);
1043 DECL_TEMPLATE(solaris
, sys_timer_gettime
);
1044 DECL_TEMPLATE(solaris
, sys_timer_getoverrun
);
1045 DECL_TEMPLATE(solaris
, sys_facl
);
1046 DECL_TEMPLATE(solaris
, sys_door
);
1047 DECL_TEMPLATE(solaris
, sys_schedctl
);
1048 DECL_TEMPLATE(solaris
, sys_pset
);
1049 DECL_TEMPLATE(solaris
, sys_resolvepath
);
1050 DECL_TEMPLATE(solaris
, sys_lwp_mutex_timedlock
);
1051 DECL_TEMPLATE(solaris
, sys_lwp_rwlock_sys
);
1052 DECL_TEMPLATE(solaris
, sys_lwp_sema_timedwait
);
1053 DECL_TEMPLATE(solaris
, sys_zone
);
1054 DECL_TEMPLATE(solaris
, sys_getcwd
);
1055 DECL_TEMPLATE(solaris
, sys_so_socket
);
1056 DECL_TEMPLATE(solaris
, sys_so_socketpair
);
1057 DECL_TEMPLATE(solaris
, sys_bind
);
1058 DECL_TEMPLATE(solaris
, sys_listen
);
1059 DECL_TEMPLATE(solaris
, sys_accept
);
1060 DECL_TEMPLATE(solaris
, sys_connect
);
1061 DECL_TEMPLATE(solaris
, sys_shutdown
);
1062 DECL_TEMPLATE(solaris
, sys_recv
);
1063 DECL_TEMPLATE(solaris
, sys_recvfrom
);
1064 DECL_TEMPLATE(solaris
, sys_recvmsg
);
1065 DECL_TEMPLATE(solaris
, sys_send
);
1066 DECL_TEMPLATE(solaris
, sys_sendmsg
);
1067 DECL_TEMPLATE(solaris
, sys_sendto
);
1068 DECL_TEMPLATE(solaris
, sys_getpeername
);
1069 DECL_TEMPLATE(solaris
, sys_getsockname
);
1070 DECL_TEMPLATE(solaris
, sys_getsockopt
);
1071 DECL_TEMPLATE(solaris
, sys_setsockopt
);
1072 DECL_TEMPLATE(solaris
, sys_lwp_mutex_unlock
);
1073 DECL_TEMPLATE(solaris
, sys_lwp_mutex_register
);
1074 DECL_TEMPLATE(solaris
, sys_uucopy
);
1075 DECL_TEMPLATE(solaris
, sys_umount2
);
1077 DECL_TEMPLATE(solaris
, fast_gethrtime
);
1078 DECL_TEMPLATE(solaris
, fast_gethrvtime
);
1079 DECL_TEMPLATE(solaris
, fast_gethrestime
);
1080 DECL_TEMPLATE(solaris
, fast_getlgrp
);
1081 #if defined(SOLARIS_GETHRT_FASTTRAP)
1082 DECL_TEMPLATE(solaris
, fast_gethrt
);
1083 #endif /* SOLARIS_GETHRT_FASTTRAP */
1084 #if defined(SOLARIS_GETZONEOFFSET_FASTTRAP)
1085 DECL_TEMPLATE(solaris
, fast_getzoneoffset
);
1086 #endif /* SOLARIS_GETZONEOFFSET_FASTTRAP */
1088 /* implementation */
1091 /* void exit(int status); */
1094 PRINT("sys_exit( %ld )", SARG1
);
1095 PRE_REG_READ1(void, "exit", int, status
);
1097 for (t
= 1; t
< VG_N_THREADS
; t
++) {
1098 if (VG_(threads
)[t
].status
== VgTs_Empty
)
1101 /* Assign the exit code, VG_(nuke_all_threads_except) will assign
1103 VG_(threads
)[t
].os_state
.exitcode
= ARG1
;
1106 /* Indicate in all other threads that the process is exiting.
1107 Then wait using VG_(reap_threads) for these threads to disappear.
1108 See comments in syswrap-linux.c, PRE(sys_exit_group) wrapper,
1109 for reasoning why this cannot give a deadlock. */
1110 VG_(nuke_all_threads_except
)(tid
, VgSrc_ExitProcess
);
1111 VG_(reap_threads
)(tid
);
1112 VG_(threads
)[tid
].exitreason
= VgSrc_ExitThread
;
1113 /* We do assign VgSrc_ExitThread and not VgSrc_ExitProcess, as this thread
1114 is the thread calling exit_group and so its registers must be considered
1115 as not reachable. See pub_tool_machine.h VG_(apply_to_GP_regs). */
1117 /* We have to claim the syscall already succeeded. */
1118 SET_STATUS_Success(0);
1121 #if defined(SOLARIS_SPAWN_SYSCALL)
1122 static Bool
spawn_pre_check_kfa(ThreadId tid
, SyscallStatus
*status
,
1123 vki_kfile_attr_t
*kfa
)
1125 PRE_FIELD_READ("spawn(attrs->kfa_size)", kfa
->kfa_size
);
1126 PRE_FIELD_READ("spawn(attrs->kfa_type)", kfa
->kfa_type
);
1128 if (ML_(safe_to_deref
)(kfa
, kfa
->kfa_size
)) {
1129 switch (kfa
->kfa_type
) {
1131 PRE_FIELD_READ("spawn(attrs->kfa_filedes)", kfa
->kfa_filedes
);
1132 PRE_FIELD_READ("spawn(attrs->kfa_newfiledes)", kfa
->kfa_newfiledes
);
1133 if (!ML_(fd_allowed
)(kfa
->kfa_filedes
, "spawn(dup2)", tid
, False
) ||
1134 !ML_(fd_allowed
)(kfa
->kfa_newfiledes
, "spawn(dup2)", tid
, False
)) {
1135 SET_STATUS_Failure(VKI_EBADF
);
1140 PRE_FIELD_READ("spawn(attrs->kfa_filedes)", kfa
->kfa_filedes
);
1141 /* If doing -d style logging (which is to fd = 2 = stderr),
1142 don't allow that filedes to be closed. See ML_(fd_allowed)(). */
1143 if (!ML_(fd_allowed
)(kfa
->kfa_filedes
, "spawn(close)", tid
, False
) ||
1144 (kfa
->kfa_filedes
== 2 && VG_(debugLog_getLevel
)() > 0)) {
1145 SET_STATUS_Failure(VKI_EBADF
);
1149 case VKI_FA_CLOSEFROM
:
1150 /* :TODO: All file descriptors greater than or equal to
1151 kfa->kfa_filedes would have to be checked. */
1152 VG_(unimplemented
)("Support for spawn() with file attribute type "
1156 PRE_FIELD_READ("spawn(attrs->kfa_filedes)", kfa
->kfa_filedes
);
1157 PRE_FIELD_READ("spawn(attrs->kfa_oflag)", kfa
->kfa_oflag
);
1158 PRE_FIELD_READ("spawn(attrs->kfa_mode)", kfa
->kfa_mode
);
1159 if (!ML_(fd_allowed
)(kfa
->kfa_filedes
, "spawn(open)", tid
, False
)) {
1160 SET_STATUS_Failure(VKI_EBADF
);
1165 PRE_FIELD_READ("spawn(attrs->kfa_pathsize)", kfa
->kfa_pathsize
);
1166 if (kfa
->kfa_pathsize
!= 0) {
1167 PRE_MEM_RASCIIZ("spawn(attrs->kfa_data)", (Addr
) kfa
->kfa_data
);
1171 VG_(unimplemented
)("Support for spawn() with file attribute type %u.",
1181 /* int spawn(char *path, void *attrs, size_t attrsize,
1182 char *argenv, size_t aesize); */
1183 PRINT("sys_spawn ( %#lx(%s), %#lx, %lu, %#lx, %lu )",
1184 ARG1
, (HChar
*) ARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
1185 PRE_REG_READ5(long, "spawn", const char *, path
, void *, attrs
,
1186 size_t, attrsize
, char *, argenv
, size_t, aesize
);
1188 /* First check input arguments. */
1189 PRE_MEM_RASCIIZ("spawn(path)", ARG1
);
1191 /* --- vki_kspawn_attr_t --
1194 | ksa_attr_off | -----| (only if != 0)
1196 | ksa_path_off | =====|====| (only if != 0)
1197 | ksa_path_size | | |
1198 | ksa_shell_off | -----|----|----| (only if != 0)
1199 | ksa_shell_size | | | |
1200 | ksa_data[0] | | | |
1201 ------------------------ | | |
1202 | vki_spawn_attr_t | <----| | |
1203 ------------------------ | |
1204 | path | <---------| |
1205 ------------------------ |
1206 | shell | <---------------
1207 ------------------------
1208 | file actions | (not included in ksa_size, only in ARG3)
1209 ------------------------
1211 ksa_size = sizeof(vki_kspawn_attr_t) + ksa_attr_size + ksa_path_size +
1213 attrs_size (ARG3) = ksa_size + file actions size */
1215 vki_kspawn_attr_t
*attrs
= (vki_kspawn_attr_t
*) ARG2
;
1216 PRE_FIELD_READ("spawn(attrs->ksa_version)", attrs
->ksa_version
);
1217 PRE_FIELD_READ("spawn(attrs->ksa_size)", attrs
->ksa_size
);
1218 PRE_FIELD_READ("spawn(attrs->ksa_attr_off)", attrs
->ksa_attr_off
);
1219 PRE_FIELD_READ("spawn(attrs->ksa_path_off)", attrs
->ksa_path_off
);
1220 PRE_FIELD_READ("spawn(attrs->ksa_shell_off)", attrs
->ksa_shell_off
);
1222 if (ML_(safe_to_deref
)(attrs
, sizeof(vki_kspawn_attr_t
))) {
1223 if (attrs
->ksa_version
!= VKI_SPAWN_VERSION
) {
1224 VG_(unimplemented
)("Support for spawn() with attributes "
1225 "version %u.", attrs
->ksa_version
);
1228 if (attrs
->ksa_attr_off
!= 0) {
1229 PRE_FIELD_READ("spawn(attrs->ksa_attr_size)", attrs
->ksa_attr_size
);
1230 vki_spawn_attr_t
*sap
=
1231 (vki_spawn_attr_t
*) ((Addr
) attrs
+ attrs
->ksa_attr_off
);
1232 PRE_MEM_READ("spawn(attrs->ksa_attr)",
1233 (Addr
) sap
, attrs
->ksa_attr_size
);
1234 if (ML_(safe_to_deref
)(sap
, sizeof(vki_spawn_attr_t
))) {
1235 if (sap
->sa_psflags
& VKI_POSIX_SPAWN_SETVAMASK_NP
) {
1236 VG_(unimplemented
)("Support for spawn() with attributes flag "
1237 "including POSIX_SPAWN_SETVAMASK_NP.");
1240 Int rem
= sap
->sa_psflags
& ~(
1241 VKI_POSIX_SPAWN_RESETIDS
| VKI_POSIX_SPAWN_SETPGROUP
|
1242 VKI_POSIX_SPAWN_SETSIGDEF
| VKI_POSIX_SPAWN_SETSIGMASK
|
1243 VKI_POSIX_SPAWN_SETSCHEDPARAM
| VKI_POSIX_SPAWN_SETSCHEDULER
|
1244 VKI_POSIX_SPAWN_SETSID_NP
| VKI_POSIX_SPAWN_SETVAMASK_NP
|
1245 VKI_POSIX_SPAWN_SETSIGIGN_NP
| VKI_POSIX_SPAWN_NOSIGCHLD_NP
|
1246 VKI_POSIX_SPAWN_WAITPID_NP
| VKI_POSIX_SPAWN_NOEXECERR_NP
);
1248 VG_(unimplemented
)("Support for spawn() with attributes flag "
1249 "%#x.", sap
->sa_psflags
);
1254 if (attrs
->ksa_path_off
!= 0) {
1255 PRE_FIELD_READ("spawn(attrs->ksa_path_size)", attrs
->ksa_path_size
);
1256 PRE_MEM_RASCIIZ("spawn(attrs->ksa_path)",
1257 (Addr
) attrs
+ attrs
->ksa_path_off
);
1260 if (attrs
->ksa_shell_off
!= 0) {
1261 PRE_FIELD_READ("spawn(attrs->ksa_shell_size)",
1262 attrs
->ksa_shell_size
);
1263 PRE_MEM_RASCIIZ("spawn(attrs->ksa_shell)",
1264 (Addr
) attrs
+ attrs
->ksa_shell_off
);
1267 vki_kfile_attr_t
*kfa
= (vki_kfile_attr_t
*) (ARG2
+ attrs
->ksa_size
);
1268 while ((Addr
) kfa
< ARG2
+ ARG3
) {
1269 if (spawn_pre_check_kfa(tid
, status
, kfa
) == False
) {
1272 kfa
= (vki_kfile_attr_t
*) ((Addr
) kfa
+ kfa
->kfa_size
);
1276 PRE_MEM_READ("spawn(argenv)", ARG4
, ARG5
);
1278 /* Check that the name at least begins in client-accessible storage. */
1279 if ((ARG1
== 0) || !ML_(safe_to_deref
)((HChar
*) ARG1
, 1)) {
1280 SET_STATUS_Failure(VKI_EFAULT
);
1284 /* Check that attrs reside in client-accessible storage. */
1286 if (!VG_(am_is_valid_for_client
)(ARG2
, ARG3
, VKI_PROT_READ
)) {
1287 SET_STATUS_Failure(VKI_EFAULT
);
1292 /* Check that the argenv reside in client-accessible storage.
1293 Solaris disallows to perform spawn() without any arguments & environment
1294 variables specified. */
1295 if ((ARG4
== 0) /* obviously bogus */ ||
1296 !VG_(am_is_valid_for_client
)(ARG4
, ARG5
, VKI_PROT_READ
)) {
1297 SET_STATUS_Failure(VKI_EFAULT
);
1301 /* Copy existing attrs or create empty minimal ones. */
1302 vki_kspawn_attr_t
*attrs
;
1305 /* minimalistic kspawn_attr_t + spawn_attr_t */
1306 attrs_size
= sizeof(vki_kspawn_attr_t
) + sizeof(vki_spawn_attr_t
);
1307 attrs
= VG_(calloc
)("syswrap.spawn.1", 1, attrs_size
);
1308 attrs
->ksa_version
= VKI_SPAWN_VERSION
;
1309 attrs
->ksa_size
= attrs_size
;
1310 attrs
->ksa_attr_off
= sizeof(vki_kspawn_attr_t
);
1311 attrs
->ksa_attr_size
= sizeof(vki_spawn_attr_t
);
1312 } else if (((vki_kspawn_attr_t
*) ARG2
)->ksa_attr_off
== 0) {
1313 /* existing kspawn_attr_t but missing spawn_attr_t */
1314 attrs_size
= ARG3
+ sizeof(vki_spawn_attr_t
);
1315 attrs
= VG_(calloc
)("syswrap.spawn.2", 1, attrs_size
);
1316 VG_(memcpy
)(attrs
, (void *) ARG2
, sizeof(vki_kspawn_attr_t
));
1317 SizeT file_actions_size
= ARG3
- attrs
->ksa_size
;
1318 attrs
->ksa_size
+= sizeof(vki_spawn_attr_t
);
1319 attrs
->ksa_attr_off
= sizeof(vki_kspawn_attr_t
);
1320 attrs
->ksa_attr_size
= sizeof(vki_spawn_attr_t
);
1321 if (attrs
->ksa_path_off
!= 0) {
1322 VG_(memcpy
)((HChar
*) attrs
+ attrs
->ksa_path_off
+
1323 sizeof(vki_spawn_attr_t
), (HChar
*) ARG2
+
1324 attrs
->ksa_path_off
, attrs
->ksa_path_size
);
1325 attrs
->ksa_path_off
+= sizeof(vki_spawn_attr_t
);
1327 if (attrs
->ksa_shell_off
!= 0) {
1328 VG_(memcpy
)((HChar
*) attrs
+ attrs
->ksa_shell_off
+
1329 sizeof(vki_spawn_attr_t
), (HChar
*) ARG2
+
1330 attrs
->ksa_shell_off
, attrs
->ksa_shell_size
);
1331 attrs
->ksa_shell_off
+= sizeof(vki_spawn_attr_t
);
1333 if (file_actions_size
> 0) {
1334 VG_(memcpy
)((HChar
*) attrs
+ attrs_size
- file_actions_size
,
1335 (HChar
*) ARG2
+ ARG3
- file_actions_size
,
1339 /* existing kspawn_attr_t + spawn_attr_t */
1341 attrs
= VG_(malloc
)("syswrap.spawn.3", attrs_size
);
1342 VG_(memcpy
)(attrs
, (void *) ARG2
, attrs_size
);
1344 vki_spawn_attr_t
*spa
= (vki_spawn_attr_t
*) ((HChar
*) attrs
+
1345 attrs
->ksa_attr_off
);
1347 /* Convert argv and envp parts of argenv into their separate XArray's.
1348 Duplicate strings because argv and envp will be then modified. */
1349 XArray
*argv
= VG_(newXA
)(VG_(malloc
), "syswrap.spawn.4",
1350 VG_(free
), sizeof(HChar
*));
1351 XArray
*envp
= VG_(newXA
)(VG_(malloc
), "syswrap.spawn.5",
1352 VG_(free
), sizeof(HChar
*));
1354 HChar
*argenv
= (HChar
*) ARG4
;
1355 XArray
*current_xa
= argv
;
1356 while ((Addr
) argenv
< ARG4
+ ARG5
) {
1357 if (*argenv
== '\0') {
1359 if (current_xa
== argv
) {
1361 if ((*argenv
== '\0') && ((Addr
) argenv
== ARG4
+ ARG5
- 1)) {
1362 /* envp part is empty, it contained only {NULL}. */
1366 if ((Addr
) argenv
!= ARG4
+ ARG5
) {
1367 if (VG_(clo_trace_syscalls
))
1368 VG_(debugLog
)(3, "syswrap-solaris", "spawn: bogus argenv\n");
1369 SET_STATUS_Failure(VKI_EINVAL
);
1376 if (*argenv
!= '\1') {
1377 if (VG_(clo_trace_syscalls
))
1378 VG_(debugLog
)(3, "syswrap-solaris", "spawn: bogus argenv\n");
1379 SET_STATUS_Failure(VKI_EINVAL
);
1384 HChar
*duplicate
= VG_(strdup
)("syswrap.spawn.6", argenv
);
1385 VG_(addToXA
)(current_xa
, &duplicate
);
1386 argenv
+= VG_(strlen
)(argenv
) + 1;
1389 /* Debug-only printing. */
1391 VG_(printf
)("\nARG1 = %#lx(%s)\n", ARG1
, (HChar
*) ARG1
);
1392 VG_(printf
)("ARG4 (argv) = ");
1393 for (Word i
= 0; i
< VG_(sizeXA
)(argv
); i
++) {
1394 VG_(printf
)("%s ", *(HChar
**) VG_(indexXA
)(argv
, i
));
1397 VG_(printf
)("\nARG4 (envp) = ");
1398 for (Word i
= 0; i
< VG_(sizeXA
)(envp
); i
++) {
1399 VG_(printf
)("%s ", *(HChar
**) VG_(indexXA
)(envp
, i
));
1404 /* Decide whether or not we want to trace the spawned child.
1405 Omit the executable name itself from child_argv. */
1406 const HChar
**child_argv
= VG_(malloc
)("syswrap.spawn.7",
1407 (VG_(sizeXA
)(argv
) - 1) * sizeof(HChar
*));
1408 for (Word i
= 1; i
< VG_(sizeXA
)(argv
); i
++) {
1409 child_argv
[i
- 1] = *(HChar
**) VG_(indexXA
)(argv
, i
);
1411 Bool trace_this_child
= VG_(should_we_trace_this_child
)((HChar
*) ARG1
,
1413 VG_(free
)(child_argv
);
1415 /* If we're tracing the child, and the launcher name looks bogus (possibly
1416 because launcher.c couldn't figure it out, see comments therein) then we
1417 have no option but to fail. */
1418 if (trace_this_child
&&
1419 (!VG_(name_of_launcher
) || VG_(name_of_launcher
)[0] != '/')) {
1420 SET_STATUS_Failure(VKI_ECHILD
); /* "No child processes." */
1424 /* Set up the child's exe path. */
1425 const HChar
*path
= (const HChar
*) ARG1
;
1426 const HChar
*launcher_basename
= NULL
;
1427 if (trace_this_child
) {
1428 /* We want to exec the launcher. */
1429 path
= VG_(name_of_launcher
);
1430 vg_assert(path
!= NULL
);
1432 launcher_basename
= VG_(strrchr
)(path
, '/');
1433 if ((launcher_basename
== NULL
) || (launcher_basename
[1] == '\0')) {
1434 launcher_basename
= path
; /* hmm, tres dubious */
1436 launcher_basename
++;
1440 /* Set up the child's environment.
1442 Remove the valgrind-specific stuff from the environment so the child
1443 doesn't get vgpreload_core.so, vgpreload_<tool>.so, etc. This is done
1444 unconditionally, since if we are tracing the child, the child valgrind
1445 will set up the appropriate client environment.
1447 Then, if tracing the child, set VALGRIND_LIB for it. */
1448 HChar
**child_envp
= VG_(calloc
)("syswrap.spawn.8",
1449 VG_(sizeXA
)(envp
) + 1, sizeof(HChar
*));
1450 for (Word i
= 0; i
< VG_(sizeXA
)(envp
); i
++) {
1451 child_envp
[i
] = *(HChar
**) VG_(indexXA
)(envp
, i
);
1453 VG_(env_remove_valgrind_env_stuff
)(child_envp
, /* ro_strings */ False
,
1456 /* Stuff was removed from child_envp, reflect that in envp XArray. */
1457 VG_(dropTailXA
)(envp
, VG_(sizeXA
)(envp
));
1458 for (UInt i
= 0; child_envp
[i
] != NULL
; i
++) {
1459 VG_(addToXA
)(envp
, &child_envp
[i
]);
1461 VG_(free
)(child_envp
);
1463 if (trace_this_child
) {
1464 /* Set VALGRIND_LIB in envp. */
1465 SizeT len
= VG_(strlen
)(VALGRIND_LIB
) + VG_(strlen
)(VG_(libdir
)) + 2;
1466 HChar
*valstr
= VG_(malloc
)("syswrap.spawn.9", len
);
1467 VG_(sprintf
)(valstr
, "%s=%s", VALGRIND_LIB
, VG_(libdir
));
1468 VG_(addToXA
)(envp
, &valstr
);
1471 /* Set up the child's args. If not tracing it, they are left untouched.
1472 Otherwise, they are:
1474 [launcher_basename] ++ VG_(args_for_valgrind) ++ [ARG1] ++ ARG4[1..],
1476 except that the first VG_(args_for_valgrind_noexecpass) args are
1478 if (trace_this_child
) {
1479 vg_assert(VG_(args_for_valgrind
) != NULL
);
1480 vg_assert(VG_(args_for_valgrind_noexecpass
) >= 0);
1481 vg_assert(VG_(args_for_valgrind_noexecpass
)
1482 <= VG_(sizeXA
)(VG_(args_for_valgrind
)));
1484 /* So what args will there be? Bear with me... */
1485 /* ... launcher basename, ... */
1486 HChar
*duplicate
= VG_(strdup
)("syswrap.spawn.10", launcher_basename
);
1487 VG_(insertIndexXA
)(argv
, 0, &duplicate
);
1489 /* ... Valgrind's args, ... */
1490 UInt v_args
= VG_(sizeXA
)(VG_(args_for_valgrind
));
1491 v_args
-= VG_(args_for_valgrind_noexecpass
);
1492 for (Word i
= VG_(args_for_valgrind_noexecpass
);
1493 i
< VG_(sizeXA
)(VG_(args_for_valgrind
)); i
++) {
1494 duplicate
= VG_(strdup
)("syswrap.spawn.11",
1495 *(HChar
**) VG_(indexXA
)(VG_(args_for_valgrind
), i
));
1496 VG_(insertIndexXA
)(argv
, 1 + i
, &duplicate
);
1499 /* ... name of client executable, ... */
1500 duplicate
= VG_(strdup
)("syswrap.spawn.12", (HChar
*) ARG1
);
1501 VG_(insertIndexXA
)(argv
, 1 + v_args
, &duplicate
);
1503 /* ... and args for client executable (without [0]). */
1504 duplicate
= *(HChar
**) VG_(indexXA
)(argv
, 1 + v_args
+ 1);
1505 VG_(free
)(duplicate
);
1506 VG_(removeIndexXA
)(argv
, 1 + v_args
+ 1);
1509 /* Debug-only printing. */
1511 VG_(printf
)("\npath = %s\n", path
);
1512 VG_(printf
)("argv = ");
1513 for (Word i
= 0; i
< VG_(sizeXA
)(argv
); i
++) {
1514 VG_(printf
)("%s ", *(HChar
**) VG_(indexXA
)(argv
, i
));
1517 VG_(printf
)("\nenvp = ");
1518 for (Word i
= 0; i
< VG_(sizeXA
)(envp
); i
++) {
1519 VG_(printf
)("%s ", *(HChar
**) VG_(indexXA
)(envp
, i
));
1524 /* Set the signal state up for spawned child.
1526 Signals set to be caught are equivalent to signals set to the default
1527 action, from the child's perspective.
1529 Therefore query SCSS and prepare default (DFL) and ignore (IGN) signal
1530 sets. Then combine these sets with those passed from client, if flags
1531 POSIX_SPAWN_SETSIGDEF, or POSIX_SPAWN_SETSIGIGN_NP have been specified.
1533 vki_sigset_t sig_default
;
1534 vki_sigset_t sig_ignore
;
1535 VG_(sigemptyset
)(&sig_default
);
1536 VG_(sigemptyset
)(&sig_ignore
);
1537 for (Int i
= 1; i
< VG_(max_signal
); i
++) {
1538 vki_sigaction_fromK_t sa
;
1539 VG_(do_sys_sigaction
)(i
, NULL
, &sa
); /* query SCSS */
1540 if (sa
.sa_handler
== VKI_SIG_IGN
) {
1541 VG_(sigaddset
)(&sig_ignore
, i
);
1543 VG_(sigaddset
)(&sig_default
, i
);
1547 if (spa
->sa_psflags
& VKI_POSIX_SPAWN_SETSIGDEF
) {
1548 VG_(sigaddset_from_set
)(&spa
->sa_sigdefault
, &sig_default
);
1550 spa
->sa_psflags
|= VKI_POSIX_SPAWN_SETSIGDEF
;
1551 spa
->sa_sigdefault
= sig_default
;
1554 if (spa
->sa_psflags
& VKI_POSIX_SPAWN_SETSIGIGN_NP
) {
1555 VG_(sigaddset_from_set
)(&spa
->sa_sigignore
, &sig_ignore
);
1557 spa
->sa_psflags
|= VKI_POSIX_SPAWN_SETSIGIGN_NP
;
1558 spa
->sa_sigignore
= sig_ignore
;
1561 /* Set the signal mask for spawned child.
1563 Analogous to signal handlers: query SCSS for blocked signals mask
1564 and combine this mask with that passed from client, if flag
1565 POSIX_SPAWN_SETSIGMASK has been specified. */
1566 vki_sigset_t
*sigmask
= &VG_(get_ThreadState
)(tid
)->sig_mask
;
1567 if (spa
->sa_psflags
& VKI_POSIX_SPAWN_SETSIGMASK
) {
1568 VG_(sigaddset_from_set
)(&spa
->sa_sigmask
, sigmask
);
1570 spa
->sa_psflags
|= VKI_POSIX_SPAWN_SETSIGMASK
;
1571 spa
->sa_sigmask
= *sigmask
;
1574 /* Lastly, reconstruct argenv from argv + envp. */
1575 SizeT argenv_size
= 1 + 1;
1576 for (Word i
= 0; i
< VG_(sizeXA
)(argv
); i
++) {
1577 argenv_size
+= VG_(strlen
)(*(HChar
**) VG_(indexXA
)(argv
, i
)) + 2;
1579 for (Word i
= 0; i
< VG_(sizeXA
)(envp
); i
++) {
1580 argenv_size
+= VG_(strlen
)(*(HChar
**) VG_(indexXA
)(envp
, i
)) + 2;
1583 argenv
= VG_(malloc
)("syswrap.spawn.13", argenv_size
);
1584 HChar
*current
= argenv
;
1585 #define COPY_CHAR_TO_ARGENV(dst, character) \
1587 *(dst) = character; \
1590 #define COPY_STRING_TO_ARGENV(dst, src) \
1592 COPY_CHAR_TO_ARGENV(dst, '\1'); \
1593 SizeT src_len = VG_(strlen)((src)) + 1; \
1594 VG_(memcpy)((dst), (src), src_len); \
1598 for (Word i
= 0; i
< VG_(sizeXA
)(argv
); i
++) {
1599 COPY_STRING_TO_ARGENV(current
, *(HChar
**) VG_(indexXA
)(argv
, i
));
1601 COPY_CHAR_TO_ARGENV(current
, '\0');
1602 for (Word i
= 0; i
< VG_(sizeXA
)(envp
); i
++) {
1603 COPY_STRING_TO_ARGENV(current
, *(HChar
**) VG_(indexXA
)(envp
, i
));
1605 COPY_CHAR_TO_ARGENV(current
, '\0');
1606 vg_assert(current
== argenv
+ argenv_size
);
1607 #undef COPY_CHAR_TO_ARGENV
1608 #undef COPY_STRING_TOARGENV
1610 /* Actual spawn() syscall. */
1611 SysRes res
= VG_(do_syscall5
)(__NR_spawn
, (UWord
) path
, (UWord
) attrs
,
1612 attrs_size
, (UWord
) argenv
, argenv_size
);
1613 SET_STATUS_from_SysRes(res
);
1617 PRINT(" spawn: process %d spawned child %ld\n", VG_(getpid
)(), RES
);
1622 for (Word i
= 0; i
< VG_(sizeXA
)(argv
); i
++) {
1623 VG_(free
)(*(HChar
**) VG_(indexXA
)(argv
, i
));
1625 for (Word i
= 0; i
< VG_(sizeXA
)(envp
); i
++) {
1626 VG_(free
)(*(HChar
**) VG_(indexXA
)(envp
, i
));
1628 VG_(deleteXA
)(argv
);
1629 VG_(deleteXA
)(envp
);
1631 #endif /* SOLARIS_SPAWN_SYSCALL */
1633 /* Handles the case where the open is of /proc/self/psinfo or
1634 /proc/<pid>/psinfo. Fetch fresh contents into psinfo_t,
1635 fake fname, psargs, argc and argv. Write the structure to the fake
1636 file we cooked up at startup (in m_main) and give out a copy of this
1637 fd. Also seek the cloned fd back to the start. */
1638 static Bool
handle_psinfo_open(SyscallStatus
*status
,
1640 const HChar
*filename
,
1641 Int arg1
, UWord arg3
, UWord arg4
)
1643 if (!ML_(safe_to_deref
)((const void *) filename
, 1))
1646 HChar name
[VKI_PATH_MAX
]; // large enough
1647 VG_(sprintf
)(name
, "/proc/%d/psinfo", VG_(getpid
)());
1649 if (!VG_STREQ(filename
, name
) && !VG_STREQ(filename
, "/proc/self/psinfo"))
1652 /* Use original arguments to open() or openat(). */
1654 #if defined(SOLARIS_OLD_SYSCALLS)
1656 sres
= VG_(do_syscall4
)(SYS_openat
, arg1
, (UWord
) filename
,
1659 sres
= VG_(do_syscall3
)(SYS_open
, (UWord
) filename
, arg3
, arg4
);
1661 vg_assert(use_openat
== True
);
1662 sres
= VG_(do_syscall4
)(SYS_openat
, arg1
, (UWord
) filename
,
1664 #endif /* SOLARIS_OLD_SYSCALLS */
1666 if (sr_isError(sres
)) {
1667 SET_STATUS_from_SysRes(sres
);
1670 Int fd
= sr_Res(sres
);
1672 vki_psinfo_t psinfo
;
1673 sres
= VG_(do_syscall3
)(SYS_read
, fd
, (UWord
) &psinfo
, sizeof(psinfo
));
1674 if (sr_isError(sres
)) {
1675 SET_STATUS_from_SysRes(sres
);
1679 if (sr_Res(sres
) != sizeof(psinfo
)) {
1680 SET_STATUS_Failure(VKI_ENODATA
);
1687 VG_(client_fname
)(psinfo
.pr_fname
, sizeof(psinfo
.pr_fname
), True
);
1688 VG_(client_cmd_and_args
)(psinfo
.pr_psargs
, sizeof(psinfo
.pr_psargs
));
1690 Addr
*ptr
= (Addr
*) VG_(get_initial_client_SP
)();
1691 psinfo
.pr_argc
= *ptr
++;
1692 psinfo
.pr_argv
= (Addr
) ptr
;
1694 sres
= VG_(do_syscall4
)(SYS_pwrite
, VG_(cl_psinfo_fd
),
1695 (UWord
) &psinfo
, sizeof(psinfo
), 0);
1696 if (sr_isError(sres
)) {
1697 SET_STATUS_from_SysRes(sres
);
1701 sres
= VG_(dup
)(VG_(cl_psinfo_fd
));
1702 SET_STATUS_from_SysRes(sres
);
1703 if (!sr_isError(sres
)) {
1704 OffT off
= VG_(lseek
)(sr_Res(sres
), 0, VKI_SEEK_SET
);
1706 SET_STATUS_Failure(VKI_EMFILE
);
1712 #if defined(SOLARIS_PROC_CMDLINE)
1713 /* Handles the case where the open is of /proc/self/cmdline or
1714 /proc/<pid>/cmdline. Just give it a copy of VG_(cl_cmdline_fd) for the
1715 fake file we cooked up at startup (in m_main). Also, seek the
1716 cloned fd back to the start. */
1717 static Bool
handle_cmdline_open(SyscallStatus
*status
, const HChar
*filename
)
1719 if (!ML_(safe_to_deref
)((const void *) filename
, 1))
1722 HChar name
[VKI_PATH_MAX
]; // large enough
1723 VG_(sprintf
)(name
, "/proc/%d/cmdline", VG_(getpid
)());
1725 if (!VG_STREQ(filename
, name
) && !VG_STREQ(filename
, "/proc/self/cmdline"))
1728 SysRes sres
= VG_(dup
)(VG_(cl_cmdline_fd
));
1729 SET_STATUS_from_SysRes(sres
);
1730 if (!sr_isError(sres
)) {
1731 OffT off
= VG_(lseek
)(sr_Res(sres
), 0, VKI_SEEK_SET
);
1733 SET_STATUS_Failure(VKI_EMFILE
);
1738 #endif /* SOLARIS_PROC_CMDLINE */
1741 #if defined(SOLARIS_OLD_SYSCALLS)
1744 /* int open(const char *filename, int flags);
1745 int open(const char *filename, int flags, mode_t mode); */
1747 if (ARG2
& VKI_O_CREAT
) {
1749 PRINT("sys_open ( %#lx(%s), %ld, %lu )", ARG1
, (HChar
*) ARG1
,
1751 PRE_REG_READ3(long, "open", const char *, filename
,
1752 int, flags
, vki_mode_t
, mode
);
1755 PRINT("sys_open ( %#lx(%s), %ld )", ARG1
, (HChar
*) ARG1
, SARG2
);
1756 PRE_REG_READ2(long, "open", const char *, filename
, int, flags
);
1759 PRE_MEM_RASCIIZ("open(filename)", ARG1
);
1761 if (ML_(handle_auxv_open
)(status
, (const HChar
*)ARG1
, ARG2
))
1764 if (handle_psinfo_open(status
, False
/*use_openat*/, (const HChar
*)ARG1
, 0,
1768 *flags
|= SfMayBlock
;
1773 if (!ML_(fd_allowed
)(RES
, "open", tid
, True
)) {
1775 SET_STATUS_Failure(VKI_EMFILE
);
1776 } else if (VG_(clo_track_fds
))
1777 ML_(record_fd_open_with_given_name
)(tid
, RES
, (HChar
*) ARG1
);
1779 #endif /* SOLARIS_OLD_SYSCALLS */
1783 WRAPPER_PRE_NAME(generic
, sys_close
)(tid
, layout
, arrghs
, status
,
1789 WRAPPER_POST_NAME(generic
, sys_close
)(tid
, arrghs
, status
);
1790 door_record_revoke(tid
, ARG1
);
1791 /* Possibly an explicitly open'ed client door fd was just closed.
1792 Generic sys_close wrapper calls this only if VG_(clo_track_fds) = True. */
1793 if (!VG_(clo_track_fds
))
1794 ML_(record_fd_close
)(ARG1
);
1799 /* int linkat(int fd1, const char *path1, int fd2,
1800 const char *path2, int flag);
1803 /* Interpret the first and third arguments as 32-bit values even on 64-bit
1804 architecture. This is different from Linux, for example, where glibc
1805 sign-extends them. */
1806 Int fd1
= (Int
) ARG1
;
1807 Int fd2
= (Int
) ARG3
;
1809 PRINT("sys_linkat ( %d, %#lx(%s), %d, %#lx(%s), %ld )",
1810 fd1
, ARG2
, (HChar
*) ARG2
, fd2
, ARG4
, (HChar
*) ARG4
, SARG5
);
1811 PRE_REG_READ5(long, "linkat", int, fd1
, const char *, path1
,
1812 int, fd2
, const char *, path2
, int, flags
);
1813 PRE_MEM_RASCIIZ("linkat(path1)", ARG2
);
1814 PRE_MEM_RASCIIZ("linkat(path2)", ARG4
);
1816 /* Be strict but ignore fd1/fd2 for absolute path1/path2. */
1817 if (fd1
!= VKI_AT_FDCWD
1818 && ML_(safe_to_deref
)((void *) ARG2
, 1)
1819 && ((HChar
*) ARG2
)[0] != '/'
1820 && !ML_(fd_allowed
)(fd1
, "linkat", tid
, False
)) {
1821 SET_STATUS_Failure(VKI_EBADF
);
1823 if (fd2
!= VKI_AT_FDCWD
1824 && ML_(safe_to_deref
)((void *) ARG4
, 1)
1825 && ((HChar
*) ARG4
)[0] != '/'
1826 && !ML_(fd_allowed
)(fd2
, "linkat", tid
, False
)) {
1827 SET_STATUS_Failure(VKI_EBADF
);
1830 *flags
|= SfMayBlock
;
1835 /* int symlinkat(const char *path1, int fd, const char *path2); */
1837 /* Interpret the second argument as 32-bit value even on 64-bit architecture.
1838 This is different from Linux, for example, where glibc sign-extends it. */
1839 Int fd
= (Int
) ARG2
;
1841 PRINT("sys_symlinkat ( %#lx(%s), %d, %#lx(%s) )",
1842 ARG1
, (HChar
*) ARG1
, fd
, ARG3
, (HChar
*) ARG3
);
1843 PRE_REG_READ3(long, "symlinkat", const char *, path1
, int, fd
,
1844 const char *, path2
);
1845 PRE_MEM_RASCIIZ("symlinkat(path1)", ARG1
);
1846 PRE_MEM_RASCIIZ("symlinkat(path2)", ARG3
);
1848 /* Be strict but ignore fd for absolute path2. */
1849 if (fd
!= VKI_AT_FDCWD
1850 && ML_(safe_to_deref
)((void *) ARG3
, 1)
1851 && ((HChar
*) ARG3
)[0] != '/'
1852 && !ML_(fd_allowed
)(fd
, "symlinkat", tid
, False
))
1853 SET_STATUS_Failure(VKI_EBADF
);
1855 *flags
|= SfMayBlock
;
1860 /* time_t time(); */
1861 PRINT("sys_time ( )");
1862 PRE_REG_READ0(long, "time");
1865 /* Data segment for brk (heap). It is an expandable anonymous mapping
1866 abutting a 1-page reservation. The data segment starts at VG_(brk_base)
1867 and runs up to VG_(brk_limit). None of these two values have to be
1869 Initial data segment is established (see initimg-solaris.c for rationale):
1870 - directly during client program image initialization,
1871 - or on demand when the executed program is the runtime linker itself,
1872 after it has loaded its target dynamic executable (see PRE(sys_mmapobj)),
1873 or when the first brk() syscall is made.
1876 - VG_(brk_base) is not page aligned; does not move
1877 - VG_(brk_limit) moves between [VG_(brk_base), data segment end]
1878 - data segment end is always page aligned
1879 - right after data segment end is 1-page reservation
1882 +------+------+--------------+-------+
1883 | BSS | anon | anon | resvn |
1884 +------+------+--------------+-------+
1888 | | | data segment end
1889 | | VG_(brk_limit) -- no alignment constraint
1890 | brk_base_pgup -- page aligned
1891 VG_(brk_base) -- not page aligned -- does not move
1893 Because VG_(brk_base) is not page-aligned and is initially located within
1894 pre-established BSS (data) segment, special care has to be taken in the code
1895 below to handle this feature.
1897 Reservation segment is used to protect the data segment merging with
1898 a pre-existing segment. This should be no problem because address space
1899 manager ensures that requests for client address space are satisfied from
1900 the highest available addresses. However when memory is low, data segment
1901 can meet with mmap'ed objects and the reservation segment separates these.
1902 The page that contains VG_(brk_base) is already allocated by the program's
1903 loaded data segment. The brk syscall wrapper handles this special case. */
1905 static Bool brk_segment_established
= False
;
1907 /* Establishes initial data segment for brk (heap). */
1908 Bool
VG_(setup_client_dataseg
)(void)
1910 /* Segment size is initially at least 1 MB and at most 8 MB. */
1911 SizeT m1
= 1024 * 1024;
1913 SizeT initial_size
= VG_(client_rlimit_data
).rlim_cur
;
1914 VG_(debugLog
)(1, "syswrap-solaris", "Setup client data (brk) segment "
1915 "at %#lx\n", VG_(brk_base
));
1916 if (initial_size
< m1
)
1918 if (initial_size
> m8
)
1920 initial_size
= VG_PGROUNDUP(initial_size
);
1922 Addr anon_start
= VG_PGROUNDUP(VG_(brk_base
));
1923 SizeT anon_size
= VG_PGROUNDUP(initial_size
);
1924 Addr resvn_start
= anon_start
+ anon_size
;
1925 SizeT resvn_size
= VKI_PAGE_SIZE
;
1927 vg_assert(VG_IS_PAGE_ALIGNED(anon_size
));
1928 vg_assert(VG_IS_PAGE_ALIGNED(resvn_size
));
1929 vg_assert(VG_IS_PAGE_ALIGNED(anon_start
));
1930 vg_assert(VG_IS_PAGE_ALIGNED(resvn_start
));
1931 vg_assert(VG_(brk_base
) == VG_(brk_limit
));
1933 /* Find the loaded data segment and remember its protection. */
1934 const NSegment
*seg
= VG_(am_find_nsegment
)(VG_(brk_base
) - 1);
1935 vg_assert(seg
!= NULL
);
1936 UInt prot
= (seg
->hasR
? VKI_PROT_READ
: 0)
1937 | (seg
->hasW
? VKI_PROT_WRITE
: 0)
1938 | (seg
->hasX
? VKI_PROT_EXEC
: 0);
1940 /* Try to create the data segment and associated reservation where
1941 VG_(brk_base) says. */
1942 Bool ok
= VG_(am_create_reservation
)(resvn_start
, resvn_size
, SmLower
,
1945 /* That didn't work, we're hosed. */
1949 /* Map the data segment. */
1950 SysRes sres
= VG_(am_mmap_anon_fixed_client
)(anon_start
, anon_size
, prot
);
1951 vg_assert(!sr_isError(sres
));
1952 vg_assert(sr_Res(sres
) == anon_start
);
1954 brk_segment_established
= True
;
1958 /* Tell the tool about the client data segment and then kill it which will
1959 make it initially inaccessible/unaddressable. */
1960 void VG_(track_client_dataseg
)(ThreadId tid
)
1962 const NSegment
*seg
= VG_(am_find_nsegment
)(VG_PGROUNDUP(VG_(brk_base
)));
1963 vg_assert(seg
!= NULL
);
1964 vg_assert(seg
->kind
== SkAnonC
);
1966 VG_TRACK(new_mem_brk
, VG_(brk_base
), seg
->end
+ 1 - VG_(brk_base
), tid
);
1967 VG_TRACK(die_mem_brk
, VG_(brk_base
), seg
->end
+ 1 - VG_(brk_base
));
1970 static void PRINTF_CHECK(1, 2)
1971 possibly_complain_brk(const HChar
*format
, ...)
1973 static Bool alreadyComplained
= False
;
1974 if (!alreadyComplained
) {
1975 alreadyComplained
= True
;
1976 if (VG_(clo_verbosity
) > 0) {
1978 va_start(vargs
, format
);
1979 VG_(vmessage
)(Vg_UserMsg
, format
, vargs
);
1981 VG_(umsg
)("(See section Limitations in the user manual.)\n");
1982 VG_(umsg
)("NOTE: further instances of this message will not be "
1990 /* unsigned long brk(caddr_t end_data_segment); */
1991 /* The Solaris kernel returns 0 on success.
1992 In addition to this, brk(0) returns current data segment end. This is
1993 very different from the Linux kernel, for example. */
1995 Addr old_brk_limit
= VG_(brk_limit
);
1996 /* If VG_(brk_base) is page-aligned then old_brk_base_pgup is equal to
1998 Addr old_brk_base_pgup
= VG_PGROUNDUP(VG_(brk_base
));
1999 Addr new_brk
= ARG1
;
2000 const NSegment
*seg
, *seg2
;
2002 PRINT("sys_brk ( %#lx )", ARG1
);
2003 PRE_REG_READ1(unsigned long, "brk", vki_caddr_t
, end_data_segment
);
2006 /* brk(0) - specific to Solaris 11 only. */
2007 SET_STATUS_Success(old_brk_limit
);
2011 /* Handle some trivial cases. */
2012 if (new_brk
== old_brk_limit
) {
2013 SET_STATUS_Success(0);
2016 if (new_brk
< VG_(brk_base
)) {
2017 /* Clearly impossible. */
2018 SET_STATUS_Failure(VKI_ENOMEM
);
2021 if (new_brk
- VG_(brk_base
) > VG_(client_rlimit_data
).rlim_cur
) {
2022 SET_STATUS_Failure(VKI_ENOMEM
);
2026 /* The brk base and limit must have been already set. */
2027 vg_assert(VG_(brk_base
) != -1);
2028 vg_assert(VG_(brk_limit
) != -1);
2030 if (!brk_segment_established
) {
2031 /* Stay sane (because there should have been no brk activity yet). */
2032 vg_assert(VG_(brk_base
) == VG_(brk_limit
));
2034 if (!VG_(setup_client_dataseg
)()) {
2035 possibly_complain_brk("Cannot map memory to initialize brk segment in "
2036 "thread #%u at %#lx\n", tid
, VG_(brk_base
));
2037 SET_STATUS_Failure(VKI_ENOMEM
);
2041 VG_(track_client_dataseg
)(tid
);
2044 if (new_brk
< old_brk_limit
) {
2045 /* Shrinking the data segment. Be lazy and don't munmap the excess
2047 if (old_brk_limit
> old_brk_base_pgup
) {
2048 /* Calculate new local brk (=MAX(new_brk, old_brk_base_pgup)). */
2050 if (new_brk
< old_brk_base_pgup
)
2051 new_brk_local
= old_brk_base_pgup
;
2053 new_brk_local
= new_brk
;
2055 /* Find a segment at the beginning and at the end of the shrinked
2057 seg
= VG_(am_find_nsegment
)(new_brk_local
);
2058 seg2
= VG_(am_find_nsegment
)(old_brk_limit
- 1);
2060 vg_assert(seg
->kind
== SkAnonC
);
2062 vg_assert(seg
== seg2
);
2064 /* Discard any translations and zero-out the area. */
2066 VG_(discard_translations
)(new_brk_local
,
2067 old_brk_limit
- new_brk_local
,
2069 /* Since we're being lazy and not unmapping pages, we have to zero out
2070 the area, so that if the area later comes back into circulation, it
2071 will be filled with zeroes, as if it really had been unmapped and
2072 later remapped. Be a bit paranoid and try hard to ensure we're not
2073 going to segfault by doing the write - check that segment is
2076 VG_(memset
)((void*)new_brk_local
, 0, old_brk_limit
- new_brk_local
);
2079 /* Fixup code if the VG_(brk_base) is not page-aligned. */
2080 if (new_brk
< old_brk_base_pgup
) {
2081 /* Calculate old local brk (=MIN(old_brk_limit, old_brk_base_up)). */
2083 if (old_brk_limit
< old_brk_base_pgup
)
2084 old_brk_local
= old_brk_limit
;
2086 old_brk_local
= old_brk_base_pgup
;
2088 /* Find a segment at the beginning and at the end of the shrinked
2090 seg
= VG_(am_find_nsegment
)(new_brk
);
2091 seg2
= VG_(am_find_nsegment
)(old_brk_local
- 1);
2094 vg_assert(seg
== seg2
);
2096 /* Discard any translations and zero-out the area. */
2098 VG_(discard_translations
)(new_brk
, old_brk_local
- new_brk
,
2101 VG_(memset
)((void*)new_brk
, 0, old_brk_local
- new_brk
);
2104 /* We are done, update VG_(brk_limit), tell the tool about the changes,
2106 VG_(brk_limit
) = new_brk
;
2107 VG_TRACK(die_mem_brk
, new_brk
, old_brk_limit
- new_brk
);
2108 SET_STATUS_Success(0);
2112 /* We are expanding the brk segment. */
2114 /* Fixup code if the VG_(brk_base) is not page-aligned. */
2115 if (old_brk_limit
< old_brk_base_pgup
) {
2116 /* Calculate new local brk (=MIN(new_brk, old_brk_base_pgup)). */
2118 if (new_brk
< old_brk_base_pgup
)
2119 new_brk_local
= new_brk
;
2121 new_brk_local
= old_brk_base_pgup
;
2123 /* Find a segment at the beginning and at the end of the expanded
2125 seg
= VG_(am_find_nsegment
)(old_brk_limit
);
2126 seg2
= VG_(am_find_nsegment
)(new_brk_local
- 1);
2129 vg_assert(seg
== seg2
);
2131 /* Nothing else to do. */
2134 if (new_brk
> old_brk_base_pgup
) {
2135 /* Calculate old local brk (=MAX(old_brk_limit, old_brk_base_pgup)). */
2137 if (old_brk_limit
< old_brk_base_pgup
)
2138 old_brk_local
= old_brk_base_pgup
;
2140 old_brk_local
= old_brk_limit
;
2142 /* Find a segment at the beginning of the expanded range. */
2143 if (old_brk_local
> old_brk_base_pgup
)
2144 seg
= VG_(am_find_nsegment
)(old_brk_local
- 1);
2146 seg
= VG_(am_find_nsegment
)(old_brk_local
);
2148 vg_assert(seg
->kind
== SkAnonC
);
2150 /* Find the 1-page reservation segment. */
2151 seg2
= VG_(am_next_nsegment
)(seg
, True
/*forwards*/);
2153 vg_assert(seg2
->kind
== SkResvn
);
2154 vg_assert(seg
->end
+ 1 == seg2
->start
);
2155 vg_assert(seg2
->end
- seg2
->start
+ 1 == VKI_PAGE_SIZE
);
2157 if (new_brk
<= seg2
->start
) {
2158 /* Still fits within the existing anon segment, nothing to do. */
2160 /* Data segment limit was already checked. */
2161 Addr anon_start
= seg
->end
+ 1;
2162 Addr resvn_start
= VG_PGROUNDUP(new_brk
);
2163 SizeT anon_size
= resvn_start
- anon_start
;
2164 SizeT resvn_size
= VKI_PAGE_SIZE
;
2167 vg_assert(VG_IS_PAGE_ALIGNED(anon_size
));
2168 vg_assert(VG_IS_PAGE_ALIGNED(resvn_size
));
2169 vg_assert(VG_IS_PAGE_ALIGNED(anon_start
));
2170 vg_assert(VG_IS_PAGE_ALIGNED(resvn_start
));
2171 vg_assert(anon_size
> 0);
2173 /* Address space manager checks for free address space for us;
2174 reservation would not be otherwise created. */
2175 Bool ok
= VG_(am_create_reservation
)(resvn_start
, resvn_size
, SmLower
,
2178 possibly_complain_brk("brk segment overflow in thread #%u: can not "
2179 "grow to %#lx\n", tid
, new_brk
);
2180 SET_STATUS_Failure(VKI_ENOMEM
);
2184 /* Establish protection from the existing segment. */
2185 UInt prot
= (seg
->hasR
? VKI_PROT_READ
: 0)
2186 | (seg
->hasW
? VKI_PROT_WRITE
: 0)
2187 | (seg
->hasX
? VKI_PROT_EXEC
: 0);
2189 /* Address space manager will merge old and new data segments. */
2190 sres
= VG_(am_mmap_anon_fixed_client
)(anon_start
, anon_size
, prot
);
2191 if (sr_isError(sres
)) {
2192 possibly_complain_brk("Cannot map memory to grow brk segment in "
2193 "thread #%u to %#lx\n", tid
, new_brk
);
2194 SET_STATUS_Failure(VKI_ENOMEM
);
2197 vg_assert(sr_Res(sres
) == anon_start
);
2199 seg
= VG_(am_find_nsegment
)(old_brk_base_pgup
);
2200 seg2
= VG_(am_find_nsegment
)(VG_PGROUNDUP(new_brk
) - 1);
2203 vg_assert(seg
== seg2
);
2204 vg_assert(new_brk
<= seg
->end
+ 1);
2208 /* We are done, update VG_(brk_limit), tell the tool about the changes, and
2210 VG_(brk_limit
) = new_brk
;
2211 VG_TRACK(new_mem_brk
, old_brk_limit
, new_brk
- old_brk_limit
, tid
);
2212 SET_STATUS_Success(0);
2217 /* int stat(const char *path, struct stat *buf); */
2218 /* Note: We could use here the sys_newstat generic wrapper, but the 'new'
2219 in its name is rather confusing in the Solaris context, thus we provide
2221 PRINT("sys_stat ( %#lx(%s), %#lx )", ARG1
, (HChar
*) ARG1
, ARG2
);
2222 PRE_REG_READ2(long, "stat", const char *, path
, struct stat
*, buf
);
2224 PRE_MEM_RASCIIZ("stat(path)", ARG1
);
2225 PRE_MEM_WRITE("stat(buf)", ARG2
, sizeof(struct vki_stat
));
2230 POST_MEM_WRITE(ARG2
, sizeof(struct vki_stat
));
2235 /* off_t lseek(int fildes, off_t offset, int whence); */
2236 PRINT("sys_lseek ( %ld, %ld, %ld )", SARG1
, SARG2
, SARG3
);
2237 PRE_REG_READ3(long, "lseek", int, fildes
, vki_off_t
, offset
, int, whence
);
2240 if (!ML_(fd_allowed
)(ARG1
, "lseek", tid
, False
))
2241 SET_STATUS_Failure(VKI_EBADF
);
2246 /* int mount(const char *spec, const char *dir, int mflag, char *fstype,
2247 char *dataptr, int datalen, char *optptr, int optlen); */
2248 *flags
|= SfMayBlock
;
2249 if (ARG3
& VKI_MS_OPTIONSTR
) {
2250 /* 8-argument mount */
2251 PRINT("sys_mount ( %#lx(%s), %#lx(%s), %ld, %#lx(%s), %#lx, %lu, "
2252 "%#lx(%s), %ld )", ARG1
, (HChar
*) ARG1
, ARG2
, (HChar
*) ARG2
, SARG3
,
2253 ARG4
, (HChar
*) ARG4
, ARG5
, ARG6
, ARG7
, (HChar
*) ARG7
, SARG8
);
2254 PRE_REG_READ8(long, "mount", const char *, spec
, const char *, dir
,
2255 int, mflag
, char *, fstype
, char *, dataptr
, int, datalen
,
2256 char *, optptr
, int, optlen
);
2258 else if (ARG3
& VKI_MS_DATA
) {
2259 /* 6-argument mount */
2260 PRINT("sys_mount ( %#lx(%s), %#lx(%s), %ld, %#lx(%s), %#lx, %ld )",
2261 ARG1
, (HChar
*) ARG1
, ARG2
, (HChar
*) ARG2
, SARG3
, ARG4
,
2262 (HChar
*) ARG4
, ARG5
, SARG6
);
2263 PRE_REG_READ6(long, "mount", const char *, spec
, const char *, dir
,
2264 int, mflag
, char *, fstype
, char *, dataptr
,
2268 /* 4-argument mount */
2269 PRINT("sys_mount ( %#lx(%s), %#lx(%s), %ld, %#lx(%s) )", ARG1
,
2270 (HChar
*) ARG1
, ARG2
, (HChar
*) ARG2
, SARG3
, ARG4
, (HChar
*) ARG4
);
2271 PRE_REG_READ4(long, "mount", const char *, spec
, const char *, dir
,
2272 int, mflag
, char *, fstype
);
2275 PRE_MEM_RASCIIZ("mount(spec)", ARG1
);
2276 PRE_MEM_RASCIIZ("mount(dir)", ARG2
);
2277 if (ARG4
&& ARG4
>= 256) {
2278 /* If ARG4 < 256, then it's an index to a fs table in the kernel. */
2279 PRE_MEM_RASCIIZ("mount(fstype)", ARG4
);
2281 if (ARG3
& (VKI_MS_DATA
| VKI_MS_OPTIONSTR
)) {
2283 PRE_MEM_READ("mount(dataptr)", ARG5
, ARG6
);
2284 if ((ARG3
& VKI_MS_OPTIONSTR
) && ARG7
) {
2286 PRE_MEM_RASCIIZ("mount(optptr)", ARG7
);
2287 PRE_MEM_WRITE("mount(optptr)", ARG7
, ARG8
);
2294 if (ARG3
& VKI_MS_OPTIONSTR
) {
2295 POST_MEM_WRITE(ARG7
, VG_(strlen
)((HChar
*)ARG7
) + 1);
2296 } else if (ARG3
& VKI_MS_DATA
) {
2298 (ARG3
& MS_NOMNTTAB
) &&
2299 (VG_STREQ((HChar
*) ARG4
, "namefs")) &&
2300 (ARG6
== sizeof(struct vki_namefd
)) &&
2301 ML_(safe_to_deref
)((void *) ARG5
, ARG6
)) {
2302 /* Most likely an fattach() call for a door file descriptor. */
2303 door_record_server_fattach(((struct vki_namefd
*) ARG5
)->fd
,
2311 /* ssize_t readlinkat(int dfd, const char *path, char *buf,
2313 HChar name
[30]; // large enough
2316 /* Interpret the first argument as 32-bit value even on 64-bit architecture.
2317 This is different from Linux, for example, where glibc sign-extends it. */
2318 Int dfd
= (Int
) ARG1
;
2320 PRINT("sys_readlinkat ( %d, %#lx(%s), %#lx, %ld )", dfd
, ARG2
,
2321 (HChar
*) ARG2
, ARG3
, SARG4
);
2322 PRE_REG_READ4(long, "readlinkat", int, dfd
, const char *, path
,
2323 char *, buf
, int, bufsiz
);
2324 PRE_MEM_RASCIIZ("readlinkat(path)", ARG2
);
2325 PRE_MEM_WRITE("readlinkat(buf)", ARG3
, ARG4
);
2327 /* Be strict but ignore dfd for absolute path. */
2328 if (dfd
!= VKI_AT_FDCWD
2329 && ML_(safe_to_deref
)((void *) ARG2
, 1)
2330 && ((HChar
*) ARG2
)[0] != '/'
2331 && !ML_(fd_allowed
)(dfd
, "readlinkat", tid
, False
)) {
2332 SET_STATUS_Failure(VKI_EBADF
);
2336 /* Handle the case where readlinkat is looking at /proc/self/path/a.out or
2337 /proc/<pid>/path/a.out. */
2338 VG_(sprintf
)(name
, "/proc/%d/path/a.out", VG_(getpid
)());
2339 if (ML_(safe_to_deref
)((void*)ARG2
, 1) &&
2340 (!VG_(strcmp
)((HChar
*)ARG2
, name
) ||
2341 !VG_(strcmp
)((HChar
*)ARG2
, "/proc/self/path/a.out"))) {
2342 VG_(sprintf
)(name
, "/proc/self/path/%d", VG_(cl_exec_fd
));
2343 SET_STATUS_from_SysRes(VG_(do_syscall4
)(saved
, dfd
, (UWord
)name
, ARG3
,
2348 POST(sys_readlinkat
)
2350 POST_MEM_WRITE(ARG3
, RES
);
2355 /* Kernel: int stime(time_t time); */
2356 PRINT("sys_stime ( %lu )", ARG1
);
2357 PRE_REG_READ1(long, "stime", vki_time_t
, time
);
2362 /* int fstat(int fildes, struct stat *buf); */
2363 /* Note: We could use here the sys_newfstat generic wrapper, but the 'new'
2364 in its name is rather confusing in the Solaris context, thus we provide
2366 PRINT("sys_fstat ( %ld, %#lx )", SARG1
, ARG2
);
2367 PRE_REG_READ2(long, "fstat", int, fildes
, struct stat
*, buf
);
2368 PRE_MEM_WRITE("fstat(buf)", ARG2
, sizeof(struct vki_stat
));
2371 if (!ML_(fd_allowed
)(ARG1
, "fstat", tid
, False
))
2372 SET_STATUS_Failure(VKI_EBADF
);
2377 POST_MEM_WRITE(ARG2
, sizeof(struct vki_stat
));
2380 #if defined(SOLARIS_FREALPATHAT_SYSCALL)
2381 PRE(sys_frealpathat
)
2383 /* int frealpathat(int fd, char *path, char *buf, size_t buflen); */
2385 /* Interpret the first argument as 32-bit value even on 64-bit architecture.
2386 This is different from Linux, for example, where glibc sign-extends it. */
2387 Int fd
= (Int
) ARG1
;
2389 PRINT("sys_frealpathat ( %d, %#lx(%s), %#lx, %lu )",
2390 fd
, ARG2
, (HChar
*) ARG2
, ARG3
, ARG4
);
2391 PRE_REG_READ4(long, "frealpathat", int, fd
, char *, path
,
2392 char *, buf
, vki_size_t
, buflen
);
2393 PRE_MEM_RASCIIZ("frealpathat(path)", ARG2
);
2394 PRE_MEM_WRITE("frealpathat(buf)", ARG3
, ARG4
);
2396 /* Be strict but ignore fd for absolute path. */
2397 if (fd
!= VKI_AT_FDCWD
2398 && ML_(safe_to_deref
)((void *) ARG2
, 1)
2399 && ((HChar
*) ARG2
)[0] != '/'
2400 && !ML_(fd_allowed
)(fd
, "frealpathat", tid
, False
))
2401 SET_STATUS_Failure(VKI_EBADF
);
2404 POST(sys_frealpathat
)
2406 POST_MEM_WRITE(ARG3
, VG_(strlen
)((HChar
*) ARG3
) + 1);
2408 #endif /* SOLARIS_FREALPATHAT_SYSCALL */
2412 /* int stty(int fd, const struct sgttyb *tty); */
2413 PRINT("sys_stty ( %ld, %#lx )", SARG1
, ARG2
);
2414 PRE_REG_READ2(long, "stty", int, fd
,
2415 const struct vki_sgttyb
*, tty
);
2416 PRE_MEM_READ("stty(tty)", ARG2
, sizeof(struct vki_sgttyb
));
2419 if (!ML_(fd_allowed
)(ARG1
, "stty", tid
, False
))
2420 SET_STATUS_Failure(VKI_EBADF
);
2425 /* int gtty(int fd, struct sgttyb *tty); */
2426 PRINT("sys_gtty ( %ld, %#lx )", SARG1
, ARG2
);
2427 PRE_REG_READ2(long, "gtty", int, fd
, struct vki_sgttyb
*, tty
);
2428 PRE_MEM_WRITE("gtty(tty)", ARG2
, sizeof(struct vki_sgttyb
));
2431 if (!ML_(fd_allowed
)(ARG1
, "gtty", tid
, False
))
2432 SET_STATUS_Failure(VKI_EBADF
);
2437 POST_MEM_WRITE(ARG2
, sizeof(struct vki_sgttyb
));
2442 /* Kernel: int setpgrp(int flag, int pid, int pgid); */
2443 switch (ARG1
/*flag*/) {
2445 /* Libc: pid_t getpgrp(void); */
2446 PRINT("sys_pgrpsys ( %ld )", SARG1
);
2447 PRE_REG_READ1(long, SC2("pgrpsys", "getpgrp"), int, flag
);
2450 /* Libc: pid_t setpgrp(void); */
2451 PRINT("sys_pgrpsys ( %ld )", SARG1
);
2452 PRE_REG_READ1(long, SC2("pgrpsys", "setpgrp"), int, flag
);
2455 /* Libc: pid_t getsid(pid_t pid); */
2456 PRINT("sys_pgrpsys ( %ld, %ld )", SARG1
, SARG2
);
2457 PRE_REG_READ2(long, SC2("pgrpsys", "getsid"), int, flag
,
2461 /* Libc: pid_t setsid(void); */
2462 PRINT("sys_pgrpsys ( %ld )", SARG1
);
2463 PRE_REG_READ1(long, SC2("pgrpsys", "setsid"), int, flag
);
2466 /* Libc: pid_t getpgid(pid_t pid); */
2467 PRINT("sys_pgrpsys ( %ld, %ld )", SARG1
, SARG2
);
2468 PRE_REG_READ2(long, SC2("pgrpsys", "getpgid"), int, flag
,
2472 /* Libc: int setpgid(pid_t pid, pid_t pgid); */
2473 PRINT("sys_pgrpsys ( %ld, %ld, %ld )", SARG1
, SARG2
, SARG3
);
2474 PRE_REG_READ3(long, SC2("pgrpsys", "setpgid"), int, flag
,
2475 vki_pid_t
, pid
, vki_pid_t
, pgid
);
2478 VG_(unimplemented
)("Syswrap of the pgrpsys call with flag %ld.", SARG1
);
2486 #if defined(SOLARIS_NEW_PIPE_SYSCALL)
2487 /* int pipe(int fildes[2], int flags); */
2488 PRINT("sys_pipe ( %#lx, %ld )", ARG1
, SARG2
);
2489 PRE_REG_READ2(long, "pipe", int *, fildes
, int, flags
);
2490 PRE_MEM_WRITE("pipe(fildes)", ARG1
, 2 * sizeof(int));
2492 /* longlong_t pipe(); */
2493 PRINT("sys_pipe ( )");
2494 PRE_REG_READ0(long, "pipe");
2495 #endif /* SOLARIS_NEW_PIPE_SYSCALL */
2502 #if defined(SOLARIS_NEW_PIPE_SYSCALL)
2503 int *fds
= (int*)ARG1
;
2506 POST_MEM_WRITE(ARG1
, 2 * sizeof(int));
2510 #endif /* SOLARIS_NEW_PIPE_SYSCALL */
2512 if (!ML_(fd_allowed
)(p0
, "pipe", tid
, True
) ||
2513 !ML_(fd_allowed
)(p1
, "pipe", tid
, True
)) {
2516 SET_STATUS_Failure(VKI_EMFILE
);
2518 else if (VG_(clo_track_fds
)) {
2519 ML_(record_fd_open_nameless
)(tid
, p0
);
2520 ML_(record_fd_open_nameless
)(tid
, p1
);
2526 /* int faccessat(int fd, const char *path, int amode, int flag); */
2528 /* Interpret the first argument as 32-bit value even on 64-bit architecture.
2529 This is different from Linux, for example, where glibc sign-extends it. */
2530 Int fd
= (Int
) ARG1
;
2532 PRINT("sys_faccessat ( %d, %#lx(%s), %ld, %ld )", fd
, ARG2
,
2533 (HChar
*) ARG2
, SARG3
, SARG4
);
2534 PRE_REG_READ4(long, "faccessat", int, fd
, const char *, path
,
2535 int, amode
, int, flag
);
2536 PRE_MEM_RASCIIZ("faccessat(path)", ARG2
);
2538 /* Be strict but ignore fd for absolute path. */
2539 if (fd
!= VKI_AT_FDCWD
2540 && ML_(safe_to_deref
)((void *) ARG2
, 1)
2541 && ((HChar
*) ARG2
)[0] != '/'
2542 && !ML_(fd_allowed
)(fd
, "faccessat", tid
, False
))
2543 SET_STATUS_Failure(VKI_EBADF
);
2548 /* int mknodat(int fd, char *fname, mode_t fmode, dev_t dev); */
2550 /* Interpret the first argument as 32-bit value even on 64-bit architecture.
2551 This is different from Linux, for example, where glibc sign-extends it. */
2552 Int fd
= (Int
) ARG1
;
2554 PRINT("sys_mknodat ( %d, %#lx(%s), %ld, %ld )", fd
, ARG2
,
2555 (HChar
*) ARG2
, SARG3
, SARG4
);
2556 PRE_REG_READ4(long, "mknodat", int, fd
, const char *, fname
,
2557 vki_mode_t
, fmode
, vki_dev_t
, dev
);
2558 PRE_MEM_RASCIIZ("mknodat(fname)", ARG2
);
2560 /* Be strict but ignore fd for absolute path. */
2561 if (fd
!= VKI_AT_FDCWD
2562 && ML_(safe_to_deref
)((void *) ARG2
, 1)
2563 && ((HChar
*) ARG2
)[0] != '/'
2564 && !ML_(fd_allowed
)(fd
, "mknodat", tid
, False
))
2565 SET_STATUS_Failure(VKI_EBADF
);
2567 *flags
|= SfMayBlock
;
2572 if (!ML_(fd_allowed
)(RES
, "mknodat", tid
, True
)) {
2574 SET_STATUS_Failure(VKI_EMFILE
);
2575 } else if (VG_(clo_track_fds
))
2576 ML_(record_fd_open_with_given_name
)(tid
, RES
, (HChar
*) ARG2
);
2581 /* int sysi86(int cmd, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3); */
2582 PRINT("sys_sysi86 ( %ld, %#lx, %#lx, %#lx )", SARG1
, ARG2
, ARG3
, ARG4
);
2583 PRE_REG_READ4(long, "sysi86", int, cmd
, uintptr_t, arg1
, uintptr_t, arg2
,
2586 switch (ARG1
/*cmd*/) {
2587 case VKI_SI86FPSTART
:
2588 PRE_MEM_WRITE("sysi86(fp_hw)", ARG2
, sizeof(vki_uint_t
));
2589 /* ARG3 is a desired x87 FCW value, ARG4 is a desired SSE MXCSR value.
2590 They are passed to the kernel but V will change them later anyway
2591 (this is a general Valgrind limitation described in the official
2595 VG_(unimplemented
)("Syswrap of the sysi86 call with cmd %ld.", SARG1
);
2603 switch (ARG1
/*cmd*/) {
2604 case VKI_SI86FPSTART
:
2605 POST_MEM_WRITE(ARG2
, sizeof(vki_uint_t
));
2615 /* Kernel: uintptr_t shmsys(int opcode, uintptr_t a0, uintptr_t a1,
2616 uintptr_t a2, uintptr_t a3);
2618 *flags
|= SfMayBlock
;
2620 switch (ARG1
/*opcode*/) {
2622 /* Libc: void *shmat(int shmid, const void *shmaddr, int shmflg); */
2623 PRINT("sys_shmsys ( %ld, %ld, %#lx, %ld )",
2624 SARG1
, SARG2
, ARG3
, SARG4
);
2625 PRE_REG_READ4(long, SC2("shmsys", "shmat"), int, opcode
,
2626 int, shmid
, const void *, shmaddr
, int, shmflg
);
2628 UWord addr
= ML_(generic_PRE_sys_shmat
)(tid
, ARG2
, ARG3
, ARG4
);
2630 SET_STATUS_Failure(VKI_EINVAL
);
2636 /* Libc: int shmctl(int shmid, int cmd, struct shmid_ds *buf); */
2637 switch (ARG3
/* cmd */) {
2639 PRINT("sys_shmsys ( %ld, %ld, %ld )", SARG1
, SARG2
, SARG3
);
2640 PRE_REG_READ3(long, SC3("shmsys", "shmctl", "lock"),
2641 int, opcode
, int, shmid
, int, cmd
);
2643 case VKI_SHM_UNLOCK
:
2644 PRINT("sys_shmsys ( %ld, %ld, %ld )", SARG1
, SARG2
, SARG3
);
2645 PRE_REG_READ3(long, SC3("shmsys", "shmctl", "unlock"),
2646 int, opcode
, int, shmid
, int, cmd
);
2649 PRINT("sys_shmsys ( %ld, %ld, %ld )", SARG1
, SARG2
, SARG3
);
2650 PRE_REG_READ3(long, SC3("shmsys", "shmctl", "rmid"),
2651 int, opcode
, int, shmid
, int, cmd
);
2654 PRINT("sys_shmsys ( %ld, %ld, %ld, %#lx )",
2655 SARG1
, SARG2
, SARG3
, ARG4
);
2656 PRE_REG_READ4(long, SC3("shmsys", "shmctl", "set"),
2657 int, opcode
, int, shmid
, int, cmd
,
2658 struct vki_shmid_ds
*, buf
);
2660 struct vki_shmid_ds
*buf
= (struct vki_shmid_ds
*) ARG4
;
2661 PRE_FIELD_READ("shmsys(shmctl, ipc_set, buf->shm_perm.uid)",
2663 PRE_FIELD_READ("shmsys(shmctl, ipc_set, buf->shm_perm.gid)",
2665 PRE_FIELD_READ("shmsys(shmctl, ipc_set, buf->shm_perm.mode)",
2666 buf
->shm_perm
.mode
);
2669 PRINT("sys_shmsys ( %ld, %ld, %ld, %#lx )",
2670 SARG1
, SARG2
, SARG3
, ARG4
);
2671 PRE_REG_READ4(long, SC3("shmsys", "shmctl", "stat"),
2672 int, opcode
, int, shmid
, int, cmd
,
2673 struct vki_shmid_ds
*, buf
);
2674 PRE_MEM_WRITE("shmsys(shmctl, ipc_stat, buf)", ARG4
,
2675 sizeof(struct vki_shmid_ds
));
2678 PRINT("sys_shmsys ( %ld, %ld, %ld, %#lx )",
2679 SARG1
, SARG2
, SARG3
, ARG4
);
2680 PRE_REG_READ4(long, SC3("shmsys", "shmctl", "set64"),
2681 int, opcode
, int, shmid
, int, cmd
,
2682 struct vki_shmid_ds64
*, buf
);
2684 struct vki_shmid_ds64
*buf64
= (struct vki_shmid_ds64
*) ARG4
;
2685 PRE_FIELD_READ("shmsys(shmctl, ipc_set64, "
2686 "buf->shmx_perm.ipcx_uid)",
2687 buf64
->shmx_perm
.ipcx_uid
);
2688 PRE_FIELD_READ("shmsys(shmctl, ipc_set64, "
2689 "buf->shmx_perm.ipcx_gid)",
2690 buf64
->shmx_perm
.ipcx_gid
);
2691 PRE_FIELD_READ("shmsys(shmctl, ipc_set64, "
2692 "buf->shmx_perm.ipcx_mode)",
2693 buf64
->shmx_perm
.ipcx_mode
);
2695 case VKI_IPC_STAT64
:
2696 PRINT("sys_shmsys ( %ld, %ld, %ld, %#lx )",
2697 SARG1
, SARG2
, SARG3
, ARG4
);
2698 PRE_REG_READ4(long, SC3("shmsys", "shmctl", "stat64"),
2699 int, opcode
, int, shmid
, int, cmd
,
2700 struct vki_shmid_ds64
*, buf
);
2701 PRE_MEM_WRITE("shmsys(shmctl, ipc_stat64, buf)", ARG4
,
2702 sizeof(struct vki_shmid_ds64
));
2704 #if defined(SOLARIS_SHM_NEW)
2705 case VKI_IPC_XSTAT64
:
2706 PRINT("sys_shmsys ( %ld, %ld, %ld, %#lx )",
2707 SARG1
, SARG2
, SARG3
, ARG4
);
2708 PRE_REG_READ4(long, SC3("shmsys", "shmctl", "xstat64"),
2709 int, opcode
, int, shmid
, int, cmd
,
2710 struct vki_shmid_ds64
*, buf
);
2711 PRE_MEM_WRITE("shmsys(shmctl, ipc_xstat64, buf)", ARG4
,
2712 sizeof(struct vki_shmid_xds64
));
2714 #endif /* SOLARIS_SHM_NEW */
2716 VG_(unimplemented
)("Syswrap of the shmsys(shmctl) call with "
2724 /* Libc: int shmdt(const void *shmaddr); */
2725 PRINT("sys_shmsys ( %ld, %#lx )", SARG1
, ARG2
);
2726 PRE_REG_READ2(long, SC2("shmsys", "shmdt"), int, opcode
,
2727 const void *, shmaddr
);
2729 if (!ML_(generic_PRE_sys_shmdt
)(tid
, ARG2
))
2730 SET_STATUS_Failure(VKI_EINVAL
);
2734 /* Libc: int shmget(key_t key, size_t size, int shmflg); */
2735 PRINT("sys_shmsys ( %ld, %ld, %lu, %lu )",
2736 SARG1
, SARG2
, ARG3
, ARG4
);
2737 PRE_REG_READ4(long, SC2("shmsys", "shmget"), int, opcode
,
2738 vki_key_t
, key
, vki_size_t
, size
, int, shmflg
);
2742 /* Libc: int shmids(int *buf, uint_t nids, uint_t *pnids); */
2743 PRINT("sys_shmsys ( %ld, %#lx, %lu, %#lx )",
2744 SARG1
, ARG2
, ARG3
, ARG4
);
2745 PRE_REG_READ4(long, SC2("shmsys", "shmids"), int, opcode
,
2746 int *, buf
, vki_uint_t
, nids
, vki_uint_t
*, pnids
);
2748 PRE_MEM_WRITE("shmsys(shmids, buf)", ARG2
, ARG3
* sizeof(int *));
2749 PRE_MEM_WRITE("shmsys(shmids, pnids)", ARG4
, sizeof(vki_uint_t
));
2752 #if defined(SOLARIS_SHM_NEW)
2754 /* Libc: int shmadv(int shmid, uint_t cmd, uint_t *advice); */
2755 PRINT("sys_shmsys ( %ld, %ld, %lu, %ld )",
2756 SARG1
, SARG2
, ARG3
, ARG4
);
2757 PRE_REG_READ4(long, SC2("shmsys", "shmadv"), int, opcode
,
2758 int, shmid
, vki_uint_t
, cmd
, vki_uint_t
*, advice
);
2760 switch (ARG3
/*cmd*/) {
2761 case VKI_SHM_ADV_GET
:
2762 PRE_MEM_WRITE("shmsys(shmadv, advice)", ARG4
,
2763 sizeof(vki_uint_t
));
2765 case VKI_SHM_ADV_SET
:
2766 PRE_MEM_READ("shmsys(shmadv, advice)", ARG4
,
2767 sizeof(vki_uint_t
));
2770 VG_(unimplemented
)("Syswrap of the shmsys(shmadv) call with "
2777 case VKI_SHMGET_OSM
:
2778 /* Libc: int shmget_osm(key_t key, size_t size, int shmflg,
2781 PRINT("sys_shmsys ( %ld, %ld, %lu, %ld, %lu )",
2782 SARG1
, SARG2
, ARG3
, SARG4
, ARG5
);
2783 PRE_REG_READ5(long, SC2("shmsys", "shmget_osm"), int, opcode
,
2784 vki_key_t
, key
, vki_size_t
, size
, int, shmflg
,
2785 vki_size_t
, granule_sz
);
2787 #endif /* SOLARIS_SHM_NEW */
2790 VG_(unimplemented
)("Syswrap of the shmsys call with opcode %ld.",
2799 switch (ARG1
/*opcode*/) {
2801 ML_(generic_POST_sys_shmat
)(tid
, RES
, ARG2
, ARG3
, ARG4
);
2805 switch (ARG3
/*cmd*/) {
2807 case VKI_SHM_UNLOCK
:
2812 POST_MEM_WRITE(ARG4
, sizeof(struct vki_shmid_ds
));
2816 case VKI_IPC_STAT64
:
2817 POST_MEM_WRITE(ARG4
, sizeof(struct vki_shmid_ds64
));
2819 #if defined(SOLARIS_SHM_NEW)
2820 case VKI_IPC_XSTAT64
:
2821 POST_MEM_WRITE(ARG4
, sizeof(struct vki_shmid_xds64
));
2823 #endif /* SOLARIS_SHM_NEW */
2831 ML_(generic_POST_sys_shmdt
)(tid
, RES
, ARG2
);
2839 POST_MEM_WRITE(ARG4
, sizeof(vki_uint_t
));
2841 uint_t
*pnids
= (vki_uint_t
*) ARG4
;
2843 POST_MEM_WRITE(ARG2
, *pnids
* sizeof(int *));
2847 #if defined(SOLARIS_SHM_NEW)
2849 switch (ARG3
/*cmd*/) {
2850 case VKI_SHM_ADV_GET
:
2851 POST_MEM_WRITE(ARG4
, sizeof(vki_uint_t
));
2853 case VKI_SHM_ADV_SET
:
2861 case VKI_SHMGET_OSM
:
2863 #endif /* SOLARIS_SHM_NEW */
2873 /* Kernel: int semsys(int opcode, uintptr_t a1, uintptr_t a2, uintptr_t a3,
2876 *flags
|= SfMayBlock
;
2878 switch (ARG1
/*opcode*/) {
2880 /* Libc: int semctl(int semid, int semnum, int cmd...); */
2883 PRINT("sys_semsys ( %ld, %ld, %ld, %ld, %#lx )",
2884 SARG1
, SARG2
, SARG3
, SARG4
, ARG5
);
2885 PRE_REG_READ5(long, SC3("semsys", "semctl", "stat"), int, opcode
,
2886 int, semid
, int, semnum
, int, cmd
,
2887 struct vki_semid_ds
*, arg
);
2890 PRINT("sys_semsys ( %ld, %ld, %ld, %ld, %#lx )",
2891 SARG1
, SARG2
, SARG3
, SARG4
, ARG5
);
2892 PRE_REG_READ5(long, SC3("semsys", "semctl", "set"), int, opcode
,
2893 int, semid
, int, semnum
, int, cmd
,
2894 struct vki_semid_ds
*, arg
);
2896 case VKI_IPC_STAT64
:
2897 PRINT("sys_semsys ( %ld, %ld, %ld, %ld, %#lx )",
2898 SARG1
, SARG2
, SARG3
, SARG4
, ARG5
);
2899 PRE_REG_READ5(long, SC3("semsys", "semctl", "stat64"), int, opcode
,
2900 int, semid
, int, semnum
, int, cmd
,
2901 struct vki_semid64_ds
*, arg
);
2904 PRINT("sys_semsys ( %ld, %ld, %ld, %ld, %#lx )",
2905 SARG1
, SARG2
, SARG3
, SARG4
, ARG5
);
2906 PRE_REG_READ5(long, SC3("semsys", "semctl", "set64"), int, opcode
,
2907 int, semid
, int, semnum
, int, cmd
,
2908 struct vki_semid64_ds
*, arg
);
2911 PRINT("sys_semsys ( %ld, %ld, %ld )", SARG1
, SARG3
, SARG4
);
2912 PRE_REG_READ3(long, SC3("semsys", "semctl", "rmid"), int, opcode
,
2913 int, semid
, int, cmd
);
2916 PRINT("sys_semsys ( %ld, %ld, %ld, %#lx )",
2917 SARG1
, SARG2
, SARG4
, ARG5
);
2918 PRE_REG_READ4(long, SC3("semsys", "semctl", "getall"), int, opcode
,
2919 int, semid
, int, cmd
, ushort_t
*, arg
);
2922 PRINT("sys_semsys ( %ld, %ld, %ld, %#lx )",
2923 SARG1
, SARG2
, SARG4
, ARG5
);
2924 PRE_REG_READ4(long, SC3("semsys", "semctl", "setall"), int, opcode
,
2925 int, semid
, int, cmd
, ushort_t
*, arg
);
2928 PRINT("sys_semsys ( %ld, %ld, %ld, %ld )",
2929 SARG1
, SARG2
, SARG3
, SARG4
);
2930 PRE_REG_READ4(long, SC3("semsys", "semctl", "getval"), int, opcode
,
2931 int, semid
, int, semnum
, int, cmd
);
2934 PRINT("sys_semsys ( %ld, %ld, %ld, %ld, %#lx )",
2935 SARG1
, SARG2
, SARG3
, SARG4
, ARG5
);
2936 PRE_REG_READ5(long, SC3("semsys", "semctl", "setval"), int, opcode
,
2937 int, semid
, int, semnum
, int, cmd
,
2938 union vki_semun
*, arg
);
2941 PRINT("sys_semsys ( %ld, %ld, %ld, %ld )",
2942 SARG1
, SARG2
, SARG3
, SARG4
);
2943 PRE_REG_READ4(long, SC3("semsys", "semctl", "getpid"), int, opcode
,
2944 int, semid
, int, semnum
, int, cmd
);
2947 PRINT("sys_semsys ( %ld, %ld, %ld, %ld )",
2948 SARG1
, SARG2
, SARG3
, SARG4
);
2949 PRE_REG_READ4(long, SC3("semsys", "semctl", "getncnt"),
2950 int, opcode
, int, semid
, int, semnum
, int, cmd
);
2953 PRINT("sys_semsys ( %ld, %ld, %ld, %ld )",
2954 SARG1
, SARG2
, SARG3
, SARG4
);
2955 PRE_REG_READ4(long, SC3("semsys", "semctl", "getzcnt"),
2956 int, opcode
, int, semid
, int, semnum
, int, cmd
);
2959 VG_(unimplemented
)("Syswrap of the semsys(semctl) call "
2960 "with cmd %ld.", SARG4
);
2964 ML_(generic_PRE_sys_semctl
)(tid
, ARG2
, ARG3
, ARG4
, ARG5
);
2967 /* Libc: int semget(key_t key, int nsems, int semflg); */
2968 PRINT("sys_semsys ( %ld, %ld, %ld, %ld )", SARG1
, SARG2
, SARG3
, SARG4
);
2969 PRE_REG_READ4(long, SC2("semsys", "semget"), int, opcode
,
2970 vki_key_t
, key
, int, nsems
, int, semflg
);
2973 /* Libc: int semop(int semid, struct sembuf *sops, size_t nsops); */
2974 PRINT("sys_semsys ( %ld, %ld, %#lx, %lu )", SARG1
, SARG2
, ARG3
, ARG4
);
2975 PRE_REG_READ4(long, SC2("semsys", "semop"), int, opcode
, int, semid
,
2976 struct vki_sembuf
*, sops
, vki_size_t
, nsops
);
2977 ML_(generic_PRE_sys_semop
)(tid
, ARG2
, ARG3
, ARG4
);
2980 /* Libc: int semids(int *buf, uint_t nids, uint_t *pnids); */
2981 PRINT("sys_semsys ( %ld, %#lx, %lu, %#lx )", SARG1
, ARG2
, ARG3
, ARG4
);
2982 PRE_REG_READ4(long, SC2("semsys", "semids"), int, opcode
, int *, buf
,
2983 vki_uint_t
, nids
, vki_uint_t
*, pnids
);
2985 PRE_MEM_WRITE("semsys(semids, buf)", ARG2
, ARG3
* sizeof(int *));
2986 PRE_MEM_WRITE("semsys(semids, pnids)", ARG4
, sizeof(vki_uint_t
));
2988 case VKI_SEMTIMEDOP
:
2989 /* Libc: int semtimedop(int semid, struct sembuf *sops, size_t nsops,
2990 const struct timespec *timeout);
2992 PRINT("sys_semsys ( %ld, %ld, %#lx, %lu, %#lx )", SARG1
, SARG2
, ARG3
,
2994 PRE_REG_READ5(long, SC2("semsys", "semtimedop"), int, opcode
,
2995 int, semid
, struct vki_sembuf
*, sops
, vki_size_t
, nsops
,
2996 struct vki_timespec
*, timeout
);
2997 ML_(generic_PRE_sys_semtimedop
)(tid
, ARG2
, ARG3
, ARG4
, ARG5
);
3000 VG_(unimplemented
)("Syswrap of the semsys call with opcode %ld.", SARG1
);
3008 switch (ARG1
/*opcode*/) {
3010 ML_(generic_POST_sys_semctl
)(tid
, RES
, ARG2
, ARG3
, ARG4
, ARG5
);
3017 POST_MEM_WRITE(ARG4
, sizeof(vki_uint_t
));
3019 uint_t
*pnids
= (uint_t
*)ARG4
;
3021 POST_MEM_WRITE(ARG2
, *pnids
* sizeof(int *));
3024 case VKI_SEMTIMEDOP
:
3032 /* ---------------------------------------------------------------------
3034 ------------------------------------------------------------------ */
3038 /* int ioctl(int fildes, int request, ...); */
3039 *flags
|= SfMayBlock
;
3041 /* Prevent sign extending the switch case values to 64-bits on 64-bits
3043 Int cmd
= (Int
) ARG2
;
3045 switch (cmd
/*request*/) {
3046 /* Handle 2-arg specially here (they do not use ARG3 at all). */
3047 case VKI_DINFOIDENT
:
3050 PRINT("sys_ioctl ( %ld, %#lx )", SARG1
, ARG2
);
3051 PRE_REG_READ2(long, "ioctl", int, fd
, int, request
);
3053 /* And now come the 3-arg ones. */
3055 PRINT("sys_ioctl ( %ld, %#lx, %#lx )", SARG1
, ARG2
, ARG3
);
3056 PRE_REG_READ3(long, "ioctl", int, fd
, int, request
, intptr_t, arg
);
3060 switch (cmd
/*request*/) {
3062 case VKI_POOL_STATUSQ
:
3063 PRE_MEM_WRITE("ioctl(POOL_STATUSQ)", ARG3
, sizeof(vki_pool_status_t
));
3067 case VKI_MNTIOC_GETEXTMNTENT
:
3069 PRE_MEM_READ("ioctl(MNTIOC_GETEXTMNTENT)",
3070 ARG3
, sizeof(struct vki_mntentbuf
));
3072 struct vki_mntentbuf
*embuf
= (struct vki_mntentbuf
*) ARG3
;
3073 if (ML_(safe_to_deref(embuf
, sizeof(*embuf
)))) {
3074 PRE_MEM_WRITE("ioctl(MNTIOC_GETEXTMNTENT, embuf->mbuf_emp)",
3075 (Addr
) embuf
->mbuf_emp
, sizeof(struct vki_extmnttab
));
3076 PRE_MEM_WRITE("ioctl(MNTIOC_GETEXTMNTENT, embuf->mbuf_buf)",
3077 (Addr
) embuf
->mbuf_buf
, embuf
->mbuf_bufsize
);
3082 case VKI_MNTIOC_GETMNTANY
:
3084 PRE_MEM_READ("ioctl(MNTIOC_GETMNTANY)",
3085 ARG3
, sizeof(struct vki_mntentbuf
));
3087 struct vki_mntentbuf
*embuf
= (struct vki_mntentbuf
*) ARG3
;
3088 if (ML_(safe_to_deref(embuf
, sizeof(*embuf
)))) {
3089 PRE_MEM_READ("ioctl(MNTIOC_GETMNTANY, embuf->mbuf_emp)",
3090 (Addr
) embuf
->mbuf_emp
, sizeof(struct vki_mnttab
));
3091 PRE_MEM_WRITE("ioctl(MNTIOC_GETMNTANY, embuf->mbuf_buf)",
3092 (Addr
) embuf
->mbuf_buf
, embuf
->mbuf_bufsize
);
3094 struct vki_mnttab
*mnt
= (struct vki_mnttab
*) embuf
->mbuf_emp
;
3095 if (ML_(safe_to_deref(mnt
, sizeof(struct vki_mnttab
)))) {
3096 if (mnt
->mnt_special
!= NULL
)
3097 PRE_MEM_RASCIIZ("ioctl(MNTIOC_GETMNTANY, mnt->mnt_special)",
3098 (Addr
) mnt
->mnt_special
);
3099 if (mnt
->mnt_mountp
!= NULL
)
3100 PRE_MEM_RASCIIZ("ioctl(MNTIOC_GETMNTANY, mnt->mnt_mountp)",
3101 (Addr
) mnt
->mnt_mountp
);
3102 if (mnt
->mnt_fstype
!= NULL
)
3103 PRE_MEM_RASCIIZ("ioctl(MNTIOC_GETMNTANY, mnt->mnt_fstype)",
3104 (Addr
) mnt
->mnt_fstype
);
3105 if (mnt
->mnt_mntopts
!= NULL
)
3106 PRE_MEM_RASCIIZ("ioctl(MNTIOC_GETMNTANY, mnt->mnt_mntopts)",
3107 (Addr
) mnt
->mnt_mntopts
);
3108 if (mnt
->mnt_time
!= NULL
)
3109 PRE_MEM_RASCIIZ("ioctl(MNTIOC_GETMNTANY, mnt->mnt_time)",
3110 (Addr
) mnt
->mnt_time
);
3116 /* termio/termios */
3118 PRE_MEM_WRITE("ioctl(TCGETA)", ARG3
, sizeof(struct vki_termio
));
3121 PRE_MEM_WRITE("ioctl(TCGETS)", ARG3
, sizeof(struct vki_termios
));
3124 PRE_MEM_READ("ioctl(TCSETS)", ARG3
, sizeof(struct vki_termios
));
3127 PRE_MEM_READ("ioctl(TCSETSW)", ARG3
, sizeof(struct vki_termios
));
3130 PRE_MEM_READ("ioctl(TCSETSF)", ARG3
, sizeof(struct vki_termios
));
3132 case VKI_TIOCGWINSZ
:
3133 PRE_MEM_WRITE("ioctl(TIOCGWINSZ)", ARG3
, sizeof(struct vki_winsize
));
3135 case VKI_TIOCSWINSZ
:
3136 PRE_MEM_READ("ioctl(TIOCSWINSZ)", ARG3
, sizeof(struct vki_winsize
));
3139 PRE_MEM_WRITE("ioctl(TIOCGPGRP)", ARG3
, sizeof(vki_pid_t
));
3142 PRE_MEM_READ("ioctl(TIOCSPGRP)", ARG3
, sizeof(vki_pid_t
));
3145 PRE_MEM_WRITE("ioctl(TIOCGSID)", ARG3
, sizeof(vki_pid_t
));
3153 PRE_MEM_RASCIIZ("ioctl(I_PUSH)", ARG3
);
3159 PRE_MEM_READ("ioctl(I_STR)", ARG3
, sizeof(struct vki_strioctl
));
3161 struct vki_strioctl
*p
= (struct vki_strioctl
*) ARG3
;
3162 if (ML_(safe_to_deref(p
, sizeof(*p
)))) {
3163 if ((p
->ic_dp
!= NULL
) && (p
->ic_len
> 0)) {
3164 PRE_MEM_READ("ioctl(I_STR, strioctl->ic_dp)",
3165 (Addr
) p
->ic_dp
, p
->ic_len
);
3171 PRE_MEM_RASCIIZ("ioctl(I_FIND)", ARG3
);
3175 /* Try hard not to mark strpeek->*buf.len members as being read. */
3176 struct vki_strpeek
*p
= (struct vki_strpeek
*)ARG3
;
3178 PRE_FIELD_READ("ioctl(I_PEEK, strpeek->ctlbuf.maxlen)",
3180 PRE_FIELD_WRITE("ioctl(I_PEEK, strpeek->ctlbuf.len)",
3182 PRE_FIELD_READ("ioctl(I_PEEK, strpeek->ctlbuf.buf)",
3184 PRE_FIELD_READ("ioctl(I_PEEK, strpeek->databuf.maxlen)",
3186 PRE_FIELD_WRITE("ioctl(I_PEEK, strpeek->databuf.len)",
3188 PRE_FIELD_READ("ioctl(I_PEEK, strpeek->databuf.buf)",
3190 PRE_FIELD_READ("ioctl(I_PEEK, strpeek->flags)", p
->flags
);
3191 /*PRE_FIELD_WRITE("ioctl(I_PEEK, strpeek->flags)", p->flags);*/
3193 if (ML_(safe_to_deref(p
, sizeof(*p
)))) {
3194 if (p
->ctlbuf
.buf
&& p
->ctlbuf
.maxlen
> 0)
3195 PRE_MEM_WRITE("ioctl(I_PEEK, strpeek->ctlbuf.buf)",
3196 (Addr
)p
->ctlbuf
.buf
, p
->ctlbuf
.maxlen
);
3197 if (p
->databuf
.buf
&& p
->databuf
.maxlen
> 0)
3198 PRE_MEM_WRITE("ioctl(I_PEEK, strpeek->databuf.buf)",
3199 (Addr
)p
->databuf
.buf
, p
->databuf
.maxlen
);
3207 case VKI_SIOCGIFCONF
:
3209 struct vki_ifconf
*p
= (struct vki_ifconf
*) ARG3
;
3210 PRE_FIELD_READ("ioctl(SIOCGIFCONF, ifconf->ifc_len)", p
->ifc_len
);
3211 PRE_FIELD_READ("ioctl(SIOCGIFCONF, ifconf->ifc_buf)", p
->ifc_buf
);
3212 if (ML_(safe_to_deref
)(p
, sizeof(*p
))) {
3213 if ((p
->ifc_buf
!= NULL
) && (p
->ifc_len
> 0))
3214 PRE_MEM_WRITE("ioctl(SIOCGIFCONF, ifconf->ifc_buf)",
3215 (Addr
) p
->ifc_buf
, p
->ifc_len
);
3217 /* ifc_len gets also written to during SIOCGIFCONF ioctl. */
3220 case VKI_SIOCGIFFLAGS
:
3222 struct vki_ifreq
*p
= (struct vki_ifreq
*) ARG3
;
3223 PRE_FIELD_READ("ioctl(SIOCGIFFLAGS, ifreq->ifr_name)", p
->ifr_name
);
3224 PRE_FIELD_WRITE("ioctl(SIOCGIFFLAGS, ifreq->ifr_flags)", p
->ifr_flags
);
3227 case VKI_SIOCGIFNETMASK
:
3229 struct vki_ifreq
*p
= (struct vki_ifreq
*) ARG3
;
3230 PRE_FIELD_READ("ioctl(SIOCGIFFLAGS, ifreq->ifr_name)", p
->ifr_name
);
3231 PRE_FIELD_WRITE("ioctl(SIOCGIFFLAGS, ifreq->ifr_addr)", p
->ifr_addr
);
3234 case VKI_SIOCGIFNUM
:
3235 PRE_MEM_WRITE("ioctl(SIOCGIFNUM)", ARG3
, sizeof(int));
3237 case VKI_SIOCGLIFBRDADDR
:
3239 struct vki_lifreq
*p
= (struct vki_lifreq
*) ARG3
;
3240 PRE_FIELD_READ("ioctl(SIOCGLIFBRDADDR, lifreq->lifr_name)",
3242 PRE_FIELD_WRITE("ioctl(SIOCGLIFBRDADDR, lifreq->lifr_addr)",
3246 case VKI_SIOCGLIFCONF
:
3248 struct vki_lifconf
*p
= (struct vki_lifconf
*) ARG3
;
3249 PRE_FIELD_READ("ioctl(SIOCGLIFCONF, lifconf->lifc_len)", p
->lifc_len
);
3250 PRE_FIELD_READ("ioctl(SIOCGLIFCONF, lifconf->lifc_buf)", p
->lifc_buf
);
3251 PRE_FIELD_READ("ioctl(SIOCGLIFCONF, lifconf->lifc_family)",
3253 PRE_FIELD_READ("ioctl(SIOCGLIFCONF, lifconf->lifc_flags)",
3255 if (ML_(safe_to_deref
)(p
, sizeof(*p
))) {
3256 if ((p
->lifc_buf
!= NULL
) && (p
->lifc_len
> 0))
3257 PRE_MEM_WRITE("ioctl(SIOCGLIFCONF, lifconf->lifc_buf)",
3258 (Addr
) p
->lifc_buf
, p
->lifc_len
);
3260 /* lifc_len gets also written to during SIOCGLIFCONF ioctl. */
3263 case VKI_SIOCGLIFFLAGS
:
3265 struct vki_lifreq
*p
= (struct vki_lifreq
*) ARG3
;
3266 PRE_FIELD_READ("ioctl(SIOCGLIFFLAGS, lifreq->lifr_name)",
3268 PRE_FIELD_WRITE("ioctl(SIOCGLIFFLAGS, lifreq->lifr_flags)",
3272 case VKI_SIOCGLIFNETMASK
:
3274 struct vki_lifreq
*p
= (struct vki_lifreq
*) ARG3
;
3275 PRE_FIELD_READ("ioctl(SIOCGLIFNETMASK, lifreq->lifr_name)",
3277 PRE_FIELD_WRITE("ioctl(SIOCGLIFNETMASK, lifreq->lifr_addr)",
3281 case VKI_SIOCGLIFNUM
:
3283 struct vki_lifnum
*p
= (struct vki_lifnum
*) ARG3
;
3284 PRE_FIELD_READ("ioctl(SIOCGLIFNUM, lifn->lifn_family)",
3286 PRE_FIELD_READ("ioctl(SIOCGLIFNUM, lifn->lifn_flags)",
3288 PRE_FIELD_WRITE("ioctl(SIOCGLIFNUM, lifn->lifn_count)",
3295 PRE_MEM_READ("ioctl(FIOSETOWN)", ARG3
, sizeof(vki_pid_t
));
3298 PRE_MEM_WRITE("ioctl(FIOGETOWN)", ARG3
, sizeof(vki_pid_t
));
3302 case VKI_CRYPTO_GET_PROVIDER_LIST
:
3304 vki_crypto_get_provider_list_t
*pl
=
3305 (vki_crypto_get_provider_list_t
*) ARG3
;
3306 PRE_FIELD_READ("ioctl(CRYPTO_GET_PROVIDER_LIST, pl->pl_count)",
3309 if (ML_(safe_to_deref
)(pl
, sizeof(*pl
))) {
3310 PRE_MEM_WRITE("ioctl(CRYPTO_GET_PROVIDER_LIST)", ARG3
,
3311 MAX(1, pl
->pl_count
) *
3312 sizeof(vki_crypto_get_provider_list_t
));
3314 /* Save the requested count to unused ARG4 below,
3315 when we know pre-handler succeeded.
3321 case VKI_DTRACEHIOC_REMOVE
:
3323 case VKI_DTRACEHIOC_ADDDOF
:
3325 vki_dof_helper_t
*dh
= (vki_dof_helper_t
*) ARG3
;
3326 PRE_MEM_RASCIIZ("ioctl(DTRACEHIOC_ADDDOF, dh->dofhp_mod)",
3327 (Addr
) dh
->dofhp_mod
);
3328 PRE_FIELD_READ("ioctl(DTRACEHIOC_ADDDOF, dh->dofhp_addr",
3330 PRE_FIELD_READ("ioctl(DTRACEHIOC_ADDDOF, dh->dofhp_dof",
3336 case VKI_DINFOUSRLD
:
3337 /* We should do PRE_MEM_WRITE here but the question is for how many? */
3339 case VKI_DINFOIDENT
:
3343 ML_(PRE_unknown_ioctl
)(tid
, ARG2
, ARG3
);
3348 if (!ML_(fd_allowed
)(ARG1
, "ioctl", tid
, False
)) {
3349 SET_STATUS_Failure(VKI_EBADF
);
3350 } else if (ARG2
== VKI_CRYPTO_GET_PROVIDER_LIST
) {
3351 /* Save the requested count to unused ARG4 now. */
3358 /* Prevent sign extending the switch case values to 64-bits on 64-bits
3360 Int cmd
= (Int
) ARG2
;
3362 switch (cmd
/*request*/) {
3364 case VKI_POOL_STATUSQ
:
3365 POST_MEM_WRITE(ARG3
, sizeof(vki_pool_status_t
));
3369 case VKI_MNTIOC_GETEXTMNTENT
:
3371 struct vki_mntentbuf
*embuf
= (struct vki_mntentbuf
*) ARG3
;
3372 struct vki_extmnttab
*mnt
= (struct vki_extmnttab
*) embuf
->mbuf_emp
;
3374 POST_MEM_WRITE((Addr
) mnt
, sizeof(struct vki_extmnttab
));
3376 if (mnt
->mnt_special
!= NULL
)
3377 POST_MEM_WRITE((Addr
) mnt
->mnt_special
,
3378 VG_(strlen
)(mnt
->mnt_special
) + 1);
3379 if (mnt
->mnt_mountp
!= NULL
)
3380 POST_MEM_WRITE((Addr
) mnt
->mnt_mountp
,
3381 VG_(strlen
)(mnt
->mnt_mountp
) + 1);
3382 if (mnt
->mnt_fstype
!= NULL
)
3383 POST_MEM_WRITE((Addr
) mnt
->mnt_fstype
,
3384 VG_(strlen
)(mnt
->mnt_fstype
) + 1);
3385 if (mnt
->mnt_mntopts
!= NULL
)
3386 POST_MEM_WRITE((Addr
) mnt
->mnt_mntopts
,
3387 VG_(strlen
)(mnt
->mnt_mntopts
) + 1);
3388 if (mnt
->mnt_time
!= NULL
)
3389 POST_MEM_WRITE((Addr
) mnt
->mnt_time
,
3390 VG_(strlen
)(mnt
->mnt_time
) + 1);
3395 case VKI_MNTIOC_GETMNTANY
:
3397 struct vki_mntentbuf
*embuf
= (struct vki_mntentbuf
*) ARG3
;
3398 struct vki_mnttab
*mnt
= (struct vki_mnttab
*) embuf
->mbuf_emp
;
3400 POST_MEM_WRITE((Addr
) mnt
, sizeof(struct vki_mnttab
));
3402 if (mnt
->mnt_special
!= NULL
)
3403 POST_MEM_WRITE((Addr
) mnt
->mnt_special
,
3404 VG_(strlen
)(mnt
->mnt_special
) + 1);
3405 if (mnt
->mnt_mountp
!= NULL
)
3406 POST_MEM_WRITE((Addr
) mnt
->mnt_mountp
,
3407 VG_(strlen
)(mnt
->mnt_mountp
) + 1);
3408 if (mnt
->mnt_fstype
!= NULL
)
3409 POST_MEM_WRITE((Addr
) mnt
->mnt_fstype
,
3410 VG_(strlen
)(mnt
->mnt_fstype
) + 1);
3411 if (mnt
->mnt_mntopts
!= NULL
)
3412 POST_MEM_WRITE((Addr
) mnt
->mnt_mntopts
,
3413 VG_(strlen
)(mnt
->mnt_mntopts
) + 1);
3414 if (mnt
->mnt_time
!= NULL
)
3415 POST_MEM_WRITE((Addr
) mnt
->mnt_time
,
3416 VG_(strlen
)(mnt
->mnt_time
) + 1);
3421 /* termio/termios */
3423 POST_MEM_WRITE(ARG3
, sizeof(struct vki_termio
));
3426 POST_MEM_WRITE(ARG3
, sizeof(struct vki_termios
));
3434 case VKI_TIOCGWINSZ
:
3435 POST_MEM_WRITE(ARG3
, sizeof(struct vki_winsize
));
3437 case VKI_TIOCSWINSZ
:
3440 POST_MEM_WRITE(ARG3
, sizeof(vki_pid_t
));
3445 POST_MEM_WRITE(ARG3
, sizeof(vki_pid_t
));
3458 struct vki_strioctl
*p
= (struct vki_strioctl
*) ARG3
;
3460 POST_FIELD_WRITE(p
->ic_len
);
3461 if ((p
->ic_dp
!= NULL
) && (p
->ic_len
> 0))
3462 POST_MEM_WRITE((Addr
) p
->ic_dp
, p
->ic_len
);
3469 struct vki_strpeek
*p
= (struct vki_strpeek
*)ARG3
;
3471 POST_FIELD_WRITE(p
->ctlbuf
.len
);
3472 POST_FIELD_WRITE(p
->databuf
.len
);
3473 POST_FIELD_WRITE(p
->flags
);
3475 if (p
->ctlbuf
.buf
&& p
->ctlbuf
.len
> 0)
3476 POST_MEM_WRITE((Addr
)p
->ctlbuf
.buf
, p
->ctlbuf
.len
);
3477 if (p
->databuf
.buf
&& p
->databuf
.len
> 0)
3478 POST_MEM_WRITE((Addr
)p
->databuf
.buf
, p
->databuf
.len
);
3485 case VKI_SIOCGIFCONF
:
3487 struct vki_ifconf
*p
= (struct vki_ifconf
*) ARG3
;
3488 POST_FIELD_WRITE(p
->ifc_len
);
3489 POST_FIELD_WRITE(p
->ifc_req
);
3490 if ((p
->ifc_req
!= NULL
) && (p
->ifc_len
> 0))
3491 POST_MEM_WRITE((Addr
) p
->ifc_req
, p
->ifc_len
);
3494 case VKI_SIOCGIFFLAGS
:
3496 struct vki_ifreq
*p
= (struct vki_ifreq
*) ARG3
;
3497 POST_FIELD_WRITE(p
->ifr_flags
);
3500 case VKI_SIOCGIFNETMASK
:
3502 struct vki_ifreq
*p
= (struct vki_ifreq
*) ARG3
;
3503 POST_FIELD_WRITE(p
->ifr_addr
);
3506 case VKI_SIOCGIFNUM
:
3507 POST_MEM_WRITE(ARG3
, sizeof(int));
3509 case VKI_SIOCGLIFBRDADDR
:
3511 struct vki_lifreq
*p
= (struct vki_lifreq
*) ARG3
;
3512 POST_FIELD_WRITE(p
->lifr_addr
);
3515 case VKI_SIOCGLIFCONF
:
3517 struct vki_lifconf
*p
= (struct vki_lifconf
*) ARG3
;
3518 POST_FIELD_WRITE(p
->lifc_len
);
3519 POST_FIELD_WRITE(p
->lifc_req
);
3520 if ((p
->lifc_req
!= NULL
) && (p
->lifc_len
> 0))
3521 POST_MEM_WRITE((Addr
) p
->lifc_req
, p
->lifc_len
);
3524 case VKI_SIOCGLIFFLAGS
:
3526 struct vki_lifreq
*p
= (struct vki_lifreq
*) ARG3
;
3527 POST_FIELD_WRITE(p
->lifr_flags
);
3530 case VKI_SIOCGLIFNETMASK
:
3532 struct vki_lifreq
*p
= (struct vki_lifreq
*) ARG3
;
3533 POST_FIELD_WRITE(p
->lifr_addr
);
3536 case VKI_SIOCGLIFNUM
:
3538 struct vki_lifnum
*p
= (struct vki_lifnum
*) ARG3
;
3539 POST_FIELD_WRITE(p
->lifn_count
);
3547 POST_MEM_WRITE(ARG3
, sizeof(vki_pid_t
));
3551 case VKI_CRYPTO_GET_PROVIDER_LIST
:
3553 vki_crypto_get_provider_list_t
*pl
=
3554 (vki_crypto_get_provider_list_t
*) ARG3
;
3556 POST_FIELD_WRITE(pl
->pl_count
);
3557 POST_FIELD_WRITE(pl
->pl_return_value
);
3559 if ((ARG4
> 0) && (pl
->pl_return_value
== VKI_CRYPTO_SUCCESS
))
3560 POST_MEM_WRITE((Addr
) pl
->pl_list
, pl
->pl_count
*
3561 sizeof(vki_crypto_provider_entry_t
));
3566 case VKI_DTRACEHIOC_REMOVE
:
3567 case VKI_DTRACEHIOC_ADDDOF
:
3571 case VKI_DINFOUSRLD
:
3572 POST_MEM_WRITE(ARG3
, RES
);
3574 case VKI_DINFOIDENT
:
3578 /* Not really anything to do since ioctl direction hints are hardly used
3586 /* int fchownat(int fd, const char *path, uid_t owner, gid_t group,
3589 /* Interpret the first argument as 32-bit value even on 64-bit architecture.
3590 This is different from Linux, for example, where glibc sign-extends it. */
3591 Int fd
= (Int
) ARG1
;
3593 PRINT("sys_fchownat ( %d, %#lx(%s), %ld, %ld, %lu )", fd
,
3594 ARG2
, (HChar
*) ARG2
, SARG3
, SARG4
, ARG5
);
3595 PRE_REG_READ5(long, "fchownat", int, fd
, const char *, path
,
3596 vki_uid_t
, owner
, vki_gid_t
, group
, int, flag
);
3599 PRE_MEM_RASCIIZ("fchownat(path)", ARG2
);
3601 /* Be strict but ignore fd for absolute path. */
3602 if (fd
!= VKI_AT_FDCWD
3603 && ML_(safe_to_deref
)((void *) ARG2
, 1)
3604 && ((HChar
*) ARG2
)[0] != '/'
3605 && !ML_(fd_allowed
)(fd
, "fchownat", tid
, False
))
3606 SET_STATUS_Failure(VKI_EBADF
);
3611 /* int fdsync(int fd, int flag); */
3612 PRINT("sys_fdsync ( %ld, %ld )", SARG1
, SARG2
);
3613 PRE_REG_READ2(long, "fdsync", int, fd
, int, flag
);
3616 if (!ML_(fd_allowed
)(ARG1
, "fdsync", tid
, False
))
3617 SET_STATUS_Failure(VKI_EBADF
);
3624 const char* str2
= "execve(argv)";
3625 const char* str3
= "execve(argv[0])";
3626 const char* str4
= "execve(argv[i])";
3627 /* This is a Solaris specific version of the generic pre-execve wrapper. */
3629 #if defined(SOLARIS_EXECVE_SYSCALL_TAKES_FLAGS)
3630 /* int execve(uintptr_t file, const char **argv, const char **envp,
3632 PRINT("sys_execve ( %#lx, %#lx, %#lx, %ld )", ARG1
, ARG2
, ARG3
, SARG4
);
3633 PRE_REG_READ4(long, "execve", uintptr_t, file
, const char **, argv
,
3634 const char **, envp
, int, flags
);
3638 /* int execve(const char *fname, const char **argv, const char **envp); */
3639 PRINT("sys_execve ( %#lx(%s), %#lx, %#lx )",
3640 ARG1
, (HChar
*) ARG1
, ARG2
, ARG3
);
3641 PRE_REG_READ3(long, "execve", const char *, file
, const char **, argv
,
3642 const char **, envp
);
3643 #endif /* SOLARIS_EXECVE_SYSCALL_TAKES_FLAGS */
3645 Bool ARG1_is_fd
= False
;
3646 #if defined(SOLARIS_EXECVE_SYSCALL_TAKES_FLAGS)
3647 if (ARG4
& VKI_EXEC_DESCRIPTOR
) {
3650 #endif /* SOLARIS_EXECVE_SYSCALL_TAKES_FLAGS */
3652 if (ARG1_is_fd
== False
)
3653 PRE_MEM_RASCIIZ("execve(filename)", ARG1
);
3655 /* Erk. If the exec fails, then the following will have made a mess of
3656 things which makes it hard for us to continue. The right thing to do is
3657 piece everything together again in POST(execve), but that's close to
3658 impossible. Instead, we make an effort to check that the execve will
3659 work before actually doing it. */
3661 const HChar
*fname
= (const HChar
*) ARG1
;
3663 if (!ML_(fd_allowed
)(ARG1
, "execve", tid
, False
)) {
3664 SET_STATUS_Failure(VKI_EBADF
);
3668 if (VG_(resolve_filename
)(ARG1
, &fname
) == False
) {
3669 SET_STATUS_Failure(VKI_EBADF
);
3673 struct vg_stat stats
;
3674 if (VG_(fstat
)(ARG1
, &stats
) != 0) {
3675 SET_STATUS_Failure(VKI_EBADF
);
3679 if (stats
.nlink
> 1)
3680 VG_(unimplemented
)("Syswrap of execve where fd points to a hardlink.");
3683 arg_2_check
= (Addr
)ARG2
;
3685 /* argv[] should not be NULL and valid. */
3686 PRE_MEM_READ(str2
, arg_2_check
, sizeof(Addr
));
3688 /* argv[0] should not be NULL and valid. */
3689 if (ML_(safe_to_deref
)((HChar
**) (Addr
)arg_2_check
, sizeof(HChar
*))) {
3690 Addr argv0
= *(Addr
*)arg_2_check
;
3691 PRE_MEM_RASCIIZ( str3
, argv0
);
3692 /* The rest of argv can be NULL or a valid string pointer. */
3693 if (VG_(am_is_valid_for_client
)(arg_2_check
, sizeof(HChar
), VKI_PROT_READ
)) {
3694 arg_2_check
+= sizeof(HChar
*);
3695 ML_(pre_argv_envp
)( arg_2_check
, tid
, str2
, str4
);
3698 SET_STATUS_Failure(VKI_EFAULT
);
3703 /* At least the terminating NULL must be addressable. */
3704 if (!ML_(safe_to_deref
)((HChar
**) (Addr
)ARG3
, sizeof(HChar
*))) {
3705 SET_STATUS_Failure(VKI_EFAULT
);
3708 ML_(pre_argv_envp
)( ARG3
, tid
, "execve(envp)", "execve(envp[i])" );
3711 /* Check that the name at least begins in client-accessible storage. */
3712 if (ARG1_is_fd
== False
) {
3713 if ((fname
== NULL
) || !ML_(safe_to_deref
)(fname
, 1)) {
3714 SET_STATUS_Failure(VKI_EFAULT
);
3719 /* Check that the args at least begin in client-accessible storage.
3720 Solaris disallows to perform the exec without any arguments specified.
3722 if (!ARG2
/* obviously bogus */ ||
3723 !VG_(am_is_valid_for_client
)(ARG2
, 1, VKI_PROT_READ
)) {
3724 SET_STATUS_Failure(VKI_EFAULT
);
3728 /* Debug-only printing. */
3730 VG_(printf
)("ARG1 = %#lx(%s)\n", ARG1
, fname
);
3733 HChar
** vec
= (HChar
**)ARG2
;
3735 VG_(printf
)("ARG2 = ");
3736 for (q
= 0; vec
[q
]; q
++)
3737 VG_(printf
)("%p(%s) ", vec
[q
], vec
[q
]);
3741 VG_(printf
)("ARG2 = null\n");
3744 /* Decide whether or not we want to follow along. */
3745 /* Make 'child_argv' be a pointer to the child's arg vector (skipping the
3747 const HChar
**child_argv
= (const HChar
**) ARG2
;
3748 if (child_argv
[0] == NULL
)
3750 Bool trace_this_child
= VG_(should_we_trace_this_child
)(fname
, child_argv
);
3752 /* Do the important checks: it is a file, is executable, permissions are
3753 ok, etc. We allow setuid executables to run only in the case when
3754 we are not simulating them, that is, they to be run natively. */
3755 Bool setuid_allowed
= trace_this_child
? False
: True
;
3756 SysRes res
= VG_(pre_exec_check
)(fname
, NULL
, setuid_allowed
);
3757 if (sr_isError(res
)) {
3758 SET_STATUS_Failure(sr_Err(res
));
3762 /* If we're tracing the child, and the launcher name looks bogus (possibly
3763 because launcher.c couldn't figure it out, see comments therein) then we
3764 have no option but to fail. */
3765 if (trace_this_child
&&
3766 (!VG_(name_of_launcher
) || VG_(name_of_launcher
)[0] != '/')) {
3767 SET_STATUS_Failure(VKI_ECHILD
); /* "No child processes." */
3771 /* After this point, we can't recover if the execve fails. */
3772 VG_(debugLog
)(1, "syswrap", "Exec of %s\n", fname
);
3774 /* Terminate gdbserver if it is active. */
3775 if (VG_(clo_vgdb
) != Vg_VgdbNo
) {
3776 /* If the child will not be traced, we need to terminate gdbserver to
3777 cleanup the gdbserver resources (e.g. the FIFO files). If child will
3778 be traced, we also terminate gdbserver: the new Valgrind will start a
3779 fresh gdbserver after exec. */
3783 /* Resistance is futile. Nuke all other threads. POSIX mandates this.
3784 (Really, nuke them all, since the new process will make its own new
3786 VG_(nuke_all_threads_except
)(tid
, VgSrc_ExitThread
);
3787 VG_(reap_threads
)(tid
);
3789 /* Set up the child's exe path. */
3790 const HChar
*path
= fname
;
3791 const HChar
*launcher_basename
= NULL
;
3792 if (trace_this_child
) {
3793 /* We want to exec the launcher. Get its pre-remembered path. */
3794 path
= VG_(name_of_launcher
);
3795 /* VG_(name_of_launcher) should have been acquired by m_main at
3799 launcher_basename
= VG_(strrchr
)(path
, '/');
3800 if (!launcher_basename
|| launcher_basename
[1] == '\0')
3801 launcher_basename
= path
; /* hmm, tres dubious */
3803 launcher_basename
++;
3806 /* Set up the child's environment.
3808 Remove the valgrind-specific stuff from the environment so the child
3809 doesn't get vgpreload_core.so, vgpreload_<tool>.so, etc. This is done
3810 unconditionally, since if we are tracing the child, the child valgrind
3811 will set up the appropriate client environment. Nb: we make a copy of
3812 the environment before trying to mangle it as it might be in read-only
3813 memory (bug #101881).
3815 Then, if tracing the child, set VALGRIND_LIB for it. */
3816 HChar
**envp
= NULL
;
3818 envp
= VG_(env_clone
)((HChar
**)ARG3
);
3819 vg_assert(envp
!= NULL
);
3820 VG_(env_remove_valgrind_env_stuff
)(envp
, True
/*ro_strings*/, NULL
);
3823 if (trace_this_child
) {
3824 /* Set VALGRIND_LIB in ARG3 (the environment). */
3825 VG_(env_setenv
)( &envp
, VALGRIND_LIB
, VG_(libdir
));
3828 /* Set up the child's args. If not tracing it, they are simply ARG2.
3829 Otherwise, they are:
3831 [launcher_basename] ++ VG_(args_for_valgrind) ++ [ARG1] ++ ARG2[1..],
3833 except that the first VG_(args_for_valgrind_noexecpass) args are
3835 HChar
**argv
= NULL
;
3836 if (!trace_this_child
)
3837 argv
= (HChar
**) ARG2
;
3841 vg_assert(VG_(args_for_valgrind
));
3842 vg_assert(VG_(args_for_valgrind_noexecpass
) >= 0);
3843 vg_assert(VG_(args_for_valgrind_noexecpass
)
3844 <= VG_(sizeXA
)(VG_(args_for_valgrind
)));
3846 /* How many args in total will there be? */
3847 /* launcher basename */
3850 tot_args
+= VG_(sizeXA
)(VG_(args_for_valgrind
));
3851 tot_args
-= VG_(args_for_valgrind_noexecpass
);
3852 /* name of client exe */
3854 /* args for client exe, skipping [0] */
3855 HChar
**arg2copy
= (HChar
**) ARG2
;
3856 if (arg2copy
[0] != NULL
)
3857 for (i
= 1; arg2copy
[i
]; i
++)
3860 argv
= VG_(malloc
)("syswrap.exec.5", (tot_args
+ 1) * sizeof(HChar
*));
3863 argv
[j
++] = CONST_CAST(HChar
*, launcher_basename
);
3864 for (i
= 0; i
< VG_(sizeXA
)(VG_(args_for_valgrind
)); i
++) {
3865 if (i
< VG_(args_for_valgrind_noexecpass
))
3867 argv
[j
++] = *(HChar
**)VG_(indexXA
)(VG_(args_for_valgrind
), i
);
3869 argv
[j
++] = CONST_CAST(HChar
*, fname
);
3870 if (arg2copy
[0] != NULL
)
3871 for (i
= 1; arg2copy
[i
]; i
++)
3872 argv
[j
++] = arg2copy
[i
];
3875 vg_assert(j
== tot_args
+ 1);
3878 /* Set the signal state up for exec.
3880 We need to set the real signal state to make sure the exec'd process
3881 gets SIG_IGN properly.
3883 Also set our real sigmask to match the client's sigmask so that the
3884 exec'd child will get the right mask. First we need to clear out any
3885 pending signals so they they don't get delivered, which would confuse
3888 XXX This is a bug - the signals should remain pending, and be delivered
3889 to the new process after exec. There's also a race-condition, since if
3890 someone delivers us a signal between the sigprocmask and the execve,
3891 we'll still get the signal. Oh well.
3894 vki_sigset_t allsigs
;
3897 /* What this loop does: it queries SCSS (the signal state that the
3898 client _thinks_ the kernel is in) by calling VG_(do_sys_sigaction),
3899 and modifies the real kernel signal state accordingly. */
3900 for (i
= 1; i
< VG_(max_signal
); i
++) {
3901 vki_sigaction_fromK_t sa_f
;
3902 vki_sigaction_toK_t sa_t
;
3903 VG_(do_sys_sigaction
)(i
, NULL
, &sa_f
);
3904 VG_(convert_sigaction_fromK_to_toK
)(&sa_f
, &sa_t
);
3905 VG_(sigaction
)(i
, &sa_t
, NULL
);
3908 VG_(sigfillset
)(&allsigs
);
3909 while (VG_(sigtimedwait_zero
)(&allsigs
, &info
) > 0)
3912 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
3913 VG_(sigprocmask
)(VKI_SIG_SETMASK
, &tst
->sig_mask
, NULL
);
3916 /* Debug-only printing. */
3919 VG_(printf
)("exec: %s\n", path
);
3920 for (cpp
= argv
; cpp
&& *cpp
; cpp
++)
3921 VG_(printf
)("argv: %s\n", *cpp
);
3923 for (cpp
= envp
; cpp
&& *cpp
; cpp
++)
3924 VG_(printf
)("env: %s\n", *cpp
);
3927 #if defined(SOLARIS_EXECVE_SYSCALL_TAKES_FLAGS)
3928 res
= VG_(do_syscall4
)(__NR_execve
, (UWord
) path
, (UWord
) argv
,
3929 (UWord
) envp
, ARG4
& ~VKI_EXEC_DESCRIPTOR
);
3931 res
= VG_(do_syscall3
)(__NR_execve
, (UWord
) path
, (UWord
) argv
,
3933 #endif /* SOLARIS_EXECVE_SYSCALL_TAKES_FLAGS */
3934 SET_STATUS_from_SysRes(res
);
3936 /* If we got here, then the execve failed. We've already made way too much
3937 of a mess to continue, so we have to abort. */
3939 #if defined(SOLARIS_EXECVE_SYSCALL_TAKES_FLAGS)
3941 VG_(message
)(Vg_UserMsg
, "execve(%ld, %#lx, %#lx, %lu) failed, "
3942 "errno %ld\n", SARG1
, ARG2
, ARG3
, ARG4
, ERR
);
3944 VG_(message
)(Vg_UserMsg
, "execve(%#lx(%s), %#lx, %#lx, %ld) failed, errno"
3945 " %lu\n", ARG1
, (HChar
*) ARG1
, ARG2
, ARG3
, SARG4
, ERR
);
3947 VG_(message
)(Vg_UserMsg
, "execve(%#lx(%s), %#lx, %#lx) failed, errno %lu\n",
3948 ARG1
, (HChar
*) ARG1
, ARG2
, ARG3
, ERR
);
3949 #endif /* SOLARIS_EXECVE_SYSCALL_TAKES_FLAGS */
3950 VG_(message
)(Vg_UserMsg
, "EXEC FAILED: I can't recover from "
3951 "execve() failing, so I'm dying.\n");
3952 VG_(message
)(Vg_UserMsg
, "Add more stringent tests in PRE(sys_execve), "
3953 "or work out how to recover.\n");
3958 static void pre_mem_read_flock(ThreadId tid
, struct vki_flock
*lock
)
3960 PRE_FIELD_READ("fcntl(lock->l_type)", lock
->l_type
);
3961 PRE_FIELD_READ("fcntl(lock->l_whence)", lock
->l_whence
);
3962 PRE_FIELD_READ("fcntl(lock->l_start)", lock
->l_start
);
3963 PRE_FIELD_READ("fcntl(lock->l_len)", lock
->l_len
);
3966 #if defined(VGP_x86_solaris)
3967 static void pre_mem_read_flock64(ThreadId tid
, struct vki_flock64
*lock
)
3969 PRE_FIELD_READ("fcntl(lock->l_type)", lock
->l_type
);
3970 PRE_FIELD_READ("fcntl(lock->l_whence)", lock
->l_whence
);
3971 PRE_FIELD_READ("fcntl(lock->l_start)", lock
->l_start
);
3972 PRE_FIELD_READ("fcntl(lock->l_len)", lock
->l_len
);
3974 #endif /* VGP_x86_solaris */
3978 /* int fcntl(int fildes, int cmd, ...); */
3980 switch (ARG2
/*cmd*/) {
3981 /* These ones ignore ARG3. */
3985 PRINT("sys_fcntl ( %ld, %ld )", SARG1
, SARG2
);
3986 PRE_REG_READ2(long, "fcntl", int, fildes
, int, cmd
);
3989 /* These ones use ARG3 as "arg". */
3991 case VKI_F_DUPFD_CLOEXEC
:
3996 PRINT("sys_fcntl ( %ld, %ld, %ld )", SARG1
, SARG2
, SARG3
);
3997 PRE_REG_READ3(long, "fcntl", int, fildes
, int, cmd
, int, arg
);
3998 /* Check if a client program isn't going to poison any of V's output
4000 if (ARG2
== VKI_F_DUP2FD
&&
4001 !ML_(fd_allowed
)(ARG3
, "fcntl(F_DUP2FD)", tid
, False
)) {
4002 SET_STATUS_Failure(VKI_EBADF
);
4007 /* These ones use ARG3 as "native lock" (input only). */
4012 case VKI_F_SETLK_NBMAND
:
4013 PRINT("sys_fcntl ( %ld, %ld, %#lx )", SARG1
, SARG2
, ARG3
);
4014 PRE_REG_READ3(long, "fcntl", int, fildes
, int, cmd
,
4015 struct flock
*, lock
);
4016 pre_mem_read_flock(tid
, (struct vki_flock
*)ARG3
);
4019 /* This one uses ARG3 as "native lock" (input&output). */
4021 PRINT("sys_fcntl ( %ld, %ld, %#lx )", SARG1
, SARG2
, ARG3
);
4022 PRE_REG_READ3(long, "fcntl", int, fildes
, int, cmd
,
4023 struct flock
*, lock
);
4024 pre_mem_read_flock(tid
, (struct vki_flock
*)ARG3
);
4025 PRE_MEM_WRITE("fcntl(lock)", ARG3
, sizeof(struct vki_flock
));
4028 #if defined(VGP_x86_solaris)
4029 /* These ones use ARG3 as "transitional 64b lock" (input only). */
4031 case VKI_F_SETLKW64
:
4032 case VKI_F_ALLOCSP64
:
4033 case VKI_F_FREESP64
:
4034 case VKI_F_SETLK64_NBMAND
:
4035 PRINT("sys_fcntl ( %ld, %ld, %#lx )", SARG1
, SARG2
, ARG3
);
4036 PRE_REG_READ3(long, "fcntl", int, fildes
, int, cmd
,
4037 struct flock64
*, lock
);
4038 pre_mem_read_flock64(tid
, (struct vki_flock64
*)ARG3
);
4041 /* This one uses ARG3 as "transitional 64b lock" (input&output). */
4043 PRINT("sys_fcntl ( %ld, %ld, %#lx )", SARG1
, SARG2
, ARG3
);
4044 PRE_REG_READ3(long, "fcntl", int, fildes
, int, cmd
,
4045 struct flock64
*, lock
);
4046 pre_mem_read_flock64(tid
, (struct vki_flock64
*)ARG3
);
4047 PRE_MEM_WRITE("fcntl(lock)", ARG3
, sizeof(struct vki_flock64
));
4049 #endif /* VGP_x86_solaris */
4051 /* These ones use ARG3 as "fshare". */
4054 case VKI_F_SHARE_NBMAND
:
4055 PRINT("sys_fcntl[ARG3=='fshare'] ( %ld, %ld, %#lx )", SARG1
, SARG2
, ARG3
);
4056 PRE_REG_READ3(long, "fcntl", int, fildes
, int, cmd
,
4057 struct fshare
*, sh
);
4058 PRE_MEM_READ("fcntl(fshare)", ARG3
, sizeof(struct vki_fshare
));
4062 VG_(unimplemented
)("Syswrap of the fcntl call with cmd %ld.", SARG2
);
4067 if (ARG2
== VKI_F_SETLKW
4068 #if defined(VGP_x86_solaris)
4069 || ARG2
== VKI_F_SETLKW64
4070 #endif /* VGP_x86_solaris */
4072 *flags
|= SfMayBlock
;
4075 if (!ML_(fd_allowed
)(ARG1
, "fcntl", tid
, False
))
4076 SET_STATUS_Failure(VKI_EBADF
);
4081 switch (ARG2
/*cmd*/) {
4083 if (!ML_(fd_allowed
)(RES
, "fcntl(F_DUPFD)", tid
, True
)) {
4085 SET_STATUS_Failure(VKI_EMFILE
);
4086 } else if (VG_(clo_track_fds
))
4087 ML_(record_fd_open_named
)(tid
, RES
);
4090 case VKI_F_DUPFD_CLOEXEC
:
4091 if (!ML_(fd_allowed
)(RES
, "fcntl(F_DUPFD_CLOEXEC)", tid
, True
)) {
4093 SET_STATUS_Failure(VKI_EMFILE
);
4094 } else if (VG_(clo_track_fds
))
4095 ML_(record_fd_open_named
)(tid
, RES
);
4099 if (!ML_(fd_allowed
)(RES
, "fcntl(F_DUP2FD)", tid
, True
)) {
4101 SET_STATUS_Failure(VKI_EMFILE
);
4102 } else if (VG_(clo_track_fds
))
4103 ML_(record_fd_open_named
)(tid
, RES
);
4106 /* This one uses ARG3 as "native lock" (input&output). */
4108 POST_MEM_WRITE(ARG3
, sizeof(struct vki_flock
));
4111 #if defined(VGP_x86_solaris)
4112 /* This one uses ARG3 as "transitional 64b lock" (input&output). */
4114 POST_MEM_WRITE(ARG3
, sizeof(struct vki_flock64
));
4116 #endif /* VGP_x86_solaris */
4125 /* int renameat(int fromfd, const char *old, int tofd, const char *new); */
4127 /* Interpret the first and third arguments as 32-bit values even on 64-bit
4128 architecture. This is different from Linux, for example, where glibc
4129 sign-extends them. */
4130 Int fromfd
= (Int
) ARG1
;
4131 Int tofd
= (Int
) ARG3
;
4133 *flags
|= SfMayBlock
;
4134 PRINT("sys_renameat ( %d, %#lx(%s), %d, %#lx(%s) )", fromfd
,
4135 ARG2
, (HChar
*) ARG2
, tofd
, ARG4
, (HChar
*) ARG4
);
4136 PRE_REG_READ4(long, "renameat", int, fromfd
, const char *, old
,
4137 int, tofd
, const char *, new);
4139 PRE_MEM_RASCIIZ("renameat(old)", ARG2
);
4140 PRE_MEM_RASCIIZ("renameat(new)", ARG4
);
4142 /* Be strict but ignore fromfd/tofd for absolute old/new. */
4143 if (fromfd
!= VKI_AT_FDCWD
4144 && ML_(safe_to_deref
)((void *) ARG2
, 1)
4145 && ((HChar
*) ARG2
)[0] != '/'
4146 && !ML_(fd_allowed
)(fromfd
, "renameat", tid
, False
)) {
4147 SET_STATUS_Failure(VKI_EBADF
);
4149 if (tofd
!= VKI_AT_FDCWD
4150 && ML_(safe_to_deref
)((void *) ARG4
, 1)
4151 && ((HChar
*) ARG4
)[0] != '/'
4152 && !ML_(fd_allowed
)(tofd
, "renameat", tid
, False
)) {
4153 SET_STATUS_Failure(VKI_EBADF
);
4159 /* int unlinkat(int dirfd, const char *pathname, int flags); */
4161 /* Interpret the first argument as 32-bit value even on 64-bit architecture.
4162 This is different from Linux, for example, where glibc sign-extends it. */
4163 Int dfd
= (Int
) ARG1
;
4165 *flags
|= SfMayBlock
;
4166 PRINT("sys_unlinkat ( %d, %#lx(%s), %ld )", dfd
, ARG2
, (HChar
*) ARG2
,
4168 PRE_REG_READ3(long, "unlinkat", int, dirfd
, const char *, pathname
,
4170 PRE_MEM_RASCIIZ("unlinkat(pathname)", ARG2
);
4172 /* Be strict but ignore dfd for absolute pathname. */
4173 if (dfd
!= VKI_AT_FDCWD
4174 && ML_(safe_to_deref
)((void *) ARG2
, 1)
4175 && ((HChar
*) ARG2
)[0] != '/'
4176 && !ML_(fd_allowed
)(dfd
, "unlinkat", tid
, False
))
4177 SET_STATUS_Failure(VKI_EBADF
);
4182 /* int fstatat(int fildes, const char *path, struct stat *buf,
4185 /* Interpret the first argument as 32-bit value even on 64-bit architecture.
4186 This is different from Linux, for example, where glibc sign-extends it. */
4187 Int fd
= (Int
) ARG1
;
4189 PRINT("sys_fstatat ( %d, %#lx(%s), %#lx, %ld )", fd
, ARG2
,
4190 (HChar
*) ARG2
, ARG3
, SARG4
);
4191 PRE_REG_READ4(long, "fstatat", int, fildes
, const char *, path
,
4192 struct stat
*, buf
, int, flag
);
4194 /* Only test ARG2 if it isn't NULL. The kernel treats the NULL-case as
4195 fstat(fildes, buf). */
4196 PRE_MEM_RASCIIZ("fstatat(path)", ARG2
);
4198 PRE_MEM_WRITE("fstatat(buf)", ARG3
, sizeof(struct vki_stat
));
4200 /* Be strict but ignore fildes for absolute path. */
4201 if (fd
!= VKI_AT_FDCWD
4202 && ML_(safe_to_deref
)((void *) ARG2
, 1)
4203 && ((HChar
*) ARG2
)[0] != '/'
4204 && !ML_(fd_allowed
)(fd
, "fstatat", tid
, False
))
4205 SET_STATUS_Failure(VKI_EBADF
);
4210 POST_MEM_WRITE(ARG3
, sizeof(struct vki_stat
));
4215 /* int openat(int fildes, const char *filename, int flags);
4216 int openat(int fildes, const char *filename, int flags, mode_t mode); */
4218 /* Interpret the first argument as 32-bit value even on 64-bit architecture.
4219 This is different from Linux, for example, where glibc sign-extends it. */
4220 Int fd
= (Int
) ARG1
;
4222 if (ARG3
& VKI_O_CREAT
) {
4224 PRINT("sys_openat ( %d, %#lx(%s), %ld, %ld )", fd
, ARG2
, (HChar
*) ARG2
,
4226 PRE_REG_READ4(long, "openat", int, fildes
, const char *, filename
,
4227 int, flags
, vki_mode_t
, mode
);
4231 PRINT("sys_openat ( %d, %#lx(%s), %ld )", fd
, ARG2
, (HChar
*) ARG2
,
4233 PRE_REG_READ3(long, "openat", int, fildes
, const char *, filename
,
4237 PRE_MEM_RASCIIZ("openat(filename)", ARG2
);
4239 /* Be strict but ignore fildes for absolute pathname. */
4240 if (fd
!= VKI_AT_FDCWD
4241 && ML_(safe_to_deref
)((void *) ARG2
, 1)
4242 && ((HChar
*) ARG2
)[0] != '/'
4243 && !ML_(fd_allowed
)(fd
, "openat", tid
, False
)) {
4244 SET_STATUS_Failure(VKI_EBADF
);
4248 if (ML_(handle_auxv_open
)(status
, (const HChar
*) ARG2
, ARG3
))
4251 if (handle_psinfo_open(status
, True
/*use_openat*/, (const HChar
*) ARG2
,
4255 #if defined(SOLARIS_PROC_CMDLINE)
4256 if (handle_cmdline_open(status
, (const HChar
*) ARG2
))
4258 #endif /* SOLARIS_PROC_CMDLINE */
4260 *flags
|= SfMayBlock
;
4265 if (!ML_(fd_allowed
)(RES
, "openat", tid
, True
)) {
4267 SET_STATUS_Failure(VKI_EMFILE
);
4269 else if (VG_(clo_track_fds
))
4270 ML_(record_fd_open_with_given_name
)(tid
, RES
, (HChar
*)ARG2
);
4275 /* Kernel: long tasksys(int code, projid_t projid, uint_t flags,
4276 void *projidbuf, size_t pbufsz);
4278 switch (ARG1
/*code*/) {
4280 /* Libc: taskid_t settaskid(projid_t project, uint_t flags); */
4281 PRINT("sys_tasksys ( %ld, %ld, %lu )", SARG1
, SARG2
, ARG3
);
4282 PRE_REG_READ3(long, SC2("tasksys", "settaskid"), int, code
,
4283 vki_projid_t
, projid
, vki_uint_t
, flags
);
4286 /* Libc: taskid_t gettaskid(void); */
4287 PRINT("sys_tasksys ( %ld )", SARG1
);
4288 PRE_REG_READ1(long, SC2("tasksys", "gettaskid"), int, code
);
4291 /* Libc: projid_t getprojid(void); */
4292 PRINT("sys_tasksys ( %ld )", SARG1
);
4293 PRE_REG_READ1(long, SC2("tasksys", "getprojid"), int, code
);
4296 /* Libproject: size_t projlist(id_t *idbuf, size_t idbufsz); */
4297 PRINT("sys_tasksys ( %ld, %#lx, %lu )", SARG1
, ARG4
, ARG5
);
4298 PRE_REG_READ3(long, SC2("tasksys", "projlist"), int, code
,
4299 vki_id_t
*, idbuf
, vki_size_t
, idbufsz
);
4300 PRE_MEM_WRITE("tasksys(idbuf)", ARG4
, ARG5
);
4303 VG_(unimplemented
)("Syswrap of the tasksys call with code %ld.", SARG1
);
4311 switch (ARG1
/*code*/) {
4317 if ((ARG4
!= 0) && (ARG5
!= 0))
4318 POST_MEM_WRITE(ARG4
, MIN(RES
, ARG5
));
4328 /* Kernel: int lwp_park(int which, uintptr_t arg1, uintptr_t arg2);
4330 *flags
|= SfMayBlock
;
4331 switch (ARG1
/*which*/) {
4333 /* Libc: int lwp_park(timespec_t *timeout, id_t lwpid); */
4334 PRINT("sys_lwp_park ( %ld, %#lx, %ld )", SARG1
, ARG2
, SARG3
);
4335 PRE_REG_READ3(long, SC2("lwp_park", "lwp_park"), int, which
,
4336 timespec_t
*, timeout
, vki_id_t
, lwpid
);
4338 PRE_MEM_READ("lwp_park(timeout)", ARG2
, sizeof(vki_timespec_t
));
4339 /*PRE_MEM_WRITE("lwp_park(timeout)", ARG2,
4340 sizeof(vki_timespec_t));*/
4344 /* Libc: int lwp_unpark(id_t lwpid); */
4345 PRINT("sys_lwp_park ( %ld, %ld )", SARG1
, SARG2
);
4346 PRE_REG_READ2(long, SC2("lwp_park", "lwp_unpark"), int, which
,
4350 /* Libc: int lwp_unpark_all(id_t *lwpid, int nids); */
4351 PRINT("sys_lwp_park ( %ld, %#lx, %ld )", SARG1
, ARG2
, SARG3
);
4352 PRE_REG_READ3(long, SC2("lwp_park", "lwp_unpark_all"), int, which
,
4353 id_t
*, lwpid
, int, nids
);
4354 PRE_MEM_READ("lwp_park(lwpid)", ARG2
, ARG3
* sizeof(vki_id_t
));
4357 VG_(unimplemented
)("Syswrap of the lwp_park call with which %ld.", SARG1
);
4365 switch (ARG1
/*which*/) {
4368 POST_MEM_WRITE(ARG2
, sizeof(vki_timespec_t
));
4381 /* Kernel: ssize_t sendfilev(int opcode, int fd,
4382 const struct sendfilevec *vec,
4383 int sfvcnt, size_t *xferred);
4385 PRINT("sys_sendfilev ( %ld, %ld, %#lx, %ld, %#lx )",
4386 SARG1
, SARG2
, ARG3
, SARG4
, ARG5
);
4388 switch (ARG1
/*opcode*/) {
4391 PRE_REG_READ5(long, "sendfilev", int, opcode
, int, fd
,
4392 const struct vki_sendfilevec
*, vec
,
4393 int, sfvcnt
, vki_size_t
*, xferred
);
4395 PRE_MEM_READ("sendfilev(vec)", ARG3
,
4396 ARG4
* sizeof(struct vki_sendfilevec
));
4397 PRE_MEM_WRITE("sendfilev(xferred)", ARG5
, sizeof(vki_size_t
));
4399 struct vki_sendfilevec
*vec
= (struct vki_sendfilevec
*) ARG3
;
4400 if (ML_(safe_to_deref
)(vec
, ARG4
*
4401 sizeof(struct vki_sendfilevec
))) {
4403 for (i
= 0; i
< ARG4
; i
++) {
4404 HChar desc
[35]; // large enough
4405 if (vec
[i
].sfv_fd
== VKI_SFV_FD_SELF
) {
4406 VG_(snprintf
)(desc
, sizeof(desc
),
4407 "sendfilev(vec[%u].sfv_off", i
);
4408 PRE_MEM_READ(desc
, vec
[i
].sfv_off
, vec
[i
].sfv_len
);
4410 VG_(snprintf
)(desc
, sizeof(desc
),
4411 "sendfilev(vec[%u].sfv_fd)", i
);
4412 if (!ML_(fd_allowed
)(vec
[i
].sfv_fd
, desc
, tid
, False
))
4413 SET_STATUS_Failure(VKI_EBADF
);
4419 case VKI_SENDFILEV64
:
4421 PRE_REG_READ5(long, "sendfilev", int, opcode
, int, fd
,
4422 const struct vki_sendfilevec64
*, vec
,
4423 int, sfvcnt
, vki_size_t
*, xferred
);
4425 PRE_MEM_READ("sendfilev(vec)", ARG3
,
4426 ARG4
* sizeof(struct vki_sendfilevec64
));
4427 PRE_MEM_WRITE("sendfilev(xferred)", ARG5
, sizeof(vki_size_t
));
4429 struct vki_sendfilevec64
*vec64
=
4430 (struct vki_sendfilevec64
*) ARG3
;
4431 if (ML_(safe_to_deref
)(vec64
, ARG4
*
4432 sizeof(struct vki_sendfilevec64
))) {
4434 for (i
= 0; i
< ARG4
; i
++) {
4435 HChar desc
[35]; // large enough
4436 if (vec64
[i
].sfv_fd
== VKI_SFV_FD_SELF
) {
4437 VG_(snprintf
)(desc
, sizeof(desc
),
4438 "sendfilev(vec[%u].sfv_off", i
);
4439 PRE_MEM_READ(desc
, vec64
[i
].sfv_off
, vec64
[i
].sfv_len
);
4441 VG_(snprintf
)(desc
, sizeof(desc
),
4442 "sendfilev(vec[%u].sfv_fd)", i
);
4443 if (!ML_(fd_allowed
)(vec64
[i
].sfv_fd
, desc
,
4445 SET_STATUS_Failure(VKI_EBADF
);
4452 VG_(unimplemented
)("Syswrap of the sendfilev call with "
4453 "opcode %ld.", SARG1
);
4459 if (!ML_(fd_allowed
)(ARG2
, "sendfilev(fd)", tid
, False
))
4460 SET_STATUS_Failure(VKI_EBADF
);
4462 *flags
|= SfMayBlock
;
4467 POST_MEM_WRITE(ARG5
, sizeof(vki_size_t
));
4470 #if defined(SOLARIS_LWP_NAME_SYSCALL)
4473 /* int lwp_name(int opcode, id_t lwpid, char *name, size_t len); */
4474 PRINT("sys_lwp_name ( %ld, %ld, %#lx, %lu )", SARG1
, SARG2
, ARG3
, ARG4
);
4476 switch (ARG1
/*opcode*/) {
4479 PRE_REG_READ3(long, "lwp_name", int, opcode
, vki_id_t
, lwpid
,
4481 PRE_MEM_RASCIIZ("lwp_name(name)", ARG3
);
4485 PRE_REG_READ4(long, "lwp_name", int, opcode
, vki_id_t
, lwpid
,
4486 char *, name
, vki_size_t
, len
);
4487 PRE_MEM_WRITE("lwp_name(name)", ARG3
, ARG4
);
4490 VG_(unimplemented
)("Syswrap of the lwp_name call with opcode %ld.", SARG1
);
4498 switch (ARG1
/*opcode*/) {
4500 if (ARG3
) { // Paranoia
4501 const HChar
*new_name
= (const HChar
*) ARG3
;
4502 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
4503 SizeT new_len
= VG_(strlen
)(new_name
);
4505 /* Don't bother reusing the memory. This is a rare event. */
4506 tst
->thread_name
= VG_(realloc
)("syswrap.lwp_name", tst
->thread_name
,
4508 VG_(strcpy
)(tst
->thread_name
, new_name
);
4512 POST_MEM_WRITE(ARG3
, VG_(strlen
)((HChar
*) ARG3
) + 1);
4519 #endif /* SOLARIS_LWP_NAME_SYSCALL */
4523 /* Kernel: int privsys(int code, priv_op_t op, priv_ptype_t type,
4524 void *buf, size_t bufsize, int itype);
4526 switch (ARG1
/*code*/) {
4527 case VKI_PRIVSYS_SETPPRIV
:
4528 /* Libc: int setppriv(priv_op_t op, priv_ptype_t type,
4529 const priv_set_t *pset);
4531 PRINT("sys_privsys ( %ld, %ld, %ld, %#lx, %lu )", SARG1
, SARG2
, SARG3
,
4533 PRE_REG_READ5(long, SC2("privsys", "setppriv"), int, code
,
4534 vki_priv_op_t
, op
, vki_priv_ptype_t
, type
,
4535 const priv_set_t
*, pset
, vki_size_t
, bufsize
);
4536 PRE_MEM_READ("privsys(pset)", ARG4
, ARG5
);
4538 case VKI_PRIVSYS_GETPPRIV
:
4539 /* Libc: int getppriv(priv_ptype_t type, priv_set_t *pset);
4540 priv_set_t *pset -> void *buf
4542 PRINT("sys_privsys ( %ld, %ld, %ld, %#lx, %lu )", SARG1
, SARG2
, SARG3
,
4544 PRE_REG_READ5(long, SC2("privsys", "getppriv"), int, code
,
4545 vki_priv_op_t
, op
, vki_priv_ptype_t
, type
, priv_set_t
*, pset
,
4546 vki_size_t
, bufsize
);
4547 PRE_MEM_WRITE("privsys(pset)", ARG4
, ARG5
);
4549 case VKI_PRIVSYS_GETIMPLINFO
:
4550 /* Libc: int getprivinfo(priv_impl_info_t *buf, size_t bufsize);
4551 priv_impl_info_t *buf -> void *buf
4553 PRINT("sys_privsys ( %ld, %ld, %ld, %#lx, %lu )", SARG1
, SARG2
, SARG3
,
4555 PRE_REG_READ5(long, SC2("privsys", "getprivinfo"), int, code
,
4556 vki_priv_op_t
, op
, vki_priv_ptype_t
, type
,
4557 priv_impl_info_t
*, buf
, vki_size_t
, bufsize
);
4558 PRE_MEM_WRITE("privsys(buf)", ARG4
, ARG5
);
4560 case VKI_PRIVSYS_SETPFLAGS
:
4561 /* Libc: int setpflags(uint_t flag, uint_t val);
4562 uint_t flag -> priv_op_t op
4563 uint_t val -> priv_ptype_t type
4565 PRINT("sys_privsys ( %ld, %lu, %lu )", SARG1
, ARG2
, ARG3
);
4566 PRE_REG_READ3(long, SC2("privsys", "setpflags"), int, code
,
4567 vki_uint_t
, flag
, vki_uint_t
, val
);
4569 case VKI_PRIVSYS_GETPFLAGS
:
4570 /* Libc: uint_t getpflags(uint_t flag);
4571 uint_t flag -> priv_op_t op
4573 PRINT("sys_privsys ( %ld, %lu )", SARG1
, ARG2
);
4574 PRE_REG_READ2(long, SC2("privsys", "setpflags"), int, code
,
4577 case VKI_PRIVSYS_ISSETUGID
:
4578 /* Libc: int issetugid(void); */
4579 PRINT("sys_privsys ( %ld )", SARG1
);
4580 PRE_REG_READ1(long, SC2("privsys", "issetugid"), int, code
);
4582 case VKI_PRIVSYS_PFEXEC_REG
:
4583 /* Libc: int register_pfexec(int did);
4584 int did -> priv_op_t op
4586 PRINT("sys_privsys ( %ld, %ld )", SARG1
, SARG2
);
4587 PRE_REG_READ2(long, SC2("privsys", "register_pfexec"), int, code
,
4590 case VKI_PRIVSYS_PFEXEC_UNREG
:
4591 /* Libc: int unregister_pfexec(int did); */
4592 PRINT("sys_privsys ( %ld, %ld )", SARG1
, SARG2
);
4593 PRE_REG_READ2(long, SC2("privsys", "unregister_pfexec"), int, code
,
4597 VG_(unimplemented
)("Syswrap of the privsys call with code %ld.", SARG1
);
4603 if ((ARG1
== VKI_PRIVSYS_PFEXEC_REG
||
4604 ARG1
== VKI_PRIVSYS_PFEXEC_UNREG
) &&
4605 !ML_(fd_allowed
)(ARG2
, "privsys", tid
, False
))
4606 SET_STATUS_Failure(VKI_EBADF
);
4611 switch (ARG1
/*code*/) {
4612 case VKI_PRIVSYS_SETPPRIV
:
4614 case VKI_PRIVSYS_GETPPRIV
:
4615 POST_MEM_WRITE(ARG4
, sizeof(vki_priv_set_t
));
4617 case VKI_PRIVSYS_GETIMPLINFO
:
4618 /* The kernel copy outs data of size min(bufsize, privinfosize).
4619 Unfortunately, it does not seem to be possible to easily obtain the
4620 privinfosize value. The code below optimistically marks all ARG5
4621 bytes (aka bufsize) as written by the kernel. */
4622 POST_MEM_WRITE(ARG4
, ARG5
);
4624 case VKI_PRIVSYS_SETPFLAGS
:
4625 case VKI_PRIVSYS_GETPFLAGS
:
4626 case VKI_PRIVSYS_ISSETUGID
:
4627 case VKI_PRIVSYS_PFEXEC_REG
:
4628 case VKI_PRIVSYS_PFEXEC_UNREG
:
4638 /* Kernel: int ucredsys(int code, int obj, void *buf); */
4639 PRINT("sys_ucredsys ( %ld, %ld, %#lx )", SARG1
, SARG2
, ARG3
);
4641 switch (ARG1
/*code*/) {
4642 case VKI_UCREDSYS_UCREDGET
:
4643 /* Libc: ucred_t *ucred_get(pid_t pid); */
4644 PRE_REG_READ3(long, SC2("ucredsys", "ucredget"), int, code
,
4645 vki_pid_t
, pid
, vki_ucred_t
*, buf
);
4646 PRE_MEM_WRITE("ucredsys(buf)", ARG3
, sizeof(vki_ucred_t
));
4649 case VKI_UCREDSYS_GETPEERUCRED
:
4650 /* Libc: int getpeerucred(int fd, ucred_t **ucred); */
4651 PRE_REG_READ3(long, SC2("ucredsys", "getpeerucred"), int, code
,
4652 int, fd
, vki_ucred_t
*, buf
);
4653 PRE_MEM_WRITE("ucredsys(buf)", ARG3
, sizeof(vki_ucred_t
));
4656 if (!ML_(fd_allowed
)(ARG2
, "ucredsys", tid
, False
))
4657 SET_STATUS_Failure(VKI_EBADF
);
4661 VG_(unimplemented
)("Syswrap of the ucredsys call with code %ld.", SARG1
);
4669 switch (ARG1
/*code*/) {
4670 case VKI_UCREDSYS_UCREDGET
:
4671 case VKI_UCREDSYS_GETPEERUCRED
:
4672 vg_assert(ARG3
!= 0);
4673 POST_MEM_WRITE(ARG3
, ((vki_ucred_t
*) ARG3
)->uc_size
);
4684 /* Kernel: int sysfs(int opcode, long a1, long a2); */
4685 PRINT("sys_sysfs ( %ld, %ld, %ld )", SARG1
, SARG2
, SARG3
);
4687 switch (ARG1
/*opcode*/) {
4689 /* Libc: int sysfs(int opcode, const char *fsname); */
4690 PRE_REG_READ2(long, SC2("sysfs", "getfsind"), int, opcode
,
4691 const char *, fsname
);
4692 PRE_MEM_RASCIIZ("sysfs(fsname)", ARG2
);
4695 /* Libc: int sysfs(int opcode, int fs_index, char *buf); */
4696 PRE_REG_READ3(long, SC2("sysfs", "getfstyp"), int, opcode
,
4697 int, fs_index
, char *, buf
);
4698 PRE_MEM_WRITE("sysfs(buf)", ARG3
, VKI_FSTYPSZ
+ 1);
4701 /* Libc: int sysfs(int opcode); */
4702 PRE_REG_READ1(long, SC2("sysfs", "getnfstyp"), int, opcode
);
4705 VG_(unimplemented
)("Syswrap of the sysfs call with opcode %ld.", SARG1
);
4713 switch (ARG1
/*opcode*/) {
4718 POST_MEM_WRITE(ARG3
, VG_(strlen
)((HChar
*) ARG3
) + 1);
4729 /* int getmsg(int fildes, struct strbuf *ctlptr, struct strbuf *dataptr,
4731 struct vki_strbuf
*ctrlptr
= (struct vki_strbuf
*)ARG2
;
4732 struct vki_strbuf
*dataptr
= (struct vki_strbuf
*)ARG3
;
4733 *flags
|= SfMayBlock
;
4734 PRINT("sys_getmsg ( %ld, %#lx, %#lx, %#lx )", SARG1
, ARG2
, ARG3
, ARG4
);
4735 PRE_REG_READ4(long, "getmsg", int, fildes
, struct vki_strbuf
*, ctlptr
,
4736 struct vki_strbuf
*, dataptr
, int *, flagsp
);
4738 PRE_FIELD_READ("getmsg(ctrlptr->maxlen)", ctrlptr
->maxlen
);
4739 PRE_FIELD_WRITE("getmsg(ctrlptr->len)", ctrlptr
->len
);
4740 PRE_FIELD_READ("getmsg(ctrlptr->buf)", ctrlptr
->buf
);
4741 if (ML_(safe_to_deref
)((void*)ARG2
, sizeof(struct vki_strbuf
))
4742 && ctrlptr
->maxlen
> 0)
4743 PRE_MEM_WRITE("getmsg(ctrlptr->buf)", (Addr
)ctrlptr
->buf
,
4747 PRE_FIELD_READ("getmsg(dataptr->maxlen)", dataptr
->maxlen
);
4748 PRE_FIELD_WRITE("getmsg(dataptr->len)", dataptr
->len
);
4749 PRE_FIELD_READ("getmsg(dataptr->buf)", dataptr
->buf
);
4750 if (ML_(safe_to_deref
)((void*)ARG3
, sizeof(struct vki_strbuf
))
4751 && dataptr
->maxlen
> 0)
4752 PRE_MEM_WRITE("getmsg(dataptr->buf)", (Addr
)dataptr
->buf
,
4755 PRE_MEM_READ("getmsg(flagsp)", ARG4
, sizeof(int));
4756 /*PRE_MEM_WRITE("getmsg(flagsp)", ARG4, sizeof(int));*/
4759 if (!ML_(fd_allowed
)(ARG1
, "getmsg", tid
, False
))
4760 SET_STATUS_Failure(VKI_EBADF
);
4765 struct vki_strbuf
*ctrlptr
= (struct vki_strbuf
*)ARG2
;
4766 struct vki_strbuf
*dataptr
= (struct vki_strbuf
*)ARG3
;
4768 if (ctrlptr
&& ctrlptr
->len
> 0)
4769 POST_MEM_WRITE((Addr
)ctrlptr
->buf
, ctrlptr
->len
);
4770 if (dataptr
&& dataptr
->len
> 0)
4771 POST_MEM_WRITE((Addr
)dataptr
->buf
, dataptr
->len
);
4772 POST_MEM_WRITE(ARG4
, sizeof(int));
4777 /* int putmsg(int fildes, struct strbuf *ctlptr, struct strbuf *dataptr,
4779 struct vki_strbuf
*ctrlptr
= (struct vki_strbuf
*)ARG2
;
4780 struct vki_strbuf
*dataptr
= (struct vki_strbuf
*)ARG3
;
4781 *flags
|= SfMayBlock
;
4782 PRINT("sys_putmsg ( %ld, %#lx, %#lx, %ld )", SARG1
, ARG2
, ARG3
, SARG4
);
4783 PRE_REG_READ4(long, "putmsg", int, fildes
, struct vki_strbuf
*, ctrlptr
,
4784 struct vki_strbuf
*, dataptr
, int, flags
);
4786 PRE_FIELD_READ("putmsg(ctrlptr->len)", ctrlptr
->len
);
4787 PRE_FIELD_READ("putmsg(ctrlptr->buf)", ctrlptr
->buf
);
4788 if (ML_(safe_to_deref
)((void*)ARG2
, sizeof(struct vki_strbuf
))
4789 && ctrlptr
->len
> 0)
4790 PRE_MEM_READ("putmsg(ctrlptr->buf)", (Addr
)ctrlptr
->buf
,
4794 PRE_FIELD_READ("putmsg(dataptr->len)", dataptr
->len
);
4795 PRE_FIELD_READ("putmsg(dataptr->buf)", dataptr
->buf
);
4796 if (ML_(safe_to_deref
)((void*)ARG3
, sizeof(struct vki_strbuf
))
4797 && dataptr
->len
> 0)
4798 PRE_MEM_READ("putmsg(dataptr->buf)", (Addr
)dataptr
->buf
,
4803 if (!ML_(fd_allowed
)(ARG1
, "putmsg", tid
, False
))
4804 SET_STATUS_Failure(VKI_EBADF
);
4809 /* int lstat(const char *path, struct stat *buf); */
4810 /* Note: We could use here the sys_newlstat generic wrapper, but the 'new'
4811 in its name is rather confusing in the Solaris context, thus we provide
4813 PRINT("sys_lstat ( %#lx(%s), %#lx )", ARG1
, (HChar
*) ARG1
, ARG2
);
4814 PRE_REG_READ2(long, "lstat", const char *, path
, struct stat
*, buf
);
4816 PRE_MEM_RASCIIZ("lstat(path)", ARG1
);
4817 PRE_MEM_WRITE("lstat(buf)", ARG2
, sizeof(struct vki_stat
));
4822 POST_MEM_WRITE(ARG2
, sizeof(struct vki_stat
));
4825 PRE(sys_sigprocmask
)
4827 /* int sigprocmask(int how, const sigset_t *set, sigset_t *oset); */
4828 PRINT("sys_sigprocmask ( %ld, %#lx, %#lx )", SARG1
, ARG2
, ARG3
);
4829 PRE_REG_READ3(long, "sigprocmask",
4830 int, how
, vki_sigset_t
*, set
, vki_sigset_t
*, oset
);
4832 PRE_MEM_READ("sigprocmask(set)", ARG2
, sizeof(vki_sigset_t
));
4834 PRE_MEM_WRITE("sigprocmask(oset)", ARG3
, sizeof(vki_sigset_t
));
4837 if (ARG2
&& !ML_(safe_to_deref((void*)ARG2
, sizeof(vki_sigset_t
)))) {
4838 SET_STATUS_Failure(VKI_EFAULT
);
4840 if (ARG3
&& !ML_(safe_to_deref((void*)ARG3
, sizeof(vki_sigset_t
)))) {
4841 SET_STATUS_Failure(VKI_EFAULT
);
4845 SET_STATUS_from_SysRes(
4846 VG_(do_sys_sigprocmask
)(tid
, ARG1
/*how*/, (vki_sigset_t
*)ARG2
,
4847 (vki_sigset_t
*)ARG3
)
4851 *flags
|= SfPollAfter
;
4854 POST(sys_sigprocmask
)
4857 POST_MEM_WRITE(ARG3
, sizeof(vki_sigset_t
));
4862 *flags
|= SfMayBlock
;
4864 /* int sigsuspend(const sigset_t *set); */
4865 PRINT("sys_sigsuspend ( %#lx )", ARG1
);
4866 PRE_REG_READ1(long, "sigsuspend", vki_sigset_t
*, set
);
4867 PRE_MEM_READ("sigsuspend(set)", ARG1
, sizeof(vki_sigset_t
));
4870 if (ARG1
&& ML_(safe_to_deref((void *) ARG1
, sizeof(vki_sigset_t
)))) {
4871 VG_(sigdelset
)((vki_sigset_t
*) ARG1
, VG_SIGVGKILL
);
4872 /* We cannot mask VG_SIGVGKILL, as otherwise this thread would not
4873 be killable by VG_(nuke_all_threads_except).
4874 We thus silently ignore the user request to mask this signal.
4875 Note that this is similar to what is done for e.g.
4876 sigprocmask (see m_signals.c calculate_SKSS_from_SCSS). */
4882 /* int sigaction(int signal, const struct sigaction *act,
4883 struct sigaction *oact); */
4884 PRINT("sys_sigaction ( %ld, %#lx, %#lx )", SARG1
, ARG2
, ARG3
);
4885 PRE_REG_READ3(long, "sigaction", int, signal
,
4886 const struct sigaction
*, act
, struct sigaction
*, oact
);
4888 /* Note that on Solaris, vki_sigaction_toK_t and vki_sigaction_fromK_t are
4889 both typedefs of 'struct sigaction'. */
4892 vki_sigaction_toK_t
*sa
= (vki_sigaction_toK_t
*)ARG2
;
4893 PRE_FIELD_READ("sigaction(act->sa_flags)", sa
->sa_flags
);
4894 PRE_FIELD_READ("sigaction(act->sa_handler)", sa
->ksa_handler
);
4895 PRE_FIELD_READ("sigaction(act->sa_mask)", sa
->sa_mask
);
4898 PRE_MEM_WRITE("sigaction(oact)", ARG3
, sizeof(vki_sigaction_fromK_t
));
4901 if (ARG2
&& !ML_(safe_to_deref((void*)ARG2
,
4902 sizeof(vki_sigaction_toK_t
)))) {
4903 SET_STATUS_Failure(VKI_EFAULT
);
4905 if (ARG3
&& !ML_(safe_to_deref((void*)ARG3
,
4906 sizeof(vki_sigaction_fromK_t
)))) {
4907 SET_STATUS_Failure(VKI_EFAULT
);
4911 SET_STATUS_from_SysRes(
4912 VG_(do_sys_sigaction
)(ARG1
, (const vki_sigaction_toK_t
*)ARG2
,
4913 (vki_sigaction_fromK_t
*)ARG3
));
4919 POST_MEM_WRITE(ARG3
, sizeof(vki_sigaction_fromK_t
));
4924 /* int sigpending(int flag, sigset_t *setp); */
4925 PRINT("sys_sigpending ( %ld, %#lx )", SARG1
, ARG2
);
4926 PRE_REG_READ2(long, "sigpending", int, flag
, sigset_t
*, setp
);
4927 PRE_MEM_WRITE("sigpending(setp)", ARG2
, sizeof(vki_sigset_t
));
4930 POST(sys_sigpending
)
4932 POST_MEM_WRITE(ARG2
, sizeof(vki_sigset_t
));
4935 PRE(sys_getsetcontext
)
4937 /* Kernel: int getsetcontext(int flag, void *arg) */
4938 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
4939 PRINT("sys_getsetcontext ( %ld, %#lx )", SARG1
, ARG2
);
4940 switch (ARG1
/*flag*/) {
4941 case VKI_GETCONTEXT
:
4942 /* Libc: int getcontext(ucontext_t *ucp); */
4943 PRE_REG_READ2(long, SC2("getsetcontext", "getcontext"), int, flag
,
4945 PRE_MEM_WRITE("getsetcontext(ucp)", ARG2
, sizeof(vki_ucontext_t
));
4947 if (!ML_(safe_to_deref((void*)ARG2
, sizeof(vki_ucontext_t
)))) {
4948 SET_STATUS_Failure(VKI_EFAULT
);
4951 VG_(save_context
)(tid
, (vki_ucontext_t
*)ARG2
, Vg_CoreSysCall
);
4952 SET_STATUS_Success(0);
4954 case VKI_SETCONTEXT
:
4955 /* Libc: int setcontext(const ucontext_t *ucp); */
4956 PRE_REG_READ2(long, SC2("getsetcontext", "setcontext"), int, flag
,
4957 const ucontext_t
*, ucp
);
4960 /* Setting NULL context causes thread exit. */
4961 tst
->exitreason
= VgSrc_ExitThread
;
4962 tst
->os_state
.exitcode
= 0;
4963 SET_STATUS_Success(0);
4967 if (!ML_(safe_to_deref((void*)ARG2
, sizeof(vki_ucontext_t
)))) {
4968 SET_STATUS_Failure(VKI_EFAULT
);
4972 VG_(restore_context
)(tid
, (vki_ucontext_t
*)ARG2
,
4973 Vg_CoreSysCall
, False
/*esp_is_thrptr*/);
4974 /* Tell the driver not to update the guest state with the "result". */
4975 *flags
|= SfNoWriteResult
;
4976 /* Check to see if any signals arose as a result of this. */
4977 *flags
|= SfPollAfter
;
4979 /* Check if this is a possible return from a signal handler. */
4980 VG_(sigframe_return
)(tid
, (vki_ucontext_t
*)ARG2
);
4982 SET_STATUS_Success(0);
4985 /* Libc: int getustack(stack_t **spp); */
4986 PRE_REG_READ2(long, SC2("getsetcontext", "getustack"), int, flag
,
4988 PRE_MEM_WRITE("getsetcontext(spp)", ARG2
, sizeof(vki_stack_t
*));
4990 if (!ML_(safe_to_deref((void*)ARG2
, sizeof(vki_stack_t
*)))) {
4991 SET_STATUS_Failure(VKI_EFAULT
);
4995 *(vki_stack_t
**)ARG2
= tst
->os_state
.ustack
;
4996 POST_MEM_WRITE(ARG2
, sizeof(vki_stack_t
*));
4997 SET_STATUS_Success(0);
5001 /* Libc: int setustack(stack_t *sp); */
5002 PRE_REG_READ2(long, SC2("getsetcontext", "setustack"), int, flag
,
5005 /* The kernel does not read the stack data instantly but it can read
5006 them later so it is better to make sure the data are defined. */
5007 PRE_MEM_READ("getsetcontext_setustack(sp)", ARG2
, sizeof(vki_stack_t
));
5009 if (!ML_(safe_to_deref((void*)ARG2
, sizeof(vki_stack_t
)))) {
5010 SET_STATUS_Failure(VKI_EFAULT
);
5014 vki_stack_t
*old_stack
= tst
->os_state
.ustack
;
5015 tst
->os_state
.ustack
= (vki_stack_t
*)ARG2
;
5017 /* The thread is setting the ustack pointer. It is a good time to get
5018 information about its stack. */
5019 if (tst
->os_state
.ustack
->ss_flags
== 0) {
5020 /* If the sanity check of ss_flags passed set the stack. */
5021 set_stack(tid
, tst
->os_state
.ustack
);
5023 if ((old_stack
== NULL
) && (tid
> 1)) {
5024 /* New thread creation is now completed. Inform the tool. */
5025 VG_TRACK(pre_thread_first_insn
, tid
);
5029 SET_STATUS_Success(0);
5033 VG_(unimplemented
)("Syswrap of the context call with flag %ld.", SARG1
);
5041 /* int fchmodat(int fd, const char *path, mode_t mode, int flag); */
5043 /* Interpret the first argument as 32-bit value even on 64-bit architecture.
5044 This is different from Linux, for example, where glibc sign-extends it. */
5045 Int fd
= (Int
) ARG1
;
5047 PRINT("sys_fchmodat ( %d, %#lx(%s), %ld, %ld )",
5048 fd
, ARG2
, (HChar
*) ARG2
, SARG3
, SARG4
);
5049 PRE_REG_READ4(long, "fchmodat",
5050 int, fd
, const char *, path
, vki_mode_t
, mode
, int, flag
);
5053 PRE_MEM_RASCIIZ("fchmodat(path)", ARG2
);
5055 /* Be strict but ignore fd for absolute path. */
5056 if (fd
!= VKI_AT_FDCWD
5057 && ML_(safe_to_deref
)((void *) ARG2
, 1)
5058 && ((HChar
*) ARG2
)[0] != '/'
5059 && !ML_(fd_allowed
)(fd
, "fchmodat", tid
, False
))
5060 SET_STATUS_Failure(VKI_EBADF
);
5065 /* int mkdirat(int fd, const char *path, mode_t mode); */
5067 /* Interpret the first argument as 32-bit value even on 64-bit architecture.
5068 This is different from Linux, for example, where glibc sign-extends it. */
5069 Int fd
= (Int
) ARG1
;
5071 *flags
|= SfMayBlock
;
5072 PRINT("sys_mkdirat ( %d, %#lx(%s), %ld )", fd
, ARG2
, (HChar
*) ARG2
, SARG3
);
5073 PRE_REG_READ3(long, "mkdirat", int, fd
, const char *, path
,
5075 PRE_MEM_RASCIIZ("mkdirat(path)", ARG2
);
5077 /* Be strict but ignore fd for absolute path. */
5078 if (fd
!= VKI_AT_FDCWD
5079 && ML_(safe_to_deref
)((void *) ARG2
, 1)
5080 && ((HChar
*) ARG2
)[0] != '/'
5081 && !ML_(fd_allowed
)(fd
, "mkdirat", tid
, False
))
5082 SET_STATUS_Failure(VKI_EBADF
);
5085 static void do_statvfs_post(struct vki_statvfs
*stats
, ThreadId tid
)
5087 POST_FIELD_WRITE(stats
->f_bsize
);
5088 POST_FIELD_WRITE(stats
->f_frsize
);
5089 POST_FIELD_WRITE(stats
->f_blocks
);
5090 POST_FIELD_WRITE(stats
->f_bfree
);
5091 POST_FIELD_WRITE(stats
->f_bavail
);
5092 POST_FIELD_WRITE(stats
->f_files
);
5093 POST_FIELD_WRITE(stats
->f_ffree
);
5094 POST_FIELD_WRITE(stats
->f_favail
);
5095 POST_FIELD_WRITE(stats
->f_fsid
);
5096 POST_MEM_WRITE((Addr
) stats
->f_basetype
, VG_(strlen
)(stats
->f_basetype
) + 1);
5097 POST_FIELD_WRITE(stats
->f_flag
);
5098 POST_FIELD_WRITE(stats
->f_namemax
);
5099 POST_MEM_WRITE((Addr
) stats
->f_fstr
, VG_(strlen
)(stats
->f_fstr
) + 1);
5104 /* int statvfs(const char *path, struct statvfs *buf); */
5105 *flags
|= SfMayBlock
;
5106 PRINT("sys_statvfs ( %#lx(%s), %#lx )", ARG1
, (HChar
*) ARG1
, ARG2
);
5107 PRE_REG_READ2(long, "statvfs", const char *, path
,
5108 struct vki_statvfs
*, buf
);
5109 PRE_MEM_RASCIIZ("statvfs(path)", ARG1
);
5110 PRE_MEM_WRITE("statvfs(buf)", ARG2
, sizeof(struct vki_statvfs
));
5115 do_statvfs_post((struct vki_statvfs
*) ARG2
, tid
);
5120 /* int fstatvfs(int fd, struct statvfs *buf); */
5121 *flags
|= SfMayBlock
;
5122 PRINT("sys_fstatvfs ( %ld, %#lx )", SARG1
, ARG2
);
5123 PRE_REG_READ2(long, "fstatvfs", int, fd
, struct vki_statvfs
*, buf
);
5124 PRE_MEM_WRITE("fstatvfs(buf)", ARG2
, sizeof(struct vki_statvfs
));
5127 if (!ML_(fd_allowed
)(ARG1
, "fstatvfs", tid
, False
))
5128 SET_STATUS_Failure(VKI_EBADF
);
5133 do_statvfs_post((struct vki_statvfs
*) ARG2
, tid
);
5138 /* int nfssys(enum nfssys_op opcode, void *arg); */
5139 *flags
|= SfMayBlock
;
5140 PRINT("sys_nfssys ( %ld, %#lx )", SARG1
, ARG2
);
5142 switch (ARG1
/*opcode*/) {
5143 case VKI_NFS_REVAUTH
:
5144 PRE_REG_READ2(long, SC2("nfssys", "nfs_revauth"), int, opcode
,
5145 struct vki_nfs_revauth_args
*, args
);
5146 PRE_MEM_READ("nfssys(arg)", ARG2
,
5147 sizeof(struct vki_nfs_revauth_args
));
5150 VG_(unimplemented
)("Syswrap of the nfssys call with opcode %ld.", SARG1
);
5158 switch (ARG1
/*opcode*/) {
5159 case VKI_NFS_REVAUTH
:
5169 /* int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options); */
5170 *flags
|= SfMayBlock
;
5171 PRINT("sys_waitid( %ld, %ld, %#lx, %ld )", SARG1
, SARG2
, ARG3
, SARG4
);
5172 PRE_REG_READ4(long, "waitid", vki_idtype_t
, idtype
, vki_id_t
, id
,
5173 siginfo_t
*, infop
, int, options
);
5174 PRE_MEM_WRITE("waitid(infop)", ARG3
, sizeof(vki_siginfo_t
));
5179 POST_MEM_WRITE(ARG3
, sizeof(vki_siginfo_t
));
5184 /* int sigsendsys(procset_t *psp, int sig); */
5185 PRINT("sys_sigsendsys( %#lx, %ld )", ARG1
, SARG2
);
5186 PRE_REG_READ2(long, "sigsendsys", vki_procset_t
*, psp
, int, signal
);
5187 PRE_MEM_READ("sigsendsys(psp)", ARG1
, sizeof(vki_procset_t
));
5189 if (!ML_(client_signal_OK
)(ARG1
)) {
5190 SET_STATUS_Failure(VKI_EINVAL
);
5192 if (!ML_(safe_to_deref
)((void *) ARG1
, sizeof(vki_procset_t
))) {
5193 SET_STATUS_Failure(VKI_EFAULT
);
5196 /* Exit early if there are problems. */
5200 vki_procset_t
*psp
= (vki_procset_t
*) ARG1
;
5201 switch (psp
->p_op
) {
5205 VG_(unimplemented
)("Syswrap of the sigsendsys call with op %u.",
5210 if ((psp
->p_lidtype
== VKI_P_PID
) && (psp
->p_ridtype
== VKI_P_ALL
)) {
5212 } else if ((psp
->p_lidtype
== VKI_P_ALL
) && (psp
->p_ridtype
== VKI_P_PID
)) {
5215 VG_(unimplemented
)("Syswrap of the sigsendsys call with lidtype %u and"
5216 "ridtype %u.", psp
->p_lidtype
, psp
->p_ridtype
);
5219 if (VG_(clo_trace_signals
))
5220 VG_(message
)(Vg_DebugMsg
, "sigsendsys: sending signal to process %u\n",
5223 /* Handle SIGKILL specially. */
5224 if (ARG2
== VKI_SIGKILL
&& ML_(do_sigkill
)(pid
, -1)) {
5225 SET_STATUS_Success(0);
5229 /* Check to see if this gave us a pending signal. */
5230 *flags
|= SfPollAfter
;
5233 #if defined(SOLARIS_UTIMESYS_SYSCALL)
5236 /* Kernel: int utimesys(int code, uintptr_t arg1, uintptr_t arg2,
5237 uintptr_t arg3, uintptr_t arg4);
5240 switch (ARG1
/*code*/) {
5242 /* Libc: int futimens(int fd, const timespec_t times[2]); */
5243 PRINT("sys_utimesys ( %ld, %ld, %#lx )", SARG1
, SARG2
, ARG3
);
5244 PRE_REG_READ3(long, "utimesys", int, code
, int, fd
,
5245 const vki_timespec_t
*, times
);
5247 PRE_MEM_READ("utimesys(times)", ARG3
, 2 * sizeof(vki_timespec_t
));
5250 if (!ML_(fd_allowed
)(ARG2
, "utimesys", tid
, False
))
5251 SET_STATUS_Failure(VKI_EBADF
);
5255 /* Libc: int utimensat(int fd, const char *path,
5256 const timespec_t times[2], int flag);
5259 /* Interpret the second argument as 32-bit value even on 64-bit
5260 architecture. This is different from Linux, for example, where glibc
5262 Int fd
= (Int
) ARG2
;
5264 PRINT("sys_utimesys ( %ld, %d, %#lx(%s), %#lx, %ld )",
5265 SARG1
, fd
, ARG3
, (HChar
*) ARG3
, ARG4
, SARG5
);
5266 PRE_REG_READ5(long, "utimesys", int, code
, int, fd
, const char *, path
,
5267 const vki_timespec_t
*, times
, int, flag
);
5269 PRE_MEM_RASCIIZ("utimesys(path)", ARG3
);
5271 PRE_MEM_READ("utimesys(times)", ARG4
, 2 * sizeof(vki_timespec_t
));
5273 /* Be strict but ignore fd for absolute path. */
5274 if (fd
!= VKI_AT_FDCWD
5275 && ML_(safe_to_deref
)((void *) ARG3
, 1)
5276 && ((HChar
*) ARG3
)[0] != '/'
5277 && !ML_(fd_allowed
)(fd
, "utimesys", tid
, False
))
5278 SET_STATUS_Failure(VKI_EBADF
);
5282 VG_(unimplemented
)("Syswrap of the utimesys call with code %ld.", SARG1
);
5287 #endif /* SOLARIS_UTIMESYS_SYSCALL */
5289 #if defined(SOLARIS_UTIMENSAT_SYSCALL)
5292 /* int utimensat(int fd, const char *path, const timespec_t times[2],
5296 /* Interpret the first argument as 32-bit value even on 64-bit architecture.
5297 This is different from Linux, for example, where glibc sign-extends it. */
5298 Int fd
= (Int
) ARG1
;
5300 PRINT("sys_utimensat ( %d, %#lx(%s), %#lx, %ld )",
5301 fd
, ARG2
, (HChar
*) ARG2
, ARG3
, SARG4
);
5302 PRE_REG_READ4(long, "utimensat", int, fd
, const char *, path
,
5303 const vki_timespec_t
*, times
, int, flag
);
5305 PRE_MEM_RASCIIZ("utimensat(path)", ARG2
);
5307 PRE_MEM_READ("utimensat(times)", ARG3
, 2 * sizeof(vki_timespec_t
));
5309 /* Be strict but ignore fd for absolute path. */
5310 if (fd
!= VKI_AT_FDCWD
5311 && ML_(safe_to_deref
)((void *) ARG2
, 1)
5312 && ((HChar
*) ARG2
)[0] != '/'
5313 && !ML_(fd_allowed
)(fd
, "utimensat", tid
, False
))
5314 SET_STATUS_Failure(VKI_EBADF
);
5316 #endif /* SOLARIS_UTIMENSAT_SYSCALL */
5320 /* int sigresend(int signal, siginfo_t *siginfo, sigset_t *mask); */
5321 /* Sends a signal to the calling thread, the mask parameter specifies a new
5324 /* Static (const) mask accessible from outside of this function. */
5325 static vki_sigset_t block_all
;
5327 PRINT("sys_sigresend( %ld, %#lx, %#lx )", SARG1
, ARG2
, ARG3
);
5328 PRE_REG_READ3(long, "sigresend", int, signal
, vki_siginfo_t
*, siginfo
,
5329 vki_sigset_t
*, mask
);
5332 PRE_MEM_READ("sigresend(siginfo)", ARG2
, sizeof(vki_siginfo_t
));
5333 PRE_MEM_WRITE("sigresend(mask)", ARG3
, sizeof(vki_sigset_t
));
5335 /* Check the signal and mask. */
5336 if (!ML_(client_signal_OK
)(ARG1
)) {
5337 SET_STATUS_Failure(VKI_EINVAL
);
5339 if (!ML_(safe_to_deref
)((void*)ARG3
, sizeof(vki_sigset_t
))) {
5340 SET_STATUS_Failure(VKI_EFAULT
);
5343 /* Exit early if there are problems. */
5347 /* Save the requested mask to unused ARG4. */
5350 /* Fake the requested sigmask with a block-all mask. If the syscall
5351 succeeds then we will block "all" signals for a few instructions (in
5352 syscall-x86-solaris.S) but the correct mask will be almost instantly set
5353 again by a call to sigprocmask (also in syscall-x86-solaris.S). If the
5354 syscall fails then the mask is not changed, so everything is ok too. */
5355 VG_(sigfillset
)(&block_all
);
5356 ARG3
= (UWord
)&block_all
;
5358 /* Check to see if this gave us a pending signal. */
5359 *flags
|= SfPollAfter
;
5361 if (VG_(clo_trace_signals
))
5362 VG_(message
)(Vg_DebugMsg
, "sigresend: resending signal %lu\n", ARG1
);
5364 /* Handle SIGKILL specially. */
5365 if (ARG1
== VKI_SIGKILL
&& ML_(do_sigkill
)(tid
, -1)) {
5366 SET_STATUS_Success(0);
5370 /* Ask to handle this syscall via the slow route, since that's the only one
5371 that sets tst->status to VgTs_WaitSys. If the result of doing the
5372 syscall is an immediate run of async_signalhandler() in m_signals.c,
5373 then we need the thread to be properly tidied away. */
5374 *flags
|= SfMayBlock
;
5379 /* The syscall succeeded, set the requested mask. */
5380 VG_(do_sys_sigprocmask
)(tid
, VKI_SIG_SETMASK
, (vki_sigset_t
*)ARG4
, NULL
);
5382 if (VG_(clo_trace_signals
))
5383 VG_(message
)(Vg_DebugMsg
, "sigresend: resent signal %lu\n", ARG1
);
5386 static void mem_priocntlsys_parm_ok(ThreadId tid
, Bool pre
, Bool reade
,
5387 vki_pc_vaparm_t
*parm
)
5393 PRE_FIELD_WRITE("priocntlsys(parm)", parm
->pc_parm
);
5395 POST_FIELD_WRITE(parm
->pc_parm
);
5398 static void mem_priocntlsys_parm(ThreadId tid
, Bool pre
, Bool reade
,
5399 const HChar
*clname
,
5400 vki_pc_vaparm_t
*parm
)
5402 /* This function is used to handle the PC_SETXPARMS and PC_GETXPARMS
5403 parameters. In the case of PC_SETXPARMS, the code below merely checks
5404 if all parameters are scalar, PRE_MEM_READ() for these parameters is
5405 already done by the PC_SETXPARMS handler in PRE(sys_priocntlsys).
5407 A caller of this function is responsible for checking that clname and
5408 &parm->key can be dereferenced. */
5410 if (VG_STREQ(clname
, "RT")) {
5411 switch (parm
->pc_key
) {
5413 case VKI_RT_KY_TQSECS
:
5414 case VKI_RT_KY_TQNSECS
:
5415 case VKI_RT_KY_TQSIG
:
5416 /* Scalar values that are stored directly in pc_parm. */
5417 mem_priocntlsys_parm_ok(tid
, pre
, reade
, parm
);
5421 else if (VG_STREQ(clname
, "TS")) {
5422 switch (parm
->pc_key
) {
5423 case VKI_TS_KY_UPRILIM
:
5424 case VKI_TS_KY_UPRI
:
5425 /* Scalar values that are stored directly in pc_parm. */
5426 mem_priocntlsys_parm_ok(tid
, pre
, reade
, parm
);
5430 else if (VG_STREQ(clname
, "IA")) {
5431 switch (parm
->pc_key
) {
5432 case VKI_IA_KY_UPRILIM
:
5433 case VKI_IA_KY_UPRI
:
5434 case VKI_IA_KY_MODE
:
5435 /* Scalar values that are stored directly in pc_parm. */
5436 mem_priocntlsys_parm_ok(tid
, pre
, reade
, parm
);
5440 else if (VG_STREQ(clname
, "FSS")) {
5441 switch (parm
->pc_key
) {
5442 case VKI_FSS_KY_UPRILIM
:
5443 case VKI_FSS_KY_UPRI
:
5444 /* Scalar values that are stored directly in pc_parm. */
5445 mem_priocntlsys_parm_ok(tid
, pre
, reade
, parm
);
5449 else if (VG_STREQ(clname
, "FX")) {
5450 switch (parm
->pc_key
) {
5451 case VKI_FX_KY_UPRILIM
:
5452 case VKI_FX_KY_UPRI
:
5453 case VKI_FX_KY_TQSECS
:
5454 case VKI_FX_KY_TQNSECS
:
5455 /* Scalar values that are stored directly in pc_parm. */
5456 mem_priocntlsys_parm_ok(tid
, pre
, reade
, parm
);
5461 /* Unknown class. */
5462 VG_(unimplemented
)("Syswrap of the priocntlsys call where clname=%s.",
5467 /* The class is known but pc_key is unknown. */
5468 VG_(unimplemented
)("Syswrap of the priocntlsys call where clname=%s "
5469 "and pc_key=%d.", clname
, parm
->pc_key
);
5473 PRE(sys_priocntlsys
)
5475 /* long priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg,
5479 /* Only the first version of priocntlsys is supported by the code below.
5481 VG_(unimplemented
)("Syswrap of the priocntlsys where pc_version=%lu.",
5486 PRINT("sys_priocntlsys ( %ld, %#lx, %ld, %#lx, %#lx )", SARG1
, ARG2
, SARG3
,
5488 PRE_REG_READ5(long, "priocntlsys", int, pc_version
, procset_t
*, psp
,
5489 int, cmd
, void *, arg
, void *, arg2
);
5491 switch (ARG3
/*cmd*/) {
5494 vki_pcinfo_t
*info
= (vki_pcinfo_t
*)ARG4
;
5495 PRE_MEM_RASCIIZ("priocntlsys(clname)", (Addr
)info
->pc_clname
);
5496 /* The next line says that the complete pcinfo_t structure can be
5497 written, but this actually isn't true for pc_clname which is
5498 always only read. */
5499 PRE_MEM_WRITE("priocntlsys(pcinfo)", ARG4
, sizeof(vki_pcinfo_t
));
5502 case VKI_PC_GETCLINFO
:
5504 vki_pcinfo_t
*info
= (vki_pcinfo_t
*)ARG4
;
5505 PRE_FIELD_READ("priocntlsys(cid)", info
->pc_cid
);
5506 /* The next line says that the complete pcinfo_t structure can be
5507 written, but this actually isn't true for pc_cid which is
5508 always only read. */
5509 PRE_MEM_WRITE("priocntlsys(pcinfo)", ARG4
, sizeof(vki_pcinfo_t
));
5512 case VKI_PC_SETPARMS
:
5513 PRE_MEM_READ("priocntlsys(psp)", ARG2
, sizeof(vki_procset_t
));
5514 /* The next line says that the complete pcparms_t structure is read
5515 which is never actually true (we are too pessimistic here).
5516 Unfortunately we can't do better because we don't know what
5517 process class is involved. */
5518 PRE_MEM_READ("priocntlsys(parms)", ARG4
, sizeof(vki_pcparms_t
));
5520 case VKI_PC_GETPARMS
:
5521 PRE_MEM_READ("priocntlsys(psp)", ARG2
, sizeof(vki_procset_t
));
5522 PRE_MEM_WRITE("priocntlsys(parms)", ARG4
, sizeof(vki_pcparms_t
));
5524 case VKI_PC_GETPRIRANGE
:
5526 vki_pcpri_t
*pcpri
= (vki_pcpri_t
*)ARG4
;
5527 PRE_FIELD_READ("priocntlsys(cid)", pcpri
->pc_cid
);
5529 PRE_MEM_WRITE("priocntlsys(pri)", ARG4
, sizeof(vki_pcpri_t
));
5532 PRE_MEM_READ("priocntlsys(psp)", ARG2
, sizeof(vki_procset_t
));
5534 vki_pcnice_t
*nicee
= (vki_pcnice_t
*)ARG4
;
5535 PRE_FIELD_READ("priocntlsys(op)", nicee
->pc_op
);
5536 if (ML_(safe_to_deref
)(&nicee
->pc_op
, sizeof(nicee
->pc_op
))) {
5537 switch (nicee
->pc_op
) {
5538 case VKI_PC_GETNICE
:
5539 PRE_FIELD_WRITE("priocntlsys(val)", nicee
->pc_val
);
5541 case VKI_PC_SETNICE
:
5542 PRE_FIELD_READ("priocntlsys(val)", nicee
->pc_val
);
5545 VG_(unimplemented
)("Syswrap of the priocntlsys call where "
5546 "cmd=PC_DONICE and pc_op=%d", nicee
->pc_op
);
5553 case VKI_PC_SETXPARMS
:
5554 PRE_MEM_READ("priocntlsys(psp)", ARG2
, sizeof(vki_procset_t
));
5555 PRE_MEM_RASCIIZ("priocntlsys(clname)", ARG4
);
5557 vki_pc_vaparms_t
*parms
= (vki_pc_vaparms_t
*)ARG5
;
5558 PRE_FIELD_READ("priocntlsys(vaparmscnt)", parms
->pc_vaparmscnt
);
5559 if (ML_(safe_to_deref
)(&parms
->pc_vaparmscnt
,
5560 sizeof(parms
->pc_vaparmscnt
))) {
5562 PRE_MEM_READ("priocntlsys(parms)", (Addr
)parms
->pc_parms
,
5563 parms
->pc_vaparmscnt
* sizeof(parms
->pc_parms
[0]));
5564 for (i
= 0; i
< parms
->pc_vaparmscnt
; i
++) {
5565 vki_pc_vaparm_t
*parm
= &parms
->pc_parms
[i
];
5566 if (ML_(safe_to_deref
)(parm
, sizeof(*parm
)) &&
5567 ML_(safe_to_deref
)((void*)ARG4
, 1))
5568 mem_priocntlsys_parm(tid
, True
/*pre*/, True
/*read*/,
5569 (HChar
*)ARG4
, parm
);
5574 case VKI_PC_GETXPARMS
:
5575 PRE_MEM_READ("priocntlsys(psp)", ARG2
, sizeof(vki_procset_t
));
5577 PRE_MEM_RASCIIZ("priocntlsys(clname)", ARG4
);
5579 vki_pc_vaparms_t
*parms
= (vki_pc_vaparms_t
*)ARG5
;
5580 PRE_FIELD_READ("priocntlsys(vaparmscnt)", parms
->pc_vaparmscnt
);
5581 if (ML_(safe_to_deref
)(&parms
->pc_vaparmscnt
,
5582 sizeof(parms
->pc_vaparmscnt
))) {
5584 for (i
= 0; i
< parms
->pc_vaparmscnt
; i
++) {
5585 vki_pc_vaparm_t
*parm
= &parms
->pc_parms
[i
];
5586 PRE_MEM_READ("priocntlsys(parms)", (Addr
)&parm
->pc_key
,
5587 parms
->pc_vaparmscnt
* sizeof(parm
->pc_key
));
5588 if (ML_(safe_to_deref
)(&parm
->pc_key
,
5589 sizeof(parm
->pc_key
))) {
5590 /* First handle PC_KY_CLNAME, then class specific keys.
5591 Note that PC_KY_CLNAME can be used only with
5592 ARG4==NULL && parms->pc_vaparmscnt==1. We are not so
5593 strict here and handle this special case as a regular
5594 one which makes the code simpler. */
5595 if (parm
->pc_key
== VKI_PC_KY_CLNAME
)
5596 PRE_MEM_WRITE("priocntlsys(clname)", parm
->pc_parm
,
5598 else if (ARG4
&& ML_(safe_to_deref
)((void*)ARG4
, 1))
5599 mem_priocntlsys_parm(tid
, True
/*pre*/,
5600 False
/*read*/, (HChar
*)ARG4
,
5607 case VKI_PC_SETDFLCL
:
5608 PRE_MEM_RASCIIZ("priocntlsys(clname)", ARG4
);
5610 case VKI_PC_GETDFLCL
:
5612 /* GETDFLCL writes to the ARG4 buffer only if ARG4 isn't NULL. Also
5613 note that if ARG4 is NULL then the syscall succeeds. */
5614 PRE_MEM_WRITE("priocntlsys(clname)", ARG4
, VKI_PC_CLNMSZ
);
5618 PRE_MEM_READ("priocntlsys(psp)", ARG2
, sizeof(vki_procset_t
));
5620 vki_pcprio_t
*prio
= (vki_pcprio_t
*)ARG4
;
5621 PRE_FIELD_READ("priocntlsys(op)", prio
->pc_op
);
5622 if (ML_(safe_to_deref
)(&prio
->pc_op
, sizeof(prio
->pc_op
))) {
5623 switch (prio
->pc_op
) {
5624 case VKI_PC_GETPRIO
:
5625 PRE_FIELD_WRITE("priocntlsys(cid)", prio
->pc_cid
);
5626 PRE_FIELD_WRITE("priocntlsys(val)", prio
->pc_val
);
5628 case VKI_PC_SETPRIO
:
5629 PRE_FIELD_READ("priocntlsys(cid)", prio
->pc_cid
);
5630 PRE_FIELD_READ("priocntlsys(val)", prio
->pc_val
);
5633 VG_(unimplemented
)("Syswrap of the priocntlsys call where "
5634 "cmd=PC_DOPRIO and pc_op=%d", prio
->pc_op
);
5643 VG_(unimplemented
)("Syswrap of the priocntlsys call with cmd %ld.", SARG3
);
5649 static void post_mem_write_priocntlsys_clinfo(ThreadId tid
,
5650 const HChar
*clname
, Addr clinfo
)
5652 if (VG_STREQ(clname
, "RT"))
5653 POST_MEM_WRITE(clinfo
, sizeof(vki_rtinfo_t
));
5654 else if (VG_STREQ(clname
, "TS"))
5655 POST_MEM_WRITE(clinfo
, sizeof(vki_tsinfo_t
));
5656 else if (VG_STREQ(clname
, "IA"))
5657 POST_MEM_WRITE(clinfo
, sizeof(vki_iainfo_t
));
5658 else if (VG_STREQ(clname
, "FSS"))
5659 POST_MEM_WRITE(clinfo
, sizeof(vki_fssinfo_t
));
5660 else if (VG_STREQ(clname
, "FX"))
5661 POST_MEM_WRITE(clinfo
, sizeof(vki_fxinfo_t
));
5662 else if (VG_STREQ(clname
, "SDC")) {
5666 VG_(unimplemented
)("Syswrap of the priocntlsys call where clname=%s.",
5672 POST(sys_priocntlsys
)
5674 switch (ARG3
/*cmd*/) {
5677 vki_pcinfo_t
*info
= (vki_pcinfo_t
*)ARG4
;
5678 POST_FIELD_WRITE(info
->pc_cid
);
5679 post_mem_write_priocntlsys_clinfo(tid
, info
->pc_clname
,
5680 (Addr
)&info
->pc_clinfo
);
5683 case VKI_PC_GETCLINFO
:
5685 vki_pcinfo_t
*info
= (vki_pcinfo_t
*)ARG4
;
5686 POST_MEM_WRITE((Addr
)info
->pc_clname
,
5687 VG_(strlen
)((HChar
*)info
->pc_clname
) + 1);
5688 post_mem_write_priocntlsys_clinfo(tid
, info
->pc_clname
,
5689 (Addr
)&info
->pc_clinfo
);
5692 case VKI_PC_SETPARMS
:
5695 case VKI_PC_GETPARMS
:
5696 /* The next line says that the complete pcparms_t structure is
5697 written which is never actually true (we are too optimistic here).
5698 Unfortunately we can't do better because we don't know what
5699 process class is involved. */
5700 POST_MEM_WRITE(ARG4
, sizeof(vki_pcparms_t
));
5702 case VKI_PC_GETPRIRANGE
:
5703 POST_MEM_WRITE(ARG4
, sizeof(vki_pcpri_t
));
5707 vki_pcnice_t
*nicee
= (vki_pcnice_t
*)ARG4
;
5708 if (nicee
->pc_op
== VKI_PC_GETNICE
)
5709 POST_FIELD_WRITE(nicee
->pc_val
);
5712 case VKI_PC_SETXPARMS
:
5715 case VKI_PC_GETXPARMS
:
5717 vki_pc_vaparms_t
*parms
= (vki_pc_vaparms_t
*)ARG5
;
5719 for (i
= 0; i
< parms
->pc_vaparmscnt
; i
++) {
5720 vki_pc_vaparm_t
*parm
= &parms
->pc_parms
[i
];
5721 if (parm
->pc_key
== VKI_PC_KY_CLNAME
)
5722 POST_MEM_WRITE(parm
->pc_parm
,
5723 VG_(strlen
)((HChar
*)(Addr
)parm
->pc_parm
) + 1);
5725 mem_priocntlsys_parm(tid
, False
/*pre*/, False
/*read*/,
5726 (HChar
*)ARG4
, parm
);
5730 case VKI_PC_SETDFLCL
:
5733 case VKI_PC_GETDFLCL
:
5735 POST_MEM_WRITE(ARG4
, VG_(strlen
)((HChar
*)ARG4
) + 1);
5739 vki_pcprio_t
*prio
= (vki_pcprio_t
*)ARG4
;
5740 if (prio
->pc_op
== VKI_PC_GETPRIO
) {
5741 POST_FIELD_WRITE(prio
->pc_cid
);
5742 POST_FIELD_WRITE(prio
->pc_val
);
5755 /* long pathconf(const char *path, int name); */
5756 PRINT("sys_pathconf ( %#lx(%s), %ld )", ARG1
, (HChar
*) ARG1
, SARG2
);
5757 PRE_REG_READ2(long, "pathconf", const char *, path
, int, name
);
5758 PRE_MEM_RASCIIZ("pathconf(path)", ARG1
);
5763 /* void *mmap(void *addr, size_t len, int prot, int flags,
5764 int fildes, off_t off); */
5769 vg_assert(VKI_PAGE_SIZE
== 4096);
5770 vg_assert(sizeof(offset
) == sizeof(ARG6
));
5772 PRINT("sys_mmap ( %#lx, %#lx, %#lx, %#lx, %ld, %#lx )",
5773 ARG1
, ARG2
, ARG3
, ARG4
, SARG5
, ARG6
);
5774 PRE_REG_READ6(long, "mmap", void *, start
, vki_size_t
, length
,
5775 int, prot
, int, flags
, int, fd
, vki_off_t
, offset
);
5777 /* Make sure that if off < 0 then it's passed correctly to the generic mmap
5779 offset
= *(OffT
*)&ARG6
;
5781 r
= ML_(generic_PRE_sys_mmap
)(tid
, ARG1
, ARG2
, ARG3
, ARG4
, ARG5
, offset
);
5782 SET_STATUS_from_SysRes(r
);
5785 #if defined(SOLARIS_UUIDSYS_SYSCALL)
5788 /* int uuidsys(struct uuid *uuid); */
5789 PRINT("sys_uuidsys ( %#lx )", ARG1
);
5790 PRE_REG_READ1(long, "uuidsys", struct vki_uuid
*, uuid
);
5791 PRE_MEM_WRITE("uuidsys(uuid)", ARG1
, sizeof(struct vki_uuid
));
5796 POST_MEM_WRITE(ARG1
, sizeof(struct vki_uuid
));
5798 #endif /* SOLARIS_UUIDSYS_SYSCALL */
5800 /* Syscall mmapobj emulation. Processes ELF program headers
5801 and maps them into correct place in memory. Not an easy task, though.
5802 ELF program header of PT_LOAD/PT_SUNWBSS type specifies:
5803 o p_vaddr - actually a memory offset
5804 o p_memsz - total segment size, including text, data and BSS
5805 o p_filesz - file-based segment size mapping (includes only text and data);
5806 p_memsz - p_filesz is the size of BSS
5807 o p_offset - offset into the ELF file where the file-based mapping starts
5809 Several problematic areas to cover here:
5810 1. p_offset can contain a value which is not page-aligned. In that case
5811 we mmap a part of the file prior to p_offset to make the start address
5813 2. Partially unused page after the file-based mapping must be zeroed.
5814 3. The first mapping is flagged with MR_HDR_ELF and needs to contain
5815 the ELF header. This information is used and verified by the dynamic
5816 linker (ld.so.1). */
5817 static SysRes
mmapobj_process_phdrs(ThreadId tid
, Int fd
,
5818 vki_mmapobj_result_t
*storage
,
5819 vki_uint_t
*elements
,
5820 const VKI_ESZ(Ehdr
) *ehdr
,
5821 const VKI_ESZ(Phdr
) *phdrs
)
5823 #define ADVANCE_PHDR(ehdr, phdr) \
5824 (const VKI_ESZ(Phdr) *) ((const HChar *) (phdr) + (ehdr)->e_phentsize)
5828 Int first_segment_idx
= -1;
5830 UInt segments
= 0; /* loadable segments */
5831 Addr start_addr
= 0;
5834 SizeT max_align
= VKI_PAGE_SIZE
;
5836 /* 1. First pass over phdrs - determine number, span and max alignment. */
5837 const VKI_ESZ(Phdr
) *phdr
= phdrs
;
5838 for (idx
= 0; idx
< ehdr
->e_phnum
; idx
++, phdr
= ADVANCE_PHDR(ehdr
, phdr
)) {
5839 /* Skip this header if no memory is requested. */
5840 if (phdr
->p_memsz
== 0)
5843 if ((phdr
->p_type
== VKI_PT_LOAD
) || (phdr
->p_type
== VKI_PT_SUNWBSS
)) {
5846 if (VG_(clo_trace_syscalls
))
5847 VG_(debugLog
)(2, "syswrap-solaris", "mmapobj_process_phdrs: "
5848 "program header #%u: addr=%#lx type=%#lx "
5849 "prot=%#lx memsz=%#lx filesz=%#lx file "
5850 "offset=%#lx\n", idx
, phdr
->p_vaddr
,
5851 (UWord
) phdr
->p_type
, (UWord
) phdr
->p_flags
,
5852 phdr
->p_memsz
, phdr
->p_filesz
, phdr
->p_offset
);
5854 if (segments
== 0) {
5855 first_segment_idx
= idx
;
5857 if (phdr
->p_filesz
== 0) {
5858 VG_(unimplemented
)("Syswrap of the mmapobj call with the first "
5859 "loadable ELF program header specifying "
5865 /* Address of the first segment must be either NULL or within the
5867 if ((ehdr
->e_type
== VKI_ET_DYN
) &&
5868 ((phdr
->p_vaddr
& VKI_PAGEMASK
) != 0)) {
5869 if (VG_(clo_trace_syscalls
))
5870 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_process_phdrs: "
5871 "ELF program header #%u does not land on "
5872 "the first page (vaddr=%#lx)\n", idx
,
5874 return VG_(mk_SysRes_Error
)(VKI_ENOTSUP
);
5877 start_addr
= phdr
->p_vaddr
;
5878 /* The first segment is mapped from the beginning of the file (to
5879 include also the ELF header), so include this memory as well.
5880 Later on we flag this mapping with MR_HDR_ELF. */
5881 offset
= phdr
->p_offset
;
5884 if (phdr
->p_align
> 1) {
5885 if ((phdr
->p_vaddr
% phdr
->p_align
) !=
5886 (phdr
->p_offset
% phdr
->p_align
)) {
5887 if (VG_(clo_trace_syscalls
))
5888 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_process_phdrs: "
5889 "ELF program header #%u does not have "
5890 "congruent offset and vaddr (vaddr=%#lx "
5891 "file offset=%#lx align=%#lx)\n", idx
,
5892 phdr
->p_vaddr
, phdr
->p_offset
,
5894 return VG_(mk_SysRes_Error
)(VKI_ENOTSUP
);
5898 if (phdr
->p_vaddr
< end_addr
) {
5899 if (VG_(clo_trace_syscalls
))
5900 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_process_phdrs: "
5901 "ELF program header #%u specifies overlaping "
5902 "address (vaddr=%#lx end_addr=%#lx)\n",
5903 idx
, phdr
->p_vaddr
, end_addr
);
5904 return VG_(mk_SysRes_Error
)(VKI_ENOTSUP
);
5907 end_addr
= elfbrk
= phdr
->p_vaddr
+ phdr
->p_memsz
+ offset
;
5908 end_addr
= VG_PGROUNDUP(end_addr
);
5909 if (phdr
->p_align
> max_align
) {
5910 max_align
= phdr
->p_align
;
5917 /* Alignment check - it should be power of two. */
5918 if ((max_align
& (max_align
- 1)) != 0) {
5919 if (VG_(clo_trace_syscalls
))
5920 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_process_phdrs: alignment "
5921 "is not a power of 2 (%#lx)\n", max_align
);
5922 return VG_(mk_SysRes_Error
)(VKI_ENOTSUP
);
5924 vg_assert(max_align
>= VKI_PAGE_SIZE
);
5926 #if defined(VGP_x86_solaris)
5927 if (max_align
> VKI_UINT_MAX
) {
5928 if (VG_(clo_trace_syscalls
))
5929 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_process_phdrs: alignment "
5930 "for 32-bit ELF is >32-bits (%#lx)\n", max_align
);
5931 return VG_(mk_SysRes_Error
)(VKI_ENOTSUP
);
5933 #endif /* VGP_x86_solaris */
5935 if (segments
== 0) {
5936 if (VG_(clo_trace_syscalls
))
5937 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_process_phdrs: nothing "
5938 "to map (0 loadable segments)");
5939 return VG_(mk_SysRes_Error
)(VKI_ENOTSUP
);
5942 vg_assert(end_addr
>= start_addr
);
5943 SizeT span
= end_addr
- start_addr
;
5945 if (VG_(clo_trace_syscalls
))
5946 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_process_phdrs: nothing "
5947 "to map (%u loadable segments spanning 0 bytes)\n",
5949 return VG_(mk_SysRes_Error
)(VKI_ENOTSUP
);
5951 vg_assert(first_segment_idx
>= 0);
5953 if (segments
> *elements
) {
5954 if (VG_(clo_trace_syscalls
))
5955 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_process_phdrs: too many "
5956 "segments (%u)\n", segments
);
5957 return VG_(mk_SysRes_Error
)(VKI_E2BIG
);
5960 if (VG_(clo_trace_syscalls
))
5961 VG_(debugLog
)(2, "syswrap-solaris", "mmapobj_process_phdrs: there "
5962 "are %u loadable segments spanning %#lx bytes; max "
5963 "align is %#lx\n", segments
, span
, max_align
);
5965 /* Now get the aspacemgr oraculum advisory.
5966 Later on we mmap file-based and BSS mappings into this address space area
5967 as required and leave the holes unmapped. */
5968 if (ehdr
->e_type
== VKI_ET_DYN
) {
5969 MapRequest mreq
= {MAlign
, max_align
, span
};
5971 start_addr
= VG_(am_get_advisory
)(&mreq
, True
/* forClient */, &ok
);
5973 if (VG_(clo_trace_syscalls
))
5974 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_process_phdrs: "
5975 "failed to reserve address space of %#lx bytes "
5976 "with alignment %#lx\n", span
, max_align
);
5977 return VG_(mk_SysRes_Error
)(VKI_ENOMEM
);
5979 vg_assert(VG_ROUNDUP(start_addr
, max_align
) == start_addr
);
5981 if (VG_(clo_trace_syscalls
))
5982 VG_(debugLog
)(2, "syswrap-solaris", "PRE(sys_mmapobj): address space "
5983 "reserved at: vaddr=%#lx size=%#lx\n",
5986 vg_assert(ehdr
->e_type
== VKI_ET_EXEC
);
5987 /* ET_EXEC uses fixed mappings. Will be checked when processing phdrs. */
5990 /* This is an utterly ugly hack, the aspacemgr assumes that only one
5991 segment is added at the time. However we add here multiple segments so
5992 AM_SANITY_CHECK inside the aspacemgr can easily fail. We want to
5993 prevent that thus we disable these checks. The scheduler will check the
5994 aspacemgr sanity after the syscall. */
5995 UInt sanity_level
= VG_(clo_sanity_level
);
5996 VG_(clo_sanity_level
) = 1;
5998 /* 2. Second pass over phdrs - map the program headers and fill in
5999 the mmapobj_result_t array. */
6002 for (idx
= 0; idx
< ehdr
->e_phnum
; idx
++, phdr
= ADVANCE_PHDR(ehdr
, phdr
)) {
6003 /* Skip this header if no memory is requested. */
6004 if (phdr
->p_memsz
== 0)
6007 if ((phdr
->p_type
== VKI_PT_LOAD
) || (phdr
->p_type
== VKI_PT_SUNWBSS
)) {
6009 if (phdr
->p_flags
& VKI_PF_R
)
6010 prot
|= VKI_PROT_READ
;
6011 if (phdr
->p_flags
& VKI_PF_W
)
6012 prot
|= VKI_PROT_WRITE
;
6013 if (phdr
->p_flags
& VKI_PF_X
)
6014 prot
|= VKI_PROT_EXEC
;
6016 vki_mmapobj_result_t
*mrp
= &storage
[*elements
];
6017 mrp
->mr_msize
= phdr
->p_memsz
;
6018 mrp
->mr_fsize
= phdr
->p_filesz
;
6020 mrp
->mr_prot
= prot
;
6022 Off64T file_offset
= phdr
->p_offset
;
6023 if (idx
== first_segment_idx
) {
6024 mrp
->mr_flags
= VKI_MR_HDR_ELF
;
6025 if (ehdr
->e_type
== VKI_ET_DYN
) {
6026 if (phdr
->p_offset
> 0) {
6027 /* Include the ELF header into the first segment.
6028 This means we ignore p_offset from the program header
6029 and map from file offset 0. */
6030 mrp
->mr_msize
+= phdr
->p_offset
;
6031 mrp
->mr_fsize
+= phdr
->p_offset
;
6035 vg_assert(ehdr
->e_type
== VKI_ET_EXEC
);
6036 start_addr
= phdr
->p_vaddr
;
6040 /* p_vaddr is absolute for ET_EXEC, and relative for ET_DYN. */
6041 mrp
->mr_addr
= (vki_caddr_t
) phdr
->p_vaddr
;
6042 if (ehdr
->e_type
== VKI_ET_DYN
) {
6043 mrp
->mr_addr
+= start_addr
;
6046 SizeT page_offset
= (Addr
) mrp
->mr_addr
& VKI_PAGEOFFSET
;
6047 if (page_offset
> 0) {
6048 vg_assert(file_offset
>= page_offset
);
6049 /* Mapping address does not start at the beginning of a page.
6050 Therefore include some bytes before to make it page aligned. */
6051 mrp
->mr_addr
-= page_offset
;
6052 mrp
->mr_msize
+= page_offset
;
6053 mrp
->mr_offset
= page_offset
;
6054 file_offset
-= page_offset
;
6056 SizeT file_size
= mrp
->mr_fsize
+ mrp
->mr_offset
;
6057 if (VG_(clo_trace_syscalls
))
6058 VG_(debugLog
)(2, "syswrap-solaris", "mmapobj_process_phdrs: "
6059 "mmapobj result #%u: addr=%#lx msize=%#lx "
6060 "fsize=%#lx mr_offset=%#lx prot=%#x flags=%#x\n",
6061 *elements
, (Addr
) mrp
->mr_addr
,
6062 (UWord
) mrp
->mr_msize
, (UWord
) mrp
->mr_fsize
,
6063 (UWord
) mrp
->mr_offset
, mrp
->mr_prot
,
6066 UInt flags
= VKI_MAP_PRIVATE
| VKI_MAP_FIXED
;
6067 if ((mrp
->mr_prot
& (VKI_PROT_WRITE
| VKI_PROT_EXEC
)) ==
6069 flags
|= VKI_MAP_TEXT
;
6071 flags
|= VKI_MAP_INITDATA
;
6074 /* Determine if there will be partially unused page after file-based
6075 mapping. If so, then we need to zero it explicitly afterwards. */
6076 Addr mapping_end
= (Addr
) mrp
->mr_addr
+ file_size
;
6077 SizeT zeroed_size
= VG_PGROUNDUP(mapping_end
) - mapping_end
;
6078 Bool mprotect_needed
= False
;
6079 if ((zeroed_size
> 0) && ((prot
& VKI_PROT_WRITE
) == 0)) {
6080 prot
|= VKI_PROT_WRITE
;
6081 mprotect_needed
= True
;
6084 if (ehdr
->e_type
== VKI_ET_EXEC
) {
6085 /* Now check if the requested address space is available. */
6086 if (!VG_(am_is_free_or_resvn
)((Addr
) mrp
->mr_addr
, mrp
->mr_msize
)) {
6087 if (VG_(clo_trace_syscalls
))
6088 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_process_phdrs: "
6089 "requested segment at %#lx with size of "
6090 "%#lx bytes is not available\n",
6091 (Addr
) mrp
->mr_addr
, (UWord
) mrp
->mr_msize
);
6092 res
= VG_(mk_SysRes_Error
)(VKI_EADDRINUSE
);
6097 if (file_size
> 0) {
6098 res
= VG_(am_mmap_file_fixed_client_flags
)((Addr
) mrp
->mr_addr
,
6099 file_size
, prot
, flags
, fd
, file_offset
);
6100 if (sr_isError(res
)) {
6101 if (VG_(clo_trace_syscalls
))
6102 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_process_phdrs: "
6103 "mmap failed: addr=%#lx size=%#lx prot=%#x "
6104 "flags=%#x fd=%d file offset=%#llx\n",
6105 (Addr
) mrp
->mr_addr
, file_size
,
6106 prot
, flags
, fd
, (unsigned long long)file_offset
);
6110 VG_(debugLog
)(1, "syswrap-solaris", "PRE(sys_mmapobj): new "
6111 "segment: vaddr=%#lx size=%#lx prot=%#x "
6112 "flags=%#x fd=%d file offset=%#llx\n",
6113 (Addr
) mrp
->mr_addr
, file_size
, mrp
->mr_prot
,
6114 flags
, fd
, (unsigned long long)file_offset
);
6117 if (zeroed_size
> 0) {
6118 /* Now zero out the end of partially used page. */
6119 VG_(memset
)((void *) mapping_end
, 0, zeroed_size
);
6120 if (mprotect_needed
) {
6121 prot
&= ~VKI_PROT_WRITE
;
6122 res
= VG_(do_syscall3
)(SYS_mprotect
, (Addr
) mrp
->mr_addr
,
6124 if (sr_isError(res
)) {
6125 if (VG_(clo_trace_syscalls
))
6126 VG_(debugLog
)(3, "syswrap-solaris",
6127 "mmapobj_process_phdrs: mprotect failed: "
6128 "addr=%#lx size=%#lx prot=%#x",
6129 (Addr
) mrp
->mr_addr
, file_size
, prot
);
6130 /* Mapping for this segment was already established. */
6137 if (file_size
> 0) {
6138 ML_(notify_core_and_tool_of_mmap
)((Addr
) mrp
->mr_addr
, file_size
,
6139 prot
, flags
, fd
, file_offset
);
6142 /* Page(s) after the mapping backed up by the file are part of BSS.
6143 They need to be mmap'ed over with correct flags and will be
6144 implicitly zeroed. */
6145 mapping_end
= VG_PGROUNDUP(mrp
->mr_addr
+ mrp
->mr_msize
);
6146 Addr page_end
= VG_PGROUNDUP(mrp
->mr_addr
+ file_size
);
6147 vg_assert(mapping_end
>= page_end
);
6148 zeroed_size
= mapping_end
- page_end
;
6149 if (zeroed_size
> 0) {
6150 flags
= VKI_MAP_FIXED
| VKI_MAP_PRIVATE
| VKI_MAP_ANONYMOUS
;
6151 res
= VG_(am_mmap_anon_fixed_client
)(page_end
, zeroed_size
, prot
);
6152 if (sr_isError(res
)) {
6153 if (VG_(clo_trace_syscalls
))
6154 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_process_phdrs: "
6155 "mmap_anon failed: addr=%#lx size=%#lx "
6156 "prot=%#x\n", page_end
, zeroed_size
, prot
);
6157 idx
+= 1; /* mapping for this segment was already established */
6161 VG_(debugLog
)(1, "syswrap-solaris", "PRE(sys_mmapobj): new "
6162 "anonymous segment (BSS): vaddr=%#lx size=%#lx "
6163 "prot=%#x\n", page_end
, zeroed_size
, prot
);
6164 ML_(notify_core_and_tool_of_mmap
)(page_end
, zeroed_size
,
6165 prot
, flags
, -1, 0);
6168 VG_(di_notify_mmap
)((Addr
) mrp
->mr_addr
, False
/*allow_SkFileV*/, fd
);
6171 vg_assert(*elements
<= segments
);
6175 if ((ehdr
->e_type
== VKI_ET_EXEC
) && (!brk_segment_established
)) {
6176 vg_assert(VG_(brk_base
) == VG_(brk_limit
));
6177 vg_assert(VG_(brk_base
) == -1);
6178 VG_(brk_base
) = VG_(brk_limit
) = elfbrk
;
6180 if (!VG_(setup_client_dataseg
)()) {
6181 VG_(umsg
)("Cannot map memory to initialize brk segment in thread #%u "
6182 "at %#lx\n", tid
, VG_(brk_base
));
6183 res
= VG_(mk_SysRes_Error
)(VKI_ENOMEM
);
6187 VG_(track_client_dataseg
)(tid
);
6190 /* Restore VG_(clo_sanity_level). The scheduler will perform the aspacemgr
6191 sanity check after the syscall. */
6192 VG_(clo_sanity_level
) = sanity_level
;
6194 return VG_(mk_SysRes_Success
)(0);
6197 for (i
= idx
- 1; i
> 0; i
--) {
6198 Bool discard_translations
;
6199 Addr addr
= (Addr
) storage
[i
].mr_addr
;
6201 VG_(am_munmap_client
)(&discard_translations
, addr
, storage
[i
].mr_msize
);
6202 ML_(notify_core_and_tool_of_munmap
)(addr
, storage
[i
].mr_msize
);
6210 static SysRes
mmapobj_interpret(ThreadId tid
, Int fd
,
6211 vki_mmapobj_result_t
*storage
,
6212 vki_uint_t
*elements
)
6216 struct vg_stat stats
;
6217 if (VG_(fstat
)(fd
, &stats
) != 0) {
6218 return VG_(mk_SysRes_Error
)(VKI_EBADF
);
6221 if (stats
.size
< sizeof(VKI_ESZ(Ehdr
))) {
6222 if (VG_(clo_trace_syscalls
))
6223 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_interpret: insufficient "
6224 "file size (%lld)\n", stats
.size
);
6225 return VG_(mk_SysRes_Error
)(VKI_ENOTSUP
);
6228 /* Align the header buffer appropriately. */
6229 vki_ulong_t lheader
[sizeof(VKI_ESZ(Ehdr
)) / sizeof(vki_ulong_t
) + 1];
6230 HChar
*header
= (HChar
*) &lheader
;
6232 res
= VG_(pread
)(fd
, header
, sizeof(VKI_ESZ(Ehdr
)), 0);
6233 if (sr_isError(res
)) {
6234 if (VG_(clo_trace_syscalls
))
6235 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_interpret: read of ELF "
6238 } else if (sr_Res(res
) != sizeof(VKI_ESZ(Ehdr
))) {
6239 if (VG_(clo_trace_syscalls
))
6240 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_interpret: read of ELF "
6241 "header failed - only %lu bytes out of %lu\n",
6242 sr_Res(res
), (UWord
) sizeof(VKI_ESZ(Ehdr
)));
6243 return VG_(mk_SysRes_Error
)(VKI_ENOTSUP
);
6246 /* Verify file type is ELF. */
6247 if ((header
[VKI_EI_MAG0
] != VKI_ELFMAG0
) ||
6248 (header
[VKI_EI_MAG1
] != VKI_ELFMAG1
) ||
6249 (header
[VKI_EI_MAG2
] != VKI_ELFMAG2
) ||
6250 (header
[VKI_EI_MAG3
] != VKI_ELFMAG3
)) {
6251 if (VG_(clo_trace_syscalls
))
6252 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_interpret: ELF header "
6254 return VG_(mk_SysRes_Error
)(VKI_ENOTSUP
);
6257 if (header
[VKI_EI_CLASS
] != VG_ELF_CLASS
) {
6258 if (VG_(clo_trace_syscalls
))
6259 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_interpret: ELF class "
6260 "mismatch (%d vs %d)\n", header
[VKI_EI_CLASS
],
6262 return VG_(mk_SysRes_Error
)(VKI_ENOTSUP
);
6265 VKI_ESZ(Ehdr
) *ehdr
= (VKI_ESZ(Ehdr
) *) header
;
6266 if ((ehdr
->e_type
!= VKI_ET_EXEC
) && (ehdr
->e_type
!= VKI_ET_DYN
)) {
6267 VG_(unimplemented
)("Syswrap of the mmapobj call with ELF type %u.",
6273 if (ehdr
->e_phnum
== VKI_PN_XNUM
) {
6274 VG_(unimplemented
)("Syswrap of the mmapobj call with number of ELF "
6275 "program headers == PN_XNUM");
6280 /* Check alignment. */
6281 #if defined(VGP_x86_solaris)
6282 if (!VG_IS_4_ALIGNED(ehdr
->e_phentsize
)) {
6283 #elif defined(VGP_amd64_solaris)
6284 if (!VG_IS_8_ALIGNED(ehdr
->e_phentsize
)) {
6286 # error "Unknown platform"
6288 if (VG_(clo_trace_syscalls
))
6289 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_interpret: ELF header "
6290 "phentsize not aligned properly (%u)\n",
6292 return VG_(mk_SysRes_Error
)(VKI_ENOTSUP
);
6295 SizeT phdrs_size
= ehdr
->e_phnum
* ehdr
->e_phentsize
;
6296 if (phdrs_size
== 0) {
6297 if (VG_(clo_trace_syscalls
))
6298 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_interpret: no ELF "
6299 "program headers\n");
6300 return VG_(mk_SysRes_Error
)(VKI_ENOTSUP
);
6303 VKI_ESZ(Phdr
) *phdrs
= VG_(malloc
)("syswrap.mi.1", phdrs_size
);
6304 res
= VG_(pread
)(fd
, phdrs
, phdrs_size
, ehdr
->e_phoff
);
6305 if (sr_isError(res
)) {
6306 if (VG_(clo_trace_syscalls
))
6307 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_interpret: read of ELF "
6308 "program headers failed\n");
6310 return VG_(mk_SysRes_Error
)(VKI_ENOTSUP
);
6311 } else if (sr_Res(res
) != phdrs_size
) {
6312 if (VG_(clo_trace_syscalls
))
6313 VG_(debugLog
)(3, "syswrap-solaris", "mmapobj_interpret: read of ELF "
6314 "program headers failed - only %lu bytes out of %lu\n",
6315 sr_Res(res
), phdrs_size
);
6317 return VG_(mk_SysRes_Error
)(VKI_ENOTSUP
);
6320 if (VG_(clo_trace_syscalls
))
6321 VG_(debugLog
)(2, "syswrap-solaris", "mmapobj_interpret: %u ELF "
6322 "program headers with total size of %lu bytes\n",
6323 ehdr
->e_phnum
, phdrs_size
);
6325 /* Now process the program headers. */
6326 res
= mmapobj_process_phdrs(tid
, fd
, storage
, elements
, ehdr
, phdrs
);
6333 /* int mmapobj(int fd, uint_t flags, mmapobj_result_t *storage,
6334 uint_t *elements, void *arg); */
6335 PRINT("sys_mmapobj ( %ld, %#lx, %#lx, %#lx, %#lx )", SARG1
, ARG2
, ARG3
,
6337 PRE_REG_READ5(long, "mmapobj", int, fd
, vki_uint_t
, flags
,
6338 mmapobj_result_t
*, storage
, uint_t
*, elements
,
6341 PRE_MEM_READ("mmapobj(elements)", ARG4
, sizeof(vki_uint_t
));
6342 /*PRE_MEM_WRITE("mmapobj(elements)", ARG4, sizeof(vki_uint_t));*/
6343 if (ML_(safe_to_deref
)((void*)ARG4
, sizeof(vki_uint_t
))) {
6344 vki_uint_t
*u
= (vki_uint_t
*)ARG4
;
6345 PRE_MEM_WRITE("mmapobj(storage)", ARG3
,
6346 *u
* sizeof(vki_mmapobj_result_t
));
6349 if (ARG2
& VKI_MMOBJ_PADDING
)
6350 PRE_MEM_READ("mmapobj(arg)", ARG5
, sizeof(vki_size_t
));
6353 if (!ML_(fd_allowed
)(ARG1
, "mmapobj", tid
, False
)) {
6354 SET_STATUS_Failure(VKI_EBADF
);
6358 /* We cannot advise mmapobj about desired address(es). Unfortunately
6359 kernel places mappings from mmapobj at the end of process address
6360 space, defeating memcheck's optimized fast 2-level array algorithm.
6361 So we need to emulate what mmapobj does in the kernel. */
6363 /* Sanity check on parameters. */
6364 if ((ARG2
& ~VKI_MMOBJ_ALL_FLAGS
) != 0) {
6365 SET_STATUS_Failure(VKI_EINVAL
);
6369 if (!ML_(safe_to_deref
)((void *) ARG4
, sizeof(vki_uint_t
))) {
6370 SET_STATUS_Failure(VKI_EFAULT
);
6373 vki_uint_t
*elements
= (vki_uint_t
*) ARG4
;
6375 if (*elements
> 0) {
6376 if (!ML_(safe_to_deref
)((void *) ARG3
,
6377 *elements
* sizeof(vki_mmapobj_result_t
))) {
6378 SET_STATUS_Failure(VKI_EFAULT
);
6383 /* For now, supported is only MMOBJ_INTERPRET and no MMOBJ_PADDING. */
6384 if (ARG2
!= VKI_MMOBJ_INTERPRET
) {
6385 VG_(unimplemented
)("Syswrap of the mmapobj call with flags %lu.", ARG2
);
6390 SysRes res
= mmapobj_interpret(tid
, (Int
) ARG1
,
6391 (vki_mmapobj_result_t
*) ARG3
, elements
);
6392 SET_STATUS_from_SysRes(res
);
6394 if (!sr_isError(res
)) {
6395 POST_MEM_WRITE(ARG4
, sizeof(vki_uint_t
));
6398 for (idx
= 0; idx
< *(vki_uint_t
*) ARG4
; idx
++) {
6399 vki_mmapobj_result_t
*mrp
= &((vki_mmapobj_result_t
*) ARG3
)[idx
];
6400 POST_FIELD_WRITE(mrp
->mr_addr
);
6401 POST_FIELD_WRITE(mrp
->mr_msize
);
6402 POST_FIELD_WRITE(mrp
->mr_fsize
);
6403 POST_FIELD_WRITE(mrp
->mr_prot
);
6404 POST_FIELD_WRITE(mrp
->mr_flags
);
6405 POST_FIELD_WRITE(mrp
->mr_offset
);
6412 /* int memcntl(caddr_t addr, size_t len, int cmd, caddr_t arg,
6413 int attr, int mask); */
6414 PRINT("sys_memcntl ( %#lx, %#lx, %ld, %#lx, %#lx, %#lx )", ARG1
, ARG2
,
6415 SARG3
, ARG4
, ARG5
, ARG6
);
6416 PRE_REG_READ6(long, "memcntl", void *, addr
, vki_size_t
, len
, int, cmd
,
6417 void *, arg
, int, attr
, int, mask
);
6419 if (ARG3
!= VKI_MC_LOCKAS
&& ARG3
!= VKI_MC_UNLOCKAS
&&
6420 !ML_(valid_client_addr
)(ARG1
, ARG2
, tid
, "memcntl")) {
6421 /* MC_LOCKAS and MC_UNLOCKAS work on the complete address space thus we
6422 don't check the address range validity if these commands are
6424 SET_STATUS_Failure(VKI_ENOMEM
);
6428 if (ARG3
== VKI_MC_HAT_ADVISE
)
6429 PRE_MEM_READ("memcntl(arg)", ARG4
, sizeof(struct vki_memcntl_mha
));
6434 /* int getpmsg(int fildes, struct strbuf *ctlptr, struct strbuf *dataptr,
6435 int *bandp, int *flagsp); */
6436 struct vki_strbuf
*ctrlptr
= (struct vki_strbuf
*)ARG2
;
6437 struct vki_strbuf
*dataptr
= (struct vki_strbuf
*)ARG3
;
6438 *flags
|= SfMayBlock
;
6439 PRINT("sys_getpmsg ( %ld, %#lx, %#lx, %#lx, %#lx )", SARG1
, ARG2
, ARG3
,
6441 PRE_REG_READ5(long, "getpmsg", int, fildes
, struct vki_strbuf
*, ctlptr
,
6442 struct vki_strbuf
*, dataptr
, int *, bandp
, int *, flagsp
);
6444 PRE_FIELD_READ("getpmsg(ctrlptr->maxlen)", ctrlptr
->maxlen
);
6445 PRE_FIELD_WRITE("getpmsg(ctrlptr->len)", ctrlptr
->len
);
6446 PRE_FIELD_READ("getpmsg(ctrlptr->buf)", ctrlptr
->buf
);
6447 if (ML_(safe_to_deref
)((void*)ARG2
, sizeof(struct vki_strbuf
))
6448 && ctrlptr
->maxlen
> 0)
6449 PRE_MEM_WRITE("getpmsg(ctrlptr->buf)", (Addr
)ctrlptr
->buf
,
6453 PRE_FIELD_READ("getpmsg(dataptr->maxlen)", dataptr
->maxlen
);
6454 PRE_FIELD_WRITE("getpmsg(dataptr->len)", dataptr
->len
);
6455 PRE_FIELD_READ("getpmsg(dataptr->buf)", dataptr
->buf
);
6456 if (ML_(safe_to_deref
)((void*)ARG3
, sizeof(struct vki_strbuf
))
6457 && dataptr
->maxlen
> 0)
6458 PRE_MEM_WRITE("getpmsg(dataptr->buf)", (Addr
)dataptr
->buf
,
6461 PRE_MEM_READ("getpmsg(bandp)", ARG4
, sizeof(int));
6462 /*PRE_MEM_WRITE("getpmsg(bandp)", ARG4, sizeof(int));*/
6463 PRE_MEM_READ("getpmsg(flagsp)", ARG5
, sizeof(int));
6464 /*PRE_MEM_WRITE("getpmsg(flagsp)", ARG5, sizeof(int));*/
6467 if (!ML_(fd_allowed
)(ARG1
, "getpmsg", tid
, False
))
6468 SET_STATUS_Failure(VKI_EBADF
);
6473 struct vki_strbuf
*ctrlptr
= (struct vki_strbuf
*)ARG2
;
6474 struct vki_strbuf
*dataptr
= (struct vki_strbuf
*)ARG3
;
6476 if (ctrlptr
&& ctrlptr
->len
> 0)
6477 POST_MEM_WRITE((Addr
)ctrlptr
->buf
, ctrlptr
->len
);
6478 if (dataptr
&& dataptr
->len
> 0)
6479 POST_MEM_WRITE((Addr
)dataptr
->buf
, dataptr
->len
);
6480 POST_MEM_WRITE(ARG4
, sizeof(int));
6481 POST_MEM_WRITE(ARG5
, sizeof(int));
6486 /* int putpmsg(int fildes, const struct strbuf *ctlptr,
6487 const struct strbuf *dataptr, int band, int flags); */
6488 struct vki_strbuf
*ctrlptr
= (struct vki_strbuf
*)ARG2
;
6489 struct vki_strbuf
*dataptr
= (struct vki_strbuf
*)ARG3
;
6490 *flags
|= SfMayBlock
;
6491 PRINT("sys_putpmsg ( %ld, %#lx, %#lx, %ld, %ld )", SARG1
, ARG2
, ARG3
, SARG4
,
6493 PRE_REG_READ5(long, "putpmsg", int, fildes
, struct vki_strbuf
*, ctrlptr
,
6494 struct vki_strbuf
*, dataptr
, int, band
, int, flags
);
6496 PRE_FIELD_READ("putpmsg(ctrlptr->len)", ctrlptr
->len
);
6497 PRE_FIELD_READ("putpmsg(ctrlptr->buf)", ctrlptr
->buf
);
6498 if (ML_(safe_to_deref
)((void*)ARG2
, sizeof(struct vki_strbuf
))
6499 && ctrlptr
->len
> 0)
6500 PRE_MEM_READ("putpmsg(ctrlptr->buf)", (Addr
)ctrlptr
->buf
,
6504 PRE_FIELD_READ("putpmsg(dataptr->len)", dataptr
->len
);
6505 PRE_FIELD_READ("putpmsg(dataptr->buf)", dataptr
->buf
);
6506 if (ML_(safe_to_deref
)((void*)ARG3
, sizeof(struct vki_strbuf
))
6507 && dataptr
->len
> 0)
6508 PRE_MEM_READ("putpmsg(dataptr->buf)", (Addr
)dataptr
->buf
,
6513 if (!ML_(fd_allowed
)(ARG1
, "putpmsg", tid
, False
))
6514 SET_STATUS_Failure(VKI_EBADF
);
6517 #if defined(SOLARIS_OLD_SYSCALLS)
6520 /* int rename(const char *from, const char *to); */
6522 *flags
|= SfMayBlock
;
6523 PRINT("sys_rename ( %#lx(%s), %#lx(%s) )",
6524 ARG1
, (HChar
*) ARG1
, ARG2
, (HChar
*) ARG2
);
6525 PRE_REG_READ2(long, "rename", const char *, from
, const char *, to
);
6527 PRE_MEM_RASCIIZ("rename(from)", ARG1
);
6528 PRE_MEM_RASCIIZ("rename(to)", ARG2
);
6530 #endif /* SOLARIS_OLD_SYSCALLS */
6534 /* int uname(struct utsname *name); */
6535 PRINT("sys_uname ( %#lx )", ARG1
);
6536 PRE_REG_READ1(long, "uname", struct vki_utsname
*, name
);
6537 PRE_MEM_WRITE("uname(name)", ARG1
, sizeof(struct vki_utsname
));
6542 struct vki_utsname
*name
= (struct vki_utsname
*) ARG1
;
6543 POST_MEM_WRITE((Addr
) name
->sysname
, VG_(strlen
)(name
->sysname
) + 1);
6544 POST_MEM_WRITE((Addr
) name
->nodename
, VG_(strlen
)(name
->nodename
) + 1);
6545 POST_MEM_WRITE((Addr
) name
->release
, VG_(strlen
)(name
->release
) + 1);
6546 POST_MEM_WRITE((Addr
) name
->version
, VG_(strlen
)(name
->version
) + 1);
6547 POST_MEM_WRITE((Addr
) name
->machine
, VG_(strlen
)(name
->machine
) + 1);
6552 /* int setegid(gid_t egid); */
6553 PRINT("sys_setegid ( %ld )", SARG1
);
6554 PRE_REG_READ1(long, "setegid", vki_gid_t
, egid
);
6559 /* long sysconf(int name); */
6560 PRINT("sys_sysconfig ( %ld )", SARG1
);
6561 PRE_REG_READ1(long, "sysconf", int, name
);
6563 if (ARG1
== VKI_CONFIG_OPEN_FILES
)
6564 SET_STATUS_Success(VG_(fd_soft_limit
));
6569 /* int sysinfo(int command, char *buf, long count); */
6570 PRINT("sys_systeminfo ( %ld, %#lx, %ld )", SARG1
, ARG2
, SARG3
);
6571 PRE_REG_READ3(long, "sysinfo", int, command
, char *, buf
, long, count
);
6573 switch (ARG1
/*command*/) {
6574 case VKI_SI_SYSNAME
:
6575 case VKI_SI_HOSTNAME
:
6576 case VKI_SI_RELEASE
:
6577 case VKI_SI_VERSION
:
6578 case VKI_SI_MACHINE
:
6579 case VKI_SI_ARCHITECTURE
:
6580 case VKI_SI_HW_SERIAL
:
6581 case VKI_SI_HW_PROVIDER
:
6582 case VKI_SI_SRPC_DOMAIN
:
6583 case VKI_SI_PLATFORM
:
6584 case VKI_SI_ISALIST
:
6585 case VKI_SI_DHCP_CACHE
:
6586 case VKI_SI_ARCHITECTURE_32
:
6587 case VKI_SI_ARCHITECTURE_64
:
6588 case VKI_SI_ARCHITECTURE_K
:
6589 case VKI_SI_ARCHITECTURE_NATIVE
:
6590 PRE_MEM_WRITE("sysinfo(buf)", ARG2
, ARG3
);
6593 case VKI_SI_SET_HOSTNAME
:
6594 case VKI_SI_SET_SRCP_DOMAIN
:
6595 PRE_MEM_RASCIIZ("sysinfo(buf)", ARG2
);
6599 VG_(unimplemented
)("Syswrap of the sysinfo call with command %ld.", SARG1
);
6605 POST(sys_systeminfo
)
6607 if (ARG1
!= VKI_SI_SET_HOSTNAME
&& ARG1
!= VKI_SI_SET_SRCP_DOMAIN
)
6608 POST_MEM_WRITE(ARG2
, MIN(RES
, ARG3
));
6613 /* int seteuid(uid_t euid); */
6614 PRINT("sys_seteuid ( %ld )", SARG1
);
6615 PRE_REG_READ1(long, "seteuid", vki_uid_t
, euid
);
6620 /* int64_t forksys(int subcode, int flags); */
6623 PRINT("sys_forksys ( %ld, %ld )", SARG1
, SARG2
);
6624 PRE_REG_READ2(long, "forksys", int, subcode
, int, flags
);
6627 /* Support for forkall() requires changes to the big lock processing
6628 which are not yet implemented. */
6629 VG_(unimplemented
)("Support for forkall().");
6634 if (ARG1
!= 0 && ARG1
!= 2) {
6635 VG_(unimplemented
)("Syswrap of the forksys call where subcode=%ld.",
6641 /* vfork() is requested. Translate it to a normal fork() but work around
6642 a problem with posix_spawn() which relies on the real vfork()
6643 behaviour. See a description in vg_preloaded.c for details. */
6644 res
= VG_(pipe
)(fds
);
6645 vg_assert(res
== 0);
6647 vg_assert(fds
[0] != fds
[1]);
6649 /* Move to Valgrind fds and set close-on-exec flag on both of them (done
6651 fds
[0] = VG_(safe_fd
)(fds
[0]);
6652 fds
[1] = VG_(safe_fd
)(fds
[1]);
6653 vg_assert(fds
[0] != fds
[1]);
6655 vg_assert(VG_(vfork_fildes_addr
) != NULL
);
6656 vg_assert(*VG_(vfork_fildes_addr
) == -1);
6657 *VG_(vfork_fildes_addr
) = fds
[0];
6660 VG_(do_atfork_pre
)(tid
);
6661 SET_STATUS_from_SysRes(VG_(do_syscall2
)(__NR_forksys
, 0, ARG2
));
6674 VG_(do_atfork_child
)(tid
);
6680 # if defined(SOLARIS_PT_SUNDWTRACE_THRP)
6681 /* Kernel can map a new page as a scratch space of the DTrace fasttrap
6682 provider. There is no way we can directly get its address - it's all
6683 private to the kernel. Fish it the slow way. */
6687 Bool found
= VG_(am_search_for_new_segment
)(&addr
, &size
, &prot
);
6689 VG_(debugLog
)(1, "syswrap-solaris", "PRE(forksys), new segment: "
6690 "vaddr=%#lx, size=%#lx, prot=%#x\n", addr
, size
, prot
);
6691 vg_assert(prot
== (VKI_PROT_READ
| VKI_PROT_EXEC
));
6692 vg_assert(size
== VKI_PAGE_SIZE
);
6693 ML_(notify_core_and_tool_of_mmap
)(addr
, size
, prot
, VKI_MAP_ANONYMOUS
,
6696 /* Note: We don't notify the debuginfo reader about this mapping
6697 because there is no debug information stored in this segment. */
6699 # endif /* SOLARIS_PT_SUNDWTRACE_THRP */
6702 VG_(do_atfork_parent
)(tid
);
6704 /* Print information about the fork. */
6705 PRINT(" fork: process %d created child %d\n", VG_(getpid
)(),
6710 /* Wait for the child to finish (exec or exit). */
6715 res
= VG_(read
)(fds
[1], &w
, 1);
6717 SET_STATUS_Failure(w
);
6720 *VG_(vfork_fildes_addr
) = -1;
6725 #if defined(SOLARIS_GETRANDOM_SYSCALL)
6728 /* int getrandom(void *buf, size_t buflen, uint_t flags); */
6729 PRINT("sys_getrandom ( %#lx, %lu, %lu )", ARG1
, ARG2
, ARG3
);
6730 PRE_REG_READ3(long, "getrandom", void *, buf
, vki_size_t
, buflen
,
6732 PRE_MEM_WRITE("getrandom(buf)", ARG1
, ARG2
);
6737 POST_MEM_WRITE(ARG1
, RES
);
6739 #endif /* SOLARIS_GETRANDOM_SYSCALL */
6741 PRE(sys_sigtimedwait
)
6743 /* int sigtimedwait(const sigset_t *set, siginfo_t *info,
6744 const timespec_t *timeout); */
6745 *flags
|= SfMayBlock
;
6746 PRINT("sys_sigtimedwait ( %#lx, %#lx, %#lx )", ARG1
, ARG2
, ARG3
);
6747 PRE_REG_READ3(long, "sigtimedwait", vki_sigset_t
*, set
,
6748 vki_siginfo_t
*, info
, vki_timespec_t
*, timeout
);
6749 PRE_MEM_READ("sigtimewait(set)", ARG1
, sizeof(vki_sigset_t
));
6751 PRE_MEM_WRITE("sigtimedwait(info)", ARG2
, sizeof(vki_siginfo_t
));
6753 PRE_MEM_READ("sigtimedwait(timeout)", ARG3
, sizeof(vki_timespec_t
));
6756 POST(sys_sigtimedwait
)
6759 POST_MEM_WRITE(ARG2
, sizeof(vki_siginfo_t
));
6764 /* void yield(void); */
6765 *flags
|= SfMayBlock
;
6766 PRINT("sys_yield ( )");
6767 PRE_REG_READ0(long, "yield");
6770 PRE(sys_lwp_sema_post
)
6772 /* int lwp_sema_post(lwp_sema_t *sema); */
6773 vki_lwp_sema_t
*sema
= (vki_lwp_sema_t
*)ARG1
;
6774 *flags
|= SfMayBlock
;
6775 PRINT("sys_lwp_sema_post ( %#lx )", ARG1
);
6776 PRE_REG_READ1(long, "lwp_sema_post", lwp_sema_t
*, sema
);
6778 PRE_FIELD_READ("lwp_sema_post(sema->type)", sema
->vki_sema_type
);
6779 PRE_FIELD_READ("lwp_sema_post(sema->count)", sema
->vki_sema_count
);
6780 /*PRE_FIELD_WRITE("lwp_sema_post(sema->count)", sema->vki_sema_count);*/
6781 PRE_FIELD_READ("lwp_sema_post(sema->waiters)", sema
->vki_sema_waiters
);
6782 /*PRE_FIELD_WRITE("lwp_sema_post(sema->waiters)", sema->vki_sema_waiters);*/
6785 POST(sys_lwp_sema_post
)
6787 vki_lwp_sema_t
*sema
= (vki_lwp_sema_t
*)ARG1
;
6788 POST_FIELD_WRITE(sema
->vki_sema_count
);
6789 POST_FIELD_WRITE(sema
->vki_sema_waiters
);
6792 PRE(sys_lwp_sema_trywait
)
6794 /* int lwp_sema_trywait(lwp_sema_t *sema); */
6795 vki_lwp_sema_t
*sema
= (vki_lwp_sema_t
*)ARG1
;
6796 PRINT("sys_lwp_sema_trywait ( %#lx )", ARG1
);
6797 PRE_REG_READ1(long, "lwp_sema_trywait", lwp_sema_t
*, sema
);
6799 PRE_FIELD_READ("lwp_sema_trywait(sema->type)", sema
->vki_sema_type
);
6800 PRE_FIELD_READ("lwp_sema_trywait(sema->count)", sema
->vki_sema_count
);
6801 /*PRE_FIELD_WRITE("lwp_sema_trywait(sema->count)", sema->vki_sema_count);*/
6802 PRE_FIELD_READ("lwp_sema_trywait(sema->waiters)", sema
->vki_sema_waiters
);
6803 /*PRE_FIELD_WRITE("lwp_sema_trywait(sema->waiters)",
6804 sema->vki_sema_waiters);*/
6807 POST(sys_lwp_sema_trywait
)
6809 vki_lwp_sema_t
*sema
= (vki_lwp_sema_t
*)ARG1
;
6810 POST_FIELD_WRITE(sema
->vki_sema_count
);
6811 POST_FIELD_WRITE(sema
->vki_sema_waiters
);
6816 /* int lwp_detach(id_t lwpid); */
6817 PRINT("sys_lwp_detach ( %ld )", SARG1
);
6818 PRE_REG_READ1(long, "lwp_detach", vki_id_t
, lwpid
);
6823 /* int modctl(int cmd, uintptr_t a1, uintptr_t a2, uintptr_t a3,
6824 uintptr_t a4, uintptr_t a5); */
6825 *flags
|= SfMayBlock
;
6827 switch (ARG1
/*cmd*/) {
6829 /* int modctl_modload(int use_path, char *filename, int *rvp); */
6830 PRINT("sys_modctl ( %ld, %lu, %#lx(%s), %#lx )",
6831 SARG1
, ARG2
, ARG3
, (HChar
*) ARG3
, ARG4
);
6832 PRE_REG_READ4(long, SC2("modctl", "modload"),
6833 int, cmd
, int, use_path
, char *, filename
, int *, rvp
);
6834 PRE_MEM_RASCIIZ("modctl(filaneme)", ARG3
);
6836 PRE_MEM_WRITE("modctl(rvp)", ARG4
, sizeof(int *));
6840 /* int modctl_modunload(modid_t id); */
6841 PRINT("sys_modctl ( %ld, %ld )", SARG1
, SARG2
);
6842 PRE_REG_READ2(long, SC2("modctl", "modunload"),
6843 int, cmd
, vki_modid_t
, id
);
6846 /* int modctl_modinfo(modid_t id, struct modinfo *umodi); */
6847 PRINT("sys_modctl ( %ld, %ld, %#lx )", SARG1
, SARG2
, ARG3
);
6848 PRE_REG_READ3(long, SC2("modctl", "modinfo"),
6849 int, cmd
, vki_modid_t
, id
, struct modinfo
*, umodi
);
6851 struct vki_modinfo
*umodi
= (struct vki_modinfo
*) ARG3
;
6852 PRE_FIELD_READ("modctl(umodi->mi_info)", umodi
->mi_info
);
6853 PRE_FIELD_READ("modctl(umodi->mi_id)", umodi
->mi_id
);
6854 PRE_FIELD_READ("modctl(umodi->mi_nextid)", umodi
->mi_nextid
);
6855 PRE_MEM_WRITE("modctl(umodi)", ARG3
, sizeof(struct vki_modinfo
));
6859 # if defined(SOLARIS_MODCTL_MODNVL)
6860 case VKI_MODNVL_DEVLINKSYNC
:
6861 /* int modnvl_devlinksync(sysnvl_op_t a1, uintptr_t a2, uintptr_t a3,
6863 switch (ARG2
/*op*/) {
6865 # if defined(HAVE_SYS_SYSNVL_H)
6866 case VKI_SYSNVL_OP_GET
:
6867 PRE_REG_READ5(long, SC3("modctl", "modnvl_devlinksync", "get"),
6868 int, cmd
, sysnvl_op_t
, a1
, char *, bufp
,
6869 uint64_t *, buflenp
, uint64_t *, genp
);
6871 case VKI_MODCTL_NVL_OP_GET
:
6872 PRE_REG_READ5(long, SC3("modctl", "modnvl_devlinksync", "get"),
6873 int, cmd
, modctl_nvl_op_t
, a1
, char *, bufp
,
6874 uint64_t *, buflenp
, uint64_t *, genp
);
6875 # endif /* HAVE_SYS_SYSNVL_H */
6877 PRINT("sys_modctl ( %ld, %lu, %#lx, %#lx, %#lx )",
6878 SARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
6879 PRE_MEM_WRITE("modctl(buflenp)", ARG4
, sizeof(vki_uint64_t
));
6880 if (ML_(safe_to_deref
)((vki_uint64_t
*) ARG4
, sizeof(vki_uint64_t
))) {
6882 PRE_MEM_WRITE("modctl(bufp)", ARG3
, *(vki_uint64_t
*) ARG4
);
6886 PRE_MEM_WRITE("modctl(genp)", ARG5
, sizeof(vki_uint64_t
));
6890 # if defined(HAVE_SYS_SYSNVL_H)
6891 case VKI_SYSNVL_OP_UPDATE
:
6892 PRE_REG_READ4(long, SC3("modctl", "modnvl_devlinksync", "update"),
6893 int, cmd
, sysnvl_op_t
, a1
, char *, bufp
,
6894 uint64_t *, buflenp
);
6896 case VKI_MODCTL_NVL_OP_UPDATE
:
6897 PRE_REG_READ4(long, SC3("modctl", "modnvl_devlinksync", "update"),
6898 int, cmd
, modctl_nvl_op_t
, a1
, char *, bufp
,
6899 uint64_t *, buflenp
);
6900 # endif /* HAVE_SYS_SYSNVL_H */
6902 PRINT("sys_modctl ( %ld, %lu, %#lx, %#lx )", SARG1
, ARG2
, ARG3
, ARG4
);
6903 PRE_MEM_READ("modctl(buflenp)", ARG4
, sizeof(vki_uint64_t
));
6904 if (ML_(safe_to_deref
)((vki_uint64_t
*) ARG4
, sizeof(vki_uint64_t
))) {
6905 PRE_MEM_READ("modctl(bufp)", ARG3
, *(vki_uint64_t
*) ARG4
);
6910 VG_(unimplemented
)("Syswrap of the modctl call with command "
6911 "MODNVL_DEVLINKSYNC and op %ld.", ARG2
);
6917 case VKI_MODDEVINFO_CACHE_TS
:
6918 /* int modctl_devinfo_cache_ts(uint64_t *utsp); */
6919 PRINT("sys_modctl ( %ld, %#lx )", SARG1
, ARG2
);
6920 PRE_REG_READ2(long, SC2("modctl", "moddevinfo_cache_ts"),
6921 int, cmd
, uint64_t *, utsp
);
6922 PRE_MEM_WRITE("modctl(utsp)", ARG2
, sizeof(vki_uint64_t
));
6924 # endif /* SOLARIS_MODCTL_MODNVL */
6927 VG_(unimplemented
)("Syswrap of the modctl call with command %ld.", SARG1
);
6935 switch (ARG1
/*cmd*/) {
6938 POST_MEM_WRITE(ARG4
, sizeof(int *));
6944 POST_MEM_WRITE(ARG3
, sizeof(struct vki_modinfo
));
6946 # if defined(SOLARIS_MODCTL_MODNVL)
6947 case VKI_MODNVL_DEVLINKSYNC
:
6948 switch (ARG2
/*op*/) {
6950 # if defined(HAVE_SYS_SYSNVL_H)
6951 case VKI_SYSNVL_OP_GET
:
6953 case VKI_MODCTL_NVL_OP_GET
:
6954 # endif /* HAVE_SYS_SYSNVL_H */
6956 POST_MEM_WRITE(ARG4
, sizeof(vki_uint64_t
));
6958 POST_MEM_WRITE(ARG3
, *(vki_uint64_t
*) ARG4
);
6961 POST_MEM_WRITE(ARG5
, sizeof(vki_uint64_t
));
6965 # if defined(HAVE_SYS_SYSNVL_H)
6966 case VKI_SYSNVL_OP_UPDATE
:
6968 case VKI_MODCTL_NVL_OP_UPDATE
:
6969 # endif /* HAVE_SYS_SYSNVL_H */
6977 case VKI_MODDEVINFO_CACHE_TS
:
6978 POST_MEM_WRITE(ARG2
, sizeof(vki_uint64_t
));
6980 # endif /* SOLARIS_MODCTL_MODNVL */
6990 /* int fchroot(int fd); */
6991 PRINT("sys_fchroot ( %ld )", SARG1
);
6992 PRE_REG_READ1(long, "fchroot", int, fd
);
6995 if (!ML_(fd_allowed
)(ARG1
, "fchroot", tid
, False
))
6996 SET_STATUS_Failure(VKI_EBADF
);
6999 #if defined(SOLARIS_SYSTEM_STATS_SYSCALL)
7000 PRE(sys_system_stats
)
7002 /* void system_stats(int flag); */
7003 PRINT("sys_system_stats ( %ld )", SARG1
);
7004 PRE_REG_READ1(void, "system_stats", int, flag
);
7006 #endif /* SOLARIS_SYSTEM_STATS_SYSCALL */
7008 PRE(sys_gettimeofday
)
7010 /* Kernel: int gettimeofday(struct timeval *tp); */
7011 PRINT("sys_gettimeofday ( %#lx )", ARG1
);
7012 PRE_REG_READ1(long, "gettimeofday", struct timeval
*, tp
);
7014 PRE_timeval_WRITE("gettimeofday(tp)", ARG1
);
7017 POST(sys_gettimeofday
)
7020 POST_timeval_WRITE(ARG1
);
7025 /* int lwp_create(ucontext_t *ucp, int flags, id_t *new_lwp) */
7033 Bool tool_informed
= False
;
7035 PRINT("sys_lwp_create ( %#lx, %lu, %#lx )", ARG1
, ARG2
, ARG3
);
7036 PRE_REG_READ3(long, "lwp_create", ucontext_t
*, ucp
, int, flags
,
7040 PRE_MEM_WRITE("lwp_create(new_lwp)", ARG3
, sizeof(vki_id_t
));
7042 /* If we can't deref ucontext_t then we can't do anything. */
7043 if (!ML_(safe_to_deref
)((void*)ARG1
, sizeof(vki_ucontext_t
))) {
7044 SET_STATUS_Failure(VKI_EINVAL
);
7048 ctid
= VG_(alloc_ThreadState
)();
7049 ptst
= VG_(get_ThreadState
)(tid
);
7050 ctst
= VG_(get_ThreadState
)(ctid
);
7053 vg_assert(VG_(is_running_thread
)(tid
));
7054 vg_assert(VG_(is_valid_tid
)(ctid
));
7056 stack
= ML_(allocstack
)(ctid
);
7058 res
= VG_(mk_SysRes_Error
)(VKI_ENOMEM
);
7062 /* First inherit parent's guest state */
7063 ctst
->arch
.vex
= ptst
->arch
.vex
;
7064 ctst
->arch
.vex_shadow1
= ptst
->arch
.vex_shadow1
;
7065 ctst
->arch
.vex_shadow2
= ptst
->arch
.vex_shadow2
;
7067 /* Set up some values. */
7068 ctst
->os_state
.parent
= tid
;
7069 ctst
->os_state
.threadgroup
= ptst
->os_state
.threadgroup
;
7070 ctst
->sig_mask
= ptst
->sig_mask
;
7071 ctst
->tmp_sig_mask
= ptst
->sig_mask
;
7073 /* No stack definition should be currently present. The stack will be set
7074 later by libc by a setustack() call (the getsetcontext syscall). */
7075 ctst
->client_stack_highest_byte
= 0;
7076 ctst
->client_stack_szB
= 0;
7077 vg_assert(ctst
->os_state
.stk_id
== NULL_STK_ID
);
7079 /* Inform a tool that a new thread is created. This has to be done before
7080 any other core->tool event is sent. */
7081 vg_assert(VG_(owns_BigLock_LL
)(tid
));
7082 VG_TRACK(pre_thread_ll_create
, tid
, ctid
);
7083 tool_informed
= True
;
7085 #if defined(VGP_x86_solaris)
7086 /* Set up GDT (this has to be done before calling
7087 VG_(restore_context)(). */
7088 ML_(setup_gdt
)(&ctst
->arch
.vex
);
7089 #elif defined(VGP_amd64_solaris)
7090 /* Nothing to do. */
7092 # error "Unknown platform"
7095 /* Now set up the new thread according to ucontext_t. */
7096 VG_(restore_context
)(ctid
, (vki_ucontext_t
*)ARG1
, Vg_CoreSysCall
,
7097 True
/*esp_is_thrptr*/);
7099 /* Set up V thread (this also tells the kernel to block all signals in the
7101 ML_(setup_start_thread_context
)(ctid
, &uc
);
7103 /* Actually create the new thread. */
7104 res
= VG_(do_syscall3
)(__NR_lwp_create
, (UWord
)&uc
, ARG2
, ARG3
);
7106 if (!sr_isError(res
)) {
7108 POST_MEM_WRITE(ARG3
, sizeof(vki_id_t
));
7109 if (ARG2
& VKI_LWP_DAEMON
)
7110 ctst
->os_state
.daemon_thread
= True
;
7114 if (sr_isError(res
)) {
7115 if (tool_informed
) {
7116 /* Tell a tool the thread exited in a hurry. */
7117 VG_TRACK(pre_thread_ll_exit
, ctid
);
7120 /* lwp_create failed. */
7121 VG_(cleanup_thread
)(&ctst
->arch
);
7122 ctst
->status
= VgTs_Empty
;
7125 SET_STATUS_from_SysRes(res
);
7130 /* void syslwp_exit(); */
7131 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
7132 PRINT("sys_lwp_exit ( )");
7133 PRE_REG_READ0(long, "lwp_exit");
7135 /* Set the thread's status to be exiting, then claim that the syscall
7137 tst
->exitreason
= VgSrc_ExitThread
;
7138 tst
->os_state
.exitcode
= 0;
7139 SET_STATUS_Success(0);
7142 PRE(sys_lwp_suspend
)
7144 /* int lwp_suspend(id_t lwpid); */
7145 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
7146 PRINT("sys_lwp_suspend ( %ld )", SARG1
);
7147 PRE_REG_READ1(long, "lwp_suspend", vki_id_t
, lwpid
);
7149 if (ARG1
== tst
->os_state
.lwpid
) {
7150 /* Set the SfMayBlock flag only if the currently running thread should
7151 be suspended. If this flag was used also when suspending other
7152 threads then it could happen that a thread holding the_BigLock would
7153 be suspended and Valgrind would hang. */
7154 *flags
|= SfMayBlock
;
7158 PRE(sys_lwp_continue
)
7160 /* int lwp_continue(id_t target_lwp); */
7161 PRINT("sys_lwp_continue ( %ld )", SARG1
);
7162 PRE_REG_READ1(long, "lwp_continue", vki_id_t
, target_lwp
);
7166 do_lwp_sigqueue(const HChar
*syscall_name
, UWord target_lwp
, UWord signo
,
7167 SyscallStatus
*status
, UWord
*flags
)
7169 if (!ML_(client_signal_OK
)(signo
)) {
7170 SET_STATUS_Failure(VKI_EINVAL
);
7174 /* Check to see if this gave us a pending signal. */
7175 *flags
|= SfPollAfter
;
7177 if (VG_(clo_trace_signals
))
7178 VG_(message
)(Vg_DebugMsg
, "%s: sending signal %lu to thread %lu\n",
7179 syscall_name
, signo
, target_lwp
);
7181 /* If we're sending SIGKILL, check to see if the target is one of our
7182 threads and handle it specially. */
7183 if (signo
== VKI_SIGKILL
&& ML_(do_sigkill
)(target_lwp
, -1)) {
7184 SET_STATUS_Success(0);
7188 /* Ask to handle this syscall via the slow route, since that's the only one
7189 that sets tst->status to VgTs_WaitSys. If the result of doing the
7190 syscall is an immediate run of async_signalhandler() in m_signals.c,
7191 then we need the thread to be properly tidied away. */
7192 *flags
|= SfMayBlock
;
7195 #if defined(SOLARIS_LWP_SIGQUEUE_SYSCALL)
7196 #if defined(SOLARIS_LWP_SIGQUEUE_SYSCALL_TAKES_PID)
7197 PRE(sys_lwp_sigqueue
)
7199 /* int lwp_sigqueue(pid_t target_pid, id_t target_lwp, int signal,
7200 void *value, int si_code, timespec_t *timeout);
7202 PRINT("sys_lwp_sigqueue ( %ld, %ld, %ld, %#lx, %ld, %#lx )",
7203 SARG1
, SARG2
, SARG3
, ARG4
, SARG5
, ARG6
);
7204 PRE_REG_READ6(long, "lwp_sigqueue", vki_pid_t
, target_pid
,
7205 vki_id_t
, target_lwp
, int, signal
, void *, value
, int, si_code
,
7206 vki_timespec_t
*, timeout
);
7209 PRE_MEM_READ("lwp_sigqueue(timeout)", ARG6
, sizeof(vki_timespec_t
));
7211 if ((ARG1
== 0) || (ARG1
== VG_(getpid
)())) {
7212 do_lwp_sigqueue("lwp_sigqueue", ARG2
, ARG3
, status
, flags
);
7214 /* Signal is sent to a different process. */
7215 if (VG_(clo_trace_signals
))
7216 VG_(message
)(Vg_DebugMsg
, "lwp_sigqueue: sending signal %ld to "
7217 "process %ld, thread %ld\n", SARG3
, SARG1
, SARG2
);
7218 *flags
|= SfMayBlock
;
7222 POST(sys_lwp_sigqueue
)
7224 if (VG_(clo_trace_signals
))
7225 VG_(message
)(Vg_DebugMsg
, "lwp_sigqueue: sent signal %ld to process %ld, "
7226 "thread %ld\n", SARG3
, SARG1
, SARG2
);
7231 PRE(sys_lwp_sigqueue
)
7233 /* int lwp_sigqueue(id_t target_lwp, int signal, void *value,
7234 int si_code, timespec_t *timeout);
7236 PRINT("sys_lwp_sigqueue ( %ld, %ld, %#lx, %ld, %#lx )",
7237 SARG1
, SARG2
, ARG3
, SARG4
, ARG5
);
7238 PRE_REG_READ5(long, "lwp_sigqueue", vki_id_t
, target_lwp
, int, signal
,
7239 void *, value
, int, si_code
, vki_timespec_t
*, timeout
);
7242 PRE_MEM_READ("lwp_sigqueue(timeout)", ARG5
, sizeof(vki_timespec_t
));
7244 do_lwp_sigqueue("lwp_sigqueue", ARG1
, ARG2
, status
, flags
);
7247 POST(sys_lwp_sigqueue
)
7249 if (VG_(clo_trace_signals
))
7250 VG_(message
)(Vg_DebugMsg
, "lwp_sigqueue: sent signal %lu to thread %lu\n",
7255 #endif /* SOLARIS_LWP_SIGQUEUE_SYSCALL_TAKES_PID */
7261 /* int lwp_kill(id_t target_lwp, int signal); */
7262 PRINT("sys_lwp_kill ( %ld, %ld )", SARG1
, SARG2
);
7263 PRE_REG_READ2(long, "lwp_kill", vki_id_t
, target_lwp
, int, signal
);
7265 do_lwp_sigqueue("lwp_kill", ARG1
, ARG2
, status
, flags
);
7270 if (VG_(clo_trace_signals
))
7271 VG_(message
)(Vg_DebugMsg
, "lwp_kill: sent signal %lu to thread %lu\n",
7274 #endif /* SOLARIS_LWP_SIGQUEUE_SYSCALL */
7278 /* id_t lwp_self(void); */
7279 PRINT("sys_lwp_self ( )");
7280 PRE_REG_READ0(long, "lwp_self");
7283 PRE(sys_lwp_sigmask
)
7285 /* int64_t lwp_sigmask(int how, uint_t bits0, uint_t bits1, uint_t bits2,
7287 vki_sigset_t sigset
;
7288 PRINT("sys_lwp_sigmask ( %ld, %#lx, %#lx, %#lx, %#lx )", SARG1
, ARG2
, ARG3
,
7290 PRE_REG_READ5(long, "lwp_sigmask", int, how
, vki_uint_t
, bits0
,
7291 vki_uint_t
, bits1
, vki_uint_t
, bits2
, vki_uint_t
, bits3
);
7293 sigset
.__sigbits
[0] = ARG2
;
7294 sigset
.__sigbits
[1] = ARG3
;
7295 sigset
.__sigbits
[2] = ARG4
;
7296 sigset
.__sigbits
[3] = ARG5
;
7298 SET_STATUS_from_SysRes(
7299 VG_(do_sys_sigprocmask
)(tid
, ARG1
/*how*/, &sigset
, NULL
)
7303 *flags
|= SfPollAfter
;
7306 PRE(sys_lwp_private
)
7308 /* int lwp_private(int cmd, int which, uintptr_t base); */
7309 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
7310 Int supported_base
, supported_sel
;
7311 PRINT("sys_lwp_private ( %ld, %ld, %#lx )", SARG1
, SARG2
, ARG3
);
7312 PRE_REG_READ3(long, "lwp_private", int, cmd
, int, which
,
7315 /* Note: Only the %gs base is currently supported on x86 and the %fs base
7316 on amd64. Support for the %fs base on x86 and for the %gs base on amd64
7317 should be added. Anything else is probably a client program error. */
7318 #if defined(VGP_x86_solaris)
7319 supported_base
= VKI_LWP_GSBASE
;
7320 supported_sel
= VKI_LWPGS_SEL
;
7321 #elif defined(VGP_amd64_solaris)
7322 supported_base
= VKI_LWP_FSBASE
;
7325 #error "Unknown platform"
7327 if (ARG2
!= supported_base
) {
7328 VG_(unimplemented
)("Syswrap of the lwp_private call where which=%ld.",
7333 switch (ARG1
/*cmd*/) {
7334 case VKI_LWP_SETPRIVATE
:
7335 #if defined(VGP_x86_solaris)
7336 tst
->os_state
.thrptr
= ARG3
;
7337 ML_(update_gdt_lwpgs
)(tid
);
7338 #elif defined(VGP_amd64_solaris)
7339 tst
->arch
.vex
.guest_FS_CONST
= ARG3
;
7341 #error "Unknown platform"
7343 SET_STATUS_Success(supported_sel
);
7345 case VKI_LWP_GETPRIVATE
:
7348 #if defined(VGP_x86_solaris)
7349 thrptr
= tst
->os_state
.thrptr
;
7350 #elif defined(VGP_amd64_solaris)
7351 thrptr
= tst
->arch
.vex
.guest_FS_CONST
;
7353 #error "Unknown platform"
7357 SET_STATUS_Failure(VKI_EINVAL
);
7361 #if defined(VGP_x86_solaris)
7362 if (tst
->arch
.vex
.guest_GS
!= supported_sel
) {
7363 SET_STATUS_Failure(VKI_EINVAL
);
7366 #elif defined(VGP_amd64_solaris)
7367 /* Valgrind on amd64 does not allow to change the gs register so
7368 a check that guest_GS is equal to supported_sel is not needed
7371 #error "Unknown platform"
7374 PRE_MEM_WRITE("lwp_private(base)", ARG3
, sizeof(Addr
));
7375 if (!ML_(safe_to_deref((void*)ARG3
, sizeof(Addr
)))) {
7376 SET_STATUS_Failure(VKI_EFAULT
);
7379 *(Addr
*)ARG3
= thrptr
;
7380 POST_MEM_WRITE((Addr
)ARG3
, sizeof(Addr
));
7381 SET_STATUS_Success(0);
7385 VG_(unimplemented
)("Syswrap of the lwp_private call where cmd=%ld.",
7394 /* int lwp_wait(id_t lwpid, id_t *departed); */
7395 *flags
|= SfMayBlock
;
7396 PRINT("sys_lwp_wait ( %ld, %#lx )", SARG1
, ARG2
);
7397 PRE_REG_READ2(long, "lwp_wait", vki_id_t
, lwpid
, vki_id_t
*, departed
);
7399 PRE_MEM_WRITE("lwp_wait(departed)", ARG2
, sizeof(vki_id_t
));
7404 POST_MEM_WRITE(ARG2
, sizeof(vki_id_t
));
7407 PRE(sys_lwp_mutex_wakeup
)
7409 /* int lwp_mutex_wakeup(lwp_mutex_t *lp, int release_all); */
7410 *flags
|= SfMayBlock
;
7411 PRINT("sys_lwp_mutex_wakeup ( %#lx, %ld )", ARG1
, SARG2
);
7412 PRE_REG_READ2(long, "lwp_mutex_wakeup", vki_lwp_mutex_t
*, lp
,
7414 vki_lwp_mutex_t
*lp
= (vki_lwp_mutex_t
*) ARG1
;
7415 PRE_FIELD_READ("lwp_mutex_wakeup(lp->mutex_type)", lp
->vki_mutex_type
);
7416 PRE_FIELD_WRITE("lwp_mutex_wakeup(lp->mutex_waiters)",
7417 lp
->vki_mutex_waiters
);
7420 POST(sys_lwp_mutex_wakeup
)
7422 vki_lwp_mutex_t
*lp
= (vki_lwp_mutex_t
*) ARG1
;
7423 POST_FIELD_WRITE(lp
->vki_mutex_waiters
);
7426 PRE(sys_lwp_cond_wait
)
7428 /* int lwp_cond_wait(lwp_cond_t *cvp, lwp_mutex_t *mp, timespec_t *tsp,
7430 *flags
|= SfMayBlock
;
7431 PRINT("sys_lwp_cond_wait( %#lx, %#lx, %#lx, %ld )", ARG1
, ARG2
, ARG3
, SARG4
);
7432 PRE_REG_READ4(long, "lwp_cond_wait", vki_lwp_cond_t
*, cvp
,
7433 vki_lwp_mutex_t
*, mp
, vki_timespec_t
*, tsp
, int, check_part
);
7435 vki_lwp_cond_t
*cvp
= (vki_lwp_cond_t
*) ARG1
;
7436 vki_lwp_mutex_t
*mp
= (vki_lwp_mutex_t
*) ARG2
;
7437 PRE_FIELD_READ("lwp_cond_wait(cvp->type)", cvp
->vki_cond_type
);
7438 PRE_FIELD_READ("lwp_cond_wait(cvp->waiters_kernel)",
7439 cvp
->vki_cond_waiters_kernel
);
7440 PRE_FIELD_READ("lwp_cond_wait(mp->mutex_type)", mp
->vki_mutex_type
);
7441 PRE_FIELD_WRITE("lwp_cond_wait(mp->mutex_waiters)", mp
->vki_mutex_waiters
);
7443 PRE_MEM_READ("lwp_cond_wait(tsp)", ARG3
, sizeof(vki_timespec_t
));
7446 POST(sys_lwp_cond_wait
)
7448 vki_lwp_cond_t
*cvp
= (vki_lwp_cond_t
*) ARG1
;
7449 vki_lwp_mutex_t
*mp
= (vki_lwp_mutex_t
*) ARG2
;
7450 POST_FIELD_WRITE(cvp
->vki_cond_waiters_kernel
);
7451 POST_FIELD_WRITE(mp
->vki_mutex_waiters
);
7453 POST_MEM_WRITE(ARG3
, sizeof(vki_timespec_t
));
7456 PRE(sys_lwp_cond_signal
)
7458 /* int lwp_cond_signal(lwp_cond_t *cvp); */
7459 *flags
|= SfMayBlock
;
7460 PRINT("sys_lwp_cond_signal( %#lx )", ARG1
);
7461 PRE_REG_READ1(long, "lwp_cond_signal", vki_lwp_cond_t
*, cvp
);
7463 vki_lwp_cond_t
*cvp
= (vki_lwp_cond_t
*) ARG1
;
7464 PRE_FIELD_READ("lwp_cond_signal(cvp->type)", cvp
->vki_cond_type
);
7465 PRE_FIELD_READ("lwp_cond_signal(cvp->waiters_kernel)",
7466 cvp
->vki_cond_waiters_kernel
);
7469 POST(sys_lwp_cond_signal
)
7471 vki_lwp_cond_t
*cvp
= (vki_lwp_cond_t
*) ARG1
;
7472 POST_FIELD_WRITE(cvp
->vki_cond_waiters_kernel
);
7475 PRE(sys_lwp_cond_broadcast
)
7477 /* int lwp_cond_broadcast(lwp_cond_t *cvp); */
7478 *flags
|= SfMayBlock
;
7479 PRINT("sys_lwp_cond_broadcast ( %#lx )", ARG1
);
7480 PRE_REG_READ1(long, "lwp_cond_broadcast", vki_lwp_cond_t
*, cvp
);
7482 vki_lwp_cond_t
*cvp
= (vki_lwp_cond_t
*) ARG1
;
7483 PRE_FIELD_READ("lwp_cond_broadcast(cvp->type)", cvp
->vki_cond_type
);
7484 PRE_FIELD_READ("lwp_cond_broadcast(cvp->waiters_kernel)",
7485 cvp
->vki_cond_waiters_kernel
);
7486 /*PRE_FIELD_WRITE("lwp_cond_broadcast(cvp->waiters_kernel)",
7487 cvp->vki_cond_waiters_kernel);*/
7490 POST(sys_lwp_cond_broadcast
)
7492 vki_lwp_cond_t
*cvp
= (vki_lwp_cond_t
*) ARG1
;
7493 POST_FIELD_WRITE(cvp
->vki_cond_waiters_kernel
);
7498 /* ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset); */
7499 *flags
|= SfMayBlock
;
7500 PRINT("sys_pread ( %ld, %#lx, %lu, %ld )", SARG1
, ARG2
, ARG3
, SARG4
);
7501 PRE_REG_READ4(long, "pread", int, fildes
, void *, buf
,
7502 vki_size_t
, nbyte
, vki_off_t
, offset
);
7503 PRE_MEM_WRITE("pread(buf)", ARG2
, ARG3
);
7506 if (!ML_(fd_allowed
)(ARG1
, "pread", tid
, False
))
7507 SET_STATUS_Failure(VKI_EBADF
);
7512 POST_MEM_WRITE(ARG2
, RES
);
7517 /* ssize_t pwrite(int fildes, const void *buf, size_t nbyte,
7519 *flags
|= SfMayBlock
;
7520 PRINT("sys_pwrite ( %ld, %#lx, %lu, %ld )", SARG1
, ARG2
, ARG3
, SARG4
);
7521 PRE_REG_READ4(long, "pwrite", int, fildes
, const void *, buf
,
7522 vki_size_t
, nbyte
, vki_off_t
, offset
);
7523 PRE_MEM_READ("pwrite(buf)", ARG2
, ARG3
);
7526 if (!ML_(fd_allowed
)(ARG1
, "pwrite", tid
, False
))
7527 SET_STATUS_Failure(VKI_EBADF
);
7530 PRE(sys_getpagesizes
)
7532 /* int getpagesizes(int legacy, size_t *buf, int nelem); */
7533 PRINT("sys_getpagesizes ( %ld, %#lx, %ld )", SARG1
, ARG2
, SARG3
);
7534 PRE_REG_READ3(long, "getpagesizes", int, legacy
, size_t *, buf
,
7537 PRE_MEM_WRITE("getpagesizes(buf)", ARG2
, ARG3
* sizeof(vki_size_t
));
7540 POST(sys_getpagesizes
)
7543 POST_MEM_WRITE(ARG2
, RES
* sizeof(vki_size_t
));
7548 /* Kernel: int lgrpsys(int subcode, long ia, void *ap); */
7549 switch (ARG1
/*subcode*/) {
7550 case VKI_LGRP_SYS_MEMINFO
:
7551 PRINT("sys_lgrpsys ( %ld, %ld, %#lx )", SARG1
, SARG2
, ARG3
);
7552 PRE_REG_READ3(long, SC2("lgrpsys", "meminfo"), int, subcode
,
7553 int, addr_count
, vki_meminfo_t
*, minfo
);
7554 PRE_MEM_READ("lgrpsys(minfo)", ARG3
, sizeof(vki_meminfo_t
));
7556 if (ML_(safe_to_deref
)((vki_meminfo_t
*) ARG3
, sizeof(vki_meminfo_t
))) {
7557 vki_meminfo_t
*minfo
= (vki_meminfo_t
*) ARG3
;
7558 PRE_MEM_READ("lgrpsys(minfo->mi_inaddr)",
7559 (Addr
) minfo
->mi_inaddr
, SARG2
* sizeof(vki_uint64_t
));
7560 PRE_MEM_READ("lgrpsys(minfo->mi_info_req)", (Addr
) minfo
->mi_info_req
,
7561 minfo
->mi_info_count
* sizeof(vki_uint_t
));
7562 PRE_MEM_WRITE("lgrpsys(minfo->mi_outdata)", (Addr
) minfo
->mi_outdata
,
7563 SARG2
* minfo
->mi_info_count
* sizeof(vki_uint64_t
));
7564 PRE_MEM_WRITE("lgrpsys(minfo->mi_validity)",
7565 (Addr
) minfo
->mi_validity
, SARG2
* sizeof(vki_uint_t
));
7568 case VKI_LGRP_SYS_GENERATION
:
7569 /* Liblgrp: lgrp_gen_t lgrp_generation(lgrp_view_t view); */
7570 PRINT("sys_lgrpsys ( %ld, %ld )", SARG1
, SARG2
);
7571 PRE_REG_READ2(long, SC2("lgrpsys", "generation"), int, subcode
,
7572 vki_lgrp_view_t
, view
);
7574 case VKI_LGRP_SYS_VERSION
:
7575 /* Liblgrp: int lgrp_version(int version); */
7576 PRINT("sys_lgrpsys ( %ld, %ld )", SARG1
, SARG2
);
7577 PRE_REG_READ2(long, SC2("lgrpsys", "version"), int, subcode
,
7580 case VKI_LGRP_SYS_SNAPSHOT
:
7581 /* Liblgrp: int lgrp_snapshot(void *buf, size_t bufsize); */
7582 PRINT("sys_lgrpsys ( %ld, %lu, %#lx )", SARG1
, ARG2
, ARG3
);
7583 PRE_REG_READ3(long, SC2("lgrpsys", "snapshot"), int, subcode
,
7584 vki_size_t
, bufsize
, void *, buf
);
7585 PRE_MEM_WRITE("lgrpsys(buf)", ARG3
, ARG2
);
7588 VG_(unimplemented
)("Syswrap of the lgrpsys call with subcode %ld.",
7597 switch (ARG1
/*subcode*/) {
7598 case VKI_LGRP_SYS_MEMINFO
:
7600 vki_meminfo_t
*minfo
= (vki_meminfo_t
*) ARG3
;
7601 POST_MEM_WRITE((Addr
) minfo
->mi_outdata
,
7602 SARG2
* minfo
->mi_info_count
* sizeof(vki_uint64_t
));
7603 POST_MEM_WRITE((Addr
) minfo
->mi_validity
, SARG2
* sizeof(vki_uint_t
));
7606 case VKI_LGRP_SYS_GENERATION
:
7607 case VKI_LGRP_SYS_VERSION
:
7609 case VKI_LGRP_SYS_SNAPSHOT
:
7610 POST_MEM_WRITE(ARG3
, RES
);
7620 /* Kernel: int rusagesys(int code, void *arg1, void *arg2,
7621 void *arg3, void *arg4); */
7622 switch (ARG1
/*code*/) {
7623 case VKI__RUSAGESYS_GETRUSAGE
:
7624 case VKI__RUSAGESYS_GETRUSAGE_CHLD
:
7625 case VKI__RUSAGESYS_GETRUSAGE_LWP
:
7626 /* Libc: int getrusage(int who, struct rusage *r_usage); */
7627 PRINT("sys_rusagesys ( %ld, %#lx )", SARG1
, ARG2
);
7628 PRE_REG_READ2(long, SC2("rusagesys", "getrusage"), int, code
,
7629 struct vki_rusage
*, r_usage
);
7630 PRE_MEM_WRITE("rusagesys(r_usage)", ARG2
, sizeof(struct vki_rusage
));
7633 case VKI__RUSAGESYS_GETVMUSAGE
:
7634 /* Libc: int getvmusage(uint_t flags, time_t age,
7635 vmusage_t *buf, size_t *nres); */
7636 PRINT("sys_rusagesys ( %ld, %lu, %ld, %#lx, %#lx )",
7637 SARG1
, ARG2
, SARG3
, ARG4
, ARG5
);
7638 PRE_REG_READ5(long, SC2("rusagesys", "getvmusage"), int, code
,
7639 vki_uint_t
, flags
, vki_time_t
, age
,
7640 vki_vmusage_t
*, buf
, vki_size_t
*, nres
);
7641 PRE_MEM_READ("rusagesys(nres)", ARG5
, sizeof(vki_size_t
));
7642 /* PRE_MEM_WRITE("rusagesys(nres)", ARG5, sizeof(vki_size_t)); */
7644 if (ML_(safe_to_deref
)((void *) ARG5
, sizeof(vki_size_t
))) {
7645 vki_size_t
*nres
= (vki_size_t
*) ARG5
;
7646 PRE_MEM_WRITE("rusagesys(buf)", ARG4
,
7647 *nres
* sizeof(vki_vmusage_t
));
7649 *flags
|= SfMayBlock
;
7653 VG_(unimplemented
)("Syswrap of the rusagesys call with code %ld.", SARG1
);
7661 switch (ARG1
/*code*/) {
7662 case VKI__RUSAGESYS_GETRUSAGE
:
7663 case VKI__RUSAGESYS_GETRUSAGE_CHLD
:
7664 case VKI__RUSAGESYS_GETRUSAGE_LWP
:
7665 POST_MEM_WRITE(ARG2
, sizeof(struct vki_rusage
));
7667 case VKI__RUSAGESYS_GETVMUSAGE
:
7669 vki_size_t
*nres
= (vki_size_t
*) ARG5
;
7670 POST_MEM_WRITE(ARG5
, sizeof(vki_size_t
));
7671 POST_MEM_WRITE(ARG4
, *nres
* sizeof(vki_vmusage_t
));
7682 /* Kernel: int64_t portfs(int opcode, uintptr_t a0, uintptr_t a1,
7683 uintptr_t a2, uintptr_t a3, uintptr_t a4); */
7684 Int opcode
= ARG1
& VKI_PORT_CODE_MASK
;
7685 *flags
|= SfMayBlock
;
7687 case VKI_PORT_CREATE
:
7688 PRINT("sys_port ( %ld )", SARG1
);
7689 PRE_REG_READ1(long, SC2("port", "create"), int, opcode
);
7691 case VKI_PORT_ASSOCIATE
:
7692 case VKI_PORT_DISSOCIATE
:
7693 PRINT("sys_port ( %ld, %ld, %ld, %#lx, %ld, %#lx )", SARG1
, SARG2
, SARG3
,
7695 if (opcode
== VKI_PORT_ASSOCIATE
) {
7696 PRE_REG_READ6(long, SC2("port", "associate"), int, opcode
, int, a0
,
7697 int, a1
, uintptr_t, a2
, int, a3
, void *, a4
);
7700 PRE_REG_READ6(long, SC2("port", "dissociate"), int, opcode
, int, a0
,
7701 int, a1
, uintptr_t, a2
, int, a3
, void *, a4
);
7704 switch (ARG3
/*source*/) {
7705 case VKI_PORT_SOURCE_FD
:
7706 if (!ML_(fd_allowed
)(ARG4
, "port", tid
, False
)) {
7707 SET_STATUS_Failure(VKI_EBADF
);
7710 case VKI_PORT_SOURCE_FILE
:
7712 struct vki_file_obj
*fo
= (struct vki_file_obj
*)ARG4
;
7713 PRE_MEM_READ("port(file_obj)", ARG4
, sizeof(struct vki_file_obj
));
7714 if (ML_(safe_to_deref
)(&fo
->fo_name
, sizeof(fo
->fo_name
)))
7715 PRE_MEM_RASCIIZ("port(file_obj->fo_name)", (Addr
)fo
->fo_name
);
7719 VG_(unimplemented
)("Syswrap of the port_associate/dissociate call "
7720 "type %ld.", SARG3
);
7726 PRINT("sys_port ( %ld, %ld, %ld, %#lx )", SARG1
, SARG2
, SARG3
, ARG4
);
7727 PRE_REG_READ4(long, SC2("port", "send"), int, opcode
, int, a0
, int, a1
,
7730 case VKI_PORT_SENDN
:
7731 PRINT("sys_port ( %ld, %#lx, %#lx, %lu, %lx, %#lx)", SARG1
, ARG2
, ARG3
,
7733 PRE_REG_READ6(long, SC2("port", "sendn"), int, opcode
, int *, a0
,
7734 int *, a1
, vki_uint_t
, a2
, int, a3
, void *, a4
);
7735 PRE_MEM_READ("port(ports)", ARG2
, ARG4
* sizeof(int));
7736 PRE_MEM_WRITE("port(errors)", ARG3
, ARG4
* sizeof(int));
7739 PRINT("sys_port ( %ld, %ld, %#lx, %ld, %ld, %#lx )", SARG1
, SARG2
, ARG3
,
7740 SARG4
, SARG5
, ARG6
);
7741 PRE_REG_READ6(long, SC2("port", "get"), int, opcode
, int, a0
,
7742 port_event_t
*, a1
, vki_time_t
, a2
, long, a3
,
7744 PRE_MEM_WRITE("port(uevp)", ARG3
, sizeof(vki_port_event_t
));
7747 PRINT("sys_port ( %ld, %ld, %#lx, %lu, %lu, %#lx )", SARG1
, SARG2
, ARG3
,
7749 PRE_REG_READ6(long, SC2("port", "getn"), int, opcode
, int, a0
,
7750 port_event_t
*, a1
, vki_uint_t
, a2
, vki_uint_t
, a3
,
7753 PRE_MEM_READ("port(timeout)", ARG6
, sizeof(vki_timespec_t
));
7754 PRE_MEM_WRITE("port(uevp)", ARG3
, ARG4
* sizeof(vki_port_event_t
));
7756 case VKI_PORT_ALERT
:
7757 PRINT("sys_port ( %ld, %ld, %ld, %ld, %#lx )", SARG1
, SARG2
, SARG3
, SARG4
,
7759 PRE_REG_READ5(long, SC2("port", "alert"), int, opcode
, int, a0
, int, a1
,
7760 int, a2
, void *, a3
);
7762 case VKI_PORT_DISPATCH
:
7763 // FIXME: check order: SARG2, SARG1 or SARG1, SARG2 ??
7764 PRINT("sys_port ( %ld, %ld, %ld, %ld, %#lx, %#lx )", SARG2
, SARG1
, SARG3
,
7766 PRE_REG_READ6(long, SC2("port", "dispatch"), int, opcode
, int, a0
,
7767 int, a1
, int, a2
, uintptr_t, a3
, void *, a4
);
7770 VG_(unimplemented
)("Syswrap of the port call with opcode %ld.", SARG1
);
7776 if ((opcode
!= VKI_PORT_CREATE
&& opcode
!= VKI_PORT_SENDN
) &&
7777 !ML_(fd_allowed
)(ARG2
, "port", tid
, False
))
7778 SET_STATUS_Failure(VKI_EBADF
);
7783 Int opcode
= ARG1
& VKI_PORT_CODE_MASK
;
7785 case VKI_PORT_CREATE
:
7786 if (!ML_(fd_allowed
)(RES
, "port", tid
, True
)) {
7788 SET_STATUS_Failure(VKI_EMFILE
);
7790 else if (VG_(clo_track_fds
))
7791 ML_(record_fd_open_named
)(tid
, RES
);
7793 case VKI_PORT_ASSOCIATE
:
7794 case VKI_PORT_DISSOCIATE
:
7797 case VKI_PORT_SENDN
:
7799 /* If there is any error then the whole errors area is written. */
7800 POST_MEM_WRITE(ARG3
, ARG4
* sizeof(int));
7804 POST_MEM_WRITE(ARG3
, sizeof(vki_port_event_t
));
7807 POST_MEM_WRITE(ARG3
, RES
* sizeof(vki_port_event_t
));
7809 case VKI_PORT_ALERT
:
7810 case VKI_PORT_DISPATCH
:
7813 VG_(unimplemented
)("Syswrap of the port call with opcode %lu.", ARG1
);
7821 /* int pollsys(pollfd_t *fds, nfds_t nfds, timespec_t *timeout,
7824 struct vki_pollfd
*ufds
= (struct vki_pollfd
*)ARG1
;
7826 *flags
|= SfMayBlock
| SfPostOnFail
;
7828 PRINT("sys_pollsys ( %#lx, %lu, %#lx, %#lx )", ARG1
, ARG2
, ARG3
, ARG4
);
7829 PRE_REG_READ4(long, "poll", pollfd_t
*, fds
, vki_nfds_t
, nfds
,
7830 timespec_t
*, timeout
, sigset_t
*, set
);
7832 for (i
= 0; i
< ARG2
; i
++) {
7833 vki_pollfd_t
*u
= &ufds
[i
];
7834 PRE_FIELD_READ("poll(ufds.fd)", u
->fd
);
7835 if (ML_(safe_to_deref
)(&ufds
[i
].fd
, sizeof(ufds
[i
].fd
)) && ufds
[i
].fd
>= 0) {
7836 PRE_FIELD_READ("poll(ufds.events)", u
->events
);
7838 PRE_FIELD_WRITE("poll(ufds.revents)", u
->revents
);
7842 PRE_MEM_READ("poll(timeout)", ARG3
, sizeof(vki_timespec_t
));
7845 PRE_MEM_READ("poll(set)", ARG4
, sizeof(vki_sigset_t
));
7847 const vki_sigset_t
*guest_sigmask
= (vki_sigset_t
*) ARG4
;
7848 if (!ML_(safe_to_deref
)(guest_sigmask
, sizeof(vki_sigset_t
))) {
7849 ARG4
= 1; /* Something recognisable to POST() hook. */
7851 vki_sigset_t
*vg_sigmask
=
7852 VG_(malloc
)("syswrap.pollsys.1", sizeof(vki_sigset_t
));
7853 ARG4
= (Addr
) vg_sigmask
;
7854 *vg_sigmask
= *guest_sigmask
;
7855 VG_(sanitize_client_sigmask
)(vg_sigmask
);
7862 vg_assert(SUCCESS
|| FAILURE
);
7864 if (SUCCESS
&& (RES
>= 0)) {
7866 vki_pollfd_t
*ufds
= (vki_pollfd_t
*)ARG1
;
7867 for (i
= 0; i
< ARG2
; i
++)
7868 POST_FIELD_WRITE(ufds
[i
].revents
);
7871 if ((ARG4
!= 0) && (ARG4
!= 1)) {
7872 VG_(free
)((vki_sigset_t
*) ARG4
);
7878 /* Kernel: int labelsys(int op, void *a1, void *a2, void *a3,
7879 void *a4, void *a5); */
7881 switch (ARG1
/*op*/) {
7882 case VKI_TSOL_SYSLABELING
:
7883 /* Libc: int is_system_labeled(void); */
7884 PRINT("sys_labelsys ( %ld )", SARG1
);
7885 PRE_REG_READ1(long, SC2("labelsys", "syslabeling"), int, op
);
7889 /* Libtsnet: int tnrh(int cmd, tsol_rhent_t *buf); */
7890 PRINT("sys_labelsys ( %ld, %ld, %#lx )", SARG1
, SARG2
, ARG3
);
7891 PRE_REG_READ3(long, SC2("labelsys", "tnrh"), int, op
, int, cmd
,
7892 vki_tsol_rhent_t
*, buf
);
7893 if (ARG2
!= VKI_TNDB_FLUSH
)
7894 PRE_MEM_READ("labelsys(buf)", ARG3
, sizeof(vki_tsol_rhent_t
));
7897 case VKI_TSOL_TNRHTP
:
7898 /* Libtsnet: int tnrhtp(int cmd, tsol_tpent_t *buf); */
7899 PRINT("sys_labelsys ( %ld, %ld, %#lx )", SARG1
, SARG2
, ARG3
);
7900 PRE_REG_READ3(long, SC2("labelsys", "tnrhtp"), int, op
, int, cmd
,
7901 vki_tsol_tpent_t
*, buf
);
7902 if (ARG2
!= VKI_TNDB_FLUSH
)
7903 PRE_MEM_READ("labelsys(buf)", ARG3
, sizeof(vki_tsol_tpent_t
));
7906 case VKI_TSOL_TNMLP
:
7907 /* Libtsnet: int tnmlp(int cmd, tsol_mlpent_t *buf); */
7908 PRINT("sys_labelsys ( %ld, %ld, %#lx )", SARG1
, SARG2
, ARG3
);
7909 PRE_REG_READ3(long, SC2("labelsys", "tnmlp"), int, op
, int, cmd
,
7910 vki_tsol_mlpent_t
*, buf
);
7911 PRE_MEM_READ("labelsys(buf)", ARG3
, sizeof(vki_tsol_mlpent_t
));
7914 case VKI_TSOL_GETLABEL
:
7915 /* Libtsol: int getlabel(const char *path, bslabel_t *label); */
7916 PRINT("sys_labelsys ( %ld, %#lx(%s), %#lx )",
7917 SARG1
, ARG2
, (HChar
*) ARG2
, ARG3
);
7918 PRE_REG_READ3(long, SC2("labelsys", "getlabel"), int, op
,
7919 const char *, path
, vki_bslabel_t
*, label
);
7920 PRE_MEM_RASCIIZ("labelsys(path)", ARG2
);
7921 PRE_MEM_WRITE("labelsys(label)", ARG3
, sizeof(vki_bslabel_t
));
7924 case VKI_TSOL_FGETLABEL
:
7925 /* Libtsol: int fgetlabel(int fd, bslabel_t *label); */
7926 PRINT("sys_labelsys ( %ld, %ld, %#lx )", SARG1
, SARG2
, ARG3
);
7927 PRE_REG_READ3(long, SC2("labelsys", "fgetlabel"), int, op
,
7928 int, fd
, vki_bslabel_t
*, label
);
7930 if (!ML_(fd_allowed
)(ARG2
, "labelsys(fgetlabel)", tid
, False
))
7931 SET_STATUS_Failure(VKI_EBADF
);
7932 PRE_MEM_WRITE("labelsys(label)", ARG3
, sizeof(vki_bslabel_t
));
7935 #if defined(SOLARIS_TSOL_CLEARANCE)
7936 case VKI_TSOL_GETCLEARANCE
:
7937 /* Libtsol: int getclearance(bslabel_t *clearance); */
7938 PRINT("sys_labelsys ( %ld, %#lx )", SARG1
, ARG2
);
7939 PRE_REG_READ2(long, SC2("labelsys", "getclearance"), int, op
,
7940 vki_bslabel_t
*, clearance
);
7941 PRE_MEM_WRITE("labelsys(clearance)", ARG2
, sizeof(vki_bslabel_t
));
7944 case VKI_TSOL_SETCLEARANCE
:
7945 /* Libtsol: int setclearance(bslabel_t *clearance); */
7946 PRINT("sys_labelsys ( %ld, %#lx )", SARG1
, ARG2
);
7947 PRE_REG_READ2(long, SC2("labelsys", "setclearance"), int, op
,
7948 vki_bslabel_t
*, clearance
);
7949 PRE_MEM_READ("labelsys(clearance)", ARG2
, sizeof(vki_bslabel_t
));
7951 #endif /* SOLARIS_TSOL_CLEARANCE */
7954 VG_(unimplemented
)("Syswrap of the labelsys call with op %ld.", SARG1
);
7962 switch (ARG1
/*op*/) {
7963 case VKI_TSOL_SYSLABELING
:
7967 switch (ARG2
/*cmd*/) {
7969 case VKI_TNDB_DELETE
:
7970 case VKI_TNDB_FLUSH
:
7972 #if defined(SOLARIS_TNDB_GET_TNIP)
7974 #endif /* SOLARIS_TNDB_GET_TNIP */
7976 POST_MEM_WRITE(ARG3
, sizeof(vki_tsol_rhent_t
));
7984 case VKI_TSOL_TNRHTP
:
7985 switch (ARG2
/*cmd*/) {
7987 case VKI_TNDB_DELETE
:
7988 case VKI_TNDB_FLUSH
:
7991 POST_MEM_WRITE(ARG3
, sizeof(vki_tsol_tpent_t
));
7999 case VKI_TSOL_TNMLP
:
8000 switch (ARG2
/*cmd*/) {
8002 case VKI_TNDB_DELETE
:
8003 case VKI_TNDB_FLUSH
:
8006 POST_MEM_WRITE(ARG3
, sizeof(vki_tsol_mlpent_t
));
8014 case VKI_TSOL_GETLABEL
:
8015 case VKI_TSOL_FGETLABEL
:
8016 POST_MEM_WRITE(ARG3
, sizeof(vki_bslabel_t
));
8019 #if defined(SOLARIS_TSOL_CLEARANCE)
8020 case VKI_TSOL_GETCLEARANCE
:
8021 POST_MEM_WRITE(ARG2
, sizeof(vki_bslabel_t
));
8024 case VKI_TSOL_SETCLEARANCE
:
8026 #endif /* SOLARIS_TSOL_CLEARANCE */
8036 /* int acl(char *pathp, int cmd, int nentries, void *aclbufp); */
8037 PRINT("sys_acl ( %#lx(%s), %ld, %ld, %#lx )", ARG1
, (HChar
*) ARG1
, SARG2
,
8040 PRE_REG_READ4(long, "acl", char *, pathp
, int, cmd
,
8041 int, nentries
, void *, aclbufp
);
8042 PRE_MEM_RASCIIZ("acl(pathp)", ARG1
);
8044 switch (ARG2
/*cmd*/) {
8047 PRE_MEM_READ("acl(aclbufp)", ARG4
, ARG3
* sizeof(vki_aclent_t
));
8050 PRE_MEM_WRITE("acl(aclbufp)", ARG4
, ARG3
* sizeof(vki_aclent_t
));
8054 case VKI_ACE_SETACL
:
8056 PRE_MEM_READ("acl(aclbufp)", ARG4
, ARG3
* sizeof(vki_ace_t
));
8058 case VKI_ACE_GETACL
:
8059 PRE_MEM_WRITE("acl(aclbufp)", ARG4
, ARG3
* sizeof(vki_ace_t
));
8061 case VKI_ACE_GETACLCNT
:
8064 VG_(unimplemented
)("Syswrap of the acl call with cmd %ld.", SARG2
);
8072 switch (ARG2
/*cmd*/) {
8076 POST_MEM_WRITE(ARG4
, ARG3
* sizeof(vki_aclent_t
));
8080 case VKI_ACE_SETACL
:
8082 case VKI_ACE_GETACL
:
8083 POST_MEM_WRITE(ARG4
, ARG3
* sizeof(vki_ace_t
));
8085 case VKI_ACE_GETACLCNT
:
8095 /* Kernel: int auditsys(long code, long a1, long a2, long a3, long a4); */
8096 switch (ARG1
/*code*/) {
8097 case VKI_BSM_GETAUID
:
8098 /* Libbsm: int getauid(au_id_t *auid); */
8099 PRINT("sys_auditsys ( %ld, %#lx )", SARG1
, ARG2
);
8100 PRE_REG_READ2(long, SC2("auditsys", "getauid"), long, code
,
8101 vki_au_id_t
*, auid
);
8102 PRE_MEM_WRITE("auditsys(auid)", ARG2
, sizeof(vki_au_id_t
));
8104 case VKI_BSM_SETAUID
:
8105 /* Libbsm: int setauid(au_id_t *auid); */
8106 PRINT("sys_auditsys ( %ld, %#lx )", SARG1
, ARG2
);
8107 PRE_REG_READ2(long, SC2("auditsys", "setauid"), long, code
,
8108 vki_au_id_t
*, auid
);
8109 PRE_MEM_READ("auditsys(auid)", ARG2
, sizeof(vki_au_id_t
));
8111 case VKI_BSM_GETAUDIT
:
8112 /* Libbsm: int getaudit(auditinfo_t *ai); */
8113 PRINT("sys_auditsys ( %ld, %#lx )", SARG1
, ARG2
);
8114 PRE_REG_READ2(long, SC2("auditsys", "getaudit"), long, code
,
8115 vki_auditinfo_t
*, ai
);
8116 PRE_MEM_WRITE("auditsys(ai)", ARG2
, sizeof(vki_auditinfo_t
));
8118 case VKI_BSM_SETAUDIT
:
8119 /* Libbsm: int setaudit(auditinfo_t *ai); */
8120 PRINT("sys_auditsys ( %ld, %#lx )", SARG1
, ARG2
);
8121 PRE_REG_READ2(long, SC2("auditsys", "setaudit"), long, code
,
8122 vki_auditinfo_t
*, ai
);
8123 PRE_MEM_READ("auditsys(ai)", ARG2
, sizeof(vki_auditinfo_t
));
8126 /* Libbsm: int audit(void *record, int length); */
8127 PRINT("sys_auditsys ( %ld, %#lx, %ld )", SARG1
, ARG2
, SARG3
);
8128 PRE_REG_READ3(long, SC2("auditsys", "audit"), long, code
,
8129 void *, record
, int, length
);
8130 PRE_MEM_READ("auditsys(record)", ARG2
, ARG3
);
8132 case VKI_BSM_AUDITCTL
:
8133 /* Libbsm: int auditon(int cmd, caddr_t data, int length); */
8134 PRINT("sys_auditsys ( %ld, %ld, %#lx, %ld )",
8135 SARG1
, SARG2
, ARG3
, SARG4
);
8137 switch (ARG2
/*cmd*/) {
8138 case VKI_A_GETPOLICY
:
8139 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "getpolicy"),
8140 long, code
, int, cmd
, vki_uint32_t
*, policy
);
8141 PRE_MEM_WRITE("auditsys(policy)", ARG3
, sizeof(vki_uint32_t
));
8143 case VKI_A_SETPOLICY
:
8144 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "setpolicy"),
8145 long, code
, int, cmd
, vki_uint32_t
*, policy
);
8146 PRE_MEM_READ("auditsys(policy)", ARG3
, sizeof(vki_uint32_t
));
8148 case VKI_A_GETKMASK
:
8149 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "getkmask"),
8150 long, code
, int, cmd
, vki_au_mask_t
*, kmask
);
8151 PRE_MEM_WRITE("auditsys(kmask)", ARG3
, sizeof(vki_au_mask_t
));
8153 case VKI_A_SETKMASK
:
8154 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "setkmask"),
8155 long, code
, int, cmd
, vki_au_mask_t
*, kmask
);
8156 PRE_MEM_READ("auditsys(kmask)", ARG3
, sizeof(vki_au_mask_t
));
8158 case VKI_A_GETQCTRL
:
8159 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "getqctrl"),
8160 long, code
, int, cmd
,
8161 struct vki_au_qctrl
*, qctrl
);
8162 PRE_MEM_WRITE("auditsys(qctrl)", ARG3
,
8163 sizeof(struct vki_au_qctrl
));
8165 case VKI_A_SETQCTRL
:
8166 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "setqctrl"),
8167 long, code
, int, cmd
,
8168 struct vki_au_qctrl
*, qctrl
);
8169 PRE_MEM_READ("auditsys(qctrl)", ARG3
,
8170 sizeof(struct vki_au_qctrl
));
8173 PRE_REG_READ4(long, SC3("auditsys", "auditctl", "getcwd"),
8174 long, code
, int, cmd
, char *, data
, int, length
);
8175 PRE_MEM_WRITE("auditsys(data)", ARG3
, ARG4
);
8178 PRE_REG_READ4(long, SC3("auditsys", "auditctl", "getcar"),
8179 long, code
, int, cmd
, char *, data
, int, length
);
8180 PRE_MEM_WRITE("auditsys(data)", ARG3
, ARG4
);
8182 #if defined(SOLARIS_AUDITON_STAT)
8184 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "getstat"),
8185 long, code
, int, cmd
, vki_au_stat_t
*, stats
);
8186 PRE_MEM_WRITE("auditsys(stats)", ARG3
, sizeof(vki_au_stat_t
));
8189 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "setstat"),
8190 long, code
, int, cmd
, vki_au_stat_t
*, stats
);
8191 PRE_MEM_READ("auditsys(stats)", ARG3
, sizeof(vki_au_stat_t
));
8193 #endif /* SOLARIS_AUDITON_STAT */
8194 case VKI_A_SETUMASK
:
8195 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "setumask"),
8196 long, code
, int, cmd
, vki_auditinfo_t
*, umask
);
8197 PRE_MEM_READ("auditsys(umask)", ARG3
, sizeof(vki_auditinfo_t
));
8199 case VKI_A_SETSMASK
:
8200 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "setsmask"),
8201 long, code
, int, cmd
, vki_auditinfo_t
*, smask
);
8202 PRE_MEM_READ("auditsys(smask)", ARG3
, sizeof(vki_auditinfo_t
));
8205 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "getcond"),
8206 long, code
, int, cmd
, int *, cond
);
8207 PRE_MEM_WRITE("auditsys(cond)", ARG3
, sizeof(int));
8210 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "setcond"),
8211 long, code
, int, cmd
, int *, state
);
8212 PRE_MEM_READ("auditsys(cond)", ARG3
, sizeof(int));
8214 case VKI_A_GETCLASS
:
8215 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "getclass"),
8216 long, code
, int, cmd
,
8217 vki_au_evclass_map_t
*, classmap
);
8219 if (ML_(safe_to_deref((void *) ARG3
,
8220 sizeof(vki_au_evclass_map_t
)))) {
8221 vki_au_evclass_map_t
*classmap
=
8222 (vki_au_evclass_map_t
*) ARG3
;
8223 PRE_FIELD_READ("auditsys(classmap.ec_number)",
8224 classmap
->ec_number
);
8225 PRE_MEM_WRITE("auditsys(classmap)", ARG3
,
8226 sizeof(vki_au_evclass_map_t
));
8229 case VKI_A_SETCLASS
:
8230 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "setclass"),
8231 long, code
, int, cmd
,
8232 vki_au_evclass_map_t
*, classmap
);
8234 if (ML_(safe_to_deref((void *) ARG3
,
8235 sizeof(vki_au_evclass_map_t
)))) {
8236 vki_au_evclass_map_t
*classmap
=
8237 (vki_au_evclass_map_t
*) ARG3
;
8238 PRE_FIELD_READ("auditsys(classmap.ec_number)",
8239 classmap
->ec_number
);
8240 PRE_FIELD_READ("auditsys(classmap.ec_class)",
8241 classmap
->ec_class
);
8244 case VKI_A_GETPINFO
:
8245 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "getpinfo"),
8246 long, code
, int, cmd
,
8247 struct vki_auditpinfo
*, apinfo
);
8249 if (ML_(safe_to_deref((void *) ARG3
,
8250 sizeof(struct vki_auditpinfo
)))) {
8251 struct vki_auditpinfo
*apinfo
=
8252 (struct vki_auditpinfo
*) ARG3
;
8253 PRE_FIELD_READ("auditsys(apinfo.ap_pid)", apinfo
->ap_pid
);
8254 PRE_MEM_WRITE("auditsys(apinfo)", ARG3
,
8255 sizeof(struct vki_auditpinfo
));
8258 case VKI_A_SETPMASK
:
8259 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "setpmask"),
8260 long, code
, int, cmd
,
8261 struct vki_auditpinfo
*, apinfo
);
8262 PRE_MEM_WRITE("auditsys(apinfo)", ARG3
,
8263 sizeof(struct vki_auditpinfo
));
8265 case VKI_A_GETPINFO_ADDR
:
8266 PRE_REG_READ4(long, SC3("auditsys", "auditctl", "getpinfo_addr"),
8267 long, code
, int, cmd
,
8268 struct vki_auditpinfo_addr
*, apinfo
, int, length
);
8270 if (ML_(safe_to_deref((void *) ARG3
,
8271 sizeof(struct vki_auditpinfo_addr
)))) {
8272 struct vki_auditpinfo_addr
*apinfo_addr
=
8273 (struct vki_auditpinfo_addr
*) ARG3
;
8274 PRE_FIELD_READ("auditsys(apinfo_addr.ap_pid)",
8275 apinfo_addr
->ap_pid
);
8276 PRE_MEM_WRITE("auditsys(apinfo_addr)", ARG3
, ARG4
);
8279 case VKI_A_GETKAUDIT
:
8280 PRE_REG_READ4(long, SC3("auditsys", "auditctl", "getkaudit"),
8281 long, code
, int, cmd
,
8282 vki_auditinfo_addr_t
*, kaudit
, int, length
);
8283 PRE_MEM_WRITE("auditsys(kaudit)", ARG3
, ARG4
);
8285 case VKI_A_SETKAUDIT
:
8286 PRE_REG_READ4(long, SC3("auditsys", "auditctl", "setkaudit"),
8287 long, code
, int, cmd
,
8288 vki_auditinfo_addr_t
*, kaudit
, int, length
);
8289 PRE_MEM_READ("auditsys(kaudit)", ARG3
, ARG4
);
8291 case VKI_A_GETAMASK
:
8292 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "getamask"),
8293 long, code
, int, cmd
, vki_au_mask_t
*, amask
);
8294 PRE_MEM_WRITE("auditsys(amask)", ARG3
, sizeof(vki_au_mask_t
));
8296 case VKI_A_SETAMASK
:
8297 PRE_REG_READ3(long, SC3("auditsys", "auditctl", "setamask"),
8298 long, code
, int, cmd
, vki_au_mask_t
*, amask
);
8299 PRE_MEM_READ("auditsys(amask)", ARG3
, sizeof(vki_au_mask_t
));
8302 VG_(unimplemented
)("Syswrap of the auditsys(auditctl) call "
8303 "with cmd %lu.", ARG2
);
8308 case VKI_BSM_GETAUDIT_ADDR
:
8309 /* Libbsm: int getaudit_addr(auditinfo_addr_t *ai, int len); */
8310 PRINT("sys_auditsys ( %ld, %#lx, %ld )", SARG1
, ARG2
, SARG3
);
8311 PRE_REG_READ3(long, SC2("auditsys", "getaudit_addr"), long, code
,
8312 vki_auditinfo_addr_t
*, ai
, int, len
);
8313 PRE_MEM_WRITE("auditsys(ai)", ARG2
, ARG3
);
8315 case VKI_BSM_SETAUDIT_ADDR
:
8316 /* Libbsm: int setaudit_addr(auditinfo_addr_t *ai, int len); */
8317 PRINT("sys_auditsys ( %ld, %#lx, %ld )", SARG1
, ARG2
, SARG3
);
8318 PRE_REG_READ3(long, SC2("auditsys", "setaudit_addr"), long, code
,
8319 vki_auditinfo_addr_t
*, ai
, int, len
);
8320 PRE_MEM_READ("auditsys(ai)", ARG2
, ARG3
);
8322 case VKI_BSM_AUDITDOOR
:
8323 /* Libbsm: int auditdoor(int fd); */
8324 PRINT("sys_auditsys ( %ld, %ld )", SARG1
, SARG2
);
8325 PRE_REG_READ2(long, SC2("auditsys", "door"), long, code
, int, fd
);
8328 if (!ML_(fd_allowed
)(ARG2
, SC2("auditsys", "door")"(fd)",
8330 SET_STATUS_Failure(VKI_EBADF
);
8333 VG_(unimplemented
)("Syswrap of the auditsys call with code %lu.", ARG1
);
8341 switch (ARG1
/*code*/) {
8342 case VKI_BSM_GETAUID
:
8343 POST_MEM_WRITE(ARG2
, sizeof(vki_au_id_t
));
8345 case VKI_BSM_SETAUID
:
8347 case VKI_BSM_GETAUDIT
:
8348 POST_MEM_WRITE(ARG2
, sizeof(vki_auditinfo_t
));
8350 case VKI_BSM_SETAUDIT
:
8353 case VKI_BSM_AUDITCTL
:
8354 switch (ARG2
/*cmd*/) {
8355 case VKI_A_GETPOLICY
:
8356 POST_MEM_WRITE(ARG3
, sizeof(vki_uint32_t
));
8358 case VKI_A_SETPOLICY
:
8360 case VKI_A_GETKMASK
:
8361 POST_MEM_WRITE(ARG3
, sizeof(vki_au_mask_t
));
8363 case VKI_A_SETKMASK
:
8365 case VKI_A_GETQCTRL
:
8366 POST_MEM_WRITE(ARG3
, sizeof(struct vki_au_qctrl
));
8368 case VKI_A_SETQCTRL
:
8372 POST_MEM_WRITE(ARG3
, VG_(strlen
)((HChar
*) ARG3
) + 1);
8374 #if defined(SOLARIS_AUDITON_STAT)
8376 POST_MEM_WRITE(ARG3
, sizeof(vki_au_stat_t
));
8379 #endif /* SOLARIS_AUDITON_STAT */
8380 case VKI_A_SETUMASK
:
8381 case VKI_A_SETSMASK
:
8384 POST_MEM_WRITE(ARG3
, sizeof(int));
8388 case VKI_A_GETCLASS
:
8389 POST_MEM_WRITE(ARG3
, sizeof(vki_au_evclass_map_t
));
8391 case VKI_A_SETCLASS
:
8393 case VKI_A_GETPINFO
:
8394 POST_MEM_WRITE(ARG3
, sizeof(struct vki_auditpinfo
));
8396 case VKI_A_SETPMASK
:
8398 case VKI_A_GETPINFO_ADDR
:
8399 POST_MEM_WRITE(ARG3
, sizeof(struct auditpinfo_addr
));
8401 case VKI_A_GETKAUDIT
:
8402 POST_MEM_WRITE(ARG3
, sizeof(vki_auditinfo_addr_t
));
8404 case VKI_A_SETKAUDIT
:
8406 case VKI_A_GETAMASK
:
8407 POST_MEM_WRITE(ARG3
, sizeof(vki_au_mask_t
));
8409 case VKI_A_SETAMASK
:
8413 case VKI_BSM_GETAUDIT_ADDR
:
8414 POST_MEM_WRITE(ARG2
, sizeof(vki_auditinfo_addr_t
));
8416 case VKI_BSM_SETAUDIT_ADDR
:
8418 case VKI_BSM_AUDITDOOR
:
8425 /* int p_online(processorid_t processorid, int flag); */
8426 PRINT("sys_p_online ( %ld, %ld )", SARG1
, SARG2
);
8427 PRE_REG_READ2(long, "p_online", vki_processorid_t
, processorid
, int, flag
);
8432 /* int sigqueue(pid_t pid, int signo, void *value,
8433 int si_code, timespec_t *timeout);
8435 PRINT("sys_sigqueue ( %ld, %ld, %#lx, %ld, %#lx )",
8436 SARG1
, SARG2
, ARG3
, SARG4
, ARG5
);
8437 PRE_REG_READ5(long, "sigqueue", vki_pid_t
, pid
, int, signo
,
8438 void *, value
, int, si_code
,
8439 vki_timespec_t
*, timeout
);
8442 PRE_MEM_READ("sigqueue(timeout)", ARG5
, sizeof(vki_timespec_t
));
8444 if (!ML_(client_signal_OK
)(ARG2
)) {
8445 SET_STATUS_Failure(VKI_EINVAL
);
8449 /* If we're sending SIGKILL, check to see if the target is one of
8450 our threads and handle it specially. */
8451 if (ARG2
== VKI_SIGKILL
&& ML_(do_sigkill
)(ARG1
, -1)) {
8452 SET_STATUS_Success(0);
8454 SysRes res
= VG_(do_syscall5
)(SYSNO
, ARG1
, ARG2
, ARG3
, ARG4
,
8456 SET_STATUS_from_SysRes(res
);
8459 if (VG_(clo_trace_signals
))
8460 VG_(message
)(Vg_DebugMsg
,
8461 "sigqueue: signal %ld queued for pid %ld\n",
8464 /* Check to see if this gave us a pending signal. */
8465 *flags
|= SfPollAfter
;
8468 PRE(sys_clock_gettime
)
8470 /* int clock_gettime(clockid_t clock_id, struct timespec *tp); */
8471 PRINT("sys_clock_gettime ( %ld, %#lx )", SARG1
, ARG2
);
8472 PRE_REG_READ2(long, "clock_gettime", vki_clockid_t
, clock_id
,
8473 struct timespec
*, tp
);
8474 PRE_MEM_WRITE("clock_gettime(tp)", ARG2
, sizeof(struct vki_timespec
));
8477 POST(sys_clock_gettime
)
8479 POST_MEM_WRITE(ARG2
, sizeof(struct vki_timespec
));
8482 PRE(sys_clock_settime
)
8484 /* int clock_settime(clockid_t clock_id, const struct timespec *tp); */
8485 PRINT("sys_clock_settime ( %ld, %#lx )", SARG1
, ARG2
);
8486 PRE_REG_READ2(long, "clock_settime", vki_clockid_t
, clock_id
,
8487 const struct timespec
*, tp
);
8488 PRE_MEM_READ("clock_settime(tp)", ARG2
, sizeof(struct vki_timespec
));
8491 PRE(sys_clock_getres
)
8493 /* int clock_getres(clockid_t clock_id, struct timespec *res); */
8494 PRINT("sys_clock_getres ( %ld, %#lx )", SARG1
, ARG2
);
8495 PRE_REG_READ2(long, "clock_getres", vki_clockid_t
, clock_id
,
8496 struct timespec
*, res
);
8499 PRE_MEM_WRITE("clock_getres(res)", ARG2
, sizeof(struct vki_timespec
));
8502 POST(sys_clock_getres
)
8505 POST_MEM_WRITE(ARG2
, sizeof(struct vki_timespec
));
8508 PRE(sys_timer_create
)
8510 /* int timer_create(clockid_t clock_id,
8511 struct sigevent *evp, timer_t *timerid);
8513 PRINT("sys_timer_create ( %ld, %#lx, %#lx )", SARG1
, ARG2
, ARG3
);
8514 PRE_REG_READ3(long, "timer_create", vki_clockid_t
, clock_id
,
8515 struct vki_sigevent
*, evp
, vki_timer_t
*, timerid
);
8518 struct vki_sigevent
*evp
= (struct vki_sigevent
*) ARG2
;
8519 PRE_FIELD_READ("timer_create(evp.sigev_notify)", evp
->sigev_notify
);
8520 PRE_FIELD_READ("timer_create(evp.sigev_signo)", evp
->sigev_signo
);
8521 PRE_FIELD_READ("timer_create(evp.sigev_value.sival_int)",
8522 evp
->sigev_value
.sival_int
);
8525 if (ML_(safe_to_deref(evp
, sizeof(struct vki_sigevent
)))) {
8526 if ((evp
->sigev_notify
== VKI_SIGEV_PORT
) ||
8527 (evp
->sigev_notify
== VKI_SIGEV_THREAD
))
8528 PRE_MEM_READ("timer_create(evp.sigev_value.sival_ptr)",
8529 (Addr
) evp
->sigev_value
.sival_ptr
,
8530 sizeof(vki_port_notify_t
));
8534 PRE_MEM_WRITE("timer_create(timerid)", ARG3
, sizeof(vki_timer_t
));
8537 POST(sys_timer_create
)
8539 POST_MEM_WRITE(ARG3
, sizeof(vki_timer_t
));
8542 PRE(sys_timer_delete
)
8544 /* int timer_delete(timer_t timerid); */
8545 PRINT("sys_timer_delete ( %ld )", SARG1
);
8546 PRE_REG_READ1(long, "timer_delete", vki_timer_t
, timerid
);
8549 PRE(sys_timer_settime
)
8551 /* int timer_settime(timer_t timerid, int flags,
8552 const struct itimerspec *value,
8553 struct itimerspec *ovalue);
8555 PRINT("sys_timer_settime ( %ld, %ld, %#lx, %#lx )",
8556 SARG1
, SARG2
, ARG3
, ARG4
);
8557 PRE_REG_READ4(long, "timer_settime", vki_timer_t
, timerid
,
8558 int, flags
, const struct vki_itimerspec
*, value
,
8559 struct vki_itimerspec
*, ovalue
);
8560 PRE_MEM_READ("timer_settime(value)",
8561 ARG3
, sizeof(struct vki_itimerspec
));
8563 PRE_MEM_WRITE("timer_settime(ovalue)",
8564 ARG4
, sizeof(struct vki_itimerspec
));
8567 POST(sys_timer_settime
)
8570 POST_MEM_WRITE(ARG4
, sizeof(struct vki_itimerspec
));
8573 PRE(sys_timer_gettime
)
8575 /* int timer_gettime(timer_t timerid, struct itimerspec *value); */
8576 PRINT("sys_timer_gettime ( %ld, %#lx )", SARG1
, ARG2
);
8577 PRE_REG_READ2(long, "timer_gettime", vki_timer_t
, timerid
,
8578 struct vki_itimerspec
*, value
);
8579 PRE_MEM_WRITE("timer_gettime(value)",
8580 ARG2
, sizeof(struct vki_itimerspec
));
8583 POST(sys_timer_gettime
)
8585 POST_MEM_WRITE(ARG2
, sizeof(struct vki_itimerspec
));
8588 PRE(sys_timer_getoverrun
)
8590 /* int timer_getoverrun(timer_t timerid); */
8591 PRINT("sys_timer_getoverrun ( %ld )", SARG1
);
8592 PRE_REG_READ1(long, "timer_getoverrun", vki_timer_t
, timerid
);
8597 /* int facl(int fildes, int cmd, int nentries, void *aclbufp); */
8598 PRINT("sys_facl ( %ld, %ld, %ld, %#lx )", SARG1
, SARG2
, SARG3
, ARG4
);
8600 PRE_REG_READ4(long, "facl", int, fildes
, int, cmd
,
8601 int, nentries
, void *, aclbufp
);
8603 switch (ARG2
/*cmd*/) {
8606 PRE_MEM_READ("facl(aclbufp)", ARG4
, sizeof(vki_aclent_t
));
8609 PRE_MEM_WRITE("facl(aclbufp)", ARG4
, ARG3
* sizeof(vki_aclent_t
));
8613 case VKI_ACE_SETACL
:
8615 PRE_MEM_READ("facl(aclbufp)", ARG4
, sizeof(vki_ace_t
));
8617 case VKI_ACE_GETACL
:
8618 PRE_MEM_WRITE("facl(aclbufp)", ARG4
, ARG3
* sizeof(vki_ace_t
));
8620 case VKI_ACE_GETACLCNT
:
8623 VG_(unimplemented
)("Syswrap of the facl call with cmd %ld.", SARG2
);
8629 if (!ML_(fd_allowed
)(ARG1
, "facl", tid
, False
))
8630 SET_STATUS_Failure(VKI_EBADF
);
8635 switch (ARG2
/*cmd*/) {
8639 POST_MEM_WRITE(ARG4
, ARG3
* sizeof(vki_aclent_t
));
8643 case VKI_ACE_SETACL
:
8645 case VKI_ACE_GETACL
:
8646 POST_MEM_WRITE(ARG4
, ARG3
* sizeof(vki_ace_t
));
8648 case VKI_ACE_GETACLCNT
:
8656 static Int
pre_check_and_close_fds(ThreadId tid
, const HChar
*name
,
8657 vki_door_desc_t
*desc_ptr
,
8658 vki_uint_t desc_num
)
8662 /* Verify passed file descriptors. */
8663 for (i
= 0; i
< desc_num
; i
++) {
8664 vki_door_desc_t
*desc
= &desc_ptr
[i
];
8665 if ((desc
->d_attributes
& DOOR_DESCRIPTOR
) &&
8666 (desc
->d_attributes
& DOOR_RELEASE
)) {
8667 Int fd
= desc
->d_data
.d_desc
.d_descriptor
;
8669 /* Detect and negate attempts by the client to close Valgrind's fds.
8670 Also if doing -d style logging (which is to fd = 2 = stderr),
8671 don't allow that to be closed either. */
8672 if (!ML_(fd_allowed
)(fd
, name
, tid
, False
) ||
8673 (fd
== 2 && VG_(debugLog_getLevel
)() > 0))
8678 /* All fds are allowed, record information about the closed ones.
8680 Note: Recording information about any closed fds should generally happen
8681 in a post wrapper but it is not possible in this case because door calls
8682 are "very blocking", if the information was recorded after the syscall
8683 finishes then it would be out-of-date during the call, i.e. while the
8684 syscall is blocked in the kernel. Therefore, we record closed fds for
8685 this specific syscall in the PRE wrapper. Unfortunately, this creates
8686 a problem when the syscall fails, for example, door_call() can fail with
8687 EBADF or EFAULT and then no fds are released. If that happens the
8688 information about opened fds is incorrect. This should be very rare (I
8689 hope) and such a condition is also reported in the post wrapper. */
8690 if (VG_(clo_track_fds
)) {
8691 for (i
= 0; i
< desc_num
; i
++) {
8692 vki_door_desc_t
*desc
= &desc_ptr
[i
];
8693 if ((desc
->d_attributes
& DOOR_DESCRIPTOR
) &&
8694 (desc
->d_attributes
& DOOR_RELEASE
)) {
8695 Int fd
= desc
->d_data
.d_desc
.d_descriptor
;
8696 ML_(record_fd_close
)(fd
);
8704 static void post_record_fds(ThreadId tid
, const HChar
*name
,
8705 vki_door_desc_t
*desc_ptr
, vki_uint_t desc_num
)
8709 /* Record returned file descriptors. */
8710 for (i
= 0; i
< desc_num
; i
++) {
8711 vki_door_desc_t
*desc
= &desc_ptr
[i
];
8712 if (desc
->d_attributes
& DOOR_DESCRIPTOR
) {
8713 Int fd
= desc
->d_data
.d_desc
.d_descriptor
;
8714 if (!ML_(fd_allowed
)(fd
, name
, tid
, True
)) {
8715 /* Unfortunately, we cannot recover at this point and have to fail
8717 VG_(message
)(Vg_UserMsg
, "The %s syscall returned an unallowed"
8718 "file descriptor %d.\n", name
, fd
);
8721 else if (VG_(clo_track_fds
))
8722 ML_(record_fd_open_named
)(tid
, fd
);
8727 /* Handles repository door protocol request over client door fd. */
8728 static void repository_door_pre_mem_door_call_hook(ThreadId tid
, Int fd
,
8732 vki_rep_protocol_request_t
*p
= (vki_rep_protocol_request_t
*) data_ptr
;
8733 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8734 "request->rpr_request)", p
->rpr_request
);
8736 if (ML_(safe_to_deref
)(p
, sizeof(vki_rep_protocol_request_t
))) {
8737 switch (p
->rpr_request
) {
8738 case VKI_REP_PROTOCOL_CLOSE
:
8740 case VKI_REP_PROTOCOL_ENTITY_SETUP
:
8742 struct vki_rep_protocol_entity_setup
*r
=
8743 (struct vki_rep_protocol_entity_setup
*) p
;
8744 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8745 "entity_setup->rpr_entityid)", r
->rpr_entityid
);
8746 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8747 "entity_setup->rpr_entitytype)", r
->rpr_entitytype
);
8750 case VKI_REP_PROTOCOL_ENTITY_NAME
:
8752 struct vki_rep_protocol_entity_name
*r
=
8753 (struct vki_rep_protocol_entity_name
*) p
;
8754 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8755 "entity_name->rpr_entityid)", r
->rpr_entityid
);
8756 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8757 "entity_name->rpr_answertype)", r
->rpr_answertype
);
8760 #if (SOLARIS_REPCACHE_PROTOCOL_VERSION >= 24) && (SOLARIS_REPCACHE_PROTOCOL_VERSION <= 30)
8761 case VKI_REP_PROTOCOL_ENTITY_FMRI
:
8763 struct vki_rep_protocol_entity_fmri
*r
=
8764 (struct vki_rep_protocol_entity_fmri
*) p
;
8765 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8766 "entity_fmri->rpr_entityid)", r
->rpr_entityid
);
8769 #endif /* 24 <= SOLARIS_REPCACHE_PROTOCOL_VERSION =< 30 */
8770 #if (SOLARIS_REPCACHE_PROTOCOL_VERSION >= 25)
8771 case VKI_REP_PROTOCOL_ENTITY_GET_ROOT
:
8773 struct vki_rep_protocol_entity_root
*r
=
8774 (struct vki_rep_protocol_entity_root
*) p
;
8775 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8776 "entity_root->rpr_entityid)", r
->rpr_entityid
);
8777 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8778 "entity_root->rpr_outid)", r
->rpr_outid
);
8781 #endif /* SOLARIS_REPCACHE_PROTOCOL_VERSION >= 25 */
8782 case VKI_REP_PROTOCOL_ENTITY_GET
:
8784 struct vki_rep_protocol_entity_get
*r
=
8785 (struct vki_rep_protocol_entity_get
*) p
;
8786 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8787 "entity_get->rpr_entityid)", r
->rpr_entityid
);
8788 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8789 "entity_get->rpr_object)", r
->rpr_object
);
8792 case VKI_REP_PROTOCOL_ENTITY_GET_CHILD
:
8793 #if (SOLARIS_REPCACHE_PROTOCOL_VERSION >= 31)
8794 case VKI_REP_PROTOCOL_ENTITY_GET_CHILD_COMPOSED
:
8797 struct vki_rep_protocol_entity_get_child
*r
=
8798 (struct vki_rep_protocol_entity_get_child
*) p
;
8799 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8800 "entity_get_child->rpr_entityid)", r
->rpr_entityid
);
8801 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8802 "entity_get_child->rpr_childid)", r
->rpr_childid
);
8803 PRE_MEM_RASCIIZ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8804 "entity_get_child->rpr_name)", (Addr
) r
->rpr_name
);
8807 case VKI_REP_PROTOCOL_ENTITY_GET_PARENT
:
8809 struct vki_rep_protocol_entity_parent
*r
=
8810 (struct vki_rep_protocol_entity_parent
*) p
;
8811 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8812 "entity_get_parent->rpr_entityid)", r
->rpr_entityid
);
8813 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8814 "entity_get_parent->rpr_outid)", r
->rpr_outid
);
8817 case VKI_REP_PROTOCOL_ENTITY_RESET
:
8819 struct vki_rep_protocol_entity_reset
*r
=
8820 (struct vki_rep_protocol_entity_reset
*) p
;
8821 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8822 "entity_reset->rpr_entityid)", r
->rpr_entityid
);
8825 case VKI_REP_PROTOCOL_ENTITY_TEARDOWN
:
8827 struct vki_rep_protocol_entity_teardown
*r
=
8828 (struct vki_rep_protocol_entity_teardown
*) p
;
8829 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8830 "entity_teardown->rpr_entityid)", r
->rpr_entityid
);
8833 case VKI_REP_PROTOCOL_ITER_READ
:
8835 struct vki_rep_protocol_iter_read
*r
=
8836 (struct vki_rep_protocol_iter_read
*) p
;
8837 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8838 "iter_read->rpr_iterid)", r
->rpr_iterid
);
8839 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8840 "iter_read->rpr_sequence)", r
->rpr_sequence
);
8841 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8842 "iter_read->rpr_entityid)", r
->rpr_entityid
);
8845 case VKI_REP_PROTOCOL_ITER_READ_VALUE
:
8847 struct vki_rep_protocol_iter_read_value
*r
=
8848 (struct vki_rep_protocol_iter_read_value
*) p
;
8849 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8850 "iter_read_value->rpr_iterid)", r
->rpr_iterid
);
8851 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8852 "iter_read_value->rpr_sequence)", r
->rpr_sequence
);
8855 case VKI_REP_PROTOCOL_ITER_RESET
:
8856 case VKI_REP_PROTOCOL_ITER_SETUP
:
8857 case VKI_REP_PROTOCOL_ITER_TEARDOWN
:
8859 struct vki_rep_protocol_iter_request
*r
=
8860 (struct vki_rep_protocol_iter_request
*) p
;
8861 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8862 "iter_request->rpr_iterid)", r
->rpr_iterid
);
8865 case VKI_REP_PROTOCOL_ITER_START
:
8867 struct vki_rep_protocol_iter_start
*r
=
8868 (struct vki_rep_protocol_iter_start
*) p
;
8869 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8870 "iter_start->rpr_iterid)", r
->rpr_iterid
);
8871 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8872 "iter_start->rpr_entity)", r
->rpr_entity
);
8873 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8874 "iter_start->rpr_itertype)", r
->rpr_itertype
);
8875 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8876 "iter_start->rpr_flags)", r
->rpr_flags
);
8877 PRE_MEM_RASCIIZ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8878 "iter_start->rpr_pattern)", (Addr
) r
->rpr_pattern
);
8881 case VKI_REP_PROTOCOL_PROPERTY_GET_TYPE
:
8882 case VKI_REP_PROTOCOL_PROPERTY_GET_VALUE
:
8884 struct vki_rep_protocol_property_request
*r
=
8885 (struct vki_rep_protocol_property_request
*) p
;
8886 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
8887 "property_request->rpr_entityid)", r
->rpr_entityid
);
8891 VG_(unimplemented
)("Door wrapper of " VKI_REPOSITORY_DOOR_NAME
8892 " where rpr_request=%#x.", p
->rpr_request
);
8899 /* Handles repository door protocol response over client door fd. */
8900 static void repository_door_post_mem_door_call_hook(ThreadId tid
, Int fd
,
8901 void *rbuf
, SizeT rsize
)
8903 /* :TODO: Ideally we would need to match the response type with the
8904 previous request because response itself does not contain any
8905 type identification.
8906 For now simply make defined whole response buffer. */
8907 POST_MEM_WRITE((Addr
) rbuf
, rsize
);
8910 /* Pre-syscall checks for params->data_ptr contents of a door_call(). */
8911 static void door_call_pre_mem_params_data(ThreadId tid
, Int fd
,
8912 void *data_ptr
, SizeT data_size
)
8914 const HChar
*pathname
;
8916 /* Get pathname of the door file descriptor, if not already done.
8917 Needed to dissect door service on the pathname below. */
8918 if (!VG_(clo_track_fds
) && !ML_(fd_recorded
)(fd
)) {
8919 ML_(record_fd_open_named
)(tid
, fd
);
8921 pathname
= ML_(find_fd_recorded_by_fd
)(fd
);
8923 /* Debug-only printing. */
8925 VG_(printf
)("PRE(door_call) with fd=%d and filename=%s\n",
8929 if (VG_STREQ(pathname
, VKI__PATH_KCFD_DOOR
)) {
8930 vki_kcf_door_arg_t
*p
= (vki_kcf_door_arg_t
*) data_ptr
;
8932 PRE_FIELD_READ("door_call(\"" VKI__PATH_KCFD_DOOR
"\", "
8933 "kcf_door_arg_t->da_version)", p
->da_version
);
8934 PRE_FIELD_READ("door_call(\"" VKI__PATH_KCFD_DOOR
"\", "
8935 "kcf_door_arg_t->da_iskernel)", p
->da_iskernel
);
8936 PRE_MEM_RASCIIZ("door_call(\"" VKI__PATH_KCFD_DOOR
"\", "
8937 "kcf_door_arg_t->da_u.filename)",
8938 (Addr
) p
->vki_da_u
.filename
);
8939 } else if (VG_STREQ(pathname
, VKI_NAME_SERVICE_DOOR
)) {
8940 vki_nss_pheader_t
*p
= (vki_nss_pheader_t
*) data_ptr
;
8942 PRE_FIELD_READ("door_call(\"" VKI_NAME_SERVICE_DOOR
"\", "
8943 "nss_pheader->nsc_callnumber)", p
->nsc_callnumber
);
8944 if (ML_(safe_to_deref
)(p
, sizeof(vki_nss_pheader_t
))) {
8945 if ((p
->nsc_callnumber
& VKI_NSCDV2CATMASK
) == VKI_NSCD_CALLCAT_APP
) {
8946 /* request from an application towards nscd */
8947 PRE_FIELD_READ("door_call(\"" VKI_NAME_SERVICE_DOOR
"\", "
8948 "nss_pheader->p_version)", p
->p_version
);
8949 PRE_FIELD_READ("door_call(\"" VKI_NAME_SERVICE_DOOR
"\", "
8950 "nss_pheader->dbd_off)", p
->dbd_off
);
8951 PRE_FIELD_READ("door_call(\"" VKI_NAME_SERVICE_DOOR
"\", "
8952 "nss_pheader->dbd_len)", p
->dbd_len
);
8953 PRE_FIELD_READ("door_call(\"" VKI_NAME_SERVICE_DOOR
"\", "
8954 "nss_pheader->key_off)", p
->key_off
);
8955 PRE_FIELD_READ("door_call(\"" VKI_NAME_SERVICE_DOOR
"\", "
8956 "nss_pheader->key_len)", p
->key_len
);
8957 PRE_FIELD_READ("door_call(\"" VKI_NAME_SERVICE_DOOR
"\", "
8958 "nss_pheader->data_off)", p
->data_off
);
8959 PRE_FIELD_READ("door_call(\"" VKI_NAME_SERVICE_DOOR
"\", "
8960 "nss_pheader->data_len)", p
->data_len
);
8961 /* Fields ext_off and ext_len are set only sporadically. */
8962 PRE_FIELD_READ("door_call(\"" VKI_NAME_SERVICE_DOOR
"\", "
8963 "nss_pheader->pbufsiz)", p
->pbufsiz
);
8964 PRE_MEM_WRITE("door_call(\"" VKI_NAME_SERVICE_DOOR
"\", pbuf)",
8965 (Addr
) p
, p
->pbufsiz
);
8967 if (p
->dbd_len
> 0) {
8969 = (vki_nss_dbd_t
*) ((HChar
*) p
+ p
->dbd_off
);
8971 PRE_MEM_READ("door_call(\"" VKI_NAME_SERVICE_DOOR
8972 "\", nss_dbd)", (Addr
) dbd
, sizeof(vki_nss_dbd_t
));
8973 if (ML_(safe_to_deref
)(dbd
, sizeof(vki_nss_dbd_t
))) {
8974 if (dbd
->o_name
!= 0)
8975 PRE_MEM_RASCIIZ("door_call(\"" VKI_NAME_SERVICE_DOOR
8976 "\", nss_dbd->o_name)", (Addr
) ((HChar
*) p
8977 + p
->dbd_off
+ dbd
->o_name
));
8978 if (dbd
->o_config_name
!= 0)
8979 PRE_MEM_RASCIIZ("door_call(\"" VKI_NAME_SERVICE_DOOR
8980 "\", nss_dbd->o_config_name)",
8981 (Addr
) ((HChar
*) p
+ p
->dbd_off
8982 + dbd
->o_config_name
));
8983 if (dbd
->o_default_config
!= 0)
8984 PRE_MEM_RASCIIZ("door_call(\"" VKI_NAME_SERVICE_DOOR
8985 "\", nss_dbd->o_default_config)",
8986 (Addr
) ((HChar
*) p
+ p
->dbd_off
+
8987 dbd
->o_default_config
));
8991 PRE_MEM_READ("door_call(\"" VKI_NAME_SERVICE_DOOR
"\", nss->key)",
8992 (Addr
) ((HChar
*) p
+ p
->key_off
), p
->key_len
);
8994 /* request from a child nscd towards parent nscd */
8995 VG_(unimplemented
)("Door wrapper of child/parent nscd.");
8998 } else if (VG_STREQ(pathname
, VKI_REPOSITORY_DOOR_NAME
)) {
8999 vki_repository_door_request_t
*p
=
9000 (vki_repository_door_request_t
*) data_ptr
;
9002 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
9003 "request->rdr_version)", p
->rdr_version
);
9004 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
9005 "request->rdr_request)", p
->rdr_request
);
9006 if (ML_(safe_to_deref
)(p
, sizeof(vki_repository_door_request_t
))) {
9007 if (p
->rdr_version
== VKI_REPOSITORY_DOOR_VERSION
) {
9008 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
9009 "request->rdr_flags)", p
->rdr_flags
);
9010 PRE_FIELD_READ("door_call(\"" VKI_REPOSITORY_DOOR_NAME
"\", "
9011 "request->rdr_debug)", p
->rdr_debug
);
9013 VG_(unimplemented
)("Door wrapper of " VKI_REPOSITORY_DOOR_NAME
9014 " where version=%u.", p
->rdr_version
);
9018 const OpenDoor
*open_door
= door_find_by_fd(fd
);
9019 if ((open_door
!= NULL
) && (open_door
->pre_mem_hook
!= NULL
)) {
9020 open_door
->pre_mem_hook(tid
, fd
, data_ptr
, data_size
);
9022 if (SimHintiS(SimHint_lax_doors
, VG_(clo_sim_hints
))) {
9024 * Be very lax about door syscall handling over unrecognized
9025 * door file descriptors. Does not require that full buffer
9026 * is initialized when writing. Without this, programs using
9027 * libdoor(3LIB) functionality with completely proprietary
9028 * semantics may report large number of false positives.
9031 static Int moans
= 3;
9033 /* generic default */
9034 if (moans
> 0 && !VG_(clo_xml
)) {
9037 "Warning: noted and generically handled door call\n"
9038 " on file descriptor %d (filename: %s).\n"
9039 " This could cause spurious value errors to appear.\n"
9040 " See README_MISSING_SYSCALL_OR_IOCTL for guidance on writing a proper wrapper.\n"
9041 " Alternatively you may find '--sim-hints=lax-doors' option useful.\n",
9044 PRE_MEM_READ("door_call(params->data_ptr)",
9045 (Addr
) data_ptr
, data_size
);
9051 /* Post-syscall checks for params->rbuf contents of a door_call(). */
9052 static void door_call_post_mem_params_rbuf(ThreadId tid
, Int fd
,
9053 void *rbuf
, SizeT rsize
,
9054 const vki_door_desc_t
*desc_ptr
,
9055 vki_uint_t desc_num
)
9057 const HChar
*pathname
= ML_(find_fd_recorded_by_fd
)(fd
);
9059 /* Debug-only printing. */
9061 VG_(printf
)("POST(door_call) with fd=%d and filename=%s\n",
9065 if (VG_STREQ(pathname
, VKI__PATH_KCFD_DOOR
)) {
9066 vki_kcf_door_arg_t
*p
= (vki_kcf_door_arg_t
*) rbuf
;
9068 POST_FIELD_WRITE(p
->da_version
);
9069 POST_FIELD_WRITE(p
->vki_da_u
.result
.status
);
9070 POST_MEM_WRITE((Addr
) p
->vki_da_u
.result
.signature
,
9071 p
->vki_da_u
.result
.siglen
);
9072 } else if (VG_STREQ(pathname
, VKI_NAME_SERVICE_DOOR
)) {
9073 vki_nss_pheader_t
*p
= (vki_nss_pheader_t
*) rbuf
;
9075 POST_FIELD_WRITE(p
->nsc_callnumber
);
9076 if (ML_(safe_to_deref
)(p
, sizeof(vki_nss_pheader_t
))) {
9077 if ((p
->nsc_callnumber
& VKI_NSCDV2CATMASK
) == VKI_NSCD_CALLCAT_APP
) {
9078 /* response from nscd to an application */
9079 POST_FIELD_WRITE(p
->p_status
);
9080 POST_FIELD_WRITE(p
->p_errno
);
9081 POST_FIELD_WRITE(p
->p_herrno
);
9082 POST_FIELD_WRITE(p
->dbd_off
);
9083 POST_FIELD_WRITE(p
->dbd_len
);
9084 POST_FIELD_WRITE(p
->key_off
);
9085 POST_FIELD_WRITE(p
->key_len
);
9086 POST_FIELD_WRITE(p
->data_off
);
9087 POST_FIELD_WRITE(p
->data_len
);
9088 POST_FIELD_WRITE(p
->ext_off
);
9089 POST_FIELD_WRITE(p
->ext_len
);
9090 POST_FIELD_WRITE(p
->pbufsiz
);
9092 if (p
->pbufsiz
<= rsize
) {
9093 if (p
->dbd_off
< p
->pbufsiz
- sizeof(vki_nss_pheader_t
)) {
9094 SizeT len
= MIN(p
->dbd_len
, p
->pbufsiz
- p
->dbd_off
);
9095 POST_MEM_WRITE((Addr
) ((HChar
*) p
+ p
->dbd_off
), len
);
9098 if (p
->key_off
< p
->pbufsiz
- sizeof(vki_nss_pheader_t
)) {
9099 SizeT len
= MIN(p
->key_len
, p
->pbufsiz
- p
->key_off
);
9100 POST_MEM_WRITE((Addr
) ((HChar
*) p
+ p
->key_off
), len
);
9103 if (p
->data_off
< p
->pbufsiz
- sizeof(vki_nss_pheader_t
)) {
9104 SizeT len
= MIN(p
->data_len
, p
->pbufsiz
- p
->data_off
);
9105 POST_MEM_WRITE((Addr
) ((HChar
*) p
+ p
->data_off
), len
);
9108 if (p
->ext_off
< p
->pbufsiz
- sizeof(vki_nss_pheader_t
)) {
9109 SizeT len
= MIN(p
->ext_len
, p
->pbufsiz
- p
->ext_off
);
9110 POST_MEM_WRITE((Addr
) ((HChar
*) p
+ p
->ext_off
), len
);
9114 /* response from parent nscd to a child nscd */
9115 VG_(unimplemented
)("Door wrapper of child/parent nscd.");
9118 } else if (VG_STREQ(pathname
, VKI_REPOSITORY_DOOR_NAME
)) {
9119 POST_FIELD_WRITE(((vki_repository_door_response_t
*) rbuf
)->rdr_status
);
9120 /* A new client door fd is passed over the global repository door. */
9121 if ((desc_ptr
!= NULL
) && (desc_num
> 0)) {
9122 if (desc_ptr
[0].d_attributes
& DOOR_DESCRIPTOR
) {
9123 door_record_client(tid
, desc_ptr
[0].d_data
.d_desc
.d_descriptor
,
9124 repository_door_pre_mem_door_call_hook
,
9125 repository_door_post_mem_door_call_hook
);
9129 const OpenDoor
*open_door
= door_find_by_fd(fd
);
9130 if ((open_door
!= NULL
) && (open_door
->post_mem_hook
!= NULL
)) {
9131 open_door
->post_mem_hook(tid
, fd
, rbuf
, rsize
);
9133 /* generic default */
9134 POST_MEM_WRITE((Addr
) rbuf
, rsize
);
9139 /* Pre-syscall checks for data_ptr contents in a door_return(). */
9140 static void door_return_pre_mem_data(ThreadId tid
, Addr server_procedure
,
9141 void *data_ptr
, SizeT data_size
)
9143 if ((data_size
== 0) || (server_procedure
== 0)) {
9144 /* There is nothing to check. This usually happens during thread's
9145 first call to door_return(). */
9149 /* Get pathname of the door file descriptor based on the
9150 door server procedure (that's all we have).
9151 Needed to dissect door service on the pathname below. */
9152 const OpenDoor
*open_door
= door_find_by_proc(server_procedure
);
9153 const HChar
*pathname
= (open_door
!= NULL
) ? open_door
->pathname
: NULL
;
9154 Int fd
= (open_door
!= NULL
) ? open_door
->fd
: -1;
9156 /* Debug-only printing. */
9158 VG_(printf
)("PRE(door_return) with fd=%d and filename=%s "
9159 "(nr_doors_recorded=%u)\n",
9160 fd
, pathname
, nr_doors_recorded
);
9163 if (VG_STREQ(pathname
, VKI__PATH_KCFD_DOOR
)) {
9164 vki_kcf_door_arg_t
*p
= (vki_kcf_door_arg_t
*) data_ptr
;
9166 PRE_FIELD_READ("door_return(\"" VKI__PATH_KCFD_DOOR
"\", "
9167 "kcf_door_arg_t->da_version)", p
->da_version
);
9168 PRE_FIELD_READ("door_return(\"" VKI__PATH_KCFD_DOOR
"\", "
9169 "kcf_door_arg_t->da_u.result.status)",
9170 p
->vki_da_u
.result
.status
);
9171 PRE_MEM_READ("door_return(\"" VKI__PATH_KCFD_DOOR
"\", "
9172 "kcf_door_arg_t->da_u.result.signature)",
9173 (Addr
) p
->vki_da_u
.result
.signature
,
9174 p
->vki_da_u
.result
.siglen
);
9175 } else if (VG_STREQ(pathname
, VKI_NAME_SERVICE_DOOR
)) {
9176 vki_nss_pheader_t
*p
= (vki_nss_pheader_t
*) data_ptr
;
9178 PRE_FIELD_READ("door_return(\"" VKI_NAME_SERVICE_DOOR
"\", "
9179 "nss_pheader->nsc_callnumber)", p
->nsc_callnumber
);
9180 if (ML_(safe_to_deref
)(p
, sizeof(vki_nss_pheader_t
))) {
9181 if ((p
->nsc_callnumber
& VKI_NSCDV2CATMASK
) == VKI_NSCD_CALLCAT_APP
) {
9182 /* response from nscd to an application */
9183 PRE_FIELD_READ("door_return(\"" VKI_NAME_SERVICE_DOOR
"\", "
9184 "nss_pheader->p_status)", p
->p_status
);
9185 PRE_FIELD_READ("door_return(\"" VKI_NAME_SERVICE_DOOR
"\", "
9186 "nss_pheader->p_errno)", p
->p_errno
);
9187 PRE_FIELD_READ("door_return(\"" VKI_NAME_SERVICE_DOOR
"\", "
9188 "nss_pheader->p_herrno)", p
->p_herrno
);
9189 PRE_FIELD_READ("door_return(\"" VKI_NAME_SERVICE_DOOR
"\", "
9190 "nss_pheader->dbd_off)", p
->dbd_off
);
9191 PRE_FIELD_READ("door_return(\"" VKI_NAME_SERVICE_DOOR
"\", "
9192 "nss_pheader->dbd_len)", p
->dbd_len
);
9193 PRE_FIELD_READ("door_return(\"" VKI_NAME_SERVICE_DOOR
"\", "
9194 "nss_pheader->data_off)", p
->data_off
);
9195 PRE_FIELD_READ("door_return(\"" VKI_NAME_SERVICE_DOOR
"\", "
9196 "nss_pheader->data_len)", p
->data_len
);
9197 PRE_FIELD_READ("door_return(\"" VKI_NAME_SERVICE_DOOR
"\", "
9198 "nss_pheader->ext_off)", p
->ext_off
);
9199 PRE_FIELD_READ("door_return(\"" VKI_NAME_SERVICE_DOOR
"\", "
9200 "nss_pheader->ext_len)", p
->ext_len
);
9201 PRE_FIELD_READ("door_return(\"" VKI_NAME_SERVICE_DOOR
"\", "
9202 "nss_pheader->pbufsiz)", p
->pbufsiz
);
9203 PRE_MEM_WRITE("door_return(\"" VKI_NAME_SERVICE_DOOR
"\", pbuf)",
9204 (Addr
) p
, p
->pbufsiz
);
9205 PRE_MEM_READ("door_return(\"" VKI_NAME_SERVICE_DOOR
9207 (Addr
) ((HChar
*) p
+ p
->data_off
), p
->data_len
);
9208 PRE_MEM_READ("door_return(\"" VKI_NAME_SERVICE_DOOR
9210 (Addr
) ((HChar
*) p
+ p
->ext_off
), p
->ext_len
);
9212 /* response from parent nscd to a child nscd */
9213 VG_(unimplemented
)("Door wrapper of child/parent nscd.");
9216 } else if (VG_STREQ(pathname
, VKI_REPOSITORY_DOOR_NAME
)) {
9217 VG_(unimplemented
)("Door wrapper of " VKI_REPOSITORY_DOOR_NAME
);
9219 if (SimHintiS(SimHint_lax_doors
, VG_(clo_sim_hints
))) {
9221 * Be very lax about door syscall handling over unrecognized
9222 * door file descriptors. Does not require that full buffer
9223 * is initialized when writing. Without this, programs using
9224 * libdoor(3LIB) functionality with completely proprietary
9225 * semantics may report large number of false positives.
9228 static Int moans
= 3;
9230 /* generic default */
9231 if (moans
> 0 && !VG_(clo_xml
)) {
9234 "Warning: noted and generically handled door return\n"
9235 " on file descriptor %d (filename: %s).\n"
9236 " This could cause spurious value errors to appear.\n"
9237 " See README_MISSING_SYSCALL_OR_IOCTL for guidance on writing a proper wrapper.\n"
9238 " Alternatively you may find '--sim-hints=lax-doors' option useful.\n",
9241 PRE_MEM_READ("door_return(data_ptr)",
9242 (Addr
) data_ptr
, data_size
);
9247 /* Post-syscall checks for data_ptr contents in a door_return(). */
9248 static void door_return_post_mem_data(ThreadId tid
, Addr server_procedure
,
9249 void *data_ptr
, SizeT data_size
)
9251 const OpenDoor
*open_door
= door_find_by_proc(server_procedure
);
9252 const HChar
*pathname
= (open_door
!= NULL
) ? open_door
->pathname
: NULL
;
9254 /* Debug-only printing. */
9256 Int fd
= (open_door
!= NULL
) ? open_door
->fd
: -1;
9257 VG_(printf
)("POST(door_return) with fd=%d and filename=%s "
9258 "(nr_doors_recorded=%u)\n",
9259 fd
, pathname
, nr_doors_recorded
);
9262 if (VG_STREQ(pathname
, VKI__PATH_KCFD_DOOR
)) {
9263 vki_kcf_door_arg_t
*p
= (vki_kcf_door_arg_t
*) data_ptr
;
9265 POST_FIELD_WRITE(p
->da_version
);
9266 POST_FIELD_WRITE(p
->da_iskernel
);
9267 POST_MEM_WRITE((Addr
) p
->vki_da_u
.filename
,
9268 VG_(strlen
)(p
->vki_da_u
.filename
) + 1);
9269 } else if (VG_STREQ(pathname
, VKI_NAME_SERVICE_DOOR
)) {
9270 vki_nss_pheader_t
*p
= (vki_nss_pheader_t
*) data_ptr
;
9272 POST_FIELD_WRITE(p
->nsc_callnumber
);
9273 if (ML_(safe_to_deref
)(p
, sizeof(vki_nss_pheader_t
))) {
9274 if ((p
->nsc_callnumber
& VKI_NSCDV2CATMASK
) == VKI_NSCD_CALLCAT_APP
) {
9275 /* request from an application towards nscd */
9276 POST_FIELD_WRITE(p
->p_version
);
9277 POST_FIELD_WRITE(p
->dbd_off
);
9278 POST_FIELD_WRITE(p
->dbd_len
);
9279 POST_FIELD_WRITE(p
->key_off
);
9280 POST_FIELD_WRITE(p
->key_len
);
9281 POST_FIELD_WRITE(p
->data_off
);
9282 POST_FIELD_WRITE(p
->data_len
);
9283 POST_FIELD_WRITE(p
->ext_off
);
9284 POST_FIELD_WRITE(p
->ext_len
);
9285 POST_FIELD_WRITE(p
->pbufsiz
);
9287 if (p
->dbd_len
> 0) {
9289 = (vki_nss_dbd_t
*) ((HChar
*) p
+ p
->dbd_off
);
9291 POST_MEM_WRITE((Addr
) dbd
, sizeof(vki_nss_dbd_t
));
9292 if (ML_(safe_to_deref
)(dbd
, sizeof(vki_nss_dbd_t
))) {
9293 SizeT headers_size
= sizeof(vki_nss_pheader_t
)
9294 + sizeof(vki_nss_dbd_t
);
9296 if (dbd
->o_name
!= 0) {
9297 HChar
*name
= (HChar
*) p
+ p
->dbd_off
+ dbd
->o_name
;
9298 SizeT name_len
= VG_(strlen
)(name
) + 1;
9299 if (name_len
<= data_size
- headers_size
)
9300 POST_MEM_WRITE((Addr
) name
, name_len
);
9302 if (dbd
->o_config_name
!= 0) {
9303 HChar
*name
= (HChar
*) p
+ p
->dbd_off
+ dbd
->o_config_name
;
9304 SizeT name_len
= VG_(strlen
)(name
) + 1;
9305 if (name_len
<= data_size
- headers_size
)
9306 POST_MEM_WRITE((Addr
) name
, name_len
);
9308 if (dbd
->o_default_config
!= 0) {
9309 HChar
*name
= (HChar
*) p
+ p
->dbd_off
9310 + dbd
->o_default_config
;
9311 SizeT name_len
= VG_(strlen
)(name
) + 1;
9312 if (name_len
<= data_size
- headers_size
)
9313 POST_MEM_WRITE((Addr
) name
, name_len
);
9318 if (p
->key_len
<= data_size
- p
->key_off
)
9319 POST_MEM_WRITE((Addr
) ((HChar
*) p
+ p
->key_off
), p
->key_len
);
9321 /* request from a child nscd towards parent nscd */
9322 VG_(unimplemented
)("Door wrapper of child/parent nscd.");
9325 } else if (VG_STREQ(pathname
, VKI_REPOSITORY_DOOR_NAME
)) {
9326 VG_(unimplemented
)("Door wrapper of " VKI_REPOSITORY_DOOR_NAME
);
9328 /* generic default */
9329 POST_MEM_WRITE((Addr
) data_ptr
, data_size
);
9335 /* int doorfs(long arg1, long arg2, long arg3, long arg4, long arg5,
9337 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
9338 *flags
|= SfMayBlock
| SfPostOnFail
;
9340 PRINT("sys_door ( %#lx, %#lx, %#lx, %#lx, %#lx, %ld )", ARG1
, ARG2
, ARG3
,
9343 /* Macro PRE_REG_READ6 cannot be simply used because not all ARGs are used
9344 in door() syscall variants. Note that ARG6 (subcode) is used always. */
9345 #define PRE_REG_READ_SIXTH_ONLY \
9346 if (VG_(tdict).track_pre_reg_read) { \
9347 PRA6("door", long, subcode); \
9350 switch (ARG6
/*subcode*/) {
9351 case VKI_DOOR_CREATE
:
9352 PRE_REG_READ3(long, "door", long, arg1
, long, arg2
, long, arg3
);
9353 PRE_REG_READ_SIXTH_ONLY
;
9354 /* Note: the first argument to DOOR_CREATE is a server procedure.
9355 This could lead to a problem if the kernel tries to force the
9356 execution of this procedure, similarly to how signal handlers are
9357 executed. Fortunately, the kernel never does that (for user-space
9358 server procedures). The procedure is always executed by the standard
9361 case VKI_DOOR_REVOKE
:
9362 PRE_REG_READ1(long, "door", long, arg1
);
9363 PRE_REG_READ_SIXTH_ONLY
;
9364 if (!ML_(fd_allowed
)(ARG1
, "door_revoke", tid
, False
))
9365 SET_STATUS_Failure(VKI_EBADF
);
9368 PRE_REG_READ2(long, "door", long, arg1
, long, arg2
);
9369 PRE_REG_READ_SIXTH_ONLY
;
9370 PRE_MEM_WRITE("door_info(info)", ARG2
, sizeof(vki_door_info_t
));
9374 PRE_REG_READ2(long, "door", long, arg1
, long, arg2
);
9375 PRE_REG_READ_SIXTH_ONLY
;
9378 vki_door_arg_t
*params
= (vki_door_arg_t
*)ARG2
;
9380 if (!ML_(fd_allowed
)(ARG1
, "door_call", tid
, False
))
9383 PRE_FIELD_READ("door_call(params->data_ptr)", params
->data_ptr
);
9384 PRE_FIELD_READ("door_call(params->data_size)", params
->data_size
);
9385 PRE_FIELD_READ("door_call(params->desc_ptr)", params
->desc_ptr
);
9386 PRE_FIELD_READ("door_call(params->desc_num)", params
->desc_num
);
9387 PRE_FIELD_READ("door_call(params->rbuf)", params
->rbuf
);
9388 PRE_FIELD_READ("door_call(params->rsize)", params
->rsize
);
9390 if (ML_(safe_to_deref
)(params
, sizeof(*params
))) {
9391 if (params
->data_ptr
)
9392 door_call_pre_mem_params_data(tid
, ARG1
, params
->data_ptr
,
9395 if (params
->desc_ptr
) {
9396 SizeT desc_size
= params
->desc_num
* sizeof(*params
->desc_ptr
);
9397 PRE_MEM_READ("door_call(params->desc_ptr)",
9398 (Addr
)params
->desc_ptr
, desc_size
);
9400 /* Do not record information about closed fds if we are going
9401 to fail the syscall and so no fds will be closed. */
9403 (ML_(safe_to_deref
)(params
->desc_ptr
, desc_size
))) {
9404 rval
= pre_check_and_close_fds(tid
, "door_call",
9411 PRE_MEM_WRITE("door_call(params->rbuf)", (Addr
)params
->rbuf
,
9416 SET_STATUS_Failure(rval
);
9420 PRE_REG_READ1(long, "door", long, arg1
);
9421 PRE_REG_READ_SIXTH_ONLY
;
9422 VG_(unimplemented
)("DOOR_BIND");
9424 case VKI_DOOR_UNBIND
:
9425 PRE_REG_READ0(long, "door");
9426 PRE_REG_READ_SIXTH_ONLY
;
9427 VG_(unimplemented
)("DOOR_UNBIND");
9429 case VKI_DOOR_UNREFSYS
:
9430 PRE_REG_READ0(long, "door");
9431 PRE_REG_READ_SIXTH_ONLY
;
9432 VG_(unimplemented
)("DOOR_UNREFSYS");
9434 case VKI_DOOR_UCRED
:
9435 PRE_REG_READ1(long, "door", long, arg1
);
9436 PRE_REG_READ_SIXTH_ONLY
;
9437 VG_(unimplemented
)("DOOR_UCRED");
9439 case VKI_DOOR_RETURN
:
9440 PRE_REG_READ6(long, "door", long, arg1
, long, arg2
, long, arg3
,
9441 long, arg4
, long, arg5
, long, subcode
);
9443 /* Register %esp/%rsp is read and modified by the syscall. */
9444 VG_TRACK(pre_reg_read
, Vg_CoreSysCall
, tid
, "door_return(sp)",
9445 VG_O_STACK_PTR
, sizeof(UWord
));
9446 /* Register %ebp/%rbp is not really read by the syscall, it is only
9447 written by it, but it is hard to determine when it is written so we
9448 make sure it is always valid prior to making the syscall. */
9449 VG_TRACK(pre_reg_read
, Vg_CoreSysCall
, tid
, "door_return(bp)",
9450 VG_O_FRAME_PTR
, sizeof(UWord
));
9452 door_return_pre_mem_data(tid
, tst
->os_state
.door_return_procedure
,
9453 (void *) ARG1
, ARG2
);
9455 /* Do not tell the tool where the syscall is going to write the
9456 resulting data. It is necessary to skip this check because the data
9457 area starting at ARG4-ARG5 (of length ARG5) is usually on a client
9458 thread stack below the stack pointer and therefore it can be marked
9459 by a tool (for example, Memcheck) as inaccessible. It is ok to skip
9460 this check in this case because if there is something wrong with the
9461 data area then the syscall will fail or the error will be handled by
9462 POST_MEM_WRITE() in the post wrapper. */
9463 /*PRE_MEM_WRITE("door_return(sp)", ARG4 - ARG5, ARG5);*/
9466 vki_door_return_desc_t
*desc_env
= (vki_door_return_desc_t
*)ARG3
;
9468 PRE_MEM_READ("door_return(desc_env)", ARG3
,
9469 sizeof(vki_door_return_desc_t
));
9471 if (ML_(safe_to_deref
)(desc_env
, sizeof(*desc_env
)) &&
9472 desc_env
->desc_ptr
) {
9475 PRE_MEM_READ("door_return(desc_env->desc_ptr)",
9476 (Addr
)desc_env
->desc_ptr
,
9477 desc_env
->desc_num
* sizeof(*desc_env
->desc_ptr
));
9479 rval
= pre_check_and_close_fds(tid
, "door_return",
9481 desc_env
->desc_num
);
9483 SET_STATUS_Failure(rval
);
9486 tst
->os_state
.in_door_return
= True
;
9487 tst
->os_state
.door_return_procedure
= 0;
9489 case VKI_DOOR_GETPARAM
:
9490 PRE_REG_READ3(long, "door", long, arg1
, long, arg2
, long, arg3
);
9491 PRE_REG_READ_SIXTH_ONLY
;
9492 VG_(unimplemented
)("DOOR_GETPARAM");
9494 case VKI_DOOR_SETPARAM
:
9495 PRE_REG_READ3(long, "door", long, arg1
, long, arg2
, long, arg3
);
9496 PRE_REG_READ_SIXTH_ONLY
;
9497 if (!ML_(fd_allowed
)(ARG1
, "door_setparam", tid
, False
))
9498 SET_STATUS_Failure(VKI_EBADF
);
9501 VG_(unimplemented
)("Syswrap of the door call with subcode %ld.", SARG6
);
9506 #undef PRE_REG_READ_SIXTH_ONLY
9511 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
9513 vg_assert(SUCCESS
|| FAILURE
);
9515 /* Alter the tst->os_state.in_door_return flag. */
9516 if (ARG6
== VKI_DOOR_RETURN
) {
9517 vg_assert(tst
->os_state
.in_door_return
== True
);
9518 tst
->os_state
.in_door_return
= False
;
9520 /* Inform the tool that %esp/%rsp and %ebp/%rbp were (potentially)
9522 VG_TRACK(post_reg_write
, Vg_CoreSysCall
, tid
, VG_O_STACK_PTR
,
9524 VG_TRACK(post_reg_write
, Vg_CoreSysCall
, tid
, VG_O_FRAME_PTR
,
9528 vg_assert(tst
->os_state
.in_door_return
== False
);
9531 if (VG_(clo_track_fds
)) {
9532 /* See the discussion in pre_check_and_close_fds() to understand this
9535 switch (ARG6
/*subcode*/) {
9537 if (ERR
== VKI_EFAULT
|| ERR
== VKI_EBADF
)
9540 case VKI_DOOR_RETURN
:
9541 if (ERR
== VKI_EFAULT
|| ERR
== VKI_EINVAL
)
9548 VG_(message
)(Vg_UserMsg
, "The door call failed with an "
9549 "unexpected error and information "
9550 "about open file descriptors can be "
9551 "now imprecise.\n");
9559 switch (ARG6
/*subcode*/) {
9560 case VKI_DOOR_CREATE
:
9561 door_record_server(tid
, ARG1
, RES
);
9563 case VKI_DOOR_REVOKE
:
9564 door_record_revoke(tid
, ARG1
);
9565 if (VG_(clo_track_fds
))
9566 ML_(record_fd_close
)(ARG1
);
9569 POST_MEM_WRITE(ARG2
, sizeof(vki_door_info_t
));
9573 /* Note that all returned values are stored in the rbuf, i.e.
9574 data_ptr and desc_ptr points into this buffer. */
9575 vki_door_arg_t
*params
= (vki_door_arg_t
*)ARG2
;
9578 Addr addr
= (Addr
)params
->rbuf
;
9579 if (!VG_(am_find_anon_segment
)(addr
)) {
9580 /* This segment is new and was mapped by the kernel. */
9584 prot
= VKI_PROT_READ
| VKI_PROT_WRITE
| VKI_PROT_EXEC
;
9585 flags
= VKI_MAP_ANONYMOUS
;
9586 size
= VG_PGROUNDUP(params
->rsize
);
9588 VG_(debugLog
)(1, "syswrap-solaris", "POST(sys_door), "
9589 "new segment: vaddr=%#lx, size=%#lx, "
9590 "prot=%#x, flags=%#x, fd=%lu, offset=%#llx\n",
9591 addr
, size
, prot
, flags
, (UWord
)-1, (ULong
)0);
9593 ML_(notify_core_and_tool_of_mmap
)(addr
, size
, prot
, flags
,
9596 /* Note: We don't notify the debuginfo reader about this
9597 mapping because there is no debug information stored in
9601 door_call_post_mem_params_rbuf(tid
, ARG1
, (void *) addr
,
9602 params
->rsize
, params
->desc_ptr
,
9606 if (params
->desc_ptr
) {
9607 POST_MEM_WRITE((Addr
)params
->desc_ptr
,
9608 params
->desc_num
* sizeof(vki_door_desc_t
));
9609 post_record_fds(tid
, "door_call", params
->desc_ptr
,
9616 case VKI_DOOR_UNBIND
:
9618 case VKI_DOOR_UNREFSYS
:
9620 case VKI_DOOR_UCRED
:
9622 case VKI_DOOR_RETURN
:
9624 struct vki_door_results
*results
9625 = (struct vki_door_results
*)VG_(get_SP
)(tid
);
9627 tst
->os_state
.door_return_procedure
= (Addr
)results
->pc
;
9629 POST_MEM_WRITE((Addr
)results
, sizeof(*results
));
9630 if (results
->data_ptr
)
9631 door_return_post_mem_data(tid
,
9632 tst
->os_state
.door_return_procedure
,
9634 results
->data_size
);
9635 if (results
->desc_ptr
) {
9636 POST_MEM_WRITE((Addr
)results
->desc_ptr
,
9637 results
->desc_num
* sizeof(vki_door_desc_t
));
9638 post_record_fds(tid
, "door_return", results
->desc_ptr
,
9642 POST_MEM_WRITE((Addr
)results
->door_info
,
9643 sizeof(*results
->door_info
));
9646 case VKI_DOOR_GETPARAM
:
9648 case VKI_DOOR_SETPARAM
:
9658 /* caddr_t schedctl(void); */
9659 /* This syscall returns an address that points to struct sc_shared.
9660 This per-thread structure is used as an interface between the libc and
9662 PRINT("sys_schedctl ( )");
9663 PRE_REG_READ0(long, "schedctl");
9669 ThreadState
*tst
= VG_(get_ThreadState
)(tid
);
9672 vg_assert((tst
->os_state
.schedctl_data
== 0) ||
9673 (tst
->os_state
.schedctl_data
== a
));
9674 tst
->os_state
.schedctl_data
= a
;
9676 /* Returned address points to a block in a mapped page. */
9677 if (!VG_(am_find_anon_segment
)(a
)) {
9678 Addr page
= VG_PGROUNDDN(a
);
9679 UInt prot
= VKI_PROT_READ
| VKI_PROT_WRITE
;
9680 # if defined(SOLARIS_SCHEDCTL_PAGE_EXEC)
9681 prot
|= VKI_PROT_EXEC
;
9682 # endif /* SOLARIS_SCHEDCTL_PAGE_EXEC */
9683 UInt flags
= VKI_MAP_ANONYMOUS
;
9684 /* The kernel always allocates one page for the sc_shared struct. */
9685 SizeT size
= VKI_PAGE_SIZE
;
9687 VG_(debugLog
)(1, "syswrap-solaris", "POST(sys_schedctl), new segment: "
9688 "vaddr=%#lx, size=%#lx, prot=%#x, flags=%#x, fd=-1, "
9689 "offset=0\n", page
, size
, prot
, flags
);
9691 /* The kernel always places redzone before and after the allocated page.
9692 Check this assertion now; the tool can later request to allocate
9693 a Valgrind segment and aspacemgr will place it adjacent. */
9694 const NSegment
*seg
= VG_(am_find_nsegment
)(page
- 1);
9695 vg_assert(seg
== NULL
|| seg
->kind
== SkResvn
);
9696 seg
= VG_(am_find_nsegment
)(page
+ VKI_PAGE_SIZE
);
9697 vg_assert(seg
== NULL
|| seg
->kind
== SkResvn
);
9699 /* The address space manager works with whole pages. */
9700 VG_(am_notify_client_mmap
)(page
, size
, prot
, flags
, -1, 0);
9702 /* Note: It isn't needed to notify debuginfo about the new mapping
9703 because it's only an anonymous mapping. */
9704 /* Note: schedctl data are cleaned in two places:
9705 - for the tool when the thread exits
9706 - for the core in child's post-fork handler clean_schedctl_data(). */
9709 /* The tool needs per-thread granularity, not whole pages. */
9710 VG_TRACK(new_mem_mmap
, a
, sizeof(struct vki_sc_shared
), True
, True
, True
, 0);
9711 POST_MEM_WRITE(a
, sizeof(struct vki_sc_shared
));
9716 /* Kernel: int pset(int subcode, long arg1, long arg2, long arg3,
9718 switch (ARG1
/* subcode */) {
9719 case VKI_PSET_CREATE
:
9720 /* Libc: int pset_create(psetid_t *newpset); */
9721 PRINT("sys_pset ( %ld, %#lx )", SARG1
, ARG2
);
9722 PRE_REG_READ2(long, SC2("pset", "create"), int, subcode
,
9723 vki_psetid_t
*, newpset
);
9724 PRE_MEM_WRITE("pset(newpset)", ARG2
, sizeof(vki_psetid_t
));
9726 case VKI_PSET_DESTROY
:
9727 /* Libc: int pset_destroy(psetid_t pset); */
9728 PRINT("sys_pset ( %ld, %ld )", SARG1
, SARG2
);
9729 PRE_REG_READ2(long, SC2("pset", "destroy"), int, subcode
,
9730 vki_psetid_t
, pset
);
9732 case VKI_PSET_ASSIGN
:
9733 /* Libc: int pset_assign(psetid_t pset, processorid_t cpu,
9734 psetid_t *opset); */
9735 PRINT("sys_pset ( %ld, %ld, %ld, %#lx )", SARG1
, SARG2
, SARG3
, ARG4
);
9736 PRE_REG_READ4(long, SC2("pset", "assign"), int, subcode
,
9737 vki_psetid_t
, pset
, vki_processorid_t
, cpu
,
9738 vki_psetid_t
*, opset
);
9740 PRE_MEM_WRITE("pset(opset)", ARG4
, sizeof(vki_psetid_t
));
9743 /* Libc: int pset_info(psetid_t pset, int *type, uint_t *numcpus,
9744 processorid_t *cpulist); */
9745 PRINT("sys_pset ( %ld, %ld, %#lx, %#lx, %#lx )", SARG1
, SARG2
, ARG3
,
9747 PRE_REG_READ5(long, SC2("pset", "info"), int, subcode
, vki_psetid_t
, pset
,
9748 int *, type
, vki_uint_t
*, numcpus
,
9749 vki_processorid_t
*, cpulist
);
9751 PRE_MEM_WRITE("pset(type)", ARG3
, sizeof(int));
9753 PRE_MEM_WRITE("pset(numcpus)", ARG4
, sizeof(vki_uint_t
));
9754 if ((ARG4
!= 0) && (ARG5
!= 0)) {
9755 vki_uint_t
*numcpus
= (vki_uint_t
*) ARG4
;
9756 if (ML_(safe_to_deref(numcpus
, sizeof(vki_uint_t
)))) {
9757 PRE_MEM_WRITE("pset(cpulist)", ARG5
,
9758 *numcpus
* sizeof(vki_processorid_t
));
9759 /* If cpulist buffer is not large enough, it will hold only as many
9760 entries as fit in the buffer. However numcpus will contain the
9761 real number of cpus which will be greater than originally passed
9762 in. Stash the original value in unused ARG6. */
9768 /* Libc: int pset_bind(psetid_t pset, idtype_t idtype, id_t id,
9769 psetid_t *opset); */
9770 PRINT("sys_pset ( %ld, %ld, %ld, %ld, %#lx )", SARG1
, SARG2
, SARG3
,
9772 PRE_REG_READ5(long, SC2("pset", "bind"), int, subcode
, vki_psetid_t
, pset
,
9773 vki_idtype_t
, idtype
, vki_id_t
, id
, vki_psetid_t
*, opset
);
9775 PRE_MEM_WRITE("pset(opset)", ARG5
, sizeof(vki_psetid_t
));
9777 case VKI_PSET_BIND_LWP
:
9778 /* Libc: int pset_bind_lwp(psetid_t pset, id_t id, pid_t pid,
9779 psetid_t *opset); */
9780 PRINT("sys_pset ( %ld, %ld, %ld, %ld, %#lx )", SARG1
, SARG2
, SARG3
,
9782 PRE_REG_READ5(long, SC2("pset", "bind_lwp"), int, subcode
,
9783 vki_psetid_t
, pset
, vki_id_t
, id
, vki_pid_t
, pid
,
9784 vki_psetid_t
*, opset
);
9786 PRE_MEM_WRITE("pset(opset)", ARG5
, sizeof(vki_psetid_t
));
9788 case VKI_PSET_GETLOADAVG
:
9789 /* Libc: int pset_getloadavg(psetid_t pset, double loadavg[],
9791 PRINT("sys_pset ( %ld, %ld, %#lx, %ld )", SARG1
, SARG2
, ARG3
, SARG4
);
9792 PRE_REG_READ4(long, SC2("pset", "getloadavg"), int, subcode
,
9793 vki_psetid_t
, pset
, int *, buf
, int, nelem
);
9795 PRE_MEM_WRITE("pset(buf)", ARG3
, SARG4
* sizeof(int));
9798 /* Libc: int pset_list(psetid_t *psetlist, uint_t *numpsets); */
9799 PRINT("sys_pset ( %ld, %#lx, %#lx )", SARG1
, ARG2
, ARG3
);
9800 PRE_REG_READ3(long, SC2("pset", "list"), int, subcode
,
9801 vki_psetid_t
*, psetlist
, vki_uint_t
*, numpsets
);
9803 PRE_MEM_WRITE("pset(numpsets)", ARG3
, sizeof(vki_uint_t
));
9804 if ((ARG2
!= 0) && (ARG3
!= 0)) {
9805 vki_uint_t
*numpsets
= (vki_uint_t
*) ARG3
;
9806 if (ML_(safe_to_deref(numpsets
, sizeof(vki_uint_t
)))) {
9807 PRE_MEM_WRITE("pset(psetlist)", ARG2
,
9808 *numpsets
* sizeof(vki_psetid_t
));
9809 /* If psetlist buffer is not large enough, it will hold only as many
9810 entries as fit in the buffer. However numpsets will contain the
9811 real number of processor sets which will be greater than
9812 originally passed in. Stash the original value in unused ARG6. */
9817 # if defined(SOLARIS_PSET_GET_NAME)
9818 case VKI_PSET_GET_NAME
:
9819 /* Libc: int pset_get_name(psetid_t psetid, char *buf, uint_t len); */
9820 PRINT("sys_pset ( %ld, %ld, %#lx, %ld )", SARG1
, SARG2
, ARG3
, SARG4
);
9821 PRE_REG_READ4(long, SC2("pset", "get_name"), int, subcode
,
9822 vki_psetid_t
, pset
, char *, buf
, vki_uint_t
, len
);
9823 PRE_MEM_WRITE("pset(buf)", ARG3
, ARG4
);
9825 # endif /* SOLARIS_PSET_GET_NAME */
9826 case VKI_PSET_SETATTR
:
9827 /* Libc: int pset_setattr(psetid_t pset, uint_t attr); */
9828 PRINT("sys_pset ( %ld, %ld, %lu )", SARG1
, SARG2
, ARG3
);
9829 PRE_REG_READ3(long, SC2("pset", "setattr"), int, subcode
,
9830 vki_psetid_t
, pset
, vki_uint_t
, attr
);
9832 case VKI_PSET_GETATTR
:
9833 /* Libc: int pset_getattr(psetid_t pset, uint_t *attr); */
9834 PRINT("sys_pset ( %ld, %ld, %#lx )", SARG1
, SARG2
, ARG3
);
9835 PRE_REG_READ3(long, SC2("pset", "getattr"), int, subcode
,
9836 vki_psetid_t
, pset
, vki_uint_t
*, attr
);
9837 PRE_MEM_WRITE("pset(attr)", ARG3
, sizeof(vki_uint_t
));
9839 case VKI_PSET_ASSIGN_FORCED
:
9840 /* Libc: int pset_assign_forced(psetid_t pset, processorid_t cpu,
9841 psetid_t *opset); */
9842 PRINT("sys_pset ( %ld, %ld, %ld, %#lx )", SARG1
, SARG2
, SARG3
, ARG4
);
9843 PRE_REG_READ4(long, SC2("pset", "assign_forced"), int, subcode
,
9844 vki_psetid_t
, pset
, vki_processorid_t
, cpu
,
9845 vki_psetid_t
*, opset
);
9847 PRE_MEM_WRITE("pset(opset)", ARG4
, sizeof(vki_psetid_t
));
9850 VG_(unimplemented
)("Syswrap of pset syscall with subcode %ld.", SARG1
);
9858 switch (ARG1
/*subcode*/) {
9859 case VKI_PSET_CREATE
:
9860 POST_MEM_WRITE(ARG2
, sizeof(vki_psetid_t
));
9862 case VKI_PSET_DESTROY
:
9864 case VKI_PSET_ASSIGN
:
9866 POST_MEM_WRITE(ARG4
, sizeof(vki_psetid_t
));
9870 POST_MEM_WRITE(ARG3
, sizeof(int));
9872 POST_MEM_WRITE(ARG4
, sizeof(vki_uint_t
));
9873 if ((ARG4
!= 0) && (ARG5
!= 0)) {
9874 vki_uint_t
*numcpus
= (vki_uint_t
*) ARG4
;
9875 POST_MEM_WRITE(ARG5
, MIN(*numcpus
, ARG6
) * sizeof(vki_processorid_t
));
9880 POST_MEM_WRITE(ARG5
, sizeof(vki_psetid_t
));
9882 case VKI_PSET_BIND_LWP
:
9884 POST_MEM_WRITE(ARG5
, sizeof(vki_psetid_t
));
9886 case VKI_PSET_GETLOADAVG
:
9888 POST_MEM_WRITE(ARG3
, MIN(SARG4
, VKI_LOADAVG_NSTATS
) * sizeof(int));
9892 POST_MEM_WRITE(ARG3
, sizeof(vki_uint_t
));
9893 if ((ARG2
!= 0) && (ARG3
!= 0)) {
9894 vki_uint_t
*numpsets
= (vki_uint_t
*) ARG3
;
9895 POST_MEM_WRITE(ARG2
, MIN(*numpsets
, ARG6
) * sizeof(vki_psetid_t
));
9898 # if defined(SOLARIS_PSET_GET_NAME)
9899 case VKI_PSET_GET_NAME
:
9900 POST_MEM_WRITE(ARG3
, VG_(strlen
)((HChar
*) ARG3
) + 1);
9902 # endif /* SOLARIS_PSET_GET_NAME */
9903 case VKI_PSET_SETATTR
:
9905 case VKI_PSET_GETATTR
:
9906 POST_MEM_WRITE(ARG3
, sizeof(vki_uint_t
));
9908 case VKI_PSET_ASSIGN_FORCED
:
9910 POST_MEM_WRITE(ARG4
, sizeof(vki_psetid_t
));
9918 PRE(sys_resolvepath
)
9920 /* int resolvepath(const char *path, char *buf, size_t bufsiz); */
9921 PRINT("sys_resolvepath ( %#lx(%s), %#lx, %lu )", ARG1
, (HChar
*) ARG1
, ARG2
,
9923 PRE_REG_READ3(long, "resolvepath", const char *, path
, char *, buf
,
9924 vki_size_t
, bufsiz
);
9926 PRE_MEM_RASCIIZ("resolvepath(path)", ARG1
);
9927 PRE_MEM_WRITE("resolvepath(buf)", ARG2
, ARG3
);
9930 POST(sys_resolvepath
)
9932 POST_MEM_WRITE(ARG2
, RES
);
9935 PRE(sys_lwp_mutex_timedlock
)
9937 /* int lwp_mutex_timedlock(lwp_mutex_t *lp, timespec_t *tsp,
9938 uintptr_t owner); */
9939 vki_lwp_mutex_t
*lp
= (vki_lwp_mutex_t
*)ARG1
;
9940 *flags
|= SfMayBlock
;
9941 PRINT("lwp_mutex_timedlock ( %#lx, %#lx, %#lx )", ARG1
, ARG2
, ARG3
);
9942 PRE_REG_READ3(long, "lwp_mutex_timedlock", lwp_mutex_t
*, lp
,
9943 timespec_t
*, tsp
, uintptr_t, owner
);
9945 PRE_FIELD_READ("lwp_mutex_timedlock(lp->mutex_flag)", lp
->vki_mutex_flag
);
9946 PRE_FIELD_READ("lwp_mutex_timedlock(lp->mutex_type)", lp
->vki_mutex_type
);
9947 PRE_FIELD_WRITE("lwp_mutex_timedlock(lp->mutex_owner)",
9948 lp
->vki_mutex_owner
);
9949 PRE_FIELD_WRITE("lwp_mutex_timedlock(lp->mutex_ownerpid)",
9950 lp
->vki_mutex_ownerpid
);
9951 PRE_FIELD_READ("lwp_mutex_timedlock(lp->mutex_lockw)", lp
->vki_mutex_lockw
);
9952 /*PRE_FIELD_WRITE("lwp_mutex_timedlock(lp->mutex_lockw)",
9953 lp->vki_mutex_lockw);*/
9954 PRE_FIELD_READ("lwp_mutex_timedlock(lp->mutex_waiters)",
9955 lp
->vki_mutex_waiters
);
9956 /*PRE_FIELD_WRITE("lwp_mutex_timedlock(lp->mutex_waiters)",
9957 lp->vki_mutex_waiters);*/
9959 PRE_MEM_READ("lwp_mutex_timedlock(tsp)", ARG2
, sizeof(vki_timespec_t
));
9960 /*PRE_MEM_WRITE("lwp_mutex_timedlock(tsp)", ARG2,
9961 sizeof(vki_timespec_t));*/
9965 POST(sys_lwp_mutex_timedlock
)
9967 vki_lwp_mutex_t
*lp
= (vki_lwp_mutex_t
*)ARG1
;
9968 POST_FIELD_WRITE(lp
->vki_mutex_owner
);
9969 POST_FIELD_WRITE(lp
->vki_mutex_ownerpid
);
9970 POST_FIELD_WRITE(lp
->vki_mutex_lockw
);
9971 POST_FIELD_WRITE(lp
->vki_mutex_waiters
);
9973 POST_MEM_WRITE(ARG2
, sizeof(vki_timespec_t
));
9976 PRE(sys_lwp_rwlock_sys
)
9978 /* int lwp_rwlock_sys(int subcode, lwp_rwlock_t *rwlp, timespec_t *tsp); */
9979 vki_lwp_rwlock_t
*rwlp
= (vki_lwp_rwlock_t
*)ARG2
;
9980 switch (ARG1
/*subcode*/) {
9985 *flags
|= SfMayBlock
;
9986 switch (ARG1
/*subcode*/) {
9988 PRINT("sys_lwp_rwlock ( %ld, %#lx, %#lx )", SARG1
, ARG2
, ARG3
);
9989 PRE_REG_READ3(long, SC2("lwp_rwlock", "rdlock"), int, subcode
,
9990 lwp_rwlock_t
*, rwlp
, timespec_t
*, tsp
);
9993 PRINT("sys_lwp_rwlock ( %ld, %#lx, %#lx )", SARG1
, ARG2
, ARG3
);
9994 PRE_REG_READ3(long, SC2("lwp_rwlock", "wrlock"), int, subcode
,
9995 lwp_rwlock_t
*, rwlp
, timespec_t
*, tsp
);
9998 PRINT("sys_lwp_rwlock ( %ld, %#lx )", SARG1
, ARG2
);
9999 PRE_REG_READ2(long, SC2("lwp_rwlock", "tryrdlock"), int, subcode
,
10000 lwp_rwlock_t
*, rwlp
);
10003 PRINT("sys_lwp_rwlock ( %ld, %#lx )", SARG1
, ARG2
);
10004 PRE_REG_READ2(long, SC2("lwp_rwlock", "trywrlock"), int, subcode
,
10005 lwp_rwlock_t
*, rwlp
);
10012 PRE_FIELD_READ("lwp_rwlock(rwlp->rwlock_type)", rwlp
->vki_rwlock_type
);
10013 PRE_FIELD_READ("lwp_rwlock(rwlp->rwlock_readers)",
10014 rwlp
->vki_rwlock_readers
);
10015 /*PRE_FIELD_WRITE("lwp_rwlock(rwlp->rwlock_readers)",
10016 rwlp->vki_rwlock_readers);*/
10018 PRE_FIELD_READ("lwp_rwlock(rwlp->mutex.mutex_type)",
10019 rwlp
->mutex
.vki_mutex_type
);
10020 PRE_FIELD_WRITE("lwp_rwlock(rwlp->mutex.mutex_owner)",
10021 rwlp
->mutex
.vki_mutex_owner
);
10022 PRE_FIELD_WRITE("lwp_rwlock(rwlp->mutex.mutex_ownerpid)",
10023 rwlp
->mutex
.vki_mutex_ownerpid
);
10024 /* The mutex_lockw member is not really read by the kernel for this
10025 syscall but it seems better to mark it that way because when locking
10026 an rwlock the associated mutex has to be locked. */
10027 PRE_FIELD_READ("lwp_rwlock(rwlp->mutex.mutex_lockw)",
10028 rwlp
->mutex
.vki_mutex_lockw
);
10029 /*PRE_FIELD_WRITE("lwp_rwlock(rwlp->mutex.mutex_lockw)",
10030 rwlp->mutex.vki_mutex_lockw);*/
10031 PRE_FIELD_READ("lwp_rwlock(rwlp->mutex.mutex_waiters)",
10032 rwlp
->mutex
.vki_mutex_waiters
);
10033 /*PRE_FIELD_WRITE("lwp_rwlock(rwlp->mutex.mutex_waiters)",
10034 rwlp->mutex.vki_mutex_waiters);*/
10036 if ((ARG1
== 0 || ARG1
== 1) && ARG3
)
10037 PRE_MEM_READ("lwp_rwlock(tsp)", ARG3
, sizeof(vki_timespec_t
));
10040 PRINT("sys_lwp_rwlock( %ld, %#lx )", SARG1
, ARG2
);
10041 PRE_REG_READ2(long, SC2("lwp_rwlock", "unlock"), int, subcode
,
10042 lwp_rwlock_t
*, rwlp
);
10043 PRE_FIELD_READ("lwp_rwlock(rwlp->mutex.mutex_type)",
10044 rwlp
->mutex
.vki_mutex_type
);
10045 PRE_FIELD_READ("lwp_rwlock(rwlp->rwlock_readers)",
10046 rwlp
->vki_rwlock_readers
);
10047 /*PRE_FIELD_WRITE("lwp_rwlock(rwlp->rwlock_readers)",
10048 rwlp->vki_rwlock_readers);*/
10051 VG_(unimplemented
)("Syswrap of the lwp_rwlock_sys call with subcode %ld.",
10058 POST(sys_lwp_rwlock_sys
)
10060 vki_lwp_rwlock_t
*rwlp
= (vki_lwp_rwlock_t
*)ARG2
;
10061 switch (ARG1
/*subcode*/) {
10066 POST_FIELD_WRITE(rwlp
->vki_rwlock_readers
);
10067 POST_FIELD_WRITE(rwlp
->vki_rwlock_owner
);
10068 POST_FIELD_WRITE(rwlp
->vki_rwlock_ownerpid
);
10069 POST_FIELD_WRITE(rwlp
->mutex
.vki_mutex_lockw
);
10070 POST_FIELD_WRITE(rwlp
->mutex
.vki_mutex_waiters
);
10073 POST_FIELD_WRITE(rwlp
->vki_rwlock_readers
);
10081 PRE(sys_lwp_sema_timedwait
)
10083 /* int lwp_sema_timedwait(lwp_sema_t *sema, timespec_t *timeout,
10084 int check_park); */
10085 vki_lwp_sema_t
*sema
= (vki_lwp_sema_t
*)ARG1
;
10086 *flags
|= SfMayBlock
;
10087 PRINT("sys_lwp_sema_timewait ( %#lx, %#lx, %ld )", ARG1
, ARG2
, SARG3
);
10088 PRE_REG_READ3(long, "lwp_sema_timedwait", lwp_sema_t
*, sema
,
10089 timespec_t
*, timeout
, int, check_park
);
10091 PRE_FIELD_READ("lwp_sema_timedwait(sema->type)", sema
->vki_sema_type
);
10092 PRE_FIELD_READ("lwp_sema_timedwait(sema->count)", sema
->vki_sema_count
);
10093 /*PRE_FIELD_WRITE("lwp_sema_timedwait(sema->count)",
10094 sema->vki_sema_count);*/
10095 PRE_FIELD_READ("lwp_sema_timedwait(sema->waiters)", sema
->vki_sema_waiters
);
10096 /*PRE_FIELD_WRITE("lwp_sema_timedwait(sema->waiters)",
10097 sema->vki_sema_waiters);*/
10099 PRE_MEM_READ("lwp_sema_timedwait(timeout)", ARG2
,
10100 sizeof(vki_timespec_t
));
10101 /*PRE_MEM_WRITE("lwp_sema_timedwait(timeout)", ARG2,
10102 sizeof(vki_timespec_t));*/
10106 POST(sys_lwp_sema_timedwait
)
10108 vki_lwp_sema_t
*sema
= (vki_lwp_sema_t
*)ARG1
;
10109 POST_FIELD_WRITE(sema
->vki_sema_count
);
10110 POST_FIELD_WRITE(sema
->vki_sema_waiters
);
10112 POST_MEM_WRITE(ARG2
, sizeof(vki_timespec_t
));
10117 /* Kernel: long zone(int cmd, void *arg1, void *arg2, void *arg3,
10120 switch (ARG1
/*cmd*/) {
10121 case VKI_ZONE_CREATE
:
10122 /* Libc: zoneid_t zone_create(const char *name, const char *root,
10123 const struct priv_set *privs,
10124 const char *rctls, size_t rctlsz,
10125 const char *zfs, size_t zfssz,
10126 int *extended_error, int match,
10127 int doi, const bslabel_t *label,
10129 Kernel: zoneid_t zone_create(zone_def *zd);
10131 PRINT("sys_zone ( %ld, %#lx )", SARG1
, ARG2
);
10132 PRE_REG_READ2(long, SC2("zone", "create"), int, cmd
,
10133 vki_zone_def
*, zd
);
10135 vki_zone_def
*zd
= (vki_zone_def
*) ARG2
;
10136 PRE_FIELD_READ("zone(zd.zone_name)", zd
->zone_name
);
10137 PRE_FIELD_READ("zone(zd.zone_root)", zd
->zone_root
);
10138 PRE_FIELD_READ("zone(zd.zone_privs)", zd
->zone_privs
);
10139 PRE_FIELD_READ("zone(zd.zone_privssz)", zd
->zone_privssz
);
10140 PRE_FIELD_READ("zone(zd.rctlbuf)", zd
->rctlbuf
);
10141 PRE_FIELD_READ("zone(zd.rctlbufsz)", zd
->rctlbufsz
);
10142 PRE_FIELD_READ("zone(zd.zfsbuf)", zd
->zfsbuf
);
10143 PRE_FIELD_READ("zone(zd.zfsbufsz)", zd
->zfsbufsz
);
10144 PRE_FIELD_READ("zone(zd.extended_error)", zd
->extended_error
);
10145 PRE_FIELD_READ("zone(zd.match)", zd
->match
);
10146 PRE_FIELD_READ("zone(zd.doi)", zd
->doi
);
10147 PRE_FIELD_READ("zone(zd.label)", zd
->label
);
10148 PRE_FIELD_READ("zone(zd.flags)", zd
->flags
);
10150 if (ML_(safe_to_deref((void *)ARG2
, sizeof(vki_zone_def
)))) {
10152 PRE_MEM_RASCIIZ("zone(zd.zone_name)", (Addr
) zd
->zone_name
);
10154 PRE_MEM_RASCIIZ("zone(zd.zone_root)", (Addr
) zd
->zone_root
);
10155 PRE_MEM_READ("zone(zd.zone_privs)", (Addr
) zd
->zone_privs
,
10157 PRE_MEM_READ("zone(zd.rctlbuf)", (Addr
) zd
->rctlbuf
,
10159 PRE_MEM_READ("zone(zd.zfsbuf)",
10160 (Addr
) zd
->zfsbuf
, zd
->zfsbufsz
);
10162 PRE_MEM_READ("zone(zd.label)", (Addr
) zd
->label
,
10163 sizeof(vki_bslabel_t
));
10166 case VKI_ZONE_DESTROY
:
10167 /* Libc: int zone_destroy(zoneid_t zoneid); */
10168 PRINT("sys_zone ( %ld, %ld )", SARG1
, SARG2
);
10169 PRE_REG_READ2(long, SC2("zone", "destroy"), int, cmd
,
10170 vki_zoneid_t
, zoneid
);
10172 case VKI_ZONE_GETATTR
:
10173 /* Libc: ssize_t zone_getattr(zoneid_t zoneid, int attr,
10174 void *valp, size_t size);
10176 PRINT("sys_zone ( %ld, %ld, %ld, %#lx, %ld )",
10177 SARG1
, SARG2
, SARG3
, ARG4
, SARG5
);
10178 PRE_REG_READ5(long, SC2("zone", "getattr"), int, cmd
,
10179 vki_zoneid_t
, zoneid
, int, attr
, void *, valp
,
10181 PRE_MEM_WRITE("zone(valp)", ARG4
, ARG5
);
10183 case VKI_ZONE_ENTER
:
10184 /* Libc: int zone_enter(zoneid_t zoneid); */
10185 PRINT("sys_zone ( %ld, %ld )", SARG1
, SARG2
);
10186 PRE_REG_READ2(long, SC2("zone", "enter"), int, cmd
,
10187 vki_zoneid_t
, zoneid
);
10189 case VKI_ZONE_LIST
:
10190 /* Libc: int zone_list(zoneid_t *zonelist, uint_t *numzones); */
10191 PRINT("sys_zone ( %ld, %#lx, %#lx )", SARG1
, ARG2
, ARG3
);
10192 PRE_REG_READ3(long, SC2("zone", "list"), int, cmd
,
10193 vki_zoneid_t
*, zonelist
, vki_uint_t
*, numzones
);
10195 PRE_MEM_WRITE("zone(numzones)", ARG3
, sizeof(vki_uint_t
));
10197 if (ML_(safe_to_deref((void *) ARG3
, sizeof(vki_uint_t
)))) {
10199 PRE_MEM_WRITE("zone(zonelist)", ARG2
,
10200 *(vki_uint_t
*) ARG3
* sizeof(vki_zoneid_t
));
10203 case VKI_ZONE_SHUTDOWN
:
10204 /* Libc: int zone_shutdown(zoneid_t zoneid); */
10205 PRINT("sys_zone ( %ld, %ld )", SARG1
, SARG2
);
10206 PRE_REG_READ2(long, SC2("zone", "shutdown"), int, cmd
,
10207 vki_zoneid_t
, zoneid
);
10209 case VKI_ZONE_LOOKUP
:
10210 /* Libc: zoneid_t zone_lookup(const char *name); */
10211 PRINT("sys_zone ( %ld, %#lx(%s) )", SARG1
, ARG2
, (HChar
*) ARG2
);
10212 PRE_REG_READ2(long, SC2("zone", "lookup"), int, cmd
,
10213 const char *, name
);
10215 PRE_MEM_RASCIIZ("zone(name)", ARG2
);
10217 case VKI_ZONE_BOOT
:
10218 /* Libc: int zone_boot(zoneid_t zoneid); */
10219 PRINT("sys_zone ( %ld, %ld )", SARG1
, SARG2
);
10220 PRE_REG_READ2(long, SC2("zone", "boot"), int, cmd
,
10221 vki_zoneid_t
, zoneid
);
10223 case VKI_ZONE_SETATTR
:
10224 /* Libc: int zone_setattr(zoneid_t zoneid, int attr, void *valp,
10227 PRINT("sys_zone ( %ld, %ld, %ld, %#lx, %lu )",
10228 SARG1
, SARG2
, SARG3
, ARG4
, ARG5
);
10229 PRE_REG_READ5(long, SC2("zone", "setattr"), int, cmd
,
10230 vki_zoneid_t
, zoneid
, int, attr
, void *, valp
,
10232 PRE_MEM_READ("zone(valp)", ARG4
, ARG5
);
10234 case VKI_ZONE_ADD_DATALINK
:
10235 /* Libc: int zone_add_datalink(zoneid_t zoneid,
10236 datalink_id_t linkid);
10238 PRINT("sys_zone ( %ld, %ld, %ld )", SARG1
, SARG2
, SARG3
);
10239 PRE_REG_READ3(long, SC2("zone", "add_datalink"), int, cmd
,
10240 vki_zoneid_t
, zoneid
, vki_datalink_id_t
, linkid
);
10242 case VKI_ZONE_DEL_DATALINK
:
10243 /* Libc: int zone_remove_datalink(zoneid_t zoneid,
10244 datalink_id_t linkid);
10246 PRINT("sys_zone ( %ld, %ld, %ld )", SARG1
, SARG2
, SARG3
);
10247 PRE_REG_READ3(long, SC2("zone", "del_datalink"), int, cmd
,
10248 vki_zoneid_t
, zoneid
, vki_datalink_id_t
, linkid
);
10250 case VKI_ZONE_CHECK_DATALINK
:
10251 /* Libc: int zone_check_datalink(zoneid_t *zoneidp,
10252 datalink_id_t linkid);
10254 PRINT("sys_zone ( %ld, %#lx, %ld )", SARG1
, ARG2
, SARG3
);
10255 PRE_REG_READ3(long, SC2("zone", "check_datalink"), int, cmd
,
10256 vki_zoneid_t
*, zoneidp
, vki_datalink_id_t
, linkid
);
10257 PRE_MEM_WRITE("zone(zoneidp)", ARG2
, sizeof(vki_zoneid_t
));
10259 case VKI_ZONE_LIST_DATALINK
:
10260 /* Libc: int zone_list_datalink(zoneid_t zoneid, int *dlnump,
10261 datalink_id_t *linkids);
10263 PRINT("sys_zone ( %ld, %ld, %#lx, %#lx )", SARG1
, SARG2
, ARG3
, ARG4
);
10264 PRE_REG_READ4(long, SC2("zone", "list_datalink"), int, cmd
,
10265 vki_zoneid_t
, zoneid
, int *, dlnump
,
10266 vki_datalink_id_t
*, linkids
);
10268 PRE_MEM_WRITE("zone(dlnump)", ARG3
, sizeof(int));
10269 if (ML_(safe_to_deref((void *) ARG3
, sizeof(int)))) {
10271 PRE_MEM_WRITE("zone(linkids)", ARG4
,
10272 *(int *) ARG3
* sizeof(vki_datalink_id_t
));
10275 #if defined(SOLARIS_ZONE_DEFUNCT)
10276 case VKI_ZONE_LIST_DEFUNCT
:
10277 /* Libc: int zone_list_defunct(uint64_t *uniqidlist,
10280 PRINT("sys_zone ( %ld, %#lx, %#lx )", SARG1
, ARG2
, ARG3
);
10281 PRE_REG_READ3(long, SC2("zone", "list_defunct"), int, cmd
,
10282 vki_uint64_t
*, uniqidlist
, vki_uint_t
*, numzones
);
10284 PRE_MEM_WRITE("zone(numzones)", ARG3
, sizeof(vki_uint_t
));
10286 if (ML_(safe_to_deref((void *) ARG3
, sizeof(vki_uint_t
)))) {
10288 PRE_MEM_WRITE("zone(uniqidlist)", ARG2
,
10289 *(vki_uint_t
*) ARG3
* sizeof(vki_uint64_t
));
10292 case VKI_ZONE_GETATTR_DEFUNCT
:
10293 /* Libc: ssize_t zone_getattr_defunct(uint64_t uniqid, int attr,
10294 void *valp, size_t size);
10295 Kernel: ssize_t zone_getattr_defunct(uint64_t *uniqid, int attr,
10296 void *valp, size_t size);
10298 PRINT("sys_zone ( %ld, %#lx, %ld, %#lx, %lu )",
10299 SARG1
, ARG2
, SARG3
, ARG4
, ARG5
);
10300 PRE_REG_READ5(long, SC2("zone", "getattr_defunct"), int, cmd
,
10301 vki_uint64_t
*, uniqid
, int, attr
,
10302 void *, valp
, vki_size_t
, size
);
10304 PRE_MEM_READ("zone(uniqid)", ARG2
, sizeof(vki_uint64_t
));
10305 PRE_MEM_WRITE("zone(valp)", ARG4
, ARG5
);
10307 #endif /* SOLARIS_ZONE_DEFUNCT */
10309 VG_(unimplemented
)("Syswrap of the zone call with cmd %ld.", SARG1
);
10318 switch (ARG1
/*cmd*/) {
10319 case VKI_ZONE_CREATE
:
10320 case VKI_ZONE_DESTROY
:
10322 case VKI_ZONE_GETATTR
:
10323 POST_MEM_WRITE(ARG4
, MIN(RES
, ARG5
));
10325 case VKI_ZONE_ENTER
:
10327 case VKI_ZONE_LIST
:
10328 POST_MEM_WRITE(ARG2
, *(vki_uint_t
*) ARG3
* sizeof(vki_zoneid_t
));
10330 case VKI_ZONE_SHUTDOWN
:
10331 case VKI_ZONE_LOOKUP
:
10332 case VKI_ZONE_BOOT
:
10333 case VKI_ZONE_SETATTR
:
10334 case VKI_ZONE_ADD_DATALINK
:
10335 case VKI_ZONE_DEL_DATALINK
:
10337 case VKI_ZONE_CHECK_DATALINK
:
10338 POST_MEM_WRITE(ARG2
, sizeof(vki_zoneid_t
));
10340 case VKI_ZONE_LIST_DATALINK
:
10341 POST_MEM_WRITE(ARG4
, *(int *) ARG3
* sizeof(vki_datalink_id_t
));
10343 #if defined(SOLARIS_ZONE_DEFUNCT)
10344 case VKI_ZONE_LIST_DEFUNCT
:
10345 POST_MEM_WRITE(ARG2
, *(vki_uint_t
*) ARG3
* sizeof(vki_uint64_t
));
10347 case VKI_ZONE_GETATTR_DEFUNCT
:
10348 POST_MEM_WRITE(ARG4
, MIN(RES
, ARG5
));
10350 #endif /* SOLARIS_ZONE_DEFUNCT */
10359 /* int getcwd(char *buf, size_t size); */
10360 /* Note: Generic getcwd() syswrap can't be used because it expects
10361 a different return value. */
10362 PRINT("sys_getcwd ( %#lx, %lu )", ARG1
, ARG2
);
10363 PRE_REG_READ2(long, "getcwd", char *, buf
, vki_size_t
, size
);
10364 PRE_MEM_WRITE("getcwd(buf)", ARG1
, ARG2
);
10369 POST_MEM_WRITE(ARG1
, VG_(strlen
)((HChar
*)ARG1
) + 1);
10374 /* int so_socket(int family, int type, int protocol, char *devpath,
10376 PRINT("sys_so_socket ( %ld, %ld, %ld, %#lx(%s), %ld)", SARG1
, SARG2
, SARG3
,
10377 ARG4
, (HChar
*) ARG4
, SARG5
);
10378 PRE_REG_READ5(long, "socket", int, family
, int, type
, int, protocol
,
10379 char *, devpath
, int, version
);
10381 PRE_MEM_RASCIIZ("socket(devpath)", ARG4
);
10384 POST(sys_so_socket
)
10387 r
= ML_(generic_POST_sys_socket
)(tid
, VG_(mk_SysRes_Success
)(RES
));
10388 SET_STATUS_from_SysRes(r
);
10391 PRE(sys_so_socketpair
)
10393 /* int so_socketpair(int sv[2]); */
10394 /* This syscall is used to connect two already created sockets together. */
10395 PRINT("sys_so_socketpair ( %#lx )", ARG1
);
10396 PRE_REG_READ1(long, "socketpair", int *, sv
);
10397 PRE_MEM_READ("socketpair(sv)", ARG1
, 2 * sizeof(int));
10398 /*PRE_MEM_WRITE("socketpair(sv)", ARG1, 2 * sizeof(int));*/
10399 if (ML_(safe_to_deref
)((void*)ARG1
, 2 * sizeof(int))) {
10400 int *fds
= (int*)ARG1
;
10401 if (!ML_(fd_allowed
)(fds
[0], "socketpair", tid
, False
))
10402 SET_STATUS_Failure(VKI_EBADF
);
10403 else if (!ML_(fd_allowed
)(fds
[1], "socketpair", tid
, False
))
10404 SET_STATUS_Failure(VKI_EBADF
);
10408 POST(sys_so_socketpair
)
10410 /* The kernel can return new file descriptors, in such a case we have to
10412 int *fds
= (int*)ARG1
;
10413 POST_MEM_WRITE(ARG1
, 2 * sizeof(int));
10414 if (!ML_(fd_allowed
)(fds
[0], "socketpair", tid
, True
))
10415 SET_STATUS_Failure(VKI_EMFILE
);
10416 if (!ML_(fd_allowed
)(fds
[1], "socketpair", tid
, True
))
10417 SET_STATUS_Failure(VKI_EMFILE
);
10419 /* One or both of the file descriptors weren't allowed, close newly
10420 created file descriptors but don't close the already recorded
10422 if (!ML_(fd_recorded
)(fds
[0]))
10423 VG_(close
)(fds
[0]);
10424 if (!ML_(fd_recorded
)(fds
[1]))
10425 VG_(close
)(fds
[1]);
10427 else if (VG_(clo_track_fds
)) {
10428 /* Everything went better than expected, record the newly created file
10429 descriptors. Note: If the kernel actually returns the original file
10430 descriptors, then ML_(record_fd_open_nameless) notices that these
10431 file descriptors have been already recorded. */
10432 ML_(record_fd_open_nameless
)(tid
, fds
[0]);
10433 ML_(record_fd_open_nameless
)(tid
, fds
[1]);
10439 /* int bind(int s, struct sockaddr *name, socklen_t namelen,
10441 PRINT("sys_bind ( %ld, %#lx, %lu, %ld )", SARG1
, ARG2
, ARG3
, SARG4
);
10442 PRE_REG_READ4(long, "bind", int, s
, struct sockaddr
*, name
,
10443 vki_socklen_t
, namelen
, int, version
);
10444 ML_(generic_PRE_sys_bind
)(tid
, ARG1
, ARG2
, ARG3
);
10449 /* int listen(int s, int backlog, int version); */
10450 PRINT("sys_listen ( %ld, %ld, %ld )", SARG1
, SARG2
, SARG3
);
10451 PRE_REG_READ3(long, "listen", int, s
, int, backlog
, int, version
);
10456 #if defined(SOLARIS_NEW_ACCEPT_SYSCALL)
10457 /* int accept(int s, struct sockaddr *addr, socklen_t *addrlen,
10458 int version, int flags); */
10459 *flags
|= SfMayBlock
;
10460 PRINT("sys_accept ( %ld, %#lx, %#lx, %ld, %ld )", SARG1
, ARG2
, ARG3
, SARG4
,
10462 PRE_REG_READ5(long, "accept", int, s
, struct sockaddr
*, addr
,
10463 socklen_t
*, addrlen
, int, version
, int, flags
);
10465 /* int accept(int s, struct sockaddr *addr, socklen_t *addrlen,
10467 *flags
|= SfMayBlock
;
10468 PRINT("sys_accept ( %ld, %#lx, %#lx, %ld )", SARG1
, ARG2
, ARG3
, SARG4
);
10469 PRE_REG_READ4(long, "accept", int, s
, struct sockaddr
*, addr
,
10470 socklen_t
*, addrlen
, int, version
);
10471 #endif /* SOLARIS_NEW_ACCEPT_SYSCALL */
10472 ML_(generic_PRE_sys_accept
)(tid
, ARG1
, ARG2
, ARG3
);
10478 r
= ML_(generic_POST_sys_accept
)(tid
, VG_(mk_SysRes_Success
)(RES
),
10480 SET_STATUS_from_SysRes(r
);
10485 /* int connect(int s, struct sockaddr *name, socklen_t namelen,
10487 *flags
|= SfMayBlock
;
10488 PRINT("sys_connect ( %ld, %#lx, %lu, %ld )", SARG1
, ARG2
, ARG3
, SARG4
);
10489 PRE_REG_READ4(long, "connect", int, s
, struct sockaddr
*, name
,
10490 vki_socklen_t
, namelen
, int, version
);
10491 ML_(generic_PRE_sys_connect
)(tid
, ARG1
, ARG2
, ARG3
);
10496 /* Kernel: int shutdown(int sock, int how, int version);
10497 Libc: int shutdown(int sock, int how);
10499 *flags
|= SfMayBlock
;
10500 PRINT("sys_shutdown ( %ld, %ld, %ld )", SARG1
, SARG2
, SARG3
);
10501 PRE_REG_READ3(int, "shutdown", int, sock
, int, how
, int, version
);
10504 if (!ML_(fd_allowed
)(ARG1
, "shutdown", tid
, False
))
10505 SET_STATUS_Failure(VKI_EBADF
);
10510 /* ssize_t recv(int s, void *buf, size_t len, int flags); */
10511 *flags
|= SfMayBlock
;
10512 PRINT("sys_recv ( %ld, %#lx, %lu, %ld )", SARG1
, ARG2
, ARG3
, SARG4
);
10513 PRE_REG_READ4(long, "recv", int, s
, void *, buf
, vki_size_t
, len
,
10515 ML_(generic_PRE_sys_recv
)(tid
, ARG1
, ARG2
, ARG3
);
10520 ML_(generic_POST_sys_recv
)(tid
, RES
, ARG1
, ARG2
, ARG3
);
10525 /* ssize_t recvfrom(int s, void *buf, size_t len, int flags,
10526 struct sockaddr *from, socklen_t *fromlen); */
10527 *flags
|= SfMayBlock
;
10528 PRINT("sys_recvfrom ( %ld, %#lx, %lu, %ld, %#lx, %#lx )", SARG1
, ARG2
, ARG3
,
10529 SARG4
, ARG5
, ARG6
);
10530 PRE_REG_READ6(long, "recvfrom", int, s
, void *, buf
, vki_size_t
, len
,
10531 int, flags
, struct sockaddr
*, from
, socklen_t
*, fromlen
);
10532 ML_(generic_PRE_sys_recvfrom
)(tid
, ARG1
, ARG2
, ARG3
, ARG4
, ARG5
, ARG6
);
10537 ML_(generic_POST_sys_recvfrom
)(tid
, VG_(mk_SysRes_Success
)(RES
),
10538 ARG1
, ARG2
, ARG3
, ARG4
, ARG5
, ARG6
);
10543 /* ssize_t recvmsg(int s, struct msghdr *msg, int flags); */
10544 *flags
|= SfMayBlock
;
10545 PRINT("sys_recvmsg ( %ld, %#lx, %ld )", SARG1
, ARG2
, SARG3
);
10546 PRE_REG_READ3(long, "recvmsg", int, s
, struct msghdr
*, msg
, int, flags
);
10547 ML_(generic_PRE_sys_recvmsg
)(tid
, "msg", (struct vki_msghdr
*)ARG2
);
10552 ML_(generic_POST_sys_recvmsg
)(tid
, "msg", (struct vki_msghdr
*)ARG2
, RES
);
10557 /* ssize_t send(int s, const void *msg, size_t len, int flags); */
10558 *flags
|= SfMayBlock
;
10559 PRINT("sys_send ( %ld, %#lx, %lu, %ld )", SARG1
, ARG2
, ARG3
, SARG4
);
10560 PRE_REG_READ4(long, "send", int, s
, const void *, msg
, vki_size_t
, len
,
10562 ML_(generic_PRE_sys_send
)(tid
, ARG1
, ARG2
, ARG3
);
10567 /* ssize_t sendmsg(int s, const struct msghdr *msg, int flags); */
10568 *flags
|= SfMayBlock
;
10569 PRINT("sys_sendmsg ( %ld, %#lx, %ld )", SARG1
, ARG2
, SARG3
);
10570 PRE_REG_READ3(long, "sendmsg", int, s
, const struct msghdr
*, msg
,
10572 ML_(generic_PRE_sys_sendmsg
)(tid
, "msg", (struct vki_msghdr
*)ARG2
);
10577 /* ssize_t sendto(int s, const void *msg, size_t len, int flags,
10578 const struct sockaddr *to, int tolen); */
10579 *flags
|= SfMayBlock
;
10580 PRINT("sys_sendto ( %ld, %#lx, %lu, %ld, %#lx, %ld )", SARG1
, ARG2
, ARG3
,
10581 SARG4
, ARG5
, SARG6
);
10582 PRE_REG_READ6(long, "sendto", int, s
, const void *, msg
, vki_size_t
, len
,
10583 int, flags
, const struct sockaddr
*, to
, int, tolen
);
10584 ML_(generic_PRE_sys_sendto
)(tid
, ARG1
, ARG2
, ARG3
, ARG4
, ARG5
, ARG6
);
10587 PRE(sys_getpeername
)
10589 /* Kernel: int getpeername(int s, struct sockaddr *name,
10590 socklen_t *namelen, int version);
10591 Libc: int getpeername(int s, struct sockaddr *name,
10592 socklen_t *namelen);
10594 *flags
|= SfMayBlock
;
10595 PRINT("sys_getpeername ( %ld, %#lx, %#lx, %ld )",
10596 SARG1
, ARG2
, ARG3
, SARG4
);
10597 PRE_REG_READ4(long, "getpeername", int, s
, struct vki_sockaddr
*, name
,
10598 vki_socklen_t
*, namelen
, int, version
);
10599 ML_(buf_and_len_pre_check
)(tid
, ARG2
, ARG3
, "getpeername(name)",
10600 "getpeername(namelen)");
10603 if (!ML_(fd_allowed
)(ARG1
, "getpeername", tid
, False
))
10604 SET_STATUS_Failure(VKI_EBADF
);
10607 POST(sys_getpeername
)
10609 ML_(buf_and_len_post_check
)(tid
, VG_(mk_SysRes_Success
)(RES
),
10610 ARG2
, ARG3
, "getpeername(namelen)");
10613 PRE(sys_getsockname
)
10615 /* int getsockname(int s, struct sockaddr *name, socklen_t *namelen,
10617 PRINT("sys_getsockname ( %ld, %#lx, %#lx, %ld )", SARG1
, ARG2
, ARG3
, SARG4
);
10618 PRE_REG_READ4(long, "getsockname", int, s
, struct sockaddr
*, name
,
10619 socklen_t
*, namelen
, int, version
);
10620 ML_(generic_PRE_sys_getsockname
)(tid
, ARG1
, ARG2
, ARG3
);
10623 POST(sys_getsockname
)
10625 ML_(generic_POST_sys_getsockname
)(tid
, VG_(mk_SysRes_Success
)(RES
),
10629 PRE(sys_getsockopt
)
10631 /* int getsockopt(int s, int level, int optname, void *optval,
10632 socklen_t *optlen, int version); */
10633 PRINT("sys_getsockopt ( %ld, %ld, %ld, %#lx, %#lx, %ld )", SARG1
, SARG2
,
10634 SARG3
, ARG4
, ARG5
, SARG6
);
10635 PRE_REG_READ6(long, "getsockopt", int, s
, int, level
, int, optname
,
10636 void *, optval
, socklen_t
*, option
, int, version
);
10638 ML_(buf_and_len_pre_check
)(tid
, ARG4
, ARG5
, "getsockopt(optval)",
10639 "getsockopt(optlen)");
10642 POST(sys_getsockopt
)
10645 ML_(buf_and_len_post_check
)(tid
, VG_(mk_SysRes_Success
)(RES
), ARG4
,
10646 ARG5
, "getsockopt(optlen_out)");
10649 PRE(sys_setsockopt
)
10651 /* int setsockopt(int s, int level, int optname, const void *optval,
10652 socklen_t optlen, int version); */
10653 PRINT("sys_setsockopt ( %ld, %ld, %ld, %#lx, %lu, %ld )", SARG1
, SARG2
,
10654 SARG3
, ARG4
, ARG5
, SARG6
);
10655 PRE_REG_READ6(long, "setsockopt", int, s
, int, level
, int, optname
,
10656 const void *, optval
, vki_socklen_t
, optlen
, int, version
);
10657 ML_(generic_PRE_sys_setsockopt
)(tid
, ARG1
, ARG2
, ARG3
, ARG4
, ARG5
);
10660 PRE(sys_lwp_mutex_register
)
10662 /* int lwp_mutex_register(lwp_mutex_t *mp, caddr_t uaddr); */
10663 vki_lwp_mutex_t
*mp
= (vki_lwp_mutex_t
*)ARG1
;
10664 PRINT("sys_lwp_mutex_register ( %#lx, %#lx )", ARG1
, ARG2
);
10665 PRE_REG_READ2(long, "lwp_mutex_register", lwp_mutex_t
*, mp
,
10667 PRE_FIELD_READ("lwp_mutex_register(mp->mutex_type)", mp
->vki_mutex_type
);
10670 PRE(sys_lwp_mutex_unlock
)
10672 /* int lwp_mutex_unlock(lwp_mutex_t *lp); */
10673 /* see https://github.com/illumos/illumos-gate/blob/master/usr/src/uts/common/syscall/lwp_sobj.c#L3137-L3138
10674 * (illumos, obviously) */
10675 vki_lwp_mutex_t
*lp
= (vki_lwp_mutex_t
*)ARG1
;
10676 PRINT("sys_lwp_mutex_unlock ( %#lx )", ARG1
);
10677 PRE_REG_READ1(int, "lwp_mutex_unlock", lwp_mutex_t
*, lp
);
10678 PRE_MEM_READ("lwp_mutex_unlock(lp)", (Addr
)lp
, sizeof(vki_lwp_mutex_t
));
10679 PRE_MEM_WRITE("lwp_mutex_unlock(lp)", (Addr
)lp
, sizeof(vki_lwp_mutex_t
));
10682 POST(sys_lwp_mutex_unlock
)
10684 POST_MEM_WRITE(ARG1
, sizeof(vki_lwp_mutex_t
));
10689 /* int uucopy(const void *s1, void *s2, size_t n); */
10690 PRINT("sys_uucopy ( %#lx, %#lx, %lu )", ARG1
, ARG2
, ARG3
);
10691 PRE_REG_READ3(long, "uucopy", const void *, s1
, void *, s2
, vki_size_t
, n
);
10693 /* Stay away from V segments. */
10694 if (!ML_(valid_client_addr
)(ARG1
, ARG3
, tid
, "uucopy(s1)")) {
10695 SET_STATUS_Failure(VKI_EFAULT
);
10697 if (!ML_(valid_client_addr
)(ARG2
, ARG3
, tid
, "uucopy(s2)")) {
10698 SET_STATUS_Failure(VKI_EFAULT
);
10704 /* XXX This is actually incorrect, we should be able to copy undefined
10705 values through to their new destination. */
10706 PRE_MEM_READ("uucopy(s1)", ARG1
, ARG3
);
10707 PRE_MEM_WRITE("uucopy(s2)", ARG2
, ARG3
);
10712 POST_MEM_WRITE(ARG2
, ARG3
);
10717 /* int umount2(const char *file, int mflag); */
10718 *flags
|= SfMayBlock
;
10719 PRINT("sys_umount2 ( %#lx(%s), %ld )", ARG1
, (HChar
*) ARG1
, SARG2
);
10720 PRE_REG_READ2(long, "umount2", const char *, file
, int, mflag
);
10721 PRE_MEM_RASCIIZ("umount2(file)", ARG1
);
10724 PRE(fast_gethrtime
)
10726 PRINT("fast_gethrtime ( )");
10727 PRE_REG_READ0(long, "gethrtime");
10730 PRE(fast_gethrvtime
)
10732 PRINT("fast_gethrvtime ( )");
10733 PRE_REG_READ0(long, "gethrvtime");
10736 PRE(fast_gethrestime
)
10738 /* Used by gettimeofday(3C). */
10739 PRINT("fast_gethrestime ( )");
10740 PRE_REG_READ0(long, "gethrestime");
10745 /* Fasttrap number shared between gethomelgroup() and getcpuid(). */
10746 PRINT("fast_getlgrp ( )");
10747 PRE_REG_READ0(long, "getlgrp");
10750 #if defined(SOLARIS_GETHRT_FASTTRAP)
10753 /* Used by gethrtime(3C) when tsp & tscp HWCAPs are present. */
10754 PRINT("fast_gethrt ( )");
10755 PRE_REG_READ0(long, "gethrt");
10763 VG_(change_mapping_ownership
)(RES
, False
);
10765 #endif /* SOLARIS_GETHRT_FASTTRAP */
10767 #if defined(SOLARIS_GETZONEOFFSET_FASTTRAP)
10768 PRE(fast_getzoneoffset
)
10770 /* Returns kernel's time zone offset data. */
10771 PRINT("fast_getzoneoffset ( )");
10772 PRE_REG_READ0(long, "get_zone_offset");
10775 POST(fast_getzoneoffset
)
10780 VG_(change_mapping_ownership
)(RES
, False
);
10782 #endif /* SOLARIS_GETZONEOFFSET_FASTTRAP */
10787 /* ---------------------------------------------------------------------
10788 The Solaris syscall table
10789 ------------------------------------------------------------------ */
10791 /* Add a Solaris-specific, arch-independent wrapper to a syscall table. */
10792 #define SOLX_(sysno, name) \
10793 WRAPPER_ENTRY_X_(solaris, VG_SOLARIS_SYSNO_INDEX(sysno), name)
10794 #define SOLXY(sysno, name) \
10795 WRAPPER_ENTRY_XY(solaris, VG_SOLARIS_SYSNO_INDEX(sysno), name)
10797 #if defined(VGP_x86_solaris)
10798 /* Add an x86-solaris specific wrapper to a syscall table. */
10799 #define PLAX_(sysno, name) \
10800 WRAPPER_ENTRY_X_(x86_solaris, VG_SOLARIS_SYSNO_INDEX(sysno), name)
10801 #define PLAXY(sysno, name) \
10802 WRAPPER_ENTRY_XY(x86_solaris, VG_SOLARIS_SYSNO_INDEX(sysno), name)
10804 #elif defined(VGP_amd64_solaris)
10805 /* Add an amd64-solaris specific wrapper to a syscall table. */
10806 #define PLAX_(sysno, name) \
10807 WRAPPER_ENTRY_X_(amd64_solaris, VG_SOLARIS_SYSNO_INDEX(sysno), name)
10808 #define PLAXY(sysno, name) \
10809 WRAPPER_ENTRY_XY(amd64_solaris, VG_SOLARIS_SYSNO_INDEX(sysno), name)
10812 # error "Unknown platform"
10816 GEN : handlers are in syswrap-generic.c
10817 SOL : handlers are in this file
10818 X_ : PRE handler only
10819 XY : PRE and POST handlers
10822 static SyscallTableEntry syscall_table
[] = {
10823 SOLX_(__NR_exit
, sys_exit
), /* 1 */
10824 #if defined(SOLARIS_SPAWN_SYSCALL)
10825 SOLX_(__NR_spawn
, sys_spawn
), /* 2 */
10826 #endif /* SOLARIS_SPAWN_SYSCALL */
10827 GENXY(__NR_read
, sys_read
), /* 3 */
10828 GENX_(__NR_write
, sys_write
), /* 4 */
10829 #if defined(SOLARIS_OLD_SYSCALLS)
10830 SOLXY(__NR_open
, sys_open
), /* 5 */
10831 #endif /* SOLARIS_OLD_SYSCALLS */
10832 SOLXY(__NR_close
, sys_close
), /* 6 */
10833 SOLX_(__NR_linkat
, sys_linkat
), /* 7 */
10834 #if defined(SOLARIS_OLD_SYSCALLS)
10835 GENX_(__NR_link
, sys_link
), /* 9 */
10836 GENX_(__NR_unlink
, sys_unlink
), /* 10 */
10837 #endif /* SOLARIS_OLD_SYSCALLS */
10838 SOLX_(__NR_symlinkat
, sys_symlinkat
), /* 11 */
10839 GENX_(__NR_chdir
, sys_chdir
), /* 12 */
10840 SOLX_(__NR_time
, sys_time
), /* 13 */
10841 #if defined(SOLARIS_OLD_SYSCALLS)
10842 GENX_(__NR_chmod
, sys_chmod
), /* 15 */
10843 GENX_(__NR_chown
, sys_chown
), /* 16 */
10844 #endif /* SOLARIS_OLD_SYSCALLS */
10845 SOLX_(__NR_brk
, sys_brk
), /* 17 */
10846 #if defined(SOLARIS_OLD_SYSCALLS)
10847 SOLXY(__NR_stat
, sys_stat
), /* 18 */
10848 #endif /* SOLARIS_OLD_SYSCALLS */
10849 SOLX_(__NR_lseek
, sys_lseek
), /* 19 */
10850 GENX_(__NR_getpid
, sys_getpid
), /* 20 */
10851 SOLXY(__NR_mount
, sys_mount
), /* 21 */
10852 SOLXY(__NR_readlinkat
, sys_readlinkat
), /* 22 */
10853 GENX_(__NR_setuid
, sys_setuid
), /* 23 */
10854 GENX_(__NR_getuid
, sys_getuid
), /* 24 */
10855 SOLX_(__NR_stime
, sys_stime
), /* 25 */
10856 GENX_(__NR_alarm
, sys_alarm
), /* 27 */
10857 #if defined(SOLARIS_OLD_SYSCALLS)
10858 SOLXY(__NR_fstat
, sys_fstat
), /* 28 */
10859 #endif /* SOLARIS_OLD_SYSCALLS */
10860 GENX_(__NR_pause
, sys_pause
), /* 29 */
10861 #if defined(SOLARIS_FREALPATHAT_SYSCALL)
10862 SOLXY(__NR_frealpathat
, sys_frealpathat
), /* 30 */
10863 #endif /* SOLARIS_FREALPATHAT_SYSCALL */
10864 SOLX_(__NR_stty
, sys_stty
), /* 31 */
10865 SOLXY(__NR_gtty
, sys_gtty
), /* 32 */
10866 #if defined(SOLARIS_OLD_SYSCALLS)
10867 GENX_(__NR_access
, sys_access
), /* 33 */
10868 #endif /* SOLARIS_OLD_SYSCALLS */
10869 GENX_(__NR_kill
, sys_kill
), /* 37 */
10870 SOLX_(__NR_pgrpsys
, sys_pgrpsys
), /* 39 */
10871 SOLXY(__NR_pipe
, sys_pipe
), /* 42 */
10872 GENXY(__NR_times
, sys_times
), /* 43 */
10873 SOLX_(__NR_faccessat
, sys_faccessat
), /* 45 */
10874 GENX_(__NR_setgid
, sys_setgid
), /* 46 */
10875 GENX_(__NR_getgid
, sys_getgid
), /* 47 */
10876 SOLXY(__NR_mknodat
, sys_mknodat
), /* 48 */
10877 SOLXY(__NR_sysi86
, sys_sysi86
), /* 50 */
10878 SOLXY(__NR_shmsys
, sys_shmsys
), /* 52 */
10879 SOLXY(__NR_semsys
, sys_semsys
), /* 53 */
10880 SOLXY(__NR_ioctl
, sys_ioctl
), /* 54 */
10881 SOLX_(__NR_fchownat
, sys_fchownat
), /* 56 */
10882 SOLX_(__NR_fdsync
, sys_fdsync
), /* 58 */
10883 SOLX_(__NR_execve
, sys_execve
), /* 59 */
10884 GENX_(__NR_umask
, sys_umask
), /* 60 */
10885 GENX_(__NR_chroot
, sys_chroot
), /* 61 */
10886 SOLXY(__NR_fcntl
, sys_fcntl
), /* 62 */
10887 SOLX_(__NR_renameat
, sys_renameat
), /* 64 */
10888 SOLX_(__NR_unlinkat
, sys_unlinkat
), /* 65 */
10889 SOLXY(__NR_fstatat
, sys_fstatat
), /* 66 */
10890 #if defined(VGP_x86_solaris)
10891 PLAXY(__NR_fstatat64
, sys_fstatat64
), /* 67 */
10892 #endif /* VGP_x86_solaris */
10893 SOLXY(__NR_openat
, sys_openat
), /* 68 */
10894 #if defined(VGP_x86_solaris)
10895 PLAXY(__NR_openat64
, sys_openat64
), /* 69 */
10896 #endif /* VGP_x86_solaris */
10897 SOLXY(__NR_tasksys
, sys_tasksys
), /* 70 */
10898 SOLXY(__NR_getpagesizes
, sys_getpagesizes
), /* 73 */
10899 SOLXY(__NR_lwp_park
, sys_lwp_park
), /* 77 */
10900 SOLXY(__NR_sendfilev
, sys_sendfilev
), /* 78 */
10901 #if defined(SOLARIS_LWP_NAME_SYSCALL)
10902 SOLXY(__NR_lwp_name
, sys_lwp_name
), /* 79 */
10903 #endif /* SOLARIS_LWP_NAME_SYSCALL */
10904 #if defined(SOLARIS_OLD_SYSCALLS)
10905 GENX_(__NR_rmdir
, sys_rmdir
), /* 79 */
10906 GENX_(__NR_mkdir
, sys_mkdir
), /* 80 */
10907 #endif /* SOLARIS_OLD_SYSCALLS */
10908 GENXY(__NR_getdents
, sys_getdents
), /* 81 */
10909 SOLXY(__NR_privsys
, sys_privsys
), /* 82 */
10910 SOLXY(__NR_ucredsys
, sys_ucredsys
), /* 83 */
10911 SOLXY(__NR_sysfs
, sys_sysfs
), /* 84 */
10912 SOLXY(__NR_getmsg
, sys_getmsg
), /* 85 */
10913 SOLX_(__NR_putmsg
, sys_putmsg
), /* 86 */
10914 #if defined(SOLARIS_OLD_SYSCALLS)
10915 SOLXY(__NR_lstat
, sys_lstat
), /* 88 */
10916 GENX_(__NR_symlink
, sys_symlink
), /* 89 */
10917 GENX_(__NR_readlink
, sys_readlink
), /* 90 */
10918 #endif /* SOLARIS_OLD_SYSCALLS */
10919 GENX_(__NR_setgroups
, sys_setgroups
), /* 91 */
10920 GENXY(__NR_getgroups
, sys_getgroups
), /* 92 */
10921 #if defined(SOLARIS_OLD_SYSCALLS)
10922 GENX_(__NR_fchmod
, sys_fchmod
), /* 93 */
10923 GENX_(__NR_fchown
, sys_fchown
), /* 94 */
10924 #endif /* SOLARIS_OLD_SYSCALLS */
10925 SOLXY(__NR_sigprocmask
, sys_sigprocmask
), /* 95 */
10926 SOLX_(__NR_sigsuspend
, sys_sigsuspend
), /* 96 */
10927 GENXY(__NR_sigaltstack
, sys_sigaltstack
), /* 97 */
10928 SOLXY(__NR_sigaction
, sys_sigaction
), /* 98 */
10929 SOLXY(__NR_sigpending
, sys_sigpending
), /* 99 */
10930 SOLX_(__NR_context
, sys_getsetcontext
), /* 100 */
10931 SOLX_(__NR_fchmodat
, sys_fchmodat
), /* 101 */
10932 SOLX_(__NR_mkdirat
, sys_mkdirat
), /* 102 */
10933 SOLXY(__NR_statvfs
, sys_statvfs
), /* 103 */
10934 SOLXY(__NR_fstatvfs
, sys_fstatvfs
), /* 104 */
10935 SOLXY(__NR_nfssys
, sys_nfssys
), /* 106 */
10936 SOLXY(__NR_waitid
, sys_waitid
), /* 107 */
10937 SOLX_(__NR_sigsendsys
, sys_sigsendsys
), /* 108 */
10938 #if defined(SOLARIS_UTIMESYS_SYSCALL)
10939 SOLX_(__NR_utimesys
, sys_utimesys
), /* 110 */
10940 #endif /* SOLARIS_UTIMESYS_SYSCALL */
10941 #if defined(SOLARIS_UTIMENSAT_SYSCALL)
10942 SOLX_(__NR_utimensat
, sys_utimensat
), /* 110 */
10943 #endif /* SOLARIS_UTIMENSAT_SYSCALL */
10944 SOLXY(__NR_sigresend
, sys_sigresend
), /* 111 */
10945 SOLXY(__NR_priocntlsys
, sys_priocntlsys
), /* 112 */
10946 SOLX_(__NR_pathconf
, sys_pathconf
), /* 113 */
10947 SOLX_(__NR_mmap
, sys_mmap
), /* 115 */
10948 GENXY(__NR_mprotect
, sys_mprotect
), /* 116 */
10949 GENXY(__NR_munmap
, sys_munmap
), /* 117 */
10950 GENX_(__NR_fchdir
, sys_fchdir
), /* 120 */
10951 GENXY(__NR_readv
, sys_readv
), /* 121 */
10952 GENX_(__NR_writev
, sys_writev
), /* 122 */
10953 #if defined(SOLARIS_UUIDSYS_SYSCALL)
10954 SOLXY(__NR_uuidsys
, sys_uuidsys
), /* 124 */
10955 #endif /* SOLARIS_UUIDSYS_SYSCALL */
10956 SOLX_(__NR_mmapobj
, sys_mmapobj
), /* 127 */
10957 GENX_(__NR_setrlimit
, sys_setrlimit
), /* 128 */
10958 GENXY(__NR_getrlimit
, sys_getrlimit
), /* 129 */
10959 #if defined(SOLARIS_OLD_SYSCALLS)
10960 GENX_(__NR_lchown
, sys_lchown
), /* 130 */
10961 #endif /* SOLARIS_OLD_SYSCALLS */
10962 SOLX_(__NR_memcntl
, sys_memcntl
), /* 131 */
10963 SOLXY(__NR_getpmsg
, sys_getpmsg
), /* 132 */
10964 SOLX_(__NR_putpmsg
, sys_putpmsg
), /* 133 */
10965 #if defined(SOLARIS_OLD_SYSCALLS)
10966 SOLX_(__NR_rename
, sys_rename
), /* 134 */
10967 #endif /* SOLARIS_OLD_SYSCALLS */
10968 SOLXY(__NR_uname
, sys_uname
), /* 135 */
10969 SOLX_(__NR_setegid
, sys_setegid
), /* 136 */
10970 SOLX_(__NR_sysconfig
, sys_sysconfig
), /* 137 */
10971 SOLXY(__NR_systeminfo
, sys_systeminfo
), /* 139 */
10972 SOLX_(__NR_seteuid
, sys_seteuid
), /* 141 */
10973 SOLX_(__NR_forksys
, sys_forksys
), /* 142 */
10974 #if defined(SOLARIS_GETRANDOM_SYSCALL)
10975 SOLXY(__NR_getrandom
, sys_getrandom
), /* 143 */
10976 #endif /* SOLARIS_GETRANDOM_SYSCALL */
10977 SOLXY(__NR_sigtimedwait
, sys_sigtimedwait
), /* 144 */
10978 SOLX_(__NR_yield
, sys_yield
), /* 146 */
10979 SOLXY(__NR_lwp_sema_post
, sys_lwp_sema_post
), /* 148 */
10980 SOLXY(__NR_lwp_sema_trywait
, sys_lwp_sema_trywait
), /* 149 */
10981 SOLX_(__NR_lwp_detach
, sys_lwp_detach
), /* 150 */
10982 SOLXY(__NR_modctl
, sys_modctl
), /* 152 */
10983 SOLX_(__NR_fchroot
, sys_fchroot
), /* 153 */
10984 #if defined(SOLARIS_SYSTEM_STATS_SYSCALL)
10985 SOLX_(__NR_system_stats
, sys_system_stats
), /* 154 */
10986 #endif /* SOLARIS_SYSTEM_STATS_SYSCALL */
10987 SOLXY(__NR_gettimeofday
, sys_gettimeofday
), /* 156 */
10988 GENXY(__NR_getitimer
, sys_getitimer
), /* 157 */
10989 GENXY(__NR_setitimer
, sys_setitimer
), /* 158 */
10990 SOLX_(__NR_lwp_create
, sys_lwp_create
), /* 159 */
10991 SOLX_(__NR_lwp_exit
, sys_lwp_exit
), /* 160 */
10992 SOLX_(__NR_lwp_suspend
, sys_lwp_suspend
), /* 161 */
10993 SOLX_(__NR_lwp_continue
, sys_lwp_continue
), /* 162 */
10994 #if defined(SOLARIS_LWP_SIGQUEUE_SYSCALL)
10995 SOLXY(__NR_lwp_sigqueue
, sys_lwp_sigqueue
), /* 163 */
10997 SOLXY(__NR_lwp_kill
, sys_lwp_kill
), /* 163 */
10998 #endif /* SOLARIS_LWP_SIGQUEUE_SYSCALL */
10999 SOLX_(__NR_lwp_self
, sys_lwp_self
), /* 164 */
11000 SOLX_(__NR_lwp_sigmask
, sys_lwp_sigmask
), /* 165 */
11001 SOLX_(__NR_lwp_private
, sys_lwp_private
), /* 166 */
11002 SOLXY(__NR_lwp_wait
, sys_lwp_wait
), /* 167 */
11003 SOLXY(__NR_lwp_mutex_wakeup
, sys_lwp_mutex_wakeup
), /* 168 */
11004 SOLXY(__NR_lwp_cond_wait
, sys_lwp_cond_wait
), /* 170 */
11005 SOLXY(__NR_lwp_cond_signal
, sys_lwp_cond_signal
), /* 171 */
11006 SOLX_(__NR_lwp_cond_broadcast
, sys_lwp_cond_broadcast
), /* 172 */
11007 SOLXY(__NR_pread
, sys_pread
), /* 173 */
11008 SOLX_(__NR_pwrite
, sys_pwrite
), /* 174 */
11009 #if defined(VGP_x86_solaris)
11010 PLAX_(__NR_llseek
, sys_llseek32
), /* 175 */
11011 #endif /* VGP_x86_solaris */
11012 SOLXY(__NR_lgrpsys
, sys_lgrpsys
), /* 180 */
11013 SOLXY(__NR_rusagesys
, sys_rusagesys
), /* 181 */
11014 SOLXY(__NR_port
, sys_port
), /* 182 */
11015 SOLXY(__NR_pollsys
, sys_pollsys
), /* 183 */
11016 SOLXY(__NR_labelsys
, sys_labelsys
), /* 184 */
11017 SOLXY(__NR_acl
, sys_acl
), /* 185 */
11018 SOLXY(__NR_auditsys
, sys_auditsys
), /* 186 */
11019 SOLX_(__NR_p_online
, sys_p_online
), /* 189 */
11020 SOLX_(__NR_sigqueue
, sys_sigqueue
), /* 190 */
11021 SOLXY(__NR_clock_gettime
, sys_clock_gettime
), /* 191 */
11022 SOLX_(__NR_clock_settime
, sys_clock_settime
), /* 192 */
11023 SOLXY(__NR_clock_getres
, sys_clock_getres
), /* 193 */
11024 SOLXY(__NR_timer_create
, sys_timer_create
), /* 194 */
11025 SOLX_(__NR_timer_delete
, sys_timer_delete
), /* 195 */
11026 SOLXY(__NR_timer_settime
, sys_timer_settime
), /* 196 */
11027 SOLXY(__NR_timer_gettime
, sys_timer_gettime
), /* 197 */
11028 SOLX_(__NR_timer_getoverrun
, sys_timer_getoverrun
), /* 198 */
11029 GENXY(__NR_nanosleep
, sys_nanosleep
), /* 199 */
11030 SOLXY(__NR_facl
, sys_facl
), /* 200 */
11031 SOLXY(__NR_door
, sys_door
), /* 201 */
11032 GENX_(__NR_setreuid
, sys_setreuid
), /* 202 */
11033 GENX_(__NR_setregid
, sys_setregid
), /* 202 */
11034 SOLXY(__NR_schedctl
, sys_schedctl
), /* 206 */
11035 SOLXY(__NR_pset
, sys_pset
), /* 207 */
11036 SOLXY(__NR_resolvepath
, sys_resolvepath
), /* 209 */
11037 SOLXY(__NR_lwp_mutex_timedlock
, sys_lwp_mutex_timedlock
), /* 210 */
11038 SOLXY(__NR_lwp_sema_timedwait
, sys_lwp_sema_timedwait
), /* 211 */
11039 SOLXY(__NR_lwp_rwlock_sys
, sys_lwp_rwlock_sys
), /* 212 */
11040 #if defined(VGP_x86_solaris)
11041 GENXY(__NR_getdents64
, sys_getdents64
), /* 213 */
11042 PLAX_(__NR_mmap64
, sys_mmap64
), /* 214 */
11043 #if defined(SOLARIS_OLD_SYSCALLS)
11044 PLAXY(__NR_stat64
, sys_stat64
), /* 215 */
11045 PLAXY(__NR_lstat64
, sys_lstat64
), /* 216 */
11046 PLAXY(__NR_fstat64
, sys_fstat64
), /* 217 */
11047 #endif /* SOLARIS_OLD_SYSCALLS */
11048 PLAXY(__NR_statvfs64
, sys_statvfs64
), /* 218 */
11049 PLAXY(__NR_fstatvfs64
, sys_fstatvfs64
), /* 219 */
11050 #endif /* VGP_x86_solaris */
11051 #if defined(VGP_x86_solaris)
11052 PLAX_(__NR_setrlimit64
, sys_setrlimit64
), /* 220 */
11053 PLAXY(__NR_getrlimit64
, sys_getrlimit64
), /* 221 */
11054 PLAXY(__NR_pread64
, sys_pread64
), /* 222 */
11055 PLAX_(__NR_pwrite64
, sys_pwrite64
), /* 223 */
11056 #if defined(SOLARIS_OLD_SYSCALLS)
11057 PLAXY(__NR_open64
, sys_open64
), /* 225 */
11058 #endif /* SOLARIS_OLD_SYSCALLS */
11059 #endif /* VGP_x86_solaris */
11060 SOLXY(__NR_zone
, sys_zone
), /* 227 */
11061 SOLXY(__NR_getcwd
, sys_getcwd
), /* 229 */
11062 SOLXY(__NR_so_socket
, sys_so_socket
), /* 230 */
11063 SOLXY(__NR_so_socketpair
, sys_so_socketpair
), /* 231 */
11064 SOLX_(__NR_bind
, sys_bind
), /* 232 */
11065 SOLX_(__NR_listen
, sys_listen
), /* 233 */
11066 SOLXY(__NR_accept
, sys_accept
), /* 234 */
11067 SOLX_(__NR_connect
, sys_connect
), /* 235 */
11068 SOLX_(__NR_shutdown
, sys_shutdown
), /* 236 */
11069 SOLXY(__NR_recv
, sys_recv
), /* 237 */
11070 SOLXY(__NR_recvfrom
, sys_recvfrom
), /* 238 */
11071 SOLXY(__NR_recvmsg
, sys_recvmsg
), /* 239 */
11072 SOLX_(__NR_send
, sys_send
), /* 240 */
11073 SOLX_(__NR_sendmsg
, sys_sendmsg
), /* 241 */
11074 SOLX_(__NR_sendto
, sys_sendto
), /* 242 */
11075 SOLXY(__NR_getpeername
, sys_getpeername
), /* 243 */
11076 SOLXY(__NR_getsockname
, sys_getsockname
), /* 244 */
11077 SOLXY(__NR_getsockopt
, sys_getsockopt
), /* 245 */
11078 SOLX_(__NR_setsockopt
, sys_setsockopt
), /* 246 */
11079 SOLXY(__NR_lwp_mutex_unlock
, sys_lwp_mutex_unlock
), /* 250 */
11080 SOLX_(__NR_lwp_mutex_register
, sys_lwp_mutex_register
), /* 252 */
11081 SOLXY(__NR_uucopy
, sys_uucopy
), /* 254 */
11082 SOLX_(__NR_umount2
, sys_umount2
) /* 255 */
11085 static SyscallTableEntry fasttrap_table
[] = {
11086 SOLX_(__NR_gethrtime
, fast_gethrtime
), /* 3 */
11087 SOLX_(__NR_gethrvtime
, fast_gethrvtime
), /* 4 */
11088 SOLX_(__NR_gethrestime
, fast_gethrestime
), /* 5 */
11089 SOLX_(__NR_getlgrp
, fast_getlgrp
) /* 6 */
11090 #if defined(SOLARIS_GETHRT_FASTTRAP)
11092 SOLXY(__NR_gethrt
, fast_gethrt
) /* 7 */
11093 #endif /* SOLARIS_GETHRT_FASTTRAP */
11094 #if defined(SOLARIS_GETZONEOFFSET_FASTTRAP)
11096 SOLXY(__NR_getzoneoffset
, fast_getzoneoffset
) /* 8 */
11097 #endif /* SOLARIS_GETZONEOFFSET_FASTTRAP */
11101 SyscallTableEntry
*ML_(get_solaris_syscall_entry
)(UInt sysno
)
11103 const UInt syscall_table_size
11104 = sizeof(syscall_table
) / sizeof(syscall_table
[0]);
11105 const UInt fasttrap_table_size
11106 = sizeof(fasttrap_table
) / sizeof(fasttrap_table
[0]);
11108 SyscallTableEntry
*table
;
11111 switch (VG_SOLARIS_SYSNO_CLASS(sysno
)) {
11112 case VG_SOLARIS_SYSCALL_CLASS_CLASSIC
:
11113 table
= syscall_table
;
11114 size
= syscall_table_size
;
11116 case VG_SOLARIS_SYSCALL_CLASS_FASTTRAP
:
11117 table
= fasttrap_table
;
11118 size
= fasttrap_table_size
;
11124 sysno
= VG_SOLARIS_SYSNO_INDEX(sysno
);
11125 if (sysno
< size
) {
11126 SyscallTableEntry
*sys
= &table
[sysno
];
11128 return NULL
; /* no entry */
11132 /* Can't find a wrapper. */
11136 #endif // defined(VGO_solaris)
11138 /*--------------------------------------------------------------------*/
11140 /*--------------------------------------------------------------------*/