Skip to content

Instantly share code, notes, and snippets.

@sandip4n
Last active July 5, 2021 08:51
Show Gist options
  • Save sandip4n/4632745499a34eedf4b06ed4f5cc4f34 to your computer and use it in GitHub Desktop.
Save sandip4n/4632745499a34eedf4b06ed4f5cc4f34 to your computer and use it in GitHub Desktop.
/*
* Compile with a cross toolchain and run as shown below.
* $ powerpc64le-linux-gnu-gcc clone-test.c -O0 -nostdlib -static -o clone-test
* $ ./build/POWER/gem5.debug --debug-flags=ExecAll,Registers configs/example/se.py -n 2 -c ./clone-test
*/
#ifndef __powerpc64__
#error "unsupported architecture"
#endif
#define _GNU_SOURCE
#include <sched.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#define STACK_SIZE 65536
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 \n\t"
: "=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(__NR_exit, (long) status, 0, 0, 0, 0, 0, 0);
while (1);
}
void *__mmap(void *addr, size_t length, int prot, int flags, int fd,
off_t offset)
{
return (void *) __syscall(__NR_mmap, (long) addr, (long) length,
(long) prot, (long) flags, (long) fd,
(long) offset, 0);
}
int __munmap(void *addr, size_t length)
{
return (int) __syscall(__NR_munmap, (long) addr, (long) length,
0, 0, 0, 0, 0);
}
int __clone(int flags, void *stack, int *ptid, unsigned long tls, int *ctid)
{
return (int) __syscall(__NR_clone, (long) flags, (long) stack,
(long) ptid, (long) tls, (long) ctid, 0, 0);
}
long __write(int fd, const char *buf, size_t count)
{
return (long) __syscall(__NR_write, (long) fd, (long) buf,
(long) count, 0, 0, 0, 0);
}
const char pmsg[] = "exiting from parent\n";
const char cmsg[] = "exiting from child\n";
void _start(void)
{
void *stack;
int pid;
stack = __mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE | MAP_STACK, -1, 0);
if (stack == MAP_FAILED)
__exit(1);
pid = __clone(0, stack + STACK_SIZE, NULL, 0, NULL);
if (pid < 0)
__exit(1);
if (!pid)
/* exit path of child */
__write(0, cmsg, sizeof(cmsg)), __exit(0);
/* exit path of parent */
__munmap(stack, STACK_SIZE);
__write(0, pmsg, sizeof(pmsg));
__exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment