Update userspace

This commit is contained in:
Alex 2023-06-10 13:10:56 +03:00
parent ed5faa7b55
commit 22e75b9540
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
63 changed files with 2362 additions and 2151 deletions

View File

@ -1,109 +1,109 @@
{ {
"configurations": [ "configurations": [
{ {
"name": "Fennix x64 (Linux, GCC, debug)", "name": "Fennix x64 (Linux, GCC, debug)",
"includePath": [ "includePath": [
"${workspaceFolder}/libc/include/**", "${workspaceFolder}/libc/include/**",
"${workspaceFolder}/out/usr/include/**", "${workspaceFolder}/out/usr/include/**",
"${workspaceFolder}/libs/include/**", "${workspaceFolder}/libs/include/**",
"${workspaceFolder}/libs/include" "${workspaceFolder}/libs/include"
], ],
"defines": [ "defines": [
"__debug_vscode__", "__debug_vscode__",
"KERNEL_NAME=\"Fennix\"", "KERNEL_NAME=\"Fennix\"",
"KERNEL_VERSION=\"1.0\"", "KERNEL_VERSION=\"1.0\"",
"GIT_COMMIT=\"0000000000000000000000000000000000000000\"", "GIT_COMMIT=\"0000000000000000000000000000000000000000\"",
"GIT_COMMIT_SHORT=\"0000000\"", "GIT_COMMIT_SHORT=\"0000000\"",
"a64", "a64",
"a86", "a86",
"DEBUG=\"1\"" "DEBUG=\"1\""
], ],
"compilerPath": "${workspaceFolder}/../tools/cross/bin/amd64-elf-gcc", "compilerPath": "${workspaceFolder}/../tools/cross/bin/x86_64-fennix-gcc",
"cStandard": "c17", "cStandard": "c17",
"cppStandard": "c++20", "cppStandard": "c++20",
"intelliSenseMode": "gcc-x64", "intelliSenseMode": "gcc-x64",
"configurationProvider": "ms-vscode.makefile-tools", "configurationProvider": "ms-vscode.makefile-tools",
"compilerArgs": [ "compilerArgs": [
// Compiler flags // Compiler flags
"-fPIC", "-fPIC",
"-fPIE", "-fPIE",
"-pie", "-pie",
"-march=x86-64", "-march=x86-64",
"-pipe", "-pipe",
"-ffunction-sections", "-ffunction-sections",
"-fno-builtin", "-fno-builtin",
// C++ flags // C++ flags
"-fexceptions", "-fexceptions",
// Linker flags // Linker flags
"-fPIC", "-fPIC",
"-fPIE", "-fPIE",
"-pie", "-pie",
"-nostdlib", "-nostdlib",
"-nodefaultlibs", "-nodefaultlibs",
"-nolibc", "-nolibc",
"-zmax-page-size=0x1000", "-zmax-page-size=0x1000",
"-static", "-static",
// VSCode flags // VSCode flags
"-ffreestanding", "-ffreestanding",
"-nostdinc", "-nostdinc",
"-nostdinc++" "-nostdinc++"
] ]
}, },
{ {
"name": "Fennix x32 (Linux, GCC, debug)", "name": "Fennix x32 (Linux, GCC, debug)",
"includePath": [ "includePath": [
"${workspaceFolder}/libc/include/**", "${workspaceFolder}/libc/include/**",
"${workspaceFolder}/out/usr/include/**", "${workspaceFolder}/out/usr/include/**",
"${workspaceFolder}/libs/include/**", "${workspaceFolder}/libs/include/**",
"${workspaceFolder}/libs/include" "${workspaceFolder}/libs/include"
], ],
"defines": [ "defines": [
"__debug_vscode__", "__debug_vscode__",
"KERNEL_NAME=\"Fennix\"", "KERNEL_NAME=\"Fennix\"",
"KERNEL_VERSION=\"1.0\"", "KERNEL_VERSION=\"1.0\"",
"GIT_COMMIT=\"0000000000000000000000000000000000000000\"", "GIT_COMMIT=\"0000000000000000000000000000000000000000\"",
"GIT_COMMIT_SHORT=\"0000000\"", "GIT_COMMIT_SHORT=\"0000000\"",
"a32", "a32",
"a86", "a86",
"DEBUG=\"1\"" "DEBUG=\"1\""
], ],
"compilerPath": "${workspaceFolder}/../tools/cross/bin/i386-elf-gcc", "compilerPath": "${workspaceFolder}/../tools/cross/bin/i386-fennix-gcc",
"cStandard": "c17", "cStandard": "c17",
"cppStandard": "c++20", "cppStandard": "c++20",
"intelliSenseMode": "gcc-x86", "intelliSenseMode": "gcc-x86",
"configurationProvider": "ms-vscode.makefile-tools", "configurationProvider": "ms-vscode.makefile-tools",
"compilerArgs": [ "compilerArgs": [
// Compiler flags // Compiler flags
"-fPIC", "-fPIC",
"-fPIE", "-fPIE",
"-pie", "-pie",
"-march=i386", "-march=i386",
"-pipe", "-pipe",
"-ffunction-sections", "-ffunction-sections",
"-fno-builtin", "-fno-builtin",
// C++ flags // C++ flags
"-fexceptions", "-fexceptions",
// Linker flags // Linker flags
"-fPIC", "-fPIC",
"-fPIE", "-fPIE",
"-pie", "-pie",
"-nostdlib", "-nostdlib",
"-nodefaultlibs", "-nodefaultlibs",
"-nolibc", "-nolibc",
"-zmax-page-size=0x1000", "-zmax-page-size=0x1000",
"-static", "-static",
// VSCode flags // VSCode flags
"-ffreestanding", "-ffreestanding",
"-nostdinc", "-nostdinc",
"-nostdinc++" "-nostdinc++"
] ]
} }
], ],
"version": 4 "version": 4
} }

201
.vscode/launch.json vendored
View File

@ -1,83 +1,122 @@
{ {
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "/init", "name": "/bin/init",
"type": "cppdbg", "type": "cppdbg",
"request": "launch", "request": "launch",
"program": "${workspaceFolder}/out/bin/init", "program": "${workspaceFolder}/out/bin/init",
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
"args": [], "args": [],
"targetArchitecture": "x64", "targetArchitecture": "x64",
"MIMode": "gdb", "MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb", "miDebuggerPath": "/usr/bin/gdb",
"miDebuggerArgs": "", "miDebuggerArgs": "",
"externalConsole": false, "externalConsole": false,
"additionalSOLibSearchPath": "${workspaceFolder}", "additionalSOLibSearchPath": "${workspaceFolder}",
"customLaunchSetupCommands": [ "customLaunchSetupCommands": [
{ {
"text": "target remote localhost:1234", "text": "target remote localhost:1234",
"description": "Connect to QEMU remote debugger" "description": "Connect to QEMU remote debugger"
} }
], ],
"setupCommands": [ "setupCommands": [
{ {
"description": "Enable pretty-printing for gdb", "description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing", "text": "-enable-pretty-printing",
"ignoreFailures": true "ignoreFailures": true
}, },
{ {
"text": "set breakpoint pending on", "text": "set breakpoint pending on",
"description": "Make breakpoint pending on future shared library load." "description": "Make breakpoint pending on future shared library load."
}, },
{ {
"text": "file ${workspaceFolder}/out/bin/init", "text": "file ${workspaceFolder}/out/bin/init",
"description": "Load binary." "description": "Load binary."
}, },
{ {
"text": "add-symbol-file ${workspaceFolder}/../Kernel/kernel.fsys", "text": "add-symbol-file ${workspaceFolder}/../Kernel/kernel.fsys",
"description": "Load kernel binary." "description": "Load kernel binary."
}, },
] ]
}, },
{ {
"name": "/bin/doom", "name": "/lib/ld.so",
"type": "cppdbg", "type": "cppdbg",
"request": "launch", "request": "launch",
"program": "${workspaceFolder}/out/usr/bin/doom", "program": "${workspaceFolder}/out/lib/ld.so",
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
"args": [], "args": [],
"targetArchitecture": "x64", "targetArchitecture": "x64",
"MIMode": "gdb", "MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb", "miDebuggerPath": "/usr/bin/gdb",
"miDebuggerArgs": "", "miDebuggerArgs": "",
"externalConsole": false, "externalConsole": false,
"additionalSOLibSearchPath": "${workspaceFolder}", "additionalSOLibSearchPath": "${workspaceFolder}",
"customLaunchSetupCommands": [ "customLaunchSetupCommands": [
{ {
"text": "target remote localhost:1234", "text": "target remote localhost:1234",
"description": "Connect to QEMU remote debugger" "description": "Connect to QEMU remote debugger"
} }
], ],
"setupCommands": [ "setupCommands": [
{ {
"description": "Enable pretty-printing for gdb", "description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing", "text": "-enable-pretty-printing",
"ignoreFailures": true "ignoreFailures": true
}, },
{ {
"text": "set breakpoint pending on", "text": "set breakpoint pending on",
"description": "Make breakpoint pending on future shared library load." "description": "Make breakpoint pending on future shared library load."
}, },
{ {
"text": "file ${workspaceFolder}/out/usr/bin/doom", "text": "file ${workspaceFolder}/out/lib/ld.so",
"description": "Load binary." "description": "Load binary."
}, },
{ {
"text": "add-symbol-file ${workspaceFolder}/../Kernel/kernel.fsys", "text": "add-symbol-file ${workspaceFolder}/../Kernel/kernel.fsys",
"description": "Load kernel binary." "description": "Load kernel binary."
}, },
] ]
} },
] {
"name": "/usr/bin/doom",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/out/usr/bin/doom",
"cwd": "${workspaceFolder}",
"args": [],
"targetArchitecture": "x64",
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"miDebuggerArgs": "",
"externalConsole": false,
"additionalSOLibSearchPath": "${workspaceFolder}",
"customLaunchSetupCommands": [
{
"text": "target remote localhost:1234",
"description": "Connect to QEMU remote debugger"
}
],
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"text": "set breakpoint pending on",
"description": "Make breakpoint pending on future shared library load."
},
{
"text": "file ${workspaceFolder}/out/usr/bin/doom",
"description": "Load binary."
},
{
"text": "add-symbol-file ${workspaceFolder}/../Kernel/kernel.fsys",
"description": "Load kernel binary."
},
]
}
]
} }

View File

@ -3,11 +3,11 @@ WORKSPACE := ../../../
# Config file # Config file
include ../$(WORKSPACE)Makefile.conf include ../$(WORKSPACE)Makefile.conf
CC = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc CC = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
CPP = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)g++ CPP = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)g++
LD = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ld LD = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)ld
AS = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as AS = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)as
OBJDUMP = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump OBJDUMP = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
GIT_COMMIT = $(shell git rev-parse HEAD) GIT_COMMIT = $(shell git rev-parse HEAD)
GIT_COMMIT_SHORT = $(shell git rev-parse --short HEAD) GIT_COMMIT_SHORT = $(shell git rev-parse --short HEAD)

View File

@ -2,10 +2,10 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
for (int i = 1; i < argc; i++) for (int i = 1; i < argc; i++)
{ {
printf("%s ", argv[i]); printf("%s ", argv[i]);
} }
printf("\n"); printf("\n");
return 0; return 0;
} }

View File

@ -3,11 +3,11 @@ WORKSPACE := ../../../
# Config file # Config file
include ../$(WORKSPACE)Makefile.conf include ../$(WORKSPACE)Makefile.conf
CC = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc CC = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
CPP = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)g++ CPP = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)g++
LD = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ld LD = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)ld
AS = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as AS = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)as
OBJDUMP = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump OBJDUMP = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
GIT_COMMIT = $(shell git rev-parse HEAD) GIT_COMMIT = $(shell git rev-parse HEAD)
GIT_COMMIT_SHORT = $(shell git rev-parse --short HEAD) GIT_COMMIT_SHORT = $(shell git rev-parse --short HEAD)

View File

@ -9,75 +9,75 @@
void test_args(int argc, char *argv[], char *envp[]) void test_args(int argc, char *argv[], char *envp[])
{ {
print("%p %p %p\n", (void *)(uint64_t)&argc, (void *)&argv, (void *)&envp); print("%p %p %p\n", (void *)(uint64_t)&argc, (void *)&argv, (void *)&envp);
print("I have %d arguments\n", argc); print("I have %d arguments\n", argc);
for (int i = 0; i < argc; i++) for (int i = 0; i < argc; i++)
print("argv[%d] = (%p) %s\n", i, argv[i], argv[i]); print("argv[%d] = (%p) %s\n", i, argv[i], argv[i]);
int envc = 0; int envc = 0;
while (envp[envc] != NULL) while (envp[envc] != NULL)
envc++; envc++;
print("I have %d environment variables\n", envc); print("I have %d environment variables\n", envc);
for (int i = 0; i < envc; i++) for (int i = 0; i < envc; i++)
print("envp[%d] = (%p) %s\n", i, envp[i], envp[i]); print("envp[%d] = (%p) %s\n", i, envp[i], envp[i]);
Elf64_auxv_t *auxv; Elf64_auxv_t *auxv;
char **e = envp; char **e = envp;
while (*e++ != NULL) while (*e++ != NULL)
; ;
for (auxv = (Elf64_auxv_t *)e; auxv->a_type != AT_NULL; auxv++) for (auxv = (Elf64_auxv_t *)e; auxv->a_type != AT_NULL; auxv++)
print("auxv: %ld %#lx\n", auxv->a_type, auxv->a_un.a_val); print("auxv: %ld %#lx\n", auxv->a_type, auxv->a_un.a_val);
} }
int main(int argc, char *argv[], char *envp[]) int main(int argc, char *argv[], char *envp[])
{ {
// test_args(argc, argv, envp); // test_args(argc, argv, envp);
FILE *test = fopen("/Test.txt", "r"); FILE *test = fopen("/Test.txt", "r");
if (test == NULL) if (test == NULL)
{ {
print("Failed to open file\n"); print("Failed to open file\n");
return 1; return 1;
} }
char buf[1024]; char buf[1024];
int read = fread(buf, 1024, 1, test); int read = fread(buf, 1024, 1, test);
print("/Test.txt (%ld): %s\n", read, buf); print("/Test.txt (%ld): %s\n", read, buf);
fclose(test); fclose(test);
pid_t pid; pid_t pid;
int status; int status;
pid = fork(); pid = fork();
if (pid == 0) // Child process if (pid == 0) // Child process
{ {
print("Creating shell process\n"); print("Creating shell process\n");
char *args[] = {"/bin/sh", NULL}; char *args[] = {"/bin/sh", NULL};
execv(args[0], args); execv(args[0], args);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
else if (pid > 0) else if (pid > 0)
{ {
wait(&status); wait(&status);
if (WIFEXITED(status)) if (WIFEXITED(status))
{ {
print("Child process exited with code: %d\n", WEXITSTATUS(status)); print("Child process exited with code: %d\n", WEXITSTATUS(status));
return WEXITSTATUS(status); return WEXITSTATUS(status);
} }
else else
{ {
print("Execution failed.\n"); print("Execution failed.\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
else else
{ {
print("\eFF0000Failed to create the process.\n"); print("\eFF0000Failed to create the process.\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
return 0; return 0;
} }

@ -1 +1 @@
Subproject commit 7ef0110ddcfd0d6a03204d805841915a8e56a247 Subproject commit 9af0e63ae3ef8948e67ff0d570289a309ff40dcf

View File

@ -9,10 +9,10 @@ SO_NAME=$(OBJECT_NAME)
OUTPUT_DIR=../../out/lib/ OUTPUT_DIR=../../out/lib/
SYSROOT = --sysroot=../../out/ SYSROOT = --sysroot=../../out/
CC = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
AS = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
AR = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ar AR = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
OBJDUMP = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump OBJDUMP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
NASM = /usr/bin/nasm NASM = /usr/bin/nasm
C_SOURCES = $(shell find ./ -type f -name '*.c') C_SOURCES = $(shell find ./ -type f -name '*.c')
@ -23,16 +23,25 @@ OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${ASM_SOURCES:.asm=.o} ${S_SOURC
INCLUDE = ../include INCLUDE = ../include
ifeq ($(OSARCH), amd64)
ASM_ARCH := elf64
else ifeq ($(OSARCH), i386)
ASM_ARCH := elf32
endif
SIMD_FLAGS := -mno-sse -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4.1 -mno-sse4.2 -mno-sse4 -mno-avx -mno-avx2 -mno-avx512f SIMD_FLAGS := -mno-sse -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4.1 -mno-sse4.2 -mno-sse4 -mno-avx -mno-avx2 -mno-avx512f
CFLAGS := -pie -fPIE -I$(INCLUDE) $(SIMD_FLAGS) CFLAGS := -I$(INCLUDE) $(SIMD_FLAGS) -fPIC
LDFLAGS := -nostartfiles -nostdlib -pie -fPIE -Wl,-e_ld_start,-soname,$(SO_NAME) $(SYSROOT) LDFLAGS := -nostartfiles -nostdlib -Wl,-soname,$(SO_NAME) $(SYSROOT) -fno-pie -fno-PIC
ifeq ($(OSARCH), amd64)
ASM_ARCH := elf64
LDFLAGS += -Ttext=0xFFFFFFFFF0001000
CFLAGS += -m64
else ifeq ($(OSARCH), i386)
ASM_ARCH := elf32
LDFLAGS += -fixme
CFLAGS += -m32
endif
ifeq ($(DEBUG), 1)
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm
LDFLAGS += -ggdb3 -O0
endif
build: $(OBJECT_NAME) build: $(OBJECT_NAME)

View File

@ -18,42 +18,42 @@ typedef __INT64_TYPE__ Elf64_Sxword;
enum SectionHeaderType enum SectionHeaderType
{ {
SHT_NULL = 0, SHT_NULL = 0,
SHT_PROGBITS = 1, SHT_PROGBITS = 1,
SHT_SYMTAB = 2, SHT_SYMTAB = 2,
SHT_STRTAB = 3, SHT_STRTAB = 3,
SHT_RELA = 4, SHT_RELA = 4,
SHT_HASH = 5, SHT_HASH = 5,
SHT_DYNAMIC = 6, SHT_DYNAMIC = 6,
SHT_NOTE = 7, SHT_NOTE = 7,
SHT_NOBITS = 8, SHT_NOBITS = 8,
SHT_REL = 9, SHT_REL = 9,
SHT_SHLIB = 10, SHT_SHLIB = 10,
SHT_DYNSYM = 11, SHT_DYNSYM = 11,
SHT_INIT_ARRAY = 14, SHT_INIT_ARRAY = 14,
SHT_FINI_ARRAY = 15, SHT_FINI_ARRAY = 15,
SHT_PREINIT_ARRAY = 16, SHT_PREINIT_ARRAY = 16,
SHT_GROUP = 17, SHT_GROUP = 17,
SHT_SYMTAB_SHNDX = 18, SHT_SYMTAB_SHNDX = 18,
SHT_NUM = 19, SHT_NUM = 19,
SHT_LOOS = 0x60000000, SHT_LOOS = 0x60000000,
SHT_GNU_ATTRIBUTES = 0x6ffffff5, SHT_GNU_ATTRIBUTES = 0x6ffffff5,
SHT_GNU_HASH = 0x6ffffff6, SHT_GNU_HASH = 0x6ffffff6,
SHT_GNU_LIBLIST = 0x6ffffff7, SHT_GNU_LIBLIST = 0x6ffffff7,
SHT_CHECKSUM = 0x6ffffff8, SHT_CHECKSUM = 0x6ffffff8,
SHT_LOSUNW = 0x6ffffffa, SHT_LOSUNW = 0x6ffffffa,
SHT_SUNW_move = 0x6ffffffa, SHT_SUNW_move = 0x6ffffffa,
SHT_SUNW_COMDAT = 0x6ffffffb, SHT_SUNW_COMDAT = 0x6ffffffb,
SHT_SUNW_syminfo = 0x6ffffffc, SHT_SUNW_syminfo = 0x6ffffffc,
SHT_GNU_verdef = 0x6ffffffd, SHT_GNU_verdef = 0x6ffffffd,
SHT_GNU_verneed = 0x6ffffffe, SHT_GNU_verneed = 0x6ffffffe,
SHT_GNU_versym = 0x6fffffff, SHT_GNU_versym = 0x6fffffff,
SHT_HISUNW = 0x6fffffff, SHT_HISUNW = 0x6fffffff,
SHT_HIOS = 0x6fffffff, SHT_HIOS = 0x6fffffff,
SHT_LOPROC = 0x70000000, SHT_LOPROC = 0x70000000,
SHT_HIPROC = 0x7fffffff, SHT_HIPROC = 0x7fffffff,
SHT_LOUSER = 0x80000000, SHT_LOUSER = 0x80000000,
SHT_HIUSER = 0x8fffffff SHT_HIUSER = 0x8fffffff
}; };
#define ELF32_R_SYM(i) ((i) >> 8) #define ELF32_R_SYM(i) ((i) >> 8)
@ -71,228 +71,226 @@ enum SectionHeaderType
enum DynamicTags enum DynamicTags
{ {
DT_NULL = 0, DT_NULL = 0,
DT_NEEDED = 1, DT_NEEDED = 1,
DT_PLTRELSZ = 2, DT_PLTRELSZ = 2,
DT_PLTGOT = 3, DT_PLTGOT = 3,
DT_HASH = 4, DT_HASH = 4,
DT_STRTAB = 5, DT_STRTAB = 5,
DT_SYMTAB = 6, DT_SYMTAB = 6,
DT_RELA = 7, DT_RELA = 7,
DT_RELASZ = 8, DT_RELASZ = 8,
DT_RELAENT = 9, DT_RELAENT = 9,
DT_STRSZ = 10, DT_STRSZ = 10,
DT_SYMENT = 11, DT_SYMENT = 11,
DT_INIT = 12, DT_INIT = 12,
DT_FINI = 13, DT_FINI = 13,
DT_SONAME = 14, DT_SONAME = 14,
DT_RPATH = 15, DT_RPATH = 15,
DT_SYMBOLIC = 16, DT_SYMBOLIC = 16,
DT_REL = 17, DT_REL = 17,
DT_RELSZ = 18, DT_RELSZ = 18,
DT_RELENT = 19, DT_RELENT = 19,
DT_PLTREL = 20, DT_PLTREL = 20,
DT_DEBUG = 21, DT_DEBUG = 21,
DT_TEXTREL = 22, DT_TEXTREL = 22,
DT_JMPREL = 23, DT_JMPREL = 23,
DT_BIND_NOW = 24, DT_BIND_NOW = 24,
DT_INIT_ARRAY = 25, DT_INIT_ARRAY = 25,
DT_FINI_ARRAY = 26, DT_FINI_ARRAY = 26,
DT_INIT_ARRAYSZ = 27, DT_INIT_ARRAYSZ = 27,
DT_FINI_ARRAYSZ = 28, DT_FINI_ARRAYSZ = 28,
DT_RUNPATH = 29, DT_RUNPATH = 29,
DT_FLAGS = 30, DT_FLAGS = 30,
DT_ENCODING = 32, DT_ENCODING = 32,
DT_PREINIT_ARRAY = 32, DT_PREINIT_ARRAY = 32,
DT_PREINIT_ARRAYSZ = 33, DT_PREINIT_ARRAYSZ = 33,
DT_LOOS = 0x6000000d, DT_LOOS = 0x6000000d,
DT_SUNW_RTLDINF = 0x6000000e, DT_SUNW_RTLDINF = 0x6000000e,
DT_HIOS = 0x6ffff000, DT_HIOS = 0x6ffff000,
DT_VALRNGLO = 0x6ffffd00, DT_VALRNGLO = 0x6ffffd00,
DT_CHECKSUM = 0x6ffffdf8, DT_CHECKSUM = 0x6ffffdf8,
DT_PLTPADSZ = 0x6ffffdf9, DT_PLTPADSZ = 0x6ffffdf9,
DT_MOVEENT = 0x6ffffdfa, DT_MOVEENT = 0x6ffffdfa,
DT_MOVESZ = 0x6ffffdfb, DT_MOVESZ = 0x6ffffdfb,
DT_FEATURE_1 = 0x6ffffdfc, DT_FEATURE_1 = 0x6ffffdfc,
DT_POSFLAG_1 = 0x6ffffdfd, DT_POSFLAG_1 = 0x6ffffdfd,
DT_SYMINSZ = 0x6ffffdfe, DT_SYMINSZ = 0x6ffffdfe,
DT_SYMINENT = 0x6ffffdff, DT_SYMINENT = 0x6ffffdff,
DT_VALRNGHI = 0x6ffffdff, DT_VALRNGHI = 0x6ffffdff,
DT_ADDRRNGLO = 0x6ffffe00, DT_ADDRRNGLO = 0x6ffffe00,
DT_CONFIG = 0x6ffffefa, DT_CONFIG = 0x6ffffefa,
DT_DEPAUDIT = 0x6ffffefb, DT_DEPAUDIT = 0x6ffffefb,
DT_AUDIT = 0x6ffffefc, DT_AUDIT = 0x6ffffefc,
DT_PLTPAD = 0x6ffffefd, DT_PLTPAD = 0x6ffffefd,
DT_MOVETAB = 0x6ffffefe, DT_MOVETAB = 0x6ffffefe,
DT_SYMINFO = 0x6ffffeff, DT_SYMINFO = 0x6ffffeff,
DT_ADDRRNGHI = 0x6ffffeff, DT_ADDRRNGHI = 0x6ffffeff,
DT_RELACOUNT = 0x6ffffff9, DT_RELACOUNT = 0x6ffffff9,
DT_RELCOUNT = 0x6ffffffa, DT_RELCOUNT = 0x6ffffffa,
DT_FLAGS_1 = 0x6ffffffb, DT_FLAGS_1 = 0x6ffffffb,
DT_VERDEF = 0x6ffffffc, DT_VERDEF = 0x6ffffffc,
DT_VERDEFNUM = 0x6ffffffd, DT_VERDEFNUM = 0x6ffffffd,
DT_VERNEED = 0x6ffffffe, DT_VERNEED = 0x6ffffffe,
DT_VERNEEDNUM = 0x6fffffff, DT_VERNEEDNUM = 0x6fffffff,
DT_LOPROC = 0x70000000, DT_LOPROC = 0x70000000,
DT_SPARC_REGISTER = 0x70000001, DT_SPARC_REGISTER = 0x70000001,
DT_AUXILIARY = 0x7ffffffd, DT_AUXILIARY = 0x7ffffffd,
DT_USED = 0x7ffffffe, DT_USED = 0x7ffffffe,
DT_FILTER = 0x7fffffff, DT_FILTER = 0x7fffffff,
DT_HIPROC = 0x7fffffff DT_HIPROC = 0x7fffffff
}; };
enum SegmentTypes enum SegmentTypes
{ {
PT_NULL = 0, PT_NULL = 0,
PT_LOAD = 1, PT_LOAD = 1,
PT_DYNAMIC = 2, PT_DYNAMIC = 2,
PT_INTERP = 3, PT_INTERP = 3,
PT_NOTE = 4, PT_NOTE = 4,
PT_SHLIB = 5, PT_SHLIB = 5,
PT_PHDR = 6, PT_PHDR = 6,
PT_TLS = 7, PT_TLS = 7,
PT_LOSUNW = 0x6ffffffa, PT_LOSUNW = 0x6ffffffa,
PT_SUNWBSS = 0x6ffffffb, PT_SUNWBSS = 0x6ffffffb,
PT_SUNWSTACK = 0x6ffffffa, PT_SUNWSTACK = 0x6ffffffa,
PT_HISUNW = 0x6fffffff, PT_HISUNW = 0x6fffffff,
PT_LOPROC = 0x70000000, PT_LOPROC = 0x70000000,
PT_HIPROC = 0x7fffffff PT_HIPROC = 0x7fffffff
}; };
enum RtT_Types enum RtT_Types
{ {
R_386_NONE = 0, R_386_NONE = 0,
R_386_32 = 1, R_386_32 = 1,
R_386_PC32 = 2, R_386_PC32 = 2,
R_X86_64_NONE = 0, R_X86_64_NONE = 0,
R_X86_64_64 = 1, R_X86_64_64 = 1,
R_X86_64_PC32 = 2, R_X86_64_PC32 = 2,
R_X86_64_GOT32 = 3, R_X86_64_GOT32 = 3,
R_X86_64_PLT32 = 4, R_X86_64_PLT32 = 4,
R_X86_64_COPY = 5, R_X86_64_COPY = 5,
R_X86_64_GLOB_DAT = 6, R_X86_64_GLOB_DAT = 6,
R_X86_64_JUMP_SLOT = 7, R_X86_64_JUMP_SLOT = 7,
R_X86_64_RELATIVE = 8, R_X86_64_RELATIVE = 8,
R_X86_64_GOTPCREL = 9, R_X86_64_GOTPCREL = 9,
R_X86_64_32 = 10, R_X86_64_32 = 10,
R_X86_64_32S = 11, R_X86_64_32S = 11,
R_X86_64_16 = 12, R_X86_64_16 = 12,
}; };
typedef struct elf32_hdr typedef struct elf32_hdr
{ {
unsigned char e_ident[EI_NIDENT]; unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type; Elf32_Half e_type;
Elf32_Half e_machine; Elf32_Half e_machine;
Elf32_Word e_version; Elf32_Word e_version;
Elf32_Addr e_entry; Elf32_Addr e_entry;
Elf32_Off e_phoff; Elf32_Off e_phoff;
Elf32_Off e_shoff; Elf32_Off e_shoff;
Elf32_Word e_flags; Elf32_Word e_flags;
Elf32_Half e_ehsize; Elf32_Half e_ehsize;
Elf32_Half e_phentsize; Elf32_Half e_phentsize;
Elf32_Half e_phnum; Elf32_Half e_phnum;
Elf32_Half e_shentsize; Elf32_Half e_shentsize;
Elf32_Half e_shnum; Elf32_Half e_shnum;
Elf32_Half e_shstrndx; Elf32_Half e_shstrndx;
} Elf32_Ehdr; } Elf32_Ehdr;
typedef struct elf64_hdr typedef struct elf64_hdr
{ {
unsigned char e_ident[EI_NIDENT]; unsigned char e_ident[EI_NIDENT];
Elf64_Half e_type; Elf64_Half e_type;
Elf64_Half e_machine; Elf64_Half e_machine;
Elf64_Word e_version; Elf64_Word e_version;
Elf64_Addr e_entry; Elf64_Addr e_entry;
Elf64_Off e_phoff; Elf64_Off e_phoff;
Elf64_Off e_shoff; Elf64_Off e_shoff;
Elf64_Word e_flags; Elf64_Word e_flags;
Elf64_Half e_ehsize; Elf64_Half e_ehsize;
Elf64_Half e_phentsize; Elf64_Half e_phentsize;
Elf64_Half e_phnum; Elf64_Half e_phnum;
Elf64_Half e_shentsize; Elf64_Half e_shentsize;
Elf64_Half e_shnum; Elf64_Half e_shnum;
Elf64_Half e_shstrndx; Elf64_Half e_shstrndx;
} Elf64_Ehdr; } Elf64_Ehdr;
typedef struct elf32_shdr typedef struct elf32_shdr
{ {
Elf32_Word sh_name; Elf32_Word sh_name;
Elf32_Word sh_type; Elf32_Word sh_type;
Elf32_Word sh_flags; Elf32_Word sh_flags;
Elf32_Addr sh_addr; Elf32_Addr sh_addr;
Elf32_Off sh_offset; Elf32_Off sh_offset;
Elf32_Word sh_size; Elf32_Word sh_size;
Elf32_Word sh_link; Elf32_Word sh_link;
Elf32_Word sh_info; Elf32_Word sh_info;
Elf32_Word sh_addralign; Elf32_Word sh_addralign;
Elf32_Word sh_entsize; Elf32_Word sh_entsize;
} Elf32_Shdr; } Elf32_Shdr;
typedef struct elf64_shdr typedef struct elf64_shdr
{ {
Elf64_Word sh_name; Elf64_Word sh_name;
Elf64_Word sh_type; Elf64_Word sh_type;
Elf64_Xword sh_flags; Elf64_Xword sh_flags;
Elf64_Addr sh_addr; Elf64_Addr sh_addr;
Elf64_Off sh_offset; Elf64_Off sh_offset;
Elf64_Xword sh_size; Elf64_Xword sh_size;
Elf64_Word sh_link; Elf64_Word sh_link;
Elf64_Word sh_info; Elf64_Word sh_info;
Elf64_Xword sh_addralign; Elf64_Xword sh_addralign;
Elf64_Xword sh_entsize; Elf64_Xword sh_entsize;
} Elf64_Shdr; } Elf64_Shdr;
struct Elf32_Dyn struct Elf32_Dyn
{ {
Elf32_Sword d_tag; Elf32_Sword d_tag;
union union
{ {
Elf32_Word d_val; Elf32_Word d_val;
Elf32_Addr d_ptr; Elf32_Addr d_ptr;
} d_un; } d_un;
}; };
struct Elf64_Dyn struct Elf64_Dyn
{ {
Elf64_Sxword d_tag; Elf64_Sxword d_tag;
union union
{ {
Elf64_Xword d_val; Elf64_Xword d_val;
Elf64_Addr d_ptr; Elf64_Addr d_ptr;
} d_un; } d_un;
}; };
typedef struct typedef struct
{ {
Elf64_Word p_type; Elf64_Word p_type;
Elf64_Word p_flags; Elf64_Word p_flags;
Elf64_Off p_offset; Elf64_Off p_offset;
Elf64_Addr p_vaddr; Elf64_Addr p_vaddr;
Elf64_Addr p_paddr; Elf64_Addr p_paddr;
Elf64_Xword p_filesz; Elf64_Xword p_filesz;
Elf64_Xword p_memsz; Elf64_Xword p_memsz;
Elf64_Xword p_align; Elf64_Xword p_align;
} Elf64_Phdr; } Elf64_Phdr;
typedef struct typedef struct
{ {
Elf64_Addr r_offset; Elf64_Addr r_offset;
Elf64_Xword r_info; Elf64_Xword r_info;
Elf64_Sxword r_addend; Elf64_Sxword r_addend;
} Elf64_Rela; } Elf64_Rela;
typedef struct elf64_sym typedef struct elf64_sym
{ {
Elf64_Word st_name; Elf64_Word st_name;
unsigned char st_info; unsigned char st_info;
unsigned char st_other; unsigned char st_other;
Elf64_Half st_shndx; Elf64_Half st_shndx;
Elf64_Addr st_value; Elf64_Addr st_value;
Elf64_Xword st_size; Elf64_Xword st_size;
} Elf64_Sym; } Elf64_Sym;
struct Elf64_Dyn *ELFGetDynamicTag(void *ElfFile, enum DynamicTags Tag);
#endif // !__FENNIX_LIB_ELF_LAZY_RESOLVE_H__ #endif // !__FENNIX_LIB_ELF_LAZY_RESOLVE_H__

234
libc/ElfInterpreter/fcts.c Normal file
View File

@ -0,0 +1,234 @@
#include "fcts.h"
#include "../../../Kernel/syscalls.h"
#include "../../../Kernel/ipc.h"
uintptr_t RequestPages(size_t Count)
{
return syscall1(_RequestPages, Count);
}
int FreePages(uintptr_t Address, size_t Count)
{
return syscall2(_FreePages, Address, Count);
}
int IPC(int Command, int Type, int ID, int Flags, void *Buffer, size_t Size)
{
return syscall6(_IPC, (long)Command, (long)Type, (long)ID, (long)Flags, (long)Buffer, (long)Size);
}
uintptr_t KernelCTL(int Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4)
{
return syscall5(_KernelCTL, Command, Arg1, Arg2, Arg3, Arg4);
}
int abs(int i) { return i < 0 ? -i : i; }
void swap(char *x, char *y)
{
char t = *x;
*x = *y;
*y = t;
}
char *reverse(char *Buffer, int i, int j)
{
while (i < j)
swap(&Buffer[i++], &Buffer[j--]);
return Buffer;
}
char *ltoa(long Value, char *Buffer, int Base)
{
if (Base < 2 || Base > 32)
return Buffer;
long n = (long)abs((int)Value);
int i = 0;
while (n)
{
int r = n % Base;
if (r >= 10)
Buffer[i++] = 65 + (r - 10);
else
Buffer[i++] = 48 + r;
n = n / Base;
}
if (i == 0)
Buffer[i++] = '0';
if (Value < 0 && Base == 10)
Buffer[i++] = '-';
Buffer[i] = '\0';
return reverse(Buffer, 0, i - 1);
}
void PutCharToKernelConsole(char c)
{
__asm__ __volatile__("syscall"
:
: "a"(1), "D"(c), "S"(0)
: "rcx", "r11", "memory");
}
void Print__(char *String)
{
for (short i = 0; String[i] != '\0'; i++)
PutCharToKernelConsole(String[i]);
}
void PrintNL__(char *String)
{
Print__(String);
Print__("\n");
}
void *memcpy(void *dest, const void *src, size_t n)
{
uint8_t *d = dest;
const uint8_t *s = src;
while (n--)
*d++ = *s++;
return dest;
}
void *memset(void *s, int c, size_t n)
{
uint8_t *p = s;
while (n--)
*p++ = c;
}
int strcmp(const char *l, const char *r)
{
for (; *l == *r && *l; l++, r++)
;
return *(unsigned char *)l - *(unsigned char *)r;
}
struct Elf64_Dyn ELFGetDynamicTag(char *Path, enum DynamicTags Tag)
{
void *KP = syscall2(_FileOpen, Path, (long)"r");
if (KP == NULL)
syscall1(_Exit, -0xF17E);
Elf64_Ehdr ELFHeader;
syscall3(_FileRead, KP, &ELFHeader, sizeof(Elf64_Ehdr));
Elf64_Phdr ItrProgramHeader;
for (Elf64_Half i = 0; i < ELFHeader.e_phnum; i++)
{
// memcpy(&ItrProgramHeader, (uint8_t *)ElfFile + ELFHeader.e_phoff + ELFHeader.e_phentsize * i, sizeof(Elf64_Phdr));
syscall3(_FileSeek, KP, ELFHeader.e_phoff + ELFHeader.e_phentsize * i, SEEK_SET);
syscall3(_FileRead, KP, &ItrProgramHeader, sizeof(Elf64_Phdr));
if (ItrProgramHeader.p_type == PT_DYNAMIC)
{
struct Elf64_Dyn Dynamic; // = (struct Elf64_Dyn *)((uint8_t *)ElfFile + ItrProgramHeader.p_offset);
syscall3(_FileSeek, KP, ItrProgramHeader.p_offset, SEEK_SET);
syscall3(_FileRead, KP, &Dynamic, ItrProgramHeader.p_filesz);
for (size_t i = 0; i < ItrProgramHeader.p_filesz / sizeof(struct Elf64_Dyn); i++)
{
if (Dynamic.d_tag == Tag || Dynamic.d_tag == DT_NULL)
{
syscall1(_FileClose, KP);
return Dynamic;
}
syscall3(_FileSeek, KP, ItrProgramHeader.p_offset + (i + 1) * sizeof(struct Elf64_Dyn), SEEK_SET);
syscall3(_FileRead, KP, &Dynamic, sizeof(struct Elf64_Dyn));
}
}
}
syscall1(_FileClose, KP);
return (struct Elf64_Dyn){0};
}
Elf64_Shdr *GetELFSheader(Elf64_Ehdr *Header)
{
Elf64_Off SheaderOffset = Header->e_shoff;
return (Elf64_Shdr *)((uintptr_t)Header + SheaderOffset);
}
Elf64_Shdr *GetELFSection(Elf64_Ehdr *Header, uint64_t Index)
{
Elf64_Shdr *Sheader = GetELFSheader(Header);
return &Sheader[Index];
}
char *GetELFStringTable(Elf64_Ehdr *Header)
{
if (Header->e_shstrndx == SHN_UNDEF)
return NULL;
return (char *)Header + GetELFSection(Header, Header->e_shstrndx)->sh_offset;
}
Elf64_Sym ELFLookupSymbol(char *Path, const char *Name)
{
void *KP = syscall2(_FileOpen, Path, (long)"r");
if (KP == NULL)
syscall1(_Exit, -0xF17E);
Elf64_Ehdr ELFHeader;
syscall3(_FileRead, KP, &ELFHeader, sizeof(Elf64_Ehdr));
Elf64_Shdr SymbolTable;
Elf64_Shdr StringTable;
Elf64_Sym Symbol;
char *String = NULL;
for (Elf64_Half i = 0; i < ELFHeader.e_shnum; i++)
{
Elf64_Shdr shdr;
syscall3(_FileSeek, KP,
ELFHeader.e_shoff + ELFHeader.e_shentsize * i,
SEEK_SET);
syscall3(_FileRead, KP, &shdr, sizeof(Elf64_Shdr));
switch (shdr.sh_type)
{
case SHT_SYMTAB:
{
SymbolTable = shdr;
syscall3(_FileSeek, KP,
ELFHeader.e_shoff + ELFHeader.e_shentsize * shdr.sh_link,
SEEK_SET);
syscall3(_FileRead, KP, &StringTable, sizeof(Elf64_Shdr));
break;
}
default:
{
break;
}
}
}
if (SymbolTable.sh_size == 0 || StringTable.sh_size == 0)
{
syscall1(_FileClose, KP);
return (Elf64_Sym){0};
}
for (size_t i = 0; i < (SymbolTable.sh_size / sizeof(Elf64_Sym)); i++)
{
// Symbol = (Elf64_Sym *)((uintptr_t)Header + SymbolTable->sh_offset + (i * sizeof(Elf64_Sym)));
// String = (char *)((uintptr_t)Header + StringTable->sh_offset + Symbol->st_name);
syscall3(_FileSeek, KP, SymbolTable.sh_offset + (i * sizeof(Elf64_Sym)), SEEK_SET);
syscall3(_FileRead, KP, &Symbol, sizeof(Elf64_Sym));
syscall3(_FileSeek, KP, StringTable.sh_offset + Symbol.st_name, SEEK_SET);
syscall3(_FileRead, KP, &String, sizeof(char *));
if (strcmp(String, Name) == 0)
{
syscall1(_FileClose, KP);
return Symbol;
}
}
syscall1(_FileClose, KP);
return (Elf64_Sym){0};
}

View File

@ -0,0 +1,31 @@
#ifndef __FENNIX_LIBC_FUNCTIONS_H__
#define __FENNIX_LIBC_FUNCTIONS_H__
#include <types.h>
#include "elf.h"
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
uintptr_t RequestPages(size_t Count);
int FreePages(uintptr_t Address, size_t Count);
int IPC(int Command, int Type, int ID, int Flags, void *Buffer, size_t Size);
uintptr_t KernelCTL(int Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4);
int abs(int i);
void swap(char *x, char *y);
char *reverse(char *Buffer, int i, int j);
char *ltoa(long Value, char *Buffer, int Base);
void PutCharToKernelConsole(char c);
void Print__(char *String);
void PrintNL__(char *String);
void *memcpy(void *dest, const void *src, size_t n);
void *memset(void *s, int c, size_t n);
int strcmp(const char *l, const char *r);
struct Elf64_Dyn ELFGetDynamicTag(char *Path, enum DynamicTags Tag);
Elf64_Shdr *GetELFSheader(Elf64_Ehdr *Header);
Elf64_Shdr *GetELFSection(Elf64_Ehdr *Header, uint64_t Index);
char *GetELFStringTable(Elf64_Ehdr *Header);
Elf64_Sym ELFLookupSymbol(char *Path, const char *Name);
#endif // !__FENNIX_LIBC_FUNCTIONS_H__

View File

@ -2,13 +2,13 @@
uint32_t ElfHash(const unsigned char *Name) uint32_t ElfHash(const unsigned char *Name)
{ {
uint32_t i = 0, j; uint32_t i = 0, j;
while (*Name) while (*Name)
{ {
i = (i << 4) + *Name++; i = (i << 4) + *Name++;
if ((j = i & 0xF0000000) != 0) if ((j = i & 0xF0000000) != 0)
i ^= j >> 24; i ^= j >> 24;
i &= ~j; i &= ~j;
} }
return i; return i;
} }

View File

@ -1,147 +1,14 @@
#include "ld.h" #include "ld.h"
#include "fcts.h"
#include "../../libs/include/libsys/base.h"
#include "../../../Kernel/syscalls.h" #include "../../../Kernel/syscalls.h"
#include "../../../Kernel/ipc.h" #include "../../../Kernel/ipc.h"
#include "elf.h" #include "elf.h"
uintptr_t RequestPages(size_t Count)
{
return syscall1(_RequestPages, Count);
}
int FreePages(uintptr_t Address, size_t Count)
{
return syscall2(_FreePages, Address, Count);
}
int IPC(enum IPCCommand Command, enum IPCType Type, int ID, int Flags, void *Buffer, size_t Size)
{
return syscall6(_IPC, (long)Command, (long)Type, (long)ID, (long)Flags, (long)Buffer, (long)Size);
}
uintptr_t KernelCTL(enum KCtl Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4)
{
return syscall5(_KernelCTL, Command, Arg1, Arg2, Arg3, Arg4);
}
struct LibAddressCollection
{
char Name[32];
uintptr_t ElfFile;
uintptr_t MemoryImage;
uintptr_t ParentElfFile;
uintptr_t ParentMemoryImage;
struct LibAddressCollection *Next;
char Valid;
};
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
static char Lock = 0;
__attribute__((naked, used, no_stack_protector)) void ELF_LAZY_RESOLVE_STUB()
{
while (Lock == 1)
;
__asm__ __volatile__("mfence\n");
Lock = 1;
__asm__ __volatile__("pop %r11\n"
"pop %r10\n"
"push %rdi\n"
"push %rsi\n"
"push %rdx\n"
"push %rcx\n"
"push %r8\n"
"push %r9\n"
"mov %r11, %rdi\n" // Move the first argument to rdi (libs collection)
"mov %r10, %rsi\n" // Move the second argument to rsi (rel index)
"call ELF_LAZY_RESOLVE_MAIN\n"
"mov %rax, %r11\n" // Move the return value to r11
"pop %r9\n"
"pop %r8\n"
"pop %rcx\n"
"pop %rdx\n"
"pop %rsi\n"
"pop %rdi\n"
"jmp *%r11\n"); // Jump to the return value
}
int abs(int i) { return i < 0 ? -i : i; }
void swap(char *x, char *y)
{
char t = *x;
*x = *y;
*y = t;
}
char *reverse(char *Buffer, int i, int j)
{
while (i < j)
swap(&Buffer[i++], &Buffer[j--]);
return Buffer;
}
char *ltoa(long Value, char *Buffer, int Base)
{
if (Base < 2 || Base > 32)
return Buffer;
long n = (long)abs((int)Value);
int i = 0;
while (n)
{
int r = n % Base;
if (r >= 10)
Buffer[i++] = 65 + (r - 10);
else
Buffer[i++] = 48 + r;
n = n / Base;
}
if (i == 0)
Buffer[i++] = '0';
if (Value < 0 && Base == 10)
Buffer[i++] = '-';
Buffer[i] = '\0';
return reverse(Buffer, 0, i - 1);
}
static inline void PutCharToKernelConsole(char c)
{
__asm__ __volatile__("syscall"
:
: "a"(1), "D"(c), "S"(0)
: "rcx", "r11", "memory");
}
void Print__(char *String)
{
for (short i = 0; String[i] != '\0'; i++)
PutCharToKernelConsole(String[i]);
}
void PrintNL__(char *String)
{
Print__(String);
Print__("\n");
}
#define Print(x) Print__(x) #define Print(x) Print__(x)
#define PrintNL(x) PrintNL__(x) #define PrintNL(x) PrintNL__(x)
#if (0) #if (1)
#define PrintDbg(x) Print__(x) #define PrintDbg(x) Print__(x)
#define PrintDbgNL(x) PrintNL__(x) #define PrintDbgNL(x) PrintNL__(x)
#define ltoaDbg(x, y, z) ltoa(x, y, z) #define ltoaDbg(x, y, z) ltoa(x, y, z)
@ -151,397 +18,400 @@ void PrintNL__(char *String)
#define ltoaDbg(x, y, z) #define ltoaDbg(x, y, z)
#endif #endif
void *memcpy(void *dest, const void *src, size_t n)
{
uint8_t *d = dest;
const uint8_t *s = src;
while (n--)
*d++ = *s++;
return dest;
}
void *memset(void *s, int c, size_t n)
{
uint8_t *p = s;
while (n--)
*p++ = c;
}
int strcmp(const char *l, const char *r)
{
for (; *l == *r && *l; l++, r++)
;
return *(unsigned char *)l - *(unsigned char *)r;
}
struct Elf64_Dyn *ELFGetDynamicTag(void *ElfFile, enum DynamicTags Tag)
{
Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)ElfFile;
Elf64_Phdr ItrProgramHeader;
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
{
memcpy(&ItrProgramHeader, (uint8_t *)ElfFile + ELFHeader->e_phoff + ELFHeader->e_phentsize * i, sizeof(Elf64_Phdr));
if (ItrProgramHeader.p_type == PT_DYNAMIC)
{
struct Elf64_Dyn *Dynamic = (struct Elf64_Dyn *)((uint8_t *)ElfFile + ItrProgramHeader.p_offset);
for (size_t i = 0; i < ItrProgramHeader.p_filesz / sizeof(struct Elf64_Dyn); i++)
{
if (Dynamic[i].d_tag == Tag)
return &Dynamic[i];
if (Dynamic[i].d_tag == DT_NULL)
return (void *)0;
}
}
}
return (void *)0;
}
Elf64_Shdr *GetELFSheader(Elf64_Ehdr *Header)
{
Elf64_Off SheaderOffset = Header->e_shoff;
return (Elf64_Shdr *)((uintptr_t)Header + SheaderOffset);
}
Elf64_Shdr *GetELFSection(Elf64_Ehdr *Header, uint64_t Index)
{
Elf64_Shdr *Sheader = GetELFSheader(Header);
return &Sheader[Index];
}
char *GetELFStringTable(Elf64_Ehdr *Header)
{
if (Header->e_shstrndx == SHN_UNDEF)
return NULL;
return (char *)Header + GetELFSection(Header, Header->e_shstrndx)->sh_offset;
}
Elf64_Sym *ELFLookupSymbol(Elf64_Ehdr *Header, const char *Name)
{
Elf64_Shdr *SymbolTable = NULL;
Elf64_Shdr *StringTable = NULL;
Elf64_Sym *Symbol = NULL;
char *String = NULL;
for (Elf64_Half i = 0; i < Header->e_shnum; i++)
{
Elf64_Shdr *shdr = GetELFSection(Header, i);
switch (shdr->sh_type)
{
case SHT_SYMTAB:
SymbolTable = shdr;
StringTable = GetELFSection(Header, shdr->sh_link);
break;
default:
{
break;
}
}
}
if (SymbolTable == NULL || StringTable == NULL)
return NULL;
for (size_t i = 0; i < (SymbolTable->sh_size / sizeof(Elf64_Sym)); i++)
{
Symbol = (Elf64_Sym *)((uintptr_t)Header + SymbolTable->sh_offset + (i * sizeof(Elf64_Sym)));
String = (char *)((uintptr_t)Header + StringTable->sh_offset + Symbol->st_name);
if (strcmp(String, Name) == 0)
return (void *)Symbol;
}
return NULL;
}
void (*ELF_LAZY_RESOLVE_MAIN(struct LibAddressCollection *Info, long RelIndex))()
{
char DbgBuff[32];
if (Info)
{
struct LibAddressCollection *CurLib = Info;
PrintDbgNL("_______");
// The last entry is the null entry (Valid == false) which determines the end of the list.
while (CurLib->Valid)
{
PrintDbg("-- ");
PrintDbg(CurLib->Name);
PrintDbg(" ");
ltoaDbg(RelIndex, DbgBuff, 10);
PrintDbg(DbgBuff);
PrintDbgNL(" --");
uintptr_t lib_BaseAddress = __UINTPTR_MAX__;
uintptr_t app_BaseAddress = __UINTPTR_MAX__;
Elf64_Phdr ItrProgramHeader;
for (Elf64_Half i = 0; i < ((Elf64_Ehdr *)CurLib->ElfFile)->e_phnum; i++)
{
memcpy(&ItrProgramHeader,
(uint8_t *)CurLib->ElfFile +
((Elf64_Ehdr *)CurLib->ElfFile)->e_phoff +
((Elf64_Ehdr *)CurLib->ElfFile)->e_phentsize * i,
sizeof(Elf64_Phdr));
lib_BaseAddress = MIN(lib_BaseAddress, ItrProgramHeader.p_vaddr);
}
for (Elf64_Half i = 0; i < ((Elf64_Ehdr *)CurLib->ParentElfFile)->e_phnum; i++)
{
memcpy(&ItrProgramHeader,
(uint8_t *)CurLib->ParentElfFile +
((Elf64_Ehdr *)CurLib->ParentElfFile)->e_phoff +
((Elf64_Ehdr *)CurLib->ParentElfFile)->e_phentsize * i,
sizeof(Elf64_Phdr));
app_BaseAddress = MIN(app_BaseAddress, ItrProgramHeader.p_vaddr);
}
struct Elf64_Dyn *lib_JmpRel = ELFGetDynamicTag((void *)CurLib->ElfFile, DT_JMPREL);
struct Elf64_Dyn *lib_SymTab = ELFGetDynamicTag((void *)CurLib->ElfFile, DT_SYMTAB);
struct Elf64_Dyn *lib_StrTab = ELFGetDynamicTag((void *)CurLib->ElfFile, DT_STRTAB);
struct Elf64_Dyn *app_JmpRel = ELFGetDynamicTag((void *)CurLib->ParentElfFile, DT_JMPREL);
struct Elf64_Dyn *app_SymTab = ELFGetDynamicTag((void *)CurLib->ParentElfFile, DT_SYMTAB);
struct Elf64_Dyn *app_StrTab = ELFGetDynamicTag((void *)CurLib->ParentElfFile, DT_STRTAB);
if (!lib_JmpRel)
{
PrintNL("No DT_JMPREL");
goto RetryNextLib;
}
else if (RelIndex >= lib_JmpRel->d_un.d_val / sizeof(Elf64_Rela))
{
PrintNL("RelIndex is greater than the number of relocations");
goto RetryNextLib;
}
if (!lib_SymTab)
{
PrintNL("No DT_SYMTAB");
goto RetryNextLib;
}
if (!lib_StrTab)
{
PrintNL("No DT_STRTAB");
goto RetryNextLib;
}
if (!lib_JmpRel && !lib_SymTab && !lib_StrTab)
goto RetryNextLib;
Elf64_Rela *_lib_JmpRel = (Elf64_Rela *)(CurLib->MemoryImage + (lib_JmpRel->d_un.d_ptr - lib_BaseAddress));
Elf64_Sym *_lib_SymTab = (Elf64_Sym *)(CurLib->MemoryImage + (lib_SymTab->d_un.d_ptr - lib_BaseAddress));
Elf64_Rela *_app_JmpRel = (Elf64_Rela *)(CurLib->ParentMemoryImage + (app_JmpRel->d_un.d_ptr - app_BaseAddress));
Elf64_Sym *_app_SymTab = (Elf64_Sym *)(CurLib->ParentMemoryImage + (app_SymTab->d_un.d_ptr - app_BaseAddress));
char *lib_DynStr = (char *)(CurLib->MemoryImage + (lib_StrTab->d_un.d_ptr - lib_BaseAddress));
char *app_DynStr = (char *)(CurLib->ParentMemoryImage + (app_StrTab->d_un.d_ptr - app_BaseAddress));
Elf64_Rela *Rel = _app_JmpRel + RelIndex;
Elf64_Addr *GOTEntry = (Elf64_Addr *)(Rel->r_offset);
int RelType = ELF64_R_TYPE(Rel->r_info);
switch (RelType)
{
case R_X86_64_NONE:
{
PrintDbgNL("R_X86_64_NONE");
if (*GOTEntry == 0)
{
PrintDbgNL("GOTEntry is 0");
break;
}
Lock = 0;
return (void (*)()) * GOTEntry;
}
case R_X86_64_JUMP_SLOT:
{
PrintDbgNL("R_X86_64_JUMP_SLOT");
int SymIndex = ELF64_R_SYM(Rel->r_info);
Elf64_Sym *Sym = _app_SymTab + SymIndex;
if (Sym->st_name)
{
char *SymName = app_DynStr + Sym->st_name;
PrintDbg("SymName: ");
PrintDbgNL(SymName);
Elf64_Sym *LibSym = ELFLookupSymbol((Elf64_Ehdr *)CurLib->ElfFile, SymName);
PrintDbg("LibSym: 0x");
ltoaDbg((long)LibSym, DbgBuff, 16);
PrintDbgNL(DbgBuff);
if (LibSym)
{
*GOTEntry = (Elf64_Addr)(CurLib->MemoryImage + LibSym->st_value);
ltoa(*GOTEntry, DbgBuff, 16);
PrintDbg("*GOTEntry: 0x");
PrintDbgNL(DbgBuff);
Lock = 0;
return (void (*)()) * GOTEntry;
}
PrintDbgNL("Not found in lib");
}
break;
}
default:
{
ltoa(RelType, DbgBuff, 10);
Print("RelType not supported ");
PrintNL(DbgBuff);
break;
}
}
RetryNextLib:
PrintDbgNL("Retrying next lib");
CurLib = CurLib->Next;
}
}
Lock = 0;
__asm__ __volatile__("mfence\n");
Print("Symbol index ");
ltoa(RelIndex, DbgBuff, 10);
Print(DbgBuff);
PrintNL(" not found");
int ExitCode = 0x51801;
syscall1(_Exit, ExitCode);
while (1) // Make sure we don't return
;
}
struct InterpreterIPCDataLibrary struct InterpreterIPCDataLibrary
{ {
char Name[128]; char Name[64];
}; };
typedef struct typedef struct
{ {
char Path[256]; char Path[256];
void *ElfFile; void *MemoryImage;
void *MemoryImage; struct InterpreterIPCDataLibrary Libraries[64];
struct InterpreterIPCDataLibrary Libraries[64];
} InterpreterIPCData; } InterpreterIPCData;
struct LibsCollection
{
char ParentName[32];
char LibraryName[32];
uintptr_t ParentMemoryImage;
uintptr_t LibraryMemoryImage;
struct LibsCollection *Next;
char Valid;
};
static char ParentPath[256];
static char Lock = 0;
__attribute__((naked, used, no_stack_protector)) void ELF_LAZY_RESOLVE_STUB()
{
while (Lock == 1)
;
__asm__ __volatile__("mfence\n");
Lock = 1;
__asm__ __volatile__("pop %r11\n"
"pop %r10\n"
"push %rdi\n"
"push %rsi\n"
"push %rdx\n"
"push %rcx\n"
"push %r8\n"
"push %r9\n"
"mov %r11, %rdi\n" // Move the first argument to rdi (libs collection)
"mov %r10, %rsi\n" // Move the second argument to rsi (rel index)
"call ELF_LAZY_RESOLVE_MAIN\n"
"mov %rax, %r11\n" // Move the return value to r11
"pop %r9\n"
"pop %r8\n"
"pop %rcx\n"
"pop %rdx\n"
"pop %rsi\n"
"pop %rdi\n"
"jmp *%r11\n"); // Jump to the return value
}
void (*ELF_LAZY_RESOLVE_MAIN(struct LibsCollection *Info, long RelIndex))()
{
if (!Info)
goto FailEnd;
char DbgBuff[32];
char LibraryPathBuffer[256];
struct LibsCollection *CurLib = Info;
PrintDbgNL("_______");
/* The last entry is the null entry (Valid == false)
which determines the end of the list. */
while (CurLib->Valid)
{
KernelCTL(KCTL_GET_ABSOLUTE_PATH, CurLib->LibraryName,
LibraryPathBuffer, sizeof(LibraryPathBuffer), 0);
PrintDbg("-- ");
PrintDbg(LibraryPathBuffer);
PrintDbg(" ");
ltoaDbg(RelIndex, DbgBuff, 10);
PrintDbg(DbgBuff);
PrintDbgNL(" --");
uintptr_t lib_BaseAddress = __UINTPTR_MAX__;
uintptr_t app_BaseAddress = __UINTPTR_MAX__;
Elf64_Ehdr lib_Header;
Elf64_Ehdr app_Header;
void *KP_lib = syscall2(_FileOpen, LibraryPathBuffer, "r");
void *KP_app = syscall2(_FileOpen, ParentPath, "r");
if (!KP_lib)
{
PrintNL("Failed to open library");
goto RetryNextLib;
}
if (!KP_app)
{
PrintNL("Failed to open application");
goto RetryNextLib;
}
syscall3(_FileRead, KP_lib, &lib_Header, sizeof(Elf64_Ehdr));
syscall3(_FileRead, KP_app, &app_Header, sizeof(Elf64_Ehdr));
Elf64_Phdr ItrProgramHeader;
for (Elf64_Half i = 0; i < lib_Header.e_phnum; i++)
{
syscall3(_FileSeek, KP_lib,
lib_Header.e_phoff +
lib_Header.e_phentsize * i,
SEEK_SET);
syscall3(_FileRead, KP_lib, &ItrProgramHeader, sizeof(Elf64_Phdr));
lib_BaseAddress = MIN(lib_BaseAddress, ItrProgramHeader.p_vaddr);
}
for (Elf64_Half i = 0; i < app_Header.e_phnum; i++)
{
syscall3(_FileSeek, KP_app,
app_Header.e_phoff +
app_Header.e_phentsize * i,
SEEK_SET);
syscall3(_FileRead, KP_app, &ItrProgramHeader, sizeof(Elf64_Phdr));
app_BaseAddress = MIN(app_BaseAddress, ItrProgramHeader.p_vaddr);
}
struct Elf64_Dyn lib_JmpRel = ELFGetDynamicTag(LibraryPathBuffer, DT_JMPREL);
struct Elf64_Dyn lib_SymTab = ELFGetDynamicTag(LibraryPathBuffer, DT_SYMTAB);
struct Elf64_Dyn lib_StrTab = ELFGetDynamicTag(LibraryPathBuffer, DT_STRTAB);
struct Elf64_Dyn app_JmpRel = ELFGetDynamicTag(ParentPath, DT_JMPREL);
struct Elf64_Dyn app_SymTab = ELFGetDynamicTag(ParentPath, DT_SYMTAB);
struct Elf64_Dyn app_StrTab = ELFGetDynamicTag(ParentPath, DT_STRTAB);
if (!lib_JmpRel.d_tag == 0)
{
PrintNL("No DT_JMPREL");
// goto RetryNextLib;
}
else if (RelIndex >= lib_JmpRel.d_un.d_val /
sizeof(Elf64_Rela))
{
PrintNL("RelIndex is greater than the number of relocations");
goto RetryNextLib;
}
if (!lib_SymTab.d_tag == 0)
{
PrintNL("No DT_SYMTAB");
goto RetryNextLib;
}
if (!lib_StrTab.d_tag == 0)
{
PrintNL("No DT_STRTAB");
goto RetryNextLib;
}
if (!lib_SymTab.d_tag == 0 &&
!lib_StrTab.d_tag == 0)
goto RetryNextLib;
Elf64_Rela *_lib_JmpRel = (Elf64_Rela *)(CurLib->LibraryMemoryImage + (lib_JmpRel.d_un.d_ptr - lib_BaseAddress));
Elf64_Sym *_lib_SymTab = (Elf64_Sym *)(CurLib->LibraryMemoryImage + (lib_SymTab.d_un.d_ptr - lib_BaseAddress));
Elf64_Rela *_app_JmpRel = (Elf64_Rela *)(CurLib->ParentMemoryImage + (app_JmpRel.d_un.d_ptr - app_BaseAddress));
Elf64_Sym *_app_SymTab = (Elf64_Sym *)(CurLib->ParentMemoryImage + (app_SymTab.d_un.d_ptr - app_BaseAddress));
char *lib_DynStr = (char *)(CurLib->LibraryMemoryImage + (lib_StrTab.d_un.d_ptr - lib_BaseAddress));
char *app_DynStr = (char *)(CurLib->ParentMemoryImage + (app_StrTab.d_un.d_ptr - app_BaseAddress));
Elf64_Rela *Rel = _app_JmpRel + RelIndex;
Elf64_Addr *GOTEntry = (Elf64_Addr *)(Rel->r_offset);
int RelType = ELF64_R_TYPE(Rel->r_info);
switch (RelType)
{
case R_X86_64_NONE:
{
PrintDbgNL("R_X86_64_NONE");
if (*GOTEntry == 0)
{
PrintDbgNL("GOTEntry is 0");
break;
}
Lock = 0;
return (void (*)()) * GOTEntry;
}
case R_X86_64_JUMP_SLOT:
{
PrintDbgNL("R_X86_64_JUMP_SLOT");
int SymIndex = ELF64_R_SYM(Rel->r_info);
Elf64_Sym *Sym = _app_SymTab + SymIndex;
if (Sym->st_name)
{
char *SymName = app_DynStr + Sym->st_name;
PrintDbg("SymName: ");
PrintDbgNL(SymName);
Elf64_Sym LibSym = ELFLookupSymbol(ParentPath, SymName);
PrintDbg("LibSym: 0x");
ltoaDbg((long)LibSym.st_size, DbgBuff, 16);
PrintDbgNL(DbgBuff);
if (LibSym.st_value)
{
*GOTEntry = (Elf64_Addr)(CurLib->LibraryMemoryImage + LibSym.st_value);
ltoa(*GOTEntry, DbgBuff, 16);
PrintDbg("*GOTEntry: 0x");
PrintDbgNL(DbgBuff);
Lock = 0;
return (void (*)()) * GOTEntry;
}
PrintDbgNL("Not found in lib");
}
break;
}
default:
{
ltoa(RelType, DbgBuff, 10);
Print("RelType not supported ");
PrintNL(DbgBuff);
break;
}
}
RetryNextLib:
PrintDbgNL("Retrying next lib");
CurLib = CurLib->Next;
}
FailEnd:
Lock = 0;
__asm__ __volatile__("mfence\n");
Print("Symbol index ");
ltoa(RelIndex, DbgBuff, 10);
Print(DbgBuff);
PrintNL(" not found");
int ExitCode = 0x51801;
syscall1(_Exit, ExitCode);
while (1) // Make sure we don't return
;
}
/* Preload */ /* Preload */
int ld_main() int ld_main()
{ {
/* Prevent race condition. */ /* Prevent race condition. */
uintptr_t KCTL_ret = KernelCTL(KCTL_IS_CRITICAL, 0, 0, 0, 0); uintptr_t KCTL_ret = KernelCTL(KCTL_IS_CRITICAL, 0, 0, 0, 0);
do do
{ {
syscall1(_Sleep, 250); syscall1(_Sleep, 250);
KCTL_ret = KernelCTL(KCTL_IS_CRITICAL, 0, 0, 0, 0); KCTL_ret = KernelCTL(KCTL_IS_CRITICAL, 0, 0, 0, 0);
} while (KCTL_ret == SYSCALL_ACCESS_DENIED); } while (KCTL_ret == SYSCALL_ACCESS_DENIED);
if (KCTL_ret == false) if (KCTL_ret == false)
return -4; return -1;
/* Everything is ok, continue. */ /* Everything is ok, continue. */
return 0; return 0;
} }
bool ELFAddLazyResolverToGOT(void *ElfFile, void *MemoryImage, struct LibAddressCollection *Libs) bool ELFAddLazyResolverToGOT(void *MemoryImage, struct LibsCollection *Libs)
{ {
struct Elf64_Dyn *Dyn = (struct Elf64_Dyn *)ELFGetDynamicTag(ElfFile, DT_PLTGOT); struct Elf64_Dyn Dyn = ELFGetDynamicTag(ParentPath, DT_PLTGOT);
if (!Dyn) if (!Dyn.d_tag)
return false; return false;
Elf64_Addr *GOT = (Elf64_Addr *)Dyn->d_un.d_ptr; Elf64_Addr *GOT = (Elf64_Addr *)Dyn.d_un.d_ptr;
GOT[1] = (uintptr_t)Libs; GOT[1] = (uintptr_t)Libs;
GOT[2] = (uintptr_t)ELF_LAZY_RESOLVE_STUB; GOT[2] = (uintptr_t)ELF_LAZY_RESOLVE_STUB;
return true; return true;
} }
/* Actual load */ /* Actual load */
int ld_load(int argc, char *argv[], char *envp[]) int ld_load(int argc, char *argv[], char *envp[])
{ {
uintptr_t PageSize = KernelCTL(KCTL_GET_PAGE_SIZE, 0, 0, 0, 0); PrintDbgNL("!");
int PagesForIPCDataStruct = sizeof(InterpreterIPCData) / PageSize + 1; uintptr_t PageSize = KernelCTL(KCTL_GET_PAGE_SIZE, 0, 0, 0, 0);
InterpreterIPCData *IPCBuffer = (InterpreterIPCData *)RequestPages(PagesForIPCDataStruct); int PagesForIPCDataStruct = sizeof(InterpreterIPCData) / PageSize + 1;
int PagesForLibsCollectionStruct = sizeof(struct LibsCollection) / PageSize + 1;
int IPC_ID = IPC(IPC_CREATE, IPC_TYPE_MessagePassing, 0, 0, "LOAD", sizeof(InterpreterIPCData)); InterpreterIPCData *IPCBuffer =
while (true) (InterpreterIPCData *)RequestPages(PagesForIPCDataStruct);
{
IPC(IPC_LISTEN, IPC_TYPE_MessagePassing, IPC_ID, 1, NULL, 0);
IPC(IPC_WAIT, IPC_TYPE_MessagePassing, IPC_ID, 0, NULL, 0);
int IPCResult = IPC(IPC_READ, IPC_TYPE_MessagePassing, IPC_ID, 0, IPCBuffer, PageSize);
if (IPCResult == IPC_E_CODE_Success)
break;
}
struct LibAddressCollection *LibsForLazyResolver = (struct LibAddressCollection *)RequestPages(sizeof(struct LibAddressCollection) / PageSize + 1); int IPC_ID = IPC(IPC_CREATE, IPC_TYPE_MessagePassing,
for (size_t i = 0; i < 64; i++) 0, 0, "LOAD", sizeof(InterpreterIPCData));
{ while (true)
if (IPCBuffer->Libraries[i].Name[0] == '\0') {
break; IPC(IPC_LISTEN, IPC_TYPE_MessagePassing, IPC_ID, 1, NULL, 0);
IPC(IPC_WAIT, IPC_TYPE_MessagePassing, IPC_ID, 0, NULL, 0);
int IPCResult = IPC(IPC_READ, IPC_TYPE_MessagePassing,
IPC_ID, 0, IPCBuffer, PageSize);
uintptr_t lib_addr = KernelCTL(KCTL_GET_ELF_LIB_FILE, (uint64_t)IPCBuffer->Libraries[i].Name, 0, 0, 0); if (IPCResult == IPC_E_CODE_Success)
uintptr_t lib_mm_image = KernelCTL(KCTL_GET_ELF_LIB_MEMORY_IMAGE, (uint64_t)IPCBuffer->Libraries[i].Name, 0, 0, 0); break;
if (lib_addr == 0 || lib_mm_image == 0) }
{
enum SyscallsErrorCodes ret = KernelCTL(KCTL_REGISTER_ELF_LIB, (uint64_t)IPCBuffer->Libraries[i].Name, (uint64_t)IPCBuffer->Libraries[i].Name, 0, 0);
if (ret != SYSCALL_OK)
{
PrintNL("Failed to register ELF lib");
return -0x11B;
}
lib_addr = KernelCTL(KCTL_GET_ELF_LIB_FILE, (uint64_t)IPCBuffer->Libraries[i].Name, 0, 0, 0);
lib_mm_image = KernelCTL(KCTL_GET_ELF_LIB_MEMORY_IMAGE, (uint64_t)IPCBuffer->Libraries[i].Name, 0, 0, 0);
}
if (LibsForLazyResolver->Next == NULL) struct LibsCollection *LibsForLazyResolver =
{ (struct LibsCollection *)RequestPages(PagesForLibsCollectionStruct);
LibsForLazyResolver->Valid = true;
LibsForLazyResolver->ElfFile = (uintptr_t)lib_addr;
LibsForLazyResolver->MemoryImage = (uintptr_t)lib_mm_image;
LibsForLazyResolver->ParentElfFile = (uintptr_t)IPCBuffer->ElfFile;
LibsForLazyResolver->ParentMemoryImage = (uintptr_t)IPCBuffer->MemoryImage;
for (size_t j = 0; j < 32; j++)
LibsForLazyResolver->Name[j] = IPCBuffer->Libraries[i].Name[j];
LibsForLazyResolver->Next = (struct LibAddressCollection *)RequestPages(sizeof(struct LibAddressCollection) / PageSize + 1); for (short i = 0; i < 64; i++)
memset(LibsForLazyResolver->Next, 0, sizeof(struct LibAddressCollection)); {
continue; if (IPCBuffer->Libraries[i].Name[0] == '\0')
} break;
struct LibAddressCollection *CurrentLibsForLazyResolver = LibsForLazyResolver;
while (CurrentLibsForLazyResolver->Next != NULL) uintptr_t lib_mm_image =
CurrentLibsForLazyResolver = CurrentLibsForLazyResolver->Next; KernelCTL(KCTL_GET_ELF_LIB_MEMORY_IMAGE,
(uint64_t)IPCBuffer->Libraries[i].Name, 0, 0, 0);
if (lib_mm_image == 0)
{
enum SyscallsErrorCodes ret =
KernelCTL(KCTL_REGISTER_ELF_LIB,
(uint64_t)IPCBuffer->Libraries[i].Name,
(uint64_t)IPCBuffer->Libraries[i].Name, 0, 0);
if (ret != SYSCALL_OK)
{
PrintNL("Failed to register ELF lib");
return -0x11B;
}
lib_mm_image = KernelCTL(KCTL_GET_ELF_LIB_MEMORY_IMAGE,
(uint64_t)IPCBuffer->Libraries[i].Name, 0, 0, 0);
}
CurrentLibsForLazyResolver->Valid = true; if (LibsForLazyResolver->Next == NULL)
CurrentLibsForLazyResolver->ElfFile = (uintptr_t)lib_addr; {
CurrentLibsForLazyResolver->MemoryImage = (uintptr_t)lib_mm_image; LibsForLazyResolver->Valid = true;
CurrentLibsForLazyResolver->ParentElfFile = (uintptr_t)IPCBuffer->ElfFile; LibsForLazyResolver->LibraryMemoryImage = (uintptr_t)lib_mm_image;
CurrentLibsForLazyResolver->ParentMemoryImage = (uintptr_t)IPCBuffer->MemoryImage; LibsForLazyResolver->ParentMemoryImage = (uintptr_t)IPCBuffer->MemoryImage;
for (size_t j = 0; j < 32; j++) for (short j = 0; j < sizeof(LibsForLazyResolver->LibraryName); j++)
CurrentLibsForLazyResolver->Name[j] = IPCBuffer->Libraries[i].Name[j]; LibsForLazyResolver->LibraryName[j] = IPCBuffer->Libraries[i].Name[j];
CurrentLibsForLazyResolver->Next = (struct LibAddressCollection *)RequestPages(sizeof(struct LibAddressCollection) / PageSize + 1); LibsForLazyResolver->Next =
memset(CurrentLibsForLazyResolver->Next, 0, sizeof(struct LibAddressCollection)); (struct LibsCollection *)RequestPages(PagesForLibsCollectionStruct);
} memset(LibsForLazyResolver->Next, 0, sizeof(struct LibsCollection));
continue;
}
struct LibAddressCollection *CurrentLibsForLazyResolver = LibsForLazyResolver; struct LibsCollection *CurrentLib = LibsForLazyResolver;
while (CurrentLib->Next != NULL)
CurrentLib = CurrentLib->Next;
if (!ELFAddLazyResolverToGOT(IPCBuffer->ElfFile, IPCBuffer->MemoryImage, LibsForLazyResolver)) CurrentLib->Valid = true;
{ CurrentLib->LibraryMemoryImage = (uintptr_t)lib_mm_image;
PrintNL("Failed to add lazy resolver to GOT"); CurrentLib->ParentMemoryImage = (uintptr_t)IPCBuffer->MemoryImage;
return -0x607; for (short j = 0; j < sizeof(LibsForLazyResolver->LibraryName); j++)
} CurrentLib->LibraryName[j] = IPCBuffer->Libraries[i].Name[j];
Elf64_Addr Entry = ((Elf64_Ehdr *)IPCBuffer->ElfFile)->e_entry; CurrentLib->Next =
(struct LibsCollection *)RequestPages(PagesForLibsCollectionStruct);
memset(CurrentLib->Next, 0, sizeof(struct LibsCollection));
}
IPC(IPC_DELETE, IPC_TYPE_MessagePassing, IPC_ID, 0, NULL, 0); struct LibsCollection *CurrentLib = LibsForLazyResolver;
FreePages((uintptr_t)IPCBuffer, PagesForIPCDataStruct);
return ((int (*)(int, char *[], char *[]))Entry)(argc, argv, envp); for (int i = 0; i < sizeof(ParentPath); i++)
ParentPath[i] = IPCBuffer->Path[i];
if (!ELFAddLazyResolverToGOT(IPCBuffer->MemoryImage,
LibsForLazyResolver))
{
PrintNL("Failed to add lazy resolver to GOT");
return -0x607;
}
void *KP = syscall2(_FileOpen, ParentPath, (long)"r");
if (KP == NULL)
{
PrintNL("Failed to open file");
syscall1(_Exit, -0xF17E);
}
Elf64_Ehdr ELFHeader;
syscall3(_FileRead, KP, &ELFHeader, sizeof(Elf64_Ehdr));
Elf64_Addr Entry = ELFHeader.e_entry;
syscall1(_FileClose, KP);
IPC(IPC_DELETE, IPC_TYPE_MessagePassing, IPC_ID, 0, NULL, 0);
FreePages((uintptr_t)IPCBuffer, PagesForIPCDataStruct);
PrintDbgNL("Calling entry point");
return ((int (*)(int, char *[], char *[]))Entry)(argc, argv, envp);
} }

View File

@ -1,36 +1,36 @@
void __attribute__((naked, used, no_stack_protector)) _ld_start() void __attribute__((naked, used, no_stack_protector)) _start()
{ {
__asm__("movq $0, %rbp\n" __asm__("movq $0, %rbp\n"
"pushq %rbp\n" "pushq %rbp\n"
"pushq %rbp\n" "pushq %rbp\n"
"movq %rsp, %rbp\n" "movq %rsp, %rbp\n"
"pushq %rcx\n" "pushq %rcx\n"
"pushq %rdx\n" "pushq %rdx\n"
"pushq %rsi\n" "pushq %rsi\n"
"pushq %rdi\n" "pushq %rdi\n"
"call ld_main\n" "call ld_main\n"
"movl %eax, %edi\n" // Move return value to edi "movl %eax, %edi\n" // Move return value to edi
"cmp $0, %edi\n" // Check if return value is 0 "cmp $0, %edi\n" // Check if return value is 0
"jne _exit\n" // If not, jump to _exit "jne _exit\n" // If not, jump to _exit
"popq %rdi\n" "popq %rdi\n"
"popq %rsi\n" "popq %rsi\n"
"popq %rdx\n" "popq %rdx\n"
"popq %rcx\n" "popq %rcx\n"
"call ld_load\n" "call ld_load\n"
"movl %eax, %edi\n" // Move return value to edi "movl %eax, %edi\n" // Move return value to edi
"call _exit"); // Call _exit "call _exit"); // Call _exit
} }
void _exit(int Code) void _exit(int Code)
{ {
__asm__ __volatile__("syscall" __asm__ __volatile__("syscall"
: :
: "a"(0), "D"(Code) : "a"(0), "D"(Code)
: "rcx", "r11", "memory"); : "rcx", "r11", "memory");
while (1) while (1)
; ;
} }

View File

@ -2,249 +2,249 @@
/* This function is a mess and needs to be cleaned up. */ /* This function is a mess and needs to be cleaned up. */
bool ELFDynamicReallocation(void *ElfFile, void *MemoryImage) bool ELFDynamicReallocation(void *ElfFile, void *MemoryImage)
{ {
debug("ELF dynamic reallocation for image at %#lx.", ElfFile); debug("ELF dynamic reallocation for image at %#lx.", ElfFile);
Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)ElfFile; Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)ElfFile;
uintptr_t BaseAddress = UINTPTR_MAX; uintptr_t BaseAddress = UINTPTR_MAX;
size_t ElfAppSize = 0; size_t ElfAppSize = 0;
Elf64_Phdr ItrPhdr; Elf64_Phdr ItrPhdr;
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++) for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
{ {
memcpy(&ItrPhdr, memcpy(&ItrPhdr,
(uint8_t *)ElfFile + ELFHeader->e_phoff + ELFHeader->e_phentsize * i, (uint8_t *)ElfFile + ELFHeader->e_phoff + ELFHeader->e_phentsize * i,
sizeof(Elf64_Phdr)); sizeof(Elf64_Phdr));
BaseAddress = MIN(BaseAddress, ItrPhdr.p_vaddr); BaseAddress = MIN(BaseAddress, ItrPhdr.p_vaddr);
} }
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++) for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
{ {
memcpy(&ItrPhdr, memcpy(&ItrPhdr,
(uint8_t *)ElfFile + ELFHeader->e_phoff + ELFHeader->e_phentsize * i, (uint8_t *)ElfFile + ELFHeader->e_phoff + ELFHeader->e_phentsize * i,
sizeof(Elf64_Phdr)); sizeof(Elf64_Phdr));
uintptr_t SegmentEnd = ItrPhdr.p_vaddr - BaseAddress + ItrPhdr.p_memsz; uintptr_t SegmentEnd = ItrPhdr.p_vaddr - BaseAddress + ItrPhdr.p_memsz;
ElfAppSize = MAX(ElfAppSize, SegmentEnd); ElfAppSize = MAX(ElfAppSize, SegmentEnd);
} }
debug("BaseAddress: %#lx Size: %ld", BaseAddress, ElfAppSize); debug("BaseAddress: %#lx Size: %ld", BaseAddress, ElfAppSize);
Elf64_Dyn *_GOTEntry = (Elf64_Dyn *)ELFGetDynamicTag(ElfFile, DT_PLTGOT); Elf64_Dyn *_GOTEntry = (Elf64_Dyn *)ELFGetDynamicTag(ElfFile, DT_PLTGOT);
Elf64_Dyn *_Rela = ELFGetDynamicTag(ElfFile, DT_RELA); Elf64_Dyn *_Rela = ELFGetDynamicTag(ElfFile, DT_RELA);
Elf64_Dyn *_RelaEnt = ELFGetDynamicTag(ElfFile, DT_RELAENT); Elf64_Dyn *_RelaEnt = ELFGetDynamicTag(ElfFile, DT_RELAENT);
Elf64_Dyn *_JmpRel = ELFGetDynamicTag(ElfFile, DT_JMPREL); Elf64_Dyn *_JmpRel = ELFGetDynamicTag(ElfFile, DT_JMPREL);
Elf64_Dyn *_SymTab = ELFGetDynamicTag(ElfFile, DT_SYMTAB); Elf64_Dyn *_SymTab = ELFGetDynamicTag(ElfFile, DT_SYMTAB);
Elf64_Dyn *_StrTab = ELFGetDynamicTag(ElfFile, DT_STRTAB); Elf64_Dyn *_StrTab = ELFGetDynamicTag(ElfFile, DT_STRTAB);
Elf64_Dyn *RelaSize = ELFGetDynamicTag(ElfFile, DT_RELASZ); Elf64_Dyn *RelaSize = ELFGetDynamicTag(ElfFile, DT_RELASZ);
Elf64_Dyn *PltRelSize = ELFGetDynamicTag(ElfFile, DT_PLTRELSZ); Elf64_Dyn *PltRelSize = ELFGetDynamicTag(ElfFile, DT_PLTRELSZ);
Elf64_Addr *GOTEntry = (Elf64_Addr *)((uintptr_t)(_GOTEntry->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage); Elf64_Addr *GOTEntry = (Elf64_Addr *)((uintptr_t)(_GOTEntry->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
Elf64_Dyn *Rela = (Elf64_Dyn *)((uintptr_t)(_Rela->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage); Elf64_Dyn *Rela = (Elf64_Dyn *)((uintptr_t)(_Rela->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
Elf64_Dyn *RelaEnt = (Elf64_Dyn *)((uintptr_t)(_RelaEnt->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage); Elf64_Dyn *RelaEnt = (Elf64_Dyn *)((uintptr_t)(_RelaEnt->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
Elf64_Dyn *JmpRel = (Elf64_Dyn *)((uintptr_t)(_JmpRel->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage); Elf64_Dyn *JmpRel = (Elf64_Dyn *)((uintptr_t)(_JmpRel->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
Elf64_Dyn *SymTab = (Elf64_Dyn *)((uintptr_t)(_SymTab->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage); Elf64_Dyn *SymTab = (Elf64_Dyn *)((uintptr_t)(_SymTab->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
Elf64_Dyn *StrTab = (Elf64_Dyn *)((uintptr_t)(_StrTab->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage); Elf64_Dyn *StrTab = (Elf64_Dyn *)((uintptr_t)(_StrTab->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
debug("GOTEntry: %#lx [%#lx]", _GOTEntry, GOTEntry); debug("GOTEntry: %#lx [%#lx]", _GOTEntry, GOTEntry);
debug("Rela: %#lx [%#lx]", _Rela, Rela); debug("Rela: %#lx [%#lx]", _Rela, Rela);
debug("RelaEnt: %#lx [%#lx]", _RelaEnt, RelaEnt); debug("RelaEnt: %#lx [%#lx]", _RelaEnt, RelaEnt);
debug("JmpRel: %#lx [%#lx]", _JmpRel, JmpRel); debug("JmpRel: %#lx [%#lx]", _JmpRel, JmpRel);
debug("SymTab: %#lx [%#lx]", _SymTab, SymTab); debug("SymTab: %#lx [%#lx]", _SymTab, SymTab);
debug("StrTab: %#lx [%#lx]", _StrTab, StrTab); debug("StrTab: %#lx [%#lx]", _StrTab, StrTab);
if (RelaSize) if (RelaSize)
debug("RelaSize: %ld", RelaSize->d_un.d_val); debug("RelaSize: %ld", RelaSize->d_un.d_val);
if (PltRelSize) if (PltRelSize)
debug("PltRelSize: %ld", PltRelSize->d_un.d_val); debug("PltRelSize: %ld", PltRelSize->d_un.d_val);
Elf64_Xword PltRelSizeVal = PltRelSize ? PltRelSize->d_un.d_val : 0; Elf64_Xword PltRelSizeVal = PltRelSize ? PltRelSize->d_un.d_val : 0;
Elf64_Xword RelaSizeVal = RelaSize ? RelaSize->d_un.d_val : 0; Elf64_Xword RelaSizeVal = RelaSize ? RelaSize->d_un.d_val : 0;
Elf64_Xword PltRelSizeValCount = PltRelSizeVal / sizeof(Elf64_Rela); Elf64_Xword PltRelSizeValCount = PltRelSizeVal / sizeof(Elf64_Rela);
Elf64_Xword RelaSizeValCount = RelaSizeVal / sizeof(Elf64_Rela); Elf64_Xword RelaSizeValCount = RelaSizeVal / sizeof(Elf64_Rela);
debug("PltRelSizeVal: %ld", PltRelSizeVal); debug("PltRelSizeVal: %ld", PltRelSizeVal);
debug("RelaSizeVal: %ld", RelaSizeVal); debug("RelaSizeVal: %ld", RelaSizeVal);
debug("PltRelSizeValCount: %ld", PltRelSizeValCount); debug("PltRelSizeValCount: %ld", PltRelSizeValCount);
debug("RelaSizeValCount: %ld", RelaSizeValCount); debug("RelaSizeValCount: %ld", RelaSizeValCount);
for (Elf64_Xword i = 0; i < PltRelSizeValCount; i++) for (Elf64_Xword i = 0; i < PltRelSizeValCount; i++)
{ {
Elf64_Rela *RelaF = (Elf64_Rela *)((uintptr_t)JmpRel + i); Elf64_Rela *RelaF = (Elf64_Rela *)((uintptr_t)JmpRel + i);
Elf64_Xword RelaType = ELF64_R_TYPE(RelaF->r_info); Elf64_Xword RelaType = ELF64_R_TYPE(RelaF->r_info);
debug("Itr %ld Type %ld", i, RelaType); debug("Itr %ld Type %ld", i, RelaType);
switch (RelaType) switch (RelaType)
{ {
case R_X86_64_NONE: case R_X86_64_NONE:
{ {
debug("No relocation needed"); debug("No relocation needed");
break; break;
} }
case R_X86_64_JUMP_SLOT: case R_X86_64_JUMP_SLOT:
{ {
debug("Relocation for jump slot"); debug("Relocation for jump slot");
Elf64_Xword SymIndex = ELF64_R_SYM(RelaF->r_info); Elf64_Xword SymIndex = ELF64_R_SYM(RelaF->r_info);
Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)SymTab + SymIndex); Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)SymTab + SymIndex);
char *SymName = (char *)((uintptr_t)StrTab + Sym->st_name); char *SymName = (char *)((uintptr_t)StrTab + Sym->st_name);
debug("Symbol %s at %#lx", SymName, Sym->st_value); debug("Symbol %s at %#lx", SymName, Sym->st_value);
Elf64_Addr *GOTEntry = (Elf64_Addr *)RelaF->r_offset; Elf64_Addr *GOTEntry = (Elf64_Addr *)RelaF->r_offset;
if (Sym->st_value) if (Sym->st_value)
{ {
fixme("Not implemented"); fixme("Not implemented");
*GOTEntry = (Elf64_Addr)ElfFile + Sym->st_value; *GOTEntry = (Elf64_Addr)ElfFile + Sym->st_value;
} }
// else // else
// *GOTEntry = (Elf64_Addr)ElfLazyResolver; // *GOTEntry = (Elf64_Addr)ElfLazyResolver;
// Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)ElfFile + (uintptr_t)SymTab + ELF64_R_SYM(RelaF->r_info) * sizeof(Elf64_Sym)); // Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)ElfFile + (uintptr_t)SymTab + ELF64_R_SYM(RelaF->r_info) * sizeof(Elf64_Sym));
// char *SymName = (char *)((uintptr_t)ElfFile + (uintptr_t)StrTab + Sym->st_name); // char *SymName = (char *)((uintptr_t)ElfFile + (uintptr_t)StrTab + Sym->st_name);
// void *SymAddr = (void *)Lib->Address + Sym->st_value; // void *SymAddr = (void *)Lib->Address + Sym->st_value;
// debug("Symbol %s at %#lx", SymName, SymAddr); // debug("Symbol %s at %#lx", SymName, SymAddr);
// *(void **)(RelaF->r_offset + (uintptr_t)ElfFile) = SymAddr; // *(void **)(RelaF->r_offset + (uintptr_t)ElfFile) = SymAddr;
break; break;
} }
case R_X86_64_RELATIVE: case R_X86_64_RELATIVE:
{ {
debug("Relative relocation"); debug("Relative relocation");
uintptr_t *Ptr = (uintptr_t *)((uintptr_t)ElfFile + RelaF->r_offset); uintptr_t *Ptr = (uintptr_t *)((uintptr_t)ElfFile + RelaF->r_offset);
*Ptr = (uintptr_t)MemoryImage + RelaF->r_addend; *Ptr = (uintptr_t)MemoryImage + RelaF->r_addend;
break; break;
} }
default: default:
{ {
fixme("RelaType %d", RelaType); fixme("RelaType %d", RelaType);
break; break;
} }
} }
} }
for (Elf64_Xword i = 0; i < RelaSizeValCount; i++) for (Elf64_Xword i = 0; i < RelaSizeValCount; i++)
{ {
Elf64_Rela *RelaF = (Elf64_Rela *)((uintptr_t)ElfFile + (uintptr_t)Rela + i); Elf64_Rela *RelaF = (Elf64_Rela *)((uintptr_t)ElfFile + (uintptr_t)Rela + i);
Elf64_Xword RelaType = ELF64_R_TYPE(RelaF->r_info); Elf64_Xword RelaType = ELF64_R_TYPE(RelaF->r_info);
debug("Itr %ld Type %ld", i, RelaType); debug("Itr %ld Type %ld", i, RelaType);
switch (RelaType) switch (RelaType)
{ {
case R_X86_64_NONE: case R_X86_64_NONE:
{ {
debug("No relocation needed"); debug("No relocation needed");
break; break;
} }
case R_X86_64_64: case R_X86_64_64:
{ {
debug("64-bit relocation"); debug("64-bit relocation");
Elf64_Xword SymIndex = ELF64_R_SYM(RelaF->r_info); Elf64_Xword SymIndex = ELF64_R_SYM(RelaF->r_info);
Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)ElfFile + (uintptr_t)SymTab + SymIndex); Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)ElfFile + (uintptr_t)SymTab + SymIndex);
char *SymName = (char *)((uintptr_t)ElfFile + (uintptr_t)StrTab + Sym->st_name); char *SymName = (char *)((uintptr_t)ElfFile + (uintptr_t)StrTab + Sym->st_name);
debug("Symbol %s at %#lx", SymName, Sym->st_value); debug("Symbol %s at %#lx", SymName, Sym->st_value);
uintptr_t *Ptr = (uintptr_t *)((uintptr_t)ElfFile + RelaF->r_offset); uintptr_t *Ptr = (uintptr_t *)((uintptr_t)ElfFile + RelaF->r_offset);
*Ptr = (uintptr_t)MemoryImage + Sym->st_value + RelaF->r_addend; *Ptr = (uintptr_t)MemoryImage + Sym->st_value + RelaF->r_addend;
break; break;
} }
case R_X86_64_GLOB_DAT: case R_X86_64_GLOB_DAT:
{ {
debug("Global data relocation"); debug("Global data relocation");
Elf64_Xword SymIndex = ELF64_R_SYM(RelaF->r_info); Elf64_Xword SymIndex = ELF64_R_SYM(RelaF->r_info);
Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)ElfFile + (uintptr_t)SymTab + SymIndex); Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)ElfFile + (uintptr_t)SymTab + SymIndex);
char *SymName = (char *)((uintptr_t)ElfFile + (uintptr_t)StrTab + Sym->st_name); char *SymName = (char *)((uintptr_t)ElfFile + (uintptr_t)StrTab + Sym->st_name);
debug("Symbol %s at %#lx", SymName, Sym->st_value); debug("Symbol %s at %#lx", SymName, Sym->st_value);
uintptr_t *Ptr = (uintptr_t *)((uintptr_t)ElfFile + RelaF->r_offset); uintptr_t *Ptr = (uintptr_t *)((uintptr_t)ElfFile + RelaF->r_offset);
*Ptr = (uintptr_t)MemoryImage + Sym->st_value; *Ptr = (uintptr_t)MemoryImage + Sym->st_value;
break; break;
} }
case R_X86_64_RELATIVE: case R_X86_64_RELATIVE:
{ {
debug("Relative relocation"); debug("Relative relocation");
Elf64_Xword SymIndex = ELF64_R_SYM(RelaF->r_info); Elf64_Xword SymIndex = ELF64_R_SYM(RelaF->r_info);
Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)ElfFile + (uintptr_t)SymTab + SymIndex); Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)ElfFile + (uintptr_t)SymTab + SymIndex);
char *SymName = (char *)((uintptr_t)ElfFile + (uintptr_t)StrTab + Sym->st_name); char *SymName = (char *)((uintptr_t)ElfFile + (uintptr_t)StrTab + Sym->st_name);
debug("Symbol %s at %#lx", SymName, Sym->st_value); debug("Symbol %s at %#lx", SymName, Sym->st_value);
uintptr_t *Ptr = (uintptr_t *)((uintptr_t)ElfFile + RelaF->r_offset); uintptr_t *Ptr = (uintptr_t *)((uintptr_t)ElfFile + RelaF->r_offset);
*Ptr = (uintptr_t)MemoryImage + RelaF->r_addend; *Ptr = (uintptr_t)MemoryImage + RelaF->r_addend;
break; break;
} }
default: default:
{ {
fixme("RelaType %d", RelaType); fixme("RelaType %d", RelaType);
break; break;
} }
} }
} }
return true; return true;
} }
ELFDynamicReallocation(ElfFile, MemoryImage); ELFDynamicReallocation(ElfFile, MemoryImage);
LibAddressCollection *LibsForLazyResolver = (LibAddressCollection *)ELFBase.TmpMem->RequestPages(TO_PAGES(sizeof(LibAddressCollection)), true); LibAddressCollection *LibsForLazyResolver = (LibAddressCollection *)ELFBase.TmpMem->RequestPages(TO_PAGES(sizeof(LibAddressCollection)), true);
memset(LibsForLazyResolver, 0, sizeof(LibAddressCollection)); memset(LibsForLazyResolver, 0, sizeof(LibAddressCollection));
LibAddressCollection *LFLRTmp = LibsForLazyResolver; LibAddressCollection *LFLRTmp = LibsForLazyResolver;
debug("LibsForLazyResolver: %#lx", LibsForLazyResolver); debug("LibsForLazyResolver: %#lx", LibsForLazyResolver);
if (NeededLibraries.size() > 0) if (NeededLibraries.size() > 0)
{ {
VirtualFileSystem::Node *ParentNode = ExFile->Node->Parent; // Working Directory VirtualFileSystem::Node *ParentNode = ExFile->Node->Parent; // Working Directory
if (ParentNode) if (ParentNode)
{ {
char *WorkingDirAbsolutePath = vfs->GetPathFromNode(ParentNode); char *WorkingDirAbsolutePath = vfs->GetPathFromNode(ParentNode);
debug("Working directory: \"%s\"", WorkingDirAbsolutePath); debug("Working directory: \"%s\"", WorkingDirAbsolutePath);
int LibCount = 0; int LibCount = 0;
foreach (auto Library in NeededLibraries) foreach (auto Library in NeededLibraries)
{ {
char LibPath[256]; char LibPath[256];
strcpy(LibPath, WorkingDirAbsolutePath); strcpy(LibPath, WorkingDirAbsolutePath);
strcat(LibPath, "/"); strcat(LibPath, "/");
strcat(LibPath, Library); strcat(LibPath, Library);
debug("Searching for \"%s\"...", LibPath); debug("Searching for \"%s\"...", LibPath);
bool AlreadyTried = false; bool AlreadyTried = false;
LibPathRetry: LibPathRetry:
VirtualFileSystem::FILE *LibNode = vfs->Open(LibPath); VirtualFileSystem::FILE *LibNode = vfs->Open(LibPath);
if (LibNode->Status != VirtualFileSystem::FileStatus::OK) if (LibNode->Status != VirtualFileSystem::FileStatus::OK)
{ {
vfs->Close(LibNode); vfs->Close(LibNode);
if (!AlreadyTried) if (!AlreadyTried)
{ {
debug("Library \"%s\" not found, retrying... (%#x)", LibPath, LibNode->Status); debug("Library \"%s\" not found, retrying... (%#x)", LibPath, LibNode->Status);
memset(LibPath, 0, 256); memset(LibPath, 0, 256);
strcpy(LibPath, "/lib/"); strcpy(LibPath, "/lib/");
strcat(LibPath, Library); strcat(LibPath, Library);
AlreadyTried = true; AlreadyTried = true;
goto LibPathRetry; goto LibPathRetry;
} }
else else
warn("Failed to load library \"%s\" (%#x)", Library, LibNode->Status); warn("Failed to load library \"%s\" (%#x)", Library, LibNode->Status);
} }
else else
{ {
debug("Library found \"%s\" (%#x)", LibPath, LibNode->Status); debug("Library found \"%s\" (%#x)", LibPath, LibNode->Status);
SharedLibraries *sl = AddLibrary(Library, (void *)LibNode->Node->Address, LibNode->Node->Length); SharedLibraries *sl = AddLibrary(Library, (void *)LibNode->Node->Address, LibNode->Node->Length);
strcpy(LFLRTmp->Name, Library); strcpy(LFLRTmp->Name, Library);
LFLRTmp->ElfFile = (uintptr_t *)sl->Address; LFLRTmp->ElfFile = (uintptr_t *)sl->Address;
LFLRTmp->MemoryImage = (uintptr_t *)sl->MemoryImage; LFLRTmp->MemoryImage = (uintptr_t *)sl->MemoryImage;
LFLRTmp->ParentElfFile = (uintptr_t *)ElfFile; LFLRTmp->ParentElfFile = (uintptr_t *)ElfFile;
LFLRTmp->ParentMemoryImage = (uintptr_t *)MemoryImage; LFLRTmp->ParentMemoryImage = (uintptr_t *)MemoryImage;
LFLRTmp->Valid = true; LFLRTmp->Valid = true;
debug("LIBRARY: %s, %#lx, %#lx", Library, LFLRTmp->ElfFile, LFLRTmp->MemoryImage); debug("LIBRARY: %s, %#lx, %#lx", Library, LFLRTmp->ElfFile, LFLRTmp->MemoryImage);
LFLRTmp->Next = (LibAddressCollection *)ELFBase.TmpMem->RequestPages(TO_PAGES(sizeof(LibAddressCollection)), true); LFLRTmp->Next = (LibAddressCollection *)ELFBase.TmpMem->RequestPages(TO_PAGES(sizeof(LibAddressCollection)), true);
LFLRTmp = LFLRTmp->Next; LFLRTmp = LFLRTmp->Next;
memset(LFLRTmp, 0, sizeof(LibAddressCollection)); memset(LFLRTmp, 0, sizeof(LibAddressCollection));
} }
} }
} }
else else
{ {
error("Couldn't get the parent node from path %s", vfs->GetPathFromNode(ExFile->Node)); error("Couldn't get the parent node from path %s", vfs->GetPathFromNode(ExFile->Node));
} }
} }
ELFAddLazyResolverToGOT(ElfFile, MemoryImage, LibsForLazyResolver); ELFAddLazyResolverToGOT(ElfFile, MemoryImage, LibsForLazyResolver);

View File

@ -44,20 +44,20 @@
typedef struct typedef struct
{ {
uint32_t a_type; uint32_t a_type;
union union
{ {
uint32_t a_val; uint32_t a_val;
} a_un; } a_un;
} Elf32_auxv_t; } Elf32_auxv_t;
typedef struct typedef struct
{ {
uint64_t a_type; uint64_t a_type;
union union
{ {
uint64_t a_val; uint64_t a_val;
} a_un; } a_un;
} Elf64_auxv_t; } Elf64_auxv_t;
#ifdef __LP64__ #ifdef __LP64__

View File

@ -3,7 +3,7 @@
struct sched_param struct sched_param
{ {
int sched_priority; int sched_priority;
}; };
#endif // !_BITS_TYPES_STRUCT_SCHED_PARAM_T_H #endif // !_BITS_TYPES_STRUCT_SCHED_PARAM_T_H

View File

@ -8,38 +8,38 @@
struct __spawn_action struct __spawn_action
{ {
int __stub; int __stub;
}; };
typedef struct typedef struct
{ {
short int __flags; short int __flags;
pid_t __pgrp; pid_t __pgrp;
sigset_t __sd; sigset_t __sd;
sigset_t __ss; sigset_t __ss;
struct sched_param __sp; struct sched_param __sp;
int __policy; int __policy;
int __pad[16]; int __pad[16];
} posix_spawnattr_t; } posix_spawnattr_t;
typedef struct typedef struct
{ {
int __allocated; int __allocated;
int __used; int __used;
struct __spawn_action *__actions; struct __spawn_action *__actions;
int __pad[16]; int __pad[16];
} posix_spawn_file_actions_t; } posix_spawn_file_actions_t;
int posix_spawn(pid_t *pid, const char *path, int posix_spawn(pid_t *pid, const char *path,
const posix_spawn_file_actions_t *file_actions, const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp, const posix_spawnattr_t *attrp,
char *const argv[], char *const argv[],
char *const envp[]); char *const envp[]);
int posix_spawnp(pid_t *pid, const char *file, int posix_spawnp(pid_t *pid, const char *file,
const posix_spawn_file_actions_t *file_actions, const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp, const posix_spawnattr_t *attrp,
char *const argv[], char *const argv[],
char *const envp[]); char *const envp[]);
#endif // !_SPAWN_H #endif // !_SPAWN_H

View File

@ -18,31 +18,31 @@
struct _IO_marker struct _IO_marker
{ {
struct _IO_marker *_next; struct _IO_marker *_next;
struct _IO_FILE *_sbuf; struct _IO_FILE *_sbuf;
int _pos; int _pos;
}; };
struct _IO_FILE struct _IO_FILE
{ {
int _flags; int _flags;
char *_IO_read_ptr; char *_IO_read_ptr;
char *_IO_read_end; char *_IO_read_end;
char *_IO_read_base; char *_IO_read_base;
char *_IO_write_base; char *_IO_write_base;
char *_IO_write_ptr; char *_IO_write_ptr;
char *_IO_write_end; char *_IO_write_end;
char *_IO_buf_base; char *_IO_buf_base;
char *_IO_buf_end; char *_IO_buf_end;
__off_t _offset; __off_t _offset;
struct _IO_marker *_markers; struct _IO_marker *_markers;
struct _IO_FILE *_chain; struct _IO_FILE *_chain;
int _fileno; int _fileno;
void *KernelPrivate; void *KernelPrivate;
}; };
typedef struct _IO_FILE FILE; typedef struct _IO_FILE FILE;
@ -52,32 +52,32 @@ extern "C"
{ {
#endif #endif
extern FILE *stdin; extern FILE *stdin;
extern FILE *stdout; extern FILE *stdout;
extern FILE *stderr; extern FILE *stderr;
#define stdin stdin #define stdin stdin
#define stdout stdout #define stdout stdout
#define stderr stderr #define stderr stderr
FILE *fopen(const char *filename, const char *mode); FILE *fopen(const char *filename, const char *mode);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
off_t fseek(FILE *stream, long offset, int whence); off_t fseek(FILE *stream, long offset, int whence);
long ftell(FILE *stream); long ftell(FILE *stream);
int fclose(FILE *fp); int fclose(FILE *fp);
int fflush(FILE *stream); int fflush(FILE *stream);
int fprintf(FILE *stream, const char *format, ...); int fprintf(FILE *stream, const char *format, ...);
int printf(const char *format, ...); int printf(const char *format, ...);
void setbuf(FILE *stream, char *buf); void setbuf(FILE *stream, char *buf);
int vfprintf(FILE *stream, const char *format, va_list arg); int vfprintf(FILE *stream, const char *format, va_list arg);
int vsscanf(const char *s, const char *format, va_list arg); int vsscanf(const char *s, const char *format, va_list arg);
int sscanf(const char *s, const char *format, ...); int sscanf(const char *s, const char *format, ...);
int fputc(int c, FILE *stream); int fputc(int c, FILE *stream);
int putc(int c, FILE *stream); int putc(int c, FILE *stream);
int fputs(const char *s, FILE *stream); int fputs(const char *s, FILE *stream);
int puts(const char *s); int puts(const char *s);
int putchar(int c); int putchar(int c);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -11,21 +11,21 @@ extern "C"
#define EXIT_FAILURE 1 #define EXIT_FAILURE 1
#define EXIT_SUCCESS 0 #define EXIT_SUCCESS 0
void abort(void); void abort(void);
int atexit(void (*function)(void)); int atexit(void (*function)(void));
void exit(int status); void exit(int status);
int atoi(const char *nptr); int atoi(const char *nptr);
char *getenv(const char *name); char *getenv(const char *name);
void *malloc(size_t Size); void *malloc(size_t Size);
void *realloc(void *Address, size_t Size); void *realloc(void *Address, size_t Size);
void *calloc(size_t Count, size_t Size); void *calloc(size_t Count, size_t Size);
void free(void *Address); void free(void *Address);
int system(const char *command); int system(const char *command);
double atof(const char *nptr); double atof(const char *nptr);
extern void perror(const char *s); extern void perror(const char *s);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -8,20 +8,21 @@ extern "C"
{ {
#endif #endif
size_t strlen(const char *str); size_t strlen(const char *str);
int strcmp(const char *l, const char *r); int strcmp(const char *l, const char *r);
int strncmp(const char *s1, const char *s2, size_t n); int strncmp(const char *s1, const char *s2, size_t n);
int strcasecmp(const char *s1, const char *s2); int strcasecmp(const char *s1, const char *s2);
int strncasecmp(const char *string1, const char *string2, size_t count); int strncasecmp(const char *string1, const char *string2, size_t count);
char *strstr(const char *haystack, const char *needle); char *strstr(const char *haystack, const char *needle);
char *strncpy(char *destination, const char *source, unsigned long num); char *strncpy(char *destination, const char *source, unsigned long num);
char *strdup(const char *s); char *strdup(const char *s);
char *strchr(char const *s, int c); char *strchr(char const *s, int c);
char *strrchr(char const *s, int c); char *strrchr(char const *s, int c);
void *memcpy(void *dest, const void *src, size_t n);
void *memset(void *dest, int c, size_t n);
void *memmove(void *dest, const void *src, size_t n);
void *memcpy(void *dest, const void *src, size_t n);
void *memset(void *dest, int c, size_t n);
void *memmove(void *dest, const void *src, size_t n);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,8 +1,17 @@
#ifndef _SYS_TYPES_H #ifndef _SYS_TYPES_H
#define _SYS_TYPES_H #define _SYS_TYPES_H
#ifndef PUBLIC
#define PUBLIC __attribute__((visibility("default")))
#endif // !PUBLIC
#ifndef PRIVATE
#define PRIVATE __attribute__((visibility("hidden")))
#endif // !PRIVATE
typedef int __pid_t; typedef int __pid_t;
typedef unsigned int __id_t; typedef unsigned int __id_t;
typedef unsigned int __useconds_t;
#ifndef __pid_t_defined #ifndef __pid_t_defined
typedef __pid_t pid_t; typedef __pid_t pid_t;
@ -14,4 +23,9 @@ typedef __id_t id_t;
#define __id_t_defined #define __id_t_defined
#endif #endif
#ifndef __useconds_t_defined
typedef __useconds_t useconds_t;
#define __useconds_t_defined
#endif
#endif #endif

View File

@ -5,14 +5,14 @@
typedef enum typedef enum
{ {
P_ALL, /* Wait for any child. */ P_ALL, /* Wait for any child. */
P_PID, /* Wait for specified process. */ P_PID, /* Wait for specified process. */
P_PGID /* Wait for members of process group. */ P_PGID /* Wait for members of process group. */
} idtype_t; } idtype_t;
typedef struct typedef struct
{ {
int stub; int stub;
} siginfo_t; } siginfo_t;
#include <bits/waitstatus.h> #include <bits/waitstatus.h>

View File

@ -7,10 +7,10 @@
#ifdef __cplusplus #ifdef __cplusplus
#define EXTERNC extern "C" #define EXTERNC extern "C"
#define START_EXTERNC \ #define START_EXTERNC \
EXTERNC \ EXTERNC \
{ {
#define END_EXTERNC \ #define END_EXTERNC \
} }
#else #else
#define EXTERNC #define EXTERNC
#define START_EXTERNC #define START_EXTERNC
@ -195,4 +195,12 @@ typedef __SIZE_TYPE__ size_t;
#define b48(x) (((((x)&0x0000000000ff) << 40) | (((x)&0x00000000ff00) << 24) | (((x)&0x000000ff0000) << 8) | (((x)&0x0000ff000000) >> 8) | (((x)&0x00ff00000000) >> 24) | (((x)&0xff0000000000) >> 40))) #define b48(x) (((((x)&0x0000000000ff) << 40) | (((x)&0x00000000ff00) << 24) | (((x)&0x000000ff0000) << 8) | (((x)&0x0000ff000000) >> 8) | (((x)&0x00ff00000000) >> 24) | (((x)&0xff0000000000) >> 40)))
#define b64(x) __builtin_bswap64(x) #define b64(x) __builtin_bswap64(x)
#ifndef PUBLIC
#define PUBLIC __attribute__((visibility("default")))
#endif // !PUBLIC
#ifndef PRIVATE
#define PRIVATE __attribute__((visibility("hidden")))
#endif // !PRIVATE
#endif // !__FENNIX_LIBC_TYPES_H__ #endif // !__FENNIX_LIBC_TYPES_H__

View File

@ -8,17 +8,20 @@ extern "C"
{ {
#endif #endif
extern char **environ; extern char **environ;
int execl(const char *pathname, const char *arg, ...); int execl(const char *pathname, const char *arg, ...);
int execlp(const char *file, const char *arg, ...); int execlp(const char *file, const char *arg, ...);
int execle(const char *pathname, const char *arg, ...); int execle(const char *pathname, const char *arg, ...);
int execv(const char *pathname, char *const argv[]); int execv(const char *pathname, char *const argv[]);
int execvp(const char *file, char *const argv[]); int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]); int execvpe(const char *file, char *const argv[], char *const envp[]);
int execve(const char *pathname, char *const argv[], char *const envp[]); int execve(const char *pathname, char *const argv[], char *const envp[]);
pid_t fork(void); pid_t fork(void);
unsigned int sleep(unsigned int seconds);
int usleep(useconds_t usec);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,8 +1,8 @@
# Config file # Config file
include ../../../Makefile.conf include ../../../Makefile.conf
CC = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
AS = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
NASM = /usr/bin/nasm NASM = /usr/bin/nasm
C_SOURCES = $(shell find ./ -type f -name '*.c') C_SOURCES = $(shell find ./ -type f -name '*.c')

View File

@ -1,26 +0,0 @@
# https://wiki.osdev.org/Creating_a_C_Library
.section .text
.global _start
_start:
movq $0, %rbp
pushq %rbp
pushq %rbp
movq %rsp, %rbp
pushq %rcx
pushq %rdx
pushq %rsi
pushq %rdi
call __libc_init
popq %rdi
popq %rsi
popq %rdx
popq %rcx
call main
movl %eax, %edi
call _exit
.size _start, . - _start

21
libc/runtime/crt0.c Normal file
View File

@ -0,0 +1,21 @@
// https://wiki.osdev.org/Creating_a_C_Library
#define asm __asm__ __volatile__
__attribute__((naked, used, no_stack_protector, section(".text"))) void _start()
{
asm("movq $0, %rbp\n");
asm("pushq %rbp\n");
asm("pushq %rbp\n");
asm("movq %rsp, %rbp\n");
asm("pushq %rcx\n"
"pushq %rdx\n"
"pushq %rsi\n"
"pushq %rdi\n");
asm("call __libc_init\n");
asm("popq %rdi\n"
"popq %rsi\n"
"popq %rdx\n"
"popq %rcx\n");
asm("call main\n");
asm("movl %eax, %edi\n");
asm("call _exit\n");
}

View File

@ -1,26 +0,0 @@
# https://wiki.osdev.org/Creating_a_C_Library
.section .text
.global _start
_start:
movq $0, %rbp
pushq %rbp
pushq %rbp
movq %rsp, %rbp
pushq %rcx
pushq %rdx
pushq %rsi
pushq %rdi
call __libc_init
popq %rdi
popq %rsi
popq %rdx
popq %rcx
call main
movl %eax, %edi
call _exit
.size _start, . - _start

21
libc/runtime/crt1.c Normal file
View File

@ -0,0 +1,21 @@
// https://wiki.osdev.org/Creating_a_C_Library
#define asm __asm__ __volatile__
__attribute__((naked, used, no_stack_protector, section(".text"))) void _start()
{
asm("movq $0, %rbp\n");
asm("pushq %rbp\n");
asm("pushq %rbp\n");
asm("movq %rsp, %rbp\n");
asm("pushq %rcx\n"
"pushq %rdx\n"
"pushq %rsi\n"
"pushq %rdi\n");
asm("call __libc_init\n");
asm("popq %rdi\n"
"popq %rsi\n"
"popq %rdx\n"
"popq %rcx\n");
asm("call main\n");
asm("movl %eax, %edi\n");
asm("call _exit\n");
}

View File

@ -11,12 +11,12 @@ extern fct __fini_array_start[0], __fini_array_end[0];
void __libc_init_array(void) void __libc_init_array(void)
{ {
for (fct *func = __init_array_start; func != __init_array_end; func++) for (fct *func = __init_array_start; func != __init_array_end; func++)
(*func)(); (*func)();
} }
void __libc_fini_array(void) void __libc_fini_array(void)
{ {
for (fct *func = __fini_array_start; func != __fini_array_end; func++) for (fct *func = __fini_array_start; func != __fini_array_end; func++)
(*func)(); (*func)();
} }

View File

@ -3,33 +3,33 @@
void LockClass::DeadLock(SpinLockData Lock) void LockClass::DeadLock(SpinLockData Lock)
{ {
fprintf(stdout, "Potential deadlock in lock '%s' held by '%s'! %ld locks in queue.", fprintf(stdout, "Potential deadlock in lock '%s' held by '%s'! %ld locks in queue.",
Lock.AttemptingToGet, Lock.CurrentHolder, Lock.Count); Lock.AttemptingToGet, Lock.CurrentHolder, Lock.Count);
} }
int LockClass::Lock(const char *FunctionName) int LockClass::Lock(const char *FunctionName)
{ {
LockData.AttemptingToGet = FunctionName; LockData.AttemptingToGet = FunctionName;
Retry: Retry:
unsigned int i = 0; unsigned int i = 0;
while (__atomic_exchange_n(&IsLocked, true, __ATOMIC_ACQUIRE) && ++i < 0x10000000) while (__atomic_exchange_n(&IsLocked, true, __ATOMIC_ACQUIRE) && ++i < 0x10000000)
; ;
if (i >= 0x10000000) if (i >= 0x10000000)
{ {
DeadLock(LockData); DeadLock(LockData);
goto Retry; goto Retry;
} }
LockData.Count++; LockData.Count++;
LockData.CurrentHolder = FunctionName; LockData.CurrentHolder = FunctionName;
__sync_synchronize(); __sync_synchronize();
return 0; return 0;
} }
int LockClass::Unlock() int LockClass::Unlock()
{ {
__sync_synchronize(); __sync_synchronize();
__atomic_store_n(&IsLocked, false, __ATOMIC_RELEASE); __atomic_store_n(&IsLocked, false, __ATOMIC_RELEASE);
LockData.Count--; LockData.Count--;
IsLocked = false; IsLocked = false;
return 0; return 0;
} }

View File

@ -1,27 +1,25 @@
WORKSPACE := ../../
# Config file # Config file
include ../$(WORKSPACE)Makefile.conf include ../../../Makefile.conf
NAME=c NAME=c
OBJECT_NAME=lib$(NAME).a ifeq ($(USERSPACE_STATIC_LIBS), 1)
OBJECT_NAME := lib$(NAME).a
else
OBJECT_NAME := lib$(NAME).so
endif
OUTPUT_DIR=$(WORKSPACE)out/lib/ OUTPUT_DIR=../../out/lib/
SYSROOT = --sysroot=../../out/
CC = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
AS = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
AR = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ar AR = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
NASM = /usr/bin/nasm
C_SOURCES = $(shell find ./ -type f -name '*.c') C_SOURCES = $(shell find ./ -type f -name '*.c')
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp') CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
S_SOURCES = $(shell find ./ -type f -name '*.S') S_SOURCES = $(shell find ./ -type f -name '*.S')
ASM_SOURCES = $(shell find ./ -type f -name '*.asm') OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${S_SOURCES:.S=.o}
OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${ASM_SOURCES:.asm=.o} ${S_SOURCES:.S=.o}
INCLUDE = ../include
INCLUDE2 = $(WORKSPACE)out/usr/include
ifeq ($(OSARCH), amd64) ifeq ($(OSARCH), amd64)
ASM_ARCH := elf64 ASM_ARCH := elf64
@ -29,19 +27,21 @@ else ifeq ($(OSARCH), i386)
ASM_ARCH := elf32 ASM_ARCH := elf32
endif endif
CFLAGS := -fPIC -I$(INCLUDE) -I$(INCLUDE2) CFLAGS := -fvisibility=hidden -fPIC -I../include -I../../out/usr/include
ifeq ($(DEBUG), 1) ifeq ($(DEBUG), 1)
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm
# LDFLAGS += -ggdb3 -O0
endif endif
build: $(OBJECT_NAME) build: $(OBJECT_NAME)
$(OBJECT_NAME): $(OBJ) $(OBJECT_NAME): $(OBJ)
$(info Linking $@) $(info Linking $@)
# $(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,libc.so $(OBJ) -o $(OUTPUT_DIR)$@ ifeq ($(USERSPACE_STATIC_LIBS), 1)
$(AR) rcs $(OUTPUT_DIR)$@ $(OBJ) $(AR) rcs $(OUTPUT_DIR)$@ $(OBJ)
else
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(OBJECT_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@
endif
%.o: %.c %.o: %.c
$(info Compiling $<) $(info Compiling $<)
@ -55,9 +55,5 @@ $(OBJECT_NAME): $(OBJ)
$(info Compiling $<) $(info Compiling $<)
$(AS) -c $< -o $@ $(AS) -c $< -o $@
%.o: %.asm
$(info Compiling $<)
$(NASM) $< -f $(ASM_ARCH) -o $@
clean: clean:
rm -f $(OBJ) rm -f $(OBJ)

View File

@ -1,3 +1,5 @@
#include <sys/syscalls.h>
#include <sys/types.h> // For PUBLIC
extern void __libc_init_array(void); extern void __libc_init_array(void);
extern void __libc_fini_array(void); extern void __libc_fini_array(void);
@ -5,21 +7,17 @@ extern void __libc_fini_array(void);
extern void __libc_init_std(void); extern void __libc_init_std(void);
extern void __libc_fini_std(void); extern void __libc_fini_std(void);
void __libc_init(void) PUBLIC void __libc_init(void)
{ {
__libc_init_array(); __libc_init_array();
__libc_init_std(); __libc_init_std();
} }
void _exit(int Code) PUBLIC void _exit(int Code)
{ {
__libc_fini_std(); __libc_fini_std();
__libc_fini_array(); __libc_fini_array();
__asm__ __volatile__("syscall" syscall1(_Exit, (long)Code);
: while (1)
: "a"(0), "D"(Code) ;
: "rcx", "r11", "memory");
while (1)
;
} }

View File

@ -4,20 +4,20 @@ static char *error = "Not implemented";
__attribute__((weak)) void *dlopen(const char *filename, int flags) __attribute__((weak)) void *dlopen(const char *filename, int flags)
{ {
return NULL; return NULL;
} }
__attribute__((weak)) void *dlsym(void *handle, const char *symbol) __attribute__((weak)) void *dlsym(void *handle, const char *symbol)
{ {
return NULL; return NULL;
} }
__attribute__((weak)) int dlclose(void *handle) __attribute__((weak)) int dlclose(void *handle)
{ {
return -1; return -1;
} }
__attribute__((weak)) char *dlerror(void) __attribute__((weak)) char *dlerror(void)
{ {
return error; return error;
} }

View File

@ -7,38 +7,38 @@
/** @brief Please use this macro to create a new lock. */ /** @brief Please use this macro to create a new lock. */
class LockClass class LockClass
{ {
struct SpinLockData struct SpinLockData
{ {
uint64_t LockData = 0x0; uint64_t LockData = 0x0;
const char *CurrentHolder = "(nul)"; const char *CurrentHolder = "(nul)";
const char *AttemptingToGet = "(nul)"; const char *AttemptingToGet = "(nul)";
uint64_t Count = 0; uint64_t Count = 0;
}; };
void DeadLock(SpinLockData Lock); void DeadLock(SpinLockData Lock);
private: private:
SpinLockData LockData; SpinLockData LockData;
bool IsLocked = false; bool IsLocked = false;
public: public:
SpinLockData *GetLockData() { return &LockData; } SpinLockData *GetLockData() { return &LockData; }
int Lock(const char *FunctionName); int Lock(const char *FunctionName);
int Unlock(); int Unlock();
}; };
/** @brief Please use this macro to create a new smart lock. */ /** @brief Please use this macro to create a new smart lock. */
class SmartLockClass class SmartLockClass
{ {
private: private:
LockClass *LockPointer = nullptr; LockClass *LockPointer = nullptr;
public: public:
SmartLockClass(LockClass &Lock, const char *FunctionName) SmartLockClass(LockClass &Lock, const char *FunctionName)
{ {
this->LockPointer = &Lock; this->LockPointer = &Lock;
this->LockPointer->Lock(FunctionName); this->LockPointer->Lock(FunctionName);
} }
~SmartLockClass() { this->LockPointer->Unlock(); } ~SmartLockClass() { this->LockPointer->Unlock(); }
}; };
/** @brief Create a new lock (can be used with SmartCriticalSection). */ /** @brief Create a new lock (can be used with SmartCriticalSection). */

5
libc/src/main.c Normal file
View File

@ -0,0 +1,5 @@
/* TODO: Show a message or something */
int _start()
{
return -1;
}

View File

@ -7,20 +7,20 @@ NewLock(liballocLock);
extern "C" int liballoc_lock() extern "C" int liballoc_lock()
{ {
return liballocLock.Lock(__FUNCTION__); return liballocLock.Lock(__FUNCTION__);
} }
extern "C" int liballoc_unlock() extern "C" int liballoc_unlock()
{ {
return liballocLock.Unlock(); return liballocLock.Unlock();
} }
extern "C" void *liballoc_alloc(size_t Pages) extern "C" void *liballoc_alloc(size_t Pages)
{ {
return (void *)syscall1(_RequestPages, Pages); return (void *)syscall1(_RequestPages, Pages);
} }
extern "C" int liballoc_free(void *Address, size_t Pages) extern "C" int liballoc_free(void *Address, size_t Pages)
{ {
return syscall2(_FreePages, (uint64_t)Address, Pages); return syscall2(_FreePages, (uint64_t)Address, Pages);
} }

View File

@ -73,7 +73,7 @@ extern "C"
// e.g. make them static so as not to clash with other objects also // e.g. make them static so as not to clash with other objects also
// using them. // using them.
#ifndef PRINTF_VISIBILITY #ifndef PRINTF_VISIBILITY
#define PRINTF_VISIBILITY #define PRINTF_VISIBILITY __attribute__((visibility("default")))
#endif #endif
/** /**

View File

@ -1,6 +1,8 @@
#include <ctype.h> #include <ctype.h>
int tolower(int c) #include <sys/types.h> // For PUBLIC
PUBLIC int tolower(int c)
{ {
if (c >= 'A' && c <= 'Z') if (c >= 'A' && c <= 'Z')
{ {
@ -11,7 +13,7 @@ int tolower(int c)
return c; return c;
} }
int toupper(int c) PUBLIC int toupper(int c)
{ {
if (c >= 'a' && c <= 'z') if (c >= 'a' && c <= 'z')
{ {
@ -21,7 +23,7 @@ int toupper(int c)
return c; return c;
} }
int isspace(int c) PUBLIC int isspace(int c)
{ {
return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f' || c == '\v'; return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f' || c == '\v';
} }

View File

@ -1,8 +1,10 @@
#include <errno.h> #include <errno.h>
#include <sys/types.h> // For PUBLIC
int __local_stub_errno = 0; int __local_stub_errno = 0;
int *__errno_location(void) PUBLIC int *__errno_location(void)
{ {
return &__local_stub_errno; return &__local_stub_errno;
} }

View File

@ -4,121 +4,125 @@
#include <sys/syscalls.h> #include <sys/syscalls.h>
#include <errno.h> #include <errno.h>
FILE *stdin = NULL; #include <sys/types.h> // For PUBLIC
FILE *stdout = NULL;
FILE *stderr = NULL;
FILE *fopen(const char *filename, const char *mode) PUBLIC FILE *stdin = NULL;
PUBLIC FILE *stdout = NULL;
PUBLIC FILE *stderr = NULL;
PUBLIC FILE *fopen(const char *filename, const char *mode)
{ {
void *KPrivate = (void *)syscall2(_FileOpen, (uint64_t)filename, (uint64_t)mode); void *KPrivate = (void *)syscall2(_FileOpen, (uint64_t)filename, (uint64_t)mode);
if (IsSyscallError(KPrivate)) if (IsSyscallError(KPrivate))
return NULL; return NULL;
FILE *FilePtr = malloc(sizeof(FILE)); FILE *FilePtr = malloc(sizeof(FILE));
FilePtr->KernelPrivate = KPrivate; FilePtr->KernelPrivate = KPrivate;
return FilePtr; return FilePtr;
} }
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) PUBLIC size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
{ {
if (ptr == NULL || stream == NULL || size == 0 || nmemb == 0) if (ptr == NULL || stream == NULL || size == 0 || nmemb == 0)
{ {
errno = EINVAL; errno = EINVAL;
return 0; return 0;
} }
return syscall4(_FileRead, (uint64_t)stream->KernelPrivate, stream->_offset, (uint64_t)ptr, size * nmemb); syscall3(_FileSeek, stream->KernelPrivate, stream->_offset, SEEK_SET);
return syscall3(_FileRead, (uint64_t)stream->KernelPrivate, (uint64_t)ptr, size * nmemb);
} }
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) PUBLIC size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{ {
if (ptr == NULL || stream == NULL || size == 0 || nmemb == 0) if (ptr == NULL || stream == NULL || size == 0 || nmemb == 0)
{ {
errno = EINVAL; errno = EINVAL;
return 0; return 0;
} }
return syscall4(_FileWrite, (uint64_t)stream->KernelPrivate, stream->_offset, (uint64_t)ptr, size * nmemb); syscall3(_FileSeek, stream->KernelPrivate, stream->_offset, SEEK_SET);
return syscall3(_FileWrite, (uint64_t)stream->KernelPrivate, (uint64_t)ptr, size * nmemb);
} }
int fclose(FILE *fp) PUBLIC int fclose(FILE *fp)
{ {
if (fp == NULL) if (fp == NULL)
{ {
errno = EINVAL; errno = EINVAL;
return EOF; return EOF;
} }
void *KP = fp->KernelPrivate; void *KP = fp->KernelPrivate;
free(fp); free(fp);
return syscall1(_FileClose, (uint64_t)KP); return syscall1(_FileClose, (uint64_t)KP);
} }
off_t fseek(FILE *stream, long offset, int whence) PUBLIC off_t fseek(FILE *stream, off_t offset, int whence)
{ {
if (stream == NULL || whence < 0 || whence > 2) if (stream == NULL || whence < 0 || whence > 2)
{ {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
off_t new_offset = syscall3(_FileSeek, stream->KernelPrivate, offset, whence); off_t new_offset = syscall3(_FileSeek, stream->KernelPrivate, offset, whence);
if (IsSyscallError(new_offset)) if (IsSyscallError(new_offset))
return -1; return -1;
stream->_offset = new_offset; stream->_offset = new_offset;
return new_offset; return new_offset;
} }
long ftell(FILE *stream) PUBLIC long ftell(FILE *stream)
{ {
return stream->_offset; return stream->_offset;
} }
int fflush(FILE *stream) PUBLIC int fflush(FILE *stream)
{ {
if (stream == NULL) if (stream == NULL)
{ {
errno = EINVAL; errno = EINVAL;
return EOF; return EOF;
} }
errno = ENOSYS; errno = ENOSYS;
return EOF; return EOF;
} }
int fprintf(FILE *stream, const char *format, ...) PUBLIC int fprintf(FILE *stream, const char *format, ...)
{ {
if (stream == NULL || format == NULL) if (stream == NULL || format == NULL)
{ {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
va_list args; va_list args;
va_start(args, format); va_start(args, format);
const int ret = vfprintf(stream, format, args); const int ret = vfprintf(stream, format, args);
va_end(args); va_end(args);
return ret; return ret;
} }
void setbuf(FILE *stream, char *buf) PUBLIC void setbuf(FILE *stream, char *buf)
{ {
} }
int vfprintf(FILE *stream, const char *format, va_list arg) PUBLIC int vfprintf(FILE *stream, const char *format, va_list arg)
{ {
return 0; return 0;
} }
int vsscanf(const char *s, const char *format, va_list arg) PUBLIC int vsscanf(const char *s, const char *format, va_list arg)
{ {
} }
int sscanf(const char *s, const char *format, ...) PUBLIC int sscanf(const char *s, const char *format, ...)
{ {
va_list args; va_list args;
va_start(args, format); va_start(args, format);
const int ret = vsscanf(s, format, args); const int ret = vsscanf(s, format, args);
va_end(args); va_end(args);
return ret; return ret;
} }

View File

@ -2,31 +2,33 @@
#include <stdarg.h> #include <stdarg.h>
#include <sys/syscalls.h> #include <sys/syscalls.h>
int fputc(int c, FILE *stream) #include <sys/types.h> // For PUBLIC
{
// FIXME
// if (stream == NULL)
// {
// errno = EBADF;
// return EOF;
// }
return syscall2(_Print, c, 0); PUBLIC int fputc(int c, FILE *stream)
{
// FIXME
// if (stream == NULL)
// {
// errno = EBADF;
// return EOF;
// }
return syscall2(_Print, c, 0);
} }
int putc(int c, FILE *stream) { return fputc(c, stream); } PUBLIC int putc(int c, FILE *stream) { return fputc(c, stream); }
int fputs(const char *s, FILE *stream) PUBLIC int fputs(const char *s, FILE *stream)
{ {
for (int i = 0; s[i] != '\0'; i++) for (int i = 0; s[i] != '\0'; i++)
fputc(s[i], stream); fputc(s[i], stream);
} }
int puts(const char *s) PUBLIC int puts(const char *s)
{ {
for (int i = 0; s[i] != '\0'; i++) for (int i = 0; s[i] != '\0'; i++)
fputc(s[i], stdout); fputc(s[i], stdout);
} }
int putchar(int c) { return fputc(c, stdout); } PUBLIC int putchar(int c) { return fputc(c, stdout); }
void perror(const char *s) { fputs(s, stderr); } PUBLIC void perror(const char *s) { fputs(s, stderr); }

View File

@ -2,88 +2,86 @@
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
#include <sys/syscalls.h>
#include "../mem/liballoc_1_1.h" #include "../mem/liballoc_1_1.h"
void abort(void) PUBLIC void abort(void)
{ {
__asm__ __volatile__("syscall" syscall1(_Exit, -0xAB057);
: while (1)
: "a"(0), "D"(-0xAB057) ;
: "rcx", "r11", "memory");
while (1)
;
} }
int atexit(void (*function)(void)) PUBLIC int atexit(void (*function)(void))
{ {
return 1; return 1;
} }
void exit(int status) PUBLIC void exit(int status)
{ {
_exit(status); _exit(status);
} }
int atoi(const char *nptr) PUBLIC int atoi(const char *nptr)
{ {
uint64_t Length = strlen((char *)nptr); uint64_t Length = strlen((char *)nptr);
if (nptr) if (nptr)
while (nptr[Length] != '\0') while (nptr[Length] != '\0')
++Length; ++Length;
uint64_t OutBuffer = 0; uint64_t OutBuffer = 0;
uint64_t Power = 1; uint64_t Power = 1;
for (uint64_t i = Length; i > 0; --i) for (uint64_t i = Length; i > 0; --i)
{ {
OutBuffer += (nptr[i - 1] - 48) * Power; OutBuffer += (nptr[i - 1] - 48) * Power;
Power *= 10; Power *= 10;
} }
return OutBuffer; return OutBuffer;
} }
char **environ = NULL; PUBLIC char **environ = NULL;
char *getenv(const char *name) PUBLIC char *getenv(const char *name)
{ {
char **env = environ; char **env = environ;
if (env == NULL) if (env == NULL)
return NULL; return NULL;
size_t len = strlen(name); size_t len = strlen(name);
while (*env != NULL) while (*env != NULL)
{ {
if ((strncmp(*env, name, len) == 0) && ((*env)[len] == '=')) if ((strncmp(*env, name, len) == 0) && ((*env)[len] == '='))
return &(*env)[len + 1]; return &(*env)[len + 1];
++env; ++env;
} }
} }
void *malloc(size_t Size) { return PREFIX(malloc)(Size); } PUBLIC void *malloc(size_t Size) { return PREFIX(malloc)(Size); }
void *realloc(void *Address, size_t Size) { return PREFIX(realloc)(Address, Size); } PUBLIC void *realloc(void *Address, size_t Size) { return PREFIX(realloc)(Address, Size); }
void *calloc(size_t Count, size_t Size) { return PREFIX(calloc)(Count, Size); } PUBLIC void *calloc(size_t Count, size_t Size) { return PREFIX(calloc)(Count, Size); }
void free(void *Address) PUBLIC void free(void *Address)
{ {
PREFIX(free) PREFIX(free)
(Address); (Address);
} }
int system(const char *command) PUBLIC int system(const char *command)
{ {
return -1; return -1;
} }
double atof(const char *nptr) PUBLIC double atof(const char *nptr)
{ {
// FIXME: This is a very bad implementation of atof. // FIXME: This is a very bad implementation of atof.
uint64_t Length = strlen((char *)nptr); uint64_t Length = strlen((char *)nptr);
if (nptr) if (nptr)
while (nptr[Length] != '\0') while (nptr[Length] != '\0')
++Length; ++Length;
double OutBuffer = 0; double OutBuffer = 0;
double Power = 1; double Power = 1;
for (uint64_t i = Length; i > 0; --i) for (uint64_t i = Length; i > 0; --i)
{ {
OutBuffer += (nptr[i - 1] - 48) * Power; OutBuffer += (nptr[i - 1] - 48) * Power;
Power *= 10; Power *= 10;
} }
return OutBuffer; return OutBuffer;
} }

View File

@ -1,17 +1,17 @@
#include <spawn.h> #include <spawn.h>
int posix_spawn(pid_t *pid, const char *path, int posix_spawn(pid_t *pid, const char *path,
const posix_spawn_file_actions_t *file_actions, const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp, const posix_spawnattr_t *attrp,
char *const argv[], char *const argv[],
char *const envp[]) char *const envp[])
{ {
} }
int posix_spawnp(pid_t *pid, const char *file, int posix_spawnp(pid_t *pid, const char *file,
const posix_spawn_file_actions_t *file_actions, const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp, const posix_spawnattr_t *attrp,
char *const argv[], char *const argv[],
char *const envp[]) char *const envp[])
{ {
} }

View File

@ -4,8 +4,8 @@
void __libc_init_std(void) void __libc_init_std(void)
{ {
/* FIXME: Temporal workaround */ /* FIXME: Temporal workaround */
// int IsCritical = syscall1(_KernelCTL, 6 /* KCTL_IS_CRITICAL */); // int IsCritical = syscall1(_KernelCTL, 6 /* KCTL_IS_CRITICAL */);
} }
void __libc_fini_std(void) void __libc_fini_std(void)

View File

@ -1,5 +1,7 @@
#include <stddef.h> #include <stddef.h>
#include <sys/types.h> // For PUBLIC
/* Some of the functions are from musl library */ /* Some of the functions are from musl library */
/* https://www.musl-libc.org/ */ /* https://www.musl-libc.org/ */
/* /*
@ -25,10 +27,10 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
void *memcpy(void *dest, const void *src, size_t n) PUBLIC void *memcpy(void *dest, const void *src, size_t n)
{ {
unsigned char *d = dest; unsigned char *d = dest;
const unsigned char *s = src; const unsigned char *s = src;
#ifdef __GNUC__ #ifdef __GNUC__
@ -40,305 +42,305 @@ void *memcpy(void *dest, const void *src, size_t n)
#define RS >> #define RS >>
#endif #endif
typedef uint32_t __attribute__((__may_alias__)) u32; typedef uint32_t __attribute__((__may_alias__)) u32;
uint32_t w, x; uint32_t w, x;
for (; (uintptr_t)s % 4 && n; n--) for (; (uintptr_t)s % 4 && n; n--)
*d++ = *s++; *d++ = *s++;
if ((uintptr_t)d % 4 == 0) if ((uintptr_t)d % 4 == 0)
{ {
for (; n >= 16; s += 16, d += 16, n -= 16) for (; n >= 16; s += 16, d += 16, n -= 16)
{ {
*(u32 *)(d + 0) = *(u32 *)(s + 0); *(u32 *)(d + 0) = *(u32 *)(s + 0);
*(u32 *)(d + 4) = *(u32 *)(s + 4); *(u32 *)(d + 4) = *(u32 *)(s + 4);
*(u32 *)(d + 8) = *(u32 *)(s + 8); *(u32 *)(d + 8) = *(u32 *)(s + 8);
*(u32 *)(d + 12) = *(u32 *)(s + 12); *(u32 *)(d + 12) = *(u32 *)(s + 12);
} }
if (n & 8) if (n & 8)
{ {
*(u32 *)(d + 0) = *(u32 *)(s + 0); *(u32 *)(d + 0) = *(u32 *)(s + 0);
*(u32 *)(d + 4) = *(u32 *)(s + 4); *(u32 *)(d + 4) = *(u32 *)(s + 4);
d += 8; d += 8;
s += 8; s += 8;
} }
if (n & 4) if (n & 4)
{ {
*(u32 *)(d + 0) = *(u32 *)(s + 0); *(u32 *)(d + 0) = *(u32 *)(s + 0);
d += 4; d += 4;
s += 4; s += 4;
} }
if (n & 2) if (n & 2)
{ {
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
} }
if (n & 1) if (n & 1)
{ {
*d = *s; *d = *s;
} }
return dest; return dest;
} }
if (n >= 32) if (n >= 32)
{ {
switch ((uintptr_t)d % 4) switch ((uintptr_t)d % 4)
{ {
case 1: case 1:
{ {
w = *(u32 *)s; w = *(u32 *)s;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
n -= 3; n -= 3;
for (; n >= 17; s += 16, d += 16, n -= 16) for (; n >= 17; s += 16, d += 16, n -= 16)
{ {
x = *(u32 *)(s + 1); x = *(u32 *)(s + 1);
*(u32 *)(d + 0) = (w LS 24) | (x RS 8); *(u32 *)(d + 0) = (w LS 24) | (x RS 8);
w = *(u32 *)(s + 5); w = *(u32 *)(s + 5);
*(u32 *)(d + 4) = (x LS 24) | (w RS 8); *(u32 *)(d + 4) = (x LS 24) | (w RS 8);
x = *(u32 *)(s + 9); x = *(u32 *)(s + 9);
*(u32 *)(d + 8) = (w LS 24) | (x RS 8); *(u32 *)(d + 8) = (w LS 24) | (x RS 8);
w = *(u32 *)(s + 13); w = *(u32 *)(s + 13);
*(u32 *)(d + 12) = (x LS 24) | (w RS 8); *(u32 *)(d + 12) = (x LS 24) | (w RS 8);
} }
break; break;
} }
case 2: case 2:
{ {
w = *(u32 *)s; w = *(u32 *)s;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
n -= 2; n -= 2;
for (; n >= 18; s += 16, d += 16, n -= 16) for (; n >= 18; s += 16, d += 16, n -= 16)
{ {
x = *(u32 *)(s + 2); x = *(u32 *)(s + 2);
*(u32 *)(d + 0) = (w LS 16) | (x RS 16); *(u32 *)(d + 0) = (w LS 16) | (x RS 16);
w = *(u32 *)(s + 6); w = *(u32 *)(s + 6);
*(u32 *)(d + 4) = (x LS 16) | (w RS 16); *(u32 *)(d + 4) = (x LS 16) | (w RS 16);
x = *(u32 *)(s + 10); x = *(u32 *)(s + 10);
*(u32 *)(d + 8) = (w LS 16) | (x RS 16); *(u32 *)(d + 8) = (w LS 16) | (x RS 16);
w = *(u32 *)(s + 14); w = *(u32 *)(s + 14);
*(u32 *)(d + 12) = (x LS 16) | (w RS 16); *(u32 *)(d + 12) = (x LS 16) | (w RS 16);
} }
break; break;
} }
case 3: case 3:
{ {
w = *(u32 *)s; w = *(u32 *)s;
*d++ = *s++; *d++ = *s++;
n -= 1; n -= 1;
for (; n >= 19; s += 16, d += 16, n -= 16) for (; n >= 19; s += 16, d += 16, n -= 16)
{ {
x = *(u32 *)(s + 3); x = *(u32 *)(s + 3);
*(u32 *)(d + 0) = (w LS 8) | (x RS 24); *(u32 *)(d + 0) = (w LS 8) | (x RS 24);
w = *(u32 *)(s + 7); w = *(u32 *)(s + 7);
*(u32 *)(d + 4) = (x LS 8) | (w RS 24); *(u32 *)(d + 4) = (x LS 8) | (w RS 24);
x = *(u32 *)(s + 11); x = *(u32 *)(s + 11);
*(u32 *)(d + 8) = (w LS 8) | (x RS 24); *(u32 *)(d + 8) = (w LS 8) | (x RS 24);
w = *(u32 *)(s + 15); w = *(u32 *)(s + 15);
*(u32 *)(d + 12) = (x LS 8) | (w RS 24); *(u32 *)(d + 12) = (x LS 8) | (w RS 24);
} }
break; break;
} }
default: default:
break; break;
} }
} }
if (n & 16) if (n & 16)
{ {
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
} }
if (n & 8) if (n & 8)
{ {
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
} }
if (n & 4) if (n & 4)
{ {
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
} }
if (n & 2) if (n & 2)
{ {
*d++ = *s++; *d++ = *s++;
*d++ = *s++; *d++ = *s++;
} }
if (n & 1) if (n & 1)
{ {
*d = *s; *d = *s;
} }
return dest; return dest;
#endif #endif
for (; n; n--) for (; n; n--)
*d++ = *s++; *d++ = *s++;
return dest; return dest;
} }
void *memset(void *dest, int c, size_t n) PUBLIC void *memset(void *dest, int c, size_t n)
{ {
unsigned char *s = dest; unsigned char *s = dest;
size_t k; size_t k;
if (!n) if (!n)
return dest; return dest;
s[0] = c; s[0] = c;
s[n - 1] = c; s[n - 1] = c;
if (n <= 2) if (n <= 2)
return dest; return dest;
s[1] = c; s[1] = c;
s[2] = c; s[2] = c;
s[n - 2] = c; s[n - 2] = c;
s[n - 3] = c; s[n - 3] = c;
if (n <= 6) if (n <= 6)
return dest; return dest;
s[3] = c; s[3] = c;
s[n - 4] = c; s[n - 4] = c;
if (n <= 8) if (n <= 8)
return dest; return dest;
k = -(uintptr_t)s & 3; k = -(uintptr_t)s & 3;
s += k; s += k;
n -= k; n -= k;
n &= -4; n &= -4;
#ifdef __GNUC__ #ifdef __GNUC__
typedef uint32_t __attribute__((__may_alias__)) u32; typedef uint32_t __attribute__((__may_alias__)) u32;
typedef uint64_t __attribute__((__may_alias__)) u64; typedef uint64_t __attribute__((__may_alias__)) u64;
u32 c32 = ((u32)-1) / 255 * (unsigned char)c; u32 c32 = ((u32)-1) / 255 * (unsigned char)c;
*(u32 *)(s + 0) = c32; *(u32 *)(s + 0) = c32;
*(u32 *)(s + n - 4) = c32; *(u32 *)(s + n - 4) = c32;
if (n <= 8) if (n <= 8)
return dest; return dest;
*(u32 *)(s + 4) = c32; *(u32 *)(s + 4) = c32;
*(u32 *)(s + 8) = c32; *(u32 *)(s + 8) = c32;
*(u32 *)(s + n - 12) = c32; *(u32 *)(s + n - 12) = c32;
*(u32 *)(s + n - 8) = c32; *(u32 *)(s + n - 8) = c32;
if (n <= 24) if (n <= 24)
return dest; return dest;
*(u32 *)(s + 12) = c32; *(u32 *)(s + 12) = c32;
*(u32 *)(s + 16) = c32; *(u32 *)(s + 16) = c32;
*(u32 *)(s + 20) = c32; *(u32 *)(s + 20) = c32;
*(u32 *)(s + 24) = c32; *(u32 *)(s + 24) = c32;
*(u32 *)(s + n - 28) = c32; *(u32 *)(s + n - 28) = c32;
*(u32 *)(s + n - 24) = c32; *(u32 *)(s + n - 24) = c32;
*(u32 *)(s + n - 20) = c32; *(u32 *)(s + n - 20) = c32;
*(u32 *)(s + n - 16) = c32; *(u32 *)(s + n - 16) = c32;
k = 24 + ((uintptr_t)s & 4); k = 24 + ((uintptr_t)s & 4);
s += k; s += k;
n -= k; n -= k;
u64 c64 = c32 | ((u64)c32 << 32); u64 c64 = c32 | ((u64)c32 << 32);
for (; n >= 32; n -= 32, s += 32) for (; n >= 32; n -= 32, s += 32)
{ {
*(u64 *)(s + 0) = c64; *(u64 *)(s + 0) = c64;
*(u64 *)(s + 8) = c64; *(u64 *)(s + 8) = c64;
*(u64 *)(s + 16) = c64; *(u64 *)(s + 16) = c64;
*(u64 *)(s + 24) = c64; *(u64 *)(s + 24) = c64;
} }
#else #else
for (; n; n--, s++) for (; n; n--, s++)
*s = c; *s = c;
#endif #endif
return dest; return dest;
} }
void *memmove(void *dest, const void *src, size_t n) PUBLIC void *memmove(void *dest, const void *src, size_t n)
{ {
#ifdef __GNUC__ #ifdef __GNUC__
typedef __attribute__((__may_alias__)) size_t WT; typedef __attribute__((__may_alias__)) size_t WT;
#define WS (sizeof(WT)) #define WS (sizeof(WT))
#endif #endif
char *d = dest; char *d = dest;
const char *s = src; const char *s = src;
if (d == s) if (d == s)
return d; return d;
if ((uintptr_t)s - (uintptr_t)d - n <= -2 * n) if ((uintptr_t)s - (uintptr_t)d - n <= -2 * n)
return memcpy(d, s, n); return memcpy(d, s, n);
if (d < s) if (d < s)
{ {
#ifdef __GNUC__ #ifdef __GNUC__
if ((uintptr_t)s % WS == (uintptr_t)d % WS) if ((uintptr_t)s % WS == (uintptr_t)d % WS)
{ {
while ((uintptr_t)d % WS) while ((uintptr_t)d % WS)
{ {
if (!n--) if (!n--)
return dest; return dest;
*d++ = *s++; *d++ = *s++;
} }
for (; n >= WS; n -= WS, d += WS, s += WS) for (; n >= WS; n -= WS, d += WS, s += WS)
*(WT *)d = *(WT *)s; *(WT *)d = *(WT *)s;
} }
#endif #endif
for (; n; n--) for (; n; n--)
*d++ = *s++; *d++ = *s++;
} }
else else
{ {
#ifdef __GNUC__ #ifdef __GNUC__
if ((uintptr_t)s % WS == (uintptr_t)d % WS) if ((uintptr_t)s % WS == (uintptr_t)d % WS)
{ {
while ((uintptr_t)(d + n) % WS) while ((uintptr_t)(d + n) % WS)
{ {
if (!n--) if (!n--)
return dest; return dest;
d[n] = s[n]; d[n] = s[n];
} }
while (n >= WS) while (n >= WS)
n -= WS, *(WT *)(d + n) = *(WT *)(s + n); n -= WS, *(WT *)(d + n) = *(WT *)(s + n);
} }
#endif #endif
while (n) while (n)
n--, d[n] = s[n]; n--, d[n] = s[n];
} }
return dest; return dest;
} }

View File

@ -2,124 +2,124 @@
#include "../../mem/liballoc_1_1.h" #include "../../mem/liballoc_1_1.h"
size_t strlen(const char *str) PUBLIC size_t strlen(const char *str)
{ {
long unsigned i = 0; long unsigned i = 0;
if (str) if (str)
while (str[i] != '\0') while (str[i] != '\0')
++i; ++i;
return i; return i;
} }
int strcmp(const char *l, const char *r) PUBLIC int strcmp(const char *l, const char *r)
{ {
for (; *l == *r && *l; l++, r++) for (; *l == *r && *l; l++, r++)
; ;
return *(unsigned char *)l - *(unsigned char *)r; return *(unsigned char *)l - *(unsigned char *)r;
} }
int strncmp(const char *s1, const char *s2, size_t n) PUBLIC int strncmp(const char *s1, const char *s2, size_t n)
{ {
for (size_t i = 0; i < n; i++) for (size_t i = 0; i < n; i++)
{ {
char c1 = s1[i], c2 = s2[i]; char c1 = s1[i], c2 = s2[i];
if (c1 != c2) if (c1 != c2)
return c1 - c2; return c1 - c2;
if (!c1) if (!c1)
return 0; return 0;
} }
return 0; return 0;
} }
int strcasecmp(const char *s1, const char *s2) PUBLIC int strcasecmp(const char *s1, const char *s2)
{ {
const unsigned char *p1 = (const unsigned char *)s1; const unsigned char *p1 = (const unsigned char *)s1;
const unsigned char *p2 = (const unsigned char *)s2; const unsigned char *p2 = (const unsigned char *)s2;
int result; int result;
if (p1 == p2) if (p1 == p2)
return 0; return 0;
while ((result = tolower(*p1) - tolower(*p2++)) == 0) while ((result = tolower(*p1) - tolower(*p2++)) == 0)
if (*p1++ == '\0') if (*p1++ == '\0')
break; break;
return result; return result;
} }
int strncasecmp(const char *string1, const char *string2, size_t count) PUBLIC int strncasecmp(const char *string1, const char *string2, size_t count)
{ {
if (count) if (count)
{ {
const unsigned char *s1 = (const unsigned char *)string1; const unsigned char *s1 = (const unsigned char *)string1;
const unsigned char *s2 = (const unsigned char *)string2; const unsigned char *s2 = (const unsigned char *)string2;
int result; int result;
do do
{ {
if ((result = tolower(*s1) - tolower(*s2++)) != 0 || !*s1++) if ((result = tolower(*s1) - tolower(*s2++)) != 0 || !*s1++)
break; break;
} while (--count); } while (--count);
return result; return result;
} }
return 0; return 0;
} }
char *strstr(const char *haystack, const char *needle) PUBLIC char *strstr(const char *haystack, const char *needle)
{ {
const char *a = haystack, *b = needle; const char *a = haystack, *b = needle;
while (1) while (1)
{ {
if (!*b) if (!*b)
return (char *)haystack; return (char *)haystack;
if (!*a) if (!*a)
return NULL; return NULL;
if (*a++ != *b++) if (*a++ != *b++)
{ {
a = ++haystack; a = ++haystack;
b = needle; b = needle;
} }
} }
} }
char *strncpy(char *destination, const char *source, unsigned long num) PUBLIC char *strncpy(char *destination, const char *source, unsigned long num)
{ {
if (destination == NULL) if (destination == NULL)
return NULL; return NULL;
char *ptr = destination; char *ptr = destination;
while (*source && num--) while (*source && num--)
{ {
*destination = *source; *destination = *source;
destination++; destination++;
source++; source++;
} }
*destination = '\0'; *destination = '\0';
return ptr; return ptr;
} }
char *strdup(const char *s) PUBLIC char *strdup(const char *s)
{ {
char *buf = (char *)__malloc(strlen((char *)s) + 1); char *buf = (char *)__malloc(strlen((char *)s) + 1);
strncpy(buf, s, strlen(s) + 1); strncpy(buf, s, strlen(s) + 1);
return buf; return buf;
} }
char *strchr(char const *s, int c) PUBLIC char *strchr(char const *s, int c)
{ {
size_t len = strlen(s); size_t len = strlen(s);
for (size_t i = 0; i < len; i++) for (size_t i = 0; i < len; i++)
if (s[i] == c) if (s[i] == c)
return (char *)s + i; return (char *)s + i;
return NULL; return NULL;
} }
char *strrchr(char const *s, int c) PUBLIC char *strrchr(char const *s, int c)
{ {
size_t len = strlen(s); size_t len = strlen(s);
size_t pos = len; size_t pos = len;
while (s[pos] != c && pos-- != 0) while (s[pos] != c && pos-- != 0)
; ;
if (pos == len) if (pos == len)
return NULL; return NULL;
return (char *)s + pos; return (char *)s + pos;
} }

View File

@ -1,14 +1,14 @@
#include <sys/wait.h> #include <sys/wait.h>
pid_t wait(int *wstatus) PUBLIC pid_t wait(int *wstatus)
{ {
return waitpid(-1, &wstatus, 0); return waitpid(-1, &wstatus, 0);
} }
pid_t waitpid(pid_t pid, int *wstatus, int options) PUBLIC pid_t waitpid(pid_t pid, int *wstatus, int options)
{ {
} }
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options) PUBLIC int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options)
{ {
} }

View File

@ -1,16 +1,18 @@
#include <sys/stat.h> #include <sys/stat.h>
int mkdir(const char *path, mode_t mode) #include <sys/types.h> // For PUBLIC
PUBLIC int mkdir(const char *path, mode_t mode)
{ {
return 0; return 0;
} }
int remove(const char *pathname) PUBLIC int remove(const char *pathname)
{ {
return 0; return 0;
} }
int rename(const char *oldpath, const char *newpath) PUBLIC int rename(const char *oldpath, const char *newpath)
{ {
return 0; return 0;
} }

View File

@ -3,49 +3,49 @@
#include <errno.h> #include <errno.h>
#include "../../../Kernel/syscalls.h" #include "../../../Kernel/syscalls.h"
int execl(const char *pathname, const char *arg, ...) PUBLIC int execl(const char *pathname, const char *arg, ...)
{ {
errno = ENOSYS; errno = ENOSYS;
return -1; return -1;
} }
int execlp(const char *file, const char *arg, ...) PUBLIC int execlp(const char *file, const char *arg, ...)
{ {
errno = ENOSYS; errno = ENOSYS;
return -1; return -1;
} }
int execle(const char *pathname, const char *arg, ...) PUBLIC int execle(const char *pathname, const char *arg, ...)
{ {
errno = ENOSYS; errno = ENOSYS;
return -1; return -1;
} }
int execv(const char *pathname, char *const argv[]) PUBLIC int execv(const char *pathname, char *const argv[])
{ {
errno = ENOSYS; errno = ENOSYS;
return -1; return -1;
} }
int execvp(const char *file, char *const argv[]) PUBLIC int execvp(const char *file, char *const argv[])
{ {
errno = ENOSYS; errno = ENOSYS;
return -1; return -1;
} }
int execvpe(const char *file, char *const argv[], char *const envp[]) PUBLIC int execvpe(const char *file, char *const argv[], char *const envp[])
{ {
errno = ENOSYS; errno = ENOSYS;
return -1; return -1;
} }
int execve(const char *pathname, char *const argv[], char *const envp[]) PUBLIC int execve(const char *pathname, char *const argv[], char *const envp[])
{ {
errno = ENOSYS; errno = ENOSYS;
return -1; return -1;
} }
pid_t fork(void) PUBLIC pid_t fork(void)
{ {
return syscall0(_Fork); return syscall0(_Fork);
} }

14
libc/src/std/uni/sleep.c Normal file
View File

@ -0,0 +1,14 @@
#include <unistd.h>
#include <stddef.h>
#include <errno.h>
#include "../../../Kernel/syscalls.h"
unsigned int sleep(unsigned int seconds)
{
return syscall1(_Sleep, seconds * 1000000);
}
int usleep(useconds_t usec)
{
return syscall1(_Sleep, usec);
}

View File

@ -4,13 +4,13 @@
#include <stddef.h> #include <stddef.h>
#include <stdarg.h> #include <stdarg.h>
__attribute__((visibility("hidden"))) int printf_libinit(const char *format, ...); int printf_libinit(const char *format, ...);
__attribute__((visibility("hidden"))) int vprintf_libinit(const char *format, va_list arg); int vprintf_libinit(const char *format, va_list arg);
__attribute__((visibility("hidden"))) int sprintf_libinit(char *s, const char *format, ...); int sprintf_libinit(char *s, const char *format, ...);
__attribute__((visibility("hidden"))) int vsprintf_libinit(char *s, const char *format, va_list arg); int vsprintf_libinit(char *s, const char *format, va_list arg);
__attribute__((visibility("hidden"))) int snprintf_libinit(char *s, size_t count, const char *format, ...); int snprintf_libinit(char *s, size_t count, const char *format, ...);
__attribute__((visibility("hidden"))) int vsnprintf_libinit(char *s, size_t count, const char *format, va_list arg); int vsnprintf_libinit(char *s, size_t count, const char *format, va_list arg);
void init_log(const char *fmt, ...); __attribute__((visibility("default"))) void init_log(const char *fmt, ...);
#endif // !__FENNIX_LIBS_INIT_H__ #endif // !__FENNIX_LIBS_INIT_H__

View File

@ -3,49 +3,6 @@
#include <stddef.h> #include <stddef.h>
enum KCtl
{
KCTL_NULL,
KCTL_GET_PID,
KCTL_GET_TID,
KCTL_GET_UID,
KCTL_GET_GID,
/**
* @brief Get the page size
*/
KCTL_GET_PAGE_SIZE,
/**
* @brief Check whether the current thread is critical
*/
KCTL_IS_CRITICAL,
/**
* @brief Register an ELF library
* @fn int RegisterELFLib(char *Identifier, char *Path)
*/
KCTL_REGISTER_ELF_LIB,
/**
* @brief Get an ELF library
* @fn uintptr_t GetELFLib(char *Identifier);
*/
KCTL_GET_ELF_LIB_FILE,
/**
* @brief Get an ELF library
* @fn uintptr_t GetELFLib(char *Identifier);
*/
KCTL_GET_ELF_LIB_MEMORY_IMAGE,
KCTL_GET_FRAMEBUFFER_BUFFER,
KCTL_GET_FRAMEBUFFER_WIDTH,
KCTL_GET_FRAMEBUFFER_HEIGHT,
KCTL_GET_FRAMEBUFFER_SIZE,
};
long DoCtl(uint64_t Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4); long DoCtl(uint64_t Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4);
uintptr_t KrnlRequestPages(size_t Count); uintptr_t KrnlRequestPages(size_t Count);

View File

@ -5,21 +5,21 @@
typedef struct typedef struct
{ {
void *KernelPrivate; void *KernelPrivate;
} File; } File;
enum FileFlags enum FileFlags
{ {
FILE_READ = 1, FILE_READ = 1,
FILE_WRITE = 2, FILE_WRITE = 2,
FILE_APPEND = 4, FILE_APPEND = 4,
FILE_CREATE = 8, FILE_CREATE = 8,
FILE_TRUNCATE = 16, FILE_TRUNCATE = 16,
FILE_EXCLUSIVE = 32, FILE_EXCLUSIVE = 32,
FILE_DIRECTORY = 64, FILE_DIRECTORY = 64,
FILE_SYMLINK = 128, FILE_SYMLINK = 128,
FILE_NONBLOCK = 256, FILE_NONBLOCK = 256,
FILE_CLOEXEC = 512, FILE_CLOEXEC = 512,
}; };
File *FileOpen(const char *Path, uint64_t Flags); File *FileOpen(const char *Path, uint64_t Flags);

View File

@ -7,7 +7,7 @@ OBJECT_NAME=lib$(NAME).a
OUTPUT_DIR=../../out/lib/ OUTPUT_DIR=../../out/lib/
CC = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
CRTBEGIN_PATH = $(shell $(CC) -print-file-name=libgcc.a) CRTBEGIN_PATH = $(shell $(CC) -print-file-name=libgcc.a)

View File

@ -3,23 +3,23 @@ include ../../../Makefile.conf
NAME=init NAME=init
OBJECT_NAME=lib$(NAME).so ifeq ($(USERSPACE_STATIC_LIBS), 1)
SO_NAME=$(OBJECT_NAME) OBJECT_NAME := lib$(NAME).a
else
OBJECT_NAME := lib$(NAME).so
endif
OUTPUT_DIR=../../out/lib/ OUTPUT_DIR=../../out/lib/
SYSROOT = --sysroot=../../out/ SYSROOT = --sysroot=../../out/
CC = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
AS = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
AR = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ar AR = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
OBJDUMP = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump
NASM = /usr/bin/nasm
C_SOURCES = $(shell find ./ -type f -name '*.c') C_SOURCES = $(shell find ./ -type f -name '*.c')
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp') CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
S_SOURCES = $(shell find ./ -type f -name '*.S') S_SOURCES = $(shell find ./ -type f -name '*.S')
ASM_SOURCES = $(shell find ./ -type f -name '*.asm') OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${S_SOURCES:.S=.o}
OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${ASM_SOURCES:.asm=.o} ${S_SOURCES:.S=.o}
ifeq ($(OSARCH), amd64) ifeq ($(OSARCH), amd64)
ASM_ARCH := elf64 ASM_ARCH := elf64
@ -27,16 +27,21 @@ else ifeq ($(OSARCH), i386)
ASM_ARCH := elf32 ASM_ARCH := elf32
endif endif
SIMD_FLAGS := -mno-sse -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4.1 -mno-sse4.2 -mno-sse4 -mno-avx -mno-avx2 -mno-avx512f CFLAGS := -fvisibility=hidden -fPIC -fPIE -I../include -I../../libc/include
CFLAGS := -fPIC -fPIE -I../include -I../../libc/include $(SIMD_FLAGS) ifeq ($(DEBUG), 1)
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm
endif
build: $(OBJECT_NAME) build: $(OBJECT_NAME)
$(OBJECT_NAME): $(OBJ) $(OBJECT_NAME): $(OBJ)
$(info Linking $@) $(info Linking $@)
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(SO_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@ ifeq ($(USERSPACE_STATIC_LIBS), 1)
$(OBJDUMP) -d $(OUTPUT_DIR)$@ > file_dump.map $(AR) rcs $(OUTPUT_DIR)$@ $(OBJ)
else
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(OBJECT_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@
endif
%.o: %.c %.o: %.c
$(info Compiling $<) $(info Compiling $<)
@ -50,9 +55,5 @@ $(OBJECT_NAME): $(OBJ)
$(info Compiling $<) $(info Compiling $<)
$(AS) -c $< -o $@ $(AS) -c $< -o $@
%.o: %.asm
$(info Compiling $<)
$(NASM) $< -f $(ASM_ARCH) -o $@
clean: clean:
rm -f file_dump.map $(OBJ) rm -f $(OBJ)

View File

@ -1,13 +1,22 @@
#include <libinit/init.h> #include <libinit/init.h>
#include <unistd.h>
#include "printf.h" #include "printf.h"
void init_log(const char *fmt, ...) void init_log(const char *fmt, ...)
{ {
printf_libinit("\eCCCCCC[\e0088FFinit\eCCCCCC] \eAAAAAA"); static short log_lock = 0;
va_list args; while (log_lock)
va_start(args, fmt); usleep(1);
vprintf_libinit(fmt, args); __sync_synchronize();
va_end(args); log_lock = 1;
printf_libinit("\eCCCCCC");
printf_libinit("\eCCCCCC[\e0088FFinit\eCCCCCC] \eAAAAAA");
va_list args;
va_start(args, fmt);
vprintf_libinit(fmt, args);
va_end(args);
printf_libinit("\eCCCCCC");
log_lock = 0;
__sync_synchronize();
} }

View File

@ -3,18 +3,23 @@ include ../../../Makefile.conf
NAME=ssp NAME=ssp
OBJECT_NAME=lib$(NAME).a ifeq ($(USERSPACE_STATIC_LIBS), 1)
OBJECT_NAME := lib$(NAME).a
else
OBJECT_NAME := lib$(NAME).so
endif
OUTPUT_DIR=../../out/lib/ OUTPUT_DIR=../../out/lib/
SYSROOT = --sysroot=../../out/
CC = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
AR = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ar AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
OBJDUMP = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump AR = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
NASM = /usr/bin/nasm
C_SOURCES = $(shell find ./ -type f -name '*.c') C_SOURCES = $(shell find ./ -type f -name '*.c')
ASM_SOURCES = $(shell find ./ -type f -name '*.asm') CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
OBJ = ${C_SOURCES:.c=.o} ${ASM_SOURCES:.asm=.o} S_SOURCES = $(shell find ./ -type f -name '*.S')
OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${S_SOURCES:.S=.o}
ifeq ($(OSARCH), amd64) ifeq ($(OSARCH), amd64)
ASM_ARCH := elf64 ASM_ARCH := elf64
@ -22,14 +27,21 @@ else ifeq ($(OSARCH), i386)
ASM_ARCH := elf32 ASM_ARCH := elf32
endif endif
CFLAGS := -fPIC -I../include -I../../libc/include CFLAGS := -fvisibility=hidden -fPIC -I../include -I../../libc/include
ifeq ($(DEBUG), 1)
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm
endif
build: $(OBJECT_NAME) build: $(OBJECT_NAME)
$(OBJECT_NAME): $(OBJ) $(OBJECT_NAME): $(OBJ)
$(info Linking $@) $(info Linking $@)
ifeq ($(USERSPACE_STATIC_LIBS), 1)
$(AR) rcs $(OUTPUT_DIR)$@ $(OBJ) $(AR) rcs $(OUTPUT_DIR)$@ $(OBJ)
$(OBJDUMP) -d $(OUTPUT_DIR)$@ > file_dump.map else
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(OBJECT_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@
endif
%.o: %.c %.o: %.c
$(info Compiling $<) $(info Compiling $<)
@ -39,9 +51,9 @@ $(OBJECT_NAME): $(OBJ)
$(info Compiling $<) $(info Compiling $<)
$(CC) $(CFLAGS) -std=c++20 -c $< -o $@ $(CC) $(CFLAGS) -std=c++20 -c $< -o $@
%.o: %.asm %.o: %.S
$(info Compiling $<) $(info Compiling $<)
$(NASM) $< -f $(ASM_ARCH) -o $@ $(AS) -c $< -o $@
clean: clean:
rm -f file_dump.map $(OBJ) rm -f $(OBJ)

View File

@ -6,30 +6,39 @@
#endif #endif
#endif #endif
__UINTPTR_TYPE__ __stack_chk_guard = 0;
#ifndef PUBLIC
#define PUBLIC __attribute__((visibility("default")))
#endif // !PUBLIC
#ifndef PRIVATE
#define PRIVATE __attribute__((visibility("hidden")))
#endif // !PRIVATE
PUBLIC __UINTPTR_TYPE__ __stack_chk_guard = 0;
static void __attribute__((constructor, no_stack_protector)) __guard_setup(void) static void __attribute__((constructor, no_stack_protector)) __guard_setup(void)
{ {
if (__stack_chk_guard == 0) if (__stack_chk_guard == 0)
__stack_chk_guard = STACK_CHK_GUARD_VALUE; __stack_chk_guard = STACK_CHK_GUARD_VALUE;
} }
__attribute__((weak, noreturn, no_stack_protector)) void __stack_chk_fail(void) PUBLIC __attribute__((weak, noreturn, no_stack_protector)) void __stack_chk_fail(void)
{ {
const char *msg = "Stack smashing detected"; const char *msg = "Stack smashing detected";
__asm__ __volatile__("syscall" __asm__ __volatile__("syscall"
: :
: "a"(0), "D"(0x57AC) : "a"(0), "D"(0x57AC)
: "rcx", "r11", "memory"); : "rcx", "r11", "memory");
__builtin_unreachable(); __builtin_unreachable();
} }
__attribute__((weak, noreturn, no_stack_protector)) void __chk_fail(void) PUBLIC __attribute__((weak, noreturn, no_stack_protector)) void __chk_fail(void)
{ {
const char *msg = "Buffer overflow detected"; const char *msg = "Buffer overflow detected";
__asm__ __volatile__("syscall" __asm__ __volatile__("syscall"
: :
: "a"(0), "D"(0xF700) : "a"(0), "D"(0xF700)
: "rcx", "r11", "memory"); : "rcx", "r11", "memory");
__builtin_unreachable(); __builtin_unreachable();
} }

View File

@ -4,15 +4,15 @@
long DoCtl(uint64_t Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4) long DoCtl(uint64_t Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4)
{ {
return syscall5(_KernelCTL, Command, Arg1, Arg2, Arg3, Arg4); return syscall5(_KernelCTL, Command, Arg1, Arg2, Arg3, Arg4);
} }
uintptr_t KrnlRequestPages(size_t Count) uintptr_t KrnlRequestPages(size_t Count)
{ {
return syscall1(_RequestPages, Count); return syscall1(_RequestPages, Count);
} }
void KrnlFreePages(uintptr_t Address, size_t Count) void KrnlFreePages(uintptr_t Address, size_t Count)
{ {
syscall2(_FreePages, Address, Count); syscall2(_FreePages, Address, Count);
} }

View File

@ -5,41 +5,41 @@
__attribute__((visibility("hidden"))) long __FILE_GetPageSize() __attribute__((visibility("hidden"))) long __FILE_GetPageSize()
{ {
static long PageSize = 0; static long PageSize = 0;
if (PageSize == 0) if (PageSize == 0)
PageSize = DoCtl(KCTL_GET_PAGE_SIZE, 0, 0, 0, 0); PageSize = DoCtl(KCTL_GET_PAGE_SIZE, 0, 0, 0, 0);
return PageSize; return PageSize;
} }
File *FileOpen(const char *Path, uint64_t Flags) File *FileOpen(const char *Path, uint64_t Flags)
{ {
File *FilePtr = (File *)KrnlRequestPages(sizeof(File) / __FILE_GetPageSize() + 1); File *FilePtr = (File *)KrnlRequestPages(sizeof(File) / __FILE_GetPageSize() + 1);
FilePtr->KernelPrivate = (void *)syscall2(_FileOpen, (uint64_t)Path, Flags); FilePtr->KernelPrivate = (void *)syscall2(_FileOpen, (uint64_t)Path, Flags);
return FilePtr; return FilePtr;
} }
void FileClose(File *File) void FileClose(File *File)
{ {
syscall1(_FileClose, (uint64_t)File->KernelPrivate); syscall1(_FileClose, (uint64_t)File->KernelPrivate);
KrnlFreePages((uintptr_t)File, sizeof(File) / __FILE_GetPageSize() + 1); KrnlFreePages((uintptr_t)File, sizeof(File) / __FILE_GetPageSize() + 1);
} }
uint64_t FileRead(File *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size) uint64_t FileRead(File *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size)
{ {
return syscall4(_FileRead, (uint64_t)File->KernelPrivate, Offset, (uint64_t)Buffer, Size); return syscall4(_FileRead, (uint64_t)File->KernelPrivate, Offset, (uint64_t)Buffer, Size);
} }
uint64_t FileWrite(File *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size) uint64_t FileWrite(File *File, uint64_t Offset, uint8_t *Buffer, uint64_t Size)
{ {
return syscall4(_FileWrite, (uint64_t)File->KernelPrivate, Offset, (uint64_t)Buffer, Size); return syscall4(_FileWrite, (uint64_t)File->KernelPrivate, Offset, (uint64_t)Buffer, Size);
} }
uint64_t FileSeek(File *File, uint64_t Offset, uint64_t Whence) uint64_t FileSeek(File *File, uint64_t Offset, uint64_t Whence)
{ {
return syscall3(_FileSeek, (uint64_t)File->KernelPrivate, Offset, Whence); return syscall3(_FileSeek, (uint64_t)File->KernelPrivate, Offset, Whence);
} }
uint64_t FileStatus(File *File) uint64_t FileStatus(File *File)
{ {
return syscall1(_FileStatus, (uint64_t)File->KernelPrivate); return syscall1(_FileStatus, (uint64_t)File->KernelPrivate);
} }

View File

@ -3,23 +3,23 @@ include ../../../Makefile.conf
NAME=sys NAME=sys
OBJECT_NAME=lib$(NAME).so ifeq ($(USERSPACE_STATIC_LIBS), 1)
SO_NAME=$(OBJECT_NAME) OBJECT_NAME := lib$(NAME).a
else
OBJECT_NAME := lib$(NAME).so
endif
OUTPUT_DIR=../../out/lib/ OUTPUT_DIR=../../out/lib/
SYSROOT = --sysroot=../../out/ SYSROOT = --sysroot=../../out/
CC = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
AS = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
AR = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ar AR = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
OBJDUMP = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump
NASM = /usr/bin/nasm
C_SOURCES = $(shell find ./ -type f -name '*.c') C_SOURCES = $(shell find ./ -type f -name '*.c')
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp') CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
S_SOURCES = $(shell find ./ -type f -name '*.S') S_SOURCES = $(shell find ./ -type f -name '*.S')
ASM_SOURCES = $(shell find ./ -type f -name '*.asm') OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${S_SOURCES:.S=.o}
OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${ASM_SOURCES:.asm=.o} ${S_SOURCES:.S=.o}
ifeq ($(OSARCH), amd64) ifeq ($(OSARCH), amd64)
ASM_ARCH := elf64 ASM_ARCH := elf64
@ -27,16 +27,21 @@ else ifeq ($(OSARCH), i386)
ASM_ARCH := elf32 ASM_ARCH := elf32
endif endif
SIMD_FLAGS := -mno-sse -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4.1 -mno-sse4.2 -mno-sse4 -mno-avx -mno-avx2 -mno-avx512f CFLAGS := -fvisibility=hidden -fPIC -I../include -I../../libc/include
CFLAGS := -fPIC -fPIE -I../include -I../../libc/include $(SIMD_FLAGS) ifeq ($(DEBUG), 1)
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm
endif
build: $(OBJECT_NAME) build: $(OBJECT_NAME)
$(OBJECT_NAME): $(OBJ) $(OBJECT_NAME): $(OBJ)
$(info Linking $@) $(info Linking $@)
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(SO_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@ ifeq ($(USERSPACE_STATIC_LIBS), 1)
$(OBJDUMP) -d $(OUTPUT_DIR)$@ > file_dump.map $(AR) rcs $(OUTPUT_DIR)$@ $(OBJ)
else
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(OBJECT_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@
endif
%.o: %.c %.o: %.c
$(info Compiling $<) $(info Compiling $<)
@ -50,9 +55,5 @@ $(OBJECT_NAME): $(OBJ)
$(info Compiling $<) $(info Compiling $<)
$(AS) -c $< -o $@ $(AS) -c $< -o $@
%.o: %.asm
$(info Compiling $<)
$(NASM) $< -f $(ASM_ARCH) -o $@
clean: clean:
rm -f file_dump.map $(OBJ) rm -f $(OBJ)