implement more syscalls
This commit is contained in:
parent
93d66e8a25
commit
0f7d978071
8 changed files with 175 additions and 65 deletions
BIN
a.out
BIN
a.out
Binary file not shown.
BIN
grep
Executable file
BIN
grep
Executable file
Binary file not shown.
6
myfile
6
myfile
|
@ -1 +1,5 @@
|
||||||
hello
|
stuff
|
||||||
|
stuff
|
||||||
|
stuff
|
||||||
|
something
|
||||||
|
stuff
|
BIN
sam
Executable file
BIN
sam
Executable file
Binary file not shown.
49
src/main.c
49
src/main.c
|
@ -1,4 +1,3 @@
|
||||||
#include "syscall.h"
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -18,12 +17,14 @@
|
||||||
#include "mach.h"
|
#include "mach.h"
|
||||||
#include "tos.h"
|
#include "tos.h"
|
||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
|
#include "syscall.h"
|
||||||
|
|
||||||
#define ALIGN(v, a) (((v) + (a) - 1) & ~((a) - 1))
|
#define ALIGN(v, a) (((v) + (a) - 1) & ~((a) - 1))
|
||||||
#define DONE_ERR(M_err, M_ret) do { fprintf(stderr, (M_err)); defer_status = (M_ret); goto done; } while(0)
|
#define DONE_ERR(M_err, M_ret) do { fprintf(stderr, (M_err)); defer_status = (M_ret); goto done; } while(0)
|
||||||
|
|
||||||
static char sud_intercept = SYSCALL_DISPATCH_FILTER_ALLOW;
|
static char sud_intercept = SYSCALL_DISPATCH_FILTER_ALLOW;
|
||||||
|
void *data_segment = NULL;
|
||||||
|
size_t data_segment_size = 0;
|
||||||
|
|
||||||
extern void start(uintptr_t entry, Tos* tos, int argc, char **argv);
|
extern void start(uintptr_t entry, Tos* tos, int argc, char **argv);
|
||||||
void enter(uintptr_t entry, int argc, char **argv)
|
void enter(uintptr_t entry, int argc, char **argv)
|
||||||
|
@ -45,14 +46,41 @@ void handle_sigsys(int sig, siginfo_t *info, void *ptr)
|
||||||
int64_t *sp = (int64_t *)gregs[REG_RSP];
|
int64_t *sp = (int64_t *)gregs[REG_RSP];
|
||||||
int64_t syscall = gregs[REG_RBP];
|
int64_t syscall = gregs[REG_RBP];
|
||||||
|
|
||||||
printf("syscall %ld\n", syscall);
|
/*
|
||||||
|
printf("0x%"PRIxPTR"\n", (uintptr_t)info->si_call_addr);
|
||||||
|
|
||||||
|
for (int i = -4; i < 3; i++)
|
||||||
|
printf("%d: 0x%"PRIxPTR"\n", i, sp[i]);
|
||||||
|
printf("donezo\n");
|
||||||
|
*/
|
||||||
|
|
||||||
switch (syscall) {
|
switch (syscall) {
|
||||||
case OPEN:
|
case OPEN:
|
||||||
ret = sys$open((char *)sp[1], (int)sp[2]);
|
ret = sys$open((char *)sp[1], (int)sp[2]);
|
||||||
break;
|
break;
|
||||||
|
case EXITS:
|
||||||
|
sys$exits((char *)sp[1]);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
case PREAD:
|
||||||
|
ret = sys$pread((int)sp[1], (void*)sp[2], (int64_t)sp[3], (int64_t)sp[4]);
|
||||||
|
break;
|
||||||
|
case PWRITE:
|
||||||
|
ret = sys$pwrite((int)sp[1], (void*)sp[2], (int64_t)sp[3], (int64_t)sp[4]);
|
||||||
|
break;
|
||||||
|
case CLOSE:
|
||||||
|
ret = sys$close((int)sp[1]);
|
||||||
|
break;
|
||||||
|
case BRK_:
|
||||||
|
ret = sys$brk((void*)sp[1], data_segment, &data_segment_size);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("unimplemented syscall %ld\n", syscall);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//printf("ret = %ld\n", ret);
|
||||||
|
|
||||||
gregs[REG_RAX] = ret;
|
gregs[REG_RAX] = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +107,7 @@ int findlibc(struct dl_phdr_info *info, size_t size, void *ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *program_argv[] = {
|
static char *program_argv[] = {
|
||||||
"out",
|
"sam",
|
||||||
"../myfile",
|
"../myfile",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
@ -93,7 +121,7 @@ int main()
|
||||||
size_t text_addr = 0x200000;
|
size_t text_addr = 0x200000;
|
||||||
size_t data_addr;
|
size_t data_addr;
|
||||||
|
|
||||||
f = fopen("../a.out", "rb");
|
f = fopen("../sam", "rb");
|
||||||
|
|
||||||
if (fread(&header, 1, sizeof(header), f) != sizeof(header)) {
|
if (fread(&header, 1, sizeof(header), f) != sizeof(header)) {
|
||||||
DONE_ERR("failed to read file header\n", 1);
|
DONE_ERR("failed to read file header\n", 1);
|
||||||
|
@ -109,6 +137,8 @@ int main()
|
||||||
|
|
||||||
data_addr = ALIGN(text_addr + header.text, 0x200000);
|
data_addr = ALIGN(text_addr + header.text, 0x200000);
|
||||||
|
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
|
||||||
size_t segments_size = sizeof(Exec) + header.text + header.data;
|
size_t segments_size = sizeof(Exec) + header.text + header.data;
|
||||||
file_segments = malloc(segments_size);
|
file_segments = malloc(segments_size);
|
||||||
if (!file_segments) {
|
if (!file_segments) {
|
||||||
|
@ -125,14 +155,15 @@ int main()
|
||||||
}
|
}
|
||||||
printf("mapped text segment at 0x%"PRIxPTR"\n", (uintptr_t)text_segment);
|
printf("mapped text segment at 0x%"PRIxPTR"\n", (uintptr_t)text_segment);
|
||||||
|
|
||||||
void *data_segment = mmap((void*)data_addr, header.data + header.bss, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
data_segment_size = header.data + header.bss;
|
||||||
|
data_segment = mmap((void*)data_addr, data_segment_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||||
if (!text_segment) {
|
if (!text_segment) {
|
||||||
DONE_ERR("failed to map data segment into memory\n", 1);
|
DONE_ERR("failed to map data segment into memory\n", 1);
|
||||||
}
|
}
|
||||||
printf("mapped data segment at 0x%"PRIxPTR"\n", (uintptr_t)data_segment);
|
printf("mapped data segment at 0x%"PRIxPTR"\n", (uintptr_t)data_segment);
|
||||||
|
|
||||||
memcpy(text_segment, file_segments, header.text);
|
memcpy(text_segment, file_segments, header.text + sizeof(Exec));
|
||||||
memcpy(data_segment, file_segments + sizeof(Exec) + header.text, header.data);
|
memcpy(data_segment, file_segments + header.text + sizeof(Exec), header.data);
|
||||||
|
|
||||||
if (dl_iterate_phdr(findlibc, NULL) != 1) {
|
if (dl_iterate_phdr(findlibc, NULL) != 1) {
|
||||||
DONE_ERR("failed to find libc and enable SUD\n", 1);
|
DONE_ERR("failed to find libc and enable SUD\n", 1);
|
||||||
|
@ -144,7 +175,7 @@ int main()
|
||||||
};
|
};
|
||||||
sigaction(SIGSYS, &sa, NULL);
|
sigaction(SIGSYS, &sa, NULL);
|
||||||
|
|
||||||
enter(header.entry32, 2, program_argv);
|
enter(header.entry32, 3, program_argv);
|
||||||
done:
|
done:
|
||||||
free(file_segments);
|
free(file_segments);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
104
src/sys.h
104
src/sys.h
|
@ -1,52 +1,52 @@
|
||||||
#define SYSR1 0
|
#define SYSR1 0
|
||||||
#define _ERRSTR 1
|
#define _ERRSTR 1
|
||||||
#define BIND 2
|
#define BIND 2
|
||||||
#define CHDIR 3
|
#define CHDIR 3
|
||||||
#define CLOSE 4
|
#define CLOSE 4
|
||||||
#define DUP 5
|
#define DUP 5
|
||||||
#define ALARM 6
|
#define ALARM 6
|
||||||
#define EXEC 7
|
#define EXEC 7
|
||||||
#define EXITS 8
|
#define EXITS 8
|
||||||
#define _FSESSION 9
|
#define _FSESSION 9
|
||||||
#define FAUTH 10
|
#define FAUTH 10
|
||||||
#define _FSTAT 11
|
#define _FSTAT 11
|
||||||
#define SEGBRK 12
|
#define SEGBRK 12
|
||||||
#define _MOUNT 13
|
#define _MOUNT 13
|
||||||
#define OPEN 14
|
#define OPEN 14
|
||||||
#define _READ 15
|
#define _READ 15
|
||||||
#define OSEEK 16
|
#define OSEEK 16
|
||||||
#define SLEEP 17
|
#define SLEEP 17
|
||||||
#define _STAT 18
|
#define _STAT 18
|
||||||
#define RFORK 19
|
#define RFORK 19
|
||||||
#define _WRITE 20
|
#define _WRITE 20
|
||||||
#define PIPE 21
|
#define PIPE 21
|
||||||
#define CREATE 22
|
#define CREATE 22
|
||||||
#define FD2PATH 23
|
#define FD2PATH 23
|
||||||
#define BRK_ 24
|
#define BRK_ 24
|
||||||
#define REMOVE 25
|
#define REMOVE 25
|
||||||
#define _WSTAT 26
|
#define _WSTAT 26
|
||||||
#define _FWSTAT 27
|
#define _FWSTAT 27
|
||||||
#define NOTIFY 28
|
#define NOTIFY 28
|
||||||
#define NOTED 29
|
#define NOTED 29
|
||||||
#define SEGATTACH 30
|
#define SEGATTACH 30
|
||||||
#define SEGDETACH 31
|
#define SEGDETACH 31
|
||||||
#define SEGFREE 32
|
#define SEGFREE 32
|
||||||
#define SEGFLUSH 33
|
#define SEGFLUSH 33
|
||||||
#define RENDEZVOUS 34
|
#define RENDEZVOUS 34
|
||||||
#define UNMOUNT 35
|
#define UNMOUNT 35
|
||||||
#define _WAIT 36
|
#define _WAIT 36
|
||||||
#define SEMACQUIRE 37
|
#define SEMACQUIRE 37
|
||||||
#define SEMRELEASE 38
|
#define SEMRELEASE 38
|
||||||
#define SEEK 39
|
#define SEEK 39
|
||||||
#define FVERSION 40
|
#define FVERSION 40
|
||||||
#define ERRSTR 41
|
#define ERRSTR 41
|
||||||
#define STAT 42
|
#define STAT 42
|
||||||
#define FSTAT 43
|
#define FSTAT 43
|
||||||
#define WSTAT 44
|
#define WSTAT 44
|
||||||
#define FWSTAT 45
|
#define FWSTAT 45
|
||||||
#define MOUNT 46
|
#define MOUNT 46
|
||||||
#define AWAIT 47
|
#define AWAIT 47
|
||||||
#define PREAD 50
|
#define PREAD 50
|
||||||
#define PWRITE 51
|
#define PWRITE 51
|
||||||
#define TSEMACQUIRE 52
|
#define TSEMACQUIRE 52
|
||||||
#define _NSEC 53
|
#define _NSEC 53
|
||||||
|
|
|
@ -2,10 +2,30 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
|
|
||||||
|
char *errstr = NULL;
|
||||||
|
|
||||||
|
static int check_error(int ret)
|
||||||
|
{
|
||||||
|
if (ret < 0) {
|
||||||
|
errstr = strerror(errno);
|
||||||
|
fprintf(stderr, "errstr says: %s\n", errstr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int mode_open(char *name, int mode, int perm, int flag)
|
static int mode_open(char *name, int mode, int perm, int flag)
|
||||||
{
|
{
|
||||||
|
printf("open %s\n", name);
|
||||||
|
|
||||||
switch (mode & 3) {
|
switch (mode & 3) {
|
||||||
case 0: flag |= O_RDONLY; break;
|
case 0: flag |= O_RDONLY; break;
|
||||||
case 1: flag |= O_WRONLY; break;
|
case 1: flag |= O_WRONLY; break;
|
||||||
|
@ -22,7 +42,54 @@ static int mode_open(char *name, int mode, int perm, int flag)
|
||||||
|
|
||||||
int sys$open(char *path, int mode)
|
int sys$open(char *path, int mode)
|
||||||
{
|
{
|
||||||
printf("sys$open(0x%"PRIxPTR", %d)\n", (uintptr_t)path, mode);
|
return check_error(mode_open(path, mode, 0, 0));
|
||||||
|
}
|
||||||
return mode_open(path, mode, 0, 0);
|
|
||||||
|
int sys$exits(char *msg)
|
||||||
|
{
|
||||||
|
if (!msg) {
|
||||||
|
printf("program exited successfully\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("program exited with error message: %s\n", msg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys$pread(int fd, void *buf, int64_t nbytes, int64_t offset)
|
||||||
|
{
|
||||||
|
if (offset < 0) {
|
||||||
|
return check_error(read(fd, buf, nbytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
return check_error(pread(fd, buf, nbytes, offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys$pwrite(int fd, void *buf, int64_t nbytes, int64_t offset)
|
||||||
|
{
|
||||||
|
if (fd != 1 && fd != 2) {
|
||||||
|
fprintf(stderr, "Oh no.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset < 0) {
|
||||||
|
return check_error(write(fd, buf, nbytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
return check_error(pwrite(fd, buf, nbytes, offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys$close(int fd)
|
||||||
|
{
|
||||||
|
return check_error(close(fd));
|
||||||
|
}
|
||||||
|
|
||||||
|
int sys$brk(void *addr, void *_data_segment, size_t *_data_segment_size)
|
||||||
|
{
|
||||||
|
size_t new_size = addr - _data_segment;
|
||||||
|
if (mremap(_data_segment, *_data_segment_size, new_size, 0) == MAP_FAILED) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*_data_segment_size = new_size;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
int sys$open(char *path, int mode);
|
int sys$open(char *path, int mode);
|
||||||
|
int sys$exits(char *msg);
|
||||||
|
int sys$pread(int fd, void *buf, int64_t nbytes, int64_t offset);
|
||||||
|
int sys$pwrite(int fd, void *buf, int64_t nbytes, int64_t offset);
|
||||||
|
int sys$close(int fd);
|
||||||
|
int sys$brk(void *addr, void *_data_segment, size_t *_data_segment_size);
|
||||||
|
|
Loading…
Reference in a new issue