Added unistd.h and some linux syscall wrappers

This commit is contained in:
Max Wash
2020-03-31 18:36:58 +01:00
parent 76d1753ab5
commit 5e3d012bf7
17 changed files with 450 additions and 7 deletions

View File

@@ -39,7 +39,7 @@ set(CMAKE_EXE_LINKER_FLAGS
"${CMAKE_EXE_LINKER_FLAGS} -ffreestanding -nostdlib -lgcc") "${CMAKE_EXE_LINKER_FLAGS} -ffreestanding -nostdlib -lgcc")
set(photon_libc_sources "") set(photon_libc_sources "")
set(generic_dirs string) set(generic_dirs string stdio)
foreach (dir ${generic_dirs}) foreach (dir ${generic_dirs})
file(GLOB dir_sources ${CMAKE_CURRENT_SOURCE_DIR}/photon/libc/${dir}/*.c) file(GLOB dir_sources ${CMAKE_CURRENT_SOURCE_DIR}/photon/libc/${dir}/*.c)
@@ -74,6 +74,7 @@ target_compile_options(c PRIVATE -ffreestanding -nostdlib -nostdinc)
target_link_libraries(c crt) target_link_libraries(c crt)
target_include_directories(c PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/photon/libc/include) target_include_directories(c PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/photon/libc/include)
target_include_directories(c PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/photon/libc/sys/${PLATFORM}/)
add_custom_target(sysroot add_custom_target(sysroot
DEPENDS ${photon_libc_headers} DEPENDS ${photon_libc_headers}

View File

@@ -23,6 +23,8 @@ extern FILE *stdin;
extern FILE *stdout; extern FILE *stdout;
extern FILE *stderr; extern FILE *stderr;
extern int fileno(FILE *fp);
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif #endif

View File

@@ -0,0 +1,11 @@
#ifndef TIME_H_
#define TIME_H_
#include <sys/types.h>
struct timespec {
time_t tv_sec;
long tv_nsec;
};
#endif

View File

@@ -0,0 +1,7 @@
#include <__fio.h>
#include <stdio.h>
int fileno(FILE *f)
{
return __fileno(f);
}

View File

@@ -13,6 +13,8 @@ struct __io_file {
unsigned int fd; unsigned int fd;
}; };
extern int __fileno(struct __io_file *f);
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif #endif

View File

@@ -0,0 +1,17 @@
#ifndef SYS_LINUX___SYSCALL_H_
#define SYS_LINUX___SYSCALL_H_
#include <stdint.h>
extern intptr_t __syscall0(unsigned int id);
extern intptr_t __syscall1(unsigned int id, uintptr_t p0);
extern intptr_t __syscall2(unsigned int id, uintptr_t p0, uintptr_t p1);
extern intptr_t __syscall3(uintptr_t id, uintptr_t p0, uintptr_t p1, uintptr_t p2);
extern intptr_t __syscall4(unsigned int id, uintptr_t p0, uintptr_t p1, uintptr_t p2,
uintptr_t p3);
extern intptr_t __syscall5(unsigned int id, uintptr_t p0, uintptr_t p1, uintptr_t p2,
uintptr_t p3, uintptr_t p4);
extern intptr_t __syscall6(unsigned int id, uintptr_t p0, uintptr_t p1, uintptr_t p2,
uintptr_t p3, uintptr_t p4, uintptr_t p5);
#endif

View File

@@ -1,4 +1,5 @@
#include "__fio.h" #include "__fio.h"
#include "__syscall.h"
struct __io_file __stdin = {}; struct __io_file __stdin = {};
struct __io_file __stdout = {}; struct __io_file __stdout = {};
@@ -14,3 +15,8 @@ void __fio_init()
__stdout.fd = 1; __stdout.fd = 1;
__stderr.fd = 2; __stderr.fd = 2;
} }
int __fileno(struct __io_file *f)
{
return f->fd;
}

View File

@@ -0,0 +1,108 @@
#include <stdint.h>
intptr_t __syscall0(uintptr_t id)
{
intptr_t ret = 0;
asm volatile("mov %1, %%rax; syscall; mov %%rax, %0"
: "=m" (ret)
: "m" (id));
return ret;
}
intptr_t __syscall1(uintptr_t id, uintptr_t p0)
{
intptr_t ret = 0;
asm volatile(
"mov %1, %%rax;"
"mov %2, %%rdi;"
"syscall;"
"mov %%rax, %0"
: "=m" (ret)
: "m" (id), "m" (p0));
return ret;
}
intptr_t __syscall2(uintptr_t id, uintptr_t p0, uintptr_t p1)
{
intptr_t ret = 0;
asm volatile(
"mov %1, %%rax;"
"mov %2, %%rdi;"
"mov %3, %%rsi;"
"syscall;"
"mov %%rax, %0"
: "=m" (ret)
: "m" (id), "m" (p0), "m" (p1));
return ret;
}
intptr_t __syscall3(uintptr_t id, uintptr_t p0, uintptr_t p1, uintptr_t p2)
{
intptr_t ret = 0;
asm volatile(
"movq %1, %%rax;"
"mov %2, %%rdi;"
"mov %3, %%rsi;"
"mov %4, %%rdx;"
"syscall;"
"mov %%rax, %0"
: "=m" (ret)
: "m" (id), "m" (p0), "m" (p1), "m" (p2));
return ret;
}
intptr_t __syscall4(uintptr_t id, uintptr_t p0, uintptr_t p1, uintptr_t p2,
uintptr_t p3)
{
intptr_t ret = 0;
asm volatile(
"mov %1, %%rax;"
"mov %2, %%rdi;"
"mov %3, %%rsi;"
"mov %4, %%rdx;"
"mov %5, %%r10;"
"syscall;"
"mov %%rax, %0"
: "=m" (ret)
: "m" (id), "m" (p0), "m" (p1), "m" (p2), "m" (p3));
return ret;
}
intptr_t __syscall5(uintptr_t id, uintptr_t p0, uintptr_t p1, uintptr_t p2,
uintptr_t p3, uintptr_t p4)
{
intptr_t ret = 0;
asm volatile(
"mov %1, %%rax;"
"mov %2, %%rdi;"
"mov %3, %%rsi;"
"mov %4, %%rdx;"
"mov %5, %%r10;"
"mov %6, %%r8;"
"syscall;"
"mov %%rax, %0"
: "=m" (ret)
: "m" (id), "m" (p0), "m" (p1), "m" (p2), "m" (p3), "m" (p4));
return ret;
}
intptr_t __syscall6(uintptr_t id, uintptr_t p0, uintptr_t p1, uintptr_t p2,
uintptr_t p3, uintptr_t p4, uintptr_t p5)
{
intptr_t ret = 0;
asm volatile(
"mov %1, %%rax;"
"mov %2, %%rdi;"
"mov %3, %%rsi;"
"mov %4, %%rdx;"
"mov %5, %%r10;"
"mov %6, %%r8;"
"mov %7, %%r9;"
"syscall;"
"mov %%rax, %0"
: "=m" (ret)
: "m" (id), "m" (p0), "m" (p1), "m" (p2), "m" (p3), "m" (p4),
"m" (p5));
return ret;
}

View File

@@ -0,0 +1,33 @@
#ifndef SYS_LINUX_POLL_H_
#define SYS_LINUX_POLL_H_
#define POLLIN 0x1
#define POLLPRI 0x2
#define POLLOUT 0x4
#define POLLERR 0x8
#define POLLHUP 0x10
#define POLLNVAL 0x20
#define POLLRDNORM 0x40
#define POLLRDBAND 0x80
#define POLLWRNORM 0x100
#define POLLWRBAND 0x200
#if defined(__cplusplus)
extern "C" {
#endif
typedef unsigned long long nfds_t;
struct pollfd {
int fd;
short events;
short revents;
};
extern int poll(struct pollfd *fds, nfds_t nfds, int timeout);
#if defined(__cplusplus)
}
#endif
#endif

View File

@@ -1,5 +1,5 @@
#ifndef SYS_LINUX__FCONST_H_ #ifndef SYS_LINUX_SYS__FCONST_H_
#define SYS_LINUX__FCONST_H_ #define SYS_LINUX_SYS__FCONST_H_
#define __FILENAME_MAX 1024 #define __FILENAME_MAX 1024

View File

@@ -0,0 +1,24 @@
#ifndef SYS_LINUX_SYS_STAT_H_
#define SYS_LINUX_SYS_STAT_H_
#include <time.h>
#include <sys/types.h>
struct stat {
dev_t st_dev;
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
off_t st_size;
blksize_t st_blksize;
blkcnt_t st_blocks;
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
};
#endif

View File

@@ -0,0 +1,22 @@
#ifndef SYS_LINUX_SYSCALL_H_
#define SYS_LINUX_SYSCALL_H_
#define SYS_read 0
#define SYS_write 1
#define SYS_open 2
#define SYS_close 3
#define SYS_stat 4
#define SYS_fstat 5
#define SYS_lstat 6
#define SYS_poll 7
#define SYS_lseek 8
#define SYS_mmap 9
#define SYS_mprotect 10
#define SYS_munmap 11
#define SYS_brk 12
#define SYS_rt_sigaction 13
#define SYS_rt_sigprocmask 14
#define SYS_rt_sigreturn 15
#define SYS_ioctl 16
#endif

View File

@@ -0,0 +1,24 @@
#ifndef SYS_LINUX_SYS_TYPES_H_
#define SYS_LINUX_SYS_TYPES_H_
typedef signed long long blkcnt_t;
typedef signed long long blksize_t;
typedef unsigned long long clock_t;
typedef unsigned int clockid_t;
typedef unsigned long long fsblkcnt_t;
typedef unsigned long long fsfilcnt_t;
typedef unsigned int gid_t;
typedef unsigned int id_t;
typedef unsigned long long ino_t;
typedef unsigned int key_t;
typedef unsigned int mode_t;
typedef unsigned long long nlink_t;
typedef signed long long off_t;
typedef signed int pid_t;
typedef unsigned long long time_t;
typedef unsigned int timer_t;
typedef unsigned int uid_t;
typedef unsigned long useconds_t;
typedef unsigned long long dev_t;
#endif

View File

@@ -0,0 +1,155 @@
#include "poll.h"
#include "sys/syscall.h"
#include "__syscall.h"
#include "unistd.h"
ssize_t read(int fd, void *buf, size_t count)
{
intptr_t res = __syscall3(SYS_read, (uintptr_t)fd, (uintptr_t)buf,
(uintptr_t)count);
if (res < 0) {
return -1;
}
return (ssize_t)res;
}
ssize_t write(int fd, const void *buf, size_t count)
{
intptr_t res = __syscall3(SYS_write, (uintptr_t)fd, (uintptr_t)buf,
(uintptr_t)count);
if (res < 0) {
return -1;
}
return (ssize_t)res;
}
int open(const char *pathname, int flags)
{
intptr_t res = __syscall3(SYS_open, (uintptr_t)pathname,
(uintptr_t)flags, 0);
if (res < 0) {
return -1;
}
return (int)res;
}
int close(int fd)
{
intptr_t res = __syscall1(SYS_close, (uintptr_t)fd);
if (res < 0) {
return -1;
}
return (int)res;
}
int stat(const char *pathname, struct stat *statbuf)
{
intptr_t res = __syscall2(SYS_stat, (uintptr_t)pathname,
(uintptr_t)statbuf);
if (res < 0) {
return -1;
}
return (int)res;
}
int fstat(int fd, struct stat *statbuf)
{
intptr_t res = __syscall2(SYS_fstat, (uintptr_t)fd,
(uintptr_t)statbuf);
if (res < 0) {
return -1;
}
return (int)res;
}
int lstat(const char *pathname, struct stat *statbuf)
{
intptr_t res = __syscall2(SYS_lstat, (uintptr_t)pathname,
(uintptr_t)statbuf);
if (res < 0) {
return -1;
}
return (int)res;
}
int poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
intptr_t res = __syscall3(SYS_poll, (uintptr_t)fds,
(uintptr_t)nfds, (uintptr_t)timeout);
if (res < 0) {
return -1;
}
return (int)res;
}
off_t lseek(int fd, off_t offset, int whence)
{
intptr_t res = __syscall3(SYS_lseek, (uintptr_t)fd,
(uintptr_t)offset, (uintptr_t)whence);
if (res < 0) {
return -1;
}
return (int)res;
}
void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off)
{
intptr_t res = __syscall6(SYS_mmap, (uintptr_t)addr, (uintptr_t)len,
(uintptr_t)prot, (uintptr_t)flags, (uintptr_t)fd, (uintptr_t)off);
if (res < 0) {
return NULL;
}
return (void *)res;
}
int mprotect(void *addr, size_t len, int prot)
{
intptr_t res = __syscall3(SYS_mprotect, (uintptr_t)addr, (uintptr_t)len,
(uintptr_t)prot);
if (res < 0) {
return -1;
}
return (int)res;
}
int munmap(void *addr, size_t length)
{
intptr_t res = __syscall2(SYS_munmap, (uintptr_t)addr, (uintptr_t)length);
if (res < 0) {
return -1;
}
return (int)res;
}
int brk(void *addr)
{
intptr_t res = __syscall1(SYS_brk, (uintptr_t)addr);
if (res < 0) {
return -1;
}
return (int)res;
}
int ioctl(int fd, unsigned long req, void *arg)
{
intptr_t res = __syscall3(SYS_ioctl, (uintptr_t)fd, (uintptr_t)req,
(uintptr_t)arg);
if (res < 0) {
return -1;
}
return (int)res;
}

View File

@@ -0,0 +1,27 @@
#ifndef SYS_LINUX_UNISTD_H_
#define SYS_LINUX_UNISTD_H_
#include <stddef.h>
#include <sys/types.h>
struct stat;
struct pollfd;
typedef __intptr_t ssize_t;
extern ssize_t read(int fd, void *buf, size_t count);
extern ssize_t write(int fd, const void *buf, size_t count);
extern int open(const char *pathname, int flags);
extern int close(int fd);
extern int stat(const char *pathname, struct stat *statbuf);
extern int fstat(int fd, struct stat *statbuf);
extern int lstat(const char *pathname, struct stat *statbuf);
extern off_t lseek(int fd, off_t offset, int whence);
extern void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
extern int mprotect(void *addr, size_t len, int prot);
extern int munmap(void *addr, size_t length);
extern int brk(void *addr);
extern int ioctl(int fd, unsigned long request, void *arg);
#endif

View File

@@ -10,8 +10,10 @@ mkdir -p $build_dir/sysroot/usr/include/{sys,machine}
cp $source_dir/photon/libc/include/*.h $build_dir/sysroot/usr/include cp $source_dir/photon/libc/include/*.h $build_dir/sysroot/usr/include
platform_headers=$(find $source_dir/photon/libc/sys/$platform -type f \( -iname "*.h" ! -iname "__*" \)) platform_headers=$(find $source_dir/photon/libc/sys/$platform -maxdepth 1 -type f \( -iname "*.h" ! -iname "__*" \))
cp -t $build_dir/sysroot/usr/include/sys $platform_headers platform_sys_headers=$(find $source_dir/photon/libc/sys/$platform/sys -maxdepth 1 -type f \( -iname "*.h" ! -iname "__*" \))
cp -t $build_dir/sysroot/usr/include $platform_headers
cp -t $build_dir/sysroot/usr/include/sys $platform_sys_headers
machine_arch_headers=$(find $source_dir/photon/libc/machine/$machine/ \ machine_arch_headers=$(find $source_dir/photon/libc/machine/$machine/ \
-type f \( -iname "*.h" ! -iname "__*" \)) -type f \( -iname "*.h" ! -iname "__*" \))

View File

@@ -1,7 +1,9 @@
#include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <stdint.h>
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
return 42; const char *msg = "Hello!\n";
write(fileno(stdout), msg, 7);
return 0;
} }