Necessary changes to Valgrind to support MIPS64LE on Linux.
Minor cleanup/style changes embedded in the patch as well.
The change corresponds to r2687 in VEX.
Patch written by Dejan Jevtic and Petar Jovanovic.
More information about this issue:
https://bugs.kde.org/show_bug.cgi?id=313267
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13292
AM_CFLAGS_MIPS32_LINUX = @FLAG_M32@ $(AM_CFLAGS_BASE) -mips32
AM_CCASFLAGS_MIPS32_LINUX = @FLAG_M32@ -mips32 -g
+AM_FLAG_M3264_MIPS64_LINUX = @FLAG_M64@
+AM_CFLAGS_MIPS64_LINUX = @FLAG_M64@ $(AM_CFLAGS_BASE) -mips64
+AM_CCASFLAGS_MIPS64_LINUX = @FLAG_M64@ -mips64 -g
# Flags for the primary target. These must be used to build the
# regtests and performance tests. In fact, these must be used to
PRELOAD_LDFLAGS_AMD64_DARWIN = $(PRELOAD_LDFLAGS_COMMON_DARWIN) -arch x86_64
PRELOAD_LDFLAGS_S390X_LINUX = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M64@
PRELOAD_LDFLAGS_MIPS32_LINUX = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M32@
+PRELOAD_LDFLAGS_MIPS64_LINUX = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M64@
-static -nodefaultlibs -nostartfiles -u __start @FLAG_NO_BUILD_ID@ \
@FLAG_M32@
+TOOL_LDFLAGS_MIPS64_LINUX = \
+ -static -nodefaultlibs -nostartfiles -u __start @FLAG_NO_BUILD_ID@ \
+ @FLAG_M64@
+
# On Android we must ask for non-executable stack, not sure why.
if VGCONF_PLATFORMS_INCLUDE_ARM_LINUX
if VGCONF_PLATVARIANT_IS_ANDROID
LIBREPLACEMALLOC_MIPS32_LINUX = \
$(top_builddir)/coregrind/libreplacemalloc_toolpreload-mips32-linux.a
+LIBREPLACEMALLOC_MIPS64_LINUX = \
+ $(top_builddir)/coregrind/libreplacemalloc_toolpreload-mips64-linux.a
+
LIBREPLACEMALLOC_LDFLAGS_X86_LINUX = \
-Wl,--whole-archive \
$(LIBREPLACEMALLOC_X86_LINUX) \
$(LIBREPLACEMALLOC_MIPS32_LINUX) \
-Wl,--no-whole-archive
+LIBREPLACEMALLOC_LDFLAGS_MIPS64_LINUX = \
+ -Wl,--whole-archive \
+ $(LIBREPLACEMALLOC_MIPS64_LINUX) \
+ -Wl,--no-whole-archive
+
#----------------------------------------------------------------------------
# General stuff
#----------------------------------------------------------------------------
- AMD64/MacOSX
- S390X/Linux
- MIPS32/Linux
+- MIPS64/Linux
Note that AMD64 is just another name for x86_64, and Valgrind runs fine
on Intel processors. Also note that the core of MacOSX is called
*D1c = (cache_t) { 32768, 4, 32 };
*LLc = (cache_t) { 524288, 8, 32 };
+#elif defined(VGA_mips64)
+
+ // Set caches to default (for MIPS64 - 5kc)
+ *I1c = (cache_t) { 32768, 4, 32 };
+ *D1c = (cache_t) { 32768, 4, 32 };
+ *LLc = (cache_t) { 524288, 8, 32 };
+
#elif defined(VGA_x86) || defined(VGA_amd64)
*I1c = (cache_t) { 65536, 2, 64 };
/* How many bits at the bottom of an instruction address are
guaranteed to be zero? */
#if defined(VGA_ppc32) || defined(VGA_ppc64) || defined(VGA_arm) \
- || defined(VGA_mips32)
+ || defined(VGA_mips32) || defined(VGA_mips64)
# define N_IADDR_LO_ZERO_BITS 2
#elif defined(VGA_x86) || defined(VGA_amd64)
# define N_IADDR_LO_ZERO_BITS 0
;;
mips)
- AC_MSG_RESULT([ok (${host_cpu})])
- ARCH_MAX="mips32"
- ;;
+ AC_MSG_RESULT([ok (${host_cpu})])
+ ARCH_MAX="mips32"
+ ;;
mipsel)
- AC_MSG_RESULT([ok (${host_cpu})])
- ARCH_MAX="mips32"
- ;;
+ AC_MSG_RESULT([ok (${host_cpu})])
+ ARCH_MAX="mips32"
+ ;;
mipsisa32r2)
- AC_MSG_RESULT([ok (${host_cpu})])
- ARCH_MAX="mips32"
- ;;
+ AC_MSG_RESULT([ok (${host_cpu})])
+ ARCH_MAX="mips32"
+ ;;
+ mips64*)
+ AC_MSG_RESULT([ok (${host_cpu})])
+ ARCH_MAX="mips64"
+ ;;
+
+ mipsisa64*)
+ AC_MSG_RESULT([ok (${host_cpu})])
+ ARCH_MAX="mips64"
+ ;;
*)
AC_MSG_RESULT([no (${host_cpu})])
AC_MSG_ERROR([Unsupported host architecture. Sorry])
valt_load_address_sec_norml="0xUNSET"
valt_load_address_sec_inner="0xUNSET"
AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
- AC_MSG_RESULT([ok (${host_cpu}-${host_os})])
+ ;;
+ mips64-linux)
+ VGCONF_ARCH_PRI="mips64"
+ VGCONF_PLATFORM_PRI_CAPS="MIPS64_LINUX"
+ VGCONF_PLATFORM_SEC_CAPS=""
+ valt_load_address_pri_norml="0x38000000"
+ valt_load_address_pri_inner="0x28000000"
+ valt_load_address_sec_norml="0xUNSET"
+ valt_load_address_sec_inner="0xUNSET"
+ AC_MSG_RESULT([ok (${ARCH_MAX}-${VGCONF_OS})])
;;
*)
VGCONF_ARCH_PRI="unknown"
test x$VGCONF_PLATFORM_PRI_CAPS = xS390X_LINUX )
AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_MIPS32,
test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX )
+AM_CONDITIONAL(VGCONF_ARCHS_INCLUDE_MIPS64,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX )
# Set up VGCONF_PLATFORMS_INCLUDE_<platform>. Either one or two of these
# become defined.
-o x$VGCONF_PLATFORM_SEC_CAPS = xS390X_LINUX)
AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_MIPS32_LINUX,
test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX)
+AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_MIPS64_LINUX,
+ test x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX)
AM_CONDITIONAL(VGCONF_PLATFORMS_INCLUDE_X86_DARWIN,
test x$VGCONF_PLATFORM_PRI_CAPS = xX86_DARWIN \
-o x$VGCONF_PLATFORM_PRI_CAPS = xPPC64_LINUX \
-o x$VGCONF_PLATFORM_PRI_CAPS = xARM_LINUX \
-o x$VGCONF_PLATFORM_PRI_CAPS = xS390X_LINUX \
- -o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX)
+ -o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX \
+ -o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX)
AM_CONDITIONAL(VGCONF_OS_IS_DARWIN,
test x$VGCONF_PLATFORM_PRI_CAPS = xX86_DARWIN \
-o x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_DARWIN)
if test x$VGCONF_PLATFORM_PRI_CAPS = xX86_LINUX \
-o x$VGCONF_PLATFORM_PRI_CAPS = xPPC32_LINUX \
-o x$VGCONF_PLATFORM_PRI_CAPS = xARM_LINUX \
- -o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX ; then
+ -o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS32_LINUX \
+ -o x$VGCONF_PLATFORM_PRI_CAPS = xMIPS64_LINUX ; then
mflag_primary=$FLAG_M32
elif test x$VGCONF_PLATFORM_PRI_CAPS = xAMD64_LINUX \
-o x$VGCONF_PLATFORM_PRI_CAPS = xPPC64_LINUX \
m_dispatch/dispatch-arm-linux.S \
m_dispatch/dispatch-s390x-linux.S \
m_dispatch/dispatch-mips32-linux.S \
+ m_dispatch/dispatch-mips64-linux.S \
m_dispatch/dispatch-x86-darwin.S \
m_dispatch/dispatch-amd64-darwin.S \
m_gdbserver/inferiors.c \
m_gdbserver/valgrind-low-ppc64.c \
m_gdbserver/valgrind-low-s390x.c \
m_gdbserver/valgrind-low-mips32.c \
+ m_gdbserver/valgrind-low-mips64.c \
m_gdbserver/version.c \
m_initimg/initimg-linux.c \
m_initimg/initimg-darwin.c \
m_sigframe/sigframe-arm-linux.c \
m_sigframe/sigframe-s390x-linux.c \
m_sigframe/sigframe-mips32-linux.c \
+ m_sigframe/sigframe-mips64-linux.c \
m_sigframe/sigframe-x86-darwin.c \
m_sigframe/sigframe-amd64-darwin.c \
m_syswrap/syscall-x86-linux.S \
m_syswrap/syscall-arm-linux.S \
m_syswrap/syscall-s390x-linux.S \
m_syswrap/syscall-mips32-linux.S \
+ m_syswrap/syscall-mips64-linux.S \
m_syswrap/syscall-x86-darwin.S \
m_syswrap/syscall-amd64-darwin.S \
m_syswrap/syswrap-main.c \
m_syswrap/syswrap-arm-linux.c \
m_syswrap/syswrap-s390x-linux.c \
m_syswrap/syswrap-mips32-linux.c \
+ m_syswrap/syswrap-mips64-linux.c \
m_syswrap/syswrap-x86-darwin.c \
m_syswrap/syswrap-amd64-darwin.c \
m_syswrap/syswrap-xen.c \
m_gdbserver/mips-linux-valgrind.xml \
m_gdbserver/mips-fpu-valgrind-s1.xml \
m_gdbserver/mips-fpu-valgrind-s2.xml \
- m_gdbserver/mips-fpu.xml
+ m_gdbserver/mips-fpu.xml \
+ m_gdbserver/mips64-cp0-valgrind-s1.xml \
+ m_gdbserver/mips64-cp0-valgrind-s2.xml \
+ m_gdbserver/mips64-cp0.xml \
+ m_gdbserver/mips64-cpu-valgrind-s1.xml \
+ m_gdbserver/mips64-cpu-valgrind-s2.xml \
+ m_gdbserver/mips64-cpu.xml \
+ m_gdbserver/mips64-linux.xml \
+ m_gdbserver/mips64-linux-valgrind.xml \
+ m_gdbserver/mips64-fpu-valgrind-s1.xml \
+ m_gdbserver/mips64-fpu-valgrind-s2.xml \
+ m_gdbserver/mips64-fpu.xml
# so as to make sure these get copied into the install tree
vglibdir = $(pkglibdir)
(ehdr->e_ident[EI_OSABI] == ELFOSABI_SYSV ||
ehdr->e_ident[EI_OSABI] == ELFOSABI_LINUX)) {
platform = "amd64-linux";
+ } else if (ehdr->e_machine == EM_MIPS &&
+ (ehdr->e_ident[EI_OSABI] == ELFOSABI_SYSV ||
+ ehdr->e_ident[EI_OSABI] == ELFOSABI_LINUX)) {
+ platform = "mips64-linux";
}
} else if (header[EI_DATA] == ELFDATA2MSB) {
# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
(ehdr->e_ident[EI_OSABI] == ELFOSABI_SYSV ||
ehdr->e_ident[EI_OSABI] == ELFOSABI_LINUX)) {
platform = "s390x-linux";
+ } else if (ehdr->e_machine == EM_MIPS &&
+ (ehdr->e_ident[EI_OSABI] == ELFOSABI_SYSV ||
+ ehdr->e_ident[EI_OSABI] == ELFOSABI_LINUX)) {
+ platform = "mips64-linux";
}
# endif
}
(0==strcmp(VG_PLATFORM,"ppc64-linux")) ||
(0==strcmp(VG_PLATFORM,"arm-linux")) ||
(0==strcmp(VG_PLATFORM,"s390x-linux")) ||
- (0==strcmp(VG_PLATFORM,"mips32-linux")))
+ (0==strcmp(VG_PLATFORM,"mips32-linux")) ||
+ (0==strcmp(VG_PLATFORM,"mips64-linux")))
default_platform = VG_PLATFORM;
else
barf("Unknown VG_PLATFORM '%s'", VG_PLATFORM);
res = VG_(do_syscall6)(__NR_mmap2, (UWord)start, length,
prot, flags, fd, offset / 4096);
# elif defined(VGP_amd64_linux) || defined(VGP_ppc64_linux) \
- || defined(VGP_s390x_linux) || defined(VGP_mips32_linux)
+ || defined(VGP_s390x_linux) || defined(VGP_mips32_linux) \
+ || defined(VGP_mips64_linux)
res = VG_(do_syscall6)(__NR_mmap, (UWord)start, length,
prot, flags, fd, offset);
# elif defined(VGP_x86_darwin)
/* Ask for an advisory. If it's negative, fail immediately. */
req.rkind = MAny;
req.start = 0;
- #if defined(VGA_arm) || defined(VGA_mips32)
+ #if defined(VGA_arm) || defined(VGA_mips32) || defined(VGA_mips64)
aspacem_assert(VKI_SHMLBA >= VKI_PAGE_SIZE);
#else
aspacem_assert(VKI_SHMLBA == VKI_PAGE_SIZE);
}
#elif defined(VGA_arm) || defined(VGA_ppc32) || defined(VGA_ppc64) || \
- defined(VGA_mips32)
+ defined(VGA_mips32) || defined(VGA_mips64)
static Bool
get_cache_info(VexArchInfo *vai)
# undef DO
regs->orig_gpr2 = arch->vex.guest_r2;
#elif defined(VGP_mips32_linux)
+# define DO(n) regs->MIPS_r##n = arch->vex.guest_r##n
+ DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
+ DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
+ DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
+ DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
+# undef DO
+ regs->MIPS_hi = arch->vex.guest_HI;
+ regs->MIPS_lo = arch->vex.guest_LO;
+#elif defined(VGP_mips64_linux)
# define DO(n) regs->MIPS_r##n = arch->vex.guest_r##n
DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
# undef DO
+#elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
+# define DO(n) (*fpu)[n] = *(double*)(&arch->vex.guest_f##n)
+ DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
+ DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
+ DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
+ DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
+# undef DO
#else
# error Unknown ELF platform
#endif
return VG_(ptrace)(VKI_PTRACE_POKEUSR_AREA, pid, &pa, NULL);
-#elif defined(VGP_mips32_linux)
+#elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
struct vki_user_regs_struct regs;
VG_(memset)(®s, 0, sizeof(regs));
regs.MIPS_r0 = vex->guest_r0;
# elif defined(VGP_mips32_linux)
if (regno == 29) { *a = regs->sp; return True; }
if (regno == 30) { *a = regs->fp; return True; }
+# elif defined(VGP_mips64_linux)
+ if (regno == 29) { *a = regs->sp; return True; }
+ if (regno == 30) { *a = regs->fp; return True; }
# else
# error "Unknown platform"
# endif
is_rw_map = False;
is_ro_map = False;
-# if defined(VGA_x86) || defined(VGA_ppc32) || defined(VGA_mips32)
+# if defined(VGA_x86) || defined(VGA_ppc32) || defined(VGA_mips32) \
+ || defined(VGA_mips64)
is_rx_map = seg->hasR && seg->hasX;
is_rw_map = seg->hasR && seg->hasW;
# elif defined(VGA_amd64) || defined(VGA_ppc64) || defined(VGA_arm)
case Creg_IA_SP: return eec->uregs->sp;
case Creg_IA_BP: return eec->uregs->fp;
case Creg_S390_R14: return eec->uregs->lr;
-# elif defined(VGA_mips32)
+# elif defined(VGA_mips32) || defined(VGA_mips64)
case Creg_IA_IP: return eec->uregs->pc;
case Creg_IA_SP: return eec->uregs->sp;
case Creg_IA_BP: return eec->uregs->fp;
case CFIC_IA_BPREL:
cfa = cfsi->cfa_off + uregs->fp;
break;
-# elif defined(VGA_mips32)
+# elif defined(VGA_mips32) || defined(VGA_mips64)
case CFIC_IA_SPREL:
cfa = cfsi->cfa_off + uregs->sp;
break;
ipHere = uregsHere->r15;
# elif defined(VGA_s390x)
ipHere = uregsHere->ia;
-# elif defined(VGA_mips32)
+# elif defined(VGA_mips32) || defined(VGA_mips64)
ipHere = uregsHere->pc;
# elif defined(VGA_ppc32) || defined(VGA_ppc64)
# else
COMPUTE(uregsPrev.ia, uregsHere->ia, cfsi->ra_how, cfsi->ra_off);
COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi->sp_how, cfsi->sp_off);
COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi->fp_how, cfsi->fp_off);
-# elif defined(VGA_mips32)
+# elif defined(VGA_mips32) || defined(VGA_mips64)
COMPUTE(uregsPrev.pc, uregsHere->pc, cfsi->ra_how, cfsi->ra_off);
COMPUTE(uregsPrev.sp, uregsHere->sp, cfsi->sp_how, cfsi->sp_off);
COMPUTE(uregsPrev.fp, uregsHere->fp, cfsi->fp_how, cfsi->fp_off);
Int fp_off;
}
DiCfSI;
-#elif defined(VGA_mips32)
+#elif defined(VGA_mips32) || defined(VGA_mips64)
typedef
struct {
Addr base;
# define FP_REG 30
# define SP_REG 29
# define RA_REG_DEFAULT 31
+#elif defined(VGP_mips64_linux)
+# define FP_REG 30
+# define SP_REG 29
+# define RA_REG_DEFAULT 31
#else
# error "Unknown platform"
#endif
7 (DWARF for the ARM Architecture) specifies that values up to 320
might exist, for Neon/VFP-v3. */
#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
- || defined(VGP_mips32_linux)
+ || defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
# define N_CFI_REGS 72
#elif defined(VGP_arm_linux)
# define N_CFI_REGS 320
if (ctxs->cfa_is_regoff && ctxs->cfa_reg == SP_REG) {
si->cfa_off = ctxs->cfa_off;
# if defined(VGA_x86) || defined(VGA_amd64) || defined(VGA_s390x) \
- || defined(VGA_mips32)
+ || defined(VGA_mips32) || defined(VGA_mips64)
si->cfa_how = CFIC_IA_SPREL;
# elif defined(VGA_arm)
si->cfa_how = CFIC_ARM_R13REL;
if (ctxs->cfa_is_regoff && ctxs->cfa_reg == FP_REG) {
si->cfa_off = ctxs->cfa_off;
# if defined(VGA_x86) || defined(VGA_amd64) || defined(VGA_s390x) \
- || defined(VGA_mips32)
+ || defined(VGA_mips32) || defined(VGA_mips64)
si->cfa_how = CFIC_IA_BPREL;
# elif defined(VGA_arm)
si->cfa_how = CFIC_ARM_R12REL;
return True;
-# elif defined(VGA_mips32)
+# elif defined(VGA_mips32) || defined(VGA_mips64)
/* --- entire tail of this fn specialised for mips --- */
return ML_(CfiExpr_CfiReg)( dstxa, Creg_IA_BP );
if (dwreg == srcuc->ra_reg)
return ML_(CfiExpr_CfiReg)( dstxa, Creg_IA_IP ); /* correct? */
-# elif defined(VGA_mips32)
+# elif defined(VGA_mips32) || defined(VGA_mips64)
if (dwreg == SP_REG)
return ML_(CfiExpr_CfiReg)( dstxa, Creg_IA_SP );
if (dwreg == FP_REG)
/* PLT is different on different platforms, it seems. */
# if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
|| defined(VGP_arm_linux) || defined (VGP_s390x_linux) \
- || defined(VGP_mips32_linux)
+ || defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
/* Accept .plt where mapped as rx (code) */
if (0 == VG_(strcmp)(name, ".plt")) {
if (inrx && !di->plt_present) {
&& !defined(VGP_s390x_linux) \
&& !defined(VGP_ppc64_linux) \
&& !defined(VGPV_arm_linux_android) \
- && !defined(VGPV_x86_linux_android)
+ && !defined(VGPV_x86_linux_android) \
+ && !defined(VGP_mips64_linux)
if (stab_img && stabstr_img) {
ML_(read_debuginfo_stabs) ( di, stab_img, stab_sz,
stabstr_img, stabstr_sz );
VG_(printf)(" R7=");
SHOW_HOW(si->r7_how, si->r7_off);
# elif defined(VGA_ppc32) || defined(VGA_ppc64)
-# elif defined(VGA_s390x) || defined(VGA_mips32)
+# elif defined(VGA_s390x) || defined(VGA_mips32) || defined(VGA_mips64)
VG_(printf)(" SP=");
SHOW_HOW(si->sp_how, si->sp_off);
VG_(printf)(" FP=");
return __res;
}
+#elif defined(VGP_mips64_linux)
+static UInt local_sys_write_stderr ( const HChar* buf, Int n )
+{
+ volatile Long block[2];
+ block[0] = (Long)buf;
+ block[1] = n;
+ __asm__ volatile (
+ "li $4, 2\n\t" /* std output*/
+ "ld $5, 0(%0)\n\t" /*$5 = buf*/
+ "ld $6, 8(%0)\n\t" /*$6 = n */
+ "move $7, $0\n\t"
+ "li $2, %1\n\t" /* set v0 = __NR_write */
+ "\tsyscall\n"
+ "\tnop\n"
+ : /*wr*/
+ : /*rd*/ "r" (block), "n" (__NR_write)
+ : "2", "4", "5", "6", "7"
+ );
+ if (block[0] < 0)
+ block[0] = -1;
+ return (UInt)(Int)block[0];
+}
+
+static UInt local_sys_getpid ( void )
+{
+ ULong __res;
+ __asm__ volatile (
+ "li $2, %1\n\t" /* set v0 = __NR_getpid */
+ "syscall\n\t" /* getpid() */
+ "nop\n\t"
+ "move %0, $2\n"
+ : "=r" (__res)
+ : "n" (__NR_getpid)
+ : "$2" );
+ return (UInt)(__res);
+}
#else
# error Unknown platform
return values can be written */
sw $4, 60($29)
- /* Load address of guest state into guest state register (r10) */
- move $10, $5
+ /* Load address of guest state into guest state register ($23) */
+ move $23, $5
/* and jump into the code cache. Chained translations in
the code cache run, until for whatever reason, they can't
/*----------------------------------------------------*/
postamble:
- /* At this point, r2 and r3 contain two
- words to be returned to the caller. r2
- holds a TRC value, and r3 optionally may
+ /* At this point, $2 and $3 contain two
+ words to be returned to the caller. $2
+ holds a TRC value, and $3 optionally may
hold another word (for CHAIN_ME exits, the
address of the place to patch.) */
.global VG_(disp_cp_xindir)
VG_(disp_cp_xindir):
/* Where are we going? */
- lw $11, OFFSET_mips32_PC($10)
+ lw $11, OFFSET_mips32_PC($23)
lw $13, vgPlain_stats__n_xindirs_32
addiu $13, $13, 0x1
VG_(disp_cp_xassisted):
/* guest-state-pointer contains the TRC. Put the value into the
return register */
- move $2, $10
+ move $2, $23
move $3, $0
b postamble
--- /dev/null
+
+/*--------------------------------------------------------------------*/
+/*--- The core dispatch loop, for jumping to a code address. ---*/
+/*--- dispatch-mips64-linux.S ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2013 RT-RK
+ mips-valgrind@rt-rk.com
+
+ 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.
+*/
+
+
+#if defined(VGP_mips64_linux)
+
+#include "pub_core_basics_asm.h"
+#include "pub_core_dispatch_asm.h"
+#include "pub_core_transtab_asm.h"
+#include "libvex_guest_offsets.h" /* for OFFSET_mips_PC */
+
+
+/*------------------------------------------------------------*/
+/*--- ---*/
+/*--- The dispatch loop. VG_(disp_run_translations) is ---*/
+/*--- used to run all translations, ---*/
+/*--- including no-redir ones. ---*/
+/*--- ---*/
+/*------------------------------------------------------------*/
+
+/*----------------------------------------------------*/
+/*--- Entry and preamble (set everything up) ---*/
+/*----------------------------------------------------*/
+
+/* signature:
+void VG_(disp_run_translations)( UWord* two_words,
+ void* guest_state,
+ Addr host_addr );
+*/
+
+.text
+.globl VG_(disp_run_translations)
+VG_(disp_run_translations):
+ /* a0 ($4) holds two_words */
+ /* a1 ($5) holds guest_state */
+ /* a2 ($6) holds host_addr */
+
+ /* New stack frame. Stack must remain 16 aligned (at least) */
+ daddiu $29, -176
+
+ /* Save ra */
+ sd $31, 72($29)
+
+ /* ... and s0 - s7 */
+ sd $16, 80($29)
+ sd $17, 88($29)
+ sd $18, 96($29)
+ sd $19, 104($29)
+ sd $20, 112($29)
+ sd $21, 120($29)
+ sd $22, 128($29)
+ sd $23, 136($29)
+
+ /* ... and gp, fp/s8 */
+ sd $28, 144($29)
+ sd $30, 152($29)
+
+ /* Save a0 ($4) on stack. In postamble it will be restored such that the
+ return values can be written */
+ sd $4, 160($29)
+
+ /* Load address of guest state into guest state register ($23) */
+ move $23, $5
+
+ /* and jump into the code cache. Chained translations in
+ the code cache run, until for whatever reason, they can't
+ continue. When that happens, the translation in question
+ will jump (or call) to one of the continuation points
+ VG_(cp_...) below. */
+ jr $6
+ /*NOTREACHED*/
+
+/*----------------------------------------------------*/
+/*--- Postamble and exit. ---*/
+/*----------------------------------------------------*/
+
+postamble:
+ /* At this point, $2 and $3 contain two
+ words to be returned to the caller. $2
+ holds a TRC value, and $3 optionally may
+ hold another word (for CHAIN_ME exits, the
+ address of the place to patch.) */
+
+ /* Restore $4 from stack; holds address of two_words */
+ ld $4, 160($29)
+ sd $2, 0($4) /* Store $2 to two_words[0] */
+ sd $3, 8($4) /* Store $3 to two_words[1] */
+
+ /* Restore callee-saved registers... */
+
+ /* Restore ra */
+ ld $31, 72($29)
+
+ /* ... and s0 - s7 */
+ ld $16, 80($29)
+ ld $17, 88($29)
+ ld $18, 96($29)
+ ld $19, 104($29)
+ ld $20, 112($29)
+ ld $21, 120($29)
+ ld $22, 128($29)
+ ld $23, 136($29)
+
+ /* ... and gp, fp/s8 */
+ ld $28, 144($29)
+ ld $30, 152($29)
+
+ daddiu $29, 176 /* stack_size */
+ jr $31
+ nop
+
+/*----------------------------------------------------*/
+/*--- Continuation points ---*/
+/*----------------------------------------------------*/
+
+/* ------ Chain me to slow entry point ------ */
+.global VG_(disp_cp_chain_me_to_slowEP)
+VG_(disp_cp_chain_me_to_slowEP):
+ /* We got called. The return address indicates
+ where the patching needs to happen. Collect
+ the return address and, exit back to C land,
+ handing the caller the pair (Chain_me_S, RA) */
+ li $2, VG_TRC_CHAIN_ME_TO_SLOW_EP
+ move $3, $31
+ /* 8 = mkLoadImm_EXACTLY2or6
+ 4 = jalr $9
+ 4 = nop */
+ daddiu $3, $3, -32
+ b postamble
+
+/* ------ Chain me to slow entry point ------ */
+.global VG_(disp_cp_chain_me_to_fastEP)
+VG_(disp_cp_chain_me_to_fastEP):
+ /* We got called. The return address indicates
+ where the patching needs to happen. Collect
+ the return address and, exit back to C land,
+ handing the caller the pair (Chain_me_S, RA) */
+ li $2, VG_TRC_CHAIN_ME_TO_FAST_EP
+ move $3, $31
+ /* 8 = mkLoadImm_EXACTLY2or6
+ 4 = jalr $9
+ 4 = nop */
+ daddiu $3, $3, -32
+ b postamble
+
+/* ------ Indirect but boring jump ------ */
+.global VG_(disp_cp_xindir)
+VG_(disp_cp_xindir):
+ /* Where are we going? */
+ ld $11, OFFSET_mips64_PC($23)
+
+ lw $13, vgPlain_stats__n_xindirs_32
+ addiu $13, $13, 0x1
+ sw $13, vgPlain_stats__n_xindirs_32
+
+ /* try a fast lookup in the translation cache */
+ /* t1 = VG_TT_FAST_HASH(addr) * sizeof(ULong*)
+ = (t8 >> 2 & VG_TT_FAST_MASK) << 3 */
+
+ move $14, $11
+ li $12, VG_TT_FAST_MASK
+ srl $14, $14, 2
+ and $14, $14, $12
+ sll $14, $14, 3
+
+ /* t2 = (addr of VG_(tt_fast)) + t1 */
+ la $13, VG_(tt_fast)
+ addu $13, $13, $14
+
+ ld $12, 0($13) /* t3 = VG_(tt_fast)[hash] :: ULong* */
+ addi $13, $13, 8
+ ld $25, 0($13) /* little-endian, so comparing 1st 32bit word */
+ nop
+
+check:
+ bne $12, $11, fast_lookup_failed
+ /* run the translation */
+ jr $25
+ .long 0x0 /* persuade insn decoders not to speculate past here */
+
+fast_lookup_failed:
+ /* %PC is up to date */
+ /* back out decrement of the dispatch counter */
+ /* hold dispatch_ctr in t0 (r8) */
+ lw $13, vgPlain_stats__n_xindirs_32
+ addiu $13, $13, 0x1
+ sw $13, vgPlain_stats__n_xindirs_32
+ li $2, VG_TRC_INNER_FASTMISS
+ li $3, 0
+ b postamble
+
+/* ------ Assisted jump ------ */
+ .global VG_(disp_cp_xassisted)
+VG_(disp_cp_xassisted):
+ /* guest-state-pointer contains the TRC. Put the value into the
+ return register */
+ move $2, $23
+ move $3, $0
+ b postamble
+
+/* ------ Event check failed ------ */
+ .global VG_(disp_cp_evcheck_fail)
+VG_(disp_cp_evcheck_fail):
+ li $2, VG_TRC_INNER_COUNTERZERO
+ move $3, $0
+ b postamble
+
+.size VG_(disp_run_translations), .-VG_(disp_run_translations)
+
+
+/* Let the linker know we do not need an executable stack */
+.section .note.GNU-stack,"",@progbits
+
+#endif // defined(VGP_mips64_linux)
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.cp0.valgrind.s1">
+ <reg name="statuss1" bitsize="64" regnum="32"/>
+ <reg name="badvaddrs1" bitsize="64" regnum="35"/>
+ <reg name="causes1" bitsize="64" regnum="36"/>
+</feature>
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.cp0.valgrind.s2">
+ <reg name="statuss2" bitsize="64" regnum="32"/>
+ <reg name="badvaddrs2" bitsize="64" regnum="35"/>
+ <reg name="causes2" bitsize="64" regnum="36"/>
+</feature>
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.cp0">
+ <reg name="status" bitsize="64" regnum="32"/>
+ <reg name="badvaddr" bitsize="64" regnum="35"/>
+ <reg name="cause" bitsize="64" regnum="36"/>
+</feature>
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007-2013 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.cpu.valgrind.s1">
+ <reg name="r0s1" bitsize="64" regnum="0"/>
+ <reg name="r1s1" bitsize="64"/>
+ <reg name="r2s1" bitsize="64"/>
+ <reg name="r3s1" bitsize="64"/>
+ <reg name="r4s1" bitsize="64"/>
+ <reg name="r5s1" bitsize="64"/>
+ <reg name="r6s1" bitsize="64"/>
+ <reg name="r7s1" bitsize="64"/>
+ <reg name="r8s1" bitsize="64"/>
+ <reg name="r9s1" bitsize="64"/>
+ <reg name="r10s1" bitsize="64"/>
+ <reg name="r11s1" bitsize="64"/>
+ <reg name="r12s1" bitsize="64"/>
+ <reg name="r13s1" bitsize="64"/>
+ <reg name="r14s1" bitsize="64"/>
+ <reg name="r15s1" bitsize="64"/>
+ <reg name="r16s1" bitsize="64"/>
+ <reg name="r17s1" bitsize="64"/>
+ <reg name="r18s1" bitsize="64"/>
+ <reg name="r19s1" bitsize="64"/>
+ <reg name="r20s1" bitsize="64"/>
+ <reg name="r21s1" bitsize="64"/>
+ <reg name="r22s1" bitsize="64"/>
+ <reg name="r23s1" bitsize="64"/>
+ <reg name="r24s1" bitsize="64"/>
+ <reg name="r25s1" bitsize="64"/>
+ <reg name="r26s1" bitsize="64"/>
+ <reg name="r27s1" bitsize="64"/>
+ <reg name="r28s1" bitsize="64"/>
+ <reg name="r29s1" bitsize="64"/>
+ <reg name="r30s1" bitsize="64"/>
+ <reg name="r31s1" bitsize="64"/>
+
+ <reg name="los1" bitsize="64" regnum="33"/>
+ <reg name="his1" bitsize="64" regnum="34"/>
+ <reg name="pcs1" bitsize="64" regnum="37"/>
+</feature>
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007-2013 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.cpu.valgrind.s2">
+ <reg name="r0s2" bitsize="64" regnum="0"/>
+ <reg name="r1s2" bitsize="64"/>
+ <reg name="r2s2" bitsize="64"/>
+ <reg name="r3s2" bitsize="64"/>
+ <reg name="r4s2" bitsize="64"/>
+ <reg name="r5s2" bitsize="64"/>
+ <reg name="r6s2" bitsize="64"/>
+ <reg name="r7s2" bitsize="64"/>
+ <reg name="r8s2" bitsize="64"/>
+ <reg name="r9s2" bitsize="64"/>
+ <reg name="r10s2" bitsize="64"/>
+ <reg name="r11s2" bitsize="64"/>
+ <reg name="r12s2" bitsize="64"/>
+ <reg name="r13s2" bitsize="64"/>
+ <reg name="r14s2" bitsize="64"/>
+ <reg name="r15s2" bitsize="64"/>
+ <reg name="r16s2" bitsize="64"/>
+ <reg name="r17s2" bitsize="64"/>
+ <reg name="r18s2" bitsize="64"/>
+ <reg name="r19s2" bitsize="64"/>
+ <reg name="r20s2" bitsize="64"/>
+ <reg name="r21s2" bitsize="64"/>
+ <reg name="r22s2" bitsize="64"/>
+ <reg name="r23s2" bitsize="64"/>
+ <reg name="r24s2" bitsize="64"/>
+ <reg name="r25s2" bitsize="64"/>
+ <reg name="r26s2" bitsize="64"/>
+ <reg name="r27s2" bitsize="64"/>
+ <reg name="r28s2" bitsize="64"/>
+ <reg name="r29s2" bitsize="64"/>
+ <reg name="r30s2" bitsize="64"/>
+ <reg name="r31s2" bitsize="64"/>
+
+ <reg name="los2" bitsize="64" regnum="33"/>
+ <reg name="his2" bitsize="64" regnum="34"/>
+ <reg name="pcs2" bitsize="64" regnum="37"/>
+</feature>
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007-2013 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.cpu">
+ <reg name="r0" bitsize="64" regnum="0"/>
+ <reg name="r1" bitsize="64"/>
+ <reg name="r2" bitsize="64"/>
+ <reg name="r3" bitsize="64"/>
+ <reg name="r4" bitsize="64"/>
+ <reg name="r5" bitsize="64"/>
+ <reg name="r6" bitsize="64"/>
+ <reg name="r7" bitsize="64"/>
+ <reg name="r8" bitsize="64"/>
+ <reg name="r9" bitsize="64"/>
+ <reg name="r10" bitsize="64"/>
+ <reg name="r11" bitsize="64"/>
+ <reg name="r12" bitsize="64"/>
+ <reg name="r13" bitsize="64"/>
+ <reg name="r14" bitsize="64"/>
+ <reg name="r15" bitsize="64"/>
+ <reg name="r16" bitsize="64"/>
+ <reg name="r17" bitsize="64"/>
+ <reg name="r18" bitsize="64"/>
+ <reg name="r19" bitsize="64"/>
+ <reg name="r20" bitsize="64"/>
+ <reg name="r21" bitsize="64"/>
+ <reg name="r22" bitsize="64"/>
+ <reg name="r23" bitsize="64"/>
+ <reg name="r24" bitsize="64"/>
+ <reg name="r25" bitsize="64"/>
+ <reg name="r26" bitsize="64"/>
+ <reg name="r27" bitsize="64"/>
+ <reg name="r28" bitsize="64"/>
+ <reg name="r29" bitsize="64"/>
+ <reg name="r30" bitsize="64"/>
+ <reg name="r31" bitsize="64"/>
+
+ <reg name="lo" bitsize="64" regnum="33"/>
+ <reg name="hi" bitsize="64" regnum="34"/>
+ <reg name="pc" bitsize="64" regnum="37"/>
+</feature>
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.fpu.valgrind.s1">
+ <reg name="f0s1" bitsize="64" type="ieee_double" regnum="38"/>
+ <reg name="f1s1" bitsize="64" type="ieee_double"/>
+ <reg name="f2s1" bitsize="64" type="ieee_double"/>
+ <reg name="f3s1" bitsize="64" type="ieee_double"/>
+ <reg name="f4s1" bitsize="64" type="ieee_double"/>
+ <reg name="f5s1" bitsize="64" type="ieee_double"/>
+ <reg name="f6s1" bitsize="64" type="ieee_double"/>
+ <reg name="f7s1" bitsize="64" type="ieee_double"/>
+ <reg name="f8s1" bitsize="64" type="ieee_double"/>
+ <reg name="f9s1" bitsize="64" type="ieee_double"/>
+ <reg name="f10s1" bitsize="64" type="ieee_double"/>
+ <reg name="f11s1" bitsize="64" type="ieee_double"/>
+ <reg name="f12s1" bitsize="64" type="ieee_double"/>
+ <reg name="f13s1" bitsize="64" type="ieee_double"/>
+ <reg name="f14s1" bitsize="64" type="ieee_double"/>
+ <reg name="f15s1" bitsize="64" type="ieee_double"/>
+ <reg name="f16s1" bitsize="64" type="ieee_double"/>
+ <reg name="f17s1" bitsize="64" type="ieee_double"/>
+ <reg name="f18s1" bitsize="64" type="ieee_double"/>
+ <reg name="f19s1" bitsize="64" type="ieee_double"/>
+ <reg name="f20s1" bitsize="64" type="ieee_double"/>
+ <reg name="f21s1" bitsize="64" type="ieee_double"/>
+ <reg name="f22s1" bitsize="64" type="ieee_double"/>
+ <reg name="f23s1" bitsize="64" type="ieee_double"/>
+ <reg name="f24s1" bitsize="64" type="ieee_double"/>
+ <reg name="f25s1" bitsize="64" type="ieee_double"/>
+ <reg name="f26s1" bitsize="64" type="ieee_double"/>
+ <reg name="f27s1" bitsize="64" type="ieee_double"/>
+ <reg name="f28s1" bitsize="64" type="ieee_double"/>
+ <reg name="f29s1" bitsize="64" type="ieee_double"/>
+ <reg name="f30s1" bitsize="64" type="ieee_double"/>
+ <reg name="f31s1" bitsize="64" type="ieee_double"/>
+
+ <reg name="fcsrs1" bitsize="64" group="float"/>
+ <reg name="firs1" bitsize="64" group="float"/>
+</feature>
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.fpu.valgrind.s2">
+ <reg name="f0s2" bitsize="64" type="ieee_double" regnum="38"/>
+ <reg name="f1s2" bitsize="64" type="ieee_double"/>
+ <reg name="f2s2" bitsize="64" type="ieee_double"/>
+ <reg name="f3s2" bitsize="64" type="ieee_double"/>
+ <reg name="f4s2" bitsize="64" type="ieee_double"/>
+ <reg name="f5s2" bitsize="64" type="ieee_double"/>
+ <reg name="f6s2" bitsize="64" type="ieee_double"/>
+ <reg name="f7s2" bitsize="64" type="ieee_double"/>
+ <reg name="f8s2" bitsize="64" type="ieee_double"/>
+ <reg name="f9s2" bitsize="64" type="ieee_double"/>
+ <reg name="f10s2" bitsize="64" type="ieee_double"/>
+ <reg name="f11s2" bitsize="64" type="ieee_double"/>
+ <reg name="f12s2" bitsize="64" type="ieee_double"/>
+ <reg name="f13s2" bitsize="64" type="ieee_double"/>
+ <reg name="f14s2" bitsize="64" type="ieee_double"/>
+ <reg name="f15s2" bitsize="64" type="ieee_double"/>
+ <reg name="f16s2" bitsize="64" type="ieee_double"/>
+ <reg name="f17s2" bitsize="64" type="ieee_double"/>
+ <reg name="f18s2" bitsize="64" type="ieee_double"/>
+ <reg name="f19s2" bitsize="64" type="ieee_double"/>
+ <reg name="f20s2" bitsize="64" type="ieee_double"/>
+ <reg name="f21s2" bitsize="64" type="ieee_double"/>
+ <reg name="f22s2" bitsize="64" type="ieee_double"/>
+ <reg name="f23s2" bitsize="64" type="ieee_double"/>
+ <reg name="f24s2" bitsize="64" type="ieee_double"/>
+ <reg name="f25s2" bitsize="64" type="ieee_double"/>
+ <reg name="f26s2" bitsize="64" type="ieee_double"/>
+ <reg name="f27s2" bitsize="64" type="ieee_double"/>
+ <reg name="f28s2" bitsize="64" type="ieee_double"/>
+ <reg name="f29s2" bitsize="64" type="ieee_double"/>
+ <reg name="f30s2" bitsize="64" type="ieee_double"/>
+ <reg name="f31s2" bitsize="64" type="ieee_double"/>
+
+ <reg name="fcsrs2" bitsize="64" group="float"/>
+ <reg name="firs2" bitsize="64" group="float"/>
+</feature>
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007-2013 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.mips.fpu">
+ <reg name="f0" bitsize="64" type="ieee_double" regnum="38"/>
+ <reg name="f1" bitsize="64" type="ieee_double"/>
+ <reg name="f2" bitsize="64" type="ieee_double"/>
+ <reg name="f3" bitsize="64" type="ieee_double"/>
+ <reg name="f4" bitsize="64" type="ieee_double"/>
+ <reg name="f5" bitsize="64" type="ieee_double"/>
+ <reg name="f6" bitsize="64" type="ieee_double"/>
+ <reg name="f7" bitsize="64" type="ieee_double"/>
+ <reg name="f8" bitsize="64" type="ieee_double"/>
+ <reg name="f9" bitsize="64" type="ieee_double"/>
+ <reg name="f10" bitsize="64" type="ieee_double"/>
+ <reg name="f11" bitsize="64" type="ieee_double"/>
+ <reg name="f12" bitsize="64" type="ieee_double"/>
+ <reg name="f13" bitsize="64" type="ieee_double"/>
+ <reg name="f14" bitsize="64" type="ieee_double"/>
+ <reg name="f15" bitsize="64" type="ieee_double"/>
+ <reg name="f16" bitsize="64" type="ieee_double"/>
+ <reg name="f17" bitsize="64" type="ieee_double"/>
+ <reg name="f18" bitsize="64" type="ieee_double"/>
+ <reg name="f19" bitsize="64" type="ieee_double"/>
+ <reg name="f20" bitsize="64" type="ieee_double"/>
+ <reg name="f21" bitsize="64" type="ieee_double"/>
+ <reg name="f22" bitsize="64" type="ieee_double"/>
+ <reg name="f23" bitsize="64" type="ieee_double"/>
+ <reg name="f24" bitsize="64" type="ieee_double"/>
+ <reg name="f25" bitsize="64" type="ieee_double"/>
+ <reg name="f26" bitsize="64" type="ieee_double"/>
+ <reg name="f27" bitsize="64" type="ieee_double"/>
+ <reg name="f28" bitsize="64" type="ieee_double"/>
+ <reg name="f29" bitsize="64" type="ieee_double"/>
+ <reg name="f30" bitsize="64" type="ieee_double"/>
+ <reg name="f31" bitsize="64" type="ieee_double"/>
+
+ <reg name="fcsr" bitsize="64" group="float"/>
+ <reg name="fir" bitsize="64" group="float"/>
+</feature>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007-2013 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>mips</architecture>
+ <xi:include href="mips64-cpu.xml"/>
+ <xi:include href="mips64-cp0.xml"/>
+ <xi:include href="mips64-fpu.xml"/>
+ <xi:include href="mips64-cpu-valgrind-s1.xml"/>
+ <xi:include href="mips64-cp0-valgrind-s1.xml"/>
+ <xi:include href="mips64-fpu-valgrind-s1.xml"/>
+ <xi:include href="mips64-cpu-valgrind-s2.xml"/>
+ <xi:include href="mips64-cp0-valgrind-s2.xml"/>
+ <xi:include href="mips64-fpu-valgrind-s2.xml"/>
+
+ <feature name="org.gnu.gdb.mips.linux">
+ <reg name="restart" bitsize="64" group="system"/>
+ </feature>
+</target>
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2007-2013 Free Software Foundation, Inc.
+
+ Copying and distribution of this file, with or without modification,
+ are permitted in any medium without royalty provided the copyright
+ notice and this notice are preserved. -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>mips</architecture>
+ <xi:include href="mips64-cpu.xml"/>
+ <xi:include href="mips64-cp0.xml"/>
+ <xi:include href="mips64-fpu.xml"/>
+
+ <feature name="org.gnu.gdb.mips.linux">
+ <reg name="restart" bitsize="64" group="system"/>
+ </feature>
+</target>
\ No newline at end of file
s390x_init_architecture(&the_low_target);
#elif defined(VGA_mips32)
mips32_init_architecture(&the_low_target);
+#elif defined(VGA_mips64)
+ mips64_init_architecture(&the_low_target);
#else
architecture missing in target.c valgrind_initialize_target
#endif
--- /dev/null
+/* Low level interface to valgrind, for the remote server for GDB integrated
+ in valgrind.
+ Copyright (C) 2011
+ Free Software Foundation, Inc.
+
+ This file is part of VALGRIND.
+ It has been inspired from a file from gdbserver in gdb 6.6.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+#include "server.h"
+#include "target.h"
+#include "regdef.h"
+#include "regcache.h"
+
+#include "pub_core_aspacemgr.h"
+#include "pub_tool_machine.h"
+#include "pub_core_threadstate.h"
+#include "pub_core_transtab.h"
+#include "pub_core_gdbserver.h"
+
+#include "valgrind_low.h"
+
+#include "libvex_guest_mips64.h"
+
+static struct reg regs[] = {
+ { "r0", 0, 64 },
+ { "r1", 64, 64 },
+ { "r2", 128, 64 },
+ { "r3", 192, 64 },
+ { "r4", 256, 64 },
+ { "r5", 320, 64 },
+ { "r6", 384, 64 },
+ { "r7", 448, 64 },
+ { "r8", 512, 64 },
+ { "r9", 576, 64 },
+ { "r10", 640, 64 },
+ { "r11", 704, 64 },
+ { "r12", 768, 64 },
+ { "r13", 832, 64 },
+ { "r14", 896, 64 },
+ { "r15", 960, 64 },
+ { "r16", 1024, 64 },
+ { "r17", 1088, 64 },
+ { "r18", 1152, 64 },
+ { "r19", 1216, 64 },
+ { "r20", 1280, 64 },
+ { "r21", 1344, 64 },
+ { "r22", 1408, 64 },
+ { "r23", 1472, 64 },
+ { "r24", 1536, 64 },
+ { "r25", 1600, 64 },
+ { "r26", 1664, 64 },
+ { "r27", 1728, 64 },
+ { "r28", 1792, 64 },
+ { "r29", 1856, 64 },
+ { "r30", 1920, 64 },
+ { "r31", 1984, 64 },
+ { "status", 2048, 64 },
+ { "lo", 2112, 64 },
+ { "hi", 2176, 64 },
+ { "badvaddr", 2240, 64 },
+ { "cause", 2304, 64 },
+ { "pc", 2368, 64 },
+ { "f0", 2432, 64 },
+ { "f1", 2496, 64 },
+ { "f2", 2560, 64 },
+ { "f3", 2624, 64 },
+ { "f4", 2688, 64 },
+ { "f5", 2752, 64 },
+ { "f6", 2816, 64 },
+ { "f7", 2880, 64 },
+ { "f8", 2944, 64 },
+ { "f9", 3008, 64 },
+ { "f10", 3072, 64 },
+ { "f11", 3136, 64 },
+ { "f12", 3200, 64 },
+ { "f13", 3264, 64 },
+ { "f14", 3328, 64 },
+ { "f15", 3392, 64 },
+ { "f16", 3456, 64 },
+ { "f17", 3520, 64 },
+ { "f18", 3584, 64 },
+ { "f19", 3648, 64 },
+ { "f20", 3712, 64 },
+ { "f21", 3776, 64 },
+ { "f22", 3840, 64 },
+ { "f23", 3904, 64 },
+ { "f24", 3968, 64 },
+ { "f25", 4032, 64 },
+ { "f26", 4096, 64 },
+ { "f27", 4160, 64 },
+ { "f28", 4224, 64 },
+ { "f29", 4288, 64 },
+ { "f30", 4352, 64 },
+ { "f31", 4416, 64 },
+ { "fcsr", 4480, 64 },
+ { "fir", 4544, 64 },
+ { "restart", 4608, 64 }
+};
+
+
+#define num_regs (sizeof (regs) / sizeof (regs[0]))
+
+static const char *expedite_regs[] = { "r29", "pc", 0 };
+
+static
+CORE_ADDR get_pc (void)
+{
+ unsigned long pc;
+
+ collect_register_by_name ("pc", &pc);
+
+ dlog(1, "stop pc is %p\n", (void *) pc);
+ return pc;
+}
+
+static
+void set_pc (CORE_ADDR newpc)
+{
+ Bool mod;
+ supply_register_by_name ("pc", &newpc, &mod);
+ if (mod)
+ dlog(1, "set pc to %p\n", C2v (newpc));
+ else
+ dlog(1, "set pc not changed %p\n", C2v (newpc));
+}
+
+/* store registers in the guest state (gdbserver_to_valgrind)
+ or fetch register from the guest state (valgrind_to_gdbserver). */
+static
+void transfer_register (ThreadId tid, int abs_regno, void * buf,
+ transfer_direction dir, int size, Bool *mod)
+{
+ ThreadState* tst = VG_(get_ThreadState)(tid);
+ int set = abs_regno / num_regs;
+ int regno = abs_regno % num_regs;
+ *mod = False;
+
+ VexGuestMIPS64State* mips1 = (VexGuestMIPS64State*) get_arch (set, tst);
+
+ switch (regno) {
+ case 0: VG_(transfer) (&mips1->guest_r0, buf, dir, size, mod); break;
+ case 1: VG_(transfer) (&mips1->guest_r1, buf, dir, size, mod); break;
+ case 2: VG_(transfer) (&mips1->guest_r2, buf, dir, size, mod); break;
+ case 3: VG_(transfer) (&mips1->guest_r3, buf, dir, size, mod); break;
+ case 4: VG_(transfer) (&mips1->guest_r4, buf, dir, size, mod); break;
+ case 5: VG_(transfer) (&mips1->guest_r5, buf, dir, size, mod); break;
+ case 6: VG_(transfer) (&mips1->guest_r6, buf, dir, size, mod); break;
+ case 7: VG_(transfer) (&mips1->guest_r7, buf, dir, size, mod); break;
+ case 8: VG_(transfer) (&mips1->guest_r8, buf, dir, size, mod); break;
+ case 9: VG_(transfer) (&mips1->guest_r9, buf, dir, size, mod); break;
+ case 10: VG_(transfer) (&mips1->guest_r10, buf, dir, size, mod); break;
+ case 11: VG_(transfer) (&mips1->guest_r11, buf, dir, size, mod); break;
+ case 12: VG_(transfer) (&mips1->guest_r12, buf, dir, size, mod); break;
+ case 13: VG_(transfer) (&mips1->guest_r13, buf, dir, size, mod); break;
+ case 14: VG_(transfer) (&mips1->guest_r14, buf, dir, size, mod); break;
+ case 15: VG_(transfer) (&mips1->guest_r15, buf, dir, size, mod); break;
+ case 16: VG_(transfer) (&mips1->guest_r16, buf, dir, size, mod); break;
+ case 17: VG_(transfer) (&mips1->guest_r17, buf, dir, size, mod); break;
+ case 18: VG_(transfer) (&mips1->guest_r18, buf, dir, size, mod); break;
+ case 19: VG_(transfer) (&mips1->guest_r19, buf, dir, size, mod); break;
+ case 20: VG_(transfer) (&mips1->guest_r20, buf, dir, size, mod); break;
+ case 21: VG_(transfer) (&mips1->guest_r21, buf, dir, size, mod); break;
+ case 22: VG_(transfer) (&mips1->guest_r22, buf, dir, size, mod); break;
+ case 23: VG_(transfer) (&mips1->guest_r23, buf, dir, size, mod); break;
+ case 24: VG_(transfer) (&mips1->guest_r24, buf, dir, size, mod); break;
+ case 25: VG_(transfer) (&mips1->guest_r25, buf, dir, size, mod); break;
+ case 26: VG_(transfer) (&mips1->guest_r26, buf, dir, size, mod); break;
+ case 27: VG_(transfer) (&mips1->guest_r27, buf, dir, size, mod); break;
+ case 28: VG_(transfer) (&mips1->guest_r28, buf, dir, size, mod); break;
+ case 29: VG_(transfer) (&mips1->guest_r29, buf, dir, size, mod); break;
+ case 30: VG_(transfer) (&mips1->guest_r30, buf, dir, size, mod); break;
+ case 31: VG_(transfer) (&mips1->guest_r31, buf, dir, size, mod); break;
+ case 32: *mod = False; break; // GDBTD???? VEX { "status", 1024, 64 }
+ case 33: VG_(transfer) (&mips1->guest_LO, buf, dir, size, mod); break;
+ case 34: VG_(transfer) (&mips1->guest_HI, buf, dir, size, mod); break;
+ case 35: *mod = False; break; // GDBTD???? VEX { "badvaddr", 1120, 64 },
+ case 36: *mod = False; break; // GDBTD???? VEX { "cause", 1152, 64 },
+ case 37: VG_(transfer) (&mips1->guest_PC, buf, dir, size, mod); break;
+ case 38: VG_(transfer) (&mips1->guest_f0, buf, dir, size, mod); break;
+ case 39: VG_(transfer) (&mips1->guest_f1, buf, dir, size, mod); break;
+ case 40: VG_(transfer) (&mips1->guest_f2, buf, dir, size, mod); break;
+ case 41: VG_(transfer) (&mips1->guest_f3, buf, dir, size, mod); break;
+ case 42: VG_(transfer) (&mips1->guest_f4, buf, dir, size, mod); break;
+ case 43: VG_(transfer) (&mips1->guest_f5, buf, dir, size, mod); break;
+ case 44: VG_(transfer) (&mips1->guest_f6, buf, dir, size, mod); break;
+ case 45: VG_(transfer) (&mips1->guest_f7, buf, dir, size, mod); break;
+ case 46: VG_(transfer) (&mips1->guest_f8, buf, dir, size, mod); break;
+ case 47: VG_(transfer) (&mips1->guest_f9, buf, dir, size, mod); break;
+ case 48: VG_(transfer) (&mips1->guest_f10, buf, dir, size, mod); break;
+ case 49: VG_(transfer) (&mips1->guest_f11, buf, dir, size, mod); break;
+ case 50: VG_(transfer) (&mips1->guest_f12, buf, dir, size, mod); break;
+ case 51: VG_(transfer) (&mips1->guest_f13, buf, dir, size, mod); break;
+ case 52: VG_(transfer) (&mips1->guest_f14, buf, dir, size, mod); break;
+ case 53: VG_(transfer) (&mips1->guest_f15, buf, dir, size, mod); break;
+ case 54: VG_(transfer) (&mips1->guest_f16, buf, dir, size, mod); break;
+ case 55: VG_(transfer) (&mips1->guest_f17, buf, dir, size, mod); break;
+ case 56: VG_(transfer) (&mips1->guest_f18, buf, dir, size, mod); break;
+ case 57: VG_(transfer) (&mips1->guest_f19, buf, dir, size, mod); break;
+ case 58: VG_(transfer) (&mips1->guest_f20, buf, dir, size, mod); break;
+ case 59: VG_(transfer) (&mips1->guest_f21, buf, dir, size, mod); break;
+ case 60: VG_(transfer) (&mips1->guest_f22, buf, dir, size, mod); break;
+ case 61: VG_(transfer) (&mips1->guest_f23, buf, dir, size, mod); break;
+ case 62: VG_(transfer) (&mips1->guest_f24, buf, dir, size, mod); break;
+ case 63: VG_(transfer) (&mips1->guest_f25, buf, dir, size, mod); break;
+ case 64: VG_(transfer) (&mips1->guest_f26, buf, dir, size, mod); break;
+ case 65: VG_(transfer) (&mips1->guest_f27, buf, dir, size, mod); break;
+ case 66: VG_(transfer) (&mips1->guest_f28, buf, dir, size, mod); break;
+ case 67: VG_(transfer) (&mips1->guest_f29, buf, dir, size, mod); break;
+ case 68: VG_(transfer) (&mips1->guest_f30, buf, dir, size, mod); break;
+ case 69: VG_(transfer) (&mips1->guest_f31, buf, dir, size, mod); break;
+ case 70: VG_(transfer) (&mips1->guest_FCSR, buf, dir, size, mod); break;
+ case 71: VG_(transfer) (&mips1->guest_FIR, buf, dir, size, mod); break;
+ case 72: *mod = False; break; // GDBTD???? VEX{ "restart", 2304, 64 },
+ default: VG_(printf)("regno: %d\n", regno); vg_assert(0);
+ }
+}
+
+static
+const char* target_xml (Bool shadow_mode)
+{
+ if (shadow_mode) {
+ return "mips64-linux-valgrind.xml";
+ } else {
+ return "mips64-linux.xml";
+ }
+}
+
+static struct valgrind_target_ops low_target = {
+ num_regs,
+ regs,
+ 29, //sp = r29, which is register offset 29 in regs
+ transfer_register,
+ get_pc,
+ set_pc,
+ "mips64",
+ target_xml
+};
+
+void mips64_init_architecture (struct valgrind_target_ops *target)
+{
+ *target = low_target;
+ set_register_cache (regs, num_regs);
+ gdbserver_expedite_regs = expedite_regs;
+}
extern void ppc64_init_architecture (struct valgrind_target_ops *target);
extern void s390x_init_architecture (struct valgrind_target_ops *target);
extern void mips32_init_architecture (struct valgrind_target_ops *target);
+extern void mips64_init_architecture (struct valgrind_target_ops *target);
#endif
arch->vex.guest_PC = iifii.initial_client_IP;
arch->vex.guest_r31 = iifii.initial_client_SP;
+# elif defined(VGP_mips64_linux)
+ vg_assert(0 == sizeof(VexGuestMIPS64State) % 16);
+ /* Zero out the initial state, and set up the simulated FPU in a
+ sane way. */
+ LibVEX_GuestMIPS64_initialise(&arch->vex);
+
+ /* Zero out the shadow areas. */
+ VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestMIPS64State));
+ VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestMIPS64State));
+
+ arch->vex.guest_r29 = iifii.initial_client_SP;
+ arch->vex.guest_PC = iifii.initial_client_IP;
+ arch->vex.guest_r31 = iifii.initial_client_SP;
+
# else
# error Unknown platform
# endif
(srP)->misc.MIPS32.r31 = (ULong)ra; \
(srP)->misc.MIPS32.r28 = (ULong)gp; \
}
+#elif defined(VGP_mips64_linux)
+# define GET_STARTREGS(srP) \
+ { ULong pc, sp, fp, ra, gp; \
+ asm("move $8, $31;" /* t0 = ra */ \
+ "bal m_libcassert_get_ip;" /* ra = pc */ \
+ "m_libcassert_get_ip:\n" \
+ "move %0, $31;" \
+ "move $31, $8;" /* restore lr */ \
+ "move %1, $29;" \
+ "move %2, $30;" \
+ "move %3, $31;" \
+ "move %4, $28;" \
+ : "=r" (pc), \
+ "=r" (sp), \
+ "=r" (fp), \
+ "=r" (ra), \
+ "=r" (gp) \
+ : /* reads none */ \
+ : "$8" /* trashed */ ); \
+ (srP)->r_pc = (ULong)pc - 8; \
+ (srP)->r_sp = (ULong)sp; \
+ (srP)->misc.MIPS64.r30 = (ULong)fp; \
+ (srP)->misc.MIPS64.r31 = (ULong)ra; \
+ (srP)->misc.MIPS64.r28 = (ULong)gp; \
+ }
#else
# error Unknown platform
#endif
Int VG_(pipe) ( Int fd[2] )
{
-# if defined(VGP_mips32_linux)
+# if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
/* __NR_pipe has a strange return convention on mips32-linux. */
- SysRes res = VG_(do_syscall0)(__NR_pipe);
+ SysRes res = VG_(do_syscall1)(__NR_pipe, (UWord)fd);
if (!sr_isError(res)) {
fd[0] = (Int)sr_Res(res);
fd[1] = (Int)sr_ResEx(res);
0, // Padding needed on PPC32
0, offset); // Big endian long long
return res;
-# elif defined(VGP_mips32_linux) && VKI_LITTLE_ENDIAN
+# elif defined(VGP_mips32_linux) && (VKI_LITTLE_ENDIAN)
vg_assert(sizeof(OffT) == 4);
res = VG_(do_syscall6)(__NR_pread64, fd, (UWord)buf, count,
0, offset, 0);
return res;
-# elif defined(VGP_mips32_linux) && VKI_BIG_ENDIAN
+# elif defined(VGP_mips32_linux) && (VKI_BIG_ENDIAN)
vg_assert(sizeof(OffT) == 4);
res = VG_(do_syscall6)(__NR_pread64, fd, (UWord)buf, count,
0, 0, offset);
return res;
# elif defined(VGP_amd64_linux) \
- || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux)
+ || defined(VGP_ppc64_linux) || defined(VGP_s390x_linux) \
+ || defined(VGP_mips64_linux)
res = VG_(do_syscall4)(__NR_pread64, fd, (UWord)buf, count, offset);
return res;
# elif defined(VGP_amd64_darwin)
return sr_isError(res) ? -1 : sr_Res(res);
# elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
- || defined(VGP_mips32_linux)
+ || defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
SysRes res;
res = VG_(do_syscall3)(__NR_socket, domain, type, protocol );
return sr_isError(res) ? -1 : sr_Res(res);
return sr_isError(res) ? -1 : sr_Res(res);
# elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
- || defined(VGP_mips32_linux)
+ || defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
SysRes res;
res = VG_(do_syscall3)(__NR_connect, sockfd, (UWord)serv_addr, addrlen);
return sr_isError(res) ? -1 : sr_Res(res);
return sr_isError(res) ? -1 : sr_Res(res);
# elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
- || defined(VGP_mips32_linux)
+ || defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
SysRes res;
res = VG_(do_syscall6)(__NR_sendto, sd, (UWord)msg,
count, VKI_MSG_NOSIGNAL, 0,0);
res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKNAME, (UWord)&args);
return sr_isError(res) ? -1 : sr_Res(res);
-# elif defined(VGP_amd64_linux) || defined(VGP_arm_linux)
+# elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
+ || defined(VGP_mips64_linux)
SysRes res;
res = VG_(do_syscall3)( __NR_getsockname,
(UWord)sd, (UWord)name, (UWord)namelen );
res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETPEERNAME, (UWord)&args);
return sr_isError(res) ? -1 : sr_Res(res);
-# elif defined(VGP_amd64_linux) || defined(VGP_arm_linux)
+# elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
+ || defined(VGP_mips64_linux)
SysRes res;
res = VG_(do_syscall3)( __NR_getpeername,
(UWord)sd, (UWord)name, (UWord)namelen );
return sr_isError(res) ? -1 : sr_Res(res);
# elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
- || defined(VGP_mips32_linux)
+ || defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
SysRes res;
res = VG_(do_syscall5)( __NR_getsockopt,
(UWord)sd, (UWord)level, (UWord)optname,
platform. */
Int VG_(getgroups)( Int size, UInt* list )
{
-# if defined(VGP_x86_linux) || defined(VGP_ppc32_linux)
+# if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
+ || defined(VGP_mips64_linux)
Int i;
SysRes sres;
UShort list16[64];
Addr endaddr = startaddr + nbytes;
VG_(do_syscall2)(__NR_ARM_cacheflush, startaddr, endaddr);
-# elif defined(VGA_mips32)
+# elif defined(VGA_mips32) || defined(VGA_mips64)
SysRes sres = VG_(do_syscall3)(__NR_cacheflush, (UWord) ptr,
(UWord) nbytes, (UWord) 3);
vg_assert( sres._isError == 0 );
= VG_(threads)[tid].arch.vex.guest_r31;
regs->misc.MIPS32.r28
= VG_(threads)[tid].arch.vex.guest_r28;
+# elif defined(VGA_mips64)
+ regs->r_pc = VG_(threads)[tid].arch.vex.guest_PC;
+ regs->r_sp = VG_(threads)[tid].arch.vex.guest_r29;
+ regs->misc.MIPS64.r30
+ = VG_(threads)[tid].arch.vex.guest_r30;
+ regs->misc.MIPS64.r31
+ = VG_(threads)[tid].arch.vex.guest_r31;
+ regs->misc.MIPS64.r28
+ = VG_(threads)[tid].arch.vex.guest_r28;
# else
# error "Unknown arch"
# endif
# elif defined(VGP_s390x_linux)
VG_(threads)[tid].arch.vex_shadow1.guest_r2 = s1res;
VG_(threads)[tid].arch.vex_shadow2.guest_r2 = s2res;
-# elif defined(VGP_mips32_linux)
+# elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
VG_(threads)[tid].arch.vex_shadow1.guest_r2 = s1res;
VG_(threads)[tid].arch.vex_shadow2.guest_r2 = s2res;
# else
(*f)(tid, "r13", vex->guest_r13);
(*f)(tid, "r14", vex->guest_r14);
(*f)(tid, "r15", vex->guest_r15);
-#elif defined(VGA_mips32)
+#elif defined(VGA_mips32) || defined(VGA_mips64)
(*f)(tid, "r0" , vex->guest_r0 );
(*f)(tid, "r1" , vex->guest_r1 );
(*f)(tid, "r2" , vex->guest_r2 );
#endif /* VGA_s390x */
-#ifdef VGA_mips32
+#if defined(VGA_mips32) || defined(VGA_mips64)
/* Read /proc/cpuinfo and return the machine model. */
static UInt VG_(get_machine_model)(void)
{
- char *search_MIPS_str = "MIPS";
- char *search_Broadcom_str = "Broadcom";
+ const char *search_MIPS_str = "MIPS";
+ const char *search_Broadcom_str = "Broadcom";
+ const char *search_Netlogic_str = "Netlogic";
Int n, fh;
SysRes fd;
SizeT num_bytes, file_buf_size;
/* Parse file */
if (VG_(strstr) (file_buf, search_Broadcom_str) != NULL)
return VEX_PRID_COMP_BROADCOM;
+ if (VG_(strstr) (file_buf, search_Netlogic_str) != NULL)
+ return VEX_PRID_COMP_NETLOGIC;
if (VG_(strstr) (file_buf, search_MIPS_str) != NULL)
return VEX_PRID_COMP_MIPS;
return True;
}
+#elif defined(VGA_mips64)
+ {
+ va = VexArchMIPS64;
+ UInt model = VG_(get_machine_model)();
+ if (model== -1)
+ return False;
+
+ vai.hwcaps = model;
+
+ VG_(machine_get_cache_info)(&vai);
+
+ return True;
+ }
+
#else
# error "Unknown arch"
#endif
it? */
return 8;
+# elif defined(VGA_mips64)
+ return 8;
+
# else
# error "Unknown arch"
# endif
# if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
|| defined(VGP_arm_linux) \
|| defined(VGP_ppc32_linux) || defined(VGO_darwin) \
- || defined(VGP_s390x_linux) || defined(VGP_mips32_linux)
+ || defined(VGP_s390x_linux) || defined(VGP_mips32_linux) \
+ || defined(VGP_mips64_linux)
return f;
# elif defined(VGP_ppc64_linux)
/* ppc64-linux uses the AIX scheme, in which f is a pointer to a
iters = 5;
# elif defined(VGP_s390x_linux)
iters = 10;
-# elif defined(VGP_mips32_linux)
+# elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
iters = 10;
# elif defined(VGO_darwin)
iters = 3;
VG_(threads)[tid].arch.vex.guest_GPR2 = r2;
# endif
/* mips-linux note: we need to set t9 */
-# if defined(VGP_mips32_linux)
+# if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
VG_(threads)[tid].arch.vex.guest_r25 = __libc_freeres_wrapper;
# endif
"\tbreak 0x7\n"
".previous\n"
);
+#elif defined(VGP_mips64_linux)
+asm(
+".text\n"
+".globl __start\n"
+".type __start,@function\n"
+"__start:\n"
+ "\t.set noreorder\n"
+ "\t.cpload $25\n"
+ "\t.set reorder\n"
+ "\t.cprestore 16\n"
+ "\tlui $9, %hi(vgPlain_interim_stack)\n"
+ /* t1/$9 <- Addr(interim_stack) */
+ "\tdaddiu $9, %lo(vgPlain_interim_stack)\n"
+
+ "\tli $10, "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n"
+ "\tli $11, "VG_STRINGIFY(VG_STACK_ACTIVE_SZB)"\n"
+
+ "\tdaddu $9, $9, $10\n"
+ "\tdaddu $9, $9, $11\n"
+ "\tli $12, 0xFFFFFF00\n"
+ "\tand $9, $9, $12\n"
+ /* now t1/$9 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
+ VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
+ boundary. And $29 is the original SP. Set the SP to t1 and
+ call _start_in_C, passing it the initial SP. */
+
+ "\tmove $4, $29\n" // a0 <- $sp (_start_in_C first arg)
+ "\tmove $29, $9\n" // $sp <- t1 (new sp)
+
+ "\tlui $9, %highest(_start_in_C_linux)\n"
+ "\tori $9, %higher(_start_in_C_linux)\n"
+ "\tdsll32 $9, $9, 0x0\n"
+ "\tlui $10, %hi(_start_in_C_linux)\n"
+ "\tdaddiu $10, %lo(_start_in_C_linux)\n"
+ "\tdaddu $25, $9, $10\n"
+ "\tjalr $25\n"
+ "\tnop\n"
+".end __start\n"
+);
#else
# error "Unknown linux platform"
#endif
);
}
+# elif defined(VGP_mips64_linux)
+ if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
+
+ /* this is mandatory - can't sanely continue without it */
+ add_hardwired_spec(
+ "ld.so.3", "strlen",
+ (Addr)&VG_(mips64_linux_REDIR_FOR_strlen),
+ complain_about_stripped_glibc_ldso
+ );
+ }
+
# else
# error Unknown platform
# endif
/* no special requirements */
# endif
-# if defined(VGA_mips32)
+# if defined(VGA_mips32) || defined(VGA_mips64)
/* no special requirements */
# endif
}
#elif defined (VGA_s390x)
# define VG_CLREQ_ARGS guest_r2
# define VG_CLREQ_RET guest_r3
-#elif defined(VGA_mips32)
+#elif defined(VGA_mips32) || defined(VGA_mips64)
# define VG_CLREQ_ARGS guest_r12
# define VG_CLREQ_RET guest_r11
#else
}
static
-void setup_sigcontext2 ( ThreadState* tst, struct vki_sigcontext **sc1, const vki_siginfo_t *si)
+void setup_sigcontext2 ( ThreadState* tst, struct vki_sigcontext **sc1,
+ const vki_siginfo_t *si)
{
struct vki_sigcontext *sc = *sc1;
{
Addr sp;
ThreadState* tst = VG_(get_ThreadState)(tid);
- Addr faultaddr;
Int sigNo = siginfo->si_signo;
struct vg_sig_private *priv;
return;
vg_assert(VG_IS_8_ALIGNED(sp));
-
- /* SIGILL defines addr to be the faulting address */
-
- faultaddr = (Addr)siginfo->_sifields._sigfault._addr;
- if (sigNo == VKI_SIGILL && siginfo->si_code > 0)
- faultaddr = tst->arch.vex.guest_PC;
if (flags & VKI_SA_SIGINFO)
{
--- /dev/null
+
+/*--------------------------------------------------------------------*/
+/*--- Create/destroy signal delivery frames. ---*/
+/*--- sigframe-mips64-linux.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2010-2013 RT-RK
+ mips-valgrind@rt-rk.com
+
+ 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.
+*/
+
+#if defined(VGP_mips64_linux)
+
+#include "pub_core_basics.h"
+#include "pub_core_vki.h"
+#include "pub_core_vkiscnums.h"
+#include "pub_core_libcsetjmp.h" /* to keep _threadstate.h happy */
+#include "pub_core_threadstate.h"
+#include "pub_core_aspacemgr.h"
+#include "pub_core_libcbase.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_libcprint.h"
+#include "pub_core_machine.h"
+#include "pub_core_options.h"
+#include "pub_core_sigframe.h"
+#include "pub_core_signals.h"
+#include "pub_core_tooliface.h"
+#include "pub_core_trampoline.h"
+#include "pub_core_transtab.h" /* VG_(discard_translations) */
+
+struct vg_sig_private {
+ UInt magicPI;
+ UInt sigNo_private;
+ VexGuestMIPS64State vex_shadow1;
+ VexGuestMIPS64State vex_shadow2;
+};
+
+struct sigframe {
+ UInt sf_ass[4]; /* argument save space for o32 */
+ UInt sf_pad[2]; /* Was: signal trampoline */
+ struct vki_sigcontext sf_sc;
+ vki_sigset_t sf_mask;
+ struct vg_sig_private priv;
+};
+
+struct rt_sigframe {
+ UInt rs_ass[4]; /* argument save space for o32 */
+ UInt rs_pad[2]; /* Was: signal trampoline */
+ vki_siginfo_t rs_info;
+ struct vki_ucontext rs_uc;
+ struct vg_sig_private priv;
+};
+
+/* Extend the stack segment downwards if needed so as to ensure the new signal
+ frames are mapped to something. Return a Bool indicating whether or not the
+ operation was successful.
+*/
+static Bool extend ( ThreadState *tst, Addr addr, SizeT size )
+{
+ ThreadId tid = tst->tid;
+ NSegment const* stackseg = NULL;
+
+ if (VG_(extend_stack)(addr, tst->client_stack_szB)) {
+ stackseg = VG_(am_find_nsegment)(addr);
+ }
+
+ if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) {
+ VG_(message)(Vg_UserMsg,
+ "Can't extend stack to %#lx during signal delivery for thread %d:\n",
+ addr, tid);
+ if (stackseg == NULL)
+ VG_(message)(Vg_UserMsg, " no stack segment\n");
+ else
+ VG_(message)(Vg_UserMsg, " too small or bad protection modes\n");
+
+ /* set SIGSEGV to default handler */
+ VG_(set_default_handler)(VKI_SIGSEGV);
+ VG_(synth_fault_mapping)(tid, addr);
+
+ /* The whole process should be about to die, since the default
+ action of SIGSEGV to kill the whole process. */
+ return False;
+ }
+
+ /* For tracking memory events, indicate the entire frame has been
+ allocated. */
+ VG_TRACK(new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB,
+ size + VG_STACK_REDZONE_SZB, tid);
+
+ return True;
+}
+
+static void setup_sigcontext ( ThreadState* tst, struct vki_sigcontext **sc1,
+ const vki_siginfo_t *si)
+{
+ struct vki_sigcontext *sc = *sc1;
+
+ VG_TRACK(pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcontext",
+ (Addr)sc, sizeof(unsigned long long)*34);
+ sc->sc_regs[1] = tst->arch.vex.guest_r1;
+ sc->sc_regs[2] = tst->arch.vex.guest_r2;
+ sc->sc_regs[3] = tst->arch.vex.guest_r3;
+ sc->sc_regs[4] = tst->arch.vex.guest_r4;
+ sc->sc_regs[5] = tst->arch.vex.guest_r5;
+ sc->sc_regs[6] = tst->arch.vex.guest_r6;
+ sc->sc_regs[7] = tst->arch.vex.guest_r7;
+ sc->sc_regs[8] = tst->arch.vex.guest_r8;
+ sc->sc_regs[9] = tst->arch.vex.guest_r9;
+ sc->sc_regs[10] = tst->arch.vex.guest_r10;
+ sc->sc_regs[11] = tst->arch.vex.guest_r11;
+ sc->sc_regs[12] = tst->arch.vex.guest_r12;
+ sc->sc_regs[13] = tst->arch.vex.guest_r13;
+ sc->sc_regs[14] = tst->arch.vex.guest_r14;
+ sc->sc_regs[15] = tst->arch.vex.guest_r15;
+ sc->sc_regs[16] = tst->arch.vex.guest_r16;
+ sc->sc_regs[17] = tst->arch.vex.guest_r17;
+ sc->sc_regs[18] = tst->arch.vex.guest_r18;
+ sc->sc_regs[19] = tst->arch.vex.guest_r19;
+ sc->sc_regs[20] = tst->arch.vex.guest_r20;
+ sc->sc_regs[21] = tst->arch.vex.guest_r21;
+ sc->sc_regs[22] = tst->arch.vex.guest_r22;
+ sc->sc_regs[23] = tst->arch.vex.guest_r23;
+ sc->sc_regs[24] = tst->arch.vex.guest_r24;
+ sc->sc_regs[25] = tst->arch.vex.guest_r25;
+ sc->sc_regs[26] = tst->arch.vex.guest_r26;
+ sc->sc_regs[27] = tst->arch.vex.guest_r27;
+ sc->sc_regs[28] = tst->arch.vex.guest_r28;
+ sc->sc_regs[29] = tst->arch.vex.guest_r29;
+ sc->sc_regs[30] = tst->arch.vex.guest_r30;
+ sc->sc_regs[31] = tst->arch.vex.guest_r31;
+ sc->sc_pc = tst->arch.vex.guest_PC;
+ sc->sc_mdhi = tst->arch.vex.guest_HI;
+ sc->sc_mdlo = tst->arch.vex.guest_LO;
+}
+
+/* EXPORTED */
+void VG_(sigframe_create) ( ThreadId tid,
+ Addr sp_top_of_frame,
+ const vki_siginfo_t *siginfo,
+ const struct vki_ucontext *siguc,
+ void *handler,
+ UInt flags,
+ const vki_sigset_t *mask,
+ void *restorer )
+{
+ Addr sp;
+ ThreadState* tst = VG_(get_ThreadState)(tid);
+ Int sigNo = siginfo->si_signo;
+ struct vg_sig_private *priv;
+ /* Stack must be 16-byte aligned */
+ sp_top_of_frame &= ~0xf;
+
+ sp = sp_top_of_frame - sizeof(struct rt_sigframe);
+
+ tst = VG_(get_ThreadState)(tid);
+ if (!extend(tst, sp, sp_top_of_frame - sp))
+ return;
+
+ sp = VG_ROUNDDN(sp, 16);
+
+ struct rt_sigframe *frame = (struct rt_sigframe *)sp;
+ struct vki_ucontext *ucp = &frame->rs_uc;
+ if (VG_(clo_trace_signals))
+ VG_(printf)("rt_sigframe\n");
+ /* Create siginfo. */
+ VG_TRACK(pre_mem_write, Vg_CoreSignal, tid, "signal frame siginfo",
+ (Addr)&frame->rs_info, sizeof(frame->rs_info));
+
+ VG_(memcpy)(&frame->rs_info, siginfo, sizeof(*siginfo));
+
+ VG_TRACK(post_mem_write, Vg_CoreSignal, tid,
+ (Addr)&frame->rs_info, sizeof(frame->rs_info));
+
+ /* Create the ucontext. */
+ VG_TRACK(pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext",
+ (Addr)ucp, offsetof(struct vki_ucontext, uc_mcontext));
+
+ ucp->uc_flags = 0;
+ ucp->uc_link = 0;
+ ucp->uc_stack = tst->altstack;
+
+ VG_TRACK(post_mem_write, Vg_CoreSignal, tid, (Addr)ucp,
+ offsetof(struct vki_ucontext, uc_mcontext));
+
+ struct vki_sigcontext *scp = &(frame->rs_uc.uc_mcontext);
+ setup_sigcontext(tst, &(scp), siginfo);
+ ucp->uc_sigmask = tst->sig_mask;
+ priv = &frame->priv;
+
+ /* Arguments to signal handler:
+
+ a0 = signal number
+ a1 = 0 (should be cause)
+ a2 = pointer to ucontext
+
+ $25 and c0_epc point to the signal handler, $29 points to
+ the struct rt_sigframe. */
+
+ tst->arch.vex.guest_r4 = siginfo->si_signo;
+ tst->arch.vex.guest_r5 = (Addr) &frame->rs_info;
+ tst->arch.vex.guest_r6 = (Addr) &frame->rs_uc;
+ tst->arch.vex.guest_r29 = (Addr) frame;
+ tst->arch.vex.guest_r25 = (Addr) handler;
+
+ if (flags & VKI_SA_RESTORER)
+ tst->arch.vex.guest_r31 = (Addr) restorer;
+ else
+ tst->arch.vex.guest_r31 = (Addr)&VG_(mips64_linux_SUBST_FOR_rt_sigreturn);
+
+ priv->magicPI = 0x31415927;
+ priv->sigNo_private = sigNo;
+ priv->vex_shadow1 = tst->arch.vex_shadow1;
+ priv->vex_shadow2 = tst->arch.vex_shadow2;
+ /* Set the thread so it will next run the handler. */
+ VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr));
+ if (VG_(clo_trace_signals))
+ VG_(printf)("handler = %p\n", handler);
+ tst->arch.vex.guest_PC = (Addr) handler;
+ /* This thread needs to be marked runnable, but we leave that
+ the caller to do. */
+}
+
+/* EXPORTED */
+void VG_(sigframe_destroy) ( ThreadId tid, Bool isRT )
+{
+ ThreadState *tst;
+ struct vg_sig_private *priv1;
+ Addr sp;
+ UInt frame_size;
+ struct vki_sigcontext *mc;
+ Int sigNo;
+
+ vg_assert(VG_(is_valid_tid)(tid));
+ tst = VG_(get_ThreadState)(tid);
+ sp = tst->arch.vex.guest_r29;
+ struct rt_sigframe *frame = (struct rt_sigframe *)sp;
+ struct vki_ucontext *ucp = &frame->rs_uc;
+ frame_size = sizeof(*frame);
+ mc = &ucp->uc_mcontext;
+ tst->sig_mask = ucp->uc_sigmask;
+ tst->tmp_sig_mask = ucp->uc_sigmask;
+ priv1 = &frame->priv;
+ sigNo = priv1->sigNo_private;
+ vg_assert(priv1->magicPI == 0x31415927);
+ /* restore regs */
+ tst->arch.vex.guest_r1 = mc->sc_regs[1];
+ tst->arch.vex.guest_r2 = mc->sc_regs[2];
+ tst->arch.vex.guest_r3 = mc->sc_regs[3];
+ tst->arch.vex.guest_r4 = mc->sc_regs[4];
+ tst->arch.vex.guest_r5 = mc->sc_regs[5];
+ tst->arch.vex.guest_r6 = mc->sc_regs[6];
+ tst->arch.vex.guest_r7 = mc->sc_regs[7];
+ tst->arch.vex.guest_r8 = mc->sc_regs[8];
+ tst->arch.vex.guest_r9 = mc->sc_regs[9];
+ tst->arch.vex.guest_r10 = mc->sc_regs[10];
+ tst->arch.vex.guest_r11 = mc->sc_regs[11];
+ tst->arch.vex.guest_r12 = mc->sc_regs[12];
+ tst->arch.vex.guest_r13= mc->sc_regs[13];
+ tst->arch.vex.guest_r14 = mc->sc_regs[14];
+ tst->arch.vex.guest_r15 = mc->sc_regs[15];
+ tst->arch.vex.guest_r16 = mc->sc_regs[16];
+ tst->arch.vex.guest_r17 = mc->sc_regs[17];
+ tst->arch.vex.guest_r18 = mc->sc_regs[18];
+ tst->arch.vex.guest_r19 = mc->sc_regs[19];
+ tst->arch.vex.guest_r20 = mc->sc_regs[20];
+ tst->arch.vex.guest_r21 = mc->sc_regs[21];
+ tst->arch.vex.guest_r22 = mc->sc_regs[22];
+ tst->arch.vex.guest_r23 = mc->sc_regs[23];
+ tst->arch.vex.guest_r24 = mc->sc_regs[24];
+ tst->arch.vex.guest_r25 = mc->sc_regs[25];
+ tst->arch.vex.guest_r26 = mc->sc_regs[26];
+ tst->arch.vex.guest_r27 = mc->sc_regs[27];
+ tst->arch.vex.guest_r28 = mc->sc_regs[28];
+ tst->arch.vex.guest_r30 = mc->sc_regs[30];
+ tst->arch.vex.guest_PC = mc->sc_pc;
+ tst->arch.vex.guest_r31 = mc->sc_regs[31];
+ tst->arch.vex.guest_r29 = mc->sc_regs[29];
+
+ tst->arch.vex.guest_HI = mc->sc_mdhi;
+ tst->arch.vex.guest_LO = mc->sc_mdlo;
+ tst->arch.vex_shadow1 = priv1->vex_shadow1;
+ tst->arch.vex_shadow2 = priv1->vex_shadow2;
+
+ VG_TRACK(die_mem_stack_signal, sp, frame_size);
+ if (VG_(clo_trace_signals))
+ VG_(message)(Vg_DebugMsg,
+ "VG_(signal_return) (thread %d): isRT=%d valid magic; EIP=%#llx\n",
+ tid, isRT, tst->arch.vex.guest_PC);
+ /* tell the tools */
+ VG_TRACK( post_deliver_signal, tid, sigNo );
+}
+
+#endif /* defined(VGP_mips64_linux) */
+
+/*--------------------------------------------------------------------*/
+/*--- end sigframe-mips64-linux.c ---*/
+/*--------------------------------------------------------------------*/
(srP)->misc.MIPS32.r28 = (uc)->uc_mcontext.sc_regs[28]; \
}
+#elif defined(VGP_mips64_linux)
+# define VG_UCONTEXT_INSTR_PTR(uc) (((uc)->uc_mcontext.sc_pc))
+# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.sc_regs[29])
+# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.sc_regs[30])
+# define VG_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.sc_regs[2])
+# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
+ /* Convert the value in uc_mcontext.rax into a SysRes. */ \
+ VG_(mk_SysRes_mips64_linux)((uc)->uc_mcontext.sc_regs[2], \
+ (uc)->uc_mcontext.sc_regs[3], \
+ (uc)->uc_mcontext.sc_regs[7])
+
+# define VG_UCONTEXT_TO_UnwindStartRegs(srP, uc) \
+ { (srP)->r_pc = (uc)->uc_mcontext.sc_pc; \
+ (srP)->r_sp = (uc)->uc_mcontext.sc_regs[29]; \
+ (srP)->misc.MIPS64.r30 = (uc)->uc_mcontext.sc_regs[30]; \
+ (srP)->misc.MIPS64.r31 = (uc)->uc_mcontext.sc_regs[31]; \
+ (srP)->misc.MIPS64.r28 = (uc)->uc_mcontext.sc_regs[28]; \
+ }
#else
# error Unknown platform
" syscall\n" \
".previous\n"
+#elif defined(VGP_mips64_linux)
+# define _MY_SIGRETURN(name) \
+ ".text\n" \
+ "my_sigreturn:\n" \
+ " li $2, " #name "\n" \
+ " syscall\n" \
+ ".previous\n"
+
#else
# error Unknown platform
#endif
== skss_old.skss_per_sig[sig].skss_flags);
# if !defined(VGP_ppc32_linux) && \
!defined(VGP_x86_darwin) && !defined(VGP_amd64_darwin) && \
- !defined(VGP_mips32_linux)
+ !defined(VGP_mips32_linux) && !defined(VGP_mips64_linux)
vg_assert(ksa_old.sa_restorer
== my_sigreturn);
# endif
// Synthesise a SIGFPE.
void VG_(synth_sigfpe)(ThreadId tid, UInt code)
{
-// Only tested on mips32
-#if !defined(VGA_mips32)
+// Only tested on mips32 and mips64
+#if !defined(VGA_mips32) && !defined(VGA_mips64)
vg_assert(0);
#else
vki_siginfo_t info;
#endif
-/* ------------------------ mips 32------------------------- */
-
-#if defined(VGP_mips32_linux)
-
+/* ------------------------ mips 32/64 ------------------------- */
+#if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
/*OUT*/Addr* ips, UInt max_n_ips,
/*OUT*/Addr* sps, /*OUT*/Addr* fps,
uregs.sp = startRegs->r_sp;
Addr fp_min = uregs.sp;
+#if defined(VGP_mips32_linux)
uregs.fp = startRegs->misc.MIPS32.r30;
uregs.ra = startRegs->misc.MIPS32.r31;
+#elif defined(VGP_mips64_linux)
+ uregs.fp = startRegs->misc.MIPS64.r30;
+ uregs.ra = startRegs->misc.MIPS64.r31;
+#endif
/* Snaffle IPs from the client's stack into ips[0 .. max_n_ips-1],
stopping when the trail goes cold, which we guess to be
for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4) {
unsigned long inst, high_word, low_word;
unsigned long * cur_inst;
- int reg;
/* Fetch the instruction. */
cur_inst = (unsigned long *)cur_pc;
inst = *((UInt *) cur_inst);
/* Save some code by pre-extracting some useful fields. */
high_word = (inst >> 16) & 0xffff;
low_word = inst & 0xffff;
- reg = high_word & 0x1f;
if (high_word == 0x27bd /* addiu $sp,$sp,-i */
|| high_word == 0x23bd /* addi $sp,$sp,-i */
return res;
}
+/* MIPS uses a3 != 0 to flag an error */
+SysRes VG_(mk_SysRes_mips64_linux) ( ULong v0, ULong v1, ULong a3 ) {
+ SysRes res;
+ res._isError = (a3 != (ULong)0);
+ res._val = v0;
+ res._valEx = v1;
+ return res;
+}
+
/* Generic constructors. */
SysRes VG_(mk_SysRes_Error) ( UWord err ) {
SysRes r;
".end do_syscall_WRK\n"
);
+#elif defined(VGP_mips64_linux)
+extern UWord do_syscall_WRK ( UWord a1, UWord a2, UWord a3, UWord a4, UWord a5,
+ UWord a6, UWord syscall_no, ULong* V1_val );
+asm (
+".text\n"
+".globl do_syscall_WRK\n"
+"do_syscall_WRK:\n"
+" daddiu $29, $29, -8\n"
+" sd $11, 0($29)\n"
+" move $2, $10\n"
+" syscall\n"
+" ld $11, 0($29)\n"
+" daddiu $29, $29, 8\n"
+" sd $3, 0($11)\n" /* store vale of v1 in last param */
+" sd $7, 8($11)\n" /* store vale of a3 in last param */
+" jr $31\n"
+".previous\n"
+);
+
#else
# error Unknown platform
#endif
UWord valLo = 0;
(void) do_syscall_WRK(a1,a2,a3,a4,a5,a6, sysno,&err,&valHi,&valLo);
return VG_(mk_SysRes_mips32_linux)( valLo, valHi, (ULong)err );
+
+#elif defined(VGP_mips64_linux)
+ ULong v1_a3[2];
+ v1_a3[0] = 0xFF00;
+ v1_a3[1] = 0xFF00;
+ ULong V0 = do_syscall_WRK(a1,a2,a3,a4,a5,a6,sysno,v1_a3);
+ ULong V1 = (ULong)v1_a3[0];
+ ULong A3 = (ULong)v1_a3[1];
+ return VG_(mk_SysRes_mips64_linux)( V0, V1, A3 );
+
#else
# error Unknown platform
#endif
Int o_sysno;
# if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \
|| defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
- || defined(VGP_arm_linux) || defined(VGP_s390x_linux)
+ || defined(VGP_arm_linux) || defined(VGP_s390x_linux) \
+ || defined(VGP_mips64_linux)
Int o_arg1;
Int o_arg2;
Int o_arg3;
--- /dev/null
+
+/*--------------------------------------------------------------------*/
+/*--- Support for doing system calls. syscall-mips64-linux.S ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2010-2013 RT-RK
+ mips-valgrind@rt-rk.com
+
+ 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.
+*/
+
+#if defined(VGP_mips64_linux)
+
+#include "pub_core_basics_asm.h"
+#include "pub_core_vkiscnums_asm.h"
+#include "libvex_guest_offsets.h"
+
+/*----------------------------------------------------------------*/
+/*
+ Perform a syscall for the client. This will run a syscall
+ with the client's specific per-thread signal mask.
+
+ The structure of this function is such that, if the syscall is
+ interrupted by a signal, we can determine exactly what
+ execution state we were in with respect to the execution of
+ the syscall by examining the value of PC in the signal
+ handler. This means that we can always do the appropriate
+ thing to precisely emulate the kernel's signal/syscall
+ interactions.
+
+ The syscall number is taken from the argument, even though it
+ should also be in regs->v0. The syscall result is written
+ back to regs->v0 on completion.
+
+ VG_(fixup_guest_state_after_syscall_interrupted) does the
+ thread state fixup in the case where we were interrupted by a
+ signal.
+
+ Prototype:
+
+ UWord ML_(do_syscall_for_client_WRK)(
+ Int syscallno, // $4 - a0
+ void* guest_state, // $5 - a1
+ const vki_sigset_t *sysmask, // $6 - a2
+ const vki_sigset_t *postmask, // $7 - a3
+ Int nsigwords) // $8 - a4
+*/
+
+/* from vki_arch.h */
+#define VKI_SIG_SETMASK 3
+
+.globl ML_(do_syscall_for_client_WRK)
+ML_(do_syscall_for_client_WRK):
+
+ /* save regs $a0 - $a4 on stack */
+ daddiu $29, $29, -48
+ sd $4, 0($29) /* syscallno */
+ sd $5, 8($29) /* guest_state */
+ sd $6, 16($29) /* sysmask */
+ sd $7, 24($29) /* postmask */
+ sd $8, 32($29) /* nsigwords */
+
+1: li $2, __NR_rt_sigprocmask
+ li $4, VKI_SIG_SETMASK
+ move $5, $6 /* sysmask */
+ move $6, $7 /* postmask */
+ move $7, $8 /* nsigwords */
+ syscall
+
+ bnez $7, 7f
+ nop
+
+ /* Actually do the client syscall */
+ ld $5, 8($29) /* guest_state */
+ ld $4, OFFSET_mips64_r4($5) /* a0 */
+
+ ld $6, OFFSET_mips64_r6($5) /* a2 */
+ ld $7, OFFSET_mips64_r7($5) /* a3 */
+ ld $8, OFFSET_mips64_r8($5) /* a4 */
+ ld $9, OFFSET_mips64_r9($5) /* a5 */
+
+ ld $5, OFFSET_mips64_r5($5) /* a1 */
+ ld $2, 0($29) /* syscallno */
+2: nop
+
+ syscall
+
+ /* Saving return values into Guest state */
+3: ld $5, 8($29) /* guest_state */
+ sd $2, OFFSET_mips64_r2($5) /* v0 */
+ sd $7, OFFSET_mips64_r7($5) /* a3 */
+
+4: li $2, __NR_rt_sigprocmask
+ li $4, VKI_SIG_SETMASK
+ ld $5, 24($29) /* postmask */
+ move $6, $0 /* 0 (zero) */
+ ld $7, 32($29) /* nsigwords */
+ syscall
+
+ bnez $7, 7f
+ nop
+
+5: /* restore 29 and return */
+ daddiu $29, $29, 48
+ jr $31
+ nop
+
+7: /* error */
+ daddiu $29, $29, 48
+ li $2, 0x8000
+ jr $31
+ nop
+
+.section .rodata
+/* export the ranges so that
+ VG_(fixup_guest_state_after_syscall_interrupted) can do the
+ right thing */
+
+.globl ML_(blksys_setup)
+.globl ML_(blksys_restart)
+.globl ML_(blksys_complete)
+.globl ML_(blksys_committed)
+.globl ML_(blksys_finished)
+ML_(blksys_setup): .quad 1b
+ML_(blksys_restart): .quad 2b
+ML_(blksys_complete): .quad 3b
+ML_(blksys_committed): .quad 4b
+ML_(blksys_finished): .quad 5b
+.previous
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",%progbits
+
+#endif // defined(VGP_mips64_linux)
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
: "d" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
: "2"
);
-#elif defined(VGP_mips32_linux)
+#elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
asm volatile (
"sw %1, %0\n\t" /* set tst->status = VgTs_Empty */
"li $2, %2\n\t" /* set v0 = __NR_exit */
VG_(clone) stuff */
#if defined(VGP_x86_linux) \
|| defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
- || defined(VGP_arm_linux) || defined(VGP_mips32_linux)
+ || defined(VGP_arm_linux) || defined(VGP_mips32_linux) \
+ || defined(VGP_mips64_linux)
res = VG_(do_syscall5)( __NR_clone, flags,
(UWord)NULL, (UWord)parent_tidptr,
(UWord)NULL, (UWord)child_tidptr );
ppc32 r0 r3 r4 r5 r6 r7 r8 n/a n/a r3+CR0.SO (== ARG1)
ppc64 r0 r3 r4 r5 r6 r7 r8 n/a n/a r3+CR0.SO (== ARG1)
arm r7 r0 r1 r2 r3 r4 r5 n/a n/a r0 (== ARG1)
- mips v0 a0 a1 a2 a3 stack stack n/a n/a v0 (== NUM)
+ mips32 v0 a0 a1 a2 a3 stack stack n/a n/a v0 (== NUM)
+ mips64 v0 a0 a1 a2 a3 a4 a5 a6 a7 v0 (== NUM)
On s390x the svc instruction is used for system calls. The system call
number is encoded in the instruction (8 bit immediate field). Since Linux
canonical->arg8 = __NR_syscall;
}
+#elif defined(VGP_mips64_linux)
+ VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla;
+ canonical->sysno = gst->guest_r2; // v0
+ canonical->arg1 = gst->guest_r4; // a0
+ canonical->arg2 = gst->guest_r5; // a1
+ canonical->arg3 = gst->guest_r6; // a2
+ canonical->arg4 = gst->guest_r7; // a3
+ canonical->arg5 = gst->guest_r8; // a4
+ canonical->arg6 = gst->guest_r9; // a5
+
#elif defined(VGP_x86_darwin)
VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
UWord *stack = (UWord *)gst->guest_ESP;
*((UInt*) (gst->guest_r29 + 20)) = canonical->arg5; // 20(sp)
*((UInt*) (gst->guest_r29 + 24)) = canonical->arg6; // 24(sp)
}
+
+#elif defined(VGP_mips64_linux)
+ VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla;
+ gst->guest_r2 = canonical->sysno;
+ gst->guest_r4 = canonical->arg1;
+ gst->guest_r5 = canonical->arg2;
+ gst->guest_r6 = canonical->arg3;
+ gst->guest_r7 = canonical->arg4;
+ gst->guest_r8 = canonical->arg5;
+ gst->guest_r9 = canonical->arg6;
#else
# error "putSyscallArgsIntoGuestState: unknown arch"
#endif
canonical->sres = VG_(mk_SysRes_mips32_linux)( v0, v1, a3 );
canonical->what = SsComplete;
+# elif defined(VGP_mips64_linux)
+ VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla;
+ ULong v0 = gst->guest_r2; // v0
+ ULong v1 = gst->guest_r3; // v1
+ ULong a3 = gst->guest_r7; // a3
+ canonical->sres = VG_(mk_SysRes_mips64_linux)(v0, v1, a3);
+ canonical->what = SsComplete;
+
# elif defined(VGP_x86_darwin)
/* duplicates logic in m_signals.VG_UCONTEXT_SYSCALL_SYSRES */
VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
OFFSET_mips32_r7, sizeof(UWord) );
+# elif defined(VGP_mips64_linux)
+ VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla;
+ vg_assert(canonical->what == SsComplete);
+ if (sr_isError(canonical->sres)) {
+ gst->guest_r2 = (Int)sr_Err(canonical->sres);
+ gst->guest_r7 = (Int)sr_Err(canonical->sres);
+ } else {
+ gst->guest_r2 = sr_Res(canonical->sres);
+ gst->guest_r3 = sr_ResEx(canonical->sres);
+ gst->guest_r7 = (Int)sr_Err(canonical->sres);
+ }
+ VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
+ OFFSET_mips64_r2, sizeof(UWord) );
+ VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
+ OFFSET_mips64_r3, sizeof(UWord) );
+ VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
+ OFFSET_mips64_r7, sizeof(UWord) );
+
# else
# error "putSyscallStatusIntoGuestState: unknown arch"
# endif
layout->uu_arg7 = -1; /* impossible value */
layout->uu_arg8 = -1; /* impossible value */
+#elif defined(VGP_mips64_linux)
+ layout->o_sysno = OFFSET_mips64_r2;
+ layout->o_arg1 = OFFSET_mips64_r4;
+ layout->o_arg2 = OFFSET_mips64_r5;
+ layout->o_arg3 = OFFSET_mips64_r6;
+ layout->o_arg4 = OFFSET_mips64_r7;
+ layout->o_arg5 = OFFSET_mips64_r8;
+ layout->o_arg6 = OFFSET_mips64_r9;
+ layout->uu_arg7 = -1; /* impossible value */
+ layout->uu_arg8 = -1; /* impossible value */
+
#elif defined(VGP_x86_darwin)
layout->o_sysno = OFFSET_x86_EAX;
// syscall parameters are on stack in C convention
vg_assert(p[0] == 0x0A);
}
-#elif defined(VGP_mips32_linux)
+#elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
arch->vex.guest_PC -= 4; // sizeof(mips instr)
# if defined (VG_LITTLEENDIAN)
if (p[0] != 0x0c || p[1] != 0x00 || p[2] != 0x00 || p[3] != 0x00)
VG_(message)(Vg_DebugMsg,
- "?! restarting over syscall at %#x %02x %02x %02x %02x\n",
+ "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
arch->vex.guest_PC, p[0], p[1], p[2], p[3]);
vg_assert(p[0] == 0x0c && p[1] == 0x00 && p[2] == 0x00 && p[3] == 0x00);
# elif defined (VG_BIGENDIAN)
if (p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x00 || p[3] != 0x0c)
VG_(message)(Vg_DebugMsg,
- "?! restarting over syscall at %#x %02x %02x %02x %02x\n",
+ "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
arch->vex.guest_PC, p[0], p[1], p[2], p[3]);
vg_assert(p[0] == 0x00 && p[1] == 0x00 && p[2] == 0x00 && p[3] == 0x0c);
PRE (sys_sigreturn)
{
- ThreadState * tst;
PRINT ("sys_sigreturn ( )");
vg_assert (VG_ (is_valid_tid) (tid));
vg_assert (tid >= 1 && tid < VG_N_THREADS);
vg_assert (VG_ (is_running_thread) (tid));
- tst = VG_ (get_ThreadState) (tid);
VG_ (sigframe_destroy) (tid, False);
/* Tell the driver not to update the guest state with the "result",
and set a bogus result to keep it happy. */
--- /dev/null
+
+/*--------------------------------------------------------------------*/
+/*--- Platform-specific syscalls stuff. syswrap-mips64-linux.c ----*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2010-2013 RT-RK
+ mips-valgrind@rt-rk.com
+
+ 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.
+*/
+
+#if defined(VGP_mips64_linux)
+#include "pub_core_basics.h"
+#include "pub_core_vki.h"
+#include "pub_core_vkiscnums.h"
+#include "pub_core_libcsetjmp.h" /* to keep _threadstate.h happy */
+#include "pub_core_threadstate.h"
+#include "pub_core_aspacemgr.h"
+#include "pub_core_debuglog.h"
+#include "pub_core_libcbase.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_libcprint.h"
+#include "pub_core_libcproc.h"
+#include "pub_core_libcsignal.h"
+#include "pub_core_options.h"
+#include "pub_core_scheduler.h"
+#include "pub_core_sigframe.h" /* For VG_(sigframe_destroy)() */
+#include "pub_core_signals.h"
+#include "pub_core_syscall.h"
+#include "pub_core_syswrap.h"
+#include "pub_core_tooliface.h"
+#include "pub_core_stacks.h" /* VG_(register_stack) */
+#include "pub_core_transtab.h" /* VG_(discard_translations) */
+#include "priv_types_n_macros.h"
+#include "priv_syswrap-generic.h" /* for decls of generic wrappers */
+#include "priv_syswrap-linux.h" /* for decls of linux-ish wrappers */
+#include "priv_syswrap-main.h"
+
+#include "pub_core_debuginfo.h" /* VG_(di_notify_*) */
+#include "pub_core_xarray.h"
+#include "pub_core_clientstate.h" /* VG_(brk_base), VG_(brk_limit) */
+#include "pub_core_errormgr.h"
+#include "pub_tool_gdbserver.h" /* VG_(gdbserver) */
+#include "pub_core_libcfile.h"
+#include "pub_core_machine.h" /* VG_(get_SP) */
+#include "pub_core_mallocfree.h"
+#include "pub_core_stacktrace.h" /* For VG_(get_and_pp_StackTrace)() */
+#include "pub_core_ume.h"
+
+#include "config.h"
+
+#include <errno.h>
+
+/* ---------------------------------------------------------------------
+ clone() handling
+ ------------------------------------------------------------------ */
+
+/* Call f(arg1), but first switch stacks, using 'stack' as the new stack, and
+ use 'retaddr' as f's return-to address. Also, clear all the integer registers
+ before entering f. */
+__attribute__ ((noreturn))
+void ML_(call_on_new_stack_0_1) ( Addr stack, /* $4 - $a0 */
+ Addr retaddr, /* $5 - $a1 */
+ void (*f_desc) (Word), /* $6 - $a2 */
+ Word arg1 ); /* $7 - $a3 */
+asm (
+".text\n"
+".globl vgModuleLocal_call_on_new_stack_0_1\n"
+"vgModuleLocal_call_on_new_stack_0_1:\n"
+" move $29, $4\n" /* set stack */
+" move $4, $7\n" /* arg1 to $4 */
+" move $25, $6\n"
+" move $31, $5\n" /* retaddr to $ra */
+" jr $25\n" /* jump to f */
+" break 0x7\n" /* should never get here */
+".previous\n"
+);
+
+/* Perform a clone system call. clone is strange because it has fork()-like
+ return-twice semantics, so it needs special handling here.
+
+ Upon entry, we have:
+
+ word (fn)(void*) in a0 = 4
+ void* child_stack in a1 = 5
+ word flags in a2 = 6
+ void* arg in a3 = 7
+ pid_t* parent_tid in a4 = 8
+ void* tls in a5 = 9
+ pid_t* child_tid in a6 = 10
+
+ System call requires:
+
+ int $__NR_clone in v0
+ int flags in a0 = 4
+ void* child_stack in a1 = 5
+ pid_t* parent_tid in a2 = 6
+ void* tls_ptr in a3 = 7
+ pid_t* child_tid in a4 = 8 */
+
+#define __NR_CLONE __NR_clone
+#define __NR_EXIT __NR_exit
+
+ULong do_syscall_clone_mips64_linux ( Word (*fn) (void *), /* a0 - 4 */
+ void* stack, /* a1 - 5 */
+ Int flags, /* a2 - 6 */
+ void* arg, /* a3 - 7 */
+ Int* parent_tid, /* a4 - 8 */
+ void* /* Int tls */, /* a5 - 9 */
+ Int* child_tid ); /* a6 - 10 */
+
+asm(
+".text\n"
+".set noreorder\n"
+".set nomacro\n"
+".globl do_syscall_clone_mips64_linux\n"
+"do_syscall_clone_mips64_linux:\n"
+" daddiu $29, $29, -32\n"
+" sd $31, 0($29)\n"
+" sd $30, 8($29)\n"
+" sd $28, 16($29)\n"
+
+" daddiu $5, $5, -32\n"
+" sd $4, 0($5)\n" /* fn */
+" sd $7, 8($5)\n" /* arg */
+" sd $6, 16($5)\n" /* flags */
+
+/* 1. arg for syscalls */
+" move $4, $6\n" /* flags */
+" move $6, $8\n" /* parent */
+" move $7, $a5\n" /* tls */
+" move $8, $a6\n" /* child */
+
+/* 2. do a syscall to clone */
+" li $2, 5055\n" /* syscall num for clone */
+" syscall\n"
+
+/* 3. See if we are a child, call fn and after that exit */
+" bnez $7, p_or_error\n"
+" nop\n"
+
+" bnez $2, p_or_error\n"
+" nop\n"
+
+" ld $25,0($29)\n"
+" jalr $25\n"
+" ld $4,8($29)\n"
+
+" move $4, $2\n\t" /* retval from fn is in $v0 */
+" li $2, 5058\n\t" /* NR_exit */
+" syscall\n\t"
+" nop\n\t"
+/* 4. If we are parent or error, just return to caller */
+" p_or_error:\n"
+" ld $31, 0($29)\n"
+" ld $30, 8($29)\n"
+" ld $28, 16($29)\n"
+" jr $31\n"
+" daddi $29,$29, 32\n"
+".previous\n"
+);
+
+#undef __NR_CLONE
+#undef __NR_EXIT
+
+/* forward declarations */
+static void setup_child ( ThreadArchState *, ThreadArchState *);
+static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr);
+
+/* When a client clones, we need to keep track of the new thread. This means:
+ 1. allocate a ThreadId+ThreadState+stack for the the thread
+
+ 2. initialize the thread's new VCPU state
+
+ 3. create the thread using the same args as the client requested, but using
+ the scheduler entrypoint for IP, and a separate stack for SP. */
+static SysRes do_clone ( ThreadId ptid,
+ UInt flags, Addr sp,
+ Int* parent_tidptr,
+ Int* child_tidptr,
+ Addr child_tls )
+{
+ const Bool debug = False;
+ ThreadId ctid = VG_ (alloc_ThreadState) ();
+ ThreadState * ptst = VG_ (get_ThreadState) (ptid);
+ ThreadState * ctst = VG_ (get_ThreadState) (ctid);
+ UInt ret = 0;
+ UWord * stack;
+ NSegment const *seg;
+ SysRes res;
+ vki_sigset_t blockall, savedmask;
+
+ VG_(sigfillset)(&blockall);
+ vg_assert(VG_(is_running_thread)(ptid));
+ vg_assert(VG_(is_valid_tid)(ctid));
+ stack = (UWord *)ML_(allocstack)(ctid);
+ if (stack == NULL) {
+ res = VG_(mk_SysRes_Error)(VKI_ENOMEM);
+ goto out;
+ }
+ setup_child(&ctst->arch, &ptst->arch);
+
+ /* on MIPS we need to set V0 and A3 to zero */
+ ctst->arch.vex.guest_r2 = 0;
+ ctst->arch.vex.guest_r7 = 0;
+ if (sp != 0)
+ ctst->arch.vex.guest_r29 = sp;
+
+ ctst->os_state.parent = ptid;
+ ctst->sig_mask = ptst->sig_mask;
+ ctst->tmp_sig_mask = ptst->sig_mask;
+
+ ctst->os_state.threadgroup = ptst->os_state.threadgroup;
+ seg = VG_(am_find_nsegment)((Addr)sp);
+
+ if (seg && seg->kind != SkResvn) {
+ ctst->client_stack_highest_word = sp;
+ ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start;
+ VG_(register_stack)(seg->start, ctst->client_stack_highest_word);
+ if (debug)
+ VG_(printf)("tid %d: guessed client stack range %#lx-%#lx\n",
+ ctid, seg->start, sp /* VG_PGROUNDUP (sp) */ );
+ } else {
+ VG_(message)(Vg_UserMsg,
+ "!? New thread %d starts with sp+%#lx) unmapped\n",
+ ctid, sp);
+ ctst->client_stack_szB = 0;
+ }
+
+ VG_TRACK(pre_thread_ll_create, ptid, ctid);
+ if (flags & VKI_CLONE_SETTLS) {
+ if (debug)
+ VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls);
+ res = sys_set_tls(ctid, child_tls);
+ if (sr_isError(res))
+ goto out;
+ ctst->arch.vex.guest_r27 = child_tls;
+ }
+
+ flags &= ~VKI_CLONE_SETTLS;
+ VG_ (sigprocmask) (VKI_SIG_SETMASK, &blockall, &savedmask);
+ /* Create the new thread */
+ ret = do_syscall_clone_mips64_linux(ML_(start_thread_NORETURN),
+ stack, flags, &VG_(threads)[ctid],
+ parent_tidptr, NULL /*child_tls*/,
+ child_tidptr);
+ if (debug)
+ VG_(printf)("ret: 0x%x\n", ret);
+
+ res = VG_(mk_SysRes_mips64_linux)( /* val */ ret, 0, /* errflag */ 0);
+
+ VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
+
+ out:
+ if (sr_isError (res)) {
+ VG_ (cleanup_thread) (&ctst->arch);
+ ctst->status = VgTs_Empty;
+ VG_TRACK (pre_thread_ll_exit, ctid);
+ }
+ ptst->arch.vex.guest_r2 = 0;
+
+ return res;
+}
+
+/* ---------------------------------------------------------------------
+ More thread stuff
+ ------------------------------------------------------------------ */
+void VG_(cleanup_thread) ( ThreadArchState * arch ) { };
+
+void setup_child ( /* OUT */ ThreadArchState * child,
+ /* IN */ ThreadArchState * parent )
+{
+ /* We inherit our parent's guest state. */
+ child->vex = parent->vex;
+ child->vex_shadow1 = parent->vex_shadow1;
+ child->vex_shadow2 = parent->vex_shadow2;
+}
+
+SysRes sys_set_tls ( ThreadId tid, Addr tlsptr )
+{
+ VG_(threads)[tid].arch.vex.guest_ULR = tlsptr;
+ return VG_(mk_SysRes_Success)( 0 );
+}
+
+/* ---------------------------------------------------------------------
+ PRE/POST wrappers for mips/Linux-specific syscalls
+ ------------------------------------------------------------------ */
+
+#define PRE(name) DEFN_PRE_TEMPLATE(mips_linux, name)
+#define POST(name) DEFN_POST_TEMPLATE(mips_linux, name)
+
+/* Add prototypes for the wrappers declared here, so that gcc doesn't harass us
+ for not having prototypes. Really this is a kludge -- the right thing to do
+ is to make these wrappers 'static' since they aren't visible outside this
+ file, but that requires even more macro magic. */
+
+DECL_TEMPLATE (mips_linux, sys_set_thread_area);
+DECL_TEMPLATE (mips_linux, sys_clone);
+DECL_TEMPLATE (mips_linux, sys_socket);
+DECL_TEMPLATE (mips_linux, sys_setsockopt);
+DECL_TEMPLATE (mips_linux, sys_getsockopt);
+DECL_TEMPLATE (mips_linux, sys_connect);
+DECL_TEMPLATE (mips_linux, sys_accept);
+DECL_TEMPLATE (mips_linux, sys_tee);
+DECL_TEMPLATE (mips_linux, sys_splice);
+DECL_TEMPLATE (mips_linux, sys_vmsplice);
+DECL_TEMPLATE (mips_linux, sys_ustat);
+DECL_TEMPLATE (mips_linux, sys_sysfs);
+DECL_TEMPLATE (mips_linux, sys_swapon);
+DECL_TEMPLATE (mips_linux, sys_swapoff);
+DECL_TEMPLATE (mips_linux, sys_setdomainname);
+DECL_TEMPLATE (mips_linux, sys_sethostname);
+DECL_TEMPLATE (mips_linux, sys_accept4);
+DECL_TEMPLATE (mips_linux, sys_sendto);
+DECL_TEMPLATE (mips_linux, sys_recvfrom);
+DECL_TEMPLATE (mips_linux, sys_sendmsg);
+DECL_TEMPLATE (mips_linux, sys_recvmsg);
+DECL_TEMPLATE (mips_linux, sys_shutdown);
+DECL_TEMPLATE (mips_linux, sys_bind);
+DECL_TEMPLATE (mips_linux, sys_reboot);
+DECL_TEMPLATE (mips_linux, sys_listen);
+DECL_TEMPLATE (mips_linux, sys_getsockname);
+DECL_TEMPLATE (mips_linux, sys_getpeername);
+DECL_TEMPLATE (mips_linux, sys_socketpair);
+DECL_TEMPLATE (mips_linux, sys_semget);
+DECL_TEMPLATE (mips_linux, sys_semop);
+DECL_TEMPLATE (mips_linux, sys_semtimedop);
+DECL_TEMPLATE (mips_linux, sys_cacheflush);
+DECL_TEMPLATE (mips_linux, sys_semctl);
+DECL_TEMPLATE (mips_linux, sys_sched_rr_get_interval);
+DECL_TEMPLATE (mips_linux, sys_msgget);
+DECL_TEMPLATE (mips_linux, sys_msgrcv);
+DECL_TEMPLATE (mips_linux, sys_unshare);
+DECL_TEMPLATE (mips_linux, sys_msgsnd);
+DECL_TEMPLATE (mips_linux, sys_msgctl);
+DECL_TEMPLATE (mips_linux, sys_shmget);
+DECL_TEMPLATE (mips_linux, wrap_sys_shmat);
+DECL_TEMPLATE (mips_linux, sys_shmdt);
+DECL_TEMPLATE (mips_linux, sys_shmdt);
+DECL_TEMPLATE (mips_linux, sys_shmctl);
+DECL_TEMPLATE (mips_linux, sys_arch_prctl);
+DECL_TEMPLATE (mips_linux, sys_ptrace);
+DECL_TEMPLATE (mips_linux, sys_mmap);
+DECL_TEMPLATE (mips_linux, sys_rt_sigreturn);
+DECL_TEMPLATE (mips_linux, sys_pipe);
+
+PRE(sys_socketpair)
+{
+ PRINT("sys_socketpair ( %ld, %ld, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4);
+ PRE_REG_READ4(long, "socketpair", int, d, int, type, int, protocol,
+ int *, sv);
+ ML_(generic_PRE_sys_socketpair)(tid, ARG1, ARG2, ARG3, ARG4);
+}
+
+POST(sys_socketpair)
+{
+ vg_assert(SUCCESS);
+ ML_(generic_POST_sys_socketpair)(tid, VG_(mk_SysRes_Success)(RES),
+ ARG1, ARG2, ARG3, ARG4);
+}
+
+PRE(wrap_sys_shmat)
+{
+ UWord arg2tmp;
+ PRINT("wrap_sys_shmat ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "shmat", int, shmid, const void *, shmaddr, int, shmflg);
+ arg2tmp = ML_(generic_PRE_sys_shmat)(tid, ARG1, ARG2, ARG3);
+ if (arg2tmp == 0)
+ SET_STATUS_Failure(VKI_EINVAL);
+ else
+ ARG2 = arg2tmp;
+}
+
+POST(wrap_sys_shmat)
+{
+ ML_(generic_POST_sys_shmat)(tid, RES, ARG1, ARG2, ARG3);
+}
+
+PRE(sys_shmdt)
+{
+ PRINT("sys_shmdt ( %#lx )", ARG1);
+ PRE_REG_READ1(long, "shmdt", const void *, shmaddr);
+ if (!ML_(generic_PRE_sys_shmdt)(tid, ARG1))
+ SET_STATUS_Failure(VKI_EINVAL);
+}
+
+POST(sys_shmdt)
+{
+ ML_(generic_POST_sys_shmdt)(tid, RES, ARG1);
+}
+
+PRE(sys_shmctl)
+{
+ PRINT("sys_shmctl ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "shmctl", int, shmid, int, cmd, struct shmid_ds *, buf);
+ ML_(generic_PRE_sys_shmctl)(tid, ARG1, ARG2, ARG3);
+}
+
+POST(sys_shmctl)
+{
+ ML_(generic_POST_sys_shmctl)(tid, RES, ARG1, ARG2, ARG3);
+}
+
+PRE(sys_shmget)
+{
+ PRINT("sys_shmget ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "shmget", vki_key_t, key, vki_size_t, size, int, shmflg);
+}
+
+PRE(sys_tee)
+{
+ PRINT("sys_tee ( %ld, %ld, %ld, %ld )", ARG1, ARG2, ARG3, ARG4);
+ PRE_REG_READ4(long, "sys_tee", int, fdin, int, fdout, vki_size_t, len,
+ int, flags);
+}
+
+PRE(sys_splice)
+{
+ PRINT("sys_splice ( %ld, %ld, %ld, %ld, %ld, %ld )", ARG1, ARG2, ARG3,
+ ARG4, ARG5, ARG6);
+
+ PRE_REG_READ6(long, "sys_splice", int, fdin, vki_loff_t, sizein, int,
+ fdout, vki_loff_t, sizeout, vki_size_t, len, int, flags);
+}
+
+PRE(sys_vmsplice)
+{
+ PRINT("sys_vmsplice ( %ld, %ld, %ld, %ld )", ARG1, ARG2, ARG3, ARG4);
+ PRE_REG_READ4(long, "sys_vmsplice", int, fdin, struct vki_iovec *, v,
+ vki_size_t, len, int, flags);
+}
+
+PRE(sys_unshare)
+{
+ PRINT("sys_unshare ( %ld )", ARG1);
+ PRE_REG_READ1(long, "sys_unshare", int, flags);
+}
+
+PRE(sys_msgctl)
+{
+ PRINT("sys_msgctl ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "msgctl", int, msqid, int, cmd, struct msqid_ds *, buf);
+ ML_(linux_PRE_sys_msgctl) (tid, ARG1, ARG2, ARG3);
+}
+
+POST(sys_msgctl)
+{
+ ML_(linux_POST_sys_msgctl)(tid, RES, ARG1, ARG2, ARG3);
+}
+
+PRE(sys_msgget)
+{
+ PRINT("sys_msgget ( %ld, %ld )", ARG1, ARG2);
+ PRE_REG_READ2(long, "msgget", vki_key_t, key, int, msgflg);
+}
+
+PRE(sys_sched_rr_get_interval)
+{
+ PRINT("sys_sched_rr_get_interval ( %ld, %#lx)", ARG1, ARG2);
+ PRE_REG_READ2(long, "sched_rr_get_interval", int, flags,
+ struct timespec *, timer);
+ *flags |= SfMayBlock;
+}
+
+PRE(sys_ustat)
+{
+ PRINT("sys_ustat ( %ld, %#lx)", ARG1, ARG2);
+ PRE_REG_READ2(long, "ustat", int, flags, const void *, path);
+}
+
+PRE(sys_swapon)
+{
+ PRINT("sys_swapon ( %#lx, %ld )", ARG1, ARG2);
+ PRE_REG_READ2(long, "swapon", const void *, path, int, flags);
+}
+
+PRE(sys_swapoff)
+{
+ PRINT("sys_swapoff ( %#lx )", ARG1);
+ PRE_REG_READ1(long, "swapoff", const void *, path);
+}
+
+PRE(sys_sysfs)
+{
+ PRINT("sys_sysfs ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "sysfs", int, flags, int, desc, const void *, path);
+}
+
+PRE(sys_msgsnd)
+{
+ PRINT("sys_msgsnd ( %ld, %#lx, %ld, %ld )", ARG1, ARG2, ARG3, ARG4);
+ PRE_REG_READ4(long, "msgsnd", int, msqid, struct msgbuf *, msgp,
+ vki_size_t, msgsz, int, msgflg);
+ ML_(linux_PRE_sys_msgsnd)(tid, ARG1, ARG2, ARG3, ARG4);
+ if ((ARG4 & VKI_IPC_NOWAIT) == 0)
+ *flags |= SfMayBlock;
+}
+
+PRE(sys_msgrcv)
+{
+ PRINT("sys_msgrcv ( %ld, %#lx, %ld, %ld, %ld )", ARG1, ARG2, ARG3, ARG4,
+ ARG5);
+ PRE_REG_READ5(long, "msgrcv", int, msqid, struct msgbuf *, msgp,
+ vki_size_t, msgsz, long, msgytp, int, msgflg);
+ ML_(linux_PRE_sys_msgrcv) (tid, ARG1, ARG2, ARG3, ARG4, ARG5);
+ if ((ARG4 & VKI_IPC_NOWAIT) == 0)
+ *flags |= SfMayBlock;
+}
+
+POST(sys_msgrcv)
+{
+ ML_(linux_POST_sys_msgrcv)(tid, RES, ARG1, ARG2, ARG3, ARG4, ARG5);
+}
+
+PRE(sys_semctl)
+{
+ switch (ARG3 & ~VKI_IPC_64) {
+ case VKI_IPC_INFO:
+ case VKI_SEM_INFO:
+ PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4);
+ PRE_REG_READ4(long, "semctl", int, semid, int, semnum, int, cmd,
+ struct seminfo *, arg);
+ break;
+ case VKI_IPC_STAT:
+ case VKI_SEM_STAT:
+ case VKI_IPC_SET:
+ PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4);
+ PRE_REG_READ4(long, "semctl", int, semid, int, semnum, int, cmd,
+ struct semid_ds *, arg);
+ break;
+ case VKI_GETALL:
+ case VKI_SETALL:
+ PRINT("sys_semctl ( %ld, %ld, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4);
+ PRE_REG_READ4(long, "semctl", int, semid, int, semnum, int, cmd,
+ unsigned short *, arg);
+ break;
+ default:
+ PRINT("sys_semctl ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "semctl", int, semid, int, semnum, int, cmd);
+ break;
+ }
+ ML_(generic_PRE_sys_semctl)(tid, ARG1, ARG2, ARG3, ARG4);
+}
+
+POST(sys_semctl)
+{
+ ML_(generic_POST_sys_semctl)(tid, RES, ARG1, ARG2, ARG3, ARG4);
+}
+
+PRE(sys_semget)
+{
+ PRINT("sys_semget ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "semget", vki_key_t, key, int, nsems, int, semflg);
+}
+
+PRE(sys_semop)
+{
+ *flags |= SfMayBlock;
+ PRINT("sys_semop ( %ld, %#lx, %lu )", ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "semop", int, semid, struct sembuf *, sops,
+ unsigned, nsoops);
+ ML_(generic_PRE_sys_semop)(tid, ARG1, ARG2, ARG3);
+}
+
+PRE(sys_semtimedop)
+{
+ *flags |= SfMayBlock;
+ PRINT("sys_semtimedop ( %ld, %#lx, %lu, %#lx )", ARG1, ARG2, ARG3, ARG4);
+ PRE_REG_READ4(long, "semtimedop", int, semid, struct sembuf *, sops,
+ unsigned, nsoops, struct timespec *, timeout);
+ ML_(generic_PRE_sys_semtimedop)(tid, ARG1, ARG2, ARG3, ARG4);
+}
+
+/* Very much MIPS specific */
+PRE(sys_cacheflush)
+{
+ PRINT("cacheflush (%lx, %#lx, %#lx)", ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "cacheflush", void *, addrlow, void *, addrhigh,
+ int, flags);
+ VG_(discard_translations)((Addr64) ARG1, ((ULong) ARG2) - ((ULong) ARG1) +
+ 1ULL /*paranoia */ , "PRE(sys_cacheflush)");
+ SET_STATUS_Success(0);
+}
+
+PRE(sys_getpeername)
+{
+ PRINT("sys_getpeername ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "getpeername", int, s, struct sockaddr *, name,
+ int *, namelen);
+ ML_(generic_PRE_sys_getpeername) (tid, ARG1, ARG2, ARG3);
+}
+
+POST(sys_getpeername)
+{
+ vg_assert (SUCCESS);
+ ML_(generic_POST_sys_getpeername)(tid, VG_ (mk_SysRes_Success) (RES),
+ ARG1, ARG2, ARG3);
+}
+
+PRE(sys_getsockname)
+{
+ PRINT("sys_getsockname ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "getsockname", int, s, struct sockaddr *, name,
+ int *, namelen);
+ ML_(generic_PRE_sys_getsockname)(tid, ARG1, ARG2, ARG3);
+}
+
+POST(sys_getsockname)
+{
+ vg_assert(SUCCESS);
+ ML_(generic_POST_sys_getsockname)(tid, VG_ (mk_SysRes_Success) (RES),
+ ARG1, ARG2, ARG3);
+}
+
+PRE(sys_shutdown)
+{
+ *flags |= SfMayBlock;
+ PRINT("sys_shutdown ( %ld, %ld )", ARG1, ARG2);
+ PRE_REG_READ2(int, "shutdown", int, s, int, how);
+}
+
+PRE(sys_reboot)
+{
+ PRINT("sys_reboot ( %ld )", ARG1);
+ PRE_REG_READ1(int, "reboot", int, flags);
+ *flags |= SfMayBlock;
+}
+
+PRE(sys_bind)
+{
+ PRINT("sys_bind ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "bind", int, sockfd, struct sockaddr *, my_addr,
+ int, addrlen);
+ ML_(generic_PRE_sys_bind)(tid, ARG1, ARG2, ARG3);
+}
+
+PRE(sys_setdomainname)
+{
+ PRINT ("sys_setdomainname ( %#lx, %ld )", ARG1, ARG2);
+ PRE_REG_READ2 (long, "setdomainname", const void *, name, int, len);
+}
+
+PRE(sys_sethostname)
+{
+ PRINT ("sys_sethostname ( %ld, %ld )", ARG1, ARG2);
+ PRE_REG_READ2 (long, "sethostname", const void *, name, int, len);
+}
+
+PRE(sys_listen)
+{
+ PRINT ("sys_listen ( %ld, %ld )", ARG1, ARG2);
+ PRE_REG_READ2 (long, "listen", int, s, int, backlog);
+}
+
+PRE(sys_sendmsg)
+{
+ *flags |= SfMayBlock;
+ PRINT("sys_sendmsg ( %ld, %#lx, %ld )",ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "sendmsg", int, s, const struct msghdr *, msg,
+ int, flags);
+ ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)ARG2);
+}
+
+PRE(sys_recvmsg)
+{
+ *flags |= SfMayBlock;
+ PRINT("sys_recvmsg ( %ld, %#lx, %ld )",ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg, int, flags);
+ ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2);
+}
+
+POST(sys_recvmsg)
+{
+ ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2, RES);
+}
+
+PRE(sys_sendto)
+{
+ *flags |= SfMayBlock;
+ PRINT ("sys_sendto ( %ld, %#lx, %ld, %lu, %#lx, %ld )", ARG1, ARG2, ARG3,
+ ARG4, ARG5, ARG6);
+ PRE_REG_READ6 (long, "sendto", int, s, const void *, msg, int, len,
+ unsigned int, flags, const struct sockaddr *, to, int, tolen);
+ ML_(generic_PRE_sys_sendto) (tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
+}
+
+PRE(sys_recvfrom)
+{
+ *flags |= SfMayBlock;
+ PRINT("sys_recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )", ARG1, ARG2,
+ ARG3, ARG4, ARG5, ARG6);
+ PRE_REG_READ6(long, "recvfrom", int, s, void *, buf, int, len,
+ unsigned int, flags, struct sockaddr *, from, int *, fromlen);
+ ML_(generic_PRE_sys_recvfrom)(tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
+}
+
+POST(sys_recvfrom)
+{
+ vg_assert(SUCCESS);
+ ML_(generic_POST_sys_recvfrom)(tid, VG_(mk_SysRes_Success)(RES),
+ ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
+}
+
+PRE (sys_connect)
+{
+ *flags |= SfMayBlock;
+ PRINT("sys_connect ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "connect", int, sockfd, struct sockaddr *, serv_addr,
+ int, addrlen);
+ ML_(generic_PRE_sys_connect)(tid, ARG1, ARG2, ARG3);
+}
+
+PRE(sys_accept)
+{
+ *flags |= SfMayBlock;
+ PRINT("sys_accept ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "accept", int, s, struct sockaddr *, addr,
+ int, *addrlen);
+ ML_(generic_PRE_sys_accept)(tid, ARG1, ARG2, ARG3);
+}
+
+PRE(sys_accept4)
+{
+ *flags |= SfMayBlock;
+}
+
+POST(sys_accept)
+{
+ SysRes r;
+ vg_assert(SUCCESS);
+ r = ML_(generic_POST_sys_accept)(tid, VG_ (mk_SysRes_Success) (RES),
+ ARG1, ARG2, ARG3);
+ SET_STATUS_from_SysRes(r);
+}
+
+PRE(sys_setsockopt)
+{
+ PRINT("sys_setsockopt ( %ld, %ld, %ld, %#lx, %ld )", ARG1, ARG2, ARG3,
+ ARG4, ARG5);
+ PRE_REG_READ5(long, "setsockopt", int, s, int, level, int, optname,
+ const void *, optval, int, optlen);
+ ML_(generic_PRE_sys_setsockopt)(tid, ARG1, ARG2, ARG3, ARG4, ARG5);
+}
+
+PRE(sys_getsockopt)
+{
+ PRINT("sys_getsockopt ( %ld, %ld, %ld, %#lx, %#lx )", ARG1, ARG2, ARG3,
+ ARG4, ARG5);
+ PRE_REG_READ5(long, "getsockopt", int, s, int, level, int, optname,
+ void *, optval, int, *optlen);
+ ML_(linux_PRE_sys_getsockopt)(tid, ARG1, ARG2, ARG3, ARG4, ARG5);
+}
+
+POST(sys_getsockopt)
+{
+ vg_assert(SUCCESS);
+ ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success) (RES),
+ ARG1, ARG2, ARG3, ARG4, ARG5);
+}
+
+PRE(sys_socket)
+{
+ PRINT("sys_socket ( %ld, %ld, %ld )", ARG1, ARG2, ARG3);
+ PRE_REG_READ3(long, "socket", int, domain, int, type, int, protocol);
+}
+
+POST(sys_socket)
+{
+ SysRes r;
+ vg_assert(SUCCESS);
+ r = ML_(generic_POST_sys_socket)(tid, VG_(mk_SysRes_Success)(RES));
+ SET_STATUS_from_SysRes(r);
+}
+
+PRE(sys_ptrace)
+{
+ PRINT("sys_ptrace ( %ld, %ld, %#lx, %#lx )", ARG1, ARG2, ARG3, ARG4);
+ PRE_REG_READ4(int, "ptrace", long, request, long, pid, long, addr,
+ long, data);
+ switch (ARG1) {
+ case VKI_PTRACE_PEEKTEXT:
+ case VKI_PTRACE_PEEKDATA:
+ case VKI_PTRACE_PEEKUSR:
+ PRE_MEM_WRITE("ptrace(peek)", ARG4, sizeof(long));
+ break;
+ case VKI_PTRACE_GETEVENTMSG:
+ PRE_MEM_WRITE("ptrace(geteventmsg)", ARG4, sizeof(unsigned long));
+ break;
+ case VKI_PTRACE_GETSIGINFO:
+ PRE_MEM_WRITE("ptrace(getsiginfo)", ARG4, sizeof(vki_siginfo_t));
+ break;
+ case VKI_PTRACE_SETSIGINFO:
+ PRE_MEM_READ("ptrace(setsiginfo)", ARG4, sizeof(vki_siginfo_t));
+ break;
+ default:
+ break;
+ }
+}
+
+POST(sys_ptrace)
+{
+ switch (ARG1) {
+ case VKI_PTRACE_PEEKTEXT:
+ case VKI_PTRACE_PEEKDATA:
+ case VKI_PTRACE_PEEKUSR:
+ POST_MEM_WRITE (ARG4, sizeof(long));
+ break;
+ case VKI_PTRACE_GETEVENTMSG:
+ POST_MEM_WRITE (ARG4, sizeof(unsigned long));
+ break;
+ case VKI_PTRACE_GETSIGINFO:
+ POST_MEM_WRITE (ARG4, sizeof(vki_siginfo_t));
+ break;
+ default:
+ break;
+ }
+}
+
+PRE (sys_mmap)
+{
+ SysRes r;
+ PRINT("sys_mmap ( %#lx, %llu, %lu, %lu, %lu, %ld )", ARG1, (ULong)ARG2,
+ ARG3, ARG4, ARG5, ARG6);
+ PRE_REG_READ6(long, "mmap", unsigned long, start, vki_size_t, length,
+ int, prot, int, flags, int, fd, unsigned long, offset);
+ r = ML_(generic_PRE_sys_mmap)(tid, ARG1, ARG2, ARG3, ARG4, ARG5,
+ (Off64T) ARG6);
+ SET_STATUS_from_SysRes(r);
+}
+
+PRE(sys_clone)
+{
+ Bool badarg = False;
+ UInt cloneflags;
+ PRINT("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )", ARG1, ARG2, ARG3,
+ ARG4, ARG5);
+ PRE_REG_READ2(int, "clone", unsigned long, flags, void *, child_stack);
+ if (ARG1 & VKI_CLONE_PARENT_SETTID) {
+ if (VG_(tdict).track_pre_reg_read) {
+ PRA3("clone", int *, parent_tidptr);
+ }
+ PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
+ if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int), VKI_PROT_WRITE)) {
+ badarg = True;
+ }
+ }
+ if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
+ if (VG_(tdict).track_pre_reg_read) {
+ PRA5("clone", int *, child_tidptr);
+ }
+ PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof (Int));
+ if (!VG_(am_is_valid_for_client)(ARG5, sizeof (Int), VKI_PROT_WRITE))
+ badarg = True;
+ }
+ if (badarg) {
+ SET_STATUS_Failure(VKI_EFAULT);
+ return;
+ }
+ cloneflags = ARG1;
+ if (!ML_(client_signal_OK)(ARG1 & VKI_CSIGNAL)) {
+ SET_STATUS_Failure(VKI_EINVAL);
+ return;
+ }
+ /* Only look at the flags we really care about */
+ switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS
+ |VKI_CLONE_FILES | VKI_CLONE_VFORK)) {
+ case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES:
+ /* thread creation */
+ SET_STATUS_from_SysRes(do_clone(tid,
+ ARG1, /* flags */
+ (Addr)ARG2, /* child SP */
+ (Int *)ARG3, /* parent_tidptr */
+ (Int *)ARG5, /* child_tidptr */
+ (Addr)ARG4)); /* child_tls */
+ break;
+
+ case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */
+ /* FALLTHROUGH - assume vfork == fork */
+ cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM);
+ case 0: /* plain fork */
+ SET_STATUS_from_SysRes(ML_(do_fork_clone)(tid,
+ cloneflags, /* flags */
+ (Int *)ARG3, /* parent_tidptr */
+ (Int *)ARG5)); /* child_tidptr */
+ break;
+
+ default:
+ /* should we just ENOSYS? */
+ VG_(message)(Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1);
+ VG_(message)(Vg_UserMsg, "\n");
+ VG_(message)(Vg_UserMsg, "The only supported clone() uses are:\n");
+ VG_(message)(Vg_UserMsg,
+ " - via a threads library (LinuxThreads or NPTL)\n");
+ VG_(message)(Vg_UserMsg,
+ " - via the implementation of fork or vfork\n");
+ VG_(unimplemented)("Valgrind does not support general clone().");
+ }
+ if (SUCCESS) {
+ if (ARG1 & VKI_CLONE_PARENT_SETTID)
+ POST_MEM_WRITE(ARG3, sizeof(Int));
+ if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID))
+ POST_MEM_WRITE(ARG5, sizeof(Int));
+ /* Thread creation was successful; let the child have the chance to run */
+ *flags |= SfYieldAfter;
+ }
+}
+
+PRE(sys_rt_sigreturn)
+{
+ /* See comments on PRE(sys_rt_sigreturn) in syswrap-s390x-linux.c for
+ an explanation of what follows. */
+ ThreadState* tst;
+ PRINT("sys_rt_sigreturn ( )");
+
+ vg_assert(VG_(is_valid_tid)(tid));
+ vg_assert(tid >= 1 && tid < VG_N_THREADS);
+ vg_assert(VG_(is_running_thread)(tid));
+
+ tst = VG_(get_ThreadState)(tid);
+
+ /* This is only so that the IA is (might be) useful to report if
+ something goes wrong in the sigreturn */
+ ML_(fixup_guest_state_to_restart_syscall)(&tst->arch);
+
+ /* Restore register state from frame and remove it */
+ VG_(sigframe_destroy)(tid, True);
+
+ /* Tell the driver not to update the guest state with the "result",
+ and set a bogus result to keep it happy. */
+ *flags |= SfNoWriteResult;
+ SET_STATUS_Success(0);
+
+ /* Check to see if any signals arose as a result of this. */
+ *flags |= SfPollAfter;
+}
+
+PRE(sys_set_thread_area)
+{
+ PRINT("set_thread_area (%lx)", ARG1);
+ PRE_REG_READ1(long, "set_thread_area", unsigned long, addr);
+ SET_STATUS_from_SysRes(sys_set_tls(tid, ARG1));
+}
+
+PRE(sys_pipe)
+{
+ PRINT("sys_pipe ( %#lx )", ARG1);
+ PRE_REG_READ1(int, "pipe", int *, filedes);
+ PRE_MEM_WRITE( "pipe(filedes)", ARG1, 2*sizeof(int) );
+}
+
+POST(sys_pipe)
+{
+ Int p0, p1;
+ vg_assert(SUCCESS);
+ p0 = RES;
+ p1 = sr_ResEx(status->sres);
+
+ if (!ML_(fd_allowed)(p0, "pipe", tid, True) ||
+ !ML_(fd_allowed)(p1, "pipe", tid, True)) {
+ VG_(close)(p0);
+ VG_(close)(p1);
+ SET_STATUS_Failure( VKI_EMFILE );
+ } else {
+ if (VG_(clo_track_fds)) {
+ ML_(record_fd_open_nameless)(tid, p0);
+ ML_(record_fd_open_nameless)(tid, p1);
+ }
+ }
+}
+
+#undef PRE
+#undef POST
+
+/* ---------------------------------------------------------------------
+ The mips64/Linux syscall table
+ ------------------------------------------------------------------ */
+
+/* Add an mips64-linux specific wrapper to a syscall table. */
+#define PLAX_(sysno, name) WRAPPER_ENTRY_X_(mips_linux, sysno, name)
+#define PLAXY(sysno, name) WRAPPER_ENTRY_XY(mips_linux, sysno, name)
+
+static SyscallTableEntry syscall_main_table[] = {
+ GENXY (__NR_read, sys_read), /* 5000 */
+ GENX_ (__NR_write, sys_write),
+ GENXY (__NR_open, sys_open),
+ GENXY (__NR_close, sys_close),
+ GENXY (__NR_stat, sys_newstat),
+ GENXY (__NR_fstat, sys_newfstat),
+ GENXY (__NR_lstat, sys_newlstat),
+ GENXY (__NR_poll, sys_poll),
+ LINX_ (__NR_lseek, sys_lseek),
+ PLAX_ (__NR_mmap, sys_mmap),
+ GENXY (__NR_mprotect, sys_mprotect),
+ GENXY (__NR_munmap, sys_munmap),
+ GENX_ (__NR_brk, sys_brk),
+ LINXY (__NR_rt_sigaction, sys_rt_sigaction),
+ LINXY (__NR_rt_sigprocmask, sys_rt_sigprocmask),
+ LINXY (__NR_ioctl, sys_ioctl),
+ LINXY (__NR_eventfd2, sys_eventfd2),
+ LINXY (__NR_signalfd4, sys_signalfd4),
+ GENXY (__NR_pread64, sys_pread64),
+ GENX_ (__NR_pwrite64, sys_pwrite64),
+ GENXY (__NR_readv, sys_readv),
+ GENX_ (__NR_writev, sys_writev),
+ GENX_ (__NR_access, sys_access),
+ PLAXY (__NR_pipe, sys_pipe),
+ LINXY (__NR_pipe2, sys_pipe2),
+ GENX_ (__NR__newselect,sys_select),
+ LINX_ (__NR_sched_yield, sys_sched_yield),
+ GENX_ (__NR_mremap, sys_mremap),
+ GENX_ (__NR_msync, sys_msync),
+ GENXY (__NR_mincore, sys_mincore),
+ GENX_ (__NR_madvise, sys_madvise),
+ PLAX_ (__NR_shmget, sys_shmget),
+ /* PLAXY(__NR_shmat,sys_shmat), */
+ PLAXY (__NR_shmctl, sys_shmctl),
+ GENXY (__NR_dup, sys_dup),
+ GENXY (__NR_dup2, sys_dup2),
+ /* GENXY(__NR_dup3,sys_dup3), */
+ GENX_ (__NR_pause, sys_pause),
+ GENXY (__NR_nanosleep, sys_nanosleep),
+ GENXY (__NR_getitimer, sys_getitimer),
+ GENXY (__NR_setitimer, sys_setitimer),
+ GENX_ (__NR_alarm, sys_alarm),
+ GENX_ (__NR_getpid, sys_getpid),
+ /* LINX_(__NR_fallocate,sys_fallocate), */
+ LINXY (__NR_sendfile, sys_sendfile),
+ PLAXY (__NR_socket, sys_socket),
+ PLAX_ (__NR_connect, sys_connect),
+ PLAXY (__NR_accept, sys_accept),
+ /* PLAX_(__NR_accept4,sys_accept4), */
+ PLAX_ (__NR_sendto, sys_sendto),
+ PLAXY (__NR_recvfrom, sys_recvfrom),
+ PLAX_ (__NR_sendmsg, sys_sendmsg),
+ PLAXY (__NR_recvmsg, sys_recvmsg),
+ PLAX_ (__NR_shutdown, sys_shutdown),
+ PLAX_ (__NR_bind, sys_bind),
+ PLAX_ (__NR_listen, sys_listen),
+ PLAXY (__NR_getsockname, sys_getsockname),
+ PLAXY (__NR_getpeername, sys_getpeername),
+ PLAXY (__NR_socketpair, sys_socketpair),
+ PLAX_ (__NR_setsockopt, sys_setsockopt),
+ PLAXY (__NR_getsockopt, sys_getsockopt),
+ PLAX_ (__NR_clone, sys_clone),
+ GENX_ (__NR_fork, sys_fork),
+ GENX_ (__NR_execve, sys_execve),
+ GENX_ (__NR_exit, sys_exit),
+ GENXY (__NR_wait4, sys_wait4),
+ GENX_ (__NR_kill, sys_kill),
+ GENXY (__NR_uname, sys_newuname),
+ PLAX_ (__NR_semget, sys_semget),
+ PLAX_ (__NR_semop, sys_semop),
+ PLAXY (__NR_semctl, sys_semctl),
+ PLAXY (__NR_shmdt, sys_shmdt),
+ PLAX_ (__NR_msgget, sys_msgget),
+ PLAX_ (__NR_msgsnd, sys_msgsnd),
+ PLAXY (__NR_msgrcv, sys_msgrcv),
+ PLAXY (__NR_msgctl, sys_msgctl),
+ LINXY (__NR_fcntl, sys_fcntl),
+ GENX_ (__NR_flock, sys_flock),
+ GENX_ (__NR_fsync, sys_fsync),
+ GENX_ (__NR_fdatasync, sys_fdatasync),
+ GENX_ (__NR_truncate, sys_truncate),
+ GENX_ (__NR_ftruncate, sys_ftruncate),
+ GENXY (__NR_getdents, sys_getdents),
+ GENXY (__NR_getcwd, sys_getcwd),
+ GENX_ (__NR_chdir, sys_chdir),
+ GENX_ (__NR_fchdir, sys_fchdir),
+ GENX_ (__NR_rename, sys_rename),
+ GENX_ (__NR_mkdir, sys_mkdir),
+ GENX_ (__NR_rmdir, sys_rmdir),
+ GENXY (__NR_creat, sys_creat),
+ GENX_ (__NR_link, sys_link),
+ GENX_ (__NR_unlink, sys_unlink),
+ GENX_ (__NR_symlink, sys_symlink),
+ GENX_ (__NR_readlink, sys_readlink),
+ GENX_ (__NR_chmod, sys_chmod),
+ GENX_ (__NR_fchmod, sys_fchmod),
+ GENX_ (__NR_chown, sys_chown),
+ GENX_ (__NR_fchown, sys_fchown),
+ GENX_ (__NR_lchown, sys_lchown),
+ GENX_ (__NR_umask, sys_umask),
+ GENXY (__NR_gettimeofday, sys_gettimeofday),
+ GENXY (__NR_getrlimit, sys_getrlimit),
+ GENXY (__NR_getrusage, sys_getrusage),
+ LINXY (__NR_sysinfo, sys_sysinfo),
+ GENXY (__NR_times, sys_times),
+ PLAXY (__NR_ptrace, sys_ptrace),
+ GENX_ (__NR_getuid, sys_getuid),
+ LINXY (__NR_syslog, sys_syslog),
+ GENX_ (__NR_getgid, sys_getgid),
+ GENX_ (__NR_setuid, sys_setuid),
+ GENX_ (__NR_setgid, sys_setgid),
+ GENX_ (__NR_geteuid, sys_geteuid),
+ GENX_ (__NR_getegid, sys_getegid),
+ GENX_ (__NR_setpgid, sys_setpgid),
+ GENX_ (__NR_getppid, sys_getppid),
+ GENX_ (__NR_getpgrp, sys_getpgrp),
+ GENX_ (__NR_setsid, sys_setsid),
+ GENX_ (__NR_setreuid, sys_setreuid),
+ GENX_ (__NR_setregid, sys_setregid),
+ GENXY (__NR_getgroups, sys_getgroups),
+ GENX_ (__NR_setgroups, sys_setgroups),
+ LINX_ (__NR_setresuid, sys_setresuid),
+ LINXY (__NR_getresuid, sys_getresuid),
+ LINX_ (__NR_setresgid, sys_setresgid),
+ LINXY (__NR_getresgid, sys_getresgid),
+ GENX_ (__NR_getpgid, sys_getpgid),
+ LINX_ (__NR_setfsuid, sys_setfsuid),
+ LINX_ (__NR_setfsgid, sys_setfsgid),
+ GENX_ (__NR_getsid, sys_getsid),
+ LINXY (__NR_capget, sys_capget),
+ LINX_ (__NR_capset, sys_capset),
+ LINXY (__NR_rt_sigpending, sys_rt_sigpending),
+ LINXY (__NR_rt_sigtimedwait, sys_rt_sigtimedwait),
+ LINXY (__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo),
+ LINX_ (__NR_rt_sigsuspend, sys_rt_sigsuspend),
+ GENXY (__NR_sigaltstack, sys_sigaltstack),
+ LINX_ (__NR_utime, sys_utime),
+ GENX_ (__NR_mknod, sys_mknod),
+ LINX_ (__NR_personality, sys_personality),
+ PLAX_ (__NR_ustat, sys_ustat),
+ GENXY (__NR_statfs, sys_statfs),
+ GENXY (__NR_fstatfs, sys_fstatfs),
+ PLAX_ (__NR_sysfs, sys_sysfs),
+ GENX_ (__NR_getpriority, sys_getpriority),
+ GENX_ (__NR_setpriority, sys_setpriority),
+ LINXY (__NR_sched_setparam, sys_sched_setparam),
+ LINXY (__NR_sched_getparam, sys_sched_getparam),
+ LINX_ (__NR_sched_setscheduler, sys_sched_setscheduler),
+ LINX_ (__NR_sched_getscheduler, sys_sched_getscheduler),
+ LINX_ (__NR_sched_get_priority_max, sys_sched_get_priority_max),
+ LINX_ (__NR_sched_get_priority_min, sys_sched_get_priority_min),
+ PLAX_ (__NR_sched_rr_get_interval, sys_sched_rr_get_interval),
+ GENX_ (__NR_mlock, sys_mlock),
+ GENX_ (__NR_munlock, sys_munlock),
+ GENX_ (__NR_mlockall, sys_mlockall),
+ LINX_ (__NR_munlockall, sys_munlockall),
+ LINX_ (__NR_vhangup, sys_vhangup),
+ /* GENX_(__NR_pivot_root,sys_pivot_root), */
+ LINXY (__NR__sysctl, sys_sysctl),
+ LINXY (__NR_prctl, sys_prctl),
+ LINXY (__NR_adjtimex, sys_adjtimex),
+ GENX_ (__NR_setrlimit, sys_setrlimit),
+ GENX_ (__NR_chroot, sys_chroot),
+ GENX_ (__NR_sync, sys_sync),
+ GENX_ (__NR_acct, sys_acct),
+ GENX_ (__NR_settimeofday, sys_settimeofday),
+ LINX_ (__NR_mount, sys_mount),
+ LINX_ (__NR_umount2, sys_umount),
+ PLAX_ (__NR_swapon, sys_swapon),
+ PLAX_ (__NR_swapoff, sys_swapoff),
+ PLAX_ (__NR_reboot, sys_reboot),
+ PLAX_ (__NR_sethostname, sys_sethostname),
+ PLAX_ (__NR_setdomainname, sys_setdomainname),
+ GENX_ (__NR_create_module, sys_ni_syscall),
+ LINX_ (__NR_init_module, sys_init_module),
+ LINX_ (__NR_delete_module, sys_delete_module),
+ GENX_ (__NR_get_kernel_syms, sys_ni_syscall),
+ GENX_ (__NR_query_module, sys_ni_syscall),
+ LINX_ (__NR_quotactl, sys_quotactl),
+ /* GENX_(__NR_nfsservctl,sys_nfsservctl), */
+ GENXY (__NR_getpmsg, sys_getpmsg),
+ GENX_ (__NR_putpmsg, sys_putpmsg),
+ GENX_ (__NR_afs_syscall, sys_ni_syscall),
+ /* GENX_(__NR_reserved177,sys_reserved177), */
+ LINX_ (__NR_gettid, sys_gettid),
+ /* GENX_(__NR_readahead,sys_readahead), */
+ LINX_ (__NR_setxattr, sys_setxattr),
+ LINX_ (__NR_lsetxattr, sys_lsetxattr),
+ LINX_ (__NR_fsetxattr, sys_fsetxattr),
+ LINXY (__NR_getxattr, sys_getxattr),
+ LINXY (__NR_lgetxattr, sys_lgetxattr),
+ LINXY (__NR_fgetxattr, sys_fgetxattr),
+ LINXY (__NR_listxattr, sys_listxattr),
+ LINXY (__NR_llistxattr, sys_llistxattr),
+ LINXY (__NR_flistxattr, sys_flistxattr),
+ LINX_ (__NR_removexattr, sys_removexattr),
+ LINX_ (__NR_lremovexattr, sys_lremovexattr),
+ LINX_ (__NR_fremovexattr, sys_fremovexattr),
+ LINXY (__NR_tkill, sys_tkill),
+ /* GENX_(__NR_reserved193,sys_reserved193), */
+ LINXY (__NR_futex, sys_futex),
+ LINX_ (__NR_sched_setaffinity, sys_sched_setaffinity),
+ LINXY (__NR_sched_getaffinity, sys_sched_getaffinity),
+ PLAX_ (__NR_cacheflush, sys_cacheflush),
+ LINXY (__NR_io_setup, sys_io_setup),
+ LINX_ (__NR_io_destroy, sys_io_destroy),
+ LINXY (__NR_io_getevents, sys_io_getevents),
+ LINX_ (__NR_io_submit, sys_io_submit),
+ LINXY (__NR_io_cancel, sys_io_cancel),
+ LINX_ (__NR_exit_group, sys_exit_group),
+ /* LINXY (__NR_lookup_dcookie, sys_lookup_dcookie), */
+ LINXY (__NR_epoll_create, sys_epoll_create),
+ /* LINXY(__NR_epoll_create1,sys_epoll_create1), */
+ LINX_ (__NR_epoll_ctl, sys_epoll_ctl),
+ LINXY (__NR_epoll_wait, sys_epoll_wait),
+ PLAX_(__NR_rt_sigreturn,sys_rt_sigreturn),
+ /* LINXY(__NR_fcntl64,sys_fcntl64), */
+ LINX_ (__NR_set_tid_address, sys_set_tid_address),
+ PLAX_ (__NR_semtimedop, sys_semtimedop),
+ LINX_ (__NR_fadvise64, sys_fadvise64),
+ LINXY (__NR_timer_create, sys_timer_create),
+ LINXY (__NR_timer_settime, sys_timer_settime),
+ LINXY (__NR_timer_gettime, sys_timer_gettime),
+ LINX_ (__NR_timer_getoverrun, sys_timer_getoverrun),
+ LINX_ (__NR_timer_delete, sys_timer_delete),
+ LINX_ (__NR_clock_settime, sys_clock_settime),
+ LINXY (__NR_clock_gettime, sys_clock_gettime),
+ LINXY (__NR_clock_getres, sys_clock_getres),
+ LINXY (__NR_clock_nanosleep, sys_clock_nanosleep),
+ LINX_ (__NR_tgkill, sys_tgkill),
+ GENX_ (__NR_utimes, sys_utimes),
+ LINX_ (__NR_mbind, sys_mbind),
+ LINXY (__NR_get_mempolicy, sys_get_mempolicy),
+ LINX_ (__NR_set_mempolicy, sys_set_mempolicy),
+ LINXY (__NR_mq_open, sys_mq_open),
+ LINX_ (__NR_mq_unlink, sys_mq_unlink),
+ LINX_ (__NR_mq_timedsend, sys_mq_timedsend),
+ LINXY (__NR_mq_timedreceive, sys_mq_timedreceive),
+ LINX_ (__NR_mq_notify, sys_mq_notify),
+ LINXY (__NR_mq_getsetattr, sys_mq_getsetattr),
+ GENX_ (__NR_vserver, sys_ni_syscall),
+ LINXY (__NR_waitid, sys_waitid),
+ LINX_ (__NR_add_key, sys_add_key),
+ LINX_ (__NR_request_key, sys_request_key),
+ LINXY (__NR_keyctl, sys_keyctl),
+ PLAX_ (__NR_set_thread_area, sys_set_thread_area),
+ LINX_ (__NR_inotify_init, sys_inotify_init),
+ LINX_ (__NR_inotify_add_watch, sys_inotify_add_watch),
+ LINX_ (__NR_inotify_rm_watch, sys_inotify_rm_watch),
+ LINXY (__NR_openat, sys_openat),
+ LINX_ (__NR_mkdirat, sys_mkdirat),
+ LINX_ (__NR_mknodat, sys_mknodat),
+ LINX_ (__NR_fchownat, sys_fchownat),
+ LINX_ (__NR_futimesat, sys_futimesat),
+ LINX_ (__NR_unlinkat, sys_unlinkat),
+ LINX_ (__NR_renameat, sys_renameat),
+ LINX_ (__NR_linkat, sys_linkat),
+ LINX_ (__NR_symlinkat, sys_symlinkat),
+ LINX_ (__NR_readlinkat, sys_readlinkat),
+ LINX_ (__NR_fchmodat, sys_fchmodat),
+ LINX_ (__NR_faccessat, sys_faccessat),
+ LINX_ (__NR_pselect6, sys_pselect6),
+ LINXY (__NR_ppoll, sys_ppoll),
+ PLAX_ (__NR_unshare, sys_unshare),
+ PLAX_ (__NR_splice, sys_splice),
+ LINX_ (__NR_sync_file_range, sys_sync_file_range),
+ PLAX_ (__NR_tee, sys_tee),
+ PLAX_ (__NR_vmsplice, sys_vmsplice),
+ LINX_ (__NR_set_robust_list, sys_set_robust_list),
+ LINXY (__NR_get_robust_list, sys_get_robust_list),
+ LINXY (__NR_epoll_pwait, sys_epoll_pwait),
+ LINX_ (__NR_ioprio_set, sys_ioprio_set),
+ LINX_ (__NR_ioprio_get, sys_ioprio_get),
+ LINX_ (__NR_utimensat, sys_utimensat),
+ LINXY (__NR_signalfd, sys_signalfd),
+ LINXY (__NR_eventfd, sys_eventfd),
+ LINX_ (__NR_fallocate, sys_fallocate),
+ LINXY (__NR_timerfd_create, sys_timerfd_create),
+ LINXY (__NR_timerfd_gettime, sys_timerfd_gettime),
+ LINXY (__NR_timerfd_settime, sys_timerfd_settime)
+};
+
+SyscallTableEntry * ML_(get_linux_syscall_entry) ( UInt sysno )
+{
+ const UInt syscall_main_table_size
+ = sizeof(syscall_main_table) / sizeof(syscall_main_table[0]);
+
+ if (sysno < syscall_main_table_size) {
+ SyscallTableEntry * sys = &syscall_main_table[sysno];
+ if (sys->before == NULL)
+ return NULL; /* no entry */
+ else
+ return sys;
+ }
+ /* Can't find a wrapper */
+ return NULL;
+}
+
+#endif /* defined(VGP_mips64_linux) */
+
+/*--------------------------------------------------------------------*/
+/*--- end syswrap-mips64-linux.c ---*/
+/*--------------------------------------------------------------------*/
VG_(trampoline_stuff_end):
+# undef UD2_16
+# undef UD2_64
+# undef UD2_256
+# undef UD2_1024
+# undef UD2_PAGE
+
+/*---------------------- mips64-linux ----------------------*/
+#else
+#if defined(VGP_mips64_linux)
+
+# define UD2_16 trap ; trap ; trap; trap
+# define UD2_64 UD2_16 ; UD2_16 ; UD2_16 ; UD2_16
+# define UD2_256 UD2_64 ; UD2_64 ; UD2_64 ; UD2_64
+# define UD2_1024 UD2_256 ; UD2_256 ; UD2_256 ; UD2_256
+# define UD2_PAGE UD2_1024 ; UD2_1024 ; UD2_1024 ; UD2_1024
+
+.global VG_(trampoline_stuff_start)
+VG_(trampoline_stuff_start):
+
+.global VG_(mips64_linux_SUBST_FOR_rt_sigreturn)
+VG_(mips64_linux_SUBST_FOR_rt_sigreturn):
+ li $2,__NR_rt_sigreturn
+ syscall
+ nop
+ .long 0 /*illegal insn*/
+
+/* There's no particular reason that this needs to be handwritten
+ assembly, but since that's what this file contains, here's a
+ simple strlen implementation (written in C and compiled by gcc.)
+*/
+.global VG_(mips64_linux_REDIR_FOR_strlen)
+.type VG_(mips64_linux_REDIR_FOR_strlen), @function
+VG_(mips64_linux_REDIR_FOR_strlen):
+ lbu $12, 0($4)
+ li $13, 0
+ beq $12, $0, M01
+ nop
+
+M02:
+ addiu $13, $13, 1
+ addiu $4, $4, 1
+ lbu $12, 0($4)
+ bne $12, $0, M02
+ nop
+
+M01:
+ move $2, $13
+ jr $31
+ nop
+
+.size VG_(mips64_linux_REDIR_FOR_strlen), .-VG_(mips64_linux_REDIR_FOR_strlen)
+
+.global VG_(trampoline_stuff_end)
+VG_(trampoline_stuff_end):
+
+
# undef UD2_16
# undef UD2_64
# undef UD2_256
#endif
#endif
#endif
+#endif
#if defined(VGO_linux)
/* Let the linker know we don't need an executable stack */
static Bool translations_allowable_from_seg ( NSegment const* seg )
{
-# if defined(VGA_x86) || defined(VGA_s390x) || defined(VGA_mips32)
+# if defined(VGA_x86) || defined(VGA_s390x) || defined(VGA_mips32) \
+ || defined(VGA_mips64)
Bool allowR = True;
# else
Bool allowR = False;
nraddr_szB == 8 ? mkU64(0) : mkU32(0)
)
);
-# if defined(VGP_mips32_linux)
// t9 needs to be set to point to the start of the redirected function.
+# if defined(VGP_mips32_linux)
+ VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
+ Int offB_GPR25 = offsetof(VexGuestMIPS32State, guest_r25);
+ addStmtToIRSB(bb, IRStmt_Put(offB_GPR25, mkU32(closure->readdr)));
+# endif
+# if defined(VGP_mips64_linux)
VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
- Int offB_GPR25 = offsetof(VexGuestMIPS32State,guest_r25);
- addStmtToIRSB( bb, IRStmt_Put( offB_GPR25, mkU32( closure->readdr )) );
+ Int offB_GPR25 = offsetof(VexGuestMIPS64State, guest_r25);
+ addStmtToIRSB(bb, IRStmt_Put(offB_GPR25, mkU64(closure->readdr)));
# endif
# if defined(VG_PLAT_USES_PPCTOC)
{ VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
: IRExpr_Const(IRConst_U32( (UInt)closure->nraddr ))
)
);
-# if defined(VGP_mips32_linux)
// t9 needs to be set to point to the start of the redirected function.
- Int offB_GPR25 = offsetof(VexGuestMIPS32State,guest_r25);
- addStmtToIRSB( bb, IRStmt_Put( offB_GPR25, mkU32( closure->readdr )) );
+# if defined(VGP_mips32_linux)
+ Int offB_GPR25 = offsetof(VexGuestMIPS32State, guest_r25);
+ addStmtToIRSB(bb, IRStmt_Put(offB_GPR25, mkU32(closure->readdr)));
+# endif
+# if defined(VGP_mips64_linux)
+ Int offB_GPR25 = offsetof(VexGuestMIPS64State, guest_r25);
+ addStmtToIRSB(bb, IRStmt_Put(offB_GPR25, mkU64(closure->readdr)));
# endif
# if defined(VGP_ppc64_linux)
addStmtToIRSB(
which totally screws things up, because nothing else can go
there. So bump the hacky load addess along by 0x8000, to
0x108000. */
+ /* Later .. on mips64 we can't use 0x108000, because mapelf will fail. */
+#if defined(VGP_mips64_linux)
+ if (ebase < 0x100000)
+ ebase = 0x100000;
+#else
if (ebase < 0x108000)
ebase = 0x108000;
+#endif
}
info->phnum = e->e.e_phnum;
// protects such stacks.
#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
- || defined(VGP_mips32_linux)
+ || defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
# define VG_STACK_GUARD_SZB 65536 // 1 or 16 pages
# define VG_STACK_ACTIVE_SZB (4096 * 256) // 1Mb
#else
# include "libvex_guest_s390x.h"
#elif defined(VGA_mips32)
# include "libvex_guest_mips32.h"
+#elif defined(VGA_mips64)
+# include "libvex_guest_mips64.h"
#else
# error Unknown arch
#endif
UInt r31; /* Return address of the last subroutine call */
UInt r28;
} MIPS32;
+ struct {
+ ULong r30; /* Stack frame pointer or subroutine variable */
+ ULong r31; /* Return address of the last subroutine call */
+ ULong r28;
+ } MIPS64;
} misc;
}
UnwindStartRegs;
typedef
struct { Addr ia; Addr sp; Addr fp; Addr lr;}
D3UnwindRegs;
-#elif defined(VGA_mips32)
+#elif defined(VGA_mips32) || defined(VGA_mips64)
typedef
struct { Addr pc; Addr sp; Addr fp; Addr ra; }
D3UnwindRegs;
# define VG_ELF_MACHINE EM_MIPS
# define VG_ELF_CLASS ELFCLASS32
# undef VG_PLAT_USES_PPCTOC
+#elif defined(VGP_mips64_linux)
+# if defined (VG_LITTLEENDIAN)
+# define VG_ELF_DATA2XXX ELFDATA2LSB
+# elif defined (VG_BIGENDIAN)
+# define VG_ELF_DATA2XXX ELFDATA2MSB
+# else
+# error "Unknown endianness"
+# endif
+# define VG_ELF_MACHINE EM_MIPS
+# define VG_ELF_CLASS ELFCLASS64
+# undef VG_PLAT_USES_PPCTOC
#else
# error Unknown platform
#endif
# define VG_INSTR_PTR guest_PC
# define VG_STACK_PTR guest_r29
# define VG_FRAME_PTR guest_r30
+#elif defined(VGA_mips64)
+# define VG_INSTR_PTR guest_PC
+# define VG_STACK_PTR guest_r29
+# define VG_FRAME_PTR guest_r30
#else
# error Unknown arch
#endif
// greater than 8.
#if defined(VGP_x86_linux) || \
defined(VGP_arm_linux) || \
- defined(VGP_mips32_linux)
+ defined(VGP_mips32_linux) || \
+ defined(VGP_mips64_linux)
# define VG_MIN_MALLOC_SZB 8
// Nb: We always use 16 bytes for Darwin, even on 32-bits, so it can be used
// for any AltiVec- or SSE-related type. This matches the Darwin libc.
extern SysRes VG_(mk_SysRes_s390x_linux) ( Long val );
extern SysRes VG_(mk_SysRes_mips32_linux)( UWord v0, UWord v1,
UWord a3 );
+extern SysRes VG_(mk_SysRes_mips64_linux)( ULong v0, ULong v1,
+ ULong a3 );
extern SysRes VG_(mk_SysRes_Error) ( UWord val );
extern SysRes VG_(mk_SysRes_Success) ( UWord val );
typedef VexGuestS390XState VexGuestArchState;
#elif defined(VGA_mips32)
typedef VexGuestMIPS32State VexGuestArchState;
+#elif defined(VGA_mips64)
+ typedef VexGuestMIPS64State VexGuestArchState;
#else
# error Unknown architecture
#endif
extern UInt VG_(mips32_linux_REDIR_FOR_strlen)( void* );
#endif
+#if defined(VGP_mips64_linux)
+extern Addr VG_(mips64_linux_SUBST_FOR_rt_sigreturn);
+extern UInt VG_(mips64_linux_REDIR_FOR_strlen)( void* );
+#endif
+
#endif // __PUB_CORE_TRAMPOLINE_H
/*--------------------------------------------------------------------*/
#elif defined(VGA_s390x) || defined(VGA_arm)
# define VG_TT_FAST_HASH(_addr) ((((UWord)(_addr)) >> 1) & VG_TT_FAST_MASK)
-#elif defined(VGA_ppc32) || defined(VGA_ppc64) || defined(VGA_mips32)
+#elif defined(VGA_ppc32) || defined(VGA_ppc64) || defined(VGA_mips32) \
+ || defined(VGA_mips64)
# define VG_TT_FAST_HASH(_addr) ((((UWord)(_addr)) >> 2) & VG_TT_FAST_MASK)
#else
specific code and/or some OS specific code. */
#if defined(VGA_arm) || defined(VGA_x86) || defined(VGA_amd64) \
|| defined(VGA_ppc32) || defined(VGA_ppc64) || defined(VGA_s390x) \
- || defined(VGP_mips32_linux)
+ || defined(VGP_mips32_linux) || defined(VGA_mips64)
#define PTRACEINVOKER
#else
I_die_here : (PTRACEINVOKER) architecture missing in vgdb.c
sp = user_mod.regs.gprs[15];
#elif defined(VGA_mips32)
sp = user_mod.regs[29*2];
+#elif defined(VGA_mips64)
+ sp = user_mod.regs[29];
#else
I_die_here : (sp) architecture missing in vgdb.c
#endif
user_mod.regs[34*2+1] = 0;
user_mod.regs[25*2] = shared32->invoke_gdbserver;
user_mod.regs[25*2+1] = 0;
+#elif defined(VGA_mips64)
+ assert(0); // cannot vgdb a 32 bits executable with a 64 bits exe
#else
I_die_here : architecture missing in vgdb.c
#endif
user_mod.regs.psw.addr = shared64->invoke_gdbserver;
#elif defined(VGA_mips32)
assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe
+#elif defined(VGA_mips64)
+ /* put check arg in register 4 */
+ user_mod.regs[4] = check;
+ /* put NULL return address in ra */
+ user_mod.regs[31] = bad_return;
+ user_mod.regs[34] = shared64->invoke_gdbserver;
+ user_mod.regs[25] = shared64->invoke_gdbserver;
#else
I_die_here: architecture missing in vgdb.c
#endif
#if defined(VGA_x86) || defined(VGA_ppc32) || defined(VGA_arm) \
|| defined(VGA_mips32)
#define BITS_PER_BITS_PER_UWORD 5
-#elif defined(VGA_amd64) || defined(VGA_ppc64) || defined(VGA_s390x)
+#elif defined(VGA_amd64) || defined(VGA_ppc64) || defined(VGA_s390x) \
+ || defined(VGA_mips64)
#define BITS_PER_BITS_PER_UWORD 6
#else
#error Unknown platform.
* DRD's handler for Valgrind client requests. The code below handles both
* DRD's public and tool-internal client requests.
*/
-#if defined(VGP_mips32_linux)
+#if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
/* There is a cse related issue in gcc for MIPS. Optimization level
has to be lowered, so cse related optimizations are not
included. */
#define STACK_POINTER_OFFSET OFFSET_s390x_r15
#elif defined(VGA_mips32)
#define STACK_POINTER_OFFSET OFFSET_mips32_r29
+#elif defined(VGA_mips64)
+#define STACK_POINTER_OFFSET OFFSET_mips64_r29
#else
#error Unknown architecture.
#endif
}
/** Store the thread mode: joinable or detached. */
-#if defined(VGP_mips32_linux)
+#if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
/* There is a cse related issue in gcc for MIPS. Optimization level
has to be lowered, so cse related optimizations are not
included.*/
vki/vki-posixtypes-arm-linux.h \
vki/vki-posixtypes-s390x-linux.h \
vki/vki-posixtypes-mips32-linux.h \
+ vki/vki-posixtypes-mips64-linux.h \
vki/vki-amd64-linux.h \
vki/vki-ppc32-linux.h \
vki/vki-ppc64-linux.h \
vki/vki-arm-linux.h \
vki/vki-s390x-linux.h \
vki/vki-mips32-linux.h \
+ vki/vki-mips64-linux.h \
vki/vki-scnums-amd64-linux.h \
vki/vki-scnums-ppc32-linux.h \
vki/vki-scnums-ppc64-linux.h \
vki/vki-scnums-arm-linux.h \
vki/vki-scnums-s390x-linux.h \
vki/vki-scnums-mips32-linux.h \
+ vki/vki-scnums-mips64-linux.h \
vki/vki-scnums-darwin.h \
vki/vki-xen.h
#undef VG_LITTLEENDIAN
#if defined(VGA_x86) || defined(VGA_amd64) || defined (VGA_arm) \
- || (defined(VGA_mips32) && defined (_MIPSEL))
+ || ((defined(VGA_mips32) || defined(VGA_mips64)) && defined (_MIPSEL))
# define VG_LITTLEENDIAN 1
#elif defined(VGA_ppc32) || defined(VGA_ppc64) || defined(VGA_s390x) \
- || (defined(VGA_mips32) && defined (_MIPSEB))
+ || ((defined(VGA_mips32) || defined(VGA_mips64)) && defined (_MIPSEB))
# define VG_BIGENDIAN 1
#else
# error Unknown arch
# define VG_REGPARM(n) __attribute__((regparm(n)))
#elif defined(VGA_amd64) || defined(VGA_ppc32) \
|| defined(VGA_ppc64) || defined(VGA_arm) || defined(VGA_s390x) \
- || defined(VGA_mips32)
+ || defined(VGA_mips32) || defined(VGA_mips64)
# define VG_REGPARM(n) /* */
#else
# error Unknown arch
# define VG_CLREQ_SZB 20
# define VG_STACK_REDZONE_SZB 0
+#elif defined(VGP_mips64_linux)
+# define VG_MIN_INSTR_SZB 4
+# define VG_MAX_INSTR_SZB 4
+# define VG_CLREQ_SZB 20
+# define VG_STACK_REDZONE_SZB 0
+
#else
# error Unknown platform
#endif
#elif defined(VGP_mips32_linux)
# include "vki/vki-scnums-mips32-linux.h"
+#elif defined(VGP_mips64_linux)
+# include "vki/vki-scnums-mips64-linux.h"
+
#elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
# include "vki/vki-scnums-darwin.h"
#undef PLAT_arm_linux
#undef PLAT_s390x_linux
#undef PLAT_mips32_linux
+#undef PLAT_mips64_linux
#if defined(__APPLE__) && defined(__i386__)
#elif defined(__linux__) && defined(__s390__) && defined(__s390x__)
# define PLAT_s390x_linux 1
#elif defined(__linux__) && defined(__mips__)
+#if (__mips==64)
+# define PLAT_mips64_linux 1
+#else
# define PLAT_mips32_linux 1
+#endif
#else
/* If we're not compiling for our target platform, don't generate
any inline asms. */
"move %0, $11\n\t" /*result*/ \
: "=r" (_zzq_result) \
: "r" (_zzq_default), "r" (&_zzq_args[0]) \
- : "cc","memory", "t3", "t4"); \
+ : "$11", "$12"); \
_zzq_result; \
})
"move %0, $11" /*result*/ \
: "=r" (__addr) \
: \
- : "cc", "memory" , "t3" \
+ : "$11" \
); \
_zzq_orig->nraddr = __addr; \
}
#endif /* PLAT_mips32_linux */
+/* ------------------------- mips64-linux ---------------- */
+
+#if defined(PLAT_mips64_linux)
+
+typedef
+ struct {
+ unsigned long long nraddr; /* where's the code? */
+ }
+ OrigFn;
+
+/* dsll $0,$0, 3
+ * dsll $0,$0, 13
+ * dsll $0,$0, 29
+ * dsll $0,$0, 19*/
+#define __SPECIAL_INSTRUCTION_PREAMBLE \
+ "dsll $0,$0, 3 ; dsll $0,$0,13\n\t" \
+ "dsll $0,$0,29 ; dsll $0,$0,19\n\t"
+
+#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
+ _zzq_default, _zzq_request, \
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
+ __extension__ \
+ ({ volatile unsigned long long int _zzq_args[6]; \
+ volatile unsigned long long int _zzq_result; \
+ _zzq_args[0] = (unsigned long long int)(_zzq_request); \
+ _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \
+ _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \
+ _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \
+ _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \
+ _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \
+ __asm__ volatile("move $11, %1\n\t" /*default*/ \
+ "move $12, %2\n\t" /*ptr*/ \
+ __SPECIAL_INSTRUCTION_PREAMBLE \
+ /* $11 = client_request ( $12 ) */ \
+ "or $13, $13, $13\n\t" \
+ "move %0, $11\n\t" /*result*/ \
+ : "=r" (_zzq_result) \
+ : "r" (_zzq_default), "r" (&_zzq_args[0]) \
+ : "$11", "$12"); \
+ _zzq_result; \
+ })
+
+#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
+ volatile unsigned long long int __addr; \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ /* $11 = guest_NRADDR */ \
+ "or $14, $14, $14\n\t" \
+ "move %0, $11" /*result*/ \
+ : "=r" (__addr) \
+ : \
+ : "$11"); \
+ _zzq_orig->nraddr = __addr; \
+ }
+
+#define VALGRIND_CALL_NOREDIR_T9 \
+ __SPECIAL_INSTRUCTION_PREAMBLE \
+ /* call-noredir $25 */ \
+ "or $15, $15, $15\n\t"
+
+#define VALGRIND_VEX_INJECT_IR() \
+ do { \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ "or $11, $11, $11\n\t" \
+ ); \
+ } while (0)
+
+#endif /* PLAT_mips64_linux */
+
/* Insert assembly code for other platforms here... */
#endif /* NVALGRIND */
#endif /* PLAT_s390x_linux */
-/* ------------------------- mips-linux ------------------------- */
+/* ------------------------- mips32-linux ----------------------- */
#if defined(PLAT_mips32_linux)
_argvec[0] = (unsigned long)_orig.nraddr; \
__asm__ volatile( \
"subu $29, $29, 8 \n\t" \
- "sw $gp, 0($sp) \n\t" \
- "sw $ra, 4($sp) \n\t" \
- "subu $29, $29, 16 \n\t" \
- "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ "sw $28, 0($29) \n\t" \
+ "sw $31, 4($29) \n\t" \
+ "subu $29, $29, 16 \n\t" \
+ "lw $25, 0(%1) \n\t" /* target->t9 */ \
VALGRIND_CALL_NOREDIR_T9 \
"addu $29, $29, 16\n\t" \
- "lw $gp, 0($sp) \n\t" \
- "lw $ra, 4($sp) \n\t" \
+ "lw $28, 0($29) \n\t" \
+ "lw $31, 4($29) \n\t" \
"addu $29, $29, 8 \n\t" \
- "move %0, $v0\n" \
+ "move %0, $2\n" \
: /*out*/ "=r" (_res) \
: /*in*/ "0" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
lval = (__typeof__(lval)) _res; \
} while (0)
_argvec[1] = (unsigned long)(arg1); \
__asm__ volatile( \
"subu $29, $29, 8 \n\t" \
- "sw $gp, 0($sp) \n\t" \
- "sw $ra, 4($sp) \n\t" \
+ "sw $28, 0($29) \n\t" \
+ "sw $31, 4($29) \n\t" \
"subu $29, $29, 16 \n\t" \
- "lw $a0, 4(%1) \n\t" /* arg1*/ \
- "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ "lw $4, 4(%1) \n\t" /* arg1*/ \
+ "lw $25, 0(%1) \n\t" /* target->t9 */ \
VALGRIND_CALL_NOREDIR_T9 \
"addu $29, $29, 16 \n\t" \
- "lw $gp, 0($sp) \n\t" \
- "lw $ra, 4($sp) \n\t" \
+ "lw $28, 0($29) \n\t" \
+ "lw $31, 4($29) \n\t" \
"addu $29, $29, 8 \n\t" \
- "move %0, $v0\n" \
+ "move %0, $2\n" \
: /*out*/ "=r" (_res) \
- : /*in*/ "0" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
lval = (__typeof__(lval)) _res; \
} while (0)
_argvec[2] = (unsigned long)(arg2); \
__asm__ volatile( \
"subu $29, $29, 8 \n\t" \
- "sw $gp, 0($sp) \n\t" \
- "sw $ra, 4($sp) \n\t" \
+ "sw $28, 0($29) \n\t" \
+ "sw $31, 4($29) \n\t" \
"subu $29, $29, 16 \n\t" \
- "lw $a0, 4(%1) \n\t" \
- "lw $a1, 8(%1) \n\t" \
- "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ "lw $4, 4(%1) \n\t" \
+ "lw $5, 8(%1) \n\t" \
+ "lw $25, 0(%1) \n\t" /* target->t9 */ \
VALGRIND_CALL_NOREDIR_T9 \
"addu $29, $29, 16 \n\t" \
- "lw $gp, 0($sp) \n\t" \
- "lw $ra, 4($sp) \n\t" \
+ "lw $28, 0($29) \n\t" \
+ "lw $31, 4($29) \n\t" \
"addu $29, $29, 8 \n\t" \
- "move %0, $v0\n" \
+ "move %0, $2\n" \
: /*out*/ "=r" (_res) \
: /*in*/ "0" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
lval = (__typeof__(lval)) _res; \
} while (0)
_argvec[3] = (unsigned long)(arg3); \
__asm__ volatile( \
"subu $29, $29, 8 \n\t" \
- "sw $gp, 0($sp) \n\t" \
- "sw $ra, 4($sp) \n\t" \
+ "sw $28, 0($29) \n\t" \
+ "sw $31, 4($29) \n\t" \
"subu $29, $29, 16 \n\t" \
- "lw $a0, 4(%1) \n\t" \
- "lw $a1, 8(%1) \n\t" \
- "lw $a2, 12(%1) \n\t" \
- "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ "lw $4, 4(%1) \n\t" \
+ "lw $5, 8(%1) \n\t" \
+ "lw $6, 12(%1) \n\t" \
+ "lw $25, 0(%1) \n\t" /* target->t9 */ \
VALGRIND_CALL_NOREDIR_T9 \
"addu $29, $29, 16 \n\t" \
- "lw $gp, 0($sp) \n\t" \
- "lw $ra, 4($sp) \n\t" \
+ "lw $28, 0($29) \n\t" \
+ "lw $31, 4($29) \n\t" \
"addu $29, $29, 8 \n\t" \
- "move %0, $v0\n" \
+ "move %0, $2\n" \
: /*out*/ "=r" (_res) \
: /*in*/ "0" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
lval = (__typeof__(lval)) _res; \
} while (0)
_argvec[4] = (unsigned long)(arg4); \
__asm__ volatile( \
"subu $29, $29, 8 \n\t" \
- "sw $gp, 0($sp) \n\t" \
- "sw $ra, 4($sp) \n\t" \
+ "sw $28, 0($29) \n\t" \
+ "sw $31, 4($29) \n\t" \
"subu $29, $29, 16 \n\t" \
- "lw $a0, 4(%1) \n\t" \
- "lw $a1, 8(%1) \n\t" \
- "lw $a2, 12(%1) \n\t" \
- "lw $a3, 16(%1) \n\t" \
- "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ "lw $4, 4(%1) \n\t" \
+ "lw $5, 8(%1) \n\t" \
+ "lw $6, 12(%1) \n\t" \
+ "lw $7, 16(%1) \n\t" \
+ "lw $25, 0(%1) \n\t" /* target->t9 */ \
VALGRIND_CALL_NOREDIR_T9 \
"addu $29, $29, 16 \n\t" \
- "lw $gp, 0($sp) \n\t" \
- "lw $ra, 4($sp) \n\t" \
+ "lw $28, 0($29) \n\t" \
+ "lw $31, 4($29) \n\t" \
"addu $29, $29, 8 \n\t" \
- "move %0, $v0\n" \
+ "move %0, $2\n" \
: /*out*/ "=r" (_res) \
: /*in*/ "0" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
lval = (__typeof__(lval)) _res; \
} while (0)
_argvec[5] = (unsigned long)(arg5); \
__asm__ volatile( \
"subu $29, $29, 8 \n\t" \
- "sw $gp, 0($sp) \n\t" \
- "sw $ra, 4($sp) \n\t" \
- "lw $a0, 20(%1) \n\t" \
- "subu $sp, $sp, 24\n\t" \
- "sw $a0, 16($sp) \n\t" \
- "lw $a0, 4(%1) \n\t" \
- "lw $a1, 8(%1) \n\t" \
- "lw $a2, 12(%1) \n\t" \
- "lw $a3, 16(%1) \n\t" \
- "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ "sw $28, 0($29) \n\t" \
+ "sw $31, 4($29) \n\t" \
+ "lw $4, 20(%1) \n\t" \
+ "subu $29, $29, 24\n\t" \
+ "sw $4, 16($29) \n\t" \
+ "lw $4, 4(%1) \n\t" \
+ "lw $5, 8(%1) \n\t" \
+ "lw $6, 12(%1) \n\t" \
+ "lw $7, 16(%1) \n\t" \
+ "lw $25, 0(%1) \n\t" /* target->t9 */ \
VALGRIND_CALL_NOREDIR_T9 \
"addu $29, $29, 24 \n\t" \
- "lw $gp, 0($sp) \n\t" \
- "lw $ra, 4($sp) \n\t" \
- "addu $sp, $sp, 8 \n\t" \
- "move %0, $v0\n" \
+ "lw $28, 0($29) \n\t" \
+ "lw $31, 4($29) \n\t" \
+ "addu $29, $29, 8 \n\t" \
+ "move %0, $2\n" \
: /*out*/ "=r" (_res) \
: /*in*/ "0" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
lval = (__typeof__(lval)) _res; \
} while (0)
_argvec[6] = (unsigned long)(arg6); \
__asm__ volatile( \
"subu $29, $29, 8 \n\t" \
- "sw $gp, 0($sp) \n\t" \
- "sw $ra, 4($sp) \n\t" \
- "lw $a0, 20(%1) \n\t" \
- "subu $sp, $sp, 32\n\t" \
- "sw $a0, 16($sp) \n\t" \
- "lw $a0, 24(%1) \n\t" \
+ "sw $28, 0($29) \n\t" \
+ "sw $31, 4($29) \n\t" \
+ "lw $4, 20(%1) \n\t" \
+ "subu $29, $29, 32\n\t" \
+ "sw $4, 16($29) \n\t" \
+ "lw $4, 24(%1) \n\t" \
"nop\n\t" \
- "sw $a0, 20($sp) \n\t" \
- "lw $a0, 4(%1) \n\t" \
- "lw $a1, 8(%1) \n\t" \
- "lw $a2, 12(%1) \n\t" \
- "lw $a3, 16(%1) \n\t" \
- "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ "sw $4, 20($29) \n\t" \
+ "lw $4, 4(%1) \n\t" \
+ "lw $5, 8(%1) \n\t" \
+ "lw $6, 12(%1) \n\t" \
+ "lw $7, 16(%1) \n\t" \
+ "lw $25, 0(%1) \n\t" /* target->t9 */ \
VALGRIND_CALL_NOREDIR_T9 \
- "addu $sp, $sp, 32 \n\t" \
- "lw $gp, 0($sp) \n\t" \
- "lw $ra, 4($sp) \n\t" \
- "addu $sp, $sp, 8 \n\t" \
- "move %0, $v0\n" \
+ "addu $29, $29, 32 \n\t" \
+ "lw $28, 0($29) \n\t" \
+ "lw $31, 4($29) \n\t" \
+ "addu $29, $29, 8 \n\t" \
+ "move %0, $2\n" \
: /*out*/ "=r" (_res) \
: /*in*/ "0" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
lval = (__typeof__(lval)) _res; \
} while (0)
_argvec[7] = (unsigned long)(arg7); \
__asm__ volatile( \
"subu $29, $29, 8 \n\t" \
- "sw $gp, 0($sp) \n\t" \
- "sw $ra, 4($sp) \n\t" \
- "lw $a0, 20(%1) \n\t" \
- "subu $sp, $sp, 32\n\t" \
- "sw $a0, 16($sp) \n\t" \
- "lw $a0, 24(%1) \n\t" \
- "sw $a0, 20($sp) \n\t" \
- "lw $a0, 28(%1) \n\t" \
- "sw $a0, 24($sp) \n\t" \
- "lw $a0, 4(%1) \n\t" \
- "lw $a1, 8(%1) \n\t" \
- "lw $a2, 12(%1) \n\t" \
- "lw $a3, 16(%1) \n\t" \
- "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ "sw $28, 0($29) \n\t" \
+ "sw $31, 4($29) \n\t" \
+ "lw $4, 20(%1) \n\t" \
+ "subu $29, $29, 32\n\t" \
+ "sw $4, 16($29) \n\t" \
+ "lw $4, 24(%1) \n\t" \
+ "sw $4, 20($29) \n\t" \
+ "lw $4, 28(%1) \n\t" \
+ "sw $4, 24($29) \n\t" \
+ "lw $4, 4(%1) \n\t" \
+ "lw $5, 8(%1) \n\t" \
+ "lw $6, 12(%1) \n\t" \
+ "lw $7, 16(%1) \n\t" \
+ "lw $25, 0(%1) \n\t" /* target->t9 */ \
VALGRIND_CALL_NOREDIR_T9 \
- "addu $sp, $sp, 32 \n\t" \
- "lw $gp, 0($sp) \n\t" \
- "lw $ra, 4($sp) \n\t" \
- "addu $sp, $sp, 8 \n\t" \
- "move %0, $v0\n" \
+ "addu $29, $29, 32 \n\t" \
+ "lw $28, 0($29) \n\t" \
+ "lw $31, 4($29) \n\t" \
+ "addu $29, $29, 8 \n\t" \
+ "move %0, $2\n" \
: /*out*/ "=r" (_res) \
: /*in*/ "0" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
lval = (__typeof__(lval)) _res; \
} while (0)
_argvec[8] = (unsigned long)(arg8); \
__asm__ volatile( \
"subu $29, $29, 8 \n\t" \
- "sw $gp, 0($sp) \n\t" \
- "sw $ra, 4($sp) \n\t" \
- "lw $a0, 20(%1) \n\t" \
- "subu $sp, $sp, 40\n\t" \
- "sw $a0, 16($sp) \n\t" \
- "lw $a0, 24(%1) \n\t" \
- "sw $a0, 20($sp) \n\t" \
- "lw $a0, 28(%1) \n\t" \
- "sw $a0, 24($sp) \n\t" \
- "lw $a0, 32(%1) \n\t" \
- "sw $a0, 28($sp) \n\t" \
- "lw $a0, 4(%1) \n\t" \
- "lw $a1, 8(%1) \n\t" \
- "lw $a2, 12(%1) \n\t" \
- "lw $a3, 16(%1) \n\t" \
- "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ "sw $28, 0($29) \n\t" \
+ "sw $31, 4($29) \n\t" \
+ "lw $4, 20(%1) \n\t" \
+ "subu $29, $29, 40\n\t" \
+ "sw $4, 16($29) \n\t" \
+ "lw $4, 24(%1) \n\t" \
+ "sw $4, 20($29) \n\t" \
+ "lw $4, 28(%1) \n\t" \
+ "sw $4, 24($29) \n\t" \
+ "lw $4, 32(%1) \n\t" \
+ "sw $4, 28($29) \n\t" \
+ "lw $4, 4(%1) \n\t" \
+ "lw $5, 8(%1) \n\t" \
+ "lw $6, 12(%1) \n\t" \
+ "lw $7, 16(%1) \n\t" \
+ "lw $25, 0(%1) \n\t" /* target->t9 */ \
VALGRIND_CALL_NOREDIR_T9 \
- "addu $sp, $sp, 40 \n\t" \
- "lw $gp, 0($sp) \n\t" \
- "lw $ra, 4($sp) \n\t" \
- "addu $sp, $sp, 8 \n\t" \
- "move %0, $v0\n" \
+ "addu $29, $29, 40 \n\t" \
+ "lw $28, 0($29) \n\t" \
+ "lw $31, 4($29) \n\t" \
+ "addu $29, $29, 8 \n\t" \
+ "move %0, $2\n" \
: /*out*/ "=r" (_res) \
: /*in*/ "0" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
lval = (__typeof__(lval)) _res; \
} while (0)
_argvec[9] = (unsigned long)(arg9); \
__asm__ volatile( \
"subu $29, $29, 8 \n\t" \
- "sw $gp, 0($sp) \n\t" \
- "sw $ra, 4($sp) \n\t" \
- "lw $a0, 20(%1) \n\t" \
- "subu $sp, $sp, 40\n\t" \
- "sw $a0, 16($sp) \n\t" \
- "lw $a0, 24(%1) \n\t" \
- "sw $a0, 20($sp) \n\t" \
- "lw $a0, 28(%1) \n\t" \
- "sw $a0, 24($sp) \n\t" \
- "lw $a0, 32(%1) \n\t" \
- "sw $a0, 28($sp) \n\t" \
- "lw $a0, 36(%1) \n\t" \
- "sw $a0, 32($sp) \n\t" \
- "lw $a0, 4(%1) \n\t" \
- "lw $a1, 8(%1) \n\t" \
- "lw $a2, 12(%1) \n\t" \
- "lw $a3, 16(%1) \n\t" \
- "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ "sw $28, 0($29) \n\t" \
+ "sw $31, 4($29) \n\t" \
+ "lw $4, 20(%1) \n\t" \
+ "subu $29, $29, 40\n\t" \
+ "sw $4, 16($29) \n\t" \
+ "lw $4, 24(%1) \n\t" \
+ "sw $4, 20($29) \n\t" \
+ "lw $4, 28(%1) \n\t" \
+ "sw $4, 24($29) \n\t" \
+ "lw $4, 32(%1) \n\t" \
+ "sw $4, 28($29) \n\t" \
+ "lw $4, 36(%1) \n\t" \
+ "sw $4, 32($29) \n\t" \
+ "lw $4, 4(%1) \n\t" \
+ "lw $5, 8(%1) \n\t" \
+ "lw $6, 12(%1) \n\t" \
+ "lw $7, 16(%1) \n\t" \
+ "lw $25, 0(%1) \n\t" /* target->t9 */ \
VALGRIND_CALL_NOREDIR_T9 \
- "addu $sp, $sp, 40 \n\t" \
- "lw $gp, 0($sp) \n\t" \
- "lw $ra, 4($sp) \n\t" \
- "addu $sp, $sp, 8 \n\t" \
- "move %0, $v0\n" \
+ "addu $29, $29, 40 \n\t" \
+ "lw $28, 0($29) \n\t" \
+ "lw $31, 4($29) \n\t" \
+ "addu $29, $29, 8 \n\t" \
+ "move %0, $2\n" \
: /*out*/ "=r" (_res) \
: /*in*/ "0" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
lval = (__typeof__(lval)) _res; \
} while (0)
_argvec[10] = (unsigned long)(arg10); \
__asm__ volatile( \
"subu $29, $29, 8 \n\t" \
- "sw $gp, 0($sp) \n\t" \
- "sw $ra, 4($sp) \n\t" \
- "lw $a0, 20(%1) \n\t" \
- "subu $sp, $sp, 48\n\t" \
- "sw $a0, 16($sp) \n\t" \
- "lw $a0, 24(%1) \n\t" \
- "sw $a0, 20($sp) \n\t" \
- "lw $a0, 28(%1) \n\t" \
- "sw $a0, 24($sp) \n\t" \
- "lw $a0, 32(%1) \n\t" \
- "sw $a0, 28($sp) \n\t" \
- "lw $a0, 36(%1) \n\t" \
- "sw $a0, 32($sp) \n\t" \
- "lw $a0, 40(%1) \n\t" \
- "sw $a0, 36($sp) \n\t" \
- "lw $a0, 4(%1) \n\t" \
- "lw $a1, 8(%1) \n\t" \
- "lw $a2, 12(%1) \n\t" \
- "lw $a3, 16(%1) \n\t" \
- "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ "sw $28, 0($29) \n\t" \
+ "sw $31, 4($29) \n\t" \
+ "lw $4, 20(%1) \n\t" \
+ "subu $29, $29, 48\n\t" \
+ "sw $4, 16($29) \n\t" \
+ "lw $4, 24(%1) \n\t" \
+ "sw $4, 20($29) \n\t" \
+ "lw $4, 28(%1) \n\t" \
+ "sw $4, 24($29) \n\t" \
+ "lw $4, 32(%1) \n\t" \
+ "sw $4, 28($29) \n\t" \
+ "lw $4, 36(%1) \n\t" \
+ "sw $4, 32($29) \n\t" \
+ "lw $4, 40(%1) \n\t" \
+ "sw $4, 36($29) \n\t" \
+ "lw $4, 4(%1) \n\t" \
+ "lw $5, 8(%1) \n\t" \
+ "lw $6, 12(%1) \n\t" \
+ "lw $7, 16(%1) \n\t" \
+ "lw $25, 0(%1) \n\t" /* target->t9 */ \
VALGRIND_CALL_NOREDIR_T9 \
- "addu $sp, $sp, 48 \n\t" \
- "lw $gp, 0($sp) \n\t" \
- "lw $ra, 4($sp) \n\t" \
- "addu $sp, $sp, 8 \n\t" \
- "move %0, $v0\n" \
+ "addu $29, $29, 48 \n\t" \
+ "lw $28, 0($29) \n\t" \
+ "lw $31, 4($29) \n\t" \
+ "addu $29, $29, 8 \n\t" \
+ "move %0, $2\n" \
: /*out*/ "=r" (_res) \
: /*in*/ "0" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
lval = (__typeof__(lval)) _res; \
} while (0)
_argvec[11] = (unsigned long)(arg11); \
__asm__ volatile( \
"subu $29, $29, 8 \n\t" \
- "sw $gp, 0($sp) \n\t" \
- "sw $ra, 4($sp) \n\t" \
- "lw $a0, 20(%1) \n\t" \
- "subu $sp, $sp, 48\n\t" \
- "sw $a0, 16($sp) \n\t" \
- "lw $a0, 24(%1) \n\t" \
- "sw $a0, 20($sp) \n\t" \
- "lw $a0, 28(%1) \n\t" \
- "sw $a0, 24($sp) \n\t" \
- "lw $a0, 32(%1) \n\t" \
- "sw $a0, 28($sp) \n\t" \
- "lw $a0, 36(%1) \n\t" \
- "sw $a0, 32($sp) \n\t" \
- "lw $a0, 40(%1) \n\t" \
- "sw $a0, 36($sp) \n\t" \
- "lw $a0, 44(%1) \n\t" \
- "sw $a0, 40($sp) \n\t" \
- "lw $a0, 4(%1) \n\t" \
- "lw $a1, 8(%1) \n\t" \
- "lw $a2, 12(%1) \n\t" \
- "lw $a3, 16(%1) \n\t" \
- "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ "sw $28, 0($29) \n\t" \
+ "sw $31, 4($29) \n\t" \
+ "lw $4, 20(%1) \n\t" \
+ "subu $29, $29, 48\n\t" \
+ "sw $4, 16($29) \n\t" \
+ "lw $4, 24(%1) \n\t" \
+ "sw $4, 20($29) \n\t" \
+ "lw $4, 28(%1) \n\t" \
+ "sw $4, 24($29) \n\t" \
+ "lw $4, 32(%1) \n\t" \
+ "sw $4, 28($29) \n\t" \
+ "lw $4, 36(%1) \n\t" \
+ "sw $4, 32($29) \n\t" \
+ "lw $4, 40(%1) \n\t" \
+ "sw $4, 36($29) \n\t" \
+ "lw $4, 44(%1) \n\t" \
+ "sw $4, 40($29) \n\t" \
+ "lw $4, 4(%1) \n\t" \
+ "lw $5, 8(%1) \n\t" \
+ "lw $6, 12(%1) \n\t" \
+ "lw $7, 16(%1) \n\t" \
+ "lw $25, 0(%1) \n\t" /* target->t9 */ \
VALGRIND_CALL_NOREDIR_T9 \
- "addu $sp, $sp, 48 \n\t" \
- "lw $gp, 0($sp) \n\t" \
- "lw $ra, 4($sp) \n\t" \
- "addu $sp, $sp, 8 \n\t" \
- "move %0, $v0\n" \
+ "addu $29, $29, 48 \n\t" \
+ "lw $28, 0($29) \n\t" \
+ "lw $31, 4($29) \n\t" \
+ "addu $29, $29, 8 \n\t" \
+ "move %0, $2\n" \
: /*out*/ "=r" (_res) \
: /*in*/ "0" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
lval = (__typeof__(lval)) _res; \
} while (0)
_argvec[12] = (unsigned long)(arg12); \
__asm__ volatile( \
"subu $29, $29, 8 \n\t" \
- "sw $gp, 0($sp) \n\t" \
- "sw $ra, 4($sp) \n\t" \
- "lw $a0, 20(%1) \n\t" \
- "subu $sp, $sp, 56\n\t" \
- "sw $a0, 16($sp) \n\t" \
- "lw $a0, 24(%1) \n\t" \
- "sw $a0, 20($sp) \n\t" \
- "lw $a0, 28(%1) \n\t" \
- "sw $a0, 24($sp) \n\t" \
- "lw $a0, 32(%1) \n\t" \
- "sw $a0, 28($sp) \n\t" \
- "lw $a0, 36(%1) \n\t" \
- "sw $a0, 32($sp) \n\t" \
- "lw $a0, 40(%1) \n\t" \
- "sw $a0, 36($sp) \n\t" \
- "lw $a0, 44(%1) \n\t" \
- "sw $a0, 40($sp) \n\t" \
- "lw $a0, 48(%1) \n\t" \
- "sw $a0, 44($sp) \n\t" \
- "lw $a0, 4(%1) \n\t" \
- "lw $a1, 8(%1) \n\t" \
- "lw $a2, 12(%1) \n\t" \
- "lw $a3, 16(%1) \n\t" \
- "lw $t9, 0(%1) \n\t" /* target->t9 */ \
+ "sw $28, 0($29) \n\t" \
+ "sw $31, 4($29) \n\t" \
+ "lw $4, 20(%1) \n\t" \
+ "subu $29, $29, 56\n\t" \
+ "sw $4, 16($29) \n\t" \
+ "lw $4, 24(%1) \n\t" \
+ "sw $4, 20($29) \n\t" \
+ "lw $4, 28(%1) \n\t" \
+ "sw $4, 24($29) \n\t" \
+ "lw $4, 32(%1) \n\t" \
+ "sw $4, 28($29) \n\t" \
+ "lw $4, 36(%1) \n\t" \
+ "sw $4, 32($29) \n\t" \
+ "lw $4, 40(%1) \n\t" \
+ "sw $4, 36($29) \n\t" \
+ "lw $4, 44(%1) \n\t" \
+ "sw $4, 40($29) \n\t" \
+ "lw $4, 48(%1) \n\t" \
+ "sw $4, 44($29) \n\t" \
+ "lw $4, 4(%1) \n\t" \
+ "lw $5, 8(%1) \n\t" \
+ "lw $6, 12(%1) \n\t" \
+ "lw $7, 16(%1) \n\t" \
+ "lw $25, 0(%1) \n\t" /* target->t9 */ \
VALGRIND_CALL_NOREDIR_T9 \
- "addu $sp, $sp, 56 \n\t" \
- "lw $gp, 0($sp) \n\t" \
- "lw $ra, 4($sp) \n\t" \
- "addu $sp, $sp, 8 \n\t" \
- "move %0, $v0\n" \
+ "addu $29, $29, 56 \n\t" \
+ "lw $28, 0($29) \n\t" \
+ "lw $31, 4($29) \n\t" \
+ "addu $29, $29, 8 \n\t" \
+ "move %0, $2\n" \
: /*out*/ "=r" (_res) \
- : /*in*/ "0" (&_argvec[0]) \
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
); \
lval = (__typeof__(lval)) _res; \
} while (0)
#endif /* PLAT_mips32_linux */
+/* ------------------------- mips64-linux ------------------------- */
+
+#if defined(PLAT_mips64_linux)
+
+/* These regs are trashed by the hidden call. */
+#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6", \
+"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+"$25", "$31"
+
+/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned
+ long) == 4. */
+
+#define CALL_FN_W_v(lval, orig) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[1]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ __asm__ volatile( \
+ "ld $25, 0(%1)\n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "move %0, $2\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "0" (&_argvec[0]) \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_W(lval, orig, arg1) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[2]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ __asm__ volatile( \
+ "ld $4, 8(%1)\n\t" /* arg1*/ \
+ "ld $25, 0(%1)\n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "move %0, $2\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WW(lval, orig, arg1,arg2) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[3]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ __asm__ volatile( \
+ "ld $4, 8(%1)\n\t" \
+ "ld $5, 16(%1)\n\t" \
+ "ld $25, 0(%1)\n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "move %0, $2\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[4]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ __asm__ volatile( \
+ "ld $4, 8(%1)\n\t" \
+ "ld $5, 16(%1)\n\t" \
+ "ld $6, 24(%1)\n\t" \
+ "ld $25, 0(%1)\n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "move %0, $2\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[5]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ __asm__ volatile( \
+ "ld $4, 8(%1)\n\t" \
+ "ld $5, 16(%1)\n\t" \
+ "ld $6, 24(%1)\n\t" \
+ "ld $7, 32(%1)\n\t" \
+ "ld $25, 0(%1)\n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "move %0, $2\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[6]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ __asm__ volatile( \
+ "ld $4, 8(%1)\n\t" \
+ "ld $5, 16(%1)\n\t" \
+ "ld $6, 24(%1)\n\t" \
+ "ld $7, 32(%1)\n\t" \
+ "ld $8, 40(%1)\n\t" \
+ "ld $25, 0(%1)\n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "move %0, $2\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[7]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ __asm__ volatile( \
+ "ld $4, 8(%1)\n\t" \
+ "ld $5, 16(%1)\n\t" \
+ "ld $6, 24(%1)\n\t" \
+ "ld $7, 32(%1)\n\t" \
+ "ld $8, 40(%1)\n\t" \
+ "ld $9, 48(%1)\n\t" \
+ "ld $25, 0(%1)\n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "move %0, $2\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[8]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ __asm__ volatile( \
+ "ld $4, 8(%1)\n\t" \
+ "ld $5, 16(%1)\n\t" \
+ "ld $6, 24(%1)\n\t" \
+ "ld $7, 32(%1)\n\t" \
+ "ld $8, 40(%1)\n\t" \
+ "ld $9, 48(%1)\n\t" \
+ "ld $10, 56(%1)\n\t" \
+ "ld $25, 0(%1) \n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "move %0, $2\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[9]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ __asm__ volatile( \
+ "ld $4, 8(%1)\n\t" \
+ "ld $5, 16(%1)\n\t" \
+ "ld $6, 24(%1)\n\t" \
+ "ld $7, 32(%1)\n\t" \
+ "ld $8, 40(%1)\n\t" \
+ "ld $9, 48(%1)\n\t" \
+ "ld $10, 56(%1)\n\t" \
+ "ld $11, 64(%1)\n\t" \
+ "ld $25, 0(%1) \n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "move %0, $2\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[10]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ __asm__ volatile( \
+ "dsubu $29, $29, 8\n\t" \
+ "ld $4, 72(%1)\n\t" \
+ "sd $4, 0($29)\n\t" \
+ "ld $4, 8(%1)\n\t" \
+ "ld $5, 16(%1)\n\t" \
+ "ld $6, 24(%1)\n\t" \
+ "ld $7, 32(%1)\n\t" \
+ "ld $8, 40(%1)\n\t" \
+ "ld $9, 48(%1)\n\t" \
+ "ld $10, 56(%1)\n\t" \
+ "ld $11, 64(%1)\n\t" \
+ "ld $25, 0(%1)\n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "daddu $29, $29, 8\n\t" \
+ "move %0, $2\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
+ arg7,arg8,arg9,arg10) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[11]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ _argvec[10] = (unsigned long)(arg10); \
+ __asm__ volatile( \
+ "dsubu $29, $29, 16\n\t" \
+ "ld $4, 72(%1)\n\t" \
+ "sd $4, 0($29)\n\t" \
+ "ld $4, 80(%1)\n\t" \
+ "sd $4, 8($29)\n\t" \
+ "ld $4, 8(%1)\n\t" \
+ "ld $5, 16(%1)\n\t" \
+ "ld $6, 24(%1)\n\t" \
+ "ld $7, 32(%1)\n\t" \
+ "ld $8, 40(%1)\n\t" \
+ "ld $9, 48(%1)\n\t" \
+ "ld $10, 56(%1)\n\t" \
+ "ld $11, 64(%1)\n\t" \
+ "ld $25, 0(%1)\n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "daddu $29, $29, 16\n\t" \
+ "move %0, $2\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
+ arg6,arg7,arg8,arg9,arg10, \
+ arg11) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[12]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ _argvec[10] = (unsigned long)(arg10); \
+ _argvec[11] = (unsigned long)(arg11); \
+ __asm__ volatile( \
+ "dsubu $29, $29, 24\n\t" \
+ "ld $4, 72(%1)\n\t" \
+ "sd $4, 0($29)\n\t" \
+ "ld $4, 80(%1)\n\t" \
+ "sd $4, 8($29)\n\t" \
+ "ld $4, 88(%1)\n\t" \
+ "sd $4, 16($29)\n\t" \
+ "ld $4, 8(%1)\n\t" \
+ "ld $5, 16(%1)\n\t" \
+ "ld $6, 24(%1)\n\t" \
+ "ld $7, 32(%1)\n\t" \
+ "ld $8, 40(%1)\n\t" \
+ "ld $9, 48(%1)\n\t" \
+ "ld $10, 56(%1)\n\t" \
+ "ld $11, 64(%1)\n\t" \
+ "ld $25, 0(%1)\n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "daddu $29, $29, 24\n\t" \
+ "move %0, $2\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
+ arg6,arg7,arg8,arg9,arg10, \
+ arg11,arg12) \
+ do { \
+ volatile OrigFn _orig = (orig); \
+ volatile unsigned long _argvec[13]; \
+ volatile unsigned long _res; \
+ _argvec[0] = (unsigned long)_orig.nraddr; \
+ _argvec[1] = (unsigned long)(arg1); \
+ _argvec[2] = (unsigned long)(arg2); \
+ _argvec[3] = (unsigned long)(arg3); \
+ _argvec[4] = (unsigned long)(arg4); \
+ _argvec[5] = (unsigned long)(arg5); \
+ _argvec[6] = (unsigned long)(arg6); \
+ _argvec[7] = (unsigned long)(arg7); \
+ _argvec[8] = (unsigned long)(arg8); \
+ _argvec[9] = (unsigned long)(arg9); \
+ _argvec[10] = (unsigned long)(arg10); \
+ _argvec[11] = (unsigned long)(arg11); \
+ _argvec[12] = (unsigned long)(arg12); \
+ __asm__ volatile( \
+ "dsubu $29, $29, 32\n\t" \
+ "ld $4, 72(%1)\n\t" \
+ "sd $4, 0($29)\n\t" \
+ "ld $4, 80(%1)\n\t" \
+ "sd $4, 8($29)\n\t" \
+ "ld $4, 88(%1)\n\t" \
+ "sd $4, 16($29)\n\t" \
+ "ld $4, 96(%1)\n\t" \
+ "sd $4, 24($29)\n\t" \
+ "ld $4, 8(%1)\n\t" \
+ "ld $5, 16(%1)\n\t" \
+ "ld $6, 24(%1)\n\t" \
+ "ld $7, 32(%1)\n\t" \
+ "ld $8, 40(%1)\n\t" \
+ "ld $9, 48(%1)\n\t" \
+ "ld $10, 56(%1)\n\t" \
+ "ld $11, 64(%1)\n\t" \
+ "ld $25, 0(%1)\n\t" /* target->t9 */ \
+ VALGRIND_CALL_NOREDIR_T9 \
+ "daddu $29, $29, 32\n\t" \
+ "move %0, $2\n" \
+ : /*out*/ "=r" (_res) \
+ : /*in*/ "r" (&_argvec[0]) \
+ : /*trash*/ "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval = (__typeof__(lval)) _res; \
+ } while (0)
+
+#endif /* PLAT_mips64_linux */
+
/* ------------------------------------------------------------------ */
/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */
#undef PLAT_arm_linux
#undef PLAT_s390x_linux
#undef PLAT_mips32_linux
+#undef PLAT_mips64_linux
#endif /* __VALGRIND_H */
# include "vki-posixtypes-s390x-linux.h"
#elif defined(VGA_mips32)
# include "vki-posixtypes-mips32-linux.h"
+#elif defined(VGA_mips64)
+# include "vki-posixtypes-mips64-linux.h"
#else
# error Unknown platform
#endif
# include "vki-s390x-linux.h"
#elif defined(VGA_mips32)
# include "vki-mips32-linux.h"
+#elif defined(VGA_mips64)
+# include "vki-mips64-linux.h"
#else
# error Unknown platform
#endif
--- /dev/null
+
+/*--------------------------------------------------------------------*/
+/*--- mips/Linux-specific kernel interface. vki-mips64-linux.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2010-2013 RT-RK
+ mips-valgrind@rt-rk.com
+
+ 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.
+*/
+
+#ifndef __VKI_MIPS64_LINUX_H
+#define __VKI_MIPS64_LINUX_H
+
+#include <config.h>
+
+// mips endian
+#if defined (_MIPSEL)
+#define VKI_LITTLE_ENDIAN 1
+#elif defined (_MIPSEB)
+#define VKI_BIG_ENDIAN 1
+#endif
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/cachectl.h
+//----------------------------------------------------------------------
+
+#define VKI_ICACHE (1<<0) /* flush instruction cache */
+#define VKI_DCACHE (1<<1) /* writeback and flush data cache */
+#define VKI_BCACHE (VKI_ICACHE | VKI_DCACHE) /* flush both caches */
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/mips-mips/types.h
+//----------------------------------------------------------------------
+
+typedef __signed__ char __vki_s8;
+typedef unsigned char __vki_u8;
+
+typedef __signed__ short __vki_s16;
+typedef unsigned short __vki_u16;
+
+typedef __signed__ int __vki_s32;
+typedef unsigned int __vki_u32;
+
+typedef __signed char vki_s8;
+typedef unsigned char vki_u8;
+
+typedef __signed short vki_s16;
+typedef unsigned short vki_u16;
+
+typedef __signed int vki_s32;
+typedef unsigned int vki_u32;
+
+#if (_MIPS_SZLONG == 64)
+typedef __signed__ long __vki_s64;
+typedef unsigned long __vki_u64;
+#else
+typedef __signed__ long long __vki_s64;
+typedef unsigned long long __vki_u64;
+#endif
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/page.h
+//----------------------------------------------------------------------
+
+/* PAGE_SHIFT determines the page size */
+#define VKI_PAGE_SHIFT MIPS_PAGE_SHIFT
+#define VKI_PAGE_SIZE (1UL << VKI_PAGE_SHIFT)
+#define VKI_PAGE_MASK (~(VKI_PAGE_SIZE-1))
+#define VKI_MAX_PAGE_SHIFT VKI_PAGE_SHIFT
+#define VKI_MAX_PAGE_SIZE VKI_PAGE_SIZE
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/arch/mips/include/asm/shmparam.h
+//----------------------------------------------------------------------
+
+#define VKI_SHMLBA VKI_PAGE_SIZE
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/signal.h
+//----------------------------------------------------------------------
+
+#define VKI_MINSIGSTKSZ 2048
+
+#define VKI_SIG_BLOCK 1 /* for blocking signals */
+#define VKI_SIG_UNBLOCK 2 /* for unblocking signals */
+#define VKI_SIG_SETMASK 3 /* for setting the signal mask */
+
+/* Type of a signal handler. */
+typedef void __vki_signalfn_t(int);
+typedef __vki_signalfn_t __user *__vki_sighandler_t;
+
+typedef void __vki_restorefn_t(void);
+typedef __vki_restorefn_t __user *__vki_sigrestore_t;
+
+#define VKI_SIG_DFL ((__vki_sighandler_t)0) /* default signal handling */
+#define VKI_SIG_IGN ((__vki_sighandler_t)1) /* ignore signal */
+#define VKI_SIG_ERR ((__vki_sighandler_t)-1) /* error return from signal */
+
+#define _VKI_NSIG 128
+#define _VKI_NSIG_BPW 64
+#define _VKI_NSIG_WORDS (_VKI_NSIG / _VKI_NSIG_BPW)
+
+typedef unsigned long vki_old_sigset_t; /* at least 32 bits */
+
+typedef struct {
+ unsigned long sig[_VKI_NSIG_WORDS];
+} vki_sigset_t;
+
+#define VKI_SIGHUP 1 /* Hangup (POSIX). */
+#define VKI_SIGINT 2 /* Interrupt (ANSI). */
+#define VKI_SIGQUIT 3 /* Quit (POSIX). */
+#define VKI_SIGILL 4 /* Illegal instruction (ANSI). */
+#define VKI_SIGTRAP 5 /* Trace trap (POSIX). */
+#define VKI_SIGIOT 6 /* IOT trap (4.2 BSD). */
+#define VKI_SIGABRT VKI_SIGIOT /* Abort (ANSI). */
+#define VKI_SIGEMT 7
+#define VKI_SIGFPE 8 /* Floating-point exception (ANSI). */
+#define VKI_SIGKILL 9 /* Kill, unblockable (POSIX). */
+#define VKI_SIGBUS 10 /* BUS error (4.2 BSD). */
+#define VKI_SIGSEGV 11 /* Segmentation violation (ANSI). */
+#define VKI_SIGSYS 12
+#define VKI_SIGPIPE 13 /* Broken pipe (POSIX). */
+#define VKI_SIGALRM 14 /* Alarm clock (POSIX). */
+#define VKI_SIGTERM 15 /* Termination (ANSI). */
+#define VKI_SIGUSR1 16 /* User-defined signal 1 (POSIX). */
+#define VKI_SIGUSR2 17 /* User-defined signal 2 (POSIX). */
+#define VKI_SIGCHLD 18 /* Child status has changed (POSIX). */
+#define VKI_SIGCLD VKI_SIGCHLD /* Same as SIGCHLD (System V). */
+#define VKI_SIGPWR 19 /* Power failure restart (System V). */
+#define VKI_SIGWINCH 20 /* Window size change (4.3 BSD, Sun). */
+#define VKI_SIGURG 21 /* Urgent condition on socket. */
+#define VKI_SIGIO 22 /* I/O now possible (4.2 BSD). */
+#define VKI_SIGPOLL VKI_SIGIO /* Pollable event occurred (System V).*/
+#define VKI_SIGSTOP 23 /* Stop, unblockable (POSIX). */
+#define VKI_SIGTSTP 24 /* Keyboard stop (POSIX). */
+#define VKI_SIGCONT 25 /* Continue (POSIX). */
+#define VKI_SIGTTIN 26 /* Background read from tty (POSIX). */
+#define VKI_SIGTTOU 27 /* Background write to tty (POSIX). */
+#define VKI_SIGVTALRM 28 /* Virtual alarm clock (4.2 BSD). */
+#define VKI_SIGPROF 29 /* Profiling alarm clock (4.2 BSD). */
+#define VKI_SIGXCPU 30 /* CPU limit exceeded (4.2 BSD). */
+#define VKI_SIGXFSZ 31 /* File size limit exceeded (4.2 BSD).*/
+
+/* These should not be considered constants from userland. */
+#define VKI_SIGRTMIN 32
+// [[This was (_NSIG-1) in 2.4.X... not sure if it matters.]]
+#define VKI_SIGRTMAX (_VKI_NSIG - 1)
+
+#define VKI_SA_ONSTACK 0x08000000u
+#define VKI_SA_RESETHAND 0x80000000u
+#define VKI_SA_RESTART 0x10000000u
+#define VKI_SA_SIGINFO 0x00000008u
+#define VKI_SA_NODEFER 0x40000000u
+#define VKI_SA_NOCLDWAIT 0x00010000u
+#define VKI_SA_NOCLDSTOP 0x00000001u
+
+#define VKI_SA_NOMASK VKI_SA_NODEFER
+#define VKI_SA_ONESHOT VKI_SA_RESETHAND
+//#define VKI_SA_INTERRUPT 0x20000000 /* dummy -- ignored */
+
+#define VKI_SA_RESTORER 0x04000000
+
+#define VKI_SS_ONSTACK 1
+#define VKI_SS_DISABLE 2
+
+struct vki_old_sigaction {
+ // [[Nb: a 'k' prefix is added to "sa_handler" because
+ // bits/sigaction.h (which gets dragged in somehow via signal.h)
+ // #defines it as something else. Since that is done for glibc's
+ // purposes, which we don't care about here, we use our own name.]]
+ unsigned long sa_flags;
+ __vki_sighandler_t ksa_handler;
+ vki_old_sigset_t sa_mask;
+ __vki_sigrestore_t sa_restorer;
+};
+
+struct vki_sigaction {
+ unsigned int sa_flags;
+ __vki_sighandler_t sa_handler;
+ vki_sigset_t sa_mask;
+};
+
+
+struct vki_sigaction_base {
+ // [[See comment about extra 'k' above]]
+ unsigned int sa_flags;
+ __vki_sighandler_t ksa_handler;
+ vki_sigset_t sa_mask; // mask last for extensibility
+ __vki_sigrestore_t sa_restorer;
+};
+
+/* On Linux we use the same type for passing sigactions to
+ and from the kernel. Hence: */
+typedef struct vki_sigaction_base vki_sigaction_toK_t;
+typedef struct vki_sigaction_base vki_sigaction_fromK_t;
+
+typedef struct vki_sigaltstack {
+ void __user *ss_sp;
+ vki_size_t ss_size;
+ int ss_flags;
+} vki_stack_t;
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/sigcontext.h
+//----------------------------------------------------------------------
+
+struct _vki_fpreg {
+ unsigned short significand[4];
+ unsigned short exponent;
+};
+
+struct _vki_fpxreg {
+ unsigned short significand[4];
+ unsigned short exponent;
+ unsigned short padding[3];
+};
+
+struct _vki_xmmreg {
+ unsigned long element[4];
+};
+
+struct _vki_fpstate {
+ /* Regular FPU environment */
+ unsigned long cw;
+ unsigned long sw;
+ unsigned long tag;
+ unsigned long ipoff;
+ unsigned long cssel;
+ unsigned long dataoff;
+ unsigned long datasel;
+ struct _vki_fpreg _st[8];
+ unsigned short status;
+ unsigned short magic; /* 0xffff = regular FPU data only */
+
+ /* FXSR FPU environment */
+ unsigned long _fxsr_env[6]; /* FXSR FPU env is ignored */
+ unsigned long mxcsr;
+ unsigned long reserved;
+ struct _vki_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
+ struct _vki_xmmreg _xmm[8];
+ unsigned long padding[56];
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/sigcontext.h
+//----------------------------------------------------------------------
+struct vki_sigcontext {
+ __vki_u64 sc_regs[32];
+ __vki_u64 sc_fpregs[32];
+ __vki_u64 sc_mdhi;
+ __vki_u64 sc_hi1;
+ __vki_u64 sc_hi2;
+ __vki_u64 sc_hi3;
+ __vki_u64 sc_mdlo;
+ __vki_u64 sc_lo1;
+ __vki_u64 sc_lo2;
+ __vki_u64 sc_lo3;
+ __vki_u64 sc_pc;
+ __vki_u64 sc_fpc_csr;
+ __vki_u64 sc_used_math;
+ __vki_u64 sc_dsp;
+ __vki_u64 sc_reserved;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/mman.h
+//----------------------------------------------------------------------
+
+#define VKI_PROT_NONE 0x0 /* No page permissions */
+#define VKI_PROT_READ 0x1 /* page can be read */
+#define VKI_PROT_WRITE 0x2 /* page can be written */
+#define VKI_PROT_EXEC 0x4 /* page can be executed */
+#define VKI_PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start
+ of growsdown vma */
+#define VKI_PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end
+ of growsup vma */
+
+#define VKI_MAP_SHARED 0x001 /* Share changes */
+#define VKI_MAP_PRIVATE 0x002 /* Changes are private */
+//#define VKI_MAP_TYPE 0x0f /* Mask for type of mapping */
+#define VKI_MAP_FIXED 0x010 /* Interpret addr exactly */
+
+#define VKI_MAP_NORESERVE 0x0400 /* don't reserve swap pages */
+
+/* These are linux-specific */
+#define VKI_MAP_NORESERVE 0x0400 /* don't check for reservations */
+#define VKI_MAP_ANONYMOUS 0x0800 /* don't use a file */
+#define VKI_MAP_GROWSDOWN 0x1000 /* stack-like segment */
+#define VKI_MAP_DENYWRITE 0x2000 /* ETXTBSY */
+#define VKI_MAP_EXECUTABLE 0x4000 /* mark it as an executable */
+#define VKI_MAP_LOCKED 0x8000 /* pages are locked */
+#define VKI_MAP_POPULATE 0x10000 /* populate (prefault) pagetables */
+#define VKI_MAP_NONBLOCK 0x20000 /* do not block on IO */
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/fcntl.h
+//----------------------------------------------------------------------
+
+#define VKI_O_RDONLY 00
+#define VKI_O_WRONLY 01
+#define VKI_O_RDWR 02
+#define VKI_O_ACCMODE 03
+
+#define VKI_O_CREAT 0x0100 /* not fcntl */
+#define VKI_O_EXCL 0x0400 /* not fcntl */
+
+#define VKI_O_TRUNC 0x0200 /* not fcntl */
+
+#define VKI_O_APPEND 0x0008
+#define VKI_O_NONBLOCK 0x0080
+#define VKI_O_LARGEFILE 0x2000
+
+#define VKI_AT_FDCWD -100
+
+#define VKI_F_DUPFD 0 /* dup */
+#define VKI_F_GETFD 1 /* get close_on_exec */
+#define VKI_F_SETFD 2 /* set/clear close_on_exec */
+#define VKI_F_GETFL 3 /* get file->f_flags */
+#define VKI_F_SETFL 4 /* set file->f_flags */
+
+#define VKI_F_GETLK 14
+#define VKI_F_SETLK 6
+#define VKI_F_SETLKW 7
+
+#define VKI_F_SETOWN 24 /* for sockets. */
+#define VKI_F_GETOWN 23 /* for sockets. */
+#define VKI_F_SETSIG 10 /* for sockets. */
+#define VKI_F_GETSIG 11 /* for sockets. */
+
+#define VKI_F_SETOWN_EX 15
+#define VKI_F_GETOWN_EX 16
+
+#define VKI_F_GETLK64 33 /* using 'struct flock64' */
+#define VKI_F_SETLK64 34
+#define VKI_F_SETLKW64 35
+
+/* for F_[GET|SET]FL */
+#define VKI_FD_CLOEXEC 1 /* actually anything with low bit set goes */
+
+#define VKI_F_LINUX_SPECIFIC_BASE 1024
+
+struct vki_f_owner_ex {
+ int type;
+ __vki_kernel_pid_t pid;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/resource.h
+//----------------------------------------------------------------------
+
+#define VKI_RLIMIT_DATA 2 /* max data size */
+#define VKI_RLIMIT_STACK 3 /* max stack size */
+#define VKI_RLIMIT_CORE 4 /* max core file size */
+#define VKI_RLIMIT_NOFILE 5 /* max number of open files */
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/socket.h
+//----------------------------------------------------------------------
+
+#define VKI_SOL_SOCKET 0xffff
+#define VKI_SO_TYPE 0x1008
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-i386/sockios.h
+//----------------------------------------------------------------------
+
+#define VKI_SIOCSPGRP 0x8902
+#define VKI_SIOCGPGRP 0x8904
+#define VKI_SIOCGSTAMP 0x8906 /* Get stamp (timeval) */
+#define VKI_SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/stat.h
+//----------------------------------------------------------------------
+
+struct vki_stat {
+ unsigned int st_dev;
+ unsigned int st_pad0[3]; /* Reserved for st_dev expansion */
+
+ unsigned long st_ino;
+
+ int st_mode;
+ unsigned int st_nlink;
+
+ unsigned int st_uid;
+ unsigned int st_gid;
+
+ unsigned int st_rdev;
+ unsigned int st_pad1[3]; /* Reserved for st_rdev expansion */
+
+ long st_size;
+
+ /*
+ * Actually this should be timestruc_t st_atime, st_mtime and st_ctime
+ * but we don't have it under Linux.
+ */
+ unsigned int st_atime;
+ unsigned int st_atime_nsec; /* Reserved for st_atime expansion */
+
+ unsigned int st_mtime;
+ unsigned int st_mtime_nsec; /* Reserved for st_mtime expansion */
+
+ unsigned int st_ctime;
+ unsigned int st_ctime_nsec; /* Reserved for st_ctime expansion */
+
+ unsigned int st_blksize;
+ unsigned int st_pad2;
+
+ long long st_blocks;
+};
+
+struct vki_stat64 {
+ unsigned long st_dev;
+ unsigned long st_pad0[3]; /* Reserved for st_dev expansion */
+
+ unsigned long long st_ino;
+
+ int st_mode;
+ unsigned int st_nlink;
+
+ unsigned int st_uid;
+ unsigned int st_gid;
+
+ unsigned long st_rdev;
+ unsigned long st_pad1[3]; /* Reserved for st_rdev expansion */
+
+ long long st_size;
+
+ /*
+ * Actually this should be timestruc_t st_atime, st_mtime and st_ctime
+ * but we don't have it under Linux.
+ */
+ unsigned long st_atime;
+ unsigned long st_atime_nsec; /* Reserved for st_atime expansion */
+
+ unsigned long st_mtime;
+ unsigned long st_mtime_nsec; /* Reserved for st_mtime expansion */
+
+ unsigned long st_ctime;
+ unsigned long st_ctime_nsec; /* Reserved for st_ctime expansion */
+
+ unsigned long st_blksize;
+ unsigned long st_pad2;
+
+ long long st_blocks;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/statfs.h
+//----------------------------------------------------------------------
+
+struct vki_statfs {
+ __vki_u32 f_type;
+#define f_fstyp f_type
+ __vki_u32 f_bsize;
+ __vki_u32 f_frsize;
+ __vki_u32 f_blocks;
+ __vki_u32 f_bfree;
+ __vki_u32 f_files;
+ __vki_u32 f_ffree;
+ __vki_u32 f_bavail;
+ __vki_kernel_fsid_t f_fsid;
+ __vki_u32 f_namelen;
+ __vki_u32 f_spare[6];
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/termios.h
+//----------------------------------------------------------------------
+
+struct vki_winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define NCC 8
+#define NCCS 23
+struct vki_termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ char c_line; /* line discipline */
+ unsigned char c_cc[NCCS]; /* control characters */
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/termbits.h
+//----------------------------------------------------------------------
+
+typedef unsigned char vki_cc_t;
+typedef unsigned long vki_speed_t;
+typedef unsigned long vki_tcflag_t;
+
+struct vki_termios {
+ vki_tcflag_t c_iflag; /* input mode flags */
+ vki_tcflag_t c_oflag; /* output mode flags */
+ vki_tcflag_t c_cflag; /* control mode flags */
+ vki_tcflag_t c_lflag; /* local mode flags */
+ vki_cc_t c_line; /* line discipline */
+ vki_cc_t c_cc[NCCS]; /* control characters */
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/ioctl.h
+//----------------------------------------------------------------------
+
+#define _VKI_IOC_NRBITS 8
+#define _VKI_IOC_TYPEBITS 8
+#define _VKI_IOC_SIZEBITS 14
+#define _VKI_IOC_DIRBITS 2
+
+#define _VKI_IOC_NRMASK ((1 << _VKI_IOC_NRBITS)-1)
+#define _VKI_IOC_TYPEMASK ((1 << _VKI_IOC_TYPEBITS)-1)
+#define _VKI_IOC_SIZEMASK ((1 << _VKI_IOC_SIZEBITS)-1)
+#define _VKI_IOC_DIRMASK ((1 << _VKI_IOC_DIRBITS)-1)
+
+#define _VKI_IOC_NRSHIFT 0
+#define _VKI_IOC_TYPESHIFT (_VKI_IOC_NRSHIFT+_VKI_IOC_NRBITS)
+#define _VKI_IOC_SIZESHIFT (_VKI_IOC_TYPESHIFT+_VKI_IOC_TYPEBITS)
+#define _VKI_IOC_DIRSHIFT (_VKI_IOC_SIZESHIFT+_VKI_IOC_SIZEBITS)
+
+#define _VKI_IOC_NONE 1U
+#define _VKI_IOC_WRITE 2U
+#define _VKI_IOC_READ 4U
+
+#define _VKI_IOC(dir,type,nr,size) \
+ (((dir) << _VKI_IOC_DIRSHIFT) | \
+ ((type) << _VKI_IOC_TYPESHIFT) | \
+ ((nr) << _VKI_IOC_NRSHIFT) | \
+ ((size) << _VKI_IOC_SIZESHIFT))
+
+/* provoke compile error for invalid uses of size argument */
+extern unsigned int __VKI_invalid_size_argument_for_IOC;
+/* used to create numbers */
+#define _VKI_IO(type,nr) _VKI_IOC(_VKI_IOC_NONE,(type),(nr),0)
+#define _VKI_IOR(type,nr,size) _VKI_IOC(_VKI_IOC_READ,(type),(nr), \
+ (_VKI_IOC_TYPECHECK(size)))
+#define _VKI_IOW(type,nr,size) _VKI_IOC(_VKI_IOC_WRITE,(type),(nr), \
+ (_VKI_IOC_TYPECHECK(size)))
+#define _VKI_IOWR(type,nr,size) _VKI_IOC(_VKI_IOC_READ|_VKI_IOC_WRITE,(type), \
+ (nr),(_VKI_IOC_TYPECHECK(size)))
+
+/* used to decode ioctl numbers.. */
+#define _VKI_IOC_DIR(nr) (((nr) >> _VKI_IOC_DIRSHIFT) & _VKI_IOC_DIRMASK)
+#define _VKI_IOC_TYPE(nr) (((nr) >> _VKI_IOC_TYPESHIFT) & _VKI_IOC_TYPEMASK)
+#define _VKI_IOC_NR(nr) (((nr) >> _VKI_IOC_NRSHIFT) & _VKI_IOC_NRMASK)
+#define _VKI_IOC_SIZE(nr) (((nr) >> _VKI_IOC_SIZESHIFT) & _VKI_IOC_SIZEMASK)
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/ioctls.h
+//----------------------------------------------------------------------
+
+#define VKI_TCGETA 0x5401
+#define VKI_TCSETA 0x5402 /* Clashes with SNDCTL_TMR_START
+ sound ioctl */
+#define VKI_TCSETAW 0x5403
+#define VKI_TCSETAF 0x5404
+
+#define VKI_TCSBRK 0x5405
+#define VKI_TCXONC 0x5406
+#define VKI_TCFLSH 0x5407
+
+#define VKI_TCGETS 0x540d
+#define VKI_TCSETS 0x540e
+#define VKI_TCSETSW 0x540f
+#define VKI_TCSETSF 0x5410
+
+#define VKI_TIOCEXCL 0x740d /* set exclusive use of tty */
+#define VKI_TIOCNXCL 0x740e /* reset exclusive use of tty */
+#define VKI_TIOCOUTQ 0x7472 /* output queue size */
+#define VKI_TIOCSTI 0x5472 /* simulate terminal input */
+#define VKI_TIOCMGET 0x741d /* get all modem bits */
+#define VKI_TIOCMBIS 0x741b /* bis modem bits */
+#define VKI_TIOCMBIC 0x741c /* bic modem bits */
+#define VKI_TIOCMSET 0x741a /* set all modem bits */
+#define VKI_TIOCPKT 0x5470 /* pty: set/clear packet mode */
+#define VKI_TIOCPKT_DATA 0x00 /* data packet */
+#define VKI_TIOCPKT_FLUSHREAD 0x01 /* flush packet */
+#define VKI_TIOCPKT_FLUSHWRITE 0x02 /* flush packet */
+#define VKI_TIOCPKT_STOP 0x04 /* stop output */
+#define VKI_TIOCPKT_START 0x08 /* start output */
+#define VKI_TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */
+#define VKI_TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */
+
+/* set window size */
+#define VKI_TIOCSWINSZ _VKI_IOW('t', 103, struct vki_winsize)
+/* get window size */
+#define VKI_TIOCGWINSZ _VKI_IOR('t', 104, struct vki_winsize)
+#define VKI_TIOCNOTTY 0x5471 /* void tty association */
+#define VKI_TIOCSETD 0x7401
+#define VKI_TIOCGETD 0x7400
+
+#define VKI_FIOCLEX 0x6601
+#define VKI_FIONCLEX 0x6602
+#define VKI_FIOASYNC 0x667d
+#define VKI_FIONBIO 0x667e
+#define VKI_FIOQSIZE 0x667f
+
+#define VKI_TIOCGLTC 0x7474 /* get special local chars */
+#define VKI_TIOCSLTC 0x7475 /* set special local chars */
+#define VKI_TIOCSPGRP _VKI_IOW('t', 118, int) /* set pgrp of tty */
+#define VKI_TIOCGPGRP _VKI_IOR('t', 119, int) /* get pgrp of tty */
+#define VKI_TIOCCONS _VKI_IOW('t', 120, int) /* become virtual
+ console */
+
+#define VKI_FIONREAD 0x467f
+#define VKI_TIOCINQ FIONREAD
+
+#define VKI_TIOCGETP 0x7408
+#define VKI_TIOCSETP 0x7409
+#define VKI_TIOCSETN 0x740a /* TIOCSETP wo flush */
+
+#define VKI_TIOCSBRK 0x5427 /* BSD compatibility */
+#define VKI_TIOCCBRK 0x5428 /* BSD compatibility */
+#define VKI_TIOCGSID 0x7416 /* Return the session ID of FD */
+#define VKI_TIOCGPTN _VKI_IOR('T',0x30, unsigned int) /* Get Pty
+ Number (of pty-mux device) */
+#define VKI_TIOCSPTLCK _VKI_IOW('T',0x31, int) /* Lock/unlock Pty */
+
+/* I hope the range from 0x5480 on is free ... */
+#define VKI_TIOCSCTTY 0x5480 /* become controlling tty */
+#define VKI_TIOCGSOFTCAR 0x5481
+#define VKI_TIOCSSOFTCAR 0x5482
+#define VKI_TIOCLINUX 0x5483
+#define VKI_TIOCGSERIAL 0x5484
+#define VKI_TIOCSSERIAL 0x5485
+#define VKI_TCSBRKP 0x5486 /* Needed for POSIX tcsendbreak() */
+#define VKI_TIOCSERCONFIG 0x5488
+#define VKI_TIOCSERGWILD 0x5489
+#define VKI_TIOCSERSWILD 0x548a
+#define VKI_TIOCGLCKTRMIOS 0x548b
+#define VKI_TIOCSLCKTRMIOS 0x548c
+#define VKI_TIOCSERGSTRUCT 0x548d /* For debugging only */
+#define VKI_TIOCSERGETLSR 0x548e /* Get line status register */
+#define VKI_TIOCSERGETMULTI 0x548f /* Get multiport config */
+#define VKI_TIOCSERSETMULTI 0x5490 /* Set multiport config */
+#define VKI_TIOCMIWAIT 0x5491 /* wait for a change on serial input
+ line(s) */
+#define VKI_TIOCGICOUNT 0x5492 /* read serial port inline interrupt
+ counts */
+#define VKI_TIOCGHAYESESP 0x5493 /* Get Hayes ESP configuration */
+#define VKI_TIOCSHAYESESP 0x5494 /* Set Hayes ESP configuration */
+
+//----------------------------------------------------------------------
+// From asm-generic/poll.h
+//----------------------------------------------------------------------
+
+/* These are specified by iBCS2 */
+#define VKI_POLLIN 0x0001
+
+struct vki_pollfd {
+ int fd;
+ short events;
+ short revents;
+};
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/elf.h
+//----------------------------------------------------------------------
+
+#define VKI_ELF_NGREG 45 /* includes nip, msr, lr, etc. */
+#define VKI_ELF_NFPREG 33 /* includes fpscr */
+
+typedef unsigned long vki_elf_greg_t;
+typedef vki_elf_greg_t vki_elf_gregset_t[VKI_ELF_NGREG];
+
+typedef double vki_elf_fpreg_t;
+typedef vki_elf_fpreg_t vki_elf_fpregset_t[VKI_ELF_NFPREG];
+
+typedef struct vki_user_fxsr_struct vki_elf_fpxregset_t;
+
+#define VKI_AT_SYSINFO 32
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/ucontext.h
+//----------------------------------------------------------------------
+
+struct vki_ucontext {
+ unsigned long uc_flags;
+ struct vki_ucontext *uc_link;
+ vki_stack_t uc_stack;
+ struct vki_sigcontext uc_mcontext;
+ vki_sigset_t uc_sigmask; /* mask last for extensibility */
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/ipcbuf.h
+//----------------------------------------------------------------------
+
+struct vki_ipc64_perm {
+ __vki_kernel_key_t key;
+ __vki_kernel_uid_t uid;
+ __vki_kernel_gid_t gid;
+ __vki_kernel_uid_t cuid;
+ __vki_kernel_gid_t cgid;
+ __vki_kernel_mode_t mode;
+ unsigned short seq;
+ unsigned short __pad1;
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/sembuf.h
+//----------------------------------------------------------------------
+
+struct vki_semid64_ds {
+ struct vki_ipc64_perm sem_perm; /* permissions .. see ipc.h */
+ __vki_kernel_time_t sem_otime; /* last semop time */
+ __vki_kernel_time_t sem_ctime; /* last change time */
+ unsigned long sem_nsems; /* no. of semaphores in array */
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/msgbuf.h
+//----------------------------------------------------------------------
+
+struct vki_msqid64_ds {
+ struct vki_ipc64_perm msg_perm;
+ __vki_kernel_time_t msg_stime; /* last msgsnd time */
+ __vki_kernel_time_t msg_rtime; /* last msgrcv time */
+ __vki_kernel_time_t msg_ctime; /* last change time */
+ unsigned long msg_cbytes; /* current number of bytes on queue */
+ unsigned long msg_qnum; /* number of messages in queue */
+ unsigned long msg_qbytes; /* max number of bytes on queue */
+ __vki_kernel_pid_t msg_lspid; /* pid of last msgsnd */
+ __vki_kernel_pid_t msg_lrpid; /* last receive pid */
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/ipc.h
+//----------------------------------------------------------------------
+
+struct vki_ipc_kludge {
+ struct vki_msgbuf __user *msgp;
+ long msgtyp;
+};
+
+#define VKI_SEMOP 1
+#define VKI_SEMGET 2
+#define VKI_SEMCTL 3
+#define VKI_SEMTIMEDOP 4
+#define VKI_MSGSND 11
+#define VKI_MSGRCV 12
+#define VKI_MSGGET 13
+#define VKI_MSGCTL 14
+#define VKI_SHMAT 21
+#define VKI_SHMDT 22
+#define VKI_SHMGET 23
+#define VKI_SHMCTL 24
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/shmbuf.h
+//----------------------------------------------------------------------
+
+struct vki_shmid64_ds {
+ struct vki_ipc64_perm shm_perm; /* operation perms */
+ vki_size_t shm_segsz; /* size of segment (bytes) */
+ __vki_kernel_time_t shm_atime; /* last attach time */
+ __vki_kernel_time_t shm_dtime; /* last detach time */
+ __vki_kernel_time_t shm_ctime; /* last change time */
+ __vki_kernel_pid_t shm_cpid; /* pid of creator */
+ __vki_kernel_pid_t shm_lpid; /* pid of last operator */
+ unsigned long shm_nattch; /* no. of current attaches */
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
+struct vki_shminfo64 {
+ unsigned long shmmax;
+ unsigned long shmmin;
+ unsigned long shmmni;
+ unsigned long shmseg;
+ unsigned long shmall;
+ unsigned long __unused1;
+ unsigned long __unused2;
+ unsigned long __unused3;
+ unsigned long __unused4;
+};
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-mips/ptrace.h
+//----------------------------------------------------------------------
+
+struct vki_pt_regs {
+#ifdef CONFIG_32BIT
+ /* Pad bytes for argument save space on the stack. */
+ unsigned long pad0[6];
+#endif
+
+ /* Saved main processor registers. */
+ unsigned long regs[32];
+
+ /* Saved special registers. */
+ unsigned long cp0_status;
+ unsigned long hi;
+ unsigned long lo;
+#ifdef CONFIG_CPU_HAS_SMARTMIPS
+ unsigned long acx;
+#endif
+ unsigned long cp0_badvaddr;
+ unsigned long cp0_cause;
+ unsigned long cp0_epc;
+#ifdef CONFIG_MIPS_MT_SMTC
+ unsigned long cp0_tcstatus;
+#endif /* CONFIG_MIPS_MT_SMTC */
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ unsigned long long mpl[3]; /* MTM{0,1,2} */
+ unsigned long long mtp[3]; /* MTP{0,1,2} */
+#endif
+} __attribute__ ((aligned (8)));
+
+
+#define vki_user_regs_struct vki_pt_regs
+
+#define MIPS_lo lo
+#define MIPS_hi hi
+#define MIPS_r31 regs[31]
+#define MIPS_r30 regs[30]
+#define MIPS_r29 regs[29]
+#define MIPS_r28 regs[28]
+#define MIPS_r27 regs[27]
+#define MIPS_r26 regs[26]
+#define MIPS_r25 regs[25]
+#define MIPS_r24 regs[24]
+#define MIPS_r23 regs[23]
+#define MIPS_r22 regs[22]
+#define MIPS_r21 regs[21]
+#define MIPS_r20 regs[20]
+#define MIPS_r19 regs[19]
+#define MIPS_r18 regs[18]
+#define MIPS_r17 regs[17]
+#define MIPS_r16 regs[16]
+#define MIPS_r15 regs[15]
+#define MIPS_r14 regs[14]
+#define MIPS_r13 regs[13]
+#define MIPS_r12 regs[12]
+#define MIPS_r11 regs[11]
+#define MIPS_r10 regs[10]
+#define MIPS_r9 regs[9]
+#define MIPS_r8 regs[8]
+#define MIPS_r7 regs[7]
+#define MIPS_r6 regs[6]
+#define MIPS_r5 regs[5]
+#define MIPS_r4 regs[4]
+#define MIPS_r3 regs[3]
+#define MIPS_r2 regs[2]
+#define MIPS_r1 regs[1]
+#define MIPS_r0 regs[0]
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-i386/ptrace.h
+//----------------------------------------------------------------------
+
+#define VKI_PTRACE_GETREGS 12
+#define VKI_PTRACE_SETREGS 13
+#define VKI_PTRACE_GETFPREGS 14
+#define VKI_PTRACE_SETFPREGS 15
+#define VKI_PTRACE_GETFPXREGS 18
+#define VKI_PTRACE_SETFPXREGS 19
+
+/* Calls to trace a 64bit program from a 32bit program. */
+#define VKI_PTRACE_PEEKTEXT_3264 0xc0
+#define VKI_PTRACE_PEEKDATA_3264 0xc1
+#define VKI_PTRACE_POKETEXT_3264 0xc2
+#define VKI_PTRACE_POKEDATA_3264 0xc3
+#define VKI_PTRACE_GET_THREAD_AREA_3264 0xc4s
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.9/include/asm-generic/siginfo.h
+//----------------------------------------------------------------------
+
+#define HAVE_ARCH_SIGINFO_T
+typedef union vki_sigval {
+ int sival_int;
+ void __user *sival_ptr;
+} vki_sigval_t;
+
+#ifndef __VKI_ARCH_SI_PREAMBLE_SIZE
+#define __VKI_ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
+#endif
+
+#define VKI_SI_MAX_SIZE 128
+
+#ifndef VKI_SI_PAD_SIZE
+#define VKI_SI_PAD_SIZE ((VKI_SI_MAX_SIZE - __VKI_ARCH_SI_PREAMBLE_SIZE) / sizeof(int))
+#endif
+
+#ifndef __VKI_ARCH_SI_UID_T
+#define __VKI_ARCH_SI_UID_T vki_uid_t
+#endif
+
+#ifndef __VKI_ARCH_SI_BAND_T
+#define __VKI_ARCH_SI_BAND_T long
+#endif
+
+typedef struct vki_siginfo {
+ int si_signo;
+ int si_code;
+ int si_errno;
+ int __pad0[VKI_SI_MAX_SIZE / sizeof(int) - VKI_SI_PAD_SIZE - 3];
+
+ union {
+ int _pad[VKI_SI_PAD_SIZE];
+
+ /* kill() */
+ struct {
+ vki_pid_t _pid; /* sender's pid */
+ __VKI_ARCH_SI_UID_T _uid; /* sender's uid */
+ } _kill;
+
+ /* POSIX.1b timers */
+ struct {
+ vki_timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ char _pad[sizeof( __VKI_ARCH_SI_UID_T) - sizeof(int)];
+ vki_sigval_t _sigval; /* same as below */
+ int _sys_private; /* not to be passed to user */
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct {
+ vki_pid_t _pid; /* sender's pid */
+ __VKI_ARCH_SI_UID_T _uid; /* sender's uid */
+ vki_sigval_t _sigval;
+ } _rt;
+
+ /* SIGCHLD */
+ struct {
+ vki_pid_t _pid; /* which child */
+ __VKI_ARCH_SI_UID_T _uid; /* sender's uid */
+ int _status; /* exit code */
+ vki_clock_t _utime;
+ vki_clock_t _stime;
+ } _sigchld;
+
+ /* IRIX SIGCHLD */
+ struct {
+ vki_pid_t _pid; /* which child */
+ vki_clock_t _utime;
+ int _status; /* exit code */
+ vki_clock_t _stime;
+ } _irix_sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+ struct {
+ void __user *_addr; /* faulting insn/memory ref. */
+#ifdef __ARCH_SI_TRAPNO
+ int _trapno; /* TRAP # which caused the signal */
+#endif
+ } _sigfault;
+
+ /* SIGPOLL, SIGXFSZ (To do ...) */
+ struct {
+ __VKI_ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ int _fd;
+ } _sigpoll;
+ } _sifields;
+} vki_siginfo_t;
+
+//----------------------------------------------------------------------
+// From linux-2.6.35.5/include/asm/break.h
+//----------------------------------------------------------------------
+#define VKI_BRK_OVERFLOW 6 /* Overflow check */
+#define VKI_BRK_DIVZERO 7 /* Divide by zero check */
+
+#endif // __VKI_MIPS64_LINUX_H
+
+/*--------------------------------------------------------------------*/
+/*--- end vki-mips64-linux.h ---*/
+/*--------------------------------------------------------------------*/
--- /dev/null
+
+/*--------------------------------------------------------------------*/
+/*--- mips/Linux-specific kernel interface: posix types. ---*/
+/*--- vki-posixtypes-mips64-linux.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2010-2013 RT-RK
+ mips-valgrind@rt-rk.com
+
+ 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.
+*/
+
+#ifndef __VKI_POSIXTYPES_MIPS64_LINUX_H
+#define __VKI_POSIXTYPES_MIPS64_LINUX_H
+
+typedef unsigned long __vki_kernel_ino_t;
+typedef unsigned int __vki_kernel_mode_t;
+#if (_MIPS_SZLONG == 32)
+typedef unsigned long __vki_kernel_nlink_t;
+#endif
+#if (_MIPS_SZLONG == 64)
+typedef unsigned int __vki_kernel_nlink_t;
+#endif
+typedef long __vki_kernel_off_t;
+typedef int __vki_kernel_pid_t;
+typedef int __vki_kernel_ipc_pid_t;
+typedef unsigned int __vki_kernel_uid_t;
+typedef unsigned int __vki_kernel_gid_t;
+#if (_MIPS_SZLONG == 32)
+typedef unsigned int __vki_kernel_size_t;
+typedef int __vki_kernel_ssize_t;
+typedef int __vki_kernel_ptrdiff_t;
+#endif
+#if (_MIPS_SZLONG == 64)
+typedef unsigned long __vki_kernel_size_t;
+typedef long __vki_kernel_ssize_t;
+typedef long __vki_kernel_ptrdiff_t;
+#endif
+typedef long __vki_kernel_time_t;
+typedef long __vki_kernel_suseconds_t;
+typedef long __vki_kernel_clock_t;
+typedef int __vki_kernel_timer_t;
+typedef int __vki_kernel_clockid_t;
+typedef long __vki_kernel_daddr_t;
+typedef char * __vki_kernel_caddr_t;
+
+typedef unsigned short __vki_kernel_uid16_t;
+typedef unsigned short __vki_kernel_gid16_t;
+typedef unsigned int __vki_kernel_uid32_t;
+typedef unsigned int __vki_kernel_gid32_t;
+typedef __vki_kernel_uid_t __vki_kernel_old_uid_t;
+typedef __vki_kernel_gid_t __vki_kernel_old_gid_t;
+typedef unsigned int __vki_kernel_old_dev_t;
+
+typedef long long __vki_kernel_loff_t;
+
+typedef struct {
+#if (_MIPS_SZLONG == 32)
+ long val[2];
+#endif
+#if (_MIPS_SZLONG == 64)
+ int val[2];
+#endif
+} __vki_kernel_fsid_t;
+
+#endif // __VKI_POSIXTYPES_MIPS64_LINUX_H
+
+/*--------------------------------------------------------------------*/
+/*--- end vki-posixtypes-mips-linux.h ---*/
+/*--------------------------------------------------------------------*/
--- /dev/null
+
+/*--------------------------------------------------------------------*/
+/*--- System call numbers for mips-linux. ---*/
+/*--- vki-scnums-mips64-linux.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2010-2013 RT-RK
+ mips-valgrind@rt-rk.com
+
+ 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 __VKI_SCNUMS_MIPS64_LINUX_H
+#define __VKI_SCNUMS_MIPS64_LINUX_H
+
+/*
+ * Linux 64-bit syscalls are in the range from 5000 to 5999.
+ */
+#define __NR_Linux 5000
+#define __NR_read (__NR_Linux + 0)
+#define __NR_write (__NR_Linux + 1)
+#define __NR_open (__NR_Linux + 2)
+#define __NR_close (__NR_Linux + 3)
+#define __NR_stat (__NR_Linux + 4)
+#define __NR_fstat (__NR_Linux + 5)
+#define __NR_lstat (__NR_Linux + 6)
+#define __NR_poll (__NR_Linux + 7)
+#define __NR_lseek (__NR_Linux + 8)
+#define __NR_mmap (__NR_Linux + 9)
+#define __NR_mprotect (__NR_Linux + 10)
+#define __NR_munmap (__NR_Linux + 11)
+#define __NR_brk (__NR_Linux + 12)
+#define __NR_rt_sigaction (__NR_Linux + 13)
+#define __NR_rt_sigprocmask (__NR_Linux + 14)
+#define __NR_ioctl (__NR_Linux + 15)
+#define __NR_pread64 (__NR_Linux + 16)
+#define __NR_pwrite64 (__NR_Linux + 17)
+#define __NR_readv (__NR_Linux + 18)
+#define __NR_writev (__NR_Linux + 19)
+#define __NR_access (__NR_Linux + 20)
+#define __NR_pipe (__NR_Linux + 21)
+#define __NR__newselect (__NR_Linux + 22)
+#define __NR_sched_yield (__NR_Linux + 23)
+#define __NR_mremap (__NR_Linux + 24)
+#define __NR_msync (__NR_Linux + 25)
+#define __NR_mincore (__NR_Linux + 26)
+#define __NR_madvise (__NR_Linux + 27)
+#define __NR_shmget (__NR_Linux + 28)
+#define __NR_shmat (__NR_Linux + 29)
+#define __NR_shmctl (__NR_Linux + 30)
+#define __NR_dup (__NR_Linux + 31)
+#define __NR_dup2 (__NR_Linux + 32)
+#define __NR_pause (__NR_Linux + 33)
+#define __NR_nanosleep (__NR_Linux + 34)
+#define __NR_getitimer (__NR_Linux + 35)
+#define __NR_setitimer (__NR_Linux + 36)
+#define __NR_alarm (__NR_Linux + 37)
+#define __NR_getpid (__NR_Linux + 38)
+#define __NR_sendfile (__NR_Linux + 39)
+#define __NR_socket (__NR_Linux + 40)
+#define __NR_connect (__NR_Linux + 41)
+#define __NR_accept (__NR_Linux + 42)
+#define __NR_sendto (__NR_Linux + 43)
+#define __NR_recvfrom (__NR_Linux + 44)
+#define __NR_sendmsg (__NR_Linux + 45)
+#define __NR_recvmsg (__NR_Linux + 46)
+#define __NR_shutdown (__NR_Linux + 47)
+#define __NR_bind (__NR_Linux + 48)
+#define __NR_listen (__NR_Linux + 49)
+#define __NR_getsockname (__NR_Linux + 50)
+#define __NR_getpeername (__NR_Linux + 51)
+#define __NR_socketpair (__NR_Linux + 52)
+#define __NR_setsockopt (__NR_Linux + 53)
+#define __NR_getsockopt (__NR_Linux + 54)
+#define __NR_clone (__NR_Linux + 55)
+#define __NR_fork (__NR_Linux + 56)
+#define __NR_execve (__NR_Linux + 57)
+#define __NR_exit (__NR_Linux + 58)
+#define __NR_wait4 (__NR_Linux + 59)
+#define __NR_kill (__NR_Linux + 60)
+#define __NR_uname (__NR_Linux + 61)
+#define __NR_semget (__NR_Linux + 62)
+#define __NR_semop (__NR_Linux + 63)
+#define __NR_semctl (__NR_Linux + 64)
+#define __NR_shmdt (__NR_Linux + 65)
+#define __NR_msgget (__NR_Linux + 66)
+#define __NR_msgsnd (__NR_Linux + 67)
+#define __NR_msgrcv (__NR_Linux + 68)
+#define __NR_msgctl (__NR_Linux + 69)
+#define __NR_fcntl (__NR_Linux + 70)
+#define __NR_flock (__NR_Linux + 71)
+#define __NR_fsync (__NR_Linux + 72)
+#define __NR_fdatasync (__NR_Linux + 73)
+#define __NR_truncate (__NR_Linux + 74)
+#define __NR_ftruncate (__NR_Linux + 75)
+#define __NR_getdents (__NR_Linux + 76)
+#define __NR_getcwd (__NR_Linux + 77)
+#define __NR_chdir (__NR_Linux + 78)
+#define __NR_fchdir (__NR_Linux + 79)
+#define __NR_rename (__NR_Linux + 80)
+#define __NR_mkdir (__NR_Linux + 81)
+#define __NR_rmdir (__NR_Linux + 82)
+#define __NR_creat (__NR_Linux + 83)
+#define __NR_link (__NR_Linux + 84)
+#define __NR_unlink (__NR_Linux + 85)
+#define __NR_symlink (__NR_Linux + 86)
+#define __NR_readlink (__NR_Linux + 87)
+#define __NR_chmod (__NR_Linux + 88)
+#define __NR_fchmod (__NR_Linux + 89)
+#define __NR_chown (__NR_Linux + 90)
+#define __NR_fchown (__NR_Linux + 91)
+#define __NR_lchown (__NR_Linux + 92)
+#define __NR_umask (__NR_Linux + 93)
+#define __NR_gettimeofday (__NR_Linux + 94)
+#define __NR_getrlimit (__NR_Linux + 95)
+#define __NR_getrusage (__NR_Linux + 96)
+#define __NR_sysinfo (__NR_Linux + 97)
+#define __NR_times (__NR_Linux + 98)
+#define __NR_ptrace (__NR_Linux + 99)
+#define __NR_getuid (__NR_Linux + 100)
+#define __NR_syslog (__NR_Linux + 101)
+#define __NR_getgid (__NR_Linux + 102)
+#define __NR_setuid (__NR_Linux + 103)
+#define __NR_setgid (__NR_Linux + 104)
+#define __NR_geteuid (__NR_Linux + 105)
+#define __NR_getegid (__NR_Linux + 106)
+#define __NR_setpgid (__NR_Linux + 107)
+#define __NR_getppid (__NR_Linux + 108)
+#define __NR_getpgrp (__NR_Linux + 109)
+#define __NR_setsid (__NR_Linux + 110)
+#define __NR_setreuid (__NR_Linux + 111)
+#define __NR_setregid (__NR_Linux + 112)
+#define __NR_getgroups (__NR_Linux + 113)
+#define __NR_setgroups (__NR_Linux + 114)
+#define __NR_setresuid (__NR_Linux + 115)
+#define __NR_getresuid (__NR_Linux + 116)
+#define __NR_setresgid (__NR_Linux + 117)
+#define __NR_getresgid (__NR_Linux + 118)
+#define __NR_getpgid (__NR_Linux + 119)
+#define __NR_setfsuid (__NR_Linux + 120)
+#define __NR_setfsgid (__NR_Linux + 121)
+#define __NR_getsid (__NR_Linux + 122)
+#define __NR_capget (__NR_Linux + 123)
+#define __NR_capset (__NR_Linux + 124)
+#define __NR_rt_sigpending (__NR_Linux + 125)
+#define __NR_rt_sigtimedwait (__NR_Linux + 126)
+#define __NR_rt_sigqueueinfo (__NR_Linux + 127)
+#define __NR_rt_sigsuspend (__NR_Linux + 128)
+#define __NR_sigaltstack (__NR_Linux + 129)
+#define __NR_utime (__NR_Linux + 130)
+#define __NR_mknod (__NR_Linux + 131)
+#define __NR_personality (__NR_Linux + 132)
+#define __NR_ustat (__NR_Linux + 133)
+#define __NR_statfs (__NR_Linux + 134)
+#define __NR_fstatfs (__NR_Linux + 135)
+#define __NR_sysfs (__NR_Linux + 136)
+#define __NR_getpriority (__NR_Linux + 137)
+#define __NR_setpriority (__NR_Linux + 138)
+#define __NR_sched_setparam (__NR_Linux + 139)
+#define __NR_sched_getparam (__NR_Linux + 140)
+#define __NR_sched_setscheduler (__NR_Linux + 141)
+#define __NR_sched_getscheduler (__NR_Linux + 142)
+#define __NR_sched_get_priority_max (__NR_Linux + 143)
+#define __NR_sched_get_priority_min (__NR_Linux + 144)
+#define __NR_sched_rr_get_interval (__NR_Linux + 145)
+#define __NR_mlock (__NR_Linux + 146)
+#define __NR_munlock (__NR_Linux + 147)
+#define __NR_mlockall (__NR_Linux + 148)
+#define __NR_munlockall (__NR_Linux + 149)
+#define __NR_vhangup (__NR_Linux + 150)
+#define __NR_pivot_root (__NR_Linux + 151)
+#define __NR__sysctl (__NR_Linux + 152)
+#define __NR_prctl (__NR_Linux + 153)
+#define __NR_adjtimex (__NR_Linux + 154)
+#define __NR_setrlimit (__NR_Linux + 155)
+#define __NR_chroot (__NR_Linux + 156)
+#define __NR_sync (__NR_Linux + 157)
+#define __NR_acct (__NR_Linux + 158)
+#define __NR_settimeofday (__NR_Linux + 159)
+#define __NR_mount (__NR_Linux + 160)
+#define __NR_umount2 (__NR_Linux + 161)
+#define __NR_swapon (__NR_Linux + 162)
+#define __NR_swapoff (__NR_Linux + 163)
+#define __NR_reboot (__NR_Linux + 164)
+#define __NR_sethostname (__NR_Linux + 165)
+#define __NR_setdomainname (__NR_Linux + 166)
+#define __NR_create_module (__NR_Linux + 167)
+#define __NR_init_module (__NR_Linux + 168)
+#define __NR_delete_module (__NR_Linux + 169)
+#define __NR_get_kernel_syms (__NR_Linux + 170)
+#define __NR_query_module (__NR_Linux + 171)
+#define __NR_quotactl (__NR_Linux + 172)
+#define __NR_nfsservctl (__NR_Linux + 173)
+#define __NR_getpmsg (__NR_Linux + 174)
+#define __NR_putpmsg (__NR_Linux + 175)
+#define __NR_afs_syscall (__NR_Linux + 176)
+#define __NR_reserved177 (__NR_Linux + 177)
+#define __NR_gettid (__NR_Linux + 178)
+#define __NR_readahead (__NR_Linux + 179)
+#define __NR_setxattr (__NR_Linux + 180)
+#define __NR_lsetxattr (__NR_Linux + 181)
+#define __NR_fsetxattr (__NR_Linux + 182)
+#define __NR_getxattr (__NR_Linux + 183)
+#define __NR_lgetxattr (__NR_Linux + 184)
+#define __NR_fgetxattr (__NR_Linux + 185)
+#define __NR_listxattr (__NR_Linux + 186)
+#define __NR_llistxattr (__NR_Linux + 187)
+#define __NR_flistxattr (__NR_Linux + 188)
+#define __NR_removexattr (__NR_Linux + 189)
+#define __NR_lremovexattr (__NR_Linux + 190)
+#define __NR_fremovexattr (__NR_Linux + 191)
+#define __NR_tkill (__NR_Linux + 192)
+#define __NR_reserved193 (__NR_Linux + 193)
+#define __NR_futex (__NR_Linux + 194)
+#define __NR_sched_setaffinity (__NR_Linux + 195)
+#define __NR_sched_getaffinity (__NR_Linux + 196)
+#define __NR_cacheflush (__NR_Linux + 197)
+#define __NR_cachectl (__NR_Linux + 198)
+#define __NR_sysmips (__NR_Linux + 199)
+#define __NR_io_setup (__NR_Linux + 200)
+#define __NR_io_destroy (__NR_Linux + 201)
+#define __NR_io_getevents (__NR_Linux + 202)
+#define __NR_io_submit (__NR_Linux + 203)
+#define __NR_io_cancel (__NR_Linux + 204)
+#define __NR_exit_group (__NR_Linux + 205)
+#define __NR_lookup_dcookie (__NR_Linux + 206)
+#define __NR_epoll_create (__NR_Linux + 207)
+#define __NR_epoll_ctl (__NR_Linux + 208)
+#define __NR_epoll_wait (__NR_Linux + 209)
+#define __NR_remap_file_pages (__NR_Linux + 210)
+#define __NR_rt_sigreturn (__NR_Linux + 211)
+#define __NR_set_tid_address (__NR_Linux + 212)
+#define __NR_restart_syscall (__NR_Linux + 213)
+#define __NR_semtimedop (__NR_Linux + 214)
+#define __NR_fadvise64 (__NR_Linux + 215)
+#define __NR_timer_create (__NR_Linux + 216)
+#define __NR_timer_settime (__NR_Linux + 217)
+#define __NR_timer_gettime (__NR_Linux + 218)
+#define __NR_timer_getoverrun (__NR_Linux + 219)
+#define __NR_timer_delete (__NR_Linux + 220)
+#define __NR_clock_settime (__NR_Linux + 221)
+#define __NR_clock_gettime (__NR_Linux + 222)
+#define __NR_clock_getres (__NR_Linux + 223)
+#define __NR_clock_nanosleep (__NR_Linux + 224)
+#define __NR_tgkill (__NR_Linux + 225)
+#define __NR_utimes (__NR_Linux + 226)
+#define __NR_mbind (__NR_Linux + 227)
+#define __NR_get_mempolicy (__NR_Linux + 228)
+#define __NR_set_mempolicy (__NR_Linux + 229)
+#define __NR_mq_open (__NR_Linux + 230)
+#define __NR_mq_unlink (__NR_Linux + 231)
+#define __NR_mq_timedsend (__NR_Linux + 232)
+#define __NR_mq_timedreceive (__NR_Linux + 233)
+#define __NR_mq_notify (__NR_Linux + 234)
+#define __NR_mq_getsetattr (__NR_Linux + 235)
+#define __NR_vserver (__NR_Linux + 236)
+#define __NR_waitid (__NR_Linux + 237)
+/* #define __NR_sys_setaltroot (__NR_Linux + 238) */
+#define __NR_add_key (__NR_Linux + 239)
+#define __NR_request_key (__NR_Linux + 240)
+#define __NR_keyctl (__NR_Linux + 241)
+#define __NR_set_thread_area (__NR_Linux + 242)
+#define __NR_inotify_init (__NR_Linux + 243)
+#define __NR_inotify_add_watch (__NR_Linux + 244)
+#define __NR_inotify_rm_watch (__NR_Linux + 245)
+#define __NR_migrate_pages (__NR_Linux + 246)
+#define __NR_openat (__NR_Linux + 247)
+#define __NR_mkdirat (__NR_Linux + 248)
+#define __NR_mknodat (__NR_Linux + 249)
+#define __NR_fchownat (__NR_Linux + 250)
+#define __NR_futimesat (__NR_Linux + 251)
+#define __NR_newfstatat (__NR_Linux + 252)
+#define __NR_unlinkat (__NR_Linux + 253)
+#define __NR_renameat (__NR_Linux + 254)
+#define __NR_linkat (__NR_Linux + 255)
+#define __NR_symlinkat (__NR_Linux + 256)
+#define __NR_readlinkat (__NR_Linux + 257)
+#define __NR_fchmodat (__NR_Linux + 258)
+#define __NR_faccessat (__NR_Linux + 259)
+#define __NR_pselect6 (__NR_Linux + 260)
+#define __NR_ppoll (__NR_Linux + 261)
+#define __NR_unshare (__NR_Linux + 262)
+#define __NR_splice (__NR_Linux + 263)
+#define __NR_sync_file_range (__NR_Linux + 264)
+#define __NR_tee (__NR_Linux + 265)
+#define __NR_vmsplice (__NR_Linux + 266)
+#define __NR_move_pages (__NR_Linux + 267)
+#define __NR_set_robust_list (__NR_Linux + 268)
+#define __NR_get_robust_list (__NR_Linux + 269)
+#define __NR_kexec_load (__NR_Linux + 270)
+#define __NR_getcpu (__NR_Linux + 271)
+#define __NR_epoll_pwait (__NR_Linux + 272)
+#define __NR_ioprio_set (__NR_Linux + 273)
+#define __NR_ioprio_get (__NR_Linux + 274)
+#define __NR_utimensat (__NR_Linux + 275)
+#define __NR_signalfd (__NR_Linux + 276)
+#define __NR_timerfd (__NR_Linux + 277)
+#define __NR_eventfd (__NR_Linux + 278)
+#define __NR_fallocate (__NR_Linux + 279)
+#define __NR_timerfd_create (__NR_Linux + 280)
+#define __NR_timerfd_gettime (__NR_Linux + 281)
+#define __NR_timerfd_settime (__NR_Linux + 282)
+#define __NR_signalfd4 (__NR_Linux + 283)
+#define __NR_eventfd2 (__NR_Linux + 284)
+#define __NR_epoll_create1 (__NR_Linux + 285)
+#define __NR_dup3 (__NR_Linux + 286)
+#define __NR_pipe2 (__NR_Linux + 287)
+#define __NR_inotify_init1 (__NR_Linux + 288)
+#define __NR_preadv (__NR_Linux + 289)
+#define __NR_pwritev (__NR_Linux + 290)
+#define __NR_rt_tgsigqueueinfo (__NR_Linux + 291)
+#define __NR_perf_event_open (__NR_Linux + 292)
+#define __NR_accept4 (__NR_Linux + 293)
+
+#endif /* __VKI_SCNUMS_MIPS64_LINUX_H */
+
+/*--------------------------------------------------------------------*/
+/*--- end vki-scnums-mips64-linux.h ---*/
+/*--------------------------------------------------------------------*/
# define MC_SIZEOF_GUEST_STATE sizeof(VexGuestMIPS32State)
#endif
+#if defined(VGA_mips64)
+# include "libvex_guest_mips64.h"
+# define MC_SIZEOF_GUEST_STATE sizeof(VexGuestMIPS64State)
+#endif
+
static inline Bool host_is_big_endian ( void ) {
UInt x = 0x11223344;
return 0x1122 == *(UShort*)(&x);
offset,szB);
tl_assert(0);
# undef GOF
+# undef SZB
+
+ /* --------------------- mips64 --------------------- */
+
+# elif defined(VGA_mips64)
+
+# define GOF(_fieldname) \
+ (offsetof(VexGuestMIPS64State,guest_##_fieldname))
+# define SZB(_fieldname) \
+ (sizeof(((VexGuestMIPS64State*)0)->guest_##_fieldname))
+
+ Int o = offset;
+ Int sz = szB;
+ tl_assert(sz > 0);
+#if defined (VG_LITTLEENDIAN)
+ tl_assert(host_is_little_endian());
+#elif defined (VG_BIGENDIAN)
+ tl_assert(host_is_big_endian());
+#endif
+
+ if (o >= GOF(r0) && sz <= 8 && o <= (GOF(r31) + 8 - sz))
+ return GOF(r0) + ((o-GOF(r0)) & -8) ;
+
+ if (o == GOF(PC) && sz == 8) return -1; /* slot unused */
+
+ if (o == GOF(HI) && sz == 8) return o;
+ if (o == GOF(LO) && sz == 8) return o;
+
+ if (o == GOF(FIR) && sz == 4) return -1; /* slot unused */
+ if (o == GOF(FCCR) && sz == 4) return -1; /* slot unused */
+ if (o == GOF(FEXR) && sz == 4) return -1; /* slot unused */
+ if (o == GOF(FENR) && sz == 4) return -1; /* slot unused */
+ if (o == GOF(FCSR) && sz == 4) return -1; /* slot unused */
+ if (o == GOF(ULR) && sz == 8) return o;
+
+ if (o == GOF(EMNOTE) && sz == 4) return -1; /* slot unused */
+ if (o == GOF(TISTART) && sz == 4) return -1; /* slot unused */
+ if (o == GOF(TILEN) && sz == 4) return -1; /* slot unused */
+ if (o == GOF(NRADDR) && sz == 4) return -1; /* slot unused */
+
+ if (o >= GOF(f0) && o+sz <= GOF(f0) +SZB(f0)) return GOF(f0);
+ if (o >= GOF(f1) && o+sz <= GOF(f1) +SZB(f1)) return GOF(f1);
+ if (o >= GOF(f2) && o+sz <= GOF(f2) +SZB(f2)) return GOF(f2);
+ if (o >= GOF(f3) && o+sz <= GOF(f3) +SZB(f3)) return GOF(f3);
+ if (o >= GOF(f4) && o+sz <= GOF(f4) +SZB(f4)) return GOF(f4);
+ if (o >= GOF(f5) && o+sz <= GOF(f5) +SZB(f5)) return GOF(f5);
+ if (o >= GOF(f6) && o+sz <= GOF(f6) +SZB(f6)) return GOF(f6);
+ if (o >= GOF(f7) && o+sz <= GOF(f7) +SZB(f7)) return GOF(f7);
+ if (o >= GOF(f8) && o+sz <= GOF(f8) +SZB(f8)) return GOF(f8);
+ if (o >= GOF(f9) && o+sz <= GOF(f9) +SZB(f9)) return GOF(f9);
+ if (o >= GOF(f10) && o+sz <= GOF(f10)+SZB(f10)) return GOF(f10);
+ if (o >= GOF(f11) && o+sz <= GOF(f11)+SZB(f11)) return GOF(f11);
+ if (o >= GOF(f12) && o+sz <= GOF(f12)+SZB(f12)) return GOF(f12);
+ if (o >= GOF(f13) && o+sz <= GOF(f13)+SZB(f13)) return GOF(f13);
+ if (o >= GOF(f14) && o+sz <= GOF(f14)+SZB(f14)) return GOF(f14);
+ if (o >= GOF(f15) && o+sz <= GOF(f15)+SZB(f15)) return GOF(f15);
+ if (o >= GOF(f16) && o+sz <= GOF(f16)+SZB(f16)) return GOF(f16);
+ if (o >= GOF(f17) && o+sz <= GOF(f17)+SZB(f17)) return GOF(f17);
+ if (o >= GOF(f18) && o+sz <= GOF(f18)+SZB(f18)) return GOF(f18);
+ if (o >= GOF(f19) && o+sz <= GOF(f19)+SZB(f19)) return GOF(f19);
+ if (o >= GOF(f20) && o+sz <= GOF(f20)+SZB(f20)) return GOF(f20);
+ if (o >= GOF(f21) && o+sz <= GOF(f21)+SZB(f21)) return GOF(f21);
+ if (o >= GOF(f22) && o+sz <= GOF(f22)+SZB(f22)) return GOF(f22);
+ if (o >= GOF(f23) && o+sz <= GOF(f23)+SZB(f23)) return GOF(f23);
+ if (o >= GOF(f24) && o+sz <= GOF(f24)+SZB(f24)) return GOF(f24);
+ if (o >= GOF(f25) && o+sz <= GOF(f25)+SZB(f25)) return GOF(f25);
+ if (o >= GOF(f26) && o+sz <= GOF(f26)+SZB(f26)) return GOF(f26);
+ if (o >= GOF(f27) && o+sz <= GOF(f27)+SZB(f27)) return GOF(f27);
+ if (o >= GOF(f28) && o+sz <= GOF(f28)+SZB(f28)) return GOF(f28);
+ if (o >= GOF(f29) && o+sz <= GOF(f29)+SZB(f29)) return GOF(f29);
+ if (o >= GOF(f30) && o+sz <= GOF(f30)+SZB(f30)) return GOF(f30);
+ if (o >= GOF(f31) && o+sz <= GOF(f31)+SZB(f31)) return GOF(f31);
+
+ if ((o > GOF(NRADDR)) && (o <= GOF(NRADDR) +12 )) return -1;
+
+ VG_(printf)("MC_(get_otrack_shadow_offset)(mips)(off=%d,sz=%d)\n",
+ offset,szB);
+ tl_assert(0);
+# undef GOF
# undef SZB
# else
VG_(printf)("\n");
tl_assert(0);
+ /* --------------------- mips64 --------------------- */
+# elif defined(VGA_mips64)
+ VG_(printf)("get_reg_array_equiv_int_type(mips64): unhandled: ");
+ ppIRRegArray(arr);
+ VG_(printf)("\n");
+ tl_assert(0);
# else
# error "FIXME: not implemented for this architecture"
# endif
"arm",
"s390x",
"mips32",
+ "mips64",
NULL
};
#elif defined(VGP_mips32_linux)
if ( 0 == strcmp( arch, "mips32" ) ) return True;
+#elif defined(VGP_mips64_linux)
+ if ( 0 == strcmp( arch, "mips64" ) ) return True;
+
#else
# error Unknown platform
#endif // VGP_*
all_platforms=
all_platforms="$all_platforms x86-linux amd64-linux ppc32-linux ppc64-linux"
all_platforms="$all_platforms arm-linux"
-all_platforms="$all_platforms s390x-linux mips32-linux"
+all_platforms="$all_platforms s390x-linux mips32-linux mips64-linux"
all_platforms="$all_platforms x86-darwin amd64-darwin"
if [ $# -ne 2 ] ; then