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