mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-07-02 10:59:15 +00:00
refactor(userspace): build using cmake
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
This commit is contained in:
21
Userspace/libc/interpreter/CMakeLists.txt
Normal file
21
Userspace/libc/interpreter/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
||||
file(GLOB_RECURSE SYSDEPS_SOURCES ${SYSDEPS_PATH}/*.c ${SYSDEPS_GENERIC}/*.c)
|
||||
file(GLOB_RECURSE INTERPRETER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.c")
|
||||
list(APPEND INTERPRETER_FILES ${SYSDEPS_SOURCES})
|
||||
|
||||
add_executable(ld.so ${INTERPRETER_FILES})
|
||||
|
||||
execute_process(COMMAND git rev-parse HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_COMMIT
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
if(GIT_COMMIT)
|
||||
add_compile_definitions(LIBC_GIT_COMMIT="${GIT_COMMIT}")
|
||||
endif()
|
||||
|
||||
add_compile_definitions(FENNIX_DYNAMIC_LOADER="1")
|
||||
|
||||
install(TARGETS ld.so DESTINATION lib)
|
||||
target_compile_options(ld.so PRIVATE -fvisibility=hidden -fPIC)
|
||||
target_link_options(ld.so PRIVATE -nostdlib -shared -fPIC -fPIE -fno-plt -Wl,-e,_dl_start)
|
@ -1,40 +0,0 @@
|
||||
default:
|
||||
$(error Do not run this Makefile directly!)
|
||||
|
||||
OBJECT_NAME := ld.so
|
||||
|
||||
OUTPUT_DIR=$(WORKSPACE_DIR)/out/lib/
|
||||
SYSROOT = --sysroot=$(WORKSPACE_DIR)/out/
|
||||
|
||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||
OBJ = ${S_SOURCES:.S=.o} ${C_SOURCES:.c=.o} ${CXX_SOURCES:.cpp=.o}
|
||||
|
||||
CFLAGS := -fvisibility=hidden -fPIC -I$(WORKSPACE_DIR)/out/include -DLIBC_GIT_COMMIT='"$(shell git rev-parse HEAD)"'
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always
|
||||
endif
|
||||
|
||||
build: $(OBJECT_NAME)
|
||||
|
||||
$(OBJECT_NAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(CC) -nostdlib -shared -fPIC -fPIE -fno-plt -Wl,-soname,$(OBJECT_NAME) $(SYSROOT) $(OBJ) -o $(OBJECT_NAME)
|
||||
cp $(OBJECT_NAME) $(OUTPUT_DIR)$(OBJECT_NAME)
|
||||
|
||||
%.o: %.c
|
||||
$(info Compiling $<)
|
||||
$(CC) $(CFLAGS) -std=c17 -c $< -o $@
|
||||
|
||||
%.o: %.cpp
|
||||
$(info Compiling $<)
|
||||
$(CC) $(CFLAGS) -std=c++20 -c $< -o $@
|
||||
|
||||
%.o: %.S
|
||||
$(info Compiling $<)
|
||||
$(AS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) $(OBJECT_NAME)
|
@ -15,8 +15,9 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
@ -39,7 +40,7 @@ MemoryBlock *memory_pool = NULL;
|
||||
void *request_page(size_t size)
|
||||
{
|
||||
size_t aligned_size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
|
||||
void *addr = (void *)call_mmap(NULL, aligned_size, __SYS_PROT_READ | __SYS_PROT_WRITE, __SYS_MAP_ANONYMOUS | __SYS_MAP_PRIVATE, -1, 0);
|
||||
void *addr = (void *)sysdep(MemoryMap)(NULL, aligned_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||
if ((intptr_t)addr < 0)
|
||||
return NULL;
|
||||
return addr;
|
||||
@ -48,7 +49,7 @@ void *request_page(size_t size)
|
||||
void free_page(void *addr, size_t size)
|
||||
{
|
||||
size_t aligned_size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
|
||||
call_munmap(addr, aligned_size);
|
||||
sysdep(MemoryUnmap)(addr, aligned_size);
|
||||
}
|
||||
|
||||
MemoryBlock *allocate_block(size_t slot_size)
|
||||
|
@ -15,7 +15,7 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
@ -15,11 +15,14 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "elf.h"
|
||||
@ -167,9 +170,15 @@ __attribute__((noinline)) void *_dl_fixup(ElfInfo *Info, long RelIndex)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef __fennix__
|
||||
#include <fennix/syscalls.h>
|
||||
#endif
|
||||
|
||||
int _dl_preload()
|
||||
{
|
||||
#ifdef __fennix__
|
||||
call_api_version(0);
|
||||
#endif
|
||||
|
||||
/* TODO: Do aditional checks for miscellaneous things */
|
||||
|
||||
@ -353,16 +362,16 @@ void ProcessNeededLibraries(Elf_Dyn *elem, ElfInfo *Info)
|
||||
strcpy(fullLibPath, "/lib/");
|
||||
strcat(fullLibPath, libPath);
|
||||
/* TODO: more checks and also check environment variables */
|
||||
if (call_access(fullLibPath, __SYS_F_OK) != 0)
|
||||
if (sysdep(Access)(fullLibPath, F_OK) != 0)
|
||||
{
|
||||
printf("dl: Can't access %s\n", fullLibPath);
|
||||
return;
|
||||
}
|
||||
|
||||
int fd = call_open(fullLibPath, __SYS_O_RDONLY, 0644);
|
||||
int fd = sysdep(Open)(fullLibPath, O_RDONLY, 0644);
|
||||
int status = LoadElf(fd, fullLibPath, &info);
|
||||
elem->d_un.d_ptr = (uintptr_t)info; /* if LoadElf fails, info will still be NULL */
|
||||
call_close(fd);
|
||||
sysdep(Close)(fd);
|
||||
if (status < 0) /* announce that LoadElf failed */
|
||||
printf("dl: Can't load %s\n", fullLibPath);
|
||||
}
|
||||
@ -431,7 +440,7 @@ int LoadElfPhdrDYN(int fd, ElfInfo *Info)
|
||||
|
||||
for (Elf_Half i = 0; i < header.e_phnum; i++)
|
||||
{
|
||||
ssize_t read = call_pread(fd, &phdr, sizeof(Elf_Phdr), header.e_phoff + (header.e_phentsize * i));
|
||||
ssize_t read = sysdep(PRead)(fd, &phdr, sizeof(Elf_Phdr), header.e_phoff + (header.e_phentsize * i));
|
||||
if (read != sizeof(Elf_Phdr))
|
||||
{
|
||||
printf("dl: Can't read program header %d\n", i);
|
||||
@ -450,23 +459,23 @@ int LoadElfPhdrDYN(int fd, ElfInfo *Info)
|
||||
|
||||
int mmapProt = 0;
|
||||
if (phdr.p_flags & PF_X)
|
||||
mmapProt |= __SYS_PROT_EXEC;
|
||||
mmapProt |= PROT_EXEC;
|
||||
if (phdr.p_flags & PF_W)
|
||||
mmapProt |= __SYS_PROT_WRITE;
|
||||
mmapProt |= PROT_WRITE;
|
||||
if (phdr.p_flags & PF_R)
|
||||
mmapProt |= __SYS_PROT_READ;
|
||||
mmapProt |= PROT_READ;
|
||||
|
||||
off_t sectionOffset = ALIGN_DOWN(phdr.p_vaddr, phdr.p_align);
|
||||
size_t sectionSize = ALIGN_UP(phdr.p_memsz + (phdr.p_vaddr - sectionOffset), phdr.p_align);
|
||||
uintptr_t section = call_mmap(base + sectionOffset,
|
||||
sectionSize, mmapProt,
|
||||
__SYS_MAP_ANONYMOUS | __SYS_MAP_PRIVATE | __SYS_MAP_FIXED,
|
||||
-1, 0);
|
||||
uintptr_t section = (uintptr_t)sysdep(MemoryMap)((void *)(base + sectionOffset),
|
||||
sectionSize, mmapProt,
|
||||
MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED,
|
||||
-1, 0);
|
||||
sectionOffset = phdr.p_vaddr - ALIGN_DOWN(phdr.p_vaddr, phdr.p_align);
|
||||
|
||||
if (phdr.p_filesz > 0)
|
||||
{
|
||||
ssize_t read = call_pread(fd, section + sectionOffset, phdr.p_filesz, phdr.p_offset);
|
||||
ssize_t read = sysdep(PRead)(fd, (void *)(section + sectionOffset), phdr.p_filesz, phdr.p_offset);
|
||||
if (read != phdr.p_filesz)
|
||||
{
|
||||
printf("dl: Can't read segment %d in PT_LOAD\n", i);
|
||||
@ -495,15 +504,15 @@ int LoadElfPhdrDYN(int fd, ElfInfo *Info)
|
||||
{
|
||||
int mmapProt = 0;
|
||||
if (phdr.p_flags & PF_X)
|
||||
mmapProt |= __SYS_PROT_EXEC;
|
||||
mmapProt |= PROT_EXEC;
|
||||
if (phdr.p_flags & PF_W)
|
||||
mmapProt |= __SYS_PROT_WRITE;
|
||||
mmapProt |= PROT_WRITE;
|
||||
if (phdr.p_flags & PF_R)
|
||||
mmapProt |= __SYS_PROT_READ;
|
||||
mmapProt |= PROT_READ;
|
||||
|
||||
dynamicTable = (Elf_Dyn *)call_mmap(0, ALIGN_UP(phdr.p_memsz, phdr.p_align),
|
||||
mmapProt, __SYS_MAP_ANONYMOUS | __SYS_MAP_PRIVATE | __SYS_MAP_FIXED,
|
||||
-1, 0);
|
||||
dynamicTable = (Elf_Dyn *)sysdep(MemoryMap)(0, ALIGN_UP(phdr.p_memsz, phdr.p_align),
|
||||
mmapProt, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED,
|
||||
-1, 0);
|
||||
|
||||
if ((intptr_t)dynamicTable <= 0)
|
||||
{
|
||||
@ -511,7 +520,7 @@ int LoadElfPhdrDYN(int fd, ElfInfo *Info)
|
||||
return (int)(uintptr_t)dynamicTable;
|
||||
}
|
||||
|
||||
read = call_pread(fd, dynamicTable, phdr.p_memsz, phdr.p_offset);
|
||||
read = sysdep(PRead)(fd, dynamicTable, phdr.p_memsz, phdr.p_offset);
|
||||
if (read != phdr.p_memsz)
|
||||
{
|
||||
printf("dl: Can't read PT_DYNAMIC\n");
|
||||
@ -598,7 +607,7 @@ int LoadElf(int fd, char *Path, ElfInfo **Out)
|
||||
}
|
||||
|
||||
Elf_Ehdr header;
|
||||
call_pread(fd, &header, sizeof(Elf_Ehdr), 0);
|
||||
sysdep(PRead)(fd, &header, sizeof(Elf_Ehdr), 0);
|
||||
|
||||
int status = CheckElfEhdr(&header, Path);
|
||||
if (status != 0)
|
||||
@ -606,11 +615,11 @@ int LoadElf(int fd, char *Path, ElfInfo **Out)
|
||||
|
||||
info = AllocateLib();
|
||||
info->Header = header;
|
||||
info->Path = (char *)call_mmap(0,
|
||||
ALIGN_UP(strlen(Path) + 1, 0x1000 /* TODO: get page size from kernel */),
|
||||
__SYS_PROT_READ,
|
||||
__SYS_MAP_ANONYMOUS | __SYS_MAP_PRIVATE,
|
||||
-1, 0);
|
||||
info->Path = (char *)sysdep(MemoryMap)(0,
|
||||
ALIGN_UP(strlen(Path) + 1, 0x1000 /* TODO: get page size from kernel */),
|
||||
PROT_READ,
|
||||
MAP_ANONYMOUS | MAP_PRIVATE,
|
||||
-1, 0);
|
||||
if ((intptr_t)info->Path <= 0)
|
||||
{
|
||||
printf("dl: Can't allocate memory for path\n");
|
||||
@ -648,7 +657,7 @@ int LoadElf(int fd, char *Path, ElfInfo **Out)
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
call_munmap((uintptr_t)info->Path, ALIGN_UP(strlen(Path) + 1, 0x1000));
|
||||
sysdep(MemoryUnmap)((void *)info->Path, ALIGN_UP(strlen(Path) + 1, 0x1000));
|
||||
FreeLib(info);
|
||||
return status;
|
||||
}
|
||||
@ -956,18 +965,18 @@ int _dl_main(int argc, char *argv[], char *envp[])
|
||||
{
|
||||
char *path = argv[0];
|
||||
ElfInfo *info = NULL;
|
||||
if (call_access(path, __SYS_F_OK) < 0)
|
||||
if (sysdep(Access)(path, F_OK) < 0)
|
||||
{
|
||||
printf("dl: Can't access file %s\n", path);
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
int fd = call_open(path, __SYS_O_RDONLY, 0644);
|
||||
int fd = sysdep(Open)(path, O_RDONLY, 0644);
|
||||
int status = LoadElf(fd, path, &info);
|
||||
if (status < 0)
|
||||
{
|
||||
printf("%s: Can't load ELF file\n", path);
|
||||
call_close(fd);
|
||||
sysdep(Close)(fd);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -975,11 +984,11 @@ int _dl_main(int argc, char *argv[], char *envp[])
|
||||
if (status < 0)
|
||||
{
|
||||
printf("%s: Can't relocate ELF file\n", path);
|
||||
call_close(fd);
|
||||
sysdep(Close)(fd);
|
||||
return status;
|
||||
}
|
||||
|
||||
call_close(fd);
|
||||
sysdep(Close)(fd);
|
||||
Elf_Addr entry = info->BaseAddress + info->Header.e_entry;
|
||||
return ((int (*)(int, char *[], char *[]))entry)(argc, argv, envp);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* nanoprintf v0.5.3: a tiny embeddable printf replacement written in C.
|
||||
/* nanoprintf v0.5.4: a tiny embeddable printf replacement written in C.
|
||||
https://github.com/charlesnicholson/nanoprintf
|
||||
charles.nicholson+nanoprintf@gmail.com
|
||||
dual-licensed under 0bsd and unlicense, take your pick. see eof for details. */
|
||||
@ -336,6 +336,7 @@ static int npf_parse_format_spec(char const *format, npf_format_spec_t *out_spec
|
||||
}
|
||||
|
||||
#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1
|
||||
out_spec->field_width = 0;
|
||||
out_spec->field_width_opt = NPF_FMT_SPEC_OPT_NONE;
|
||||
if (*cur == '*')
|
||||
{
|
||||
@ -344,7 +345,6 @@ static int npf_parse_format_spec(char const *format, npf_format_spec_t *out_spec
|
||||
}
|
||||
else
|
||||
{
|
||||
out_spec->field_width = 0;
|
||||
while ((*cur >= '0') && (*cur <= '9'))
|
||||
{
|
||||
out_spec->field_width_opt = NPF_FMT_SPEC_OPT_LITERAL;
|
||||
|
@ -17,7 +17,8 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "elf.h"
|
||||
#include "misc.h"
|
||||
@ -31,7 +32,7 @@ void flush_buffer()
|
||||
{
|
||||
if (print_buffer_offset > 0)
|
||||
{
|
||||
call_write(1, print_buffer, print_buffer_offset);
|
||||
sysdep(Write)(1, print_buffer, print_buffer_offset);
|
||||
print_buffer_offset = 0;
|
||||
}
|
||||
}
|
||||
@ -45,11 +46,11 @@ void print_wrapper(int c, void *)
|
||||
|
||||
void __init_print_buffer()
|
||||
{
|
||||
print_buffer = (char *)call_mmap(0,
|
||||
0x1000,
|
||||
__SYS_PROT_READ | __SYS_PROT_WRITE,
|
||||
__SYS_MAP_PRIVATE | __SYS_MAP_ANONYMOUS,
|
||||
-1, 0);
|
||||
print_buffer = (char *)sysdep(MemoryMap)(0,
|
||||
0x1000,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
-1, 0);
|
||||
print_buffer_size = 0x1000;
|
||||
print_buffer_offset = 0;
|
||||
}
|
||||
@ -58,7 +59,7 @@ void __fini_print_buffer()
|
||||
{
|
||||
flush_buffer();
|
||||
if (print_buffer != NULL)
|
||||
call_munmap(print_buffer, 0x1000);
|
||||
sysdep(MemoryUnmap)(print_buffer, 0x1000);
|
||||
print_buffer = NULL;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fennix/syscalls.h>
|
||||
#include <bits/libc.h>
|
||||
|
||||
// const char __interp[] __attribute__((section(".interp"))) = "/boot/fennix.elf";
|
||||
|
||||
@ -97,54 +97,11 @@ const struct
|
||||
void __init_print_buffer();
|
||||
void __fini_print_buffer();
|
||||
|
||||
__attribute__((naked, used, no_stack_protector)) void _start()
|
||||
{
|
||||
#if defined(__amd64__)
|
||||
__asm__(
|
||||
"xorq %rbp, %rbp\n" /* Clear rbp */
|
||||
|
||||
"push %rdi\n"
|
||||
"push %rsi\n"
|
||||
"push %rdx\n"
|
||||
"push %rcx\n"
|
||||
"push %r8\n"
|
||||
"push %r9\n"
|
||||
|
||||
"call __init_print_buffer\n" /* Call __init_print_buffer */
|
||||
"call _dl_preload\n" /* Call _dl_preload */
|
||||
"movl %eax, %edi\n" /* Move return value to edi */
|
||||
"cmp $0, %edi\n" /* Check if return value is 0 */
|
||||
"jne _exit\n" /* If not, jump to _exit */
|
||||
|
||||
"pop %r9\n"
|
||||
"pop %r8\n"
|
||||
"pop %rcx\n"
|
||||
"pop %rdx\n"
|
||||
"pop %rsi\n"
|
||||
"pop %rdi\n"
|
||||
|
||||
"call main\n" /* Call _dl_main */
|
||||
"movl %eax, %edi\n" /* Move return value to edi */
|
||||
"call _exit\n"); /* Call _exit */
|
||||
#elif defined(__i386__)
|
||||
#warning "i386 _start not implemented"
|
||||
#elif defined(__arm__)
|
||||
#warning "arm _start not implemented"
|
||||
#elif defined(__aarch64__)
|
||||
#warning "aarch64 _start not implemented"
|
||||
#else
|
||||
#error "Unsupported architecture"
|
||||
#endif
|
||||
}
|
||||
|
||||
__attribute__((no_stack_protector)) _Noreturn void _exit(int status)
|
||||
{
|
||||
__fini_print_buffer();
|
||||
call_exit(status);
|
||||
/* At this point, the program *SHOULD* have exited. */
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
__asm__("ud2\n");
|
||||
#endif
|
||||
sysdep(Exit)(status);
|
||||
/* At this point, the program *SHOULD* have exited. */
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user