|
|
- #pragma once
- #include <cstdint>
- #include <cstddef>
- #include <gp/containers/buffer.hpp>
-
- template<int64_t syscall_id, int arg_count>
- struct syscall;
-
- template<int64_t syscall_id>
- struct syscall<syscall_id, 1> {
- int64_t operator()(int64_t p1) const {
- int64_t ret;
- asm volatile
- (
- "syscall"
- : "=a" (ret)
- : "0"(syscall_id), "D"(p1)
- : "rcx", "r11", "memory"
- );
- return ret;
- }
- };
-
- template<int64_t syscall_id>
- struct syscall<syscall_id, 2> {
- int64_t operator()(int64_t p1,int64_t p2) const {
- int64_t ret;
- asm volatile
- (
- "syscall"
- : "=a" (ret)
- : "0"(syscall_id), "D"(p1), "S"(p2)
- : "rcx", "r11", "memory"
- );
- return ret;
- }
- };
-
- template<int64_t syscall_id>
- struct syscall<syscall_id, 3> {
- int64_t operator()(int64_t p1,int64_t p2,int64_t p3) const {
- int64_t ret;
- asm volatile
- (
- "syscall"
- : "=a" (ret)
- : "0"(syscall_id), "D"(p1), "S"(p2), "d"(p3)
- : "rcx", "r11", "memory"
- );
- return ret;
- }
- };
-
- constexpr auto _read = syscall<0, 3>{};
- constexpr auto _write = syscall<1, 3>{};
- constexpr auto _exit = syscall<60, 1>{};
-
- inline int read(int fd, char* buffer, size_t sz) {
- return _read((int64_t)fd, (int64_t)buffer, (int64_t)sz);
- }
-
- inline int write(int fd, char* buffer, size_t sz) {
- return _write((int64_t)fd, (int64_t)buffer, (int64_t)sz);
- }
-
- inline int read(int fd, gp::buffer<char> buffer) {
- return _read((int64_t)fd, (int64_t)buffer.begin().data, (int64_t)buffer.size());
- }
-
- inline int write(int fd, gp::buffer<char> buffer) {
- return _write((int64_t)fd, (int64_t)buffer.begin().data, (int64_t)buffer.size());
- }
-
- extern "C" {
-
- inline __attribute__ ((__noreturn__)) void exit(int status) {
- _exit((int64_t)status);
- while(true);
- }
-
- }
|