Skip to content

Instantly share code, notes, and snippets.

@sandip4n
Created August 31, 2021 05:10
Show Gist options
  • Save sandip4n/dbe44351920674071db4e0378edba22f to your computer and use it in GitHub Desktop.
Save sandip4n/dbe44351920674071db4e0378edba22f to your computer and use it in GitHub Desktop.
/*
* Compile as:
* powerpc64-linux-gnu-gcc -o vma-coverage -g -O0 \
* -mcpu=powerpc64 -mno-altivec \
* -mno-vsx -nostdlib -static \
* vma-coverage.c
*/
#ifndef __powerpc64__
#error "unsupported architecture"
#endif
#include <sys/mman.h>
#include <sys/types.h>
#define SYS_exit 1
#define SYS_fork 2
#define SYS_mmap 90
#define SYS_munmap 91
#define SYS_mlock 150
#define EPERM 1
#define ENOENT 2
#define ESRCH 3
#define EINTR 4
#define EIO 5
#define ENXIO 6
#define E2BIG 7
#define ENOEXEC 8
#define EBADF 9
#define ECHILD 10
#define EAGAIN 11
#define ENOMEM 12
#define EACCES 13
#define EFAULT 14
#define ENOTBLK 15
#define EBUSY 16
#define EEXIST 17
#define EXDEV 18
#define ENODEV 19
#define ENOTDIR 20
#define EISDIR 21
#define EINVAL 22
#define ENFILE 23
#define EMFILE 24
#define ENOTTY 25
#define ETXTBSY 26
#define EFBIG 27
#define ENOSPC 28
#define ESPIPE 29
#define EROFS 30
#define EMLINK 31
#define EPIPE 32
#define EDOM 33
#define ERANGE 34
#define PAGE_SIZE (1UL << 16)
#define TASK_SIZE (1UL << 52)
int errno;
long syscall(long syscall, long arg1, long arg2, long arg3, long arg4,
long arg5, long arg6, long arg7)
{
long ret;
int err;
asm volatile("mr 0, 3 \n\t" \
"mr 3, 4 \n\t" \
"mr 4, 5 \n\t" \
"mr 5, 6 \n\t" \
"mr 6, 7 \n\t" \
"mr 7, 8 \n\t" \
"mr 8, 9 \n\t" \
"mr 9, 10 \n\t" \
"sc \n\t" \
"mr %0, 3 \n\t" \
"mfcr %1"
: "=r"(ret), "=r"(err)
:
: "cr0", "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9");
if (err & 0x10000000) {
errno = ret;
ret = -1L;
}
return ret;
}
__attribute__ ((noreturn))
void exit(int status)
{
syscall(SYS_exit, (long) status, 0, 0, 0, 0, 0, 0);
while (1);
}
pid_t fork(void)
{
return (pid_t) syscall(SYS_fork, 0, 0, 0, 0, 0, 0, 0);
}
void *mmap(void *addr, size_t length, int prot, int flags, int fd,
off_t offset)
{
return (void *) syscall(SYS_mmap, (long) addr, (long) length,
(long) prot, (long) flags, (long) fd,
(long) offset, 0);
}
int munmap(void *addr, size_t length)
{
return (int) syscall(SYS_munmap, (long) addr, (long) length,
0, 0, 0, 0, 0);
}
int mlock(const void *addr, size_t length)
{
return (int) syscall(SYS_mlock, (long) addr, (long) length,
0, 0, 0, 0, 0);
}
void _start()
{
unsigned long addr;
void *region;
#ifdef __STRESS
if (!fork())
goto begin;
if (!fork())
goto begin;
if (!fork())
goto begin;
if (!fork())
goto begin;
begin:
#endif
for (addr = 0; addr < TASK_SIZE; addr += 8 * PAGE_SIZE) {
region = mmap((void *) addr, 8 * PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_FIXED_NOREPLACE | MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0);
if (region == MAP_FAILED) {
if (errno == EEXIST || errno == EPERM)
continue;
break;
}
if (mlock(region, 8 * PAGE_SIZE))
break;
/* try to generate a page fault */
*((unsigned int *) (region + 0 * PAGE_SIZE)) = 0xdeadbeef;
*((unsigned int *) (region + 1 * PAGE_SIZE)) = 0xdeadbeef;
*((unsigned int *) (region + 2 * PAGE_SIZE)) = 0xdeadbeef;
*((unsigned int *) (region + 3 * PAGE_SIZE)) = 0xdeadbeef;
*((unsigned int *) (region + 4 * PAGE_SIZE)) = 0xdeadbeef;
*((unsigned int *) (region + 5 * PAGE_SIZE)) = 0xdeadbeef;
*((unsigned int *) (region + 6 * PAGE_SIZE)) = 0xdeadbeef;
*((unsigned int *) (region + 7 * PAGE_SIZE)) = 0xdeadbeef;
if (munmap(region, 8 * PAGE_SIZE))
break;
}
if (addr < TASK_SIZE)
asm volatile("trap");
exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment