Compare commits
2 Commits
d5be4cfe0b
...
729772ccbe
| Author | SHA1 | Date | |
|---|---|---|---|
|
729772ccbe
|
|||
|
4cacdeb012
|
@@ -17,11 +17,22 @@ target_link_libraries(strings PRIVATE c-libs)
|
||||
add_executable(rc ${CMAKE_CURRENT_SOURCE_DIR}/app/rc.c)
|
||||
target_link_libraries(rc PRIVATE c-libs)
|
||||
|
||||
add_executable(nolibc ${CMAKE_CURRENT_SOURCE_DIR}/app/nolibc.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/app/entry.s)
|
||||
add_library(
|
||||
sys STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/sys/entry.s
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/sys/syscall.s
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/sys/syscall.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/sys/memory.c)
|
||||
target_include_directories(
|
||||
sys PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>)
|
||||
|
||||
add_executable(nolibc ${CMAKE_CURRENT_SOURCE_DIR}/app/nolibc.c)
|
||||
target_link_libraries(nolibc PRIVATE sys)
|
||||
target_compile_options(
|
||||
nolibc PRIVATE -fno-asynchronous-unwind-tables -fno-unwind-tables
|
||||
-fno-stack-protector -ffunction-sections -fdata-sections)
|
||||
nolibc
|
||||
PRIVATE -fno-asynchronous-unwind-tables -fno-unwind-tables
|
||||
-fno-stack-protector -ffunction-sections -fdata-sections -fno-builtin)
|
||||
target_link_options(
|
||||
nolibc
|
||||
PRIVATE
|
||||
@@ -50,7 +61,7 @@ include(CMakePackageConfigHelpers)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
install(
|
||||
TARGETS c-libs
|
||||
TARGETS c-libs sys
|
||||
EXPORT c-libs
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
|
||||
29
app/entry.s
29
app/entry.s
@@ -1,29 +0,0 @@
|
||||
.global _start, syscall5
|
||||
|
||||
|
||||
_start:
|
||||
/* Load argc -> rdi, argv[0] -> rsi */
|
||||
xor %rbp, %rbp
|
||||
pop %rdi
|
||||
mov %rsp, %rsi
|
||||
|
||||
and $0xFFFFFFFFFFFFFFF0, %rsp
|
||||
|
||||
call main
|
||||
|
||||
/* Exit with ret val of main */
|
||||
mov %rax, %rdi
|
||||
mov $0x3C, %rax
|
||||
syscall
|
||||
|
||||
syscall5:
|
||||
mov %rdi, %rax /* %rax (syscall number) = func param 1 (%rdi) */
|
||||
mov %rsi, %rdi /* %rdi (syscall param 1) = func param 2 (%rsi) */
|
||||
mov %rdx, %rsi /* %rsi (syscall param 2) = func param 3 (%rdx) */
|
||||
mov %rcx, %rdx /* %rdx (syscall param 3) = func param 4 (%rcx) */
|
||||
mov %r8, %r10 /* %r10 (syscall param 4) = func param 5 (%r8) */
|
||||
mov %r9, %r8 /* %r8 (syscall param 5) = func param 6 (%r9) */
|
||||
syscall /* Enter a syscall (return value in %rax) */
|
||||
ret /* Return value is already in %rax, we can return. */
|
||||
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
25
app/nolibc.c
25
app/nolibc.c
@@ -1,18 +1,19 @@
|
||||
void *syscall5(void *number, void *arg1, void *arg2, void *arg3, void *arg4,
|
||||
void *arg5);
|
||||
#include <c-libs/sys/memory.h>
|
||||
#include <c-libs/sys/syscall.h>
|
||||
|
||||
typedef unsigned long int size_t;
|
||||
typedef long int ssize_t;
|
||||
|
||||
static ssize_t write(int fd, void const *data, size_t nbytes) {
|
||||
return (ssize_t)syscall5((void *)1, /* SYS_write, call number 1 */
|
||||
(void *)(size_t)fd, (void *)data, (void *)nbytes,
|
||||
0, /* Ignored */
|
||||
0 /* Ignored */
|
||||
);
|
||||
void strcpy(char *dst, const char *src) {
|
||||
int ix = 0;
|
||||
do {
|
||||
dst[ix] = src[ix];
|
||||
} while (src[ix++]);
|
||||
}
|
||||
|
||||
int main() {
|
||||
write(0, "Hello World!\n", 13);
|
||||
char *str = malloc(14);
|
||||
strcpy(str, "Hello World!\n");
|
||||
|
||||
write(0, str, 13);
|
||||
|
||||
munmap(str, 14);
|
||||
return 0;
|
||||
}
|
||||
|
||||
17
include/c-libs/sys/memory.h
Normal file
17
include/c-libs/sys/memory.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef CLIBS_SYS_MEMORY_H
|
||||
#define CLIBS_SYS_MEMORY_H
|
||||
|
||||
#include <c-libs/sys/syscall.h>
|
||||
#include <linux/mman.h>
|
||||
|
||||
void *malloc(__u64 size);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CLIBS_SYS_MEMORY_IMPL
|
||||
|
||||
void *malloc(__u64 size) {
|
||||
return mmap(0, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1,
|
||||
0);
|
||||
}
|
||||
#endif
|
||||
42
include/c-libs/sys/syscall.h
Normal file
42
include/c-libs/sys/syscall.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef CLIBS_SYS_SYSCALL_H
|
||||
#define CLIBS_SYS_SYSCALL_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/unistd.h>
|
||||
|
||||
void *syscall5(void *number, void *arg1, void *arg2, void *arg3, void *arg4,
|
||||
void *arg5);
|
||||
|
||||
void *syscall6(void *number, void *arg1, void *arg2, void *arg3, void *arg4,
|
||||
void *arg5, void *arg6);
|
||||
|
||||
__s64 write(int fd, void const *data, __u64 nbytes);
|
||||
|
||||
void *mmap(void *addr, __u64 len, __u64 prot, __u64 flags, __u64 fd,
|
||||
__s64 offset);
|
||||
|
||||
int munmap(void *addr, __u64 len);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CLIBS_SYS_SYSCALL_IMPL
|
||||
|
||||
__s64 write(int fd, void const *data, __u64 nbytes) {
|
||||
return (__s64)syscall5((void *)__NR_write, (void *)(__u64)fd, (void *)data,
|
||||
(void *)nbytes, 0, 0);
|
||||
}
|
||||
|
||||
void *mmap(void *addr, __u64 len, __u64 prot, __u64 flags, __u64 fd,
|
||||
__s64 offset) {
|
||||
return syscall6((void *)__NR_mmap, (void *)addr, (void *)len, (void *)prot,
|
||||
(void *)flags, (void *)fd, (void *)offset);
|
||||
}
|
||||
|
||||
int munmap(void *addr, __u64 len) {
|
||||
long val = (long)syscall5((void *)__NR_munmap, addr, (void *)len, (void *)0,
|
||||
(void *)0, (void *)0);
|
||||
|
||||
return (int)val;
|
||||
}
|
||||
|
||||
#endif
|
||||
20
src/sys/entry.s
Normal file
20
src/sys/entry.s
Normal file
@@ -0,0 +1,20 @@
|
||||
.global _start
|
||||
|
||||
|
||||
_start:
|
||||
/* Load argc -> rdi, argv[0] -> rsi */
|
||||
xor %rbp, %rbp
|
||||
pop %rdi
|
||||
mov %rsp, %rsi
|
||||
|
||||
/* align stack pointer to 16-bits */
|
||||
and $0xFFFFFFFFFFFFFFF0, %rsp
|
||||
|
||||
call main
|
||||
|
||||
/* Exit with ret val of main */
|
||||
mov %rax, %rdi
|
||||
mov $0x3C, %rax
|
||||
syscall
|
||||
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
2
src/sys/memory.c
Normal file
2
src/sys/memory.c
Normal file
@@ -0,0 +1,2 @@
|
||||
#define CLIBS_SYS_MEMORY_IMPL
|
||||
#include <c-libs/sys/memory.h>
|
||||
2
src/sys/syscall.c
Normal file
2
src/sys/syscall.c
Normal file
@@ -0,0 +1,2 @@
|
||||
#define CLIBS_SYS_SYSCALL_IMPL
|
||||
#include <c-libs/sys/syscall.h>
|
||||
24
src/sys/syscall.s
Normal file
24
src/sys/syscall.s
Normal file
@@ -0,0 +1,24 @@
|
||||
.global syscall5, syscall6
|
||||
|
||||
syscall5:
|
||||
mov %rdi, %rax /* %rax (syscall number) = func param 1 (%rdi) */
|
||||
mov %rsi, %rdi /* %rdi (syscall param 1) = func param 2 (%rsi) */
|
||||
mov %rdx, %rsi /* %rsi (syscall param 2) = func param 3 (%rdx) */
|
||||
mov %rcx, %rdx /* %rdx (syscall param 3) = func param 4 (%rcx) */
|
||||
mov %r8, %r10 /* %r10 (syscall param 4) = func param 5 (%r8) */
|
||||
mov %r9, %r8 /* %r8 (syscall param 5) = func param 6 (%r9) */
|
||||
syscall /* Enter a syscall (return value in %rax) */
|
||||
ret /* Return value is already in %rax, we can return. */
|
||||
|
||||
syscall6:
|
||||
mov %rdi, %rax /* %rax (syscall number) = func param 1 (%rdi) */
|
||||
mov %rsi, %rdi /* %rdi (syscall param 1) = func param 2 (%rsi) */
|
||||
mov %rdx, %rsi /* %rsi (syscall param 2) = func param 3 (%rdx) */
|
||||
mov %rcx, %rdx /* %rdx (syscall param 3) = func param 4 (%rcx) */
|
||||
mov %r8, %r10 /* %r10 (syscall param 4) = func param 5 (%r8) */
|
||||
mov %r9, %r8 /* %r8 (syscall param 5) = func param 6 (%r9) */
|
||||
mov 8(%rsp), %r9 /* %r9 (syscall param 6) = stack-value */
|
||||
syscall /* Enter a syscall (return value in %rax) */
|
||||
ret /* Return value is already in %rax, we can return. */
|
||||
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
Reference in New Issue
Block a user