liblinux++

Log | Files | Refs

commit e1bb4555001f97b03a501bab39c9ad6341055161
parent bb953343daf4a229c1538a2bce2d0266f11a808c
Author: Henry Wilson <henry@henryandlizzy.uk>
Date:   Mon, 22 Dec 2025 01:21:36 +0000

Initial C++ support

Diffstat:
MTupfile | 2++
Mlinux.h | 8++++++++
Alinux.hpp | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dtest.c | 22----------------------
Atest.cpp | 22++++++++++++++++++++++
Atrue.cpp | 2++
Mx86_64.s | 50++++++++++++++++++++++++++++++++++----------------
7 files changed, 142 insertions(+), 38 deletions(-)

diff --git a/Tupfile b/Tupfile @@ -2,8 +2,10 @@ CFLAGS = -g -Os -fno-asynchronous-unwind-tables -fno-pic -fno-pie -no-pie -g -fn LDFLAGS = -static -nostartfiles -nolibc -nodefaultlibs -nostdlib -fno-pic -fno-pie -no-pie -Xlinker --gc-sections !cc = |> cc $(CFLAGS) -c -o %o %f |> obj/%B.o +!c++ = |> c++ $(CFLAGS) -c -o %o %f |> obj/%B.o : foreach *.c |> !cc |> {objs} +: foreach *.cpp |> !c++ |> {objs} run ./gen.sh .gitignore diff --git a/linux.h b/linux.h @@ -1,5 +1,9 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + typedef unsigned long long size_t; typedef signed long long ssize_t; typedef unsigned long long uintptr_t; @@ -64,3 +68,7 @@ static unsigned get_errno(ssize_t ret) return -ret; return 0; } + +#ifdef __cplusplus +} +#endif diff --git a/linux.hpp b/linux.hpp @@ -0,0 +1,74 @@ +#pragma once + +typedef unsigned long long size_t; +typedef signed long long ssize_t; +typedef unsigned long long uintptr_t; +typedef signed long long intptr_t; +typedef unsigned long long ino64_t; +typedef signed long long off64_t; + +enum { + AT_FDCWD = -100, + + O_RDONLY = 0, + O_WRONLY = 1, + O_RDWR = 2, + + PROT_READ = 0x1, + PROT_WRITE = 0x2, + PROT_EXEC = 0x4, + MAP_FIXED = 0x10, + MAP_ANONYMOUS = 0x20, + MAP_SHARED = 0x1, + MAP_PRIVATE = 0x2, + + DT_UNKNOWN = 0, + DT_FIFO = 1, + DT_CHR = 2, + DT_DIR = 4, + DT_BLK = 6, + DT_REG = 8, + DT_LNK = 10, + DT_SOCK = 12, + DT_WHT = 14, +}; + +struct iovecc +{ + char const* data; + size_t len; +}; + +__attribute__((noreturn)) +extern void exit(int error_code); + +extern int read(int fd, char* data, size_t count); + +extern "C" { +extern int write(int fd, char const* data, size_t count); +} +extern int write(int fd, iovecc data); + +extern ssize_t writev(int fd, struct iovecc const* iov, size_t count); + +extern int openat(int fd, char const* name, int flags, int mode); + +extern int close(int fd); + +struct linux_dirent64 { + ino64_t d_ino; /* 64-bit inode number */ + off64_t d_off; /* Not an offset; see getdents() */ + unsigned short d_reclen; /* Size of this dirent */ + unsigned char d_type; /* File type */ + char d_name[]; /* Filename (null-terminated) */ +}; +extern ssize_t getdents64(int fd, struct linux_dirent64 dirp[], size_t count); + +extern intptr_t mmap(void* addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off); + +static unsigned get_errno(ssize_t ret) +{ + if (0 > ret && ret >= -0xFFFF) + return -ret; + return 0; +} diff --git a/test.c b/test.c @@ -1,22 +0,0 @@ -#include "linux.h" - -char const rodata[] = "rodata\n"; -char data[] = "data\n"; -char bss[4]; - -void text() -{ - write(1, rodata, sizeof(rodata) - 1); - write(1, data, sizeof(data) - 1); - - bss[0] = 'b'; - bss[1] = 's'; - bss[2] = 's'; - bss[3] = '\n'; - write(1, bss, sizeof(bss)); -} - -int main() -{ - text(); -} diff --git a/test.cpp b/test.cpp @@ -0,0 +1,22 @@ +#include "linux.hpp" + +char const rodata[] = "rodata\n"; +char data[] = "data\n"; +char bss[4]; + +void text() +{ + write(1, {rodata, sizeof(rodata) - 1}); + write(1, {data, sizeof(data) - 1}); + + bss[0] = 'b'; + bss[1] = 's'; + bss[2] = 's'; + bss[3] = '\n'; + write(1, bss, sizeof(bss)); +} + +int main() +{ + text(); +} diff --git a/true.cpp b/true.cpp @@ -0,0 +1,2 @@ +int main() +{} diff --git a/x86_64.s b/x86_64.s @@ -12,14 +12,22 @@ start: # start is the entry point known to the linker mov rdi, rax jmp exit -.macro _syscall, num, impl, name +.macro extern_alias, name .global \name -.section .text.\name \name: +.endm + +.macro extern, name +.section .text.\name +extern_alias \name +.endm + +.macro _syscall, num, impl mov rax, \num jmp \impl .endm +.section .text.syscall3 syscall3: push r11 push rcx @@ -28,6 +36,7 @@ syscall3: pop r11 ret +.section .text.syscall6 syscall6: push r11 mov r10, rcx @@ -35,18 +44,27 @@ syscall6: pop r11 ret -.macro syscall6, num, name -.global \name -.section .text.\name -\name: - mov rax, \num -.endm +extern read +_syscall 0 syscall3 + +extern write +extern_alias _Z5writei6iovecc +_syscall 1 syscall3 + +extern close +_syscall 3 syscall3 + +extern mmap +_syscall 9 syscall6 + +extern writev +_syscall 20 syscall3 + +extern exit +_syscall 60 syscall3 + +extern getdents64 +_syscall 217 syscall3 -_syscall 0 syscall3 read -_syscall 1 syscall3 write -_syscall 3 syscall3 close -_syscall 9 syscall6 mmap -_syscall 20 syscall3 writev -_syscall 60 syscall3 exit -_syscall 217 syscall3 getdents64 -_syscall 257 syscall6 openat +extern openat +_syscall 257 syscall6