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

@ -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
View File

@ -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",

View File

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

View File

@ -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

View File

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

View File

@ -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
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

@ -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);
} }

View File

@ -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"

View File

@ -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

View File

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

View File

@ -195,4 +195,12 @@ typedef __SIZE_TYPE__ size_t;
#define b48(x) (((((x)&0x0000000000ff) << 40) | (((x)&0x00000000ff00) << 24) | (((x)&0x000000ff0000) << 8) | (((x)&0x0000ff000000) >> 8) | (((x)&0x00ff00000000) >> 24) | (((x)&0xff0000000000) >> 40))) #define b48(x) (((((x)&0x0000000000ff) << 40) | (((x)&0x00000000ff00) << 24) | (((x)&0x000000ff0000) << 8) | (((x)&0x0000ff000000) >> 8) | (((x)&0x00ff00000000) >> 24) | (((x)&0xff0000000000) >> 40)))
#define b64(x) __builtin_bswap64(x) #define b64(x) __builtin_bswap64(x)
#ifndef PUBLIC
#define PUBLIC __attribute__((visibility("default")))
#endif // !PUBLIC
#ifndef PRIVATE
#define PRIVATE __attribute__((visibility("hidden")))
#endif // !PRIVATE
#endif // !__FENNIX_LIBC_TYPES_H__ #endif // !__FENNIX_LIBC_TYPES_H__

View File

@ -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

View File

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

View File

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

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

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

View File

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

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

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

@ -4,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);

View File

@ -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); }

View File

@ -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);

View File

@ -1,5 +1,7 @@
#include <stddef.h> #include <stddef.h>
#include <sys/types.h> // For PUBLIC
/* Some of the functions are from musl library */ /* Some of the functions are from musl library */
/* https://www.musl-libc.org/ */ /* https://www.musl-libc.org/ */
/* /*
@ -25,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;

View File

@ -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;

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,13 +1,22 @@
#include <libinit/init.h> #include <libinit/init.h>
#include <unistd.h>
#include "printf.h" #include "printf.h"
void init_log(const char *fmt, ...) void init_log(const char *fmt, ...)
{ {
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();
} }

View File

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

View File

@ -6,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"

View File

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