mirror of
https://github.com/Fennix-Project/Userspace.git
synced 2025-05-28 07:24:25 +00:00
Update userspace
This commit is contained in:
parent
ed5faa7b55
commit
22e75b9540
4
.vscode/c_cpp_properties.json
vendored
4
.vscode/c_cpp_properties.json
vendored
@ -18,7 +18,7 @@
|
|||||||
"a86",
|
"a86",
|
||||||
"DEBUG=\"1\""
|
"DEBUG=\"1\""
|
||||||
],
|
],
|
||||||
"compilerPath": "${workspaceFolder}/../tools/cross/bin/amd64-elf-gcc",
|
"compilerPath": "${workspaceFolder}/../tools/cross/bin/x86_64-fennix-gcc",
|
||||||
"cStandard": "c17",
|
"cStandard": "c17",
|
||||||
"cppStandard": "c++20",
|
"cppStandard": "c++20",
|
||||||
"intelliSenseMode": "gcc-x64",
|
"intelliSenseMode": "gcc-x64",
|
||||||
@ -70,7 +70,7 @@
|
|||||||
"a86",
|
"a86",
|
||||||
"DEBUG=\"1\""
|
"DEBUG=\"1\""
|
||||||
],
|
],
|
||||||
"compilerPath": "${workspaceFolder}/../tools/cross/bin/i386-elf-gcc",
|
"compilerPath": "${workspaceFolder}/../tools/cross/bin/i386-fennix-gcc",
|
||||||
"cStandard": "c17",
|
"cStandard": "c17",
|
||||||
"cppStandard": "c++20",
|
"cppStandard": "c++20",
|
||||||
"intelliSenseMode": "gcc-x86",
|
"intelliSenseMode": "gcc-x86",
|
||||||
|
43
.vscode/launch.json
vendored
43
.vscode/launch.json
vendored
@ -2,7 +2,7 @@
|
|||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "/init",
|
"name": "/bin/init",
|
||||||
"type": "cppdbg",
|
"type": "cppdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceFolder}/out/bin/init",
|
"program": "${workspaceFolder}/out/bin/init",
|
||||||
@ -41,7 +41,46 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "/bin/doom",
|
"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",
|
"type": "cppdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceFolder}/out/usr/bin/doom",
|
"program": "${workspaceFolder}/out/usr/bin/doom",
|
||||||
|
@ -3,11 +3,11 @@ WORKSPACE := ../../../
|
|||||||
# Config file
|
# Config file
|
||||||
include ../$(WORKSPACE)Makefile.conf
|
include ../$(WORKSPACE)Makefile.conf
|
||||||
|
|
||||||
CC = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc
|
CC = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
||||||
CPP = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)g++
|
CPP = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)g++
|
||||||
LD = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ld
|
LD = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)ld
|
||||||
AS = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as
|
AS = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
||||||
OBJDUMP = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump
|
OBJDUMP = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
|
||||||
|
|
||||||
GIT_COMMIT = $(shell git rev-parse HEAD)
|
GIT_COMMIT = $(shell git rev-parse HEAD)
|
||||||
GIT_COMMIT_SHORT = $(shell git rev-parse --short HEAD)
|
GIT_COMMIT_SHORT = $(shell git rev-parse --short HEAD)
|
||||||
|
@ -3,11 +3,11 @@ WORKSPACE := ../../../
|
|||||||
# Config file
|
# Config file
|
||||||
include ../$(WORKSPACE)Makefile.conf
|
include ../$(WORKSPACE)Makefile.conf
|
||||||
|
|
||||||
CC = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc
|
CC = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
||||||
CPP = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)g++
|
CPP = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)g++
|
||||||
LD = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ld
|
LD = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)ld
|
||||||
AS = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as
|
AS = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
||||||
OBJDUMP = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump
|
OBJDUMP = ../$(WORKSPACE)$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
|
||||||
|
|
||||||
GIT_COMMIT = $(shell git rev-parse HEAD)
|
GIT_COMMIT = $(shell git rev-parse HEAD)
|
||||||
GIT_COMMIT_SHORT = $(shell git rev-parse --short HEAD)
|
GIT_COMMIT_SHORT = $(shell git rev-parse --short HEAD)
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 7ef0110ddcfd0d6a03204d805841915a8e56a247
|
Subproject commit 9af0e63ae3ef8948e67ff0d570289a309ff40dcf
|
@ -9,10 +9,10 @@ SO_NAME=$(OBJECT_NAME)
|
|||||||
OUTPUT_DIR=../../out/lib/
|
OUTPUT_DIR=../../out/lib/
|
||||||
SYSROOT = --sysroot=../../out/
|
SYSROOT = --sysroot=../../out/
|
||||||
|
|
||||||
CC = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc
|
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
||||||
AS = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as
|
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
||||||
AR = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ar
|
AR = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
|
||||||
OBJDUMP = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump
|
OBJDUMP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
|
||||||
NASM = /usr/bin/nasm
|
NASM = /usr/bin/nasm
|
||||||
|
|
||||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||||
@ -23,16 +23,25 @@ OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${ASM_SOURCES:.asm=.o} ${S_SOURC
|
|||||||
|
|
||||||
INCLUDE = ../include
|
INCLUDE = ../include
|
||||||
|
|
||||||
ifeq ($(OSARCH), amd64)
|
|
||||||
ASM_ARCH := elf64
|
|
||||||
else ifeq ($(OSARCH), i386)
|
|
||||||
ASM_ARCH := elf32
|
|
||||||
endif
|
|
||||||
|
|
||||||
SIMD_FLAGS := -mno-sse -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4.1 -mno-sse4.2 -mno-sse4 -mno-avx -mno-avx2 -mno-avx512f
|
SIMD_FLAGS := -mno-sse -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4.1 -mno-sse4.2 -mno-sse4 -mno-avx -mno-avx2 -mno-avx512f
|
||||||
|
|
||||||
CFLAGS := -pie -fPIE -I$(INCLUDE) $(SIMD_FLAGS)
|
CFLAGS := -I$(INCLUDE) $(SIMD_FLAGS) -fPIC
|
||||||
LDFLAGS := -nostartfiles -nostdlib -pie -fPIE -Wl,-e_ld_start,-soname,$(SO_NAME) $(SYSROOT)
|
LDFLAGS := -nostartfiles -nostdlib -Wl,-soname,$(SO_NAME) $(SYSROOT) -fno-pie -fno-PIC
|
||||||
|
|
||||||
|
ifeq ($(OSARCH), amd64)
|
||||||
|
ASM_ARCH := elf64
|
||||||
|
LDFLAGS += -Ttext=0xFFFFFFFFF0001000
|
||||||
|
CFLAGS += -m64
|
||||||
|
else ifeq ($(OSARCH), i386)
|
||||||
|
ASM_ARCH := elf32
|
||||||
|
LDFLAGS += -fixme
|
||||||
|
CFLAGS += -m32
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(DEBUG), 1)
|
||||||
|
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm
|
||||||
|
LDFLAGS += -ggdb3 -O0
|
||||||
|
endif
|
||||||
|
|
||||||
build: $(OBJECT_NAME)
|
build: $(OBJECT_NAME)
|
||||||
|
|
||||||
|
@ -293,6 +293,4 @@ typedef struct elf64_sym
|
|||||||
Elf64_Xword st_size;
|
Elf64_Xword st_size;
|
||||||
} Elf64_Sym;
|
} Elf64_Sym;
|
||||||
|
|
||||||
struct Elf64_Dyn *ELFGetDynamicTag(void *ElfFile, enum DynamicTags Tag);
|
|
||||||
|
|
||||||
#endif // !__FENNIX_LIB_ELF_LAZY_RESOLVE_H__
|
#endif // !__FENNIX_LIB_ELF_LAZY_RESOLVE_H__
|
||||||
|
234
libc/ElfInterpreter/fcts.c
Normal file
234
libc/ElfInterpreter/fcts.c
Normal 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};
|
||||||
|
}
|
31
libc/ElfInterpreter/fcts.h
Normal file
31
libc/ElfInterpreter/fcts.h
Normal 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__
|
@ -1,44 +1,46 @@
|
|||||||
#include "ld.h"
|
#include "ld.h"
|
||||||
|
#include "fcts.h"
|
||||||
|
|
||||||
#include "../../libs/include/libsys/base.h"
|
|
||||||
#include "../../../Kernel/syscalls.h"
|
#include "../../../Kernel/syscalls.h"
|
||||||
#include "../../../Kernel/ipc.h"
|
#include "../../../Kernel/ipc.h"
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
|
|
||||||
uintptr_t RequestPages(size_t Count)
|
#define Print(x) Print__(x)
|
||||||
{
|
#define PrintNL(x) PrintNL__(x)
|
||||||
return syscall1(_RequestPages, Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
int FreePages(uintptr_t Address, size_t Count)
|
#if (1)
|
||||||
{
|
#define PrintDbg(x) Print__(x)
|
||||||
return syscall2(_FreePages, Address, Count);
|
#define PrintDbgNL(x) PrintNL__(x)
|
||||||
}
|
#define ltoaDbg(x, y, z) ltoa(x, y, z)
|
||||||
|
#else
|
||||||
|
#define PrintDbg(x)
|
||||||
|
#define PrintDbgNL(x)
|
||||||
|
#define ltoaDbg(x, y, z)
|
||||||
|
#endif
|
||||||
|
|
||||||
int IPC(enum IPCCommand Command, enum IPCType Type, int ID, int Flags, void *Buffer, size_t Size)
|
struct InterpreterIPCDataLibrary
|
||||||
{
|
{
|
||||||
return syscall6(_IPC, (long)Command, (long)Type, (long)ID, (long)Flags, (long)Buffer, (long)Size);
|
char Name[64];
|
||||||
}
|
};
|
||||||
|
|
||||||
uintptr_t KernelCTL(enum KCtl Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4)
|
typedef struct
|
||||||
{
|
{
|
||||||
return syscall5(_KernelCTL, Command, Arg1, Arg2, Arg3, Arg4);
|
char Path[256];
|
||||||
}
|
void *MemoryImage;
|
||||||
|
struct InterpreterIPCDataLibrary Libraries[64];
|
||||||
|
} InterpreterIPCData;
|
||||||
|
|
||||||
struct LibAddressCollection
|
struct LibsCollection
|
||||||
{
|
{
|
||||||
char Name[32];
|
char ParentName[32];
|
||||||
uintptr_t ElfFile;
|
char LibraryName[32];
|
||||||
uintptr_t MemoryImage;
|
|
||||||
uintptr_t ParentElfFile;
|
|
||||||
uintptr_t ParentMemoryImage;
|
uintptr_t ParentMemoryImage;
|
||||||
struct LibAddressCollection *Next;
|
uintptr_t LibraryMemoryImage;
|
||||||
|
struct LibsCollection *Next;
|
||||||
char Valid;
|
char Valid;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
static char ParentPath[256];
|
||||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
|
||||||
|
|
||||||
static char Lock = 0;
|
static char Lock = 0;
|
||||||
|
|
||||||
__attribute__((naked, used, no_stack_protector)) void ELF_LAZY_RESOLVE_STUB()
|
__attribute__((naked, used, no_stack_protector)) void ELF_LAZY_RESOLVE_STUB()
|
||||||
@ -74,197 +76,25 @@ __attribute__((naked, used, no_stack_protector)) void ELF_LAZY_RESOLVE_STUB()
|
|||||||
"jmp *%r11\n"); // Jump to the return value
|
"jmp *%r11\n"); // Jump to the return value
|
||||||
}
|
}
|
||||||
|
|
||||||
int abs(int i) { return i < 0 ? -i : i; }
|
void (*ELF_LAZY_RESOLVE_MAIN(struct LibsCollection *Info, long RelIndex))()
|
||||||
|
|
||||||
void swap(char *x, char *y)
|
|
||||||
{
|
{
|
||||||
char t = *x;
|
if (!Info)
|
||||||
*x = *y;
|
goto FailEnd;
|
||||||
*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)
|
|
||||||
#define PrintDbg(x) Print__(x)
|
|
||||||
#define PrintDbgNL(x) PrintNL__(x)
|
|
||||||
#define ltoaDbg(x, y, z) ltoa(x, y, z)
|
|
||||||
#else
|
|
||||||
#define PrintDbg(x)
|
|
||||||
#define PrintDbgNL(x)
|
|
||||||
#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];
|
char DbgBuff[32];
|
||||||
if (Info)
|
char LibraryPathBuffer[256];
|
||||||
{
|
|
||||||
struct LibAddressCollection *CurLib = Info;
|
struct LibsCollection *CurLib = Info;
|
||||||
PrintDbgNL("_______");
|
PrintDbgNL("_______");
|
||||||
// The last entry is the null entry (Valid == false) which determines the end of the list.
|
/* The last entry is the null entry (Valid == false)
|
||||||
|
which determines the end of the list. */
|
||||||
while (CurLib->Valid)
|
while (CurLib->Valid)
|
||||||
{
|
{
|
||||||
|
KernelCTL(KCTL_GET_ABSOLUTE_PATH, CurLib->LibraryName,
|
||||||
|
LibraryPathBuffer, sizeof(LibraryPathBuffer), 0);
|
||||||
|
|
||||||
PrintDbg("-- ");
|
PrintDbg("-- ");
|
||||||
PrintDbg(CurLib->Name);
|
PrintDbg(LibraryPathBuffer);
|
||||||
PrintDbg(" ");
|
PrintDbg(" ");
|
||||||
ltoaDbg(RelIndex, DbgBuff, 10);
|
ltoaDbg(RelIndex, DbgBuff, 10);
|
||||||
PrintDbg(DbgBuff);
|
PrintDbg(DbgBuff);
|
||||||
@ -272,72 +102,97 @@ void (*ELF_LAZY_RESOLVE_MAIN(struct LibAddressCollection *Info, long RelIndex))(
|
|||||||
uintptr_t lib_BaseAddress = __UINTPTR_MAX__;
|
uintptr_t lib_BaseAddress = __UINTPTR_MAX__;
|
||||||
uintptr_t app_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;
|
Elf64_Phdr ItrProgramHeader;
|
||||||
|
|
||||||
for (Elf64_Half i = 0; i < ((Elf64_Ehdr *)CurLib->ElfFile)->e_phnum; i++)
|
for (Elf64_Half i = 0; i < lib_Header.e_phnum; i++)
|
||||||
{
|
{
|
||||||
memcpy(&ItrProgramHeader,
|
syscall3(_FileSeek, KP_lib,
|
||||||
(uint8_t *)CurLib->ElfFile +
|
lib_Header.e_phoff +
|
||||||
((Elf64_Ehdr *)CurLib->ElfFile)->e_phoff +
|
lib_Header.e_phentsize * i,
|
||||||
((Elf64_Ehdr *)CurLib->ElfFile)->e_phentsize * i,
|
SEEK_SET);
|
||||||
sizeof(Elf64_Phdr));
|
|
||||||
|
syscall3(_FileRead, KP_lib, &ItrProgramHeader, sizeof(Elf64_Phdr));
|
||||||
|
|
||||||
lib_BaseAddress = MIN(lib_BaseAddress, ItrProgramHeader.p_vaddr);
|
lib_BaseAddress = MIN(lib_BaseAddress, ItrProgramHeader.p_vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Elf64_Half i = 0; i < ((Elf64_Ehdr *)CurLib->ParentElfFile)->e_phnum; i++)
|
for (Elf64_Half i = 0; i < app_Header.e_phnum; i++)
|
||||||
{
|
{
|
||||||
memcpy(&ItrProgramHeader,
|
syscall3(_FileSeek, KP_app,
|
||||||
(uint8_t *)CurLib->ParentElfFile +
|
app_Header.e_phoff +
|
||||||
((Elf64_Ehdr *)CurLib->ParentElfFile)->e_phoff +
|
app_Header.e_phentsize * i,
|
||||||
((Elf64_Ehdr *)CurLib->ParentElfFile)->e_phentsize * i,
|
SEEK_SET);
|
||||||
sizeof(Elf64_Phdr));
|
|
||||||
|
syscall3(_FileRead, KP_app, &ItrProgramHeader, sizeof(Elf64_Phdr));
|
||||||
|
|
||||||
app_BaseAddress = MIN(app_BaseAddress, ItrProgramHeader.p_vaddr);
|
app_BaseAddress = MIN(app_BaseAddress, ItrProgramHeader.p_vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Elf64_Dyn *lib_JmpRel = ELFGetDynamicTag((void *)CurLib->ElfFile, DT_JMPREL);
|
struct Elf64_Dyn lib_JmpRel = ELFGetDynamicTag(LibraryPathBuffer, DT_JMPREL);
|
||||||
struct Elf64_Dyn *lib_SymTab = ELFGetDynamicTag((void *)CurLib->ElfFile, DT_SYMTAB);
|
struct Elf64_Dyn lib_SymTab = ELFGetDynamicTag(LibraryPathBuffer, DT_SYMTAB);
|
||||||
struct Elf64_Dyn *lib_StrTab = ELFGetDynamicTag((void *)CurLib->ElfFile, DT_STRTAB);
|
struct Elf64_Dyn lib_StrTab = ELFGetDynamicTag(LibraryPathBuffer, DT_STRTAB);
|
||||||
|
|
||||||
struct Elf64_Dyn *app_JmpRel = ELFGetDynamicTag((void *)CurLib->ParentElfFile, DT_JMPREL);
|
struct Elf64_Dyn app_JmpRel = ELFGetDynamicTag(ParentPath, DT_JMPREL);
|
||||||
struct Elf64_Dyn *app_SymTab = ELFGetDynamicTag((void *)CurLib->ParentElfFile, DT_SYMTAB);
|
struct Elf64_Dyn app_SymTab = ELFGetDynamicTag(ParentPath, DT_SYMTAB);
|
||||||
struct Elf64_Dyn *app_StrTab = ELFGetDynamicTag((void *)CurLib->ParentElfFile, DT_STRTAB);
|
struct Elf64_Dyn app_StrTab = ELFGetDynamicTag(ParentPath, DT_STRTAB);
|
||||||
|
|
||||||
if (!lib_JmpRel)
|
if (!lib_JmpRel.d_tag == 0)
|
||||||
{
|
{
|
||||||
PrintNL("No DT_JMPREL");
|
PrintNL("No DT_JMPREL");
|
||||||
goto RetryNextLib;
|
// goto RetryNextLib;
|
||||||
}
|
}
|
||||||
else if (RelIndex >= lib_JmpRel->d_un.d_val / sizeof(Elf64_Rela))
|
else if (RelIndex >= lib_JmpRel.d_un.d_val /
|
||||||
|
sizeof(Elf64_Rela))
|
||||||
{
|
{
|
||||||
PrintNL("RelIndex is greater than the number of relocations");
|
PrintNL("RelIndex is greater than the number of relocations");
|
||||||
goto RetryNextLib;
|
goto RetryNextLib;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lib_SymTab)
|
if (!lib_SymTab.d_tag == 0)
|
||||||
{
|
{
|
||||||
PrintNL("No DT_SYMTAB");
|
PrintNL("No DT_SYMTAB");
|
||||||
goto RetryNextLib;
|
goto RetryNextLib;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lib_StrTab)
|
if (!lib_StrTab.d_tag == 0)
|
||||||
{
|
{
|
||||||
PrintNL("No DT_STRTAB");
|
PrintNL("No DT_STRTAB");
|
||||||
goto RetryNextLib;
|
goto RetryNextLib;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lib_JmpRel && !lib_SymTab && !lib_StrTab)
|
if (!lib_SymTab.d_tag == 0 &&
|
||||||
|
!lib_StrTab.d_tag == 0)
|
||||||
goto RetryNextLib;
|
goto RetryNextLib;
|
||||||
|
|
||||||
Elf64_Rela *_lib_JmpRel = (Elf64_Rela *)(CurLib->MemoryImage + (lib_JmpRel->d_un.d_ptr - lib_BaseAddress));
|
Elf64_Rela *_lib_JmpRel = (Elf64_Rela *)(CurLib->LibraryMemoryImage + (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_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_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));
|
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 *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));
|
char *app_DynStr = (char *)(CurLib->ParentMemoryImage + (app_StrTab.d_un.d_ptr - app_BaseAddress));
|
||||||
|
|
||||||
Elf64_Rela *Rel = _app_JmpRel + RelIndex;
|
Elf64_Rela *Rel = _app_JmpRel + RelIndex;
|
||||||
Elf64_Addr *GOTEntry = (Elf64_Addr *)(Rel->r_offset);
|
Elf64_Addr *GOTEntry = (Elf64_Addr *)(Rel->r_offset);
|
||||||
@ -369,15 +224,15 @@ void (*ELF_LAZY_RESOLVE_MAIN(struct LibAddressCollection *Info, long RelIndex))(
|
|||||||
PrintDbg("SymName: ");
|
PrintDbg("SymName: ");
|
||||||
PrintDbgNL(SymName);
|
PrintDbgNL(SymName);
|
||||||
|
|
||||||
Elf64_Sym *LibSym = ELFLookupSymbol((Elf64_Ehdr *)CurLib->ElfFile, SymName);
|
Elf64_Sym LibSym = ELFLookupSymbol(ParentPath, SymName);
|
||||||
|
|
||||||
PrintDbg("LibSym: 0x");
|
PrintDbg("LibSym: 0x");
|
||||||
ltoaDbg((long)LibSym, DbgBuff, 16);
|
ltoaDbg((long)LibSym.st_size, DbgBuff, 16);
|
||||||
PrintDbgNL(DbgBuff);
|
PrintDbgNL(DbgBuff);
|
||||||
|
|
||||||
if (LibSym)
|
if (LibSym.st_value)
|
||||||
{
|
{
|
||||||
*GOTEntry = (Elf64_Addr)(CurLib->MemoryImage + LibSym->st_value);
|
*GOTEntry = (Elf64_Addr)(CurLib->LibraryMemoryImage + LibSym.st_value);
|
||||||
|
|
||||||
ltoa(*GOTEntry, DbgBuff, 16);
|
ltoa(*GOTEntry, DbgBuff, 16);
|
||||||
PrintDbg("*GOTEntry: 0x");
|
PrintDbg("*GOTEntry: 0x");
|
||||||
@ -403,8 +258,8 @@ void (*ELF_LAZY_RESOLVE_MAIN(struct LibAddressCollection *Info, long RelIndex))(
|
|||||||
PrintDbgNL("Retrying next lib");
|
PrintDbgNL("Retrying next lib");
|
||||||
CurLib = CurLib->Next;
|
CurLib = CurLib->Next;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
FailEnd:
|
||||||
Lock = 0;
|
Lock = 0;
|
||||||
__asm__ __volatile__("mfence\n");
|
__asm__ __volatile__("mfence\n");
|
||||||
|
|
||||||
@ -418,19 +273,6 @@ void (*ELF_LAZY_RESOLVE_MAIN(struct LibAddressCollection *Info, long RelIndex))(
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InterpreterIPCDataLibrary
|
|
||||||
{
|
|
||||||
char Name[128];
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
char Path[256];
|
|
||||||
void *ElfFile;
|
|
||||||
void *MemoryImage;
|
|
||||||
struct InterpreterIPCDataLibrary Libraries[64];
|
|
||||||
} InterpreterIPCData;
|
|
||||||
|
|
||||||
/* Preload */
|
/* Preload */
|
||||||
int ld_main()
|
int ld_main()
|
||||||
{
|
{
|
||||||
@ -443,19 +285,19 @@ int ld_main()
|
|||||||
} while (KCTL_ret == SYSCALL_ACCESS_DENIED);
|
} while (KCTL_ret == SYSCALL_ACCESS_DENIED);
|
||||||
|
|
||||||
if (KCTL_ret == false)
|
if (KCTL_ret == false)
|
||||||
return -4;
|
return -1;
|
||||||
|
|
||||||
/* Everything is ok, continue. */
|
/* Everything is ok, continue. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ELFAddLazyResolverToGOT(void *ElfFile, void *MemoryImage, struct LibAddressCollection *Libs)
|
bool ELFAddLazyResolverToGOT(void *MemoryImage, struct LibsCollection *Libs)
|
||||||
{
|
{
|
||||||
struct Elf64_Dyn *Dyn = (struct Elf64_Dyn *)ELFGetDynamicTag(ElfFile, DT_PLTGOT);
|
struct Elf64_Dyn Dyn = ELFGetDynamicTag(ParentPath, DT_PLTGOT);
|
||||||
if (!Dyn)
|
if (!Dyn.d_tag)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Elf64_Addr *GOT = (Elf64_Addr *)Dyn->d_un.d_ptr;
|
Elf64_Addr *GOT = (Elf64_Addr *)Dyn.d_un.d_ptr;
|
||||||
|
|
||||||
GOT[1] = (uintptr_t)Libs;
|
GOT[1] = (uintptr_t)Libs;
|
||||||
GOT[2] = (uintptr_t)ELF_LAZY_RESOLVE_STUB;
|
GOT[2] = (uintptr_t)ELF_LAZY_RESOLVE_STUB;
|
||||||
@ -465,83 +307,111 @@ bool ELFAddLazyResolverToGOT(void *ElfFile, void *MemoryImage, struct LibAddress
|
|||||||
/* Actual load */
|
/* Actual load */
|
||||||
int ld_load(int argc, char *argv[], char *envp[])
|
int ld_load(int argc, char *argv[], char *envp[])
|
||||||
{
|
{
|
||||||
|
PrintDbgNL("!");
|
||||||
uintptr_t PageSize = KernelCTL(KCTL_GET_PAGE_SIZE, 0, 0, 0, 0);
|
uintptr_t PageSize = KernelCTL(KCTL_GET_PAGE_SIZE, 0, 0, 0, 0);
|
||||||
int PagesForIPCDataStruct = sizeof(InterpreterIPCData) / PageSize + 1;
|
int PagesForIPCDataStruct = sizeof(InterpreterIPCData) / PageSize + 1;
|
||||||
InterpreterIPCData *IPCBuffer = (InterpreterIPCData *)RequestPages(PagesForIPCDataStruct);
|
int PagesForLibsCollectionStruct = sizeof(struct LibsCollection) / PageSize + 1;
|
||||||
|
|
||||||
int IPC_ID = IPC(IPC_CREATE, IPC_TYPE_MessagePassing, 0, 0, "LOAD", sizeof(InterpreterIPCData));
|
InterpreterIPCData *IPCBuffer =
|
||||||
|
(InterpreterIPCData *)RequestPages(PagesForIPCDataStruct);
|
||||||
|
|
||||||
|
int IPC_ID = IPC(IPC_CREATE, IPC_TYPE_MessagePassing,
|
||||||
|
0, 0, "LOAD", sizeof(InterpreterIPCData));
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
IPC(IPC_LISTEN, IPC_TYPE_MessagePassing, IPC_ID, 1, NULL, 0);
|
IPC(IPC_LISTEN, IPC_TYPE_MessagePassing, IPC_ID, 1, NULL, 0);
|
||||||
IPC(IPC_WAIT, IPC_TYPE_MessagePassing, IPC_ID, 0, 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);
|
int IPCResult = IPC(IPC_READ, IPC_TYPE_MessagePassing,
|
||||||
|
IPC_ID, 0, IPCBuffer, PageSize);
|
||||||
|
|
||||||
if (IPCResult == IPC_E_CODE_Success)
|
if (IPCResult == IPC_E_CODE_Success)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LibAddressCollection *LibsForLazyResolver = (struct LibAddressCollection *)RequestPages(sizeof(struct LibAddressCollection) / PageSize + 1);
|
struct LibsCollection *LibsForLazyResolver =
|
||||||
for (size_t i = 0; i < 64; i++)
|
(struct LibsCollection *)RequestPages(PagesForLibsCollectionStruct);
|
||||||
|
|
||||||
|
for (short i = 0; i < 64; i++)
|
||||||
{
|
{
|
||||||
if (IPCBuffer->Libraries[i].Name[0] == '\0')
|
if (IPCBuffer->Libraries[i].Name[0] == '\0')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
uintptr_t lib_addr = KernelCTL(KCTL_GET_ELF_LIB_FILE, (uint64_t)IPCBuffer->Libraries[i].Name, 0, 0, 0);
|
uintptr_t lib_mm_image =
|
||||||
uintptr_t lib_mm_image = KernelCTL(KCTL_GET_ELF_LIB_MEMORY_IMAGE, (uint64_t)IPCBuffer->Libraries[i].Name, 0, 0, 0);
|
KernelCTL(KCTL_GET_ELF_LIB_MEMORY_IMAGE,
|
||||||
if (lib_addr == 0 || lib_mm_image == 0)
|
(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);
|
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)
|
if (ret != SYSCALL_OK)
|
||||||
{
|
{
|
||||||
PrintNL("Failed to register ELF lib");
|
PrintNL("Failed to register ELF lib");
|
||||||
return -0x11B;
|
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,
|
||||||
lib_mm_image = KernelCTL(KCTL_GET_ELF_LIB_MEMORY_IMAGE, (uint64_t)IPCBuffer->Libraries[i].Name, 0, 0, 0);
|
(uint64_t)IPCBuffer->Libraries[i].Name, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LibsForLazyResolver->Next == NULL)
|
if (LibsForLazyResolver->Next == NULL)
|
||||||
{
|
{
|
||||||
LibsForLazyResolver->Valid = true;
|
LibsForLazyResolver->Valid = true;
|
||||||
LibsForLazyResolver->ElfFile = (uintptr_t)lib_addr;
|
LibsForLazyResolver->LibraryMemoryImage = (uintptr_t)lib_mm_image;
|
||||||
LibsForLazyResolver->MemoryImage = (uintptr_t)lib_mm_image;
|
|
||||||
LibsForLazyResolver->ParentElfFile = (uintptr_t)IPCBuffer->ElfFile;
|
|
||||||
LibsForLazyResolver->ParentMemoryImage = (uintptr_t)IPCBuffer->MemoryImage;
|
LibsForLazyResolver->ParentMemoryImage = (uintptr_t)IPCBuffer->MemoryImage;
|
||||||
for (size_t j = 0; j < 32; j++)
|
for (short j = 0; j < sizeof(LibsForLazyResolver->LibraryName); j++)
|
||||||
LibsForLazyResolver->Name[j] = IPCBuffer->Libraries[i].Name[j];
|
LibsForLazyResolver->LibraryName[j] = IPCBuffer->Libraries[i].Name[j];
|
||||||
|
|
||||||
LibsForLazyResolver->Next = (struct LibAddressCollection *)RequestPages(sizeof(struct LibAddressCollection) / PageSize + 1);
|
LibsForLazyResolver->Next =
|
||||||
memset(LibsForLazyResolver->Next, 0, sizeof(struct LibAddressCollection));
|
(struct LibsCollection *)RequestPages(PagesForLibsCollectionStruct);
|
||||||
|
memset(LibsForLazyResolver->Next, 0, sizeof(struct LibsCollection));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
struct LibAddressCollection *CurrentLibsForLazyResolver = LibsForLazyResolver;
|
|
||||||
|
|
||||||
while (CurrentLibsForLazyResolver->Next != NULL)
|
struct LibsCollection *CurrentLib = LibsForLazyResolver;
|
||||||
CurrentLibsForLazyResolver = CurrentLibsForLazyResolver->Next;
|
while (CurrentLib->Next != NULL)
|
||||||
|
CurrentLib = CurrentLib->Next;
|
||||||
|
|
||||||
CurrentLibsForLazyResolver->Valid = true;
|
CurrentLib->Valid = true;
|
||||||
CurrentLibsForLazyResolver->ElfFile = (uintptr_t)lib_addr;
|
CurrentLib->LibraryMemoryImage = (uintptr_t)lib_mm_image;
|
||||||
CurrentLibsForLazyResolver->MemoryImage = (uintptr_t)lib_mm_image;
|
CurrentLib->ParentMemoryImage = (uintptr_t)IPCBuffer->MemoryImage;
|
||||||
CurrentLibsForLazyResolver->ParentElfFile = (uintptr_t)IPCBuffer->ElfFile;
|
for (short j = 0; j < sizeof(LibsForLazyResolver->LibraryName); j++)
|
||||||
CurrentLibsForLazyResolver->ParentMemoryImage = (uintptr_t)IPCBuffer->MemoryImage;
|
CurrentLib->LibraryName[j] = IPCBuffer->Libraries[i].Name[j];
|
||||||
for (size_t j = 0; j < 32; j++)
|
|
||||||
CurrentLibsForLazyResolver->Name[j] = IPCBuffer->Libraries[i].Name[j];
|
|
||||||
|
|
||||||
CurrentLibsForLazyResolver->Next = (struct LibAddressCollection *)RequestPages(sizeof(struct LibAddressCollection) / PageSize + 1);
|
CurrentLib->Next =
|
||||||
memset(CurrentLibsForLazyResolver->Next, 0, sizeof(struct LibAddressCollection));
|
(struct LibsCollection *)RequestPages(PagesForLibsCollectionStruct);
|
||||||
|
memset(CurrentLib->Next, 0, sizeof(struct LibsCollection));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LibAddressCollection *CurrentLibsForLazyResolver = LibsForLazyResolver;
|
struct LibsCollection *CurrentLib = LibsForLazyResolver;
|
||||||
|
|
||||||
if (!ELFAddLazyResolverToGOT(IPCBuffer->ElfFile, IPCBuffer->MemoryImage, LibsForLazyResolver))
|
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");
|
PrintNL("Failed to add lazy resolver to GOT");
|
||||||
return -0x607;
|
return -0x607;
|
||||||
}
|
}
|
||||||
|
|
||||||
Elf64_Addr Entry = ((Elf64_Ehdr *)IPCBuffer->ElfFile)->e_entry;
|
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);
|
IPC(IPC_DELETE, IPC_TYPE_MessagePassing, IPC_ID, 0, NULL, 0);
|
||||||
FreePages((uintptr_t)IPCBuffer, PagesForIPCDataStruct);
|
FreePages((uintptr_t)IPCBuffer, PagesForIPCDataStruct);
|
||||||
|
|
||||||
|
PrintDbgNL("Calling entry point");
|
||||||
return ((int (*)(int, char *[], char *[]))Entry)(argc, argv, envp);
|
return ((int (*)(int, char *[], char *[]))Entry)(argc, argv, envp);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
void __attribute__((naked, used, no_stack_protector)) _ld_start()
|
void __attribute__((naked, used, no_stack_protector)) _start()
|
||||||
{
|
{
|
||||||
__asm__("movq $0, %rbp\n"
|
__asm__("movq $0, %rbp\n"
|
||||||
"pushq %rbp\n"
|
"pushq %rbp\n"
|
||||||
|
@ -22,6 +22,7 @@ extern "C"
|
|||||||
void *memcpy(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 *memset(void *dest, int c, size_t n);
|
||||||
void *memmove(void *dest, const void *src, size_t n);
|
void *memmove(void *dest, const void *src, size_t n);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,8 +1,17 @@
|
|||||||
#ifndef _SYS_TYPES_H
|
#ifndef _SYS_TYPES_H
|
||||||
#define _SYS_TYPES_H
|
#define _SYS_TYPES_H
|
||||||
|
|
||||||
|
#ifndef PUBLIC
|
||||||
|
#define PUBLIC __attribute__((visibility("default")))
|
||||||
|
#endif // !PUBLIC
|
||||||
|
|
||||||
|
#ifndef PRIVATE
|
||||||
|
#define PRIVATE __attribute__((visibility("hidden")))
|
||||||
|
#endif // !PRIVATE
|
||||||
|
|
||||||
typedef int __pid_t;
|
typedef int __pid_t;
|
||||||
typedef unsigned int __id_t;
|
typedef unsigned int __id_t;
|
||||||
|
typedef unsigned int __useconds_t;
|
||||||
|
|
||||||
#ifndef __pid_t_defined
|
#ifndef __pid_t_defined
|
||||||
typedef __pid_t pid_t;
|
typedef __pid_t pid_t;
|
||||||
@ -14,4 +23,9 @@ typedef __id_t id_t;
|
|||||||
#define __id_t_defined
|
#define __id_t_defined
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef __useconds_t_defined
|
||||||
|
typedef __useconds_t useconds_t;
|
||||||
|
#define __useconds_t_defined
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -195,4 +195,12 @@ typedef __SIZE_TYPE__ size_t;
|
|||||||
#define b48(x) (((((x)&0x0000000000ff) << 40) | (((x)&0x00000000ff00) << 24) | (((x)&0x000000ff0000) << 8) | (((x)&0x0000ff000000) >> 8) | (((x)&0x00ff00000000) >> 24) | (((x)&0xff0000000000) >> 40)))
|
#define b48(x) (((((x)&0x0000000000ff) << 40) | (((x)&0x00000000ff00) << 24) | (((x)&0x000000ff0000) << 8) | (((x)&0x0000ff000000) >> 8) | (((x)&0x00ff00000000) >> 24) | (((x)&0xff0000000000) >> 40)))
|
||||||
#define b64(x) __builtin_bswap64(x)
|
#define b64(x) __builtin_bswap64(x)
|
||||||
|
|
||||||
|
#ifndef PUBLIC
|
||||||
|
#define PUBLIC __attribute__((visibility("default")))
|
||||||
|
#endif // !PUBLIC
|
||||||
|
|
||||||
|
#ifndef PRIVATE
|
||||||
|
#define PRIVATE __attribute__((visibility("hidden")))
|
||||||
|
#endif // !PRIVATE
|
||||||
|
|
||||||
#endif // !__FENNIX_LIBC_TYPES_H__
|
#endif // !__FENNIX_LIBC_TYPES_H__
|
||||||
|
@ -20,6 +20,9 @@ extern "C"
|
|||||||
|
|
||||||
pid_t fork(void);
|
pid_t fork(void);
|
||||||
|
|
||||||
|
unsigned int sleep(unsigned int seconds);
|
||||||
|
int usleep(useconds_t usec);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
# Config file
|
# Config file
|
||||||
include ../../../Makefile.conf
|
include ../../../Makefile.conf
|
||||||
|
|
||||||
CC = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc
|
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
||||||
AS = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as
|
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
||||||
NASM = /usr/bin/nasm
|
NASM = /usr/bin/nasm
|
||||||
|
|
||||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||||
|
@ -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
21
libc/runtime/crt0.c
Normal 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");
|
||||||
|
}
|
@ -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
21
libc/runtime/crt1.c
Normal 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");
|
||||||
|
}
|
@ -1,27 +1,25 @@
|
|||||||
WORKSPACE := ../../
|
|
||||||
|
|
||||||
# Config file
|
# Config file
|
||||||
include ../$(WORKSPACE)Makefile.conf
|
include ../../../Makefile.conf
|
||||||
|
|
||||||
NAME=c
|
NAME=c
|
||||||
|
|
||||||
OBJECT_NAME=lib$(NAME).a
|
ifeq ($(USERSPACE_STATIC_LIBS), 1)
|
||||||
|
OBJECT_NAME := lib$(NAME).a
|
||||||
|
else
|
||||||
|
OBJECT_NAME := lib$(NAME).so
|
||||||
|
endif
|
||||||
|
|
||||||
OUTPUT_DIR=$(WORKSPACE)out/lib/
|
OUTPUT_DIR=../../out/lib/
|
||||||
|
SYSROOT = --sysroot=../../out/
|
||||||
|
|
||||||
CC = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc
|
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
||||||
AS = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as
|
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
||||||
AR = ../$(WORKSPACE)$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ar
|
AR = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
|
||||||
NASM = /usr/bin/nasm
|
|
||||||
|
|
||||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||||
ASM_SOURCES = $(shell find ./ -type f -name '*.asm')
|
OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${S_SOURCES:.S=.o}
|
||||||
OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${ASM_SOURCES:.asm=.o} ${S_SOURCES:.S=.o}
|
|
||||||
|
|
||||||
INCLUDE = ../include
|
|
||||||
INCLUDE2 = $(WORKSPACE)out/usr/include
|
|
||||||
|
|
||||||
ifeq ($(OSARCH), amd64)
|
ifeq ($(OSARCH), amd64)
|
||||||
ASM_ARCH := elf64
|
ASM_ARCH := elf64
|
||||||
@ -29,19 +27,21 @@ else ifeq ($(OSARCH), i386)
|
|||||||
ASM_ARCH := elf32
|
ASM_ARCH := elf32
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS := -fPIC -I$(INCLUDE) -I$(INCLUDE2)
|
CFLAGS := -fvisibility=hidden -fPIC -I../include -I../../out/usr/include
|
||||||
|
|
||||||
ifeq ($(DEBUG), 1)
|
ifeq ($(DEBUG), 1)
|
||||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm
|
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm
|
||||||
# LDFLAGS += -ggdb3 -O0
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
build: $(OBJECT_NAME)
|
build: $(OBJECT_NAME)
|
||||||
|
|
||||||
$(OBJECT_NAME): $(OBJ)
|
$(OBJECT_NAME): $(OBJ)
|
||||||
$(info Linking $@)
|
$(info Linking $@)
|
||||||
# $(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,libc.so $(OBJ) -o $(OUTPUT_DIR)$@
|
ifeq ($(USERSPACE_STATIC_LIBS), 1)
|
||||||
$(AR) rcs $(OUTPUT_DIR)$@ $(OBJ)
|
$(AR) rcs $(OUTPUT_DIR)$@ $(OBJ)
|
||||||
|
else
|
||||||
|
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(OBJECT_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@
|
||||||
|
endif
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(info Compiling $<)
|
$(info Compiling $<)
|
||||||
@ -55,9 +55,5 @@ $(OBJECT_NAME): $(OBJ)
|
|||||||
$(info Compiling $<)
|
$(info Compiling $<)
|
||||||
$(AS) -c $< -o $@
|
$(AS) -c $< -o $@
|
||||||
|
|
||||||
%.o: %.asm
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(NASM) $< -f $(ASM_ARCH) -o $@
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJ)
|
rm -f $(OBJ)
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#include <sys/syscalls.h>
|
||||||
|
#include <sys/types.h> // For PUBLIC
|
||||||
|
|
||||||
extern void __libc_init_array(void);
|
extern void __libc_init_array(void);
|
||||||
extern void __libc_fini_array(void);
|
extern void __libc_fini_array(void);
|
||||||
@ -5,21 +7,17 @@ extern void __libc_fini_array(void);
|
|||||||
extern void __libc_init_std(void);
|
extern void __libc_init_std(void);
|
||||||
extern void __libc_fini_std(void);
|
extern void __libc_fini_std(void);
|
||||||
|
|
||||||
void __libc_init(void)
|
PUBLIC void __libc_init(void)
|
||||||
{
|
{
|
||||||
__libc_init_array();
|
__libc_init_array();
|
||||||
__libc_init_std();
|
__libc_init_std();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _exit(int Code)
|
PUBLIC void _exit(int Code)
|
||||||
{
|
{
|
||||||
__libc_fini_std();
|
__libc_fini_std();
|
||||||
__libc_fini_array();
|
__libc_fini_array();
|
||||||
__asm__ __volatile__("syscall"
|
syscall1(_Exit, (long)Code);
|
||||||
:
|
|
||||||
: "a"(0), "D"(Code)
|
|
||||||
: "rcx", "r11", "memory");
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
5
libc/src/main.c
Normal file
5
libc/src/main.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
/* TODO: Show a message or something */
|
||||||
|
int _start()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
@ -73,7 +73,7 @@ extern "C"
|
|||||||
// e.g. make them static so as not to clash with other objects also
|
// e.g. make them static so as not to clash with other objects also
|
||||||
// using them.
|
// using them.
|
||||||
#ifndef PRINTF_VISIBILITY
|
#ifndef PRINTF_VISIBILITY
|
||||||
#define PRINTF_VISIBILITY
|
#define PRINTF_VISIBILITY __attribute__((visibility("default")))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
int tolower(int c)
|
#include <sys/types.h> // For PUBLIC
|
||||||
|
|
||||||
|
PUBLIC int tolower(int c)
|
||||||
{
|
{
|
||||||
if (c >= 'A' && c <= 'Z')
|
if (c >= 'A' && c <= 'Z')
|
||||||
{
|
{
|
||||||
@ -11,7 +13,7 @@ int tolower(int c)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
int toupper(int c)
|
PUBLIC int toupper(int c)
|
||||||
{
|
{
|
||||||
if (c >= 'a' && c <= 'z')
|
if (c >= 'a' && c <= 'z')
|
||||||
{
|
{
|
||||||
@ -21,7 +23,7 @@ int toupper(int c)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
int isspace(int c)
|
PUBLIC int isspace(int c)
|
||||||
{
|
{
|
||||||
return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f' || c == '\v';
|
return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f' || c == '\v';
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <sys/types.h> // For PUBLIC
|
||||||
|
|
||||||
int __local_stub_errno = 0;
|
int __local_stub_errno = 0;
|
||||||
|
|
||||||
int *__errno_location(void)
|
PUBLIC int *__errno_location(void)
|
||||||
{
|
{
|
||||||
return &__local_stub_errno;
|
return &__local_stub_errno;
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,13 @@
|
|||||||
#include <sys/syscalls.h>
|
#include <sys/syscalls.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
FILE *stdin = NULL;
|
#include <sys/types.h> // For PUBLIC
|
||||||
FILE *stdout = NULL;
|
|
||||||
FILE *stderr = NULL;
|
|
||||||
|
|
||||||
FILE *fopen(const char *filename, const char *mode)
|
PUBLIC FILE *stdin = NULL;
|
||||||
|
PUBLIC FILE *stdout = NULL;
|
||||||
|
PUBLIC FILE *stderr = NULL;
|
||||||
|
|
||||||
|
PUBLIC FILE *fopen(const char *filename, const char *mode)
|
||||||
{
|
{
|
||||||
void *KPrivate = (void *)syscall2(_FileOpen, (uint64_t)filename, (uint64_t)mode);
|
void *KPrivate = (void *)syscall2(_FileOpen, (uint64_t)filename, (uint64_t)mode);
|
||||||
if (IsSyscallError(KPrivate))
|
if (IsSyscallError(KPrivate))
|
||||||
@ -19,7 +21,7 @@ FILE *fopen(const char *filename, const char *mode)
|
|||||||
return FilePtr;
|
return FilePtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
PUBLIC size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||||
{
|
{
|
||||||
if (ptr == NULL || stream == NULL || size == 0 || nmemb == 0)
|
if (ptr == NULL || stream == NULL || size == 0 || nmemb == 0)
|
||||||
{
|
{
|
||||||
@ -27,10 +29,11 @@ size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return syscall4(_FileRead, (uint64_t)stream->KernelPrivate, stream->_offset, (uint64_t)ptr, size * nmemb);
|
syscall3(_FileSeek, stream->KernelPrivate, stream->_offset, SEEK_SET);
|
||||||
|
return syscall3(_FileRead, (uint64_t)stream->KernelPrivate, (uint64_t)ptr, size * nmemb);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
|
PUBLIC size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||||
{
|
{
|
||||||
if (ptr == NULL || stream == NULL || size == 0 || nmemb == 0)
|
if (ptr == NULL || stream == NULL || size == 0 || nmemb == 0)
|
||||||
{
|
{
|
||||||
@ -38,10 +41,11 @@ size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return syscall4(_FileWrite, (uint64_t)stream->KernelPrivate, stream->_offset, (uint64_t)ptr, size * nmemb);
|
syscall3(_FileSeek, stream->KernelPrivate, stream->_offset, SEEK_SET);
|
||||||
|
return syscall3(_FileWrite, (uint64_t)stream->KernelPrivate, (uint64_t)ptr, size * nmemb);
|
||||||
}
|
}
|
||||||
|
|
||||||
int fclose(FILE *fp)
|
PUBLIC int fclose(FILE *fp)
|
||||||
{
|
{
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
{
|
{
|
||||||
@ -54,7 +58,7 @@ int fclose(FILE *fp)
|
|||||||
return syscall1(_FileClose, (uint64_t)KP);
|
return syscall1(_FileClose, (uint64_t)KP);
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t fseek(FILE *stream, long offset, int whence)
|
PUBLIC off_t fseek(FILE *stream, off_t offset, int whence)
|
||||||
{
|
{
|
||||||
if (stream == NULL || whence < 0 || whence > 2)
|
if (stream == NULL || whence < 0 || whence > 2)
|
||||||
{
|
{
|
||||||
@ -69,12 +73,12 @@ off_t fseek(FILE *stream, long offset, int whence)
|
|||||||
return new_offset;
|
return new_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
long ftell(FILE *stream)
|
PUBLIC long ftell(FILE *stream)
|
||||||
{
|
{
|
||||||
return stream->_offset;
|
return stream->_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fflush(FILE *stream)
|
PUBLIC int fflush(FILE *stream)
|
||||||
{
|
{
|
||||||
if (stream == NULL)
|
if (stream == NULL)
|
||||||
{
|
{
|
||||||
@ -86,7 +90,7 @@ int fflush(FILE *stream)
|
|||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fprintf(FILE *stream, const char *format, ...)
|
PUBLIC int fprintf(FILE *stream, const char *format, ...)
|
||||||
{
|
{
|
||||||
if (stream == NULL || format == NULL)
|
if (stream == NULL || format == NULL)
|
||||||
{
|
{
|
||||||
@ -101,20 +105,20 @@ int fprintf(FILE *stream, const char *format, ...)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setbuf(FILE *stream, char *buf)
|
PUBLIC void setbuf(FILE *stream, char *buf)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int vfprintf(FILE *stream, const char *format, va_list arg)
|
PUBLIC int vfprintf(FILE *stream, const char *format, va_list arg)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vsscanf(const char *s, const char *format, va_list arg)
|
PUBLIC int vsscanf(const char *s, const char *format, va_list arg)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int sscanf(const char *s, const char *format, ...)
|
PUBLIC int sscanf(const char *s, const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <sys/syscalls.h>
|
#include <sys/syscalls.h>
|
||||||
|
|
||||||
int fputc(int c, FILE *stream)
|
#include <sys/types.h> // For PUBLIC
|
||||||
|
|
||||||
|
PUBLIC int fputc(int c, FILE *stream)
|
||||||
{
|
{
|
||||||
// FIXME
|
// FIXME
|
||||||
// if (stream == NULL)
|
// if (stream == NULL)
|
||||||
@ -14,19 +16,19 @@ int fputc(int c, FILE *stream)
|
|||||||
return syscall2(_Print, c, 0);
|
return syscall2(_Print, c, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int putc(int c, FILE *stream) { return fputc(c, stream); }
|
PUBLIC int putc(int c, FILE *stream) { return fputc(c, stream); }
|
||||||
|
|
||||||
int fputs(const char *s, FILE *stream)
|
PUBLIC int fputs(const char *s, FILE *stream)
|
||||||
{
|
{
|
||||||
for (int i = 0; s[i] != '\0'; i++)
|
for (int i = 0; s[i] != '\0'; i++)
|
||||||
fputc(s[i], stream);
|
fputc(s[i], stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
int puts(const char *s)
|
PUBLIC int puts(const char *s)
|
||||||
{
|
{
|
||||||
for (int i = 0; s[i] != '\0'; i++)
|
for (int i = 0; s[i] != '\0'; i++)
|
||||||
fputc(s[i], stdout);
|
fputc(s[i], stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
int putchar(int c) { return fputc(c, stdout); }
|
PUBLIC int putchar(int c) { return fputc(c, stdout); }
|
||||||
void perror(const char *s) { fputs(s, stderr); }
|
PUBLIC void perror(const char *s) { fputs(s, stderr); }
|
||||||
|
@ -2,30 +2,28 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <sys/syscalls.h>
|
||||||
|
|
||||||
#include "../mem/liballoc_1_1.h"
|
#include "../mem/liballoc_1_1.h"
|
||||||
|
|
||||||
void abort(void)
|
PUBLIC void abort(void)
|
||||||
{
|
{
|
||||||
__asm__ __volatile__("syscall"
|
syscall1(_Exit, -0xAB057);
|
||||||
:
|
|
||||||
: "a"(0), "D"(-0xAB057)
|
|
||||||
: "rcx", "r11", "memory");
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
int atexit(void (*function)(void))
|
PUBLIC int atexit(void (*function)(void))
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void exit(int status)
|
PUBLIC void exit(int status)
|
||||||
{
|
{
|
||||||
_exit(status);
|
_exit(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int atoi(const char *nptr)
|
PUBLIC int atoi(const char *nptr)
|
||||||
{
|
{
|
||||||
uint64_t Length = strlen((char *)nptr);
|
uint64_t Length = strlen((char *)nptr);
|
||||||
if (nptr)
|
if (nptr)
|
||||||
@ -41,9 +39,9 @@ int atoi(const char *nptr)
|
|||||||
return OutBuffer;
|
return OutBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
char **environ = NULL;
|
PUBLIC char **environ = NULL;
|
||||||
|
|
||||||
char *getenv(const char *name)
|
PUBLIC char *getenv(const char *name)
|
||||||
{
|
{
|
||||||
char **env = environ;
|
char **env = environ;
|
||||||
if (env == NULL)
|
if (env == NULL)
|
||||||
@ -57,21 +55,21 @@ char *getenv(const char *name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *malloc(size_t Size) { return PREFIX(malloc)(Size); }
|
PUBLIC void *malloc(size_t Size) { return PREFIX(malloc)(Size); }
|
||||||
void *realloc(void *Address, size_t Size) { return PREFIX(realloc)(Address, Size); }
|
PUBLIC void *realloc(void *Address, size_t Size) { return PREFIX(realloc)(Address, Size); }
|
||||||
void *calloc(size_t Count, size_t Size) { return PREFIX(calloc)(Count, Size); }
|
PUBLIC void *calloc(size_t Count, size_t Size) { return PREFIX(calloc)(Count, Size); }
|
||||||
void free(void *Address)
|
PUBLIC void free(void *Address)
|
||||||
{
|
{
|
||||||
PREFIX(free)
|
PREFIX(free)
|
||||||
(Address);
|
(Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
int system(const char *command)
|
PUBLIC int system(const char *command)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
double atof(const char *nptr)
|
PUBLIC double atof(const char *nptr)
|
||||||
{
|
{
|
||||||
// FIXME: This is a very bad implementation of atof.
|
// FIXME: This is a very bad implementation of atof.
|
||||||
uint64_t Length = strlen((char *)nptr);
|
uint64_t Length = strlen((char *)nptr);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <sys/types.h> // For PUBLIC
|
||||||
|
|
||||||
/* Some of the functions are from musl library */
|
/* Some of the functions are from musl library */
|
||||||
/* https://www.musl-libc.org/ */
|
/* https://www.musl-libc.org/ */
|
||||||
/*
|
/*
|
||||||
@ -25,7 +27,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|||||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void *memcpy(void *dest, const void *src, size_t n)
|
PUBLIC void *memcpy(void *dest, const void *src, size_t n)
|
||||||
{
|
{
|
||||||
unsigned char *d = dest;
|
unsigned char *d = dest;
|
||||||
const unsigned char *s = src;
|
const unsigned char *s = src;
|
||||||
@ -204,7 +206,7 @@ void *memcpy(void *dest, const void *src, size_t n)
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *memset(void *dest, int c, size_t n)
|
PUBLIC void *memset(void *dest, int c, size_t n)
|
||||||
{
|
{
|
||||||
unsigned char *s = dest;
|
unsigned char *s = dest;
|
||||||
size_t k;
|
size_t k;
|
||||||
@ -285,7 +287,7 @@ void *memset(void *dest, int c, size_t n)
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *memmove(void *dest, const void *src, size_t n)
|
PUBLIC void *memmove(void *dest, const void *src, size_t n)
|
||||||
{
|
{
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
typedef __attribute__((__may_alias__)) size_t WT;
|
typedef __attribute__((__may_alias__)) size_t WT;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "../../mem/liballoc_1_1.h"
|
#include "../../mem/liballoc_1_1.h"
|
||||||
|
|
||||||
size_t strlen(const char *str)
|
PUBLIC size_t strlen(const char *str)
|
||||||
{
|
{
|
||||||
long unsigned i = 0;
|
long unsigned i = 0;
|
||||||
if (str)
|
if (str)
|
||||||
@ -11,14 +11,14 @@ size_t strlen(const char *str)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int strcmp(const char *l, const char *r)
|
PUBLIC int strcmp(const char *l, const char *r)
|
||||||
{
|
{
|
||||||
for (; *l == *r && *l; l++, r++)
|
for (; *l == *r && *l; l++, r++)
|
||||||
;
|
;
|
||||||
return *(unsigned char *)l - *(unsigned char *)r;
|
return *(unsigned char *)l - *(unsigned char *)r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int strncmp(const char *s1, const char *s2, size_t n)
|
PUBLIC int strncmp(const char *s1, const char *s2, size_t n)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < n; i++)
|
for (size_t i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
@ -31,7 +31,7 @@ int strncmp(const char *s1, const char *s2, size_t n)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int strcasecmp(const char *s1, const char *s2)
|
PUBLIC int strcasecmp(const char *s1, const char *s2)
|
||||||
{
|
{
|
||||||
const unsigned char *p1 = (const unsigned char *)s1;
|
const unsigned char *p1 = (const unsigned char *)s1;
|
||||||
const unsigned char *p2 = (const unsigned char *)s2;
|
const unsigned char *p2 = (const unsigned char *)s2;
|
||||||
@ -44,7 +44,7 @@ int strcasecmp(const char *s1, const char *s2)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int strncasecmp(const char *string1, const char *string2, size_t count)
|
PUBLIC int strncasecmp(const char *string1, const char *string2, size_t count)
|
||||||
{
|
{
|
||||||
if (count)
|
if (count)
|
||||||
{
|
{
|
||||||
@ -61,7 +61,7 @@ int strncasecmp(const char *string1, const char *string2, size_t count)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strstr(const char *haystack, const char *needle)
|
PUBLIC char *strstr(const char *haystack, const char *needle)
|
||||||
{
|
{
|
||||||
const char *a = haystack, *b = needle;
|
const char *a = haystack, *b = needle;
|
||||||
while (1)
|
while (1)
|
||||||
@ -78,7 +78,7 @@ char *strstr(const char *haystack, const char *needle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strncpy(char *destination, const char *source, unsigned long num)
|
PUBLIC char *strncpy(char *destination, const char *source, unsigned long num)
|
||||||
{
|
{
|
||||||
if (destination == NULL)
|
if (destination == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -93,14 +93,14 @@ char *strncpy(char *destination, const char *source, unsigned long num)
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strdup(const char *s)
|
PUBLIC char *strdup(const char *s)
|
||||||
{
|
{
|
||||||
char *buf = (char *)__malloc(strlen((char *)s) + 1);
|
char *buf = (char *)__malloc(strlen((char *)s) + 1);
|
||||||
strncpy(buf, s, strlen(s) + 1);
|
strncpy(buf, s, strlen(s) + 1);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strchr(char const *s, int c)
|
PUBLIC char *strchr(char const *s, int c)
|
||||||
{
|
{
|
||||||
size_t len = strlen(s);
|
size_t len = strlen(s);
|
||||||
for (size_t i = 0; i < len; i++)
|
for (size_t i = 0; i < len; i++)
|
||||||
@ -110,7 +110,7 @@ char *strchr(char const *s, int c)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strrchr(char const *s, int c)
|
PUBLIC char *strrchr(char const *s, int c)
|
||||||
{
|
{
|
||||||
size_t len = strlen(s);
|
size_t len = strlen(s);
|
||||||
size_t pos = len;
|
size_t pos = len;
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
pid_t wait(int *wstatus)
|
PUBLIC pid_t wait(int *wstatus)
|
||||||
{
|
{
|
||||||
return waitpid(-1, &wstatus, 0);
|
return waitpid(-1, &wstatus, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_t waitpid(pid_t pid, int *wstatus, int options)
|
PUBLIC pid_t waitpid(pid_t pid, int *wstatus, int options)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options)
|
PUBLIC int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
int mkdir(const char *path, mode_t mode)
|
#include <sys/types.h> // For PUBLIC
|
||||||
|
|
||||||
|
PUBLIC int mkdir(const char *path, mode_t mode)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int remove(const char *pathname)
|
PUBLIC int remove(const char *pathname)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rename(const char *oldpath, const char *newpath)
|
PUBLIC int rename(const char *oldpath, const char *newpath)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -3,49 +3,49 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "../../../Kernel/syscalls.h"
|
#include "../../../Kernel/syscalls.h"
|
||||||
|
|
||||||
int execl(const char *pathname, const char *arg, ...)
|
PUBLIC int execl(const char *pathname, const char *arg, ...)
|
||||||
{
|
{
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int execlp(const char *file, const char *arg, ...)
|
PUBLIC int execlp(const char *file, const char *arg, ...)
|
||||||
{
|
{
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int execle(const char *pathname, const char *arg, ...)
|
PUBLIC int execle(const char *pathname, const char *arg, ...)
|
||||||
{
|
{
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int execv(const char *pathname, char *const argv[])
|
PUBLIC int execv(const char *pathname, char *const argv[])
|
||||||
{
|
{
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int execvp(const char *file, char *const argv[])
|
PUBLIC int execvp(const char *file, char *const argv[])
|
||||||
{
|
{
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int execvpe(const char *file, char *const argv[], char *const envp[])
|
PUBLIC int execvpe(const char *file, char *const argv[], char *const envp[])
|
||||||
{
|
{
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int execve(const char *pathname, char *const argv[], char *const envp[])
|
PUBLIC int execve(const char *pathname, char *const argv[], char *const envp[])
|
||||||
{
|
{
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_t fork(void)
|
PUBLIC pid_t fork(void)
|
||||||
{
|
{
|
||||||
return syscall0(_Fork);
|
return syscall0(_Fork);
|
||||||
}
|
}
|
||||||
|
14
libc/src/std/uni/sleep.c
Normal file
14
libc/src/std/uni/sleep.c
Normal 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);
|
||||||
|
}
|
@ -4,13 +4,13 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
__attribute__((visibility("hidden"))) int printf_libinit(const char *format, ...);
|
int printf_libinit(const char *format, ...);
|
||||||
__attribute__((visibility("hidden"))) int vprintf_libinit(const char *format, va_list arg);
|
int vprintf_libinit(const char *format, va_list arg);
|
||||||
__attribute__((visibility("hidden"))) int sprintf_libinit(char *s, const char *format, ...);
|
int sprintf_libinit(char *s, const char *format, ...);
|
||||||
__attribute__((visibility("hidden"))) int vsprintf_libinit(char *s, const char *format, va_list arg);
|
int vsprintf_libinit(char *s, const char *format, va_list arg);
|
||||||
__attribute__((visibility("hidden"))) int snprintf_libinit(char *s, size_t count, const char *format, ...);
|
int snprintf_libinit(char *s, size_t count, const char *format, ...);
|
||||||
__attribute__((visibility("hidden"))) int vsnprintf_libinit(char *s, size_t count, const char *format, va_list arg);
|
int vsnprintf_libinit(char *s, size_t count, const char *format, va_list arg);
|
||||||
|
|
||||||
void init_log(const char *fmt, ...);
|
__attribute__((visibility("default"))) void init_log(const char *fmt, ...);
|
||||||
|
|
||||||
#endif // !__FENNIX_LIBS_INIT_H__
|
#endif // !__FENNIX_LIBS_INIT_H__
|
||||||
|
@ -3,49 +3,6 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
enum KCtl
|
|
||||||
{
|
|
||||||
KCTL_NULL,
|
|
||||||
|
|
||||||
KCTL_GET_PID,
|
|
||||||
KCTL_GET_TID,
|
|
||||||
KCTL_GET_UID,
|
|
||||||
KCTL_GET_GID,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the page size
|
|
||||||
*/
|
|
||||||
KCTL_GET_PAGE_SIZE,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check whether the current thread is critical
|
|
||||||
*/
|
|
||||||
KCTL_IS_CRITICAL,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Register an ELF library
|
|
||||||
* @fn int RegisterELFLib(char *Identifier, char *Path)
|
|
||||||
*/
|
|
||||||
KCTL_REGISTER_ELF_LIB,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get an ELF library
|
|
||||||
* @fn uintptr_t GetELFLib(char *Identifier);
|
|
||||||
*/
|
|
||||||
KCTL_GET_ELF_LIB_FILE,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get an ELF library
|
|
||||||
* @fn uintptr_t GetELFLib(char *Identifier);
|
|
||||||
*/
|
|
||||||
KCTL_GET_ELF_LIB_MEMORY_IMAGE,
|
|
||||||
|
|
||||||
KCTL_GET_FRAMEBUFFER_BUFFER,
|
|
||||||
KCTL_GET_FRAMEBUFFER_WIDTH,
|
|
||||||
KCTL_GET_FRAMEBUFFER_HEIGHT,
|
|
||||||
KCTL_GET_FRAMEBUFFER_SIZE,
|
|
||||||
};
|
|
||||||
|
|
||||||
long DoCtl(uint64_t Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4);
|
long DoCtl(uint64_t Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4);
|
||||||
|
|
||||||
uintptr_t KrnlRequestPages(size_t Count);
|
uintptr_t KrnlRequestPages(size_t Count);
|
||||||
|
@ -7,7 +7,7 @@ OBJECT_NAME=lib$(NAME).a
|
|||||||
|
|
||||||
OUTPUT_DIR=../../out/lib/
|
OUTPUT_DIR=../../out/lib/
|
||||||
|
|
||||||
CC = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc
|
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
||||||
|
|
||||||
CRTBEGIN_PATH = $(shell $(CC) -print-file-name=libgcc.a)
|
CRTBEGIN_PATH = $(shell $(CC) -print-file-name=libgcc.a)
|
||||||
|
|
||||||
|
@ -3,23 +3,23 @@ include ../../../Makefile.conf
|
|||||||
|
|
||||||
NAME=init
|
NAME=init
|
||||||
|
|
||||||
OBJECT_NAME=lib$(NAME).so
|
ifeq ($(USERSPACE_STATIC_LIBS), 1)
|
||||||
SO_NAME=$(OBJECT_NAME)
|
OBJECT_NAME := lib$(NAME).a
|
||||||
|
else
|
||||||
|
OBJECT_NAME := lib$(NAME).so
|
||||||
|
endif
|
||||||
|
|
||||||
OUTPUT_DIR=../../out/lib/
|
OUTPUT_DIR=../../out/lib/
|
||||||
SYSROOT = --sysroot=../../out/
|
SYSROOT = --sysroot=../../out/
|
||||||
|
|
||||||
CC = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc
|
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
||||||
AS = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as
|
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
||||||
AR = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ar
|
AR = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
|
||||||
OBJDUMP = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump
|
|
||||||
NASM = /usr/bin/nasm
|
|
||||||
|
|
||||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||||
ASM_SOURCES = $(shell find ./ -type f -name '*.asm')
|
OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${S_SOURCES:.S=.o}
|
||||||
OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${ASM_SOURCES:.asm=.o} ${S_SOURCES:.S=.o}
|
|
||||||
|
|
||||||
ifeq ($(OSARCH), amd64)
|
ifeq ($(OSARCH), amd64)
|
||||||
ASM_ARCH := elf64
|
ASM_ARCH := elf64
|
||||||
@ -27,16 +27,21 @@ else ifeq ($(OSARCH), i386)
|
|||||||
ASM_ARCH := elf32
|
ASM_ARCH := elf32
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SIMD_FLAGS := -mno-sse -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4.1 -mno-sse4.2 -mno-sse4 -mno-avx -mno-avx2 -mno-avx512f
|
CFLAGS := -fvisibility=hidden -fPIC -fPIE -I../include -I../../libc/include
|
||||||
|
|
||||||
CFLAGS := -fPIC -fPIE -I../include -I../../libc/include $(SIMD_FLAGS)
|
ifeq ($(DEBUG), 1)
|
||||||
|
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm
|
||||||
|
endif
|
||||||
|
|
||||||
build: $(OBJECT_NAME)
|
build: $(OBJECT_NAME)
|
||||||
|
|
||||||
$(OBJECT_NAME): $(OBJ)
|
$(OBJECT_NAME): $(OBJ)
|
||||||
$(info Linking $@)
|
$(info Linking $@)
|
||||||
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(SO_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@
|
ifeq ($(USERSPACE_STATIC_LIBS), 1)
|
||||||
$(OBJDUMP) -d $(OUTPUT_DIR)$@ > file_dump.map
|
$(AR) rcs $(OUTPUT_DIR)$@ $(OBJ)
|
||||||
|
else
|
||||||
|
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(OBJECT_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@
|
||||||
|
endif
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(info Compiling $<)
|
$(info Compiling $<)
|
||||||
@ -50,9 +55,5 @@ $(OBJECT_NAME): $(OBJ)
|
|||||||
$(info Compiling $<)
|
$(info Compiling $<)
|
||||||
$(AS) -c $< -o $@
|
$(AS) -c $< -o $@
|
||||||
|
|
||||||
%.o: %.asm
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(NASM) $< -f $(ASM_ARCH) -o $@
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f file_dump.map $(OBJ)
|
rm -f $(OBJ)
|
||||||
|
@ -1,13 +1,22 @@
|
|||||||
#include <libinit/init.h>
|
#include <libinit/init.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
|
|
||||||
void init_log(const char *fmt, ...)
|
void init_log(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
static short log_lock = 0;
|
||||||
|
while (log_lock)
|
||||||
|
usleep(1);
|
||||||
|
__sync_synchronize();
|
||||||
|
log_lock = 1;
|
||||||
|
|
||||||
printf_libinit("\eCCCCCC[\e0088FFinit\eCCCCCC] \eAAAAAA");
|
printf_libinit("\eCCCCCC[\e0088FFinit\eCCCCCC] \eAAAAAA");
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
vprintf_libinit(fmt, args);
|
vprintf_libinit(fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
printf_libinit("\eCCCCCC");
|
printf_libinit("\eCCCCCC");
|
||||||
|
|
||||||
|
log_lock = 0;
|
||||||
|
__sync_synchronize();
|
||||||
}
|
}
|
||||||
|
@ -3,18 +3,23 @@ include ../../../Makefile.conf
|
|||||||
|
|
||||||
NAME=ssp
|
NAME=ssp
|
||||||
|
|
||||||
OBJECT_NAME=lib$(NAME).a
|
ifeq ($(USERSPACE_STATIC_LIBS), 1)
|
||||||
|
OBJECT_NAME := lib$(NAME).a
|
||||||
|
else
|
||||||
|
OBJECT_NAME := lib$(NAME).so
|
||||||
|
endif
|
||||||
|
|
||||||
OUTPUT_DIR=../../out/lib/
|
OUTPUT_DIR=../../out/lib/
|
||||||
|
SYSROOT = --sysroot=../../out/
|
||||||
|
|
||||||
CC = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc
|
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
||||||
AR = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ar
|
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
||||||
OBJDUMP = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump
|
AR = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
|
||||||
NASM = /usr/bin/nasm
|
|
||||||
|
|
||||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||||
ASM_SOURCES = $(shell find ./ -type f -name '*.asm')
|
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||||
OBJ = ${C_SOURCES:.c=.o} ${ASM_SOURCES:.asm=.o}
|
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||||
|
OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${S_SOURCES:.S=.o}
|
||||||
|
|
||||||
ifeq ($(OSARCH), amd64)
|
ifeq ($(OSARCH), amd64)
|
||||||
ASM_ARCH := elf64
|
ASM_ARCH := elf64
|
||||||
@ -22,14 +27,21 @@ else ifeq ($(OSARCH), i386)
|
|||||||
ASM_ARCH := elf32
|
ASM_ARCH := elf32
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS := -fPIC -I../include -I../../libc/include
|
CFLAGS := -fvisibility=hidden -fPIC -I../include -I../../libc/include
|
||||||
|
|
||||||
|
ifeq ($(DEBUG), 1)
|
||||||
|
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm
|
||||||
|
endif
|
||||||
|
|
||||||
build: $(OBJECT_NAME)
|
build: $(OBJECT_NAME)
|
||||||
|
|
||||||
$(OBJECT_NAME): $(OBJ)
|
$(OBJECT_NAME): $(OBJ)
|
||||||
$(info Linking $@)
|
$(info Linking $@)
|
||||||
|
ifeq ($(USERSPACE_STATIC_LIBS), 1)
|
||||||
$(AR) rcs $(OUTPUT_DIR)$@ $(OBJ)
|
$(AR) rcs $(OUTPUT_DIR)$@ $(OBJ)
|
||||||
$(OBJDUMP) -d $(OUTPUT_DIR)$@ > file_dump.map
|
else
|
||||||
|
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(OBJECT_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@
|
||||||
|
endif
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(info Compiling $<)
|
$(info Compiling $<)
|
||||||
@ -39,9 +51,9 @@ $(OBJECT_NAME): $(OBJ)
|
|||||||
$(info Compiling $<)
|
$(info Compiling $<)
|
||||||
$(CC) $(CFLAGS) -std=c++20 -c $< -o $@
|
$(CC) $(CFLAGS) -std=c++20 -c $< -o $@
|
||||||
|
|
||||||
%.o: %.asm
|
%.o: %.S
|
||||||
$(info Compiling $<)
|
$(info Compiling $<)
|
||||||
$(NASM) $< -f $(ASM_ARCH) -o $@
|
$(AS) -c $< -o $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f file_dump.map $(OBJ)
|
rm -f $(OBJ)
|
||||||
|
@ -6,7 +6,16 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__UINTPTR_TYPE__ __stack_chk_guard = 0;
|
|
||||||
|
#ifndef PUBLIC
|
||||||
|
#define PUBLIC __attribute__((visibility("default")))
|
||||||
|
#endif // !PUBLIC
|
||||||
|
|
||||||
|
#ifndef PRIVATE
|
||||||
|
#define PRIVATE __attribute__((visibility("hidden")))
|
||||||
|
#endif // !PRIVATE
|
||||||
|
|
||||||
|
PUBLIC __UINTPTR_TYPE__ __stack_chk_guard = 0;
|
||||||
|
|
||||||
static void __attribute__((constructor, no_stack_protector)) __guard_setup(void)
|
static void __attribute__((constructor, no_stack_protector)) __guard_setup(void)
|
||||||
{
|
{
|
||||||
@ -14,7 +23,7 @@ static void __attribute__((constructor, no_stack_protector)) __guard_setup(void)
|
|||||||
__stack_chk_guard = STACK_CHK_GUARD_VALUE;
|
__stack_chk_guard = STACK_CHK_GUARD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((weak, noreturn, no_stack_protector)) void __stack_chk_fail(void)
|
PUBLIC __attribute__((weak, noreturn, no_stack_protector)) void __stack_chk_fail(void)
|
||||||
{
|
{
|
||||||
const char *msg = "Stack smashing detected";
|
const char *msg = "Stack smashing detected";
|
||||||
__asm__ __volatile__("syscall"
|
__asm__ __volatile__("syscall"
|
||||||
@ -24,7 +33,7 @@ __attribute__((weak, noreturn, no_stack_protector)) void __stack_chk_fail(void)
|
|||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((weak, noreturn, no_stack_protector)) void __chk_fail(void)
|
PUBLIC __attribute__((weak, noreturn, no_stack_protector)) void __chk_fail(void)
|
||||||
{
|
{
|
||||||
const char *msg = "Buffer overflow detected";
|
const char *msg = "Buffer overflow detected";
|
||||||
__asm__ __volatile__("syscall"
|
__asm__ __volatile__("syscall"
|
||||||
|
@ -3,23 +3,23 @@ include ../../../Makefile.conf
|
|||||||
|
|
||||||
NAME=sys
|
NAME=sys
|
||||||
|
|
||||||
OBJECT_NAME=lib$(NAME).so
|
ifeq ($(USERSPACE_STATIC_LIBS), 1)
|
||||||
SO_NAME=$(OBJECT_NAME)
|
OBJECT_NAME := lib$(NAME).a
|
||||||
|
else
|
||||||
|
OBJECT_NAME := lib$(NAME).so
|
||||||
|
endif
|
||||||
|
|
||||||
OUTPUT_DIR=../../out/lib/
|
OUTPUT_DIR=../../out/lib/
|
||||||
SYSROOT = --sysroot=../../out/
|
SYSROOT = --sysroot=../../out/
|
||||||
|
|
||||||
CC = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)gcc
|
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
||||||
AS = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)as
|
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
||||||
AR = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)ar
|
AR = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
|
||||||
OBJDUMP = ../../../$(TC_COMPILER_PATH)/$(TC_COMPILER_ARCH)objdump
|
|
||||||
NASM = /usr/bin/nasm
|
|
||||||
|
|
||||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||||
ASM_SOURCES = $(shell find ./ -type f -name '*.asm')
|
OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${S_SOURCES:.S=.o}
|
||||||
OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${ASM_SOURCES:.asm=.o} ${S_SOURCES:.S=.o}
|
|
||||||
|
|
||||||
ifeq ($(OSARCH), amd64)
|
ifeq ($(OSARCH), amd64)
|
||||||
ASM_ARCH := elf64
|
ASM_ARCH := elf64
|
||||||
@ -27,16 +27,21 @@ else ifeq ($(OSARCH), i386)
|
|||||||
ASM_ARCH := elf32
|
ASM_ARCH := elf32
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SIMD_FLAGS := -mno-sse -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4.1 -mno-sse4.2 -mno-sse4 -mno-avx -mno-avx2 -mno-avx512f
|
CFLAGS := -fvisibility=hidden -fPIC -I../include -I../../libc/include
|
||||||
|
|
||||||
CFLAGS := -fPIC -fPIE -I../include -I../../libc/include $(SIMD_FLAGS)
|
ifeq ($(DEBUG), 1)
|
||||||
|
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fverbose-asm
|
||||||
|
endif
|
||||||
|
|
||||||
build: $(OBJECT_NAME)
|
build: $(OBJECT_NAME)
|
||||||
|
|
||||||
$(OBJECT_NAME): $(OBJ)
|
$(OBJECT_NAME): $(OBJ)
|
||||||
$(info Linking $@)
|
$(info Linking $@)
|
||||||
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(SO_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@
|
ifeq ($(USERSPACE_STATIC_LIBS), 1)
|
||||||
$(OBJDUMP) -d $(OUTPUT_DIR)$@ > file_dump.map
|
$(AR) rcs $(OUTPUT_DIR)$@ $(OBJ)
|
||||||
|
else
|
||||||
|
$(CC) -nostdlib -shared -fPIC -fPIE -Wl,-soname,$(OBJECT_NAME) $(SYSROOT) $(OBJ) -o $(OUTPUT_DIR)$@
|
||||||
|
endif
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(info Compiling $<)
|
$(info Compiling $<)
|
||||||
@ -50,9 +55,5 @@ $(OBJECT_NAME): $(OBJ)
|
|||||||
$(info Compiling $<)
|
$(info Compiling $<)
|
||||||
$(AS) -c $< -o $@
|
$(AS) -c $< -o $@
|
||||||
|
|
||||||
%.o: %.asm
|
|
||||||
$(info Compiling $<)
|
|
||||||
$(NASM) $< -f $(ASM_ARCH) -o $@
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f file_dump.map $(OBJ)
|
rm -f $(OBJ)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user