pub_core_ume.h \
pub_core_vki.h \
pub_core_vkiscnums.h \
+ pub_core_vkiscnums_asm.h\
pub_core_wordfm.h \
pub_core_xarray.h \
m_aspacemgr/priv_aspacemgr.h \
#elif defined(VGP_x86_darwin)
-/* Using _SYSNO_INDEX rather than _SYSNO_NUM assumes that these are
- Unix-class syscalls (which they are). Unfortunately _SYSNO_NUM
- involves a C-style "cond ? :" expression which doesn't impress the
- Darwin assembler very much. */
+/* We would use VG_DARWIN_SYSNO_TO_KERNEL instead of VG_DARWIN_SYSNO_INDEX
+ except that the former has a C ternary ?: operator which isn't valid in
+ asm code. Both macros give the same results for Unix-class syscalls (which
+ these all are, as identified by the use of 'int 0x80'). */
__attribute__((noinline))
static UInt local_sys_write_stderr ( HChar* buf, Int n )
{
"movq $2, %%rdi\n" /* push stderr */
"movq %1, %%rsi\n" /* push buf */
"movl %2, %%edx\n" /* push n */
- "movl $"VG_STRINGIFY(VG_DARWIN_SYSNO_NUM(__NR_write_nocancel))
+ "movl $"VG_STRINGIFY(VG_DARWIN_SYSNO_FOR_KERNEL(__NR_write_nocancel))
", %%eax\n"
"syscall\n" /* write(stderr, buf, n) */
"jnc 1f\n" /* jump if no error */
{
UInt __res;
__asm__ volatile (
- "movl $"VG_STRINGIFY(VG_DARWIN_SYSNO_NUM(__NR_getpid))", %%eax\n"
+ "movl $"VG_STRINGIFY(VG_DARWIN_SYSNO_FOR_KERNEL(__NR_getpid))", %%eax\n"
"syscall\n" /* getpid() */
"movl %%eax, %0\n" /* set __res = eax */
: "=mr" (__res)
switch (scclass) {
case VG_DARWIN_SYSCALL_CLASS_UNIX:
u64 = do_syscall_unix_WRK(a1,a2,a3,a4,a5,a6,a7,a8,
- VG_DARWIN_SYSNO_NUM(sysno), &err);
+ VG_DARWIN_SYSNO_FOR_KERNEL(sysno), &err);
wLO = (UInt)u64;
wHI = (UInt)(u64 >> 32);
break;
case VG_DARWIN_SYSCALL_CLASS_MACH:
wLO = do_syscall_mach_WRK(a1,a2,a3,a4,a5,a6,a7,a8,
- VG_DARWIN_SYSNO_NUM(sysno));
+ VG_DARWIN_SYSNO_FOR_KERNEL(sysno));
err = 0;
break;
case VG_DARWIN_SYSCALL_CLASS_MDEP:
wLO = do_syscall_mdep_WRK(a1,a2,a3,a4,a5,a6,a7,a8,
- VG_DARWIN_SYSNO_NUM(sysno));
+ VG_DARWIN_SYSNO_FOR_KERNEL(sysno));
err = 0;
break;
default:
switch (scclass) {
case VG_DARWIN_SYSCALL_CLASS_UNIX:
wLO = do_syscall_unix_WRK(a1,a2,a3,a4,a5,a6,a7,a8,
- VG_DARWIN_SYSNO_NUM(sysno), &err, &wHI);
+ VG_DARWIN_SYSNO_FOR_KERNEL(sysno), &err, &wHI);
break;
case VG_DARWIN_SYSCALL_CLASS_MACH:
case VG_DARWIN_SYSCALL_CLASS_MDEP:
wLO = do_syscall_mach_WRK(a1,a2,a3,a4,a5,a6,a7,a8,
- VG_DARWIN_SYSNO_NUM(sysno));
+ VG_DARWIN_SYSNO_FOR_KERNEL(sysno));
err = 0;
break;
default:
*/
#include "pub_core_basics_asm.h"
-#include "pub_core_vkiscnums.h"
+#include "pub_core_vkiscnums_asm.h"
#include "libvex_guest_offsets.h"
*/
#include "pub_core_basics_asm.h"
-#include "pub_core_vkiscnums.h"
+#include "pub_core_vkiscnums_asm.h"
#include "libvex_guest_offsets.h"
*/
#include "pub_core_basics_asm.h"
-#include "pub_core_vkiscnums.h"
+#include "pub_core_vkiscnums_asm.h"
#include "libvex_guest_offsets.h"
*/
#include "pub_core_basics_asm.h"
-#include "pub_core_vkiscnums.h"
+#include "pub_core_vkiscnums_asm.h"
#include "libvex_guest_offsets.h"
*/
#include "pub_core_basics_asm.h"
-#include "pub_core_vkiscnums.h"
+#include "pub_core_vkiscnums_asm.h"
#include "libvex_guest_offsets.h"
*/
#include "pub_core_basics_asm.h"
-#include "pub_core_vkiscnums.h"
+#include "pub_core_vkiscnums_asm.h"
#include "libvex_guest_offsets.h"
PRE(sys_ni_syscall)
{
- PRINT("unimplemented (by the kernel) syscall %ld! (ni_syscall)\n",
-// Nb: AIX5 is handled in syswrap-aix5.c.
-// DDD: make this generic
-#if defined(VGO_linux)
- SYSNO
-#elif defined(VGO_darwin)
- VG_DARWIN_SYSNO_PRINT(SYSNO)
-#else
-# error Unknown OS
-#endif
- );
+ PRINT("unimplemented (by the kernel) syscall: %s! (ni_syscall)\n",
+ VG_SYSNUM_STRING(SYSNO));
PRE_REG_READ0(long, "ni_syscall");
SET_STATUS_Failure( VKI_ENOSYS );
}
switch (VG_DARWIN_SYSNO_CLASS(syscallno)) {
case VG_DARWIN_SYSCALL_CLASS_UNIX:
err = ML_(do_syscall_for_client_unix_WRK)(
- VG_DARWIN_SYSNO_NUM(syscallno), &tst->arch.vex,
+ VG_DARWIN_SYSNO_FOR_KERNEL(syscallno), &tst->arch.vex,
syscall_mask, &saved, 0/*unused:sigsetSzB*/
);
break;
case VG_DARWIN_SYSCALL_CLASS_MACH:
err = ML_(do_syscall_for_client_mach_WRK)(
- VG_DARWIN_SYSNO_NUM(syscallno), &tst->arch.vex,
+ VG_DARWIN_SYSNO_FOR_KERNEL(syscallno), &tst->arch.vex,
syscall_mask, &saved, 0/*unused:sigsetSzB*/
);
break;
case VG_DARWIN_SYSCALL_CLASS_MDEP:
err = ML_(do_syscall_for_client_mdep_WRK)(
- VG_DARWIN_SYSNO_NUM(syscallno), &tst->arch.vex,
+ VG_DARWIN_SYSNO_FOR_KERNEL(syscallno), &tst->arch.vex,
syscall_mask, &saved, 0/*unused:sigsetSzB*/
);
break;
canonical->arg7 = stack[8];
canonical->arg8 = stack[9];
- PRINT("SYSCALL[%d,?](%3lld) syscall(#%ld, ...); please stand by...\n",
- VG_(getpid)(), /*tid,*/ (Long)0, canonical->sysno);
+ PRINT("SYSCALL[%d,?](%s) syscall(%s, ...); please stand by...\n",
+ VG_(getpid)(), /*tid,*/
+ VG_SYSNUM_STRING(0), VG_SYSNUM_STRING(canonical->sysno));
}
+ // Here we determine what kind of syscall it was by looking at the
+ // interrupt kind, and then encode the syscall number using the 64-bit
+ // encoding for Valgrind's internal use.
+ //
// DDD: Would it be better to stash the JMP kind into the Darwin
// thread state rather than passing in the trc?
switch (trc) {
// syscall = Unix, 32-bit result
// OR Mach, 32-bit result
if (canonical->sysno >= 0) {
- // GrP fixme hack I386_SYSCALL_NUMBER_MASK
+ // GrP fixme hack: 0xffff == I386_SYSCALL_NUMBER_MASK
canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(canonical->sysno
& 0xffff);
} else {
canonical->arg7 = stack[2];
canonical->arg8 = stack[3];
- PRINT("SYSCALL[%d,?](%3lld) syscall(#%lx, ...); please stand by...\n",
- VG_(getpid)(), /*tid,*/ (Long)0,
- VG_DARWIN_SYSNO_PRINT(canonical->sysno));
+ PRINT("SYSCALL[%d,?](%s) syscall(%s, ...); please stand by...\n",
+ VG_(getpid)(), /*tid,*/
+ VG_SYSNUM_STRING(0), VG_SYSNUM_STRING(canonical->sysno));
}
// no canonical->sysno adjustment needed
VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
UWord *stack = (UWord *)gst->guest_ESP;
- gst->guest_EAX = VG_DARWIN_SYSNO_NUM(canonical->sysno);
+ gst->guest_EAX = VG_DARWIN_SYSNO_FOR_KERNEL(canonical->sysno);
// GrP fixme? gst->guest_TEMP_EFLAG_C = 0;
// stack[0] is return address
VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
UWord *stack = (UWord *)gst->guest_RSP;
- gst->guest_RAX = VG_DARWIN_SYSNO_NUM(canonical->sysno);
+ gst->guest_RAX = VG_DARWIN_SYSNO_FOR_KERNEL(canonical->sysno);
// GrP fixme? gst->guest_TEMP_EFLAG_C = 0;
// stack[0] is return address
/*OUT*/SyscallStatus* status,
/*OUT*/UWord* flags )
{
- VG_(message)
- (Vg_DebugMsg,"WARNING: unhandled syscall: %lld", (Long)args->sysno);
- // DDD: make this generic with a common function.
-# if defined(VGO_linux)
- // nothing
-# elif defined(VGO_aix5)
- VG_(message)
- (Vg_DebugMsg," name of syscall: \"%s\"",
- VG_(aix5_sysno_to_sysname)(args->sysno));
-# elif defined(VGO_darwin)
- VG_(message)
- (Vg_DebugMsg," a.k.a.: %lld",
- (Long)VG_DARWIN_SYSNO_PRINT(args->sysno));
-# else
-# error unknown OS
-# endif
- if (VG_(clo_verbosity) > 1) {
- VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
- }
- VG_(message)
- (Vg_DebugMsg,"You may be able to write your own handler.");
- VG_(message)
- (Vg_DebugMsg,"Read the file README_MISSING_SYSCALL_OR_IOCTL.");
- VG_(message)
- (Vg_DebugMsg,"Nevertheless we consider this a bug. Please report");
- VG_(message)
- (Vg_DebugMsg,"it at http://valgrind.org/support/bug_reports.html.");
+ VG_DMSG("WARNING: unhandled syscall: %s",
+ VG_SYSNUM_STRING_EXTRA(args->sysno));
+ VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
+ VG_DMSG("You may be able to write your own handler.");
+ VG_DMSG("Read the file README_MISSING_SYSCALL_OR_IOCTL.");
+ VG_DMSG("Nevertheless we consider this a bug. Please report");
+ VG_DMSG("it at http://valgrind.org/support/bug_reports.html.");
SET_STATUS_Failure(VKI_ENOSYS);
}
sci->flags is zero.
*/
- PRINT("SYSCALL[%d,%d](%3lld) ", VG_(getpid)(), tid,
- // DDD: make this generic
- #if defined(VGO_linux) || defined(VGO_aix5)
- (Long)sysno
- #elif defined(VGO_darwin)
- (Long)VG_DARWIN_SYSNO_PRINT(sysno)
- #else
- # error Unknown OS
- #endif
- );
+ PRINT("SYSCALL[%d,%d](%s) ",
+ VG_(getpid)(), tid, VG_SYSNUM_STRING(sysno));
/* Do any pre-syscall actions */
if (VG_(needs).syscall_wrapper) {
/* Be decorative, if required. */
if (VG_(clo_trace_syscalls)) {
Bool failed = sr_isError(sci->status.sres);
- Word tmp_sysno = sysno;
-# if defined(VGO_darwin)
- // DDD: genericise this
- tmp_sysno = VG_DARWIN_SYSNO_PRINT(tmp_sysno);
-# endif
if (failed) {
- PRINT("SYSCALL[%d,%d](%3ld) ... [async] --> Failure(0x%llx)",
- VG_(getpid)(), tid, tmp_sysno,
+ PRINT("SYSCALL[%d,%d](%s) ... [async] --> Failure(0x%llx)",
+ VG_(getpid)(), tid, VG_SYSNUM_STRING(sysno),
(ULong)sr_Err(sci->status.sres));
} else {
- PRINT("SYSCALL[%d,%d](%3ld) ... [async] --> "
+ PRINT("SYSCALL[%d,%d](%s) ... [async] --> "
"Success(0x%llx:0x%llx)",
- VG_(getpid)(), tid, tmp_sysno,
+ VG_(getpid)(), tid, VG_SYSNUM_STRING(sysno),
(ULong)sr_ResHI(sci->status.sres),
(ULong)sr_Res(sci->status.sres) );
}
VG_(acquire_BigLock)(tid, "wqthread_continue_NORETURN");
- PRINT("SYSCALL[%d,%d](%3lld) workq_ops() starting new workqueue item\n",
- VG_(getpid)(), tid, (Long)VG_DARWIN_SYSNO_PRINT(__NR_workq_ops));
+ PRINT("SYSCALL[%d,%d](%s) workq_ops() starting new workqueue item\n",
+ VG_(getpid)(), tid, VG_SYSNUM_STRING(__NR_workq_ops));
vg_assert(VG_(is_valid_tid)(tid));
vg_assert(tid >= 1 && tid < VG_N_THREADS);
*/
#include "pub_core_basics_asm.h"
-
-/* We need pub_core_vkiscnums.h, but the AIX5 formulation
- brings in a load of C declarations. Defining this macro
- makes them invisible. Yes, a nasty hack. */
-#define VG_IN_ASSEMBLY_SOURCE
-# include "pub_core_vkiscnums.h"
-#undef VG_IN_ASSEMBLY_SOURCE
+#include "pub_core_vkiscnums_asm.h"
/* ------------------ SIMULATED CPU HELPERS ------------------ */
/*
*/
#include "pub_core_basics.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_libcprint.h"
+
#include "pub_core_vkiscnums.h" /* self */
/* We have pub_{core,tool}_vkiscnums.h. This is the matching implementation
those variables.
*/
-#if defined(VGO_aix5)
+//---------------------------------------------------------------------------
+#if defined(VGO_linux)
+//---------------------------------------------------------------------------
+
+Char* VG_(sysnum_string)(Word sysnum, SizeT n_buf, Char* buf)
+{
+ VG_(snprintf)(buf, n_buf, "%3ld", sysnum);
+ return buf;
+}
+
+Char* VG_(sysnum_string_extra)(Word sysnum, SizeT n_buf, Char* buf)
+{
+ return VG_(sysnum_string)(sysnum, n_buf, buf);
+}
+
+//---------------------------------------------------------------------------
+#elif defined(VGO_aix5)
+//---------------------------------------------------------------------------
+
/* These ones are for AIX 5.2. */
Int VG_(aix5_NR_utrchook_sc) = __NR_AIX5_UNKNOWN;
Int VG_(aix5_NR_thread_create) = __NR_AIX5_UNKNOWN;
static Int bindings_sysno[N_BINDINGS];
static UChar* bindings_sysname[N_BINDINGS];
-UChar* VG_(aix5_sysno_to_sysname)( Int sysno ) {
+Char* VG_(sysnum_string)(Word sysnum, SizeT n_buf, Char* buf)
+{
+ VG_(snprintf)(buf, n_buf, "%3ld", sysnum);
+ return buf;
+}
+
+Char* VG_(sysnum_string_extra)(Word sysnum, SizeT n_buf, Char* buf)
+{
Int i;
- for (i = 0; i < bindings_used; i++)
- if (bindings_sysno[i] == sysno)
- return bindings_sysname[i];
- return "(unknown name)";
+ Char* name = "(unknown name)";
+ for (i = 0; i < bindings_used; i++) {
+ if (bindings_sysno[i] == sysnum) {
+ name = bindings_sysname[i];
+ break;
+ }
+ }
+ VG_(snprintf)(buf, n_buf, "%3ld (%s)", sysnum, name);
+ return buf;
}
static Bool local_streq ( UChar* s1, UChar* s2 ); /* fwds */
}
}
-#endif /* defined(VGO_aix5) */
+//---------------------------------------------------------------------------
+#elif defined(VGO_darwin)
+//---------------------------------------------------------------------------
+
+Char* VG_(sysnum_string)(Word sysnum, SizeT n_buf, Char* buf)
+{
+ Char* classname = NULL;
+ switch (VG_DARWIN_SYSNO_CLASS(sysnum)) {
+ case VG_DARWIN_SYSCALL_CLASS_MACH: classname = "mach"; break;
+ case VG_DARWIN_SYSCALL_CLASS_UNIX: classname = "unix"; break;
+ case VG_DARWIN_SYSCALL_CLASS_MDEP: classname = "mdep"; break;
+ case VG_DARWIN_SYSCALL_CLASS_DIAG: classname = "diag"; break;
+ default:
+ VG_(core_panic)("unknown Darwin sysnum class");
+ }
+ VG_(snprintf)(buf, n_buf, "%s:%3ld",
+ classname, VG_DARWIN_SYSNO_INDEX(sysnum));
+ return buf;
+}
+
+Char* VG_(sysnum_string_extra)(Word sysnum, SizeT n_buf, Char* buf)
+{
+ return VG_(sysnum_string)(sysnum, n_buf, buf);
+}
+
+//---------------------------------------------------------------------------
+#else
+//---------------------------------------------------------------------------
+# error Unknown OS
+#endif
/*--------------------------------------------------------------------*/
/*--- end ---*/
#ifndef __PUB_CORE_VKISCNUMS_H
#define __PUB_CORE_VKISCNUMS_H
+//--------------------------------------------------------------------
+// PURPOSE: This module holds all the syscall numbers, and a handful of
+// operations relating to them.
+//
+// On Linux they are a bunch of #define'd constants of the form
+// __NR_name, and this file must contain nothing else, since it will
+// be included in assembly code (m_trampoline.S).
+//
+// On AIX the __NR_name consts are renamings of global variables which
+// tell us the number for each syscall. This elaboration is necessary
+// because on AIX the syscall numbers are not constant; they can be
+// different for each process (in principle; in practice they rarely
+// change). 32- and 64-bit AIX5 share a common "implementation".
+//
+// On Darwin the __NR_name consts are #define'd constants which are
+// encoded using various macros. 32- and 64-bit Darwin share a common
+// "implementation" also.
+//
+// Note that most of the actual code for this module is in include/vki/, but
+// you should not directly #include any file in include/vki; instead #include
+// only one of pub_{core,tool}_vkiscnums{,_asm}.h.
+//--------------------------------------------------------------------
+
/* Most unfortunately, all the kernel decls are visible to tools. Not
really necessary, but to avoid this would require some tedious
refactoring of the sources. Anyway, we live with this kludge, and
that means the only thing to be done here is ... */
+#include "pub_core_vkiscnums_asm.h"
#include "pub_tool_vkiscnums.h"
-/* Make it possible to include this file in assembly sources. */
-#if !defined(VG_IN_ASSEMBLY_SOURCE)
-
#if defined(VGO_linux)
// Nothing
extern Bool VG_(aix5_register_syscall)( Int, UChar* );
#elif defined(VGO_darwin)
-
-/* Convert a syscall number into a nicer form(?) */
-#if defined(VGA_x86)
-# define VG_DARWIN_SYSNO_NUM(sysno) VG_DARWIN_SYSNO_PRINT(sysno)
-#elif defined(VGA_amd64)
-# define VG_DARWIN_SYSNO_NUM(sysno) (sysno)
-#else
-# error unknown arch
-#endif
+ // Nothing
#else
# error Unknown OS
-#endif // defined(VGO_*)
-
-#endif // !defined(VG_IN_ASSEMBLY_SOURCE)
+#endif
#endif // __PUB_CORE_VKISCNUMS_H
--- /dev/null
+
+/*--------------------------------------------------------------------*/
+/*--- Syscall numbers and related operations. pub_core_vkiscnums.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2009 Julian Seward
+ jseward@acm.org
+ Copyright (C) 2005-2009 Nicholas Nethercote
+ njn@valgrind.org
+ Copyright (C) 2006-2009 OpenWorks LLP
+ info@open-works.co.uk
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PUB_CORE_VKISCNUMS_ASM_H
+#define __PUB_CORE_VKISCNUMS_ASM_H
+
+/* Most unfortunately, all the kernel decls are visible to tools. Not
+ really necessary, but to avoid this would require some tedious
+ refactoring of the sources. Anyway, we live with this kludge, and
+ that means the only thing to be done here is ... */
+
+#include "pub_tool_vkiscnums_asm.h"
+
+
+#endif // __PUB_CORE_VKISCNUMS_ASM_H
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
tl_assert(i >= 0 && i <= n);
if (i == n) {
-// DDD: genericise this
-# if defined(VGO_linux)
- VG_(printf)("sysno == %u\n", sysno);
-# elif defined(VGO_aix5)
- VG_(printf)("sysno == %u\n", sysno);
- VG_(printf)("syscallnm == %s\n",
- VG_(aix5_sysno_to_sysname)(sysno));
-# elif defined(VGO_darwin)
- VG_(printf)("sysno == %d\n", VG_DARWIN_SYSNO_PRINT(sysno));
-# else
-# error "Unsupported OS"
-# endif
+ VG_(printf)("sysno == %s", VG_SYSNUM_STRING_EXTRA(sysno));
VG_(tool_panic)("unhandled syscall");
}
pub_tool_tooliface.h \
pub_tool_vki.h \
pub_tool_vkiscnums.h \
+ pub_tool_vkiscnums_asm.h \
pub_tool_wordfm.h \
pub_tool_xarray.h \
valgrind.h
The GNU General Public License is contained in the file COPYING.
*/
-/* This file defines the system call numbers.
-
- On Linux they are a bunch of #define'd constants of the form
- __NR_name, and this file must contain nothing else, since it will
- be included in assembly code (m_trampoline.S).
-
- On AIX the __NR_name consts are renamings of global variables which
- tell us the number for each syscall. This elaboration is necessary
- because on AIX the syscall numbers are not constant; they can be
- different for each process (in principle; in practice they rarely
- change). 32- and 64-bit AIX5 share a common "implementation".
-
- On Darwin the __NR_name consts are #define'd constants which are
- computed using various macros. 32- and 64-bit Darwin share a common
- "implementation" also.
-
- This file is merely a top-level "steering" file, which pulls in the
- correct bits for the relevant platform. You should not directly
- #include any file in include/vki; instead #include only this one or
- pub_core_vkiscnums.h.
-*/
-
#ifndef __PUB_TOOL_VKISCNUMS_H
#define __PUB_TOOL_VKISCNUMS_H
-#if defined(VGP_x86_linux)
-# include "vki/vki-scnums-x86-linux.h"
+#include "pub_tool_vkiscnums_asm.h"
+
+
+// This converts a syscall number into a string, suitable for printing. It is
+// needed because some platforms (AIX, Darwin) munge sysnums in various ways.
+// It is used in places where the sycall name will be printed alongside.
+extern Char* VG_(sysnum_string) (Word sysnum, SizeT n_buf, Char* buf);
+
+// This is like VG_(sysnum_string), but prints extra info if needed. It is
+// called in places where the syscall name will *not* be printed alongside.
+extern Char* VG_(sysnum_string_extra)(Word sysnum, SizeT n_buf, Char* buf);
-#elif defined(VGP_amd64_linux)
-# include "vki/vki-scnums-amd64-linux.h"
+// Macros that make the above functions easier to use by declaring a local
+// buffer.
+#define VG_SYSNUM_STRING(sysnum) \
+ ({ Char qq_zz_buf[32]; VG_(sysnum_string)(sysnum, 32, qq_zz_buf); })
+#define VG_SYSNUM_STRING_EXTRA(sysnum) \
+ ({ Char qq_zz_buf[64]; VG_(sysnum_string_extra)(sysnum, 64, qq_zz_buf); })
-#elif defined(VGP_ppc32_linux)
-# include "vki/vki-scnums-ppc32-linux.h"
-#elif defined(VGP_ppc64_linux)
-# include "vki/vki-scnums-ppc64-linux.h"
+#if defined(VGO_linux)
+ // Nothing.
-#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+#elif defined(VGO_aix5)
+ // See the AIX5-specific case in pub_tool_vkiscnums_asm.h for an
+ // explanation of why we include this here rather than there.
# include "vki/vki-scnums-aix5.h"
-/* Make it possible to include this file in assembly sources. */
-#if !defined(VG_IN_ASSEMBLY_SOURCE)
-
-/* Look up the name of a syscall, using the bindings previously
- created by VG_(aix5_register_syscall), for the purposes of making
- error messages. */
-// DDD: should combine this and VG_DARWIN_SYSNO_PRINT into a single generic
-// function which returns a string, something like VG_(pprint_sysno)().
-extern UChar* VG_(aix5_sysno_to_sysname)( Int sysno );
-
-#endif /* !defined(VG_IN_ASSEMBLY_SOURCE) */
-
-#elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
-# include "vki/vki-scnums-darwin.h"
-
-// Convert a syscall number into a nice form for printing. Unix syscalls
-// get positive numbers (0..400-odd), Mach traps get negative numbers
-// (-10..-127).
-// DDD: Machine-dependent ones get positive numbers which will overlap with
-// Unix ones! So eg. both 'pthread_set_self' and 'read' are reported as
-// "3".
-#define VG_DARWIN_SYSNO_PRINT(sysno) \
- ((VG_DARWIN_SYSNO_CLASS(sysno) == VG_DARWIN_SYSCALL_CLASS_MACH) \
- ? -VG_DARWIN_SYSNO_INDEX(sysno) \
- : VG_DARWIN_SYSNO_INDEX(sysno) \
- )
-
-/* Macros for working out which syscall a syscall number refers to. */
-#define VG_DARWIN_SYSNO_INDEX(sysno) ((sysno) & VG_DARWIN_SYSCALL_NUMBER_MASK)
-#define VG_DARWIN_SYSNO_CLASS(sysno) ((sysno) >> VG_DARWIN_SYSCALL_CLASS_SHIFT)
+#elif defined(VGO_darwin)
+ // Nothing.
#else
-# error Unknown platform
+# error Unknown OS
#endif
#endif // __PUB_TOOL_VKISCNUMS_H
--- /dev/null
+
+/*--------------------------------------------------------------------*/
+/*--- asm-only vkiscnums stuff. pub_tool_vkiscnums_asm.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2005-2009 Nicholas Nethercote
+ njn@valgrind.org
+ Copyright (C) 2006-2009 OpenWorks LLP
+ info@open-works.co.uk
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PUB_TOOL_VKISCNUMS_ASM_H
+#define __PUB_TOOL_VKISCNUMS_ASM_H
+
+#if defined(VGP_x86_linux)
+# include "vki/vki-scnums-x86-linux.h"
+
+#elif defined(VGP_amd64_linux)
+# include "vki/vki-scnums-amd64-linux.h"
+
+#elif defined(VGP_ppc32_linux)
+# include "vki/vki-scnums-ppc32-linux.h"
+
+#elif defined(VGP_ppc64_linux)
+# include "vki/vki-scnums-ppc64-linux.h"
+
+#elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
+ // Nothing: vki-scnums-aix5.h only contains stuff suitable for inclusion
+ // in C files, not asm files. So unlike all the other
+ // vki-scnums-PLATFORM.h files, we include it in pub_tool_vkiscnums.h
+ // rather than in include/pub_tool_vkiscnums_asm.h.
+
+#elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
+# include "vki/vki-scnums-darwin.h"
+
+#else
+# error Unknown platform
+#endif
+
+#endif // __PUB_TOOL_VKISCNUMS_ASM_H
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
# error This file should be included in AIX5 builds only.
#endif
+// WARNING: note that this file, unlike other vki-scnums-PLATFORM.h files,
+// isn't suitable for inclusion in asm files.
+
//--------------------------------------------------------------
// Syscalls for AIX 5.2 running on ppc32
//--------------------------------------------------------------
-/* Make it possible to include this file in assembly sources. */
-#if !defined(VG_IN_ASSEMBLY_SOURCE)
-
/* This is the initial value for a syscall number, when we don't
know what it is. */
#define __NR_AIX5_UNKNOWN (-1)
#define __NR_getpgrp 9999
#define __NR_geteuid 9999
-#endif /* !defined(VG_IN_ASSEMBLY_SOURCE) */
-
#endif /* __VKI_SCNUMS_AIX5_H */
// osfmk/mach/i386/syscall_sw.h
-// x86_64's syscall numbering system is used for all architectures.
-// Don't pass __NR_something directly to any syscall instruction.
+// There are two syscall number encodings in Darwin.
+//
+// The 64-bit encoding is that the top 8-bits are the syscall class. The low
+// 24 are the syscall number (index) within that class.
+//
+// The 32-bit encoding is that the syscall number (index) is stored as-is and
+// the syscall class is encoded as the argument to the 'int' instruction used
+// to trigger the syscall:
+// - 0x80: Unix
+// - 0x81: Mach
+// - 0x82: Machine-dependent
+// - 0x83: Diagnostic
+// Furthermore, just to make life interesting, for Mach traps the number is
+// negative.
+//
+// Within Valgrind we only use the 64-bit encoding -- on 32-bit systems, we
+// convert any syscall number to 64-bit encoding when we receive it, and
+// convert back with VG_DARWIN_SYSNO_FOR_KERNEL when passing any syscall
+// number back to the kernel (__NR_something shouldn't be passed directly to
+// the kernel).
+//
// Hack: x86 `int $0x80` (unix, 64-bit result) are special.
-
-// Encoding: the top 8-bits are the syscall class. The low 24 are the
-// syscall number (index) within that class.
+// [I haven't worked out why... --njn]
#define VG_DARWIN_SYSCALL_CLASS_SHIFT 24
#define VG_DARWIN_SYSCALL_CLASS_MASK (0xFF << VG_DARWIN_SYSCALL_CLASS_SHIFT)
#define VG_DARWIN_SYSCALL_CLASS_MDEP 3 /* Machine-dependent */
#define VG_DARWIN_SYSCALL_CLASS_DIAG 4 /* Diagnostics */
+// Macros for encoding syscall numbers in the 64-bit encoding scheme.
#define VG_DARWIN_SYSCALL_CONSTRUCT_MACH(syscall_number) \
((VG_DARWIN_SYSCALL_CLASS_MACH << VG_DARWIN_SYSCALL_CLASS_SHIFT) | \
(VG_DARWIN_SYSCALL_NUMBER_MASK & (syscall_number)))
(VG_DARWIN_SYSCALL_NUMBER_MASK & (syscall_number)))
+/* Macros for decoding syscall numbers from the 64-bit encoding scheme. */
+#define VG_DARWIN_SYSNO_INDEX(sysno) ((sysno) & VG_DARWIN_SYSCALL_NUMBER_MASK)
+#define VG_DARWIN_SYSNO_CLASS(sysno) ((sysno) >> VG_DARWIN_SYSCALL_CLASS_SHIFT)
+
+
+/* Macros for converting syscall numbers to the form expected by the kernel.*/
+#if defined(VGA_x86)
+ // This converts the 64-bit syscall number encoding, which we use
+ // throughout Valgrind, into the 32-bit syscall number encoding, which is
+ // suitable for passing to the (32-bit) kernel.
+# define VG_DARWIN_SYSNO_FOR_KERNEL(sysno) \
+ ((VG_DARWIN_SYSNO_CLASS(sysno) == VG_DARWIN_SYSCALL_CLASS_MACH) \
+ ? -VG_DARWIN_SYSNO_INDEX(sysno) \
+ : VG_DARWIN_SYSNO_INDEX(sysno) \
+ )
+
+#elif defined(VGA_amd64)
+ // For 64-bit systems, we don't need to do anything to the syscall number.
+# define VG_DARWIN_SYSNO_FOR_KERNEL(sysno) (sysno)
+
+#else
+# error Unknown architecture
+#endif
+
// mdep syscalls
-#include "vki/vki-scnums-darwin.h"
-#include "pub_tool_vkiscnums.h"
-
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
+#include "pub_tool_basics.h"
+#include "vki/vki-scnums-darwin.h"
+#include "pub_tool_vkiscnums.h"
+
// Since we use vki_unistd.h, we can't include <unistd.h>. So we have to
// declare this ourselves.
extern int syscall (int __sysno, ...);
#define GO(__NR_xxx, s) \
fprintf(stderr, "-----------------------------------------------------\n" \
- "%3d:%20s %s\n" \
+ "x%lx(%d):%20s %s\n" \
"-----------------------------------------------------\n", \
- VG_DARWIN_SYSNO_PRINT(__NR_xxx), #__NR_xxx, s);
+ (unsigned long)__NR_xxx, \
+ VG_DARWIN_SYSNO_FOR_KERNEL(__NR_xxx), #__NR_xxx, s);
#define SY(__NR_xxx, args...) res = syscall(__NR_xxx, ##args);
-----------------------------------------------------
- 1: __NR_exit below
+x2000001(1): __NR_exit below
-----------------------------------------------------
-----------------------------------------------------
- 2: __NR_fork other
+x2000002(2): __NR_fork other
-----------------------------------------------------
-----------------------------------------------------
- 3: __NR_read 1+3s 1m
+x2000003(3): __NR_read 1+3s 1m
-----------------------------------------------------
Syscall param (syscallno) contains uninitialised byte(s)
...
...
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
- 4: __NR_write 3s 1m
+x2000004(4): __NR_write 3s 1m
-----------------------------------------------------
Syscall param write(fd) contains uninitialised byte(s)
...
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
-105: __NR_setsockopt 5s 1m
+x2000069(105): __NR_setsockopt 5s 1m
-----------------------------------------------------
Syscall param setsockopt(s) contains uninitialised byte(s)
...
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
-118: __NR_getsockopt 5s 1m
+x2000076(118): __NR_getsockopt 5s 1m
-----------------------------------------------------
Syscall param getsockopt(s) contains uninitialised byte(s)
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: main (scalar.c:13)
-----------------------------------------------------
-169: __NR_csops 4s 1m
+x20000a9(169): __NR_csops 4s 1m
-----------------------------------------------------
Syscall param csops(pid) contains uninitialised byte(s)
...
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
-265: __NR_shmget 3s 0m
+x2000109(265): __NR_shmget 3s 0m
-----------------------------------------------------
Syscall param shmget(key) contains uninitialised byte(s)
Syscall param shmget(shmflg) contains uninitialised byte(s)
...
-----------------------------------------------------
-268: __NR_sem_open 2s 1m
+x200010c(268): __NR_sem_open 2s 1m
-----------------------------------------------------
Syscall param sem_open(name) contains uninitialised byte(s)
...
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
-268: __NR_sem_open (4-args) 2s 0m
+x200010c(268): __NR_sem_open (4-args) 2s 0m
-----------------------------------------------------
Syscall param sem_open(mode) contains uninitialised byte(s)
Syscall param sem_open(value) contains uninitialised byte(s)
...
-----------------------------------------------------
-269: __NR_sem_close 1s 0m
+x200010d(269): __NR_sem_close 1s 0m
-----------------------------------------------------
Syscall param sem_close(sem) contains uninitialised byte(s)
...
-----------------------------------------------------
-270: __NR_sem_unlink 1s 1m
+x200010e(270): __NR_sem_unlink 1s 1m
-----------------------------------------------------
Syscall param sem_unlink(name) contains uninitialised byte(s)
...
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
-273: __NR_sem_post 1s 0m
+x2000111(273): __NR_sem_post 1s 0m
-----------------------------------------------------
Syscall param sem_post(sem) contains uninitialised byte(s)
...
-----------------------------------------------------
-275: __NR_sem_init 3s 1m
+x2000113(275): __NR_sem_init 3s 1m
-----------------------------------------------------
Syscall param sem_init(sem) contains uninitialised byte(s)
...
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
-276: __NR_sem_destroy 1s 1m
+x2000114(276): __NR_sem_destroy 1s 1m
-----------------------------------------------------
Syscall param sem_destroy(sem) contains uninitialised byte(s)
...
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
-420:__NR_sem_wait_nocancel 1s 0m
+x20001a4(420):__NR_sem_wait_nocancel 1s 0m
-----------------------------------------------------
Syscall param sem_wait_nocancel(sem) contains uninitialised byte(s)
...
-----------------------------------------------------
-9999: 9999 1e
+x270f(9999): 9999 1e
-----------------------------------------------------
-WARNING: unhandled syscall: 33564431
- a.k.a.: 9999
+WARNING: unhandled syscall: unix:9999
+ at 0x........: syscall (in /...libc...)
+ by 0x........: (below main)
You may be able to write your own handler.
Read the file README_MISSING_SYSCALL_OR_IOCTL.
Nevertheless we consider this a bug. Please report
it at http://valgrind.org/support/bug_reports.html.
-----------------------------------------------------
- 1: __NR_exit 1s 0m
+x2000001(1): __NR_exit 1s 0m
-----------------------------------------------------
Syscall param exit(status) contains uninitialised byte(s)
-----------------------------------------------------
- 2: __NR_fork 0e
+x2000002(2): __NR_fork 0e
-----------------------------------------------------
-----------------------------------------------------
- 66: __NR_vfork 0e
+x2000042(66): __NR_vfork 0e
-----------------------------------------------------