Last active
July 5, 2021 08:51
-
-
Save sandip4n/4632745499a34eedf4b06ed4f5cc4f34 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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