blob: ad2774bcb96c2ca1511abe80beee367eb6d17955 [file] [log] [blame]
/* -*- Mode: C; tab-width: 8; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
#include "util.h"
static void* ptr;
static char syscall_bytes[] =
#ifdef __x86_64__
{ 0x0f, 0x05, 0xc3 }
#elif __i386__
{ 0xcd, 0x80, 0xc3 }
#elif defined(__aarch64__)
{ 0x01, 0x00, 0x00, 0xd4, // svc #0
0xc0, 0x03, 0x5f, 0xd6 } // ret
#endif
;
static void do_write(int fd, const char* p) {
size_t ret;
size_t len = strlen(p);
#ifdef __x86_64__
__asm__ __volatile__("call *%%rcx\n\t"
: "=a"(ret)
: "a"(SYS_write), "c"(ptr), "D"(fd), "S"(p), "d"(len));
#elif __i386__
__asm__ __volatile__("call *%%esi\n\t"
: "=a"(ret)
: "a"(SYS_write), "S"(ptr), "b"(fd), "c"(p), "d"(len));
#elif __aarch64__
register long x8 __asm__("x8") = SYS_write;
register long x7 __asm__("x7") = (long)ptr;
register long x0 __asm__("x0") = (long)fd;
register long x1 __asm__("x1") = (long)p;
register long x2 __asm__("x2") = (long)len;
__asm__ __volatile__("blr x7\n\t"
: "+r"(x0)
: "r"(x1), "r"(x2), "r"(x7), "r"(x8));
ret = x0;
#else
#error Unknown architecture
#endif
test_assert(ret == len);
}
int main(void) {
int fd = open("dummy", O_RDWR | O_CREAT | O_EXCL, 0700);
test_assert(fd >= 0);
unlink("dummy");
test_assert(write(fd, syscall_bytes, sizeof(syscall_bytes)) ==
sizeof(syscall_bytes));
ptr = mmap(NULL, 2, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0);
test_assert(ptr != MAP_FAILED);
do_write(STDOUT_FILENO, "EXIT-SUCCESS\n");
return 0;
}