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

201
.vscode/launch.json vendored
View File

@ -1,83 +1,122 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "/init",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/out/bin/init",
"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/bin/init",
"description": "Load binary."
},
{
"text": "add-symbol-file ${workspaceFolder}/../Kernel/kernel.fsys",
"description": "Load kernel binary."
},
]
},
{
"name": "/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."
},
]
}
]
"version": "0.2.0",
"configurations": [
{
"name": "/bin/init",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/out/bin/init",
"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/bin/init",
"description": "Load binary."
},
{
"text": "add-symbol-file ${workspaceFolder}/../Kernel/kernel.fsys",
"description": "Load kernel binary."
},
]
},
{
"name": "/lib/ld.so",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/out/lib/ld.so",
"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/lib/ld.so",
"description": "Load binary."
},
{
"text": "add-symbol-file ${workspaceFolder}/../Kernel/kernel.fsys",
"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
include ../$(WORKSPACE)Makefile.conf
CC = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc
CPP = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)g++
LD = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ld
AS = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as
OBJDUMP = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump
CC = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
CPP = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)g++
LD = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)ld
AS = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)as
OBJDUMP = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
GIT_COMMIT = $(shell git rev-parse HEAD)
GIT_COMMIT_SHORT = $(shell git rev-parse --short HEAD)

View File

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

View File

@ -3,11 +3,11 @@ WORKSPACE := ../../../
# Config file
include ../$(WORKSPACE)Makefile.conf
CC = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc
CPP = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)g++
LD = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ld
AS = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as
OBJDUMP = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump
CC = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
CPP = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)g++
LD = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)ld
AS = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)as
OBJDUMP = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
GIT_COMMIT = $(shell git rev-parse 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[])
{
print("%p %p %p\n", (void *)(uint64_t)&argc, (void *)&argv, (void *)&envp);
print("I have %d arguments\n", argc);
for (int i = 0; i < argc; i++)
print("argv[%d] = (%p) %s\n", i, argv[i], argv[i]);
print("%p %p %p\n", (void *)(uint64_t)&argc, (void *)&argv, (void *)&envp);
print("I have %d arguments\n", argc);
for (int i = 0; i < argc; i++)
print("argv[%d] = (%p) %s\n", i, argv[i], argv[i]);
int envc = 0;
while (envp[envc] != NULL)
envc++;
int envc = 0;
while (envp[envc] != NULL)
envc++;
print("I have %d environment variables\n", envc);
for (int i = 0; i < envc; i++)
print("envp[%d] = (%p) %s\n", i, envp[i], envp[i]);
print("I have %d environment variables\n", envc);
for (int i = 0; i < envc; i++)
print("envp[%d] = (%p) %s\n", i, envp[i], envp[i]);
Elf64_auxv_t *auxv;
char **e = envp;
Elf64_auxv_t *auxv;
char **e = envp;
while (*e++ != NULL)
;
while (*e++ != NULL)
;
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);
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);
}
int main(int argc, char *argv[], char *envp[])
{
// test_args(argc, argv, envp);
FILE *test = fopen("/Test.txt", "r");
if (test == NULL)
{
print("Failed to open file\n");
return 1;
}
// test_args(argc, argv, envp);
FILE *test = fopen("/Test.txt", "r");
if (test == NULL)
{
print("Failed to open file\n");
return 1;
}
char buf[1024];
int read = fread(buf, 1024, 1, test);
print("/Test.txt (%ld): %s\n", read, buf);
fclose(test);
char buf[1024];
int read = fread(buf, 1024, 1, test);
print("/Test.txt (%ld): %s\n", read, buf);
fclose(test);
pid_t pid;
int status;
pid_t pid;
int status;
pid = fork();
pid = fork();
if (pid == 0) // Child process
{
print("Creating shell process\n");
char *args[] = {"/bin/sh", NULL};
execv(args[0], args);
exit(EXIT_FAILURE);
}
else if (pid > 0)
{
wait(&status);
if (WIFEXITED(status))
{
print("Child process exited with code: %d\n", WEXITSTATUS(status));
return WEXITSTATUS(status);
}
else
{
print("Execution failed.\n");
exit(EXIT_FAILURE);
}
}
else
{
print("\eFF0000Failed to create the process.\n");
exit(EXIT_FAILURE);
}
if (pid == 0) // Child process
{
print("Creating shell process\n");
char *args[] = {"/bin/sh", NULL};
execv(args[0], args);
exit(EXIT_FAILURE);
}
else if (pid > 0)
{
wait(&status);
if (WIFEXITED(status))
{
print("Child process exited with code: %d\n", WEXITSTATUS(status));
return WEXITSTATUS(status);
}
else
{
print("Execution failed.\n");
exit(EXIT_FAILURE);
}
}
else
{
print("\eFF0000Failed to create the process.\n");
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/
SYSROOT = --sysroot=../../out/
CC = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc
AS = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as
AR = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ar
OBJDUMP = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
AR = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
OBJDUMP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
NASM = /usr/bin/nasm
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
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
CFLAGS := -pie -fPIE -I$(INCLUDE) $(SIMD_FLAGS)
LDFLAGS := -nostartfiles -nostdlib -pie -fPIE -Wl,-e_ld_start,-soname,$(SO_NAME) $(SYSROOT)
CFLAGS := -I$(INCLUDE) $(SIMD_FLAGS) -fPIC
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)

View File

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

View File

@ -1,147 +1,14 @@
#include "ld.h"
#include "fcts.h"
#include "../../libs/include/libsys/base.h"
#include "../../../Kernel/syscalls.h"
#include "../../../Kernel/ipc.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 PrintNL(x) PrintNL__(x)
#if (0)
#if (1)
#define PrintDbg(x) Print__(x)
#define PrintDbgNL(x) PrintNL__(x)
#define ltoaDbg(x, y, z) ltoa(x, y, z)
@ -151,397 +18,400 @@ void PrintNL__(char *String)
#define ltoaDbg(x, y, z)
#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
{
char Name[128];
char Name[64];
};
typedef struct
{
char Path[256];
void *ElfFile;
void *MemoryImage;
struct InterpreterIPCDataLibrary Libraries[64];
char Path[256];
void *MemoryImage;
struct InterpreterIPCDataLibrary Libraries[64];
} 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 */
int ld_main()
{
/* Prevent race condition. */
uintptr_t KCTL_ret = KernelCTL(KCTL_IS_CRITICAL, 0, 0, 0, 0);
do
{
syscall1(_Sleep, 250);
KCTL_ret = KernelCTL(KCTL_IS_CRITICAL, 0, 0, 0, 0);
} while (KCTL_ret == SYSCALL_ACCESS_DENIED);
/* Prevent race condition. */
uintptr_t KCTL_ret = KernelCTL(KCTL_IS_CRITICAL, 0, 0, 0, 0);
do
{
syscall1(_Sleep, 250);
KCTL_ret = KernelCTL(KCTL_IS_CRITICAL, 0, 0, 0, 0);
} while (KCTL_ret == SYSCALL_ACCESS_DENIED);
if (KCTL_ret == false)
return -4;
if (KCTL_ret == false)
return -1;
/* Everything is ok, continue. */
return 0;
/* Everything is ok, continue. */
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);
if (!Dyn)
return false;
struct Elf64_Dyn Dyn = ELFGetDynamicTag(ParentPath, DT_PLTGOT);
if (!Dyn.d_tag)
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[2] = (uintptr_t)ELF_LAZY_RESOLVE_STUB;
return true;
GOT[1] = (uintptr_t)Libs;
GOT[2] = (uintptr_t)ELF_LAZY_RESOLVE_STUB;
return true;
}
/* Actual load */
int ld_load(int argc, char *argv[], char *envp[])
{
uintptr_t PageSize = KernelCTL(KCTL_GET_PAGE_SIZE, 0, 0, 0, 0);
int PagesForIPCDataStruct = sizeof(InterpreterIPCData) / PageSize + 1;
InterpreterIPCData *IPCBuffer = (InterpreterIPCData *)RequestPages(PagesForIPCDataStruct);
PrintDbgNL("!");
uintptr_t PageSize = KernelCTL(KCTL_GET_PAGE_SIZE, 0, 0, 0, 0);
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));
while (true)
{
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;
}
InterpreterIPCData *IPCBuffer =
(InterpreterIPCData *)RequestPages(PagesForIPCDataStruct);
struct LibAddressCollection *LibsForLazyResolver = (struct LibAddressCollection *)RequestPages(sizeof(struct LibAddressCollection) / PageSize + 1);
for (size_t i = 0; i < 64; i++)
{
if (IPCBuffer->Libraries[i].Name[0] == '\0')
break;
int IPC_ID = IPC(IPC_CREATE, IPC_TYPE_MessagePassing,
0, 0, "LOAD", sizeof(InterpreterIPCData));
while (true)
{
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);
uintptr_t lib_mm_image = KernelCTL(KCTL_GET_ELF_LIB_MEMORY_IMAGE, (uint64_t)IPCBuffer->Libraries[i].Name, 0, 0, 0);
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 (IPCResult == IPC_E_CODE_Success)
break;
}
if (LibsForLazyResolver->Next == NULL)
{
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];
struct LibsCollection *LibsForLazyResolver =
(struct LibsCollection *)RequestPages(PagesForLibsCollectionStruct);
LibsForLazyResolver->Next = (struct LibAddressCollection *)RequestPages(sizeof(struct LibAddressCollection) / PageSize + 1);
memset(LibsForLazyResolver->Next, 0, sizeof(struct LibAddressCollection));
continue;
}
struct LibAddressCollection *CurrentLibsForLazyResolver = LibsForLazyResolver;
for (short i = 0; i < 64; i++)
{
if (IPCBuffer->Libraries[i].Name[0] == '\0')
break;
while (CurrentLibsForLazyResolver->Next != NULL)
CurrentLibsForLazyResolver = CurrentLibsForLazyResolver->Next;
uintptr_t lib_mm_image =
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;
CurrentLibsForLazyResolver->ElfFile = (uintptr_t)lib_addr;
CurrentLibsForLazyResolver->MemoryImage = (uintptr_t)lib_mm_image;
CurrentLibsForLazyResolver->ParentElfFile = (uintptr_t)IPCBuffer->ElfFile;
CurrentLibsForLazyResolver->ParentMemoryImage = (uintptr_t)IPCBuffer->MemoryImage;
for (size_t j = 0; j < 32; j++)
CurrentLibsForLazyResolver->Name[j] = IPCBuffer->Libraries[i].Name[j];
if (LibsForLazyResolver->Next == NULL)
{
LibsForLazyResolver->Valid = true;
LibsForLazyResolver->LibraryMemoryImage = (uintptr_t)lib_mm_image;
LibsForLazyResolver->ParentMemoryImage = (uintptr_t)IPCBuffer->MemoryImage;
for (short j = 0; j < sizeof(LibsForLazyResolver->LibraryName); j++)
LibsForLazyResolver->LibraryName[j] = IPCBuffer->Libraries[i].Name[j];
CurrentLibsForLazyResolver->Next = (struct LibAddressCollection *)RequestPages(sizeof(struct LibAddressCollection) / PageSize + 1);
memset(CurrentLibsForLazyResolver->Next, 0, sizeof(struct LibAddressCollection));
}
LibsForLazyResolver->Next =
(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))
{
PrintNL("Failed to add lazy resolver to GOT");
return -0x607;
}
CurrentLib->Valid = true;
CurrentLib->LibraryMemoryImage = (uintptr_t)lib_mm_image;
CurrentLib->ParentMemoryImage = (uintptr_t)IPCBuffer->MemoryImage;
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);
FreePages((uintptr_t)IPCBuffer, PagesForIPCDataStruct);
struct LibsCollection *CurrentLib = LibsForLazyResolver;
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"
"pushq %rbp\n"
"pushq %rbp\n"
"movq %rsp, %rbp\n"
__asm__("movq $0, %rbp\n"
"pushq %rbp\n"
"pushq %rbp\n"
"movq %rsp, %rbp\n"
"pushq %rcx\n"
"pushq %rdx\n"
"pushq %rsi\n"
"pushq %rdi\n"
"pushq %rcx\n"
"pushq %rdx\n"
"pushq %rsi\n"
"pushq %rdi\n"
"call ld_main\n"
"movl %eax, %edi\n" // Move return value to edi
"cmp $0, %edi\n" // Check if return value is 0
"jne _exit\n" // If not, jump to _exit
"call ld_main\n"
"movl %eax, %edi\n" // Move return value to edi
"cmp $0, %edi\n" // Check if return value is 0
"jne _exit\n" // If not, jump to _exit
"popq %rdi\n"
"popq %rsi\n"
"popq %rdx\n"
"popq %rcx\n"
"popq %rdi\n"
"popq %rsi\n"
"popq %rdx\n"
"popq %rcx\n"
"call ld_load\n"
"movl %eax, %edi\n" // Move return value to edi
"call _exit"); // Call _exit
"call ld_load\n"
"movl %eax, %edi\n" // Move return value to edi
"call _exit"); // Call _exit
}
void _exit(int Code)
{
__asm__ __volatile__("syscall"
:
: "a"(0), "D"(Code)
: "rcx", "r11", "memory");
while (1)
;
__asm__ __volatile__("syscall"
:
: "a"(0), "D"(Code)
: "rcx", "r11", "memory");
while (1)
;
}

View File

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

View File

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

View File

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

View File

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

View File

@ -11,21 +11,21 @@ extern "C"
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
void abort(void);
int atexit(void (*function)(void));
void exit(int status);
int atoi(const char *nptr);
char *getenv(const char *name);
void abort(void);
int atexit(void (*function)(void));
void exit(int status);
int atoi(const char *nptr);
char *getenv(const char *name);
void *malloc(size_t Size);
void *realloc(void *Address, size_t Size);
void *calloc(size_t Count, size_t Size);
void free(void *Address);
int system(const char *command);
void *malloc(size_t Size);
void *realloc(void *Address, size_t Size);
void *calloc(size_t Count, size_t Size);
void free(void *Address);
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
}

View File

@ -8,20 +8,21 @@ extern "C"
{
#endif
size_t strlen(const char *str);
int strcmp(const char *l, const char *r);
int strncmp(const char *s1, const char *s2, size_t n);
int strcasecmp(const char *s1, const char *s2);
int strncasecmp(const char *string1, const char *string2, size_t count);
char *strstr(const char *haystack, const char *needle);
char *strncpy(char *destination, const char *source, unsigned long num);
char *strdup(const char *s);
char *strchr(char const *s, int c);
char *strrchr(char const *s, int c);
size_t strlen(const char *str);
int strcmp(const char *l, const char *r);
int strncmp(const char *s1, const char *s2, size_t n);
int strcasecmp(const char *s1, const char *s2);
int strncasecmp(const char *string1, const char *string2, size_t count);
char *strstr(const char *haystack, const char *needle);
char *strncpy(char *destination, const char *source, unsigned long num);
char *strdup(const char *s);
char *strchr(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
}
#endif

View File

@ -1,8 +1,17 @@
#ifndef _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 unsigned int __id_t;
typedef unsigned int __useconds_t;
#ifndef __pid_t_defined
typedef __pid_t pid_t;
@ -14,4 +23,9 @@ typedef __id_t id_t;
#define __id_t_defined
#endif
#ifndef __useconds_t_defined
typedef __useconds_t useconds_t;
#define __useconds_t_defined
#endif
#endif

View File

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

View File

@ -7,10 +7,10 @@
#ifdef __cplusplus
#define EXTERNC extern "C"
#define START_EXTERNC \
EXTERNC \
{
EXTERNC \
{
#define END_EXTERNC \
}
}
#else
#define 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 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__

View File

@ -8,17 +8,20 @@ extern "C"
{
#endif
extern char **environ;
extern char **environ;
int execl(const char *pathname, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *pathname, const char *arg, ...);
int execv(const char *pathname, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
int execve(const char *pathname, char *const argv[], char *const envp[]);
int execl(const char *pathname, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *pathname, const char *arg, ...);
int execv(const char *pathname, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, 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
}

View File

@ -1,8 +1,8 @@
# Config file
include ../../../Makefile.conf
CC = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc
AS = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
NASM = /usr/bin/nasm
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)
{
for (fct *func = __init_array_start; func != __init_array_end; func++)
(*func)();
for (fct *func = __init_array_start; func != __init_array_end; func++)
(*func)();
}
void __libc_fini_array(void)
{
for (fct *func = __fini_array_start; func != __fini_array_end; func++)
(*func)();
for (fct *func = __fini_array_start; func != __fini_array_end; func++)
(*func)();
}

View File

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

View File

@ -1,27 +1,25 @@
WORKSPACE := ../../
# Config file
include ../$(WORKSPACE)Makefile.conf
include ../../../Makefile.conf
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
AS = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as
AR = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ar
NASM = /usr/bin/nasm
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
AR = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
C_SOURCES = $(shell find ./ -type f -name '*.c')
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
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} ${ASM_SOURCES:.asm=.o} ${S_SOURCES:.S=.o}
INCLUDE = ../include
INCLUDE2 = $(WORKSPACE)out/usr/include
OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${S_SOURCES:.S=.o}
ifeq ($(OSARCH), amd64)
ASM_ARCH := elf64
@ -29,19 +27,21 @@ else ifeq ($(OSARCH), i386)
ASM_ARCH := elf32
endif
CFLAGS := -fPIC -I$(INCLUDE) -I$(INCLUDE2)
CFLAGS := -fvisibility=hidden -fPIC -I../include -I../../out/usr/include
ifeq ($(DEBUG), 1)
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm
# LDFLAGS += -ggdb3 -O0
endif
build: $(OBJECT_NAME)
$(OBJECT_NAME): $(OBJ)
$(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)
else
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(OBJECT_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@
endif
%.o: %.c
$(info Compiling $<)
@ -55,9 +55,5 @@ $(OBJECT_NAME): $(OBJ)
$(info Compiling $<)
$(AS) -c $< -o $@
%.o: %.asm
$(info Compiling $<)
$(NASM) $< -f $(ASM_ARCH) -o $@
clean:
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_fini_array(void);
@ -5,21 +7,17 @@ extern void __libc_fini_array(void);
extern void __libc_init_std(void);
extern void __libc_fini_std(void);
void __libc_init(void)
PUBLIC void __libc_init(void)
{
__libc_init_array();
__libc_init_std();
__libc_init_array();
__libc_init_std();
}
void _exit(int Code)
PUBLIC void _exit(int Code)
{
__libc_fini_std();
__libc_fini_array();
__asm__ __volatile__("syscall"
:
: "a"(0), "D"(Code)
: "rcx", "r11", "memory");
while (1)
;
__libc_fini_std();
__libc_fini_array();
syscall1(_Exit, (long)Code);
while (1)
;
}

View File

@ -4,20 +4,20 @@ static char *error = "Not implemented";
__attribute__((weak)) void *dlopen(const char *filename, int flags)
{
return NULL;
return NULL;
}
__attribute__((weak)) void *dlsym(void *handle, const char *symbol)
{
return NULL;
return NULL;
}
__attribute__((weak)) int dlclose(void *handle)
{
return -1;
return -1;
}
__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. */
class LockClass
{
struct SpinLockData
{
uint64_t LockData = 0x0;
const char *CurrentHolder = "(nul)";
const char *AttemptingToGet = "(nul)";
uint64_t Count = 0;
};
void DeadLock(SpinLockData Lock);
struct SpinLockData
{
uint64_t LockData = 0x0;
const char *CurrentHolder = "(nul)";
const char *AttemptingToGet = "(nul)";
uint64_t Count = 0;
};
void DeadLock(SpinLockData Lock);
private:
SpinLockData LockData;
bool IsLocked = false;
SpinLockData LockData;
bool IsLocked = false;
public:
SpinLockData *GetLockData() { return &LockData; }
int Lock(const char *FunctionName);
int Unlock();
SpinLockData *GetLockData() { return &LockData; }
int Lock(const char *FunctionName);
int Unlock();
};
/** @brief Please use this macro to create a new smart lock. */
class SmartLockClass
{
private:
LockClass *LockPointer = nullptr;
LockClass *LockPointer = nullptr;
public:
SmartLockClass(LockClass &Lock, const char *FunctionName)
{
this->LockPointer = &Lock;
this->LockPointer->Lock(FunctionName);
}
~SmartLockClass() { this->LockPointer->Unlock(); }
SmartLockClass(LockClass &Lock, const char *FunctionName)
{
this->LockPointer = &Lock;
this->LockPointer->Lock(FunctionName);
}
~SmartLockClass() { this->LockPointer->Unlock(); }
};
/** @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()
{
return liballocLock.Lock(__FUNCTION__);
return liballocLock.Lock(__FUNCTION__);
}
extern "C" int liballoc_unlock()
{
return liballocLock.Unlock();
return liballocLock.Unlock();
}
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)
{
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
// using them.
#ifndef PRINTF_VISIBILITY
#define PRINTF_VISIBILITY
#define PRINTF_VISIBILITY __attribute__((visibility("default")))
#endif
/**

View File

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

View File

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

View File

@ -4,121 +4,125 @@
#include <sys/syscalls.h>
#include <errno.h>
FILE *stdin = NULL;
FILE *stdout = NULL;
FILE *stderr = NULL;
#include <sys/types.h> // For PUBLIC
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);
if (IsSyscallError(KPrivate))
return NULL;
void *KPrivate = (void *)syscall2(_FileOpen, (uint64_t)filename, (uint64_t)mode);
if (IsSyscallError(KPrivate))
return NULL;
FILE *FilePtr = malloc(sizeof(FILE));
FilePtr->KernelPrivate = KPrivate;
return FilePtr;
FILE *FilePtr = malloc(sizeof(FILE));
FilePtr->KernelPrivate = KPrivate;
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)
{
errno = EINVAL;
return 0;
}
if (ptr == NULL || stream == NULL || size == 0 || nmemb == 0)
{
errno = EINVAL;
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)
{
errno = EINVAL;
return 0;
}
if (ptr == NULL || stream == NULL || size == 0 || nmemb == 0)
{
errno = EINVAL;
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)
{
errno = EINVAL;
return EOF;
}
if (fp == NULL)
{
errno = EINVAL;
return EOF;
}
void *KP = fp->KernelPrivate;
free(fp);
return syscall1(_FileClose, (uint64_t)KP);
void *KP = fp->KernelPrivate;
free(fp);
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)
{
errno = EINVAL;
return -1;
}
if (stream == NULL || whence < 0 || whence > 2)
{
errno = EINVAL;
return -1;
}
off_t new_offset = syscall3(_FileSeek, stream->KernelPrivate, offset, whence);
if (IsSyscallError(new_offset))
return -1;
stream->_offset = new_offset;
return new_offset;
off_t new_offset = syscall3(_FileSeek, stream->KernelPrivate, offset, whence);
if (IsSyscallError(new_offset))
return -1;
stream->_offset = 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)
{
errno = EINVAL;
return EOF;
}
if (stream == NULL)
{
errno = EINVAL;
return EOF;
}
errno = ENOSYS;
return EOF;
errno = ENOSYS;
return EOF;
}
int fprintf(FILE *stream, const char *format, ...)
PUBLIC int fprintf(FILE *stream, const char *format, ...)
{
if (stream == NULL || format == NULL)
{
errno = EINVAL;
return -1;
}
if (stream == NULL || format == NULL)
{
errno = EINVAL;
return -1;
}
va_list args;
va_start(args, format);
const int ret = vfprintf(stream, format, args);
va_end(args);
return ret;
va_list args;
va_start(args, format);
const int ret = vfprintf(stream, format, args);
va_end(args);
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_start(args, format);
const int ret = vsscanf(s, format, args);
va_end(args);
return ret;
va_list args;
va_start(args, format);
const int ret = vsscanf(s, format, args);
va_end(args);
return ret;
}

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,7 @@
#include <stddef.h>
#include <sys/types.h> // For PUBLIC
/* Some of the functions are from musl library */
/* 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.
*/
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;
const unsigned char *s = src;
unsigned char *d = dest;
const unsigned char *s = src;
#ifdef __GNUC__
@ -40,305 +42,305 @@ void *memcpy(void *dest, const void *src, size_t n)
#define RS >>
#endif
typedef uint32_t __attribute__((__may_alias__)) u32;
uint32_t w, x;
typedef uint32_t __attribute__((__may_alias__)) u32;
uint32_t w, x;
for (; (uintptr_t)s % 4 && n; n--)
*d++ = *s++;
for (; (uintptr_t)s % 4 && n; n--)
*d++ = *s++;
if ((uintptr_t)d % 4 == 0)
{
for (; n >= 16; s += 16, d += 16, n -= 16)
{
*(u32 *)(d + 0) = *(u32 *)(s + 0);
*(u32 *)(d + 4) = *(u32 *)(s + 4);
*(u32 *)(d + 8) = *(u32 *)(s + 8);
*(u32 *)(d + 12) = *(u32 *)(s + 12);
}
if (n & 8)
{
*(u32 *)(d + 0) = *(u32 *)(s + 0);
*(u32 *)(d + 4) = *(u32 *)(s + 4);
d += 8;
s += 8;
}
if (n & 4)
{
*(u32 *)(d + 0) = *(u32 *)(s + 0);
d += 4;
s += 4;
}
if (n & 2)
{
*d++ = *s++;
*d++ = *s++;
}
if (n & 1)
{
*d = *s;
}
return dest;
}
if ((uintptr_t)d % 4 == 0)
{
for (; n >= 16; s += 16, d += 16, n -= 16)
{
*(u32 *)(d + 0) = *(u32 *)(s + 0);
*(u32 *)(d + 4) = *(u32 *)(s + 4);
*(u32 *)(d + 8) = *(u32 *)(s + 8);
*(u32 *)(d + 12) = *(u32 *)(s + 12);
}
if (n & 8)
{
*(u32 *)(d + 0) = *(u32 *)(s + 0);
*(u32 *)(d + 4) = *(u32 *)(s + 4);
d += 8;
s += 8;
}
if (n & 4)
{
*(u32 *)(d + 0) = *(u32 *)(s + 0);
d += 4;
s += 4;
}
if (n & 2)
{
*d++ = *s++;
*d++ = *s++;
}
if (n & 1)
{
*d = *s;
}
return dest;
}
if (n >= 32)
{
switch ((uintptr_t)d % 4)
{
case 1:
{
w = *(u32 *)s;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
n -= 3;
for (; n >= 17; s += 16, d += 16, n -= 16)
{
x = *(u32 *)(s + 1);
*(u32 *)(d + 0) = (w LS 24) | (x RS 8);
w = *(u32 *)(s + 5);
*(u32 *)(d + 4) = (x LS 24) | (w RS 8);
x = *(u32 *)(s + 9);
*(u32 *)(d + 8) = (w LS 24) | (x RS 8);
w = *(u32 *)(s + 13);
*(u32 *)(d + 12) = (x LS 24) | (w RS 8);
}
break;
}
case 2:
{
w = *(u32 *)s;
*d++ = *s++;
*d++ = *s++;
n -= 2;
for (; n >= 18; s += 16, d += 16, n -= 16)
{
x = *(u32 *)(s + 2);
*(u32 *)(d + 0) = (w LS 16) | (x RS 16);
w = *(u32 *)(s + 6);
*(u32 *)(d + 4) = (x LS 16) | (w RS 16);
x = *(u32 *)(s + 10);
*(u32 *)(d + 8) = (w LS 16) | (x RS 16);
w = *(u32 *)(s + 14);
*(u32 *)(d + 12) = (x LS 16) | (w RS 16);
}
break;
}
case 3:
{
w = *(u32 *)s;
*d++ = *s++;
n -= 1;
for (; n >= 19; s += 16, d += 16, n -= 16)
{
x = *(u32 *)(s + 3);
*(u32 *)(d + 0) = (w LS 8) | (x RS 24);
w = *(u32 *)(s + 7);
*(u32 *)(d + 4) = (x LS 8) | (w RS 24);
x = *(u32 *)(s + 11);
*(u32 *)(d + 8) = (w LS 8) | (x RS 24);
w = *(u32 *)(s + 15);
*(u32 *)(d + 12) = (x LS 8) | (w RS 24);
}
break;
}
default:
break;
}
}
if (n >= 32)
{
switch ((uintptr_t)d % 4)
{
case 1:
{
w = *(u32 *)s;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
n -= 3;
for (; n >= 17; s += 16, d += 16, n -= 16)
{
x = *(u32 *)(s + 1);
*(u32 *)(d + 0) = (w LS 24) | (x RS 8);
w = *(u32 *)(s + 5);
*(u32 *)(d + 4) = (x LS 24) | (w RS 8);
x = *(u32 *)(s + 9);
*(u32 *)(d + 8) = (w LS 24) | (x RS 8);
w = *(u32 *)(s + 13);
*(u32 *)(d + 12) = (x LS 24) | (w RS 8);
}
break;
}
case 2:
{
w = *(u32 *)s;
*d++ = *s++;
*d++ = *s++;
n -= 2;
for (; n >= 18; s += 16, d += 16, n -= 16)
{
x = *(u32 *)(s + 2);
*(u32 *)(d + 0) = (w LS 16) | (x RS 16);
w = *(u32 *)(s + 6);
*(u32 *)(d + 4) = (x LS 16) | (w RS 16);
x = *(u32 *)(s + 10);
*(u32 *)(d + 8) = (w LS 16) | (x RS 16);
w = *(u32 *)(s + 14);
*(u32 *)(d + 12) = (x LS 16) | (w RS 16);
}
break;
}
case 3:
{
w = *(u32 *)s;
*d++ = *s++;
n -= 1;
for (; n >= 19; s += 16, d += 16, n -= 16)
{
x = *(u32 *)(s + 3);
*(u32 *)(d + 0) = (w LS 8) | (x RS 24);
w = *(u32 *)(s + 7);
*(u32 *)(d + 4) = (x LS 8) | (w RS 24);
x = *(u32 *)(s + 11);
*(u32 *)(d + 8) = (w LS 8) | (x RS 24);
w = *(u32 *)(s + 15);
*(u32 *)(d + 12) = (x LS 8) | (w RS 24);
}
break;
}
default:
break;
}
}
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++;
}
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++;
}
if (n & 8)
{
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (n & 8)
{
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (n & 4)
{
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (n & 4)
{
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (n & 2)
{
*d++ = *s++;
*d++ = *s++;
}
if (n & 2)
{
*d++ = *s++;
*d++ = *s++;
}
if (n & 1)
{
*d = *s;
}
return dest;
if (n & 1)
{
*d = *s;
}
return dest;
#endif
for (; n; n--)
*d++ = *s++;
return dest;
for (; n; n--)
*d++ = *s++;
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;
size_t k;
unsigned char *s = dest;
size_t k;
if (!n)
return dest;
if (!n)
return dest;
s[0] = c;
s[n - 1] = c;
s[0] = c;
s[n - 1] = c;
if (n <= 2)
return dest;
if (n <= 2)
return dest;
s[1] = c;
s[2] = c;
s[n - 2] = c;
s[n - 3] = c;
s[1] = c;
s[2] = c;
s[n - 2] = c;
s[n - 3] = c;
if (n <= 6)
return dest;
if (n <= 6)
return dest;
s[3] = c;
s[n - 4] = c;
s[3] = c;
s[n - 4] = c;
if (n <= 8)
return dest;
if (n <= 8)
return dest;
k = -(uintptr_t)s & 3;
s += k;
n -= k;
n &= -4;
k = -(uintptr_t)s & 3;
s += k;
n -= k;
n &= -4;
#ifdef __GNUC__
typedef uint32_t __attribute__((__may_alias__)) u32;
typedef uint64_t __attribute__((__may_alias__)) u64;
typedef uint32_t __attribute__((__may_alias__)) u32;
typedef uint64_t __attribute__((__may_alias__)) u64;
u32 c32 = ((u32)-1) / 255 * (unsigned char)c;
*(u32 *)(s + 0) = c32;
*(u32 *)(s + n - 4) = c32;
u32 c32 = ((u32)-1) / 255 * (unsigned char)c;
*(u32 *)(s + 0) = c32;
*(u32 *)(s + n - 4) = c32;
if (n <= 8)
return dest;
if (n <= 8)
return dest;
*(u32 *)(s + 4) = c32;
*(u32 *)(s + 8) = c32;
*(u32 *)(s + n - 12) = c32;
*(u32 *)(s + n - 8) = c32;
*(u32 *)(s + 4) = c32;
*(u32 *)(s + 8) = c32;
*(u32 *)(s + n - 12) = c32;
*(u32 *)(s + n - 8) = c32;
if (n <= 24)
return dest;
if (n <= 24)
return dest;
*(u32 *)(s + 12) = c32;
*(u32 *)(s + 16) = c32;
*(u32 *)(s + 20) = c32;
*(u32 *)(s + 24) = c32;
*(u32 *)(s + n - 28) = c32;
*(u32 *)(s + n - 24) = c32;
*(u32 *)(s + n - 20) = c32;
*(u32 *)(s + n - 16) = c32;
*(u32 *)(s + 12) = c32;
*(u32 *)(s + 16) = c32;
*(u32 *)(s + 20) = c32;
*(u32 *)(s + 24) = c32;
*(u32 *)(s + n - 28) = c32;
*(u32 *)(s + n - 24) = c32;
*(u32 *)(s + n - 20) = c32;
*(u32 *)(s + n - 16) = c32;
k = 24 + ((uintptr_t)s & 4);
s += k;
n -= k;
k = 24 + ((uintptr_t)s & 4);
s += k;
n -= k;
u64 c64 = c32 | ((u64)c32 << 32);
for (; n >= 32; n -= 32, s += 32)
{
*(u64 *)(s + 0) = c64;
*(u64 *)(s + 8) = c64;
*(u64 *)(s + 16) = c64;
*(u64 *)(s + 24) = c64;
}
u64 c64 = c32 | ((u64)c32 << 32);
for (; n >= 32; n -= 32, s += 32)
{
*(u64 *)(s + 0) = c64;
*(u64 *)(s + 8) = c64;
*(u64 *)(s + 16) = c64;
*(u64 *)(s + 24) = c64;
}
#else
for (; n; n--, s++)
*s = c;
for (; n; n--, s++)
*s = c;
#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__
typedef __attribute__((__may_alias__)) size_t WT;
typedef __attribute__((__may_alias__)) size_t WT;
#define WS (sizeof(WT))
#endif
char *d = dest;
const char *s = src;
char *d = dest;
const char *s = src;
if (d == s)
return d;
if (d == s)
return d;
if ((uintptr_t)s - (uintptr_t)d - n <= -2 * n)
return memcpy(d, s, n);
if ((uintptr_t)s - (uintptr_t)d - n <= -2 * n)
return memcpy(d, s, n);
if (d < s)
{
if (d < s)
{
#ifdef __GNUC__
if ((uintptr_t)s % WS == (uintptr_t)d % WS)
{
while ((uintptr_t)d % WS)
{
if (!n--)
return dest;
if ((uintptr_t)s % WS == (uintptr_t)d % WS)
{
while ((uintptr_t)d % WS)
{
if (!n--)
return dest;
*d++ = *s++;
}
for (; n >= WS; n -= WS, d += WS, s += WS)
*(WT *)d = *(WT *)s;
}
*d++ = *s++;
}
for (; n >= WS; n -= WS, d += WS, s += WS)
*(WT *)d = *(WT *)s;
}
#endif
for (; n; n--)
*d++ = *s++;
}
else
{
for (; n; n--)
*d++ = *s++;
}
else
{
#ifdef __GNUC__
if ((uintptr_t)s % WS == (uintptr_t)d % WS)
{
while ((uintptr_t)(d + n) % WS)
{
if (!n--)
return dest;
if ((uintptr_t)s % WS == (uintptr_t)d % WS)
{
while ((uintptr_t)(d + n) % WS)
{
if (!n--)
return dest;
d[n] = s[n];
}
while (n >= WS)
n -= WS, *(WT *)(d + n) = *(WT *)(s + n);
}
d[n] = s[n];
}
while (n >= WS)
n -= WS, *(WT *)(d + n) = *(WT *)(s + n);
}
#endif
while (n)
n--, d[n] = s[n];
}
while (n)
n--, d[n] = s[n];
}
return dest;
return dest;
}

View File

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

View File

@ -1,14 +1,14 @@
#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>
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 "../../../Kernel/syscalls.h"
int execl(const char *pathname, const char *arg, ...)
PUBLIC int execl(const char *pathname, const char *arg, ...)
{
errno = ENOSYS;
return -1;
}
int execlp(const char *file, const char *arg, ...)
PUBLIC int execlp(const char *file, const char *arg, ...)
{
errno = ENOSYS;
return -1;
}
int execle(const char *pathname, const char *arg, ...)
PUBLIC int execle(const char *pathname, const char *arg, ...)
{
errno = ENOSYS;
return -1;
}
int execv(const char *pathname, char *const argv[])
PUBLIC int execv(const char *pathname, char *const argv[])
{
errno = ENOSYS;
return -1;
}
int execvp(const char *file, char *const argv[])
PUBLIC int execvp(const char *file, char *const argv[])
{
errno = ENOSYS;
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;
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;
return -1;
}
pid_t fork(void)
PUBLIC pid_t fork(void)
{
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 <stdarg.h>
__attribute__((visibility("hidden"))) int printf_libinit(const char *format, ...);
__attribute__((visibility("hidden"))) int vprintf_libinit(const char *format, va_list arg);
__attribute__((visibility("hidden"))) int sprintf_libinit(char *s, const char *format, ...);
__attribute__((visibility("hidden"))) 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, ...);
__attribute__((visibility("hidden"))) int vsnprintf_libinit(char *s, size_t count, const char *format, va_list arg);
int printf_libinit(const char *format, ...);
int vprintf_libinit(const char *format, va_list arg);
int sprintf_libinit(char *s, const char *format, ...);
int vsprintf_libinit(char *s, const char *format, va_list arg);
int snprintf_libinit(char *s, size_t count, const char *format, ...);
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__

View File

@ -3,49 +3,6 @@
#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);
uintptr_t KrnlRequestPages(size_t Count);

View File

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

View File

@ -7,7 +7,7 @@ OBJECT_NAME=lib$(NAME).a
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)

View File

@ -3,23 +3,23 @@ include ../../../Makefile.conf
NAME=init
OBJECT_NAME=lib$(NAME).so
SO_NAME=$(OBJECT_NAME)
ifeq ($(USERSPACE_STATIC_LIBS), 1)
OBJECT_NAME := lib$(NAME).a
else
OBJECT_NAME := lib$(NAME).so
endif
OUTPUT_DIR=../../out/lib/
SYSROOT = --sysroot=../../out/
CC = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc
AS = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as
AR = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ar
OBJDUMP = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump
NASM = /usr/bin/nasm
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
AR = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
C_SOURCES = $(shell find ./ -type f -name '*.c')
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
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} ${ASM_SOURCES:.asm=.o} ${S_SOURCES:.S=.o}
OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${S_SOURCES:.S=.o}
ifeq ($(OSARCH), amd64)
ASM_ARCH := elf64
@ -27,16 +27,21 @@ 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
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)
$(OBJECT_NAME): $(OBJ)
$(info Linking $@)
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(SO_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@
$(OBJDUMP) -d $(OUTPUT_DIR)$@ > file_dump.map
ifeq ($(USERSPACE_STATIC_LIBS), 1)
$(AR) rcs $(OUTPUT_DIR)$@ $(OBJ)
else
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(OBJECT_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@
endif
%.o: %.c
$(info Compiling $<)
@ -50,9 +55,5 @@ $(OBJECT_NAME): $(OBJ)
$(info Compiling $<)
$(AS) -c $< -o $@
%.o: %.asm
$(info Compiling $<)
$(NASM) $< -f $(ASM_ARCH) -o $@
clean:
rm -f file_dump.map $(OBJ)
rm -f $(OBJ)

View File

@ -1,13 +1,22 @@
#include <libinit/init.h>
#include <unistd.h>
#include "printf.h"
void init_log(const char *fmt, ...)
{
printf_libinit("\eCCCCCC[\e0088FFinit\eCCCCCC] \eAAAAAA");
va_list args;
va_start(args, fmt);
vprintf_libinit(fmt, args);
va_end(args);
printf_libinit("\eCCCCCC");
static short log_lock = 0;
while (log_lock)
usleep(1);
__sync_synchronize();
log_lock = 1;
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
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/
SYSROOT = --sysroot=../../out/
CC = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc
AR = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ar
OBJDUMP = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump
NASM = /usr/bin/nasm
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
AR = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
C_SOURCES = $(shell find ./ -type f -name '*.c')
ASM_SOURCES = $(shell find ./ -type f -name '*.asm')
OBJ = ${C_SOURCES:.c=.o} ${ASM_SOURCES:.asm=.o}
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
S_SOURCES = $(shell find ./ -type f -name '*.S')
OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${S_SOURCES:.S=.o}
ifeq ($(OSARCH), amd64)
ASM_ARCH := elf64
@ -22,14 +27,21 @@ else ifeq ($(OSARCH), i386)
ASM_ARCH := elf32
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)
$(OBJECT_NAME): $(OBJ)
$(info Linking $@)
ifeq ($(USERSPACE_STATIC_LIBS), 1)
$(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
$(info Compiling $<)
@ -39,9 +51,9 @@ $(OBJECT_NAME): $(OBJ)
$(info Compiling $<)
$(CC) $(CFLAGS) -std=c++20 -c $< -o $@
%.o: %.asm
%.o: %.S
$(info Compiling $<)
$(NASM) $< -f $(ASM_ARCH) -o $@
$(AS) -c $< -o $@
clean:
rm -f file_dump.map $(OBJ)
rm -f $(OBJ)

View File

@ -6,30 +6,39 @@
#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)
{
if (__stack_chk_guard == 0)
__stack_chk_guard = STACK_CHK_GUARD_VALUE;
if (__stack_chk_guard == 0)
__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";
__asm__ __volatile__("syscall"
:
: "a"(0), "D"(0x57AC)
: "rcx", "r11", "memory");
__builtin_unreachable();
const char *msg = "Stack smashing detected";
__asm__ __volatile__("syscall"
:
: "a"(0), "D"(0x57AC)
: "rcx", "r11", "memory");
__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";
__asm__ __volatile__("syscall"
:
: "a"(0), "D"(0xF700)
: "rcx", "r11", "memory");
__builtin_unreachable();
const char *msg = "Buffer overflow detected";
__asm__ __volatile__("syscall"
:
: "a"(0), "D"(0xF700)
: "rcx", "r11", "memory");
__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)
{
return syscall5(_KernelCTL, Command, Arg1, Arg2, Arg3, Arg4);
return syscall5(_KernelCTL, Command, Arg1, Arg2, Arg3, Arg4);
}
uintptr_t KrnlRequestPages(size_t Count)
{
return syscall1(_RequestPages, Count);
return syscall1(_RequestPages, 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()
{
static long PageSize = 0;
if (PageSize == 0)
PageSize = DoCtl(KCTL_GET_PAGE_SIZE, 0, 0, 0, 0);
return PageSize;
static long PageSize = 0;
if (PageSize == 0)
PageSize = DoCtl(KCTL_GET_PAGE_SIZE, 0, 0, 0, 0);
return PageSize;
}
File *FileOpen(const char *Path, uint64_t Flags)
{
File *FilePtr = (File *)KrnlRequestPages(sizeof(File) / __FILE_GetPageSize() + 1);
FilePtr->KernelPrivate = (void *)syscall2(_FileOpen, (uint64_t)Path, Flags);
return FilePtr;
File *FilePtr = (File *)KrnlRequestPages(sizeof(File) / __FILE_GetPageSize() + 1);
FilePtr->KernelPrivate = (void *)syscall2(_FileOpen, (uint64_t)Path, Flags);
return FilePtr;
}
void FileClose(File *File)
{
syscall1(_FileClose, (uint64_t)File->KernelPrivate);
KrnlFreePages((uintptr_t)File, sizeof(File) / __FILE_GetPageSize() + 1);
syscall1(_FileClose, (uint64_t)File->KernelPrivate);
KrnlFreePages((uintptr_t)File, sizeof(File) / __FILE_GetPageSize() + 1);
}
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)
{
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)
{
return syscall3(_FileSeek, (uint64_t)File->KernelPrivate, Offset, Whence);
return syscall3(_FileSeek, (uint64_t)File->KernelPrivate, Offset, Whence);
}
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
OBJECT_NAME=lib$(NAME).so
SO_NAME=$(OBJECT_NAME)
ifeq ($(USERSPACE_STATIC_LIBS), 1)
OBJECT_NAME := lib$(NAME).a
else
OBJECT_NAME := lib$(NAME).so
endif
OUTPUT_DIR=../../out/lib/
SYSROOT = --sysroot=../../out/
CC = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc
AS = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as
AR = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ar
OBJDUMP = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump
NASM = /usr/bin/nasm
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
AR = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
C_SOURCES = $(shell find ./ -type f -name '*.c')
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
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} ${ASM_SOURCES:.asm=.o} ${S_SOURCES:.S=.o}
OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${S_SOURCES:.S=.o}
ifeq ($(OSARCH), amd64)
ASM_ARCH := elf64
@ -27,16 +27,21 @@ 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
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)
$(OBJECT_NAME): $(OBJ)
$(info Linking $@)
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(SO_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@
$(OBJDUMP) -d $(OUTPUT_DIR)$@ > file_dump.map
ifeq ($(USERSPACE_STATIC_LIBS), 1)
$(AR) rcs $(OUTPUT_DIR)$@ $(OBJ)
else
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(OBJECT_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@
endif
%.o: %.c
$(info Compiling $<)
@ -50,9 +55,5 @@ $(OBJECT_NAME): $(OBJ)
$(info Compiling $<)
$(AS) -c $< -o $@
%.o: %.asm
$(info Compiling $<)
$(NASM) $< -f $(ASM_ARCH) -o $@
clean:
rm -f file_dump.map $(OBJ)
rm -f $(OBJ)