121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe#define _GNU_SOURCE
221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe#include <stdio.h>
321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe#include <stdlib.h>
421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe#include <unistd.h>
521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe#include "../memcheck.h"
621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe#include "leak.h"
721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe#include <sys/mman.h>
821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe#include <sys/syscall.h>
921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
108eb8bab992e3998c33770b0cdb16059a8b918a06sewardjtypedef unsigned int             UInt;
11e37c4bce28e78b9288458907357989bfacd265e7philippetypedef unsigned long            UWord;
12e37c4bce28e78b9288458907357989bfacd265e7philippetypedef unsigned long long int   ULong;
138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
14e37c4bce28e78b9288458907357989bfacd265e7philippe// Below code is copied from m_syscall.c
15e37c4bce28e78b9288458907357989bfacd265e7philippe// Refer to this file for syscall convention.
16e37c4bce28e78b9288458907357989bfacd265e7philippe#if defined(VGP_x86_linux)
178eb8bab992e3998c33770b0cdb16059a8b918a06sewardjextern UWord do_syscall_WRK (UWord syscall_no,
1821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe                             UWord a1, UWord a2, UWord a3,
1921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe                             UWord a4, UWord a5, UWord a6
2021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe                             );
2121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippeasm(
2221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe".text\n"
2321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe".globl do_syscall_WRK\n"
2421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"do_syscall_WRK:\n"
2521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	push	%esi\n"
2621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	push	%edi\n"
2721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	push	%ebx\n"
2821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	push	%ebp\n"
2921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	movl	16+ 4(%esp),%eax\n"
3021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	movl	16+ 8(%esp),%ebx\n"
3121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	movl	16+12(%esp),%ecx\n"
3221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	movl	16+16(%esp),%edx\n"
3321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	movl	16+20(%esp),%esi\n"
3421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	movl	16+24(%esp),%edi\n"
3521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	movl	16+28(%esp),%ebp\n"
3621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	int	$0x80\n"
3721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	popl	%ebp\n"
3821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	popl	%ebx\n"
3921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	popl	%edi\n"
4021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	popl	%esi\n"
4121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	ret\n"
4221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe".previous\n"
4321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe);
448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
4521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe#elif defined(VGP_amd64_linux)
4621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippeextern UWord do_syscall_WRK (
4721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe          UWord syscall_no,
4821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe          UWord a1, UWord a2, UWord a3,
4921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe          UWord a4, UWord a5, UWord a6
5021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe       );
5121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippeasm(
5221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe".text\n"
5321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe".globl do_syscall_WRK\n"
5421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"do_syscall_WRK:\n"
5521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	movq	%rdi, %rax\n"
5621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	movq	%rsi, %rdi\n"
5721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	movq	%rdx, %rsi\n"
5821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	movq	%rcx, %rdx\n"
5921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	movq	%r8,  %r10\n"
6021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	movq	%r9,  %r8\n"
6121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	movq    8(%rsp), %r9\n"	 /* last arg from stack */
6221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	syscall\n"
6321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"	ret\n"
6421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe".previous\n"
6521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe);
6621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
6721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe#elif defined(VGP_ppc32_linux)
6821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippeextern ULong do_syscall_WRK (
6921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe          UWord syscall_no,
7021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe          UWord a1, UWord a2, UWord a3,
7121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe          UWord a4, UWord a5, UWord a6
7221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe       );
7321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippeasm(
7421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe".text\n"
7521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe".globl do_syscall_WRK\n"
7621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"do_syscall_WRK:\n"
7721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"        mr      0,3\n"
7821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"        mr      3,4\n"
7921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"        mr      4,5\n"
8021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"        mr      5,6\n"
8121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"        mr      6,7\n"
8221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"        mr      7,8\n"
8321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"        mr      8,9\n"
8421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"        sc\n"                  /* syscall: sets %cr0.so on error         */
8521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"        mfcr    4\n"           /* %cr -> low word of return var          */
8621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"        rlwinm  4,4,4,31,31\n" /* rotate flag bit so to lsb, and mask it */
8721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"        blr\n"                 /* and return                             */
8821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe".previous\n"
8921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe);
9021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
9121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe#elif defined(VGP_arm_linux)
9221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippeextern UWord do_syscall_WRK (
9321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe          UWord a1, UWord a2, UWord a3,
9421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe          UWord a4, UWord a5, UWord a6,
9521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe          UWord syscall_no
9621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe       );
9721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippeasm(
9821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe".text\n"
9921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe".globl do_syscall_WRK\n"
10021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"do_syscall_WRK:\n"
10121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"         push    {r4, r5, r7}\n"
10221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"         ldr     r4, [sp, #12]\n"
10321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"         ldr     r5, [sp, #16]\n"
10421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"         ldr     r7, [sp, #20]\n"
10521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"         svc     0x0\n"
10621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"         pop     {r4, r5, r7}\n"
10721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe"         bx      lr\n"
10821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe".previous\n"
10921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe);
1108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
11121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe#elif defined(VGP_s390x_linux)
11221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippeUWord do_syscall_WRK (
11321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   UWord syscall_no,
11421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   UWord arg1, UWord arg2, UWord arg3,
11521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   UWord arg4, UWord arg5, UWord arg6
11621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   )
11721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe{
11821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   register UWord __arg1 asm("2") = arg1;
11921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   register UWord __arg2 asm("3") = arg2;
12021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   register UWord __arg3 asm("4") = arg3;
12121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   register UWord __arg4 asm("5") = arg4;
12221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   register UWord __arg5 asm("6") = arg5;
12321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   register UWord __arg6 asm("7") = arg6;
12421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   register ULong __svcres asm("2");
12521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
12621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   __asm__ __volatile__ (
12721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe                 "lgr %%r1,%1\n\t"
12821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe                 "svc 0\n\t"
12921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe		: "=d" (__svcres)
13021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe		: "a" (syscall_no),
13121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe		  "0" (__arg1),
13221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe		  "d" (__arg2),
13321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe		  "d" (__arg3),
13421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe		  "d" (__arg4),
13521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe		  "d" (__arg5),
13621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe		  "d" (__arg6)
13721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe		: "1", "cc", "memory");
13821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
13921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   return (UWord) (__svcres);
14021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe}
14121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
142ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj#elif defined(VGP_mips64_linux)
143ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanjextern UWord do_syscall_WRK (
144ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj          UWord syscall_no,
145ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj          UWord a1, UWord a2, UWord a3,
146ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj          UWord a4, UWord a5, UWord a6
147ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj       )
148ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj{
149ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj   UWord out;
150ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj   __asm__ __volatile__ (
151ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj                 "move $v0, %1\n\t"
152ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj                 "move $a0, %2\n\t"
153ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj                 "move $a1, %3\n\t"
154ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj                 "move $a2, %4\n\t"
155ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj                 "move $a3, %5\n\t"
156ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj                 "move $8,  %6\n\t"  /* We use numbers because some compilers */
157ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj                 "move $9,  %7\n\t"  /* don't recognize $a4 and $a5 */
158ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj                 "syscall\n"
159ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj                 "move %0, $v0\n\t"
160ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj                 : /*out*/ "=r" (out)
161ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj                 : "r"(syscall_no), "r"(a1), "r"(a2), "r"(a3),
162ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj                   "r"(a4), "r"(a5), "r"(a6)
163ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj                 : "v0", "v1", "a0", "a1", "a2", "a3", "$8", "$9");
164ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj   return out;
165ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj}
166112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#elif defined(VGP_tilegx_linux)
167112711afefcfcd43680c7c4aa8d38ef180e8811esewardjextern UWord do_syscall_WRK (
168112711afefcfcd43680c7c4aa8d38ef180e8811esewardj          UWord syscall_no,
169112711afefcfcd43680c7c4aa8d38ef180e8811esewardj          UWord a1, UWord a2, UWord a3,
170112711afefcfcd43680c7c4aa8d38ef180e8811esewardj          UWord a4, UWord a5, UWord a6
171112711afefcfcd43680c7c4aa8d38ef180e8811esewardj       )
172112711afefcfcd43680c7c4aa8d38ef180e8811esewardj{
173112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   UWord out;
174112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   __asm__ __volatile__ (
175e27c8cd24643d09ef7857a567771a95e888b6b5fzliu                 "move r10, %1\n\t"
176e27c8cd24643d09ef7857a567771a95e888b6b5fzliu                 "move r0,  %2\n\t"
177e27c8cd24643d09ef7857a567771a95e888b6b5fzliu                 "move r1,  %3\n\t"
178e27c8cd24643d09ef7857a567771a95e888b6b5fzliu                 "move r2,  %4\n\t"
179e27c8cd24643d09ef7857a567771a95e888b6b5fzliu                 "move r3,  %5\n\t"
180e27c8cd24643d09ef7857a567771a95e888b6b5fzliu                 "move r4,  %6\n\t"
181e27c8cd24643d09ef7857a567771a95e888b6b5fzliu                 "move r5,  %7\n\t"
182112711afefcfcd43680c7c4aa8d38ef180e8811esewardj                 "swint1      \n\t"
183112711afefcfcd43680c7c4aa8d38ef180e8811esewardj                 "move %0,  r0\n\t"
184112711afefcfcd43680c7c4aa8d38ef180e8811esewardj                 : /*out*/ "=r" (out)
185112711afefcfcd43680c7c4aa8d38ef180e8811esewardj                 : "r"(syscall_no), "r"(a1), "r"(a2), "r"(a3),
186112711afefcfcd43680c7c4aa8d38ef180e8811esewardj                   "r"(a4), "r"(a5), "r"(a6)
187112711afefcfcd43680c7c4aa8d38ef180e8811esewardj                 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r10");
188112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   return out;
189112711afefcfcd43680c7c4aa8d38ef180e8811esewardj}
190ec587b07a0d13a6dc6fab184dfb98f0dec841f18dejanj
1918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGP_x86_solaris)
1928eb8bab992e3998c33770b0cdb16059a8b918a06sewardjextern ULong
1938eb8bab992e3998c33770b0cdb16059a8b918a06sewardjdo_syscall_WRK(UWord a1, UWord a2, UWord a3,
1948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj               UWord a4, UWord a5, UWord a6,
1958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj               UWord a7, UWord a8,
1968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj               UWord syscall_no,
1978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj               UInt *errflag);
1988eb8bab992e3998c33770b0cdb16059a8b918a06sewardjasm(
1998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj".text\n"
2008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj".globl do_syscall_WRK\n"
2018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"do_syscall_WRK:\n"
2028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"        movl    40(%esp), %ecx\n"      /* assume syscall success */
2038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"        movl    $0, (%ecx)\n"
2048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"        movl    36(%esp), %eax\n"
2058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"        int     $0x91\n"
2068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"        jnc     1f\n"                  /* jump if success */
2078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"        movl    40(%esp), %ecx\n"      /* syscall failed - set *errflag */
2088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"        movl    $1, (%ecx)\n"
2098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"1:      ret\n"
2108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj".previous\n"
2118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj);
2128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
2138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGP_amd64_solaris)
2148eb8bab992e3998c33770b0cdb16059a8b918a06sewardjextern ULong
2158eb8bab992e3998c33770b0cdb16059a8b918a06sewardjdo_syscall_WRK(UWord a1, UWord a2, UWord a3,
2168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj               UWord a4, UWord a5, UWord a6,
2178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj               UWord a7, UWord a8,
2188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj               UWord syscall_no,
2198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj               UInt *errflag);
2208eb8bab992e3998c33770b0cdb16059a8b918a06sewardjasm(
2218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj".text\n"
2228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj".globl do_syscall_WRK\n"
2238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"do_syscall_WRK:\n"
2248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"       movq    %rcx, %r10\n"           /* pass rcx in r10 instead */
2258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"       movq    32(%rsp), %rcx\n"       /* assume syscall success */
2268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"       movl    $0, (%rcx)\n"
2278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"       movq    24(%rsp), %rax\n"
2288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"       syscall\n"
2298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"       jnc     1f\n"                   /* jump if success */
2308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"       movq    32(%rsp), %rcx\n"       /* syscall failed - set *errflag */
2318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"       movl    $1, (%rcx)\n"
2328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj"1:     ret\n"
2338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj".previous\n"
2348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj);
2358eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
23621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe#else
2372082b3436bd570f764945258654bd2152ec1a7dephilippe// Ensure the file compiles even if the syscall nr is not defined.
2382082b3436bd570f764945258654bd2152ec1a7dephilippe#ifndef __NR_mprotect
2392082b3436bd570f764945258654bd2152ec1a7dephilippe#define __NR_mprotect 0
2402082b3436bd570f764945258654bd2152ec1a7dephilippe#endif
24121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippeUWord do_syscall_WRK (UWord syscall_no,
24221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe                      UWord a1, UWord a2, UWord a3,
24321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe                      UWord a4, UWord a5, UWord a6
24421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe                      )
24521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe{
24621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   // not implemented. vgtest prereq should avoid this to be called.
24721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   return -1;
24821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe}
24921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe#endif
25021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
25121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
25221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
25321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippechar **b10;
254b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippechar *interior_ptrs[3];
25521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippeint mprotect_result = 0;
25621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippestatic void non_simd_mprotect (long tid, void* addr, long len)
25721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe{
2588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#if defined(VGP_x86_solaris) || defined(VGP_amd64_solaris)
2598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   UInt err = 0;
2608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   mprotect_result = do_syscall_WRK((UWord) addr, len, PROT_NONE,
2618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj                                    0, 0, 0, 0, 0, SYS_mprotect,
2628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj                                    &err);
2638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   if (err)
2648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      mprotect_result = -1;
2658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#else
26621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   mprotect_result = do_syscall_WRK(__NR_mprotect,
26721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe                                    (UWord) addr, len, PROT_NONE,
26821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe                                    0, 0, 0);
2698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#endif
27021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe}
27121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
272b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe// can this work without global variable for return value?
273b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippestatic void my_mprotect_none(void* addr, long len)
274b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe{
275b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   if (RUNNING_ON_VALGRIND)
276b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe     (void) VALGRIND_NON_SIMD_CALL2(non_simd_mprotect,
277b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe                                    addr,
278b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe                                    len);
279b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   else
280b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe      mprotect_result = mprotect(addr,
281b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe                                 len,
282b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe                                 PROT_NONE);
283b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe}
284b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe
28521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippevoid f(void)
28621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe{
28721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   long pagesize;
28821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe#define RNDPAGEDOWN(a) ((long)a & ~(pagesize-1))
2897a76f4b27db3ec7a0130a5fd7120aeb5060c89c2philippe   int i;
2907a76f4b27db3ec7a0130a5fd7120aeb5060c89c2philippe   const int nr_ptr = (10000 * 4)/sizeof(char*);
29121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
2927a76f4b27db3ec7a0130a5fd7120aeb5060c89c2philippe   b10 = calloc (nr_ptr * sizeof(char*), 1);
2937a76f4b27db3ec7a0130a5fd7120aeb5060c89c2philippe   for (i = 0; i < nr_ptr; i++)
2947a76f4b27db3ec7a0130a5fd7120aeb5060c89c2philippe      b10[i] = (char*)b10;
29521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   b10[4000] = malloc (1000);
296b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe
29721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   fprintf(stderr, "expecting no leaks\n");
29821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   fflush(stderr);
29921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   VALGRIND_DO_LEAK_CHECK;
30021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
30121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   // make b10[4000] undefined. This should create a leak.
30206bc722457ffe12e056d2f40d0d2f5c8711b541fflorian   (void) VALGRIND_MAKE_MEM_UNDEFINED (&b10[4000], sizeof(char*));
30321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   fprintf(stderr, "expecting a leak\n");
30421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   fflush(stderr);
30521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   VALGRIND_DO_LEAK_CHECK;
30621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
30721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   // make  b10[4000] defined again.
30806bc722457ffe12e056d2f40d0d2f5c8711b541fflorian   (void) VALGRIND_MAKE_MEM_DEFINED (&b10[4000], sizeof(char*));
30921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
31021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   // now make some bricolage to have some pages around b10[4000]
31121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   // unreadable. The leak check should recover from that
31221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   // thanks to a SEGV handler and a setjmp/longjmp.
31321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   // This setjmp/longjmp is useful if there is a desync between
31421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   // the aspacemgr and the real pages mapping.
31521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   // To have such a discrepancy, we resort on a non SIMD call
31621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   // to mprotect the pages : as this syscall will not be seen
31721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   // by Valgrind core, the aspacemgr will not get a chance
31821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   // to stay synchronised.
31921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   pagesize = sysconf(_SC_PAGE_SIZE);
32021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   if (pagesize == -1)
32121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe      perror ("sysconf failed");
32221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
323b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   my_mprotect_none((void*) RNDPAGEDOWN(&b10[4000]), 2 * pagesize);
32421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   fprintf(stderr, "mprotect result %d\n", mprotect_result);
32521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
32621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   fprintf(stderr, "expecting a leak again\n");
32721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   fflush(stderr);
32821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   VALGRIND_DO_LEAK_CHECK;
32921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
330b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   my_mprotect_none((void*) RNDPAGEDOWN(&b10[0]),
3317a76f4b27db3ec7a0130a5fd7120aeb5060c89c2philippe                                 RNDPAGEDOWN(&(b10[nr_ptr-1]))
332b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe                                 - RNDPAGEDOWN(&(b10[0])));
3337a76f4b27db3ec7a0130a5fd7120aeb5060c89c2philippe   fprintf(stderr, "full mprotect result %d\n", mprotect_result);
3347a76f4b27db3ec7a0130a5fd7120aeb5060c89c2philippe
3357a76f4b27db3ec7a0130a5fd7120aeb5060c89c2philippe   fprintf(stderr, "expecting a leak again after full mprotect\n");
3367a76f4b27db3ec7a0130a5fd7120aeb5060c89c2philippe   fflush(stderr);
3377a76f4b27db3ec7a0130a5fd7120aeb5060c89c2philippe   VALGRIND_DO_LEAK_CHECK;
3387a76f4b27db3ec7a0130a5fd7120aeb5060c89c2philippe
339b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   // allocate memory but keep only interior pointers to trigger various
340b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   // heuristics
341b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   // Allocate some memory:
342b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   interior_ptrs[0] = calloc (nr_ptr * sizeof(char*), 1);
343b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe
344b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   // Inner pointer after 3 sizeT: triggers the stdstring heuristic:
345b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   interior_ptrs[2] = interior_ptrs[0] + 3 * sizeof(size_t);
346b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe
347b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   // Inner pointer after 1 ULong: triggers the length64 heuristic:
348b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   interior_ptrs[1] = interior_ptrs[0] + sizeof(unsigned long);
349b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe
350b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   // Inner pointer after a size: triggers the newarray heuristics.
351b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   interior_ptrs[0] += sizeof(size_t);
352b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe
353b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   my_mprotect_none( (void*) RNDPAGEDOWN((interior_ptrs[0] - sizeof(size_t))),
354b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe                     RNDPAGEDOWN(nr_ptr * sizeof(char*)));
355b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   fprintf(stderr, "mprotect result %d\n", mprotect_result);
356b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe
357b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   fprintf(stderr, "expecting heuristic not to crash after full mprotect\n");
358b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   fflush(stderr);
359b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe   VALGRIND_DO_LEAK_CHECK;
360b5a02e7bbdd30619628dcb3bb09bd621be579a9dphilippe
36121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   fprintf(stderr, "finished\n");
36221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe}
36321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
36421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippeint main(void)
36521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe{
36621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   DECLARE_LEAK_COUNTERS;
36721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
36821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   GET_INITIAL_LEAK_COUNTS;
36921fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
37021fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   f();   // see leak-cases.c
37121fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
37221fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
37321fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   GET_FINAL_LEAK_COUNTS;
37421fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
37521fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   PRINT_LEAK_COUNTS(stderr);
37621fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe
37721fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe   return 0;
37821fcbb73c60e6eabbccf877439c095cf3b7c66cfphilippe}
379