mirror of
https://github.com/Fennix-Project/Userspace.git
synced 2025-07-10 22:59:22 +00:00
Update userspace
This commit is contained in:
@ -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)
|
||||
|
||||
|
@ -18,42 +18,42 @@ typedef __INT64_TYPE__ Elf64_Sxword;
|
||||
|
||||
enum SectionHeaderType
|
||||
{
|
||||
SHT_NULL = 0,
|
||||
SHT_PROGBITS = 1,
|
||||
SHT_SYMTAB = 2,
|
||||
SHT_STRTAB = 3,
|
||||
SHT_RELA = 4,
|
||||
SHT_HASH = 5,
|
||||
SHT_DYNAMIC = 6,
|
||||
SHT_NOTE = 7,
|
||||
SHT_NOBITS = 8,
|
||||
SHT_REL = 9,
|
||||
SHT_SHLIB = 10,
|
||||
SHT_DYNSYM = 11,
|
||||
SHT_INIT_ARRAY = 14,
|
||||
SHT_FINI_ARRAY = 15,
|
||||
SHT_PREINIT_ARRAY = 16,
|
||||
SHT_GROUP = 17,
|
||||
SHT_SYMTAB_SHNDX = 18,
|
||||
SHT_NUM = 19,
|
||||
SHT_LOOS = 0x60000000,
|
||||
SHT_GNU_ATTRIBUTES = 0x6ffffff5,
|
||||
SHT_GNU_HASH = 0x6ffffff6,
|
||||
SHT_GNU_LIBLIST = 0x6ffffff7,
|
||||
SHT_CHECKSUM = 0x6ffffff8,
|
||||
SHT_LOSUNW = 0x6ffffffa,
|
||||
SHT_SUNW_move = 0x6ffffffa,
|
||||
SHT_SUNW_COMDAT = 0x6ffffffb,
|
||||
SHT_SUNW_syminfo = 0x6ffffffc,
|
||||
SHT_GNU_verdef = 0x6ffffffd,
|
||||
SHT_GNU_verneed = 0x6ffffffe,
|
||||
SHT_GNU_versym = 0x6fffffff,
|
||||
SHT_HISUNW = 0x6fffffff,
|
||||
SHT_HIOS = 0x6fffffff,
|
||||
SHT_LOPROC = 0x70000000,
|
||||
SHT_HIPROC = 0x7fffffff,
|
||||
SHT_LOUSER = 0x80000000,
|
||||
SHT_HIUSER = 0x8fffffff
|
||||
SHT_NULL = 0,
|
||||
SHT_PROGBITS = 1,
|
||||
SHT_SYMTAB = 2,
|
||||
SHT_STRTAB = 3,
|
||||
SHT_RELA = 4,
|
||||
SHT_HASH = 5,
|
||||
SHT_DYNAMIC = 6,
|
||||
SHT_NOTE = 7,
|
||||
SHT_NOBITS = 8,
|
||||
SHT_REL = 9,
|
||||
SHT_SHLIB = 10,
|
||||
SHT_DYNSYM = 11,
|
||||
SHT_INIT_ARRAY = 14,
|
||||
SHT_FINI_ARRAY = 15,
|
||||
SHT_PREINIT_ARRAY = 16,
|
||||
SHT_GROUP = 17,
|
||||
SHT_SYMTAB_SHNDX = 18,
|
||||
SHT_NUM = 19,
|
||||
SHT_LOOS = 0x60000000,
|
||||
SHT_GNU_ATTRIBUTES = 0x6ffffff5,
|
||||
SHT_GNU_HASH = 0x6ffffff6,
|
||||
SHT_GNU_LIBLIST = 0x6ffffff7,
|
||||
SHT_CHECKSUM = 0x6ffffff8,
|
||||
SHT_LOSUNW = 0x6ffffffa,
|
||||
SHT_SUNW_move = 0x6ffffffa,
|
||||
SHT_SUNW_COMDAT = 0x6ffffffb,
|
||||
SHT_SUNW_syminfo = 0x6ffffffc,
|
||||
SHT_GNU_verdef = 0x6ffffffd,
|
||||
SHT_GNU_verneed = 0x6ffffffe,
|
||||
SHT_GNU_versym = 0x6fffffff,
|
||||
SHT_HISUNW = 0x6fffffff,
|
||||
SHT_HIOS = 0x6fffffff,
|
||||
SHT_LOPROC = 0x70000000,
|
||||
SHT_HIPROC = 0x7fffffff,
|
||||
SHT_LOUSER = 0x80000000,
|
||||
SHT_HIUSER = 0x8fffffff
|
||||
};
|
||||
|
||||
#define ELF32_R_SYM(i) ((i) >> 8)
|
||||
@ -71,228 +71,226 @@ enum SectionHeaderType
|
||||
|
||||
enum DynamicTags
|
||||
{
|
||||
DT_NULL = 0,
|
||||
DT_NEEDED = 1,
|
||||
DT_PLTRELSZ = 2,
|
||||
DT_PLTGOT = 3,
|
||||
DT_HASH = 4,
|
||||
DT_STRTAB = 5,
|
||||
DT_SYMTAB = 6,
|
||||
DT_RELA = 7,
|
||||
DT_RELASZ = 8,
|
||||
DT_RELAENT = 9,
|
||||
DT_STRSZ = 10,
|
||||
DT_SYMENT = 11,
|
||||
DT_INIT = 12,
|
||||
DT_FINI = 13,
|
||||
DT_SONAME = 14,
|
||||
DT_RPATH = 15,
|
||||
DT_SYMBOLIC = 16,
|
||||
DT_REL = 17,
|
||||
DT_RELSZ = 18,
|
||||
DT_RELENT = 19,
|
||||
DT_PLTREL = 20,
|
||||
DT_DEBUG = 21,
|
||||
DT_TEXTREL = 22,
|
||||
DT_JMPREL = 23,
|
||||
DT_BIND_NOW = 24,
|
||||
DT_INIT_ARRAY = 25,
|
||||
DT_FINI_ARRAY = 26,
|
||||
DT_INIT_ARRAYSZ = 27,
|
||||
DT_FINI_ARRAYSZ = 28,
|
||||
DT_RUNPATH = 29,
|
||||
DT_FLAGS = 30,
|
||||
DT_ENCODING = 32,
|
||||
DT_PREINIT_ARRAY = 32,
|
||||
DT_PREINIT_ARRAYSZ = 33,
|
||||
DT_LOOS = 0x6000000d,
|
||||
DT_SUNW_RTLDINF = 0x6000000e,
|
||||
DT_HIOS = 0x6ffff000,
|
||||
DT_VALRNGLO = 0x6ffffd00,
|
||||
DT_CHECKSUM = 0x6ffffdf8,
|
||||
DT_PLTPADSZ = 0x6ffffdf9,
|
||||
DT_MOVEENT = 0x6ffffdfa,
|
||||
DT_MOVESZ = 0x6ffffdfb,
|
||||
DT_FEATURE_1 = 0x6ffffdfc,
|
||||
DT_POSFLAG_1 = 0x6ffffdfd,
|
||||
DT_SYMINSZ = 0x6ffffdfe,
|
||||
DT_SYMINENT = 0x6ffffdff,
|
||||
DT_VALRNGHI = 0x6ffffdff,
|
||||
DT_ADDRRNGLO = 0x6ffffe00,
|
||||
DT_CONFIG = 0x6ffffefa,
|
||||
DT_DEPAUDIT = 0x6ffffefb,
|
||||
DT_AUDIT = 0x6ffffefc,
|
||||
DT_PLTPAD = 0x6ffffefd,
|
||||
DT_MOVETAB = 0x6ffffefe,
|
||||
DT_SYMINFO = 0x6ffffeff,
|
||||
DT_ADDRRNGHI = 0x6ffffeff,
|
||||
DT_RELACOUNT = 0x6ffffff9,
|
||||
DT_RELCOUNT = 0x6ffffffa,
|
||||
DT_FLAGS_1 = 0x6ffffffb,
|
||||
DT_VERDEF = 0x6ffffffc,
|
||||
DT_VERDEFNUM = 0x6ffffffd,
|
||||
DT_VERNEED = 0x6ffffffe,
|
||||
DT_VERNEEDNUM = 0x6fffffff,
|
||||
DT_LOPROC = 0x70000000,
|
||||
DT_SPARC_REGISTER = 0x70000001,
|
||||
DT_AUXILIARY = 0x7ffffffd,
|
||||
DT_USED = 0x7ffffffe,
|
||||
DT_FILTER = 0x7fffffff,
|
||||
DT_HIPROC = 0x7fffffff
|
||||
DT_NULL = 0,
|
||||
DT_NEEDED = 1,
|
||||
DT_PLTRELSZ = 2,
|
||||
DT_PLTGOT = 3,
|
||||
DT_HASH = 4,
|
||||
DT_STRTAB = 5,
|
||||
DT_SYMTAB = 6,
|
||||
DT_RELA = 7,
|
||||
DT_RELASZ = 8,
|
||||
DT_RELAENT = 9,
|
||||
DT_STRSZ = 10,
|
||||
DT_SYMENT = 11,
|
||||
DT_INIT = 12,
|
||||
DT_FINI = 13,
|
||||
DT_SONAME = 14,
|
||||
DT_RPATH = 15,
|
||||
DT_SYMBOLIC = 16,
|
||||
DT_REL = 17,
|
||||
DT_RELSZ = 18,
|
||||
DT_RELENT = 19,
|
||||
DT_PLTREL = 20,
|
||||
DT_DEBUG = 21,
|
||||
DT_TEXTREL = 22,
|
||||
DT_JMPREL = 23,
|
||||
DT_BIND_NOW = 24,
|
||||
DT_INIT_ARRAY = 25,
|
||||
DT_FINI_ARRAY = 26,
|
||||
DT_INIT_ARRAYSZ = 27,
|
||||
DT_FINI_ARRAYSZ = 28,
|
||||
DT_RUNPATH = 29,
|
||||
DT_FLAGS = 30,
|
||||
DT_ENCODING = 32,
|
||||
DT_PREINIT_ARRAY = 32,
|
||||
DT_PREINIT_ARRAYSZ = 33,
|
||||
DT_LOOS = 0x6000000d,
|
||||
DT_SUNW_RTLDINF = 0x6000000e,
|
||||
DT_HIOS = 0x6ffff000,
|
||||
DT_VALRNGLO = 0x6ffffd00,
|
||||
DT_CHECKSUM = 0x6ffffdf8,
|
||||
DT_PLTPADSZ = 0x6ffffdf9,
|
||||
DT_MOVEENT = 0x6ffffdfa,
|
||||
DT_MOVESZ = 0x6ffffdfb,
|
||||
DT_FEATURE_1 = 0x6ffffdfc,
|
||||
DT_POSFLAG_1 = 0x6ffffdfd,
|
||||
DT_SYMINSZ = 0x6ffffdfe,
|
||||
DT_SYMINENT = 0x6ffffdff,
|
||||
DT_VALRNGHI = 0x6ffffdff,
|
||||
DT_ADDRRNGLO = 0x6ffffe00,
|
||||
DT_CONFIG = 0x6ffffefa,
|
||||
DT_DEPAUDIT = 0x6ffffefb,
|
||||
DT_AUDIT = 0x6ffffefc,
|
||||
DT_PLTPAD = 0x6ffffefd,
|
||||
DT_MOVETAB = 0x6ffffefe,
|
||||
DT_SYMINFO = 0x6ffffeff,
|
||||
DT_ADDRRNGHI = 0x6ffffeff,
|
||||
DT_RELACOUNT = 0x6ffffff9,
|
||||
DT_RELCOUNT = 0x6ffffffa,
|
||||
DT_FLAGS_1 = 0x6ffffffb,
|
||||
DT_VERDEF = 0x6ffffffc,
|
||||
DT_VERDEFNUM = 0x6ffffffd,
|
||||
DT_VERNEED = 0x6ffffffe,
|
||||
DT_VERNEEDNUM = 0x6fffffff,
|
||||
DT_LOPROC = 0x70000000,
|
||||
DT_SPARC_REGISTER = 0x70000001,
|
||||
DT_AUXILIARY = 0x7ffffffd,
|
||||
DT_USED = 0x7ffffffe,
|
||||
DT_FILTER = 0x7fffffff,
|
||||
DT_HIPROC = 0x7fffffff
|
||||
};
|
||||
|
||||
enum SegmentTypes
|
||||
{
|
||||
PT_NULL = 0,
|
||||
PT_LOAD = 1,
|
||||
PT_DYNAMIC = 2,
|
||||
PT_INTERP = 3,
|
||||
PT_NOTE = 4,
|
||||
PT_SHLIB = 5,
|
||||
PT_PHDR = 6,
|
||||
PT_TLS = 7,
|
||||
PT_LOSUNW = 0x6ffffffa,
|
||||
PT_SUNWBSS = 0x6ffffffb,
|
||||
PT_SUNWSTACK = 0x6ffffffa,
|
||||
PT_HISUNW = 0x6fffffff,
|
||||
PT_LOPROC = 0x70000000,
|
||||
PT_HIPROC = 0x7fffffff
|
||||
PT_NULL = 0,
|
||||
PT_LOAD = 1,
|
||||
PT_DYNAMIC = 2,
|
||||
PT_INTERP = 3,
|
||||
PT_NOTE = 4,
|
||||
PT_SHLIB = 5,
|
||||
PT_PHDR = 6,
|
||||
PT_TLS = 7,
|
||||
PT_LOSUNW = 0x6ffffffa,
|
||||
PT_SUNWBSS = 0x6ffffffb,
|
||||
PT_SUNWSTACK = 0x6ffffffa,
|
||||
PT_HISUNW = 0x6fffffff,
|
||||
PT_LOPROC = 0x70000000,
|
||||
PT_HIPROC = 0x7fffffff
|
||||
};
|
||||
|
||||
enum RtT_Types
|
||||
{
|
||||
R_386_NONE = 0,
|
||||
R_386_32 = 1,
|
||||
R_386_PC32 = 2,
|
||||
R_386_NONE = 0,
|
||||
R_386_32 = 1,
|
||||
R_386_PC32 = 2,
|
||||
|
||||
R_X86_64_NONE = 0,
|
||||
R_X86_64_64 = 1,
|
||||
R_X86_64_PC32 = 2,
|
||||
R_X86_64_GOT32 = 3,
|
||||
R_X86_64_PLT32 = 4,
|
||||
R_X86_64_COPY = 5,
|
||||
R_X86_64_GLOB_DAT = 6,
|
||||
R_X86_64_JUMP_SLOT = 7,
|
||||
R_X86_64_RELATIVE = 8,
|
||||
R_X86_64_GOTPCREL = 9,
|
||||
R_X86_64_32 = 10,
|
||||
R_X86_64_32S = 11,
|
||||
R_X86_64_16 = 12,
|
||||
R_X86_64_NONE = 0,
|
||||
R_X86_64_64 = 1,
|
||||
R_X86_64_PC32 = 2,
|
||||
R_X86_64_GOT32 = 3,
|
||||
R_X86_64_PLT32 = 4,
|
||||
R_X86_64_COPY = 5,
|
||||
R_X86_64_GLOB_DAT = 6,
|
||||
R_X86_64_JUMP_SLOT = 7,
|
||||
R_X86_64_RELATIVE = 8,
|
||||
R_X86_64_GOTPCREL = 9,
|
||||
R_X86_64_32 = 10,
|
||||
R_X86_64_32S = 11,
|
||||
R_X86_64_16 = 12,
|
||||
};
|
||||
|
||||
typedef struct elf32_hdr
|
||||
{
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
Elf32_Half e_type;
|
||||
Elf32_Half e_machine;
|
||||
Elf32_Word e_version;
|
||||
Elf32_Addr e_entry;
|
||||
Elf32_Off e_phoff;
|
||||
Elf32_Off e_shoff;
|
||||
Elf32_Word e_flags;
|
||||
Elf32_Half e_ehsize;
|
||||
Elf32_Half e_phentsize;
|
||||
Elf32_Half e_phnum;
|
||||
Elf32_Half e_shentsize;
|
||||
Elf32_Half e_shnum;
|
||||
Elf32_Half e_shstrndx;
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
Elf32_Half e_type;
|
||||
Elf32_Half e_machine;
|
||||
Elf32_Word e_version;
|
||||
Elf32_Addr e_entry;
|
||||
Elf32_Off e_phoff;
|
||||
Elf32_Off e_shoff;
|
||||
Elf32_Word e_flags;
|
||||
Elf32_Half e_ehsize;
|
||||
Elf32_Half e_phentsize;
|
||||
Elf32_Half e_phnum;
|
||||
Elf32_Half e_shentsize;
|
||||
Elf32_Half e_shnum;
|
||||
Elf32_Half e_shstrndx;
|
||||
} Elf32_Ehdr;
|
||||
|
||||
typedef struct elf64_hdr
|
||||
{
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
Elf64_Half e_type;
|
||||
Elf64_Half e_machine;
|
||||
Elf64_Word e_version;
|
||||
Elf64_Addr e_entry;
|
||||
Elf64_Off e_phoff;
|
||||
Elf64_Off e_shoff;
|
||||
Elf64_Word e_flags;
|
||||
Elf64_Half e_ehsize;
|
||||
Elf64_Half e_phentsize;
|
||||
Elf64_Half e_phnum;
|
||||
Elf64_Half e_shentsize;
|
||||
Elf64_Half e_shnum;
|
||||
Elf64_Half e_shstrndx;
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
Elf64_Half e_type;
|
||||
Elf64_Half e_machine;
|
||||
Elf64_Word e_version;
|
||||
Elf64_Addr e_entry;
|
||||
Elf64_Off e_phoff;
|
||||
Elf64_Off e_shoff;
|
||||
Elf64_Word e_flags;
|
||||
Elf64_Half e_ehsize;
|
||||
Elf64_Half e_phentsize;
|
||||
Elf64_Half e_phnum;
|
||||
Elf64_Half e_shentsize;
|
||||
Elf64_Half e_shnum;
|
||||
Elf64_Half e_shstrndx;
|
||||
} Elf64_Ehdr;
|
||||
|
||||
typedef struct elf32_shdr
|
||||
{
|
||||
Elf32_Word sh_name;
|
||||
Elf32_Word sh_type;
|
||||
Elf32_Word sh_flags;
|
||||
Elf32_Addr sh_addr;
|
||||
Elf32_Off sh_offset;
|
||||
Elf32_Word sh_size;
|
||||
Elf32_Word sh_link;
|
||||
Elf32_Word sh_info;
|
||||
Elf32_Word sh_addralign;
|
||||
Elf32_Word sh_entsize;
|
||||
Elf32_Word sh_name;
|
||||
Elf32_Word sh_type;
|
||||
Elf32_Word sh_flags;
|
||||
Elf32_Addr sh_addr;
|
||||
Elf32_Off sh_offset;
|
||||
Elf32_Word sh_size;
|
||||
Elf32_Word sh_link;
|
||||
Elf32_Word sh_info;
|
||||
Elf32_Word sh_addralign;
|
||||
Elf32_Word sh_entsize;
|
||||
} Elf32_Shdr;
|
||||
|
||||
typedef struct elf64_shdr
|
||||
{
|
||||
Elf64_Word sh_name;
|
||||
Elf64_Word sh_type;
|
||||
Elf64_Xword sh_flags;
|
||||
Elf64_Addr sh_addr;
|
||||
Elf64_Off sh_offset;
|
||||
Elf64_Xword sh_size;
|
||||
Elf64_Word sh_link;
|
||||
Elf64_Word sh_info;
|
||||
Elf64_Xword sh_addralign;
|
||||
Elf64_Xword sh_entsize;
|
||||
Elf64_Word sh_name;
|
||||
Elf64_Word sh_type;
|
||||
Elf64_Xword sh_flags;
|
||||
Elf64_Addr sh_addr;
|
||||
Elf64_Off sh_offset;
|
||||
Elf64_Xword sh_size;
|
||||
Elf64_Word sh_link;
|
||||
Elf64_Word sh_info;
|
||||
Elf64_Xword sh_addralign;
|
||||
Elf64_Xword sh_entsize;
|
||||
} Elf64_Shdr;
|
||||
|
||||
struct Elf32_Dyn
|
||||
{
|
||||
Elf32_Sword d_tag;
|
||||
union
|
||||
{
|
||||
Elf32_Word d_val;
|
||||
Elf32_Addr d_ptr;
|
||||
} d_un;
|
||||
Elf32_Sword d_tag;
|
||||
union
|
||||
{
|
||||
Elf32_Word d_val;
|
||||
Elf32_Addr d_ptr;
|
||||
} d_un;
|
||||
};
|
||||
|
||||
struct Elf64_Dyn
|
||||
{
|
||||
Elf64_Sxword d_tag;
|
||||
union
|
||||
{
|
||||
Elf64_Xword d_val;
|
||||
Elf64_Addr d_ptr;
|
||||
} d_un;
|
||||
Elf64_Sxword d_tag;
|
||||
union
|
||||
{
|
||||
Elf64_Xword d_val;
|
||||
Elf64_Addr d_ptr;
|
||||
} d_un;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word p_type;
|
||||
Elf64_Word p_flags;
|
||||
Elf64_Off p_offset;
|
||||
Elf64_Addr p_vaddr;
|
||||
Elf64_Addr p_paddr;
|
||||
Elf64_Xword p_filesz;
|
||||
Elf64_Xword p_memsz;
|
||||
Elf64_Xword p_align;
|
||||
Elf64_Word p_type;
|
||||
Elf64_Word p_flags;
|
||||
Elf64_Off p_offset;
|
||||
Elf64_Addr p_vaddr;
|
||||
Elf64_Addr p_paddr;
|
||||
Elf64_Xword p_filesz;
|
||||
Elf64_Xword p_memsz;
|
||||
Elf64_Xword p_align;
|
||||
} Elf64_Phdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Addr r_offset;
|
||||
Elf64_Xword r_info;
|
||||
Elf64_Sxword r_addend;
|
||||
Elf64_Addr r_offset;
|
||||
Elf64_Xword r_info;
|
||||
Elf64_Sxword r_addend;
|
||||
} Elf64_Rela;
|
||||
|
||||
typedef struct elf64_sym
|
||||
{
|
||||
Elf64_Word st_name;
|
||||
unsigned char st_info;
|
||||
unsigned char st_other;
|
||||
Elf64_Half st_shndx;
|
||||
Elf64_Addr st_value;
|
||||
Elf64_Xword st_size;
|
||||
Elf64_Word st_name;
|
||||
unsigned char st_info;
|
||||
unsigned char st_other;
|
||||
Elf64_Half st_shndx;
|
||||
Elf64_Addr st_value;
|
||||
Elf64_Xword st_size;
|
||||
} Elf64_Sym;
|
||||
|
||||
struct Elf64_Dyn *ELFGetDynamicTag(void *ElfFile, enum DynamicTags Tag);
|
||||
|
||||
#endif // !__FENNIX_LIB_ELF_LAZY_RESOLVE_H__
|
||||
|
234
libc/ElfInterpreter/fcts.c
Normal file
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__
|
@ -2,13 +2,13 @@
|
||||
|
||||
uint32_t ElfHash(const unsigned char *Name)
|
||||
{
|
||||
uint32_t i = 0, j;
|
||||
while (*Name)
|
||||
{
|
||||
i = (i << 4) + *Name++;
|
||||
if ((j = i & 0xF0000000) != 0)
|
||||
i ^= j >> 24;
|
||||
i &= ~j;
|
||||
}
|
||||
return i;
|
||||
uint32_t i = 0, j;
|
||||
while (*Name)
|
||||
{
|
||||
i = (i << 4) + *Name++;
|
||||
if ((j = i & 0xF0000000) != 0)
|
||||
i ^= j >> 24;
|
||||
i &= ~j;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
@ -1,147 +1,14 @@
|
||||
#include "ld.h"
|
||||
#include "fcts.h"
|
||||
|
||||
#include "../../libs/include/libsys/base.h"
|
||||
#include "../../../Kernel/syscalls.h"
|
||||
#include "../../../Kernel/ipc.h"
|
||||
#include "elf.h"
|
||||
|
||||
uintptr_t RequestPages(size_t Count)
|
||||
{
|
||||
return syscall1(_RequestPages, Count);
|
||||
}
|
||||
|
||||
int FreePages(uintptr_t Address, size_t Count)
|
||||
{
|
||||
return syscall2(_FreePages, Address, Count);
|
||||
}
|
||||
|
||||
int IPC(enum IPCCommand Command, enum IPCType Type, int ID, int Flags, void *Buffer, size_t Size)
|
||||
{
|
||||
return syscall6(_IPC, (long)Command, (long)Type, (long)ID, (long)Flags, (long)Buffer, (long)Size);
|
||||
}
|
||||
|
||||
uintptr_t KernelCTL(enum KCtl Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4)
|
||||
{
|
||||
return syscall5(_KernelCTL, Command, Arg1, Arg2, Arg3, Arg4);
|
||||
}
|
||||
|
||||
struct LibAddressCollection
|
||||
{
|
||||
char Name[32];
|
||||
uintptr_t ElfFile;
|
||||
uintptr_t MemoryImage;
|
||||
uintptr_t ParentElfFile;
|
||||
uintptr_t ParentMemoryImage;
|
||||
struct LibAddressCollection *Next;
|
||||
char Valid;
|
||||
};
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
static char Lock = 0;
|
||||
|
||||
__attribute__((naked, used, no_stack_protector)) void ELF_LAZY_RESOLVE_STUB()
|
||||
{
|
||||
while (Lock == 1)
|
||||
;
|
||||
__asm__ __volatile__("mfence\n");
|
||||
Lock = 1;
|
||||
__asm__ __volatile__("pop %r11\n"
|
||||
"pop %r10\n"
|
||||
|
||||
"push %rdi\n"
|
||||
"push %rsi\n"
|
||||
"push %rdx\n"
|
||||
"push %rcx\n"
|
||||
"push %r8\n"
|
||||
"push %r9\n"
|
||||
|
||||
"mov %r11, %rdi\n" // Move the first argument to rdi (libs collection)
|
||||
"mov %r10, %rsi\n" // Move the second argument to rsi (rel index)
|
||||
|
||||
"call ELF_LAZY_RESOLVE_MAIN\n"
|
||||
|
||||
"mov %rax, %r11\n" // Move the return value to r11
|
||||
|
||||
"pop %r9\n"
|
||||
"pop %r8\n"
|
||||
"pop %rcx\n"
|
||||
"pop %rdx\n"
|
||||
"pop %rsi\n"
|
||||
"pop %rdi\n"
|
||||
|
||||
"jmp *%r11\n"); // Jump to the return value
|
||||
}
|
||||
|
||||
int abs(int i) { return i < 0 ? -i : i; }
|
||||
|
||||
void swap(char *x, char *y)
|
||||
{
|
||||
char t = *x;
|
||||
*x = *y;
|
||||
*y = t;
|
||||
}
|
||||
|
||||
char *reverse(char *Buffer, int i, int j)
|
||||
{
|
||||
while (i < j)
|
||||
swap(&Buffer[i++], &Buffer[j--]);
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
char *ltoa(long Value, char *Buffer, int Base)
|
||||
{
|
||||
if (Base < 2 || Base > 32)
|
||||
return Buffer;
|
||||
|
||||
long n = (long)abs((int)Value);
|
||||
int i = 0;
|
||||
|
||||
while (n)
|
||||
{
|
||||
int r = n % Base;
|
||||
if (r >= 10)
|
||||
Buffer[i++] = 65 + (r - 10);
|
||||
else
|
||||
Buffer[i++] = 48 + r;
|
||||
n = n / Base;
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
Buffer[i++] = '0';
|
||||
|
||||
if (Value < 0 && Base == 10)
|
||||
Buffer[i++] = '-';
|
||||
|
||||
Buffer[i] = '\0';
|
||||
return reverse(Buffer, 0, i - 1);
|
||||
}
|
||||
|
||||
static inline void PutCharToKernelConsole(char c)
|
||||
{
|
||||
__asm__ __volatile__("syscall"
|
||||
:
|
||||
: "a"(1), "D"(c), "S"(0)
|
||||
: "rcx", "r11", "memory");
|
||||
}
|
||||
|
||||
void Print__(char *String)
|
||||
{
|
||||
for (short i = 0; String[i] != '\0'; i++)
|
||||
PutCharToKernelConsole(String[i]);
|
||||
}
|
||||
|
||||
void PrintNL__(char *String)
|
||||
{
|
||||
Print__(String);
|
||||
Print__("\n");
|
||||
}
|
||||
|
||||
#define Print(x) Print__(x)
|
||||
#define PrintNL(x) PrintNL__(x)
|
||||
|
||||
#if (0)
|
||||
#if (1)
|
||||
#define PrintDbg(x) Print__(x)
|
||||
#define PrintDbgNL(x) PrintNL__(x)
|
||||
#define ltoaDbg(x, y, z) ltoa(x, y, z)
|
||||
@ -151,397 +18,400 @@ void PrintNL__(char *String)
|
||||
#define ltoaDbg(x, y, z)
|
||||
#endif
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
uint8_t *d = dest;
|
||||
const uint8_t *s = src;
|
||||
while (n--)
|
||||
*d++ = *s++;
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
uint8_t *p = s;
|
||||
while (n--)
|
||||
*p++ = c;
|
||||
}
|
||||
|
||||
int strcmp(const char *l, const char *r)
|
||||
{
|
||||
for (; *l == *r && *l; l++, r++)
|
||||
;
|
||||
return *(unsigned char *)l - *(unsigned char *)r;
|
||||
}
|
||||
|
||||
struct Elf64_Dyn *ELFGetDynamicTag(void *ElfFile, enum DynamicTags Tag)
|
||||
{
|
||||
Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)ElfFile;
|
||||
|
||||
Elf64_Phdr ItrProgramHeader;
|
||||
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
|
||||
{
|
||||
memcpy(&ItrProgramHeader, (uint8_t *)ElfFile + ELFHeader->e_phoff + ELFHeader->e_phentsize * i, sizeof(Elf64_Phdr));
|
||||
if (ItrProgramHeader.p_type == PT_DYNAMIC)
|
||||
{
|
||||
struct Elf64_Dyn *Dynamic = (struct Elf64_Dyn *)((uint8_t *)ElfFile + ItrProgramHeader.p_offset);
|
||||
for (size_t i = 0; i < ItrProgramHeader.p_filesz / sizeof(struct Elf64_Dyn); i++)
|
||||
{
|
||||
if (Dynamic[i].d_tag == Tag)
|
||||
return &Dynamic[i];
|
||||
if (Dynamic[i].d_tag == DT_NULL)
|
||||
return (void *)0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
Elf64_Shdr *GetELFSheader(Elf64_Ehdr *Header)
|
||||
{
|
||||
Elf64_Off SheaderOffset = Header->e_shoff;
|
||||
return (Elf64_Shdr *)((uintptr_t)Header + SheaderOffset);
|
||||
}
|
||||
|
||||
Elf64_Shdr *GetELFSection(Elf64_Ehdr *Header, uint64_t Index)
|
||||
{
|
||||
Elf64_Shdr *Sheader = GetELFSheader(Header);
|
||||
return &Sheader[Index];
|
||||
}
|
||||
|
||||
char *GetELFStringTable(Elf64_Ehdr *Header)
|
||||
{
|
||||
if (Header->e_shstrndx == SHN_UNDEF)
|
||||
return NULL;
|
||||
return (char *)Header + GetELFSection(Header, Header->e_shstrndx)->sh_offset;
|
||||
}
|
||||
|
||||
Elf64_Sym *ELFLookupSymbol(Elf64_Ehdr *Header, const char *Name)
|
||||
{
|
||||
Elf64_Shdr *SymbolTable = NULL;
|
||||
Elf64_Shdr *StringTable = NULL;
|
||||
Elf64_Sym *Symbol = NULL;
|
||||
char *String = NULL;
|
||||
|
||||
for (Elf64_Half i = 0; i < Header->e_shnum; i++)
|
||||
{
|
||||
Elf64_Shdr *shdr = GetELFSection(Header, i);
|
||||
switch (shdr->sh_type)
|
||||
{
|
||||
case SHT_SYMTAB:
|
||||
SymbolTable = shdr;
|
||||
StringTable = GetELFSection(Header, shdr->sh_link);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SymbolTable == NULL || StringTable == NULL)
|
||||
return NULL;
|
||||
|
||||
for (size_t i = 0; i < (SymbolTable->sh_size / sizeof(Elf64_Sym)); i++)
|
||||
{
|
||||
Symbol = (Elf64_Sym *)((uintptr_t)Header + SymbolTable->sh_offset + (i * sizeof(Elf64_Sym)));
|
||||
String = (char *)((uintptr_t)Header + StringTable->sh_offset + Symbol->st_name);
|
||||
|
||||
if (strcmp(String, Name) == 0)
|
||||
return (void *)Symbol;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void (*ELF_LAZY_RESOLVE_MAIN(struct LibAddressCollection *Info, long RelIndex))()
|
||||
{
|
||||
char DbgBuff[32];
|
||||
if (Info)
|
||||
{
|
||||
struct LibAddressCollection *CurLib = Info;
|
||||
PrintDbgNL("_______");
|
||||
// The last entry is the null entry (Valid == false) which determines the end of the list.
|
||||
while (CurLib->Valid)
|
||||
{
|
||||
PrintDbg("-- ");
|
||||
PrintDbg(CurLib->Name);
|
||||
PrintDbg(" ");
|
||||
ltoaDbg(RelIndex, DbgBuff, 10);
|
||||
PrintDbg(DbgBuff);
|
||||
PrintDbgNL(" --");
|
||||
uintptr_t lib_BaseAddress = __UINTPTR_MAX__;
|
||||
uintptr_t app_BaseAddress = __UINTPTR_MAX__;
|
||||
|
||||
Elf64_Phdr ItrProgramHeader;
|
||||
|
||||
for (Elf64_Half i = 0; i < ((Elf64_Ehdr *)CurLib->ElfFile)->e_phnum; i++)
|
||||
{
|
||||
memcpy(&ItrProgramHeader,
|
||||
(uint8_t *)CurLib->ElfFile +
|
||||
((Elf64_Ehdr *)CurLib->ElfFile)->e_phoff +
|
||||
((Elf64_Ehdr *)CurLib->ElfFile)->e_phentsize * i,
|
||||
sizeof(Elf64_Phdr));
|
||||
|
||||
lib_BaseAddress = MIN(lib_BaseAddress, ItrProgramHeader.p_vaddr);
|
||||
}
|
||||
|
||||
for (Elf64_Half i = 0; i < ((Elf64_Ehdr *)CurLib->ParentElfFile)->e_phnum; i++)
|
||||
{
|
||||
memcpy(&ItrProgramHeader,
|
||||
(uint8_t *)CurLib->ParentElfFile +
|
||||
((Elf64_Ehdr *)CurLib->ParentElfFile)->e_phoff +
|
||||
((Elf64_Ehdr *)CurLib->ParentElfFile)->e_phentsize * i,
|
||||
sizeof(Elf64_Phdr));
|
||||
|
||||
app_BaseAddress = MIN(app_BaseAddress, ItrProgramHeader.p_vaddr);
|
||||
}
|
||||
|
||||
struct Elf64_Dyn *lib_JmpRel = ELFGetDynamicTag((void *)CurLib->ElfFile, DT_JMPREL);
|
||||
struct Elf64_Dyn *lib_SymTab = ELFGetDynamicTag((void *)CurLib->ElfFile, DT_SYMTAB);
|
||||
struct Elf64_Dyn *lib_StrTab = ELFGetDynamicTag((void *)CurLib->ElfFile, DT_STRTAB);
|
||||
|
||||
struct Elf64_Dyn *app_JmpRel = ELFGetDynamicTag((void *)CurLib->ParentElfFile, DT_JMPREL);
|
||||
struct Elf64_Dyn *app_SymTab = ELFGetDynamicTag((void *)CurLib->ParentElfFile, DT_SYMTAB);
|
||||
struct Elf64_Dyn *app_StrTab = ELFGetDynamicTag((void *)CurLib->ParentElfFile, DT_STRTAB);
|
||||
|
||||
if (!lib_JmpRel)
|
||||
{
|
||||
PrintNL("No DT_JMPREL");
|
||||
goto RetryNextLib;
|
||||
}
|
||||
else if (RelIndex >= lib_JmpRel->d_un.d_val / sizeof(Elf64_Rela))
|
||||
{
|
||||
PrintNL("RelIndex is greater than the number of relocations");
|
||||
goto RetryNextLib;
|
||||
}
|
||||
|
||||
if (!lib_SymTab)
|
||||
{
|
||||
PrintNL("No DT_SYMTAB");
|
||||
goto RetryNextLib;
|
||||
}
|
||||
|
||||
if (!lib_StrTab)
|
||||
{
|
||||
PrintNL("No DT_STRTAB");
|
||||
goto RetryNextLib;
|
||||
}
|
||||
|
||||
if (!lib_JmpRel && !lib_SymTab && !lib_StrTab)
|
||||
goto RetryNextLib;
|
||||
|
||||
Elf64_Rela *_lib_JmpRel = (Elf64_Rela *)(CurLib->MemoryImage + (lib_JmpRel->d_un.d_ptr - lib_BaseAddress));
|
||||
Elf64_Sym *_lib_SymTab = (Elf64_Sym *)(CurLib->MemoryImage + (lib_SymTab->d_un.d_ptr - lib_BaseAddress));
|
||||
|
||||
Elf64_Rela *_app_JmpRel = (Elf64_Rela *)(CurLib->ParentMemoryImage + (app_JmpRel->d_un.d_ptr - app_BaseAddress));
|
||||
Elf64_Sym *_app_SymTab = (Elf64_Sym *)(CurLib->ParentMemoryImage + (app_SymTab->d_un.d_ptr - app_BaseAddress));
|
||||
|
||||
char *lib_DynStr = (char *)(CurLib->MemoryImage + (lib_StrTab->d_un.d_ptr - lib_BaseAddress));
|
||||
char *app_DynStr = (char *)(CurLib->ParentMemoryImage + (app_StrTab->d_un.d_ptr - app_BaseAddress));
|
||||
|
||||
Elf64_Rela *Rel = _app_JmpRel + RelIndex;
|
||||
Elf64_Addr *GOTEntry = (Elf64_Addr *)(Rel->r_offset);
|
||||
|
||||
int RelType = ELF64_R_TYPE(Rel->r_info);
|
||||
|
||||
switch (RelType)
|
||||
{
|
||||
case R_X86_64_NONE:
|
||||
{
|
||||
PrintDbgNL("R_X86_64_NONE");
|
||||
if (*GOTEntry == 0)
|
||||
{
|
||||
PrintDbgNL("GOTEntry is 0");
|
||||
break;
|
||||
}
|
||||
Lock = 0;
|
||||
return (void (*)()) * GOTEntry;
|
||||
}
|
||||
case R_X86_64_JUMP_SLOT:
|
||||
{
|
||||
PrintDbgNL("R_X86_64_JUMP_SLOT");
|
||||
int SymIndex = ELF64_R_SYM(Rel->r_info);
|
||||
Elf64_Sym *Sym = _app_SymTab + SymIndex;
|
||||
|
||||
if (Sym->st_name)
|
||||
{
|
||||
char *SymName = app_DynStr + Sym->st_name;
|
||||
PrintDbg("SymName: ");
|
||||
PrintDbgNL(SymName);
|
||||
|
||||
Elf64_Sym *LibSym = ELFLookupSymbol((Elf64_Ehdr *)CurLib->ElfFile, SymName);
|
||||
|
||||
PrintDbg("LibSym: 0x");
|
||||
ltoaDbg((long)LibSym, DbgBuff, 16);
|
||||
PrintDbgNL(DbgBuff);
|
||||
|
||||
if (LibSym)
|
||||
{
|
||||
*GOTEntry = (Elf64_Addr)(CurLib->MemoryImage + LibSym->st_value);
|
||||
|
||||
ltoa(*GOTEntry, DbgBuff, 16);
|
||||
PrintDbg("*GOTEntry: 0x");
|
||||
PrintDbgNL(DbgBuff);
|
||||
|
||||
Lock = 0;
|
||||
return (void (*)()) * GOTEntry;
|
||||
}
|
||||
PrintDbgNL("Not found in lib");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ltoa(RelType, DbgBuff, 10);
|
||||
Print("RelType not supported ");
|
||||
PrintNL(DbgBuff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RetryNextLib:
|
||||
PrintDbgNL("Retrying next lib");
|
||||
CurLib = CurLib->Next;
|
||||
}
|
||||
}
|
||||
|
||||
Lock = 0;
|
||||
__asm__ __volatile__("mfence\n");
|
||||
|
||||
Print("Symbol index ");
|
||||
ltoa(RelIndex, DbgBuff, 10);
|
||||
Print(DbgBuff);
|
||||
PrintNL(" not found");
|
||||
int ExitCode = 0x51801;
|
||||
syscall1(_Exit, ExitCode);
|
||||
while (1) // Make sure we don't return
|
||||
;
|
||||
}
|
||||
|
||||
struct InterpreterIPCDataLibrary
|
||||
{
|
||||
char Name[128];
|
||||
char Name[64];
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char Path[256];
|
||||
void *ElfFile;
|
||||
void *MemoryImage;
|
||||
struct InterpreterIPCDataLibrary Libraries[64];
|
||||
char Path[256];
|
||||
void *MemoryImage;
|
||||
struct InterpreterIPCDataLibrary Libraries[64];
|
||||
} InterpreterIPCData;
|
||||
|
||||
struct LibsCollection
|
||||
{
|
||||
char ParentName[32];
|
||||
char LibraryName[32];
|
||||
uintptr_t ParentMemoryImage;
|
||||
uintptr_t LibraryMemoryImage;
|
||||
struct LibsCollection *Next;
|
||||
char Valid;
|
||||
};
|
||||
|
||||
static char ParentPath[256];
|
||||
static char Lock = 0;
|
||||
|
||||
__attribute__((naked, used, no_stack_protector)) void ELF_LAZY_RESOLVE_STUB()
|
||||
{
|
||||
while (Lock == 1)
|
||||
;
|
||||
__asm__ __volatile__("mfence\n");
|
||||
Lock = 1;
|
||||
__asm__ __volatile__("pop %r11\n"
|
||||
"pop %r10\n"
|
||||
|
||||
"push %rdi\n"
|
||||
"push %rsi\n"
|
||||
"push %rdx\n"
|
||||
"push %rcx\n"
|
||||
"push %r8\n"
|
||||
"push %r9\n"
|
||||
|
||||
"mov %r11, %rdi\n" // Move the first argument to rdi (libs collection)
|
||||
"mov %r10, %rsi\n" // Move the second argument to rsi (rel index)
|
||||
|
||||
"call ELF_LAZY_RESOLVE_MAIN\n"
|
||||
|
||||
"mov %rax, %r11\n" // Move the return value to r11
|
||||
|
||||
"pop %r9\n"
|
||||
"pop %r8\n"
|
||||
"pop %rcx\n"
|
||||
"pop %rdx\n"
|
||||
"pop %rsi\n"
|
||||
"pop %rdi\n"
|
||||
|
||||
"jmp *%r11\n"); // Jump to the return value
|
||||
}
|
||||
|
||||
void (*ELF_LAZY_RESOLVE_MAIN(struct LibsCollection *Info, long RelIndex))()
|
||||
{
|
||||
if (!Info)
|
||||
goto FailEnd;
|
||||
|
||||
char DbgBuff[32];
|
||||
char LibraryPathBuffer[256];
|
||||
|
||||
struct LibsCollection *CurLib = Info;
|
||||
PrintDbgNL("_______");
|
||||
/* The last entry is the null entry (Valid == false)
|
||||
which determines the end of the list. */
|
||||
while (CurLib->Valid)
|
||||
{
|
||||
KernelCTL(KCTL_GET_ABSOLUTE_PATH, CurLib->LibraryName,
|
||||
LibraryPathBuffer, sizeof(LibraryPathBuffer), 0);
|
||||
|
||||
PrintDbg("-- ");
|
||||
PrintDbg(LibraryPathBuffer);
|
||||
PrintDbg(" ");
|
||||
ltoaDbg(RelIndex, DbgBuff, 10);
|
||||
PrintDbg(DbgBuff);
|
||||
PrintDbgNL(" --");
|
||||
uintptr_t lib_BaseAddress = __UINTPTR_MAX__;
|
||||
uintptr_t app_BaseAddress = __UINTPTR_MAX__;
|
||||
|
||||
Elf64_Ehdr lib_Header;
|
||||
Elf64_Ehdr app_Header;
|
||||
|
||||
void *KP_lib = syscall2(_FileOpen, LibraryPathBuffer, "r");
|
||||
void *KP_app = syscall2(_FileOpen, ParentPath, "r");
|
||||
|
||||
if (!KP_lib)
|
||||
{
|
||||
PrintNL("Failed to open library");
|
||||
goto RetryNextLib;
|
||||
}
|
||||
|
||||
if (!KP_app)
|
||||
{
|
||||
PrintNL("Failed to open application");
|
||||
goto RetryNextLib;
|
||||
}
|
||||
|
||||
syscall3(_FileRead, KP_lib, &lib_Header, sizeof(Elf64_Ehdr));
|
||||
syscall3(_FileRead, KP_app, &app_Header, sizeof(Elf64_Ehdr));
|
||||
|
||||
Elf64_Phdr ItrProgramHeader;
|
||||
|
||||
for (Elf64_Half i = 0; i < lib_Header.e_phnum; i++)
|
||||
{
|
||||
syscall3(_FileSeek, KP_lib,
|
||||
lib_Header.e_phoff +
|
||||
lib_Header.e_phentsize * i,
|
||||
SEEK_SET);
|
||||
|
||||
syscall3(_FileRead, KP_lib, &ItrProgramHeader, sizeof(Elf64_Phdr));
|
||||
|
||||
lib_BaseAddress = MIN(lib_BaseAddress, ItrProgramHeader.p_vaddr);
|
||||
}
|
||||
|
||||
for (Elf64_Half i = 0; i < app_Header.e_phnum; i++)
|
||||
{
|
||||
syscall3(_FileSeek, KP_app,
|
||||
app_Header.e_phoff +
|
||||
app_Header.e_phentsize * i,
|
||||
SEEK_SET);
|
||||
|
||||
syscall3(_FileRead, KP_app, &ItrProgramHeader, sizeof(Elf64_Phdr));
|
||||
|
||||
app_BaseAddress = MIN(app_BaseAddress, ItrProgramHeader.p_vaddr);
|
||||
}
|
||||
|
||||
struct Elf64_Dyn lib_JmpRel = ELFGetDynamicTag(LibraryPathBuffer, DT_JMPREL);
|
||||
struct Elf64_Dyn lib_SymTab = ELFGetDynamicTag(LibraryPathBuffer, DT_SYMTAB);
|
||||
struct Elf64_Dyn lib_StrTab = ELFGetDynamicTag(LibraryPathBuffer, DT_STRTAB);
|
||||
|
||||
struct Elf64_Dyn app_JmpRel = ELFGetDynamicTag(ParentPath, DT_JMPREL);
|
||||
struct Elf64_Dyn app_SymTab = ELFGetDynamicTag(ParentPath, DT_SYMTAB);
|
||||
struct Elf64_Dyn app_StrTab = ELFGetDynamicTag(ParentPath, DT_STRTAB);
|
||||
|
||||
if (!lib_JmpRel.d_tag == 0)
|
||||
{
|
||||
PrintNL("No DT_JMPREL");
|
||||
// goto RetryNextLib;
|
||||
}
|
||||
else if (RelIndex >= lib_JmpRel.d_un.d_val /
|
||||
sizeof(Elf64_Rela))
|
||||
{
|
||||
PrintNL("RelIndex is greater than the number of relocations");
|
||||
goto RetryNextLib;
|
||||
}
|
||||
|
||||
if (!lib_SymTab.d_tag == 0)
|
||||
{
|
||||
PrintNL("No DT_SYMTAB");
|
||||
goto RetryNextLib;
|
||||
}
|
||||
|
||||
if (!lib_StrTab.d_tag == 0)
|
||||
{
|
||||
PrintNL("No DT_STRTAB");
|
||||
goto RetryNextLib;
|
||||
}
|
||||
|
||||
if (!lib_SymTab.d_tag == 0 &&
|
||||
!lib_StrTab.d_tag == 0)
|
||||
goto RetryNextLib;
|
||||
|
||||
Elf64_Rela *_lib_JmpRel = (Elf64_Rela *)(CurLib->LibraryMemoryImage + (lib_JmpRel.d_un.d_ptr - lib_BaseAddress));
|
||||
Elf64_Sym *_lib_SymTab = (Elf64_Sym *)(CurLib->LibraryMemoryImage + (lib_SymTab.d_un.d_ptr - lib_BaseAddress));
|
||||
|
||||
Elf64_Rela *_app_JmpRel = (Elf64_Rela *)(CurLib->ParentMemoryImage + (app_JmpRel.d_un.d_ptr - app_BaseAddress));
|
||||
Elf64_Sym *_app_SymTab = (Elf64_Sym *)(CurLib->ParentMemoryImage + (app_SymTab.d_un.d_ptr - app_BaseAddress));
|
||||
|
||||
char *lib_DynStr = (char *)(CurLib->LibraryMemoryImage + (lib_StrTab.d_un.d_ptr - lib_BaseAddress));
|
||||
char *app_DynStr = (char *)(CurLib->ParentMemoryImage + (app_StrTab.d_un.d_ptr - app_BaseAddress));
|
||||
|
||||
Elf64_Rela *Rel = _app_JmpRel + RelIndex;
|
||||
Elf64_Addr *GOTEntry = (Elf64_Addr *)(Rel->r_offset);
|
||||
|
||||
int RelType = ELF64_R_TYPE(Rel->r_info);
|
||||
|
||||
switch (RelType)
|
||||
{
|
||||
case R_X86_64_NONE:
|
||||
{
|
||||
PrintDbgNL("R_X86_64_NONE");
|
||||
if (*GOTEntry == 0)
|
||||
{
|
||||
PrintDbgNL("GOTEntry is 0");
|
||||
break;
|
||||
}
|
||||
Lock = 0;
|
||||
return (void (*)()) * GOTEntry;
|
||||
}
|
||||
case R_X86_64_JUMP_SLOT:
|
||||
{
|
||||
PrintDbgNL("R_X86_64_JUMP_SLOT");
|
||||
int SymIndex = ELF64_R_SYM(Rel->r_info);
|
||||
Elf64_Sym *Sym = _app_SymTab + SymIndex;
|
||||
|
||||
if (Sym->st_name)
|
||||
{
|
||||
char *SymName = app_DynStr + Sym->st_name;
|
||||
PrintDbg("SymName: ");
|
||||
PrintDbgNL(SymName);
|
||||
|
||||
Elf64_Sym LibSym = ELFLookupSymbol(ParentPath, SymName);
|
||||
|
||||
PrintDbg("LibSym: 0x");
|
||||
ltoaDbg((long)LibSym.st_size, DbgBuff, 16);
|
||||
PrintDbgNL(DbgBuff);
|
||||
|
||||
if (LibSym.st_value)
|
||||
{
|
||||
*GOTEntry = (Elf64_Addr)(CurLib->LibraryMemoryImage + LibSym.st_value);
|
||||
|
||||
ltoa(*GOTEntry, DbgBuff, 16);
|
||||
PrintDbg("*GOTEntry: 0x");
|
||||
PrintDbgNL(DbgBuff);
|
||||
|
||||
Lock = 0;
|
||||
return (void (*)()) * GOTEntry;
|
||||
}
|
||||
PrintDbgNL("Not found in lib");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ltoa(RelType, DbgBuff, 10);
|
||||
Print("RelType not supported ");
|
||||
PrintNL(DbgBuff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RetryNextLib:
|
||||
PrintDbgNL("Retrying next lib");
|
||||
CurLib = CurLib->Next;
|
||||
}
|
||||
|
||||
FailEnd:
|
||||
Lock = 0;
|
||||
__asm__ __volatile__("mfence\n");
|
||||
|
||||
Print("Symbol index ");
|
||||
ltoa(RelIndex, DbgBuff, 10);
|
||||
Print(DbgBuff);
|
||||
PrintNL(" not found");
|
||||
int ExitCode = 0x51801;
|
||||
syscall1(_Exit, ExitCode);
|
||||
while (1) // Make sure we don't return
|
||||
;
|
||||
}
|
||||
|
||||
/* Preload */
|
||||
int ld_main()
|
||||
{
|
||||
/* Prevent race condition. */
|
||||
uintptr_t KCTL_ret = KernelCTL(KCTL_IS_CRITICAL, 0, 0, 0, 0);
|
||||
do
|
||||
{
|
||||
syscall1(_Sleep, 250);
|
||||
KCTL_ret = KernelCTL(KCTL_IS_CRITICAL, 0, 0, 0, 0);
|
||||
} while (KCTL_ret == SYSCALL_ACCESS_DENIED);
|
||||
/* Prevent race condition. */
|
||||
uintptr_t KCTL_ret = KernelCTL(KCTL_IS_CRITICAL, 0, 0, 0, 0);
|
||||
do
|
||||
{
|
||||
syscall1(_Sleep, 250);
|
||||
KCTL_ret = KernelCTL(KCTL_IS_CRITICAL, 0, 0, 0, 0);
|
||||
} while (KCTL_ret == SYSCALL_ACCESS_DENIED);
|
||||
|
||||
if (KCTL_ret == false)
|
||||
return -4;
|
||||
if (KCTL_ret == false)
|
||||
return -1;
|
||||
|
||||
/* Everything is ok, continue. */
|
||||
return 0;
|
||||
/* Everything is ok, continue. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ELFAddLazyResolverToGOT(void *ElfFile, void *MemoryImage, struct LibAddressCollection *Libs)
|
||||
bool ELFAddLazyResolverToGOT(void *MemoryImage, struct LibsCollection *Libs)
|
||||
{
|
||||
struct Elf64_Dyn *Dyn = (struct Elf64_Dyn *)ELFGetDynamicTag(ElfFile, DT_PLTGOT);
|
||||
if (!Dyn)
|
||||
return false;
|
||||
struct Elf64_Dyn Dyn = ELFGetDynamicTag(ParentPath, DT_PLTGOT);
|
||||
if (!Dyn.d_tag)
|
||||
return false;
|
||||
|
||||
Elf64_Addr *GOT = (Elf64_Addr *)Dyn->d_un.d_ptr;
|
||||
Elf64_Addr *GOT = (Elf64_Addr *)Dyn.d_un.d_ptr;
|
||||
|
||||
GOT[1] = (uintptr_t)Libs;
|
||||
GOT[2] = (uintptr_t)ELF_LAZY_RESOLVE_STUB;
|
||||
return true;
|
||||
GOT[1] = (uintptr_t)Libs;
|
||||
GOT[2] = (uintptr_t)ELF_LAZY_RESOLVE_STUB;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Actual load */
|
||||
int ld_load(int argc, char *argv[], char *envp[])
|
||||
{
|
||||
uintptr_t PageSize = KernelCTL(KCTL_GET_PAGE_SIZE, 0, 0, 0, 0);
|
||||
int PagesForIPCDataStruct = sizeof(InterpreterIPCData) / PageSize + 1;
|
||||
InterpreterIPCData *IPCBuffer = (InterpreterIPCData *)RequestPages(PagesForIPCDataStruct);
|
||||
PrintDbgNL("!");
|
||||
uintptr_t PageSize = KernelCTL(KCTL_GET_PAGE_SIZE, 0, 0, 0, 0);
|
||||
int PagesForIPCDataStruct = sizeof(InterpreterIPCData) / PageSize + 1;
|
||||
int PagesForLibsCollectionStruct = sizeof(struct LibsCollection) / PageSize + 1;
|
||||
|
||||
int IPC_ID = IPC(IPC_CREATE, IPC_TYPE_MessagePassing, 0, 0, "LOAD", sizeof(InterpreterIPCData));
|
||||
while (true)
|
||||
{
|
||||
IPC(IPC_LISTEN, IPC_TYPE_MessagePassing, IPC_ID, 1, NULL, 0);
|
||||
IPC(IPC_WAIT, IPC_TYPE_MessagePassing, IPC_ID, 0, NULL, 0);
|
||||
int IPCResult = IPC(IPC_READ, IPC_TYPE_MessagePassing, IPC_ID, 0, IPCBuffer, PageSize);
|
||||
if (IPCResult == IPC_E_CODE_Success)
|
||||
break;
|
||||
}
|
||||
InterpreterIPCData *IPCBuffer =
|
||||
(InterpreterIPCData *)RequestPages(PagesForIPCDataStruct);
|
||||
|
||||
struct LibAddressCollection *LibsForLazyResolver = (struct LibAddressCollection *)RequestPages(sizeof(struct LibAddressCollection) / PageSize + 1);
|
||||
for (size_t i = 0; i < 64; i++)
|
||||
{
|
||||
if (IPCBuffer->Libraries[i].Name[0] == '\0')
|
||||
break;
|
||||
int IPC_ID = IPC(IPC_CREATE, IPC_TYPE_MessagePassing,
|
||||
0, 0, "LOAD", sizeof(InterpreterIPCData));
|
||||
while (true)
|
||||
{
|
||||
IPC(IPC_LISTEN, IPC_TYPE_MessagePassing, IPC_ID, 1, NULL, 0);
|
||||
IPC(IPC_WAIT, IPC_TYPE_MessagePassing, IPC_ID, 0, NULL, 0);
|
||||
int IPCResult = IPC(IPC_READ, IPC_TYPE_MessagePassing,
|
||||
IPC_ID, 0, IPCBuffer, PageSize);
|
||||
|
||||
uintptr_t lib_addr = KernelCTL(KCTL_GET_ELF_LIB_FILE, (uint64_t)IPCBuffer->Libraries[i].Name, 0, 0, 0);
|
||||
uintptr_t lib_mm_image = KernelCTL(KCTL_GET_ELF_LIB_MEMORY_IMAGE, (uint64_t)IPCBuffer->Libraries[i].Name, 0, 0, 0);
|
||||
if (lib_addr == 0 || lib_mm_image == 0)
|
||||
{
|
||||
enum SyscallsErrorCodes ret = KernelCTL(KCTL_REGISTER_ELF_LIB, (uint64_t)IPCBuffer->Libraries[i].Name, (uint64_t)IPCBuffer->Libraries[i].Name, 0, 0);
|
||||
if (ret != SYSCALL_OK)
|
||||
{
|
||||
PrintNL("Failed to register ELF lib");
|
||||
return -0x11B;
|
||||
}
|
||||
lib_addr = KernelCTL(KCTL_GET_ELF_LIB_FILE, (uint64_t)IPCBuffer->Libraries[i].Name, 0, 0, 0);
|
||||
lib_mm_image = KernelCTL(KCTL_GET_ELF_LIB_MEMORY_IMAGE, (uint64_t)IPCBuffer->Libraries[i].Name, 0, 0, 0);
|
||||
}
|
||||
if (IPCResult == IPC_E_CODE_Success)
|
||||
break;
|
||||
}
|
||||
|
||||
if (LibsForLazyResolver->Next == NULL)
|
||||
{
|
||||
LibsForLazyResolver->Valid = true;
|
||||
LibsForLazyResolver->ElfFile = (uintptr_t)lib_addr;
|
||||
LibsForLazyResolver->MemoryImage = (uintptr_t)lib_mm_image;
|
||||
LibsForLazyResolver->ParentElfFile = (uintptr_t)IPCBuffer->ElfFile;
|
||||
LibsForLazyResolver->ParentMemoryImage = (uintptr_t)IPCBuffer->MemoryImage;
|
||||
for (size_t j = 0; j < 32; j++)
|
||||
LibsForLazyResolver->Name[j] = IPCBuffer->Libraries[i].Name[j];
|
||||
struct LibsCollection *LibsForLazyResolver =
|
||||
(struct LibsCollection *)RequestPages(PagesForLibsCollectionStruct);
|
||||
|
||||
LibsForLazyResolver->Next = (struct LibAddressCollection *)RequestPages(sizeof(struct LibAddressCollection) / PageSize + 1);
|
||||
memset(LibsForLazyResolver->Next, 0, sizeof(struct LibAddressCollection));
|
||||
continue;
|
||||
}
|
||||
struct LibAddressCollection *CurrentLibsForLazyResolver = LibsForLazyResolver;
|
||||
for (short i = 0; i < 64; i++)
|
||||
{
|
||||
if (IPCBuffer->Libraries[i].Name[0] == '\0')
|
||||
break;
|
||||
|
||||
while (CurrentLibsForLazyResolver->Next != NULL)
|
||||
CurrentLibsForLazyResolver = CurrentLibsForLazyResolver->Next;
|
||||
uintptr_t lib_mm_image =
|
||||
KernelCTL(KCTL_GET_ELF_LIB_MEMORY_IMAGE,
|
||||
(uint64_t)IPCBuffer->Libraries[i].Name, 0, 0, 0);
|
||||
if (lib_mm_image == 0)
|
||||
{
|
||||
enum SyscallsErrorCodes ret =
|
||||
KernelCTL(KCTL_REGISTER_ELF_LIB,
|
||||
(uint64_t)IPCBuffer->Libraries[i].Name,
|
||||
(uint64_t)IPCBuffer->Libraries[i].Name, 0, 0);
|
||||
if (ret != SYSCALL_OK)
|
||||
{
|
||||
PrintNL("Failed to register ELF lib");
|
||||
return -0x11B;
|
||||
}
|
||||
lib_mm_image = KernelCTL(KCTL_GET_ELF_LIB_MEMORY_IMAGE,
|
||||
(uint64_t)IPCBuffer->Libraries[i].Name, 0, 0, 0);
|
||||
}
|
||||
|
||||
CurrentLibsForLazyResolver->Valid = true;
|
||||
CurrentLibsForLazyResolver->ElfFile = (uintptr_t)lib_addr;
|
||||
CurrentLibsForLazyResolver->MemoryImage = (uintptr_t)lib_mm_image;
|
||||
CurrentLibsForLazyResolver->ParentElfFile = (uintptr_t)IPCBuffer->ElfFile;
|
||||
CurrentLibsForLazyResolver->ParentMemoryImage = (uintptr_t)IPCBuffer->MemoryImage;
|
||||
for (size_t j = 0; j < 32; j++)
|
||||
CurrentLibsForLazyResolver->Name[j] = IPCBuffer->Libraries[i].Name[j];
|
||||
if (LibsForLazyResolver->Next == NULL)
|
||||
{
|
||||
LibsForLazyResolver->Valid = true;
|
||||
LibsForLazyResolver->LibraryMemoryImage = (uintptr_t)lib_mm_image;
|
||||
LibsForLazyResolver->ParentMemoryImage = (uintptr_t)IPCBuffer->MemoryImage;
|
||||
for (short j = 0; j < sizeof(LibsForLazyResolver->LibraryName); j++)
|
||||
LibsForLazyResolver->LibraryName[j] = IPCBuffer->Libraries[i].Name[j];
|
||||
|
||||
CurrentLibsForLazyResolver->Next = (struct LibAddressCollection *)RequestPages(sizeof(struct LibAddressCollection) / PageSize + 1);
|
||||
memset(CurrentLibsForLazyResolver->Next, 0, sizeof(struct LibAddressCollection));
|
||||
}
|
||||
LibsForLazyResolver->Next =
|
||||
(struct LibsCollection *)RequestPages(PagesForLibsCollectionStruct);
|
||||
memset(LibsForLazyResolver->Next, 0, sizeof(struct LibsCollection));
|
||||
continue;
|
||||
}
|
||||
|
||||
struct LibAddressCollection *CurrentLibsForLazyResolver = LibsForLazyResolver;
|
||||
struct LibsCollection *CurrentLib = LibsForLazyResolver;
|
||||
while (CurrentLib->Next != NULL)
|
||||
CurrentLib = CurrentLib->Next;
|
||||
|
||||
if (!ELFAddLazyResolverToGOT(IPCBuffer->ElfFile, IPCBuffer->MemoryImage, LibsForLazyResolver))
|
||||
{
|
||||
PrintNL("Failed to add lazy resolver to GOT");
|
||||
return -0x607;
|
||||
}
|
||||
CurrentLib->Valid = true;
|
||||
CurrentLib->LibraryMemoryImage = (uintptr_t)lib_mm_image;
|
||||
CurrentLib->ParentMemoryImage = (uintptr_t)IPCBuffer->MemoryImage;
|
||||
for (short j = 0; j < sizeof(LibsForLazyResolver->LibraryName); j++)
|
||||
CurrentLib->LibraryName[j] = IPCBuffer->Libraries[i].Name[j];
|
||||
|
||||
Elf64_Addr Entry = ((Elf64_Ehdr *)IPCBuffer->ElfFile)->e_entry;
|
||||
CurrentLib->Next =
|
||||
(struct LibsCollection *)RequestPages(PagesForLibsCollectionStruct);
|
||||
memset(CurrentLib->Next, 0, sizeof(struct LibsCollection));
|
||||
}
|
||||
|
||||
IPC(IPC_DELETE, IPC_TYPE_MessagePassing, IPC_ID, 0, NULL, 0);
|
||||
FreePages((uintptr_t)IPCBuffer, PagesForIPCDataStruct);
|
||||
struct LibsCollection *CurrentLib = LibsForLazyResolver;
|
||||
|
||||
return ((int (*)(int, char *[], char *[]))Entry)(argc, argv, envp);
|
||||
for (int i = 0; i < sizeof(ParentPath); i++)
|
||||
ParentPath[i] = IPCBuffer->Path[i];
|
||||
|
||||
if (!ELFAddLazyResolverToGOT(IPCBuffer->MemoryImage,
|
||||
LibsForLazyResolver))
|
||||
{
|
||||
PrintNL("Failed to add lazy resolver to GOT");
|
||||
return -0x607;
|
||||
}
|
||||
|
||||
void *KP = syscall2(_FileOpen, ParentPath, (long)"r");
|
||||
if (KP == NULL)
|
||||
{
|
||||
PrintNL("Failed to open file");
|
||||
syscall1(_Exit, -0xF17E);
|
||||
}
|
||||
|
||||
Elf64_Ehdr ELFHeader;
|
||||
syscall3(_FileRead, KP, &ELFHeader, sizeof(Elf64_Ehdr));
|
||||
|
||||
Elf64_Addr Entry = ELFHeader.e_entry;
|
||||
|
||||
syscall1(_FileClose, KP);
|
||||
|
||||
IPC(IPC_DELETE, IPC_TYPE_MessagePassing, IPC_ID, 0, NULL, 0);
|
||||
FreePages((uintptr_t)IPCBuffer, PagesForIPCDataStruct);
|
||||
|
||||
PrintDbgNL("Calling entry point");
|
||||
return ((int (*)(int, char *[], char *[]))Entry)(argc, argv, envp);
|
||||
}
|
||||
|
@ -1,36 +1,36 @@
|
||||
void __attribute__((naked, used, no_stack_protector)) _ld_start()
|
||||
void __attribute__((naked, used, no_stack_protector)) _start()
|
||||
{
|
||||
__asm__("movq $0, %rbp\n"
|
||||
"pushq %rbp\n"
|
||||
"pushq %rbp\n"
|
||||
"movq %rsp, %rbp\n"
|
||||
__asm__("movq $0, %rbp\n"
|
||||
"pushq %rbp\n"
|
||||
"pushq %rbp\n"
|
||||
"movq %rsp, %rbp\n"
|
||||
|
||||
"pushq %rcx\n"
|
||||
"pushq %rdx\n"
|
||||
"pushq %rsi\n"
|
||||
"pushq %rdi\n"
|
||||
"pushq %rcx\n"
|
||||
"pushq %rdx\n"
|
||||
"pushq %rsi\n"
|
||||
"pushq %rdi\n"
|
||||
|
||||
"call ld_main\n"
|
||||
"movl %eax, %edi\n" // Move return value to edi
|
||||
"cmp $0, %edi\n" // Check if return value is 0
|
||||
"jne _exit\n" // If not, jump to _exit
|
||||
"call ld_main\n"
|
||||
"movl %eax, %edi\n" // Move return value to edi
|
||||
"cmp $0, %edi\n" // Check if return value is 0
|
||||
"jne _exit\n" // If not, jump to _exit
|
||||
|
||||
"popq %rdi\n"
|
||||
"popq %rsi\n"
|
||||
"popq %rdx\n"
|
||||
"popq %rcx\n"
|
||||
"popq %rdi\n"
|
||||
"popq %rsi\n"
|
||||
"popq %rdx\n"
|
||||
"popq %rcx\n"
|
||||
|
||||
"call ld_load\n"
|
||||
"movl %eax, %edi\n" // Move return value to edi
|
||||
"call _exit"); // Call _exit
|
||||
"call ld_load\n"
|
||||
"movl %eax, %edi\n" // Move return value to edi
|
||||
"call _exit"); // Call _exit
|
||||
}
|
||||
|
||||
void _exit(int Code)
|
||||
{
|
||||
__asm__ __volatile__("syscall"
|
||||
:
|
||||
: "a"(0), "D"(Code)
|
||||
: "rcx", "r11", "memory");
|
||||
while (1)
|
||||
;
|
||||
__asm__ __volatile__("syscall"
|
||||
:
|
||||
: "a"(0), "D"(Code)
|
||||
: "rcx", "r11", "memory");
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
@ -2,249 +2,249 @@
|
||||
/* This function is a mess and needs to be cleaned up. */
|
||||
bool ELFDynamicReallocation(void *ElfFile, void *MemoryImage)
|
||||
{
|
||||
debug("ELF dynamic reallocation for image at %#lx.", ElfFile);
|
||||
debug("ELF dynamic reallocation for image at %#lx.", ElfFile);
|
||||
|
||||
Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)ElfFile;
|
||||
uintptr_t BaseAddress = UINTPTR_MAX;
|
||||
size_t ElfAppSize = 0;
|
||||
Elf64_Phdr ItrPhdr;
|
||||
Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)ElfFile;
|
||||
uintptr_t BaseAddress = UINTPTR_MAX;
|
||||
size_t ElfAppSize = 0;
|
||||
Elf64_Phdr ItrPhdr;
|
||||
|
||||
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
|
||||
{
|
||||
memcpy(&ItrPhdr,
|
||||
(uint8_t *)ElfFile + ELFHeader->e_phoff + ELFHeader->e_phentsize * i,
|
||||
sizeof(Elf64_Phdr));
|
||||
BaseAddress = MIN(BaseAddress, ItrPhdr.p_vaddr);
|
||||
}
|
||||
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
|
||||
{
|
||||
memcpy(&ItrPhdr,
|
||||
(uint8_t *)ElfFile + ELFHeader->e_phoff + ELFHeader->e_phentsize * i,
|
||||
sizeof(Elf64_Phdr));
|
||||
BaseAddress = MIN(BaseAddress, ItrPhdr.p_vaddr);
|
||||
}
|
||||
|
||||
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
|
||||
{
|
||||
memcpy(&ItrPhdr,
|
||||
(uint8_t *)ElfFile + ELFHeader->e_phoff + ELFHeader->e_phentsize * i,
|
||||
sizeof(Elf64_Phdr));
|
||||
uintptr_t SegmentEnd = ItrPhdr.p_vaddr - BaseAddress + ItrPhdr.p_memsz;
|
||||
ElfAppSize = MAX(ElfAppSize, SegmentEnd);
|
||||
}
|
||||
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
|
||||
{
|
||||
memcpy(&ItrPhdr,
|
||||
(uint8_t *)ElfFile + ELFHeader->e_phoff + ELFHeader->e_phentsize * i,
|
||||
sizeof(Elf64_Phdr));
|
||||
uintptr_t SegmentEnd = ItrPhdr.p_vaddr - BaseAddress + ItrPhdr.p_memsz;
|
||||
ElfAppSize = MAX(ElfAppSize, SegmentEnd);
|
||||
}
|
||||
|
||||
debug("BaseAddress: %#lx Size: %ld", BaseAddress, ElfAppSize);
|
||||
debug("BaseAddress: %#lx Size: %ld", BaseAddress, ElfAppSize);
|
||||
|
||||
Elf64_Dyn *_GOTEntry = (Elf64_Dyn *)ELFGetDynamicTag(ElfFile, DT_PLTGOT);
|
||||
Elf64_Dyn *_Rela = ELFGetDynamicTag(ElfFile, DT_RELA);
|
||||
Elf64_Dyn *_RelaEnt = ELFGetDynamicTag(ElfFile, DT_RELAENT);
|
||||
Elf64_Dyn *_JmpRel = ELFGetDynamicTag(ElfFile, DT_JMPREL);
|
||||
Elf64_Dyn *_SymTab = ELFGetDynamicTag(ElfFile, DT_SYMTAB);
|
||||
Elf64_Dyn *_StrTab = ELFGetDynamicTag(ElfFile, DT_STRTAB);
|
||||
Elf64_Dyn *RelaSize = ELFGetDynamicTag(ElfFile, DT_RELASZ);
|
||||
Elf64_Dyn *PltRelSize = ELFGetDynamicTag(ElfFile, DT_PLTRELSZ);
|
||||
Elf64_Dyn *_GOTEntry = (Elf64_Dyn *)ELFGetDynamicTag(ElfFile, DT_PLTGOT);
|
||||
Elf64_Dyn *_Rela = ELFGetDynamicTag(ElfFile, DT_RELA);
|
||||
Elf64_Dyn *_RelaEnt = ELFGetDynamicTag(ElfFile, DT_RELAENT);
|
||||
Elf64_Dyn *_JmpRel = ELFGetDynamicTag(ElfFile, DT_JMPREL);
|
||||
Elf64_Dyn *_SymTab = ELFGetDynamicTag(ElfFile, DT_SYMTAB);
|
||||
Elf64_Dyn *_StrTab = ELFGetDynamicTag(ElfFile, DT_STRTAB);
|
||||
Elf64_Dyn *RelaSize = ELFGetDynamicTag(ElfFile, DT_RELASZ);
|
||||
Elf64_Dyn *PltRelSize = ELFGetDynamicTag(ElfFile, DT_PLTRELSZ);
|
||||
|
||||
Elf64_Addr *GOTEntry = (Elf64_Addr *)((uintptr_t)(_GOTEntry->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
|
||||
Elf64_Dyn *Rela = (Elf64_Dyn *)((uintptr_t)(_Rela->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
|
||||
Elf64_Dyn *RelaEnt = (Elf64_Dyn *)((uintptr_t)(_RelaEnt->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
|
||||
Elf64_Dyn *JmpRel = (Elf64_Dyn *)((uintptr_t)(_JmpRel->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
|
||||
Elf64_Dyn *SymTab = (Elf64_Dyn *)((uintptr_t)(_SymTab->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
|
||||
Elf64_Dyn *StrTab = (Elf64_Dyn *)((uintptr_t)(_StrTab->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
|
||||
Elf64_Addr *GOTEntry = (Elf64_Addr *)((uintptr_t)(_GOTEntry->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
|
||||
Elf64_Dyn *Rela = (Elf64_Dyn *)((uintptr_t)(_Rela->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
|
||||
Elf64_Dyn *RelaEnt = (Elf64_Dyn *)((uintptr_t)(_RelaEnt->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
|
||||
Elf64_Dyn *JmpRel = (Elf64_Dyn *)((uintptr_t)(_JmpRel->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
|
||||
Elf64_Dyn *SymTab = (Elf64_Dyn *)((uintptr_t)(_SymTab->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
|
||||
Elf64_Dyn *StrTab = (Elf64_Dyn *)((uintptr_t)(_StrTab->d_un.d_ptr - BaseAddress) + (uintptr_t)MemoryImage);
|
||||
|
||||
debug("GOTEntry: %#lx [%#lx]", _GOTEntry, GOTEntry);
|
||||
debug("Rela: %#lx [%#lx]", _Rela, Rela);
|
||||
debug("RelaEnt: %#lx [%#lx]", _RelaEnt, RelaEnt);
|
||||
debug("JmpRel: %#lx [%#lx]", _JmpRel, JmpRel);
|
||||
debug("SymTab: %#lx [%#lx]", _SymTab, SymTab);
|
||||
debug("StrTab: %#lx [%#lx]", _StrTab, StrTab);
|
||||
if (RelaSize)
|
||||
debug("RelaSize: %ld", RelaSize->d_un.d_val);
|
||||
if (PltRelSize)
|
||||
debug("PltRelSize: %ld", PltRelSize->d_un.d_val);
|
||||
debug("GOTEntry: %#lx [%#lx]", _GOTEntry, GOTEntry);
|
||||
debug("Rela: %#lx [%#lx]", _Rela, Rela);
|
||||
debug("RelaEnt: %#lx [%#lx]", _RelaEnt, RelaEnt);
|
||||
debug("JmpRel: %#lx [%#lx]", _JmpRel, JmpRel);
|
||||
debug("SymTab: %#lx [%#lx]", _SymTab, SymTab);
|
||||
debug("StrTab: %#lx [%#lx]", _StrTab, StrTab);
|
||||
if (RelaSize)
|
||||
debug("RelaSize: %ld", RelaSize->d_un.d_val);
|
||||
if (PltRelSize)
|
||||
debug("PltRelSize: %ld", PltRelSize->d_un.d_val);
|
||||
|
||||
Elf64_Xword PltRelSizeVal = PltRelSize ? PltRelSize->d_un.d_val : 0;
|
||||
Elf64_Xword RelaSizeVal = RelaSize ? RelaSize->d_un.d_val : 0;
|
||||
Elf64_Xword PltRelSizeVal = PltRelSize ? PltRelSize->d_un.d_val : 0;
|
||||
Elf64_Xword RelaSizeVal = RelaSize ? RelaSize->d_un.d_val : 0;
|
||||
|
||||
Elf64_Xword PltRelSizeValCount = PltRelSizeVal / sizeof(Elf64_Rela);
|
||||
Elf64_Xword RelaSizeValCount = RelaSizeVal / sizeof(Elf64_Rela);
|
||||
Elf64_Xword PltRelSizeValCount = PltRelSizeVal / sizeof(Elf64_Rela);
|
||||
Elf64_Xword RelaSizeValCount = RelaSizeVal / sizeof(Elf64_Rela);
|
||||
|
||||
debug("PltRelSizeVal: %ld", PltRelSizeVal);
|
||||
debug("RelaSizeVal: %ld", RelaSizeVal);
|
||||
debug("PltRelSizeValCount: %ld", PltRelSizeValCount);
|
||||
debug("RelaSizeValCount: %ld", RelaSizeValCount);
|
||||
debug("PltRelSizeVal: %ld", PltRelSizeVal);
|
||||
debug("RelaSizeVal: %ld", RelaSizeVal);
|
||||
debug("PltRelSizeValCount: %ld", PltRelSizeValCount);
|
||||
debug("RelaSizeValCount: %ld", RelaSizeValCount);
|
||||
|
||||
for (Elf64_Xword i = 0; i < PltRelSizeValCount; i++)
|
||||
{
|
||||
Elf64_Rela *RelaF = (Elf64_Rela *)((uintptr_t)JmpRel + i);
|
||||
Elf64_Xword RelaType = ELF64_R_TYPE(RelaF->r_info);
|
||||
debug("Itr %ld Type %ld", i, RelaType);
|
||||
for (Elf64_Xword i = 0; i < PltRelSizeValCount; i++)
|
||||
{
|
||||
Elf64_Rela *RelaF = (Elf64_Rela *)((uintptr_t)JmpRel + i);
|
||||
Elf64_Xword RelaType = ELF64_R_TYPE(RelaF->r_info);
|
||||
debug("Itr %ld Type %ld", i, RelaType);
|
||||
|
||||
switch (RelaType)
|
||||
{
|
||||
case R_X86_64_NONE:
|
||||
{
|
||||
debug("No relocation needed");
|
||||
break;
|
||||
}
|
||||
case R_X86_64_JUMP_SLOT:
|
||||
{
|
||||
debug("Relocation for jump slot");
|
||||
Elf64_Xword SymIndex = ELF64_R_SYM(RelaF->r_info);
|
||||
Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)SymTab + SymIndex);
|
||||
char *SymName = (char *)((uintptr_t)StrTab + Sym->st_name);
|
||||
debug("Symbol %s at %#lx", SymName, Sym->st_value);
|
||||
switch (RelaType)
|
||||
{
|
||||
case R_X86_64_NONE:
|
||||
{
|
||||
debug("No relocation needed");
|
||||
break;
|
||||
}
|
||||
case R_X86_64_JUMP_SLOT:
|
||||
{
|
||||
debug("Relocation for jump slot");
|
||||
Elf64_Xword SymIndex = ELF64_R_SYM(RelaF->r_info);
|
||||
Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)SymTab + SymIndex);
|
||||
char *SymName = (char *)((uintptr_t)StrTab + Sym->st_name);
|
||||
debug("Symbol %s at %#lx", SymName, Sym->st_value);
|
||||
|
||||
Elf64_Addr *GOTEntry = (Elf64_Addr *)RelaF->r_offset;
|
||||
if (Sym->st_value)
|
||||
{
|
||||
fixme("Not implemented");
|
||||
*GOTEntry = (Elf64_Addr)ElfFile + Sym->st_value;
|
||||
}
|
||||
// else
|
||||
// *GOTEntry = (Elf64_Addr)ElfLazyResolver;
|
||||
Elf64_Addr *GOTEntry = (Elf64_Addr *)RelaF->r_offset;
|
||||
if (Sym->st_value)
|
||||
{
|
||||
fixme("Not implemented");
|
||||
*GOTEntry = (Elf64_Addr)ElfFile + Sym->st_value;
|
||||
}
|
||||
// else
|
||||
// *GOTEntry = (Elf64_Addr)ElfLazyResolver;
|
||||
|
||||
// Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)ElfFile + (uintptr_t)SymTab + ELF64_R_SYM(RelaF->r_info) * sizeof(Elf64_Sym));
|
||||
// char *SymName = (char *)((uintptr_t)ElfFile + (uintptr_t)StrTab + Sym->st_name);
|
||||
// void *SymAddr = (void *)Lib->Address + Sym->st_value;
|
||||
// debug("Symbol %s at %#lx", SymName, SymAddr);
|
||||
// *(void **)(RelaF->r_offset + (uintptr_t)ElfFile) = SymAddr;
|
||||
break;
|
||||
}
|
||||
case R_X86_64_RELATIVE:
|
||||
{
|
||||
debug("Relative relocation");
|
||||
uintptr_t *Ptr = (uintptr_t *)((uintptr_t)ElfFile + RelaF->r_offset);
|
||||
*Ptr = (uintptr_t)MemoryImage + RelaF->r_addend;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
fixme("RelaType %d", RelaType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)ElfFile + (uintptr_t)SymTab + ELF64_R_SYM(RelaF->r_info) * sizeof(Elf64_Sym));
|
||||
// char *SymName = (char *)((uintptr_t)ElfFile + (uintptr_t)StrTab + Sym->st_name);
|
||||
// void *SymAddr = (void *)Lib->Address + Sym->st_value;
|
||||
// debug("Symbol %s at %#lx", SymName, SymAddr);
|
||||
// *(void **)(RelaF->r_offset + (uintptr_t)ElfFile) = SymAddr;
|
||||
break;
|
||||
}
|
||||
case R_X86_64_RELATIVE:
|
||||
{
|
||||
debug("Relative relocation");
|
||||
uintptr_t *Ptr = (uintptr_t *)((uintptr_t)ElfFile + RelaF->r_offset);
|
||||
*Ptr = (uintptr_t)MemoryImage + RelaF->r_addend;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
fixme("RelaType %d", RelaType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Elf64_Xword i = 0; i < RelaSizeValCount; i++)
|
||||
{
|
||||
Elf64_Rela *RelaF = (Elf64_Rela *)((uintptr_t)ElfFile + (uintptr_t)Rela + i);
|
||||
Elf64_Xword RelaType = ELF64_R_TYPE(RelaF->r_info);
|
||||
debug("Itr %ld Type %ld", i, RelaType);
|
||||
for (Elf64_Xword i = 0; i < RelaSizeValCount; i++)
|
||||
{
|
||||
Elf64_Rela *RelaF = (Elf64_Rela *)((uintptr_t)ElfFile + (uintptr_t)Rela + i);
|
||||
Elf64_Xword RelaType = ELF64_R_TYPE(RelaF->r_info);
|
||||
debug("Itr %ld Type %ld", i, RelaType);
|
||||
|
||||
switch (RelaType)
|
||||
{
|
||||
case R_X86_64_NONE:
|
||||
{
|
||||
debug("No relocation needed");
|
||||
break;
|
||||
}
|
||||
case R_X86_64_64:
|
||||
{
|
||||
debug("64-bit relocation");
|
||||
Elf64_Xword SymIndex = ELF64_R_SYM(RelaF->r_info);
|
||||
Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)ElfFile + (uintptr_t)SymTab + SymIndex);
|
||||
char *SymName = (char *)((uintptr_t)ElfFile + (uintptr_t)StrTab + Sym->st_name);
|
||||
debug("Symbol %s at %#lx", SymName, Sym->st_value);
|
||||
switch (RelaType)
|
||||
{
|
||||
case R_X86_64_NONE:
|
||||
{
|
||||
debug("No relocation needed");
|
||||
break;
|
||||
}
|
||||
case R_X86_64_64:
|
||||
{
|
||||
debug("64-bit relocation");
|
||||
Elf64_Xword SymIndex = ELF64_R_SYM(RelaF->r_info);
|
||||
Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)ElfFile + (uintptr_t)SymTab + SymIndex);
|
||||
char *SymName = (char *)((uintptr_t)ElfFile + (uintptr_t)StrTab + Sym->st_name);
|
||||
debug("Symbol %s at %#lx", SymName, Sym->st_value);
|
||||
|
||||
uintptr_t *Ptr = (uintptr_t *)((uintptr_t)ElfFile + RelaF->r_offset);
|
||||
*Ptr = (uintptr_t)MemoryImage + Sym->st_value + RelaF->r_addend;
|
||||
break;
|
||||
}
|
||||
case R_X86_64_GLOB_DAT:
|
||||
{
|
||||
debug("Global data relocation");
|
||||
Elf64_Xword SymIndex = ELF64_R_SYM(RelaF->r_info);
|
||||
Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)ElfFile + (uintptr_t)SymTab + SymIndex);
|
||||
char *SymName = (char *)((uintptr_t)ElfFile + (uintptr_t)StrTab + Sym->st_name);
|
||||
debug("Symbol %s at %#lx", SymName, Sym->st_value);
|
||||
uintptr_t *Ptr = (uintptr_t *)((uintptr_t)ElfFile + RelaF->r_offset);
|
||||
*Ptr = (uintptr_t)MemoryImage + Sym->st_value + RelaF->r_addend;
|
||||
break;
|
||||
}
|
||||
case R_X86_64_GLOB_DAT:
|
||||
{
|
||||
debug("Global data relocation");
|
||||
Elf64_Xword SymIndex = ELF64_R_SYM(RelaF->r_info);
|
||||
Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)ElfFile + (uintptr_t)SymTab + SymIndex);
|
||||
char *SymName = (char *)((uintptr_t)ElfFile + (uintptr_t)StrTab + Sym->st_name);
|
||||
debug("Symbol %s at %#lx", SymName, Sym->st_value);
|
||||
|
||||
uintptr_t *Ptr = (uintptr_t *)((uintptr_t)ElfFile + RelaF->r_offset);
|
||||
*Ptr = (uintptr_t)MemoryImage + Sym->st_value;
|
||||
break;
|
||||
}
|
||||
case R_X86_64_RELATIVE:
|
||||
{
|
||||
debug("Relative relocation");
|
||||
Elf64_Xword SymIndex = ELF64_R_SYM(RelaF->r_info);
|
||||
Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)ElfFile + (uintptr_t)SymTab + SymIndex);
|
||||
char *SymName = (char *)((uintptr_t)ElfFile + (uintptr_t)StrTab + Sym->st_name);
|
||||
debug("Symbol %s at %#lx", SymName, Sym->st_value);
|
||||
uintptr_t *Ptr = (uintptr_t *)((uintptr_t)ElfFile + RelaF->r_offset);
|
||||
*Ptr = (uintptr_t)MemoryImage + Sym->st_value;
|
||||
break;
|
||||
}
|
||||
case R_X86_64_RELATIVE:
|
||||
{
|
||||
debug("Relative relocation");
|
||||
Elf64_Xword SymIndex = ELF64_R_SYM(RelaF->r_info);
|
||||
Elf64_Sym *Sym = (Elf64_Sym *)((uintptr_t)ElfFile + (uintptr_t)SymTab + SymIndex);
|
||||
char *SymName = (char *)((uintptr_t)ElfFile + (uintptr_t)StrTab + Sym->st_name);
|
||||
debug("Symbol %s at %#lx", SymName, Sym->st_value);
|
||||
|
||||
uintptr_t *Ptr = (uintptr_t *)((uintptr_t)ElfFile + RelaF->r_offset);
|
||||
*Ptr = (uintptr_t)MemoryImage + RelaF->r_addend;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
fixme("RelaType %d", RelaType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
uintptr_t *Ptr = (uintptr_t *)((uintptr_t)ElfFile + RelaF->r_offset);
|
||||
*Ptr = (uintptr_t)MemoryImage + RelaF->r_addend;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
fixme("RelaType %d", RelaType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
ELFDynamicReallocation(ElfFile, MemoryImage);
|
||||
ELFDynamicReallocation(ElfFile, MemoryImage);
|
||||
|
||||
LibAddressCollection *LibsForLazyResolver = (LibAddressCollection *)ELFBase.TmpMem->RequestPages(TO_PAGES(sizeof(LibAddressCollection)), true);
|
||||
memset(LibsForLazyResolver, 0, sizeof(LibAddressCollection));
|
||||
LibAddressCollection *LFLRTmp = LibsForLazyResolver;
|
||||
debug("LibsForLazyResolver: %#lx", LibsForLazyResolver);
|
||||
LibAddressCollection *LibsForLazyResolver = (LibAddressCollection *)ELFBase.TmpMem->RequestPages(TO_PAGES(sizeof(LibAddressCollection)), true);
|
||||
memset(LibsForLazyResolver, 0, sizeof(LibAddressCollection));
|
||||
LibAddressCollection *LFLRTmp = LibsForLazyResolver;
|
||||
debug("LibsForLazyResolver: %#lx", LibsForLazyResolver);
|
||||
|
||||
if (NeededLibraries.size() > 0)
|
||||
{
|
||||
VirtualFileSystem::Node *ParentNode = ExFile->Node->Parent; // Working Directory
|
||||
if (ParentNode)
|
||||
{
|
||||
char *WorkingDirAbsolutePath = vfs->GetPathFromNode(ParentNode);
|
||||
debug("Working directory: \"%s\"", WorkingDirAbsolutePath);
|
||||
if (NeededLibraries.size() > 0)
|
||||
{
|
||||
VirtualFileSystem::Node *ParentNode = ExFile->Node->Parent; // Working Directory
|
||||
if (ParentNode)
|
||||
{
|
||||
char *WorkingDirAbsolutePath = vfs->GetPathFromNode(ParentNode);
|
||||
debug("Working directory: \"%s\"", WorkingDirAbsolutePath);
|
||||
|
||||
int LibCount = 0;
|
||||
foreach (auto Library in NeededLibraries)
|
||||
{
|
||||
char LibPath[256];
|
||||
strcpy(LibPath, WorkingDirAbsolutePath);
|
||||
strcat(LibPath, "/");
|
||||
strcat(LibPath, Library);
|
||||
debug("Searching for \"%s\"...", LibPath);
|
||||
int LibCount = 0;
|
||||
foreach (auto Library in NeededLibraries)
|
||||
{
|
||||
char LibPath[256];
|
||||
strcpy(LibPath, WorkingDirAbsolutePath);
|
||||
strcat(LibPath, "/");
|
||||
strcat(LibPath, Library);
|
||||
debug("Searching for \"%s\"...", LibPath);
|
||||
|
||||
bool AlreadyTried = false;
|
||||
bool AlreadyTried = false;
|
||||
|
||||
LibPathRetry:
|
||||
VirtualFileSystem::FILE *LibNode = vfs->Open(LibPath);
|
||||
LibPathRetry:
|
||||
VirtualFileSystem::FILE *LibNode = vfs->Open(LibPath);
|
||||
|
||||
if (LibNode->Status != VirtualFileSystem::FileStatus::OK)
|
||||
{
|
||||
vfs->Close(LibNode);
|
||||
if (!AlreadyTried)
|
||||
{
|
||||
debug("Library \"%s\" not found, retrying... (%#x)", LibPath, LibNode->Status);
|
||||
memset(LibPath, 0, 256);
|
||||
strcpy(LibPath, "/lib/");
|
||||
strcat(LibPath, Library);
|
||||
AlreadyTried = true;
|
||||
goto LibPathRetry;
|
||||
}
|
||||
else
|
||||
warn("Failed to load library \"%s\" (%#x)", Library, LibNode->Status);
|
||||
}
|
||||
else
|
||||
{
|
||||
debug("Library found \"%s\" (%#x)", LibPath, LibNode->Status);
|
||||
SharedLibraries *sl = AddLibrary(Library, (void *)LibNode->Node->Address, LibNode->Node->Length);
|
||||
strcpy(LFLRTmp->Name, Library);
|
||||
LFLRTmp->ElfFile = (uintptr_t *)sl->Address;
|
||||
LFLRTmp->MemoryImage = (uintptr_t *)sl->MemoryImage;
|
||||
LFLRTmp->ParentElfFile = (uintptr_t *)ElfFile;
|
||||
LFLRTmp->ParentMemoryImage = (uintptr_t *)MemoryImage;
|
||||
LFLRTmp->Valid = true;
|
||||
debug("LIBRARY: %s, %#lx, %#lx", Library, LFLRTmp->ElfFile, LFLRTmp->MemoryImage);
|
||||
if (LibNode->Status != VirtualFileSystem::FileStatus::OK)
|
||||
{
|
||||
vfs->Close(LibNode);
|
||||
if (!AlreadyTried)
|
||||
{
|
||||
debug("Library \"%s\" not found, retrying... (%#x)", LibPath, LibNode->Status);
|
||||
memset(LibPath, 0, 256);
|
||||
strcpy(LibPath, "/lib/");
|
||||
strcat(LibPath, Library);
|
||||
AlreadyTried = true;
|
||||
goto LibPathRetry;
|
||||
}
|
||||
else
|
||||
warn("Failed to load library \"%s\" (%#x)", Library, LibNode->Status);
|
||||
}
|
||||
else
|
||||
{
|
||||
debug("Library found \"%s\" (%#x)", LibPath, LibNode->Status);
|
||||
SharedLibraries *sl = AddLibrary(Library, (void *)LibNode->Node->Address, LibNode->Node->Length);
|
||||
strcpy(LFLRTmp->Name, Library);
|
||||
LFLRTmp->ElfFile = (uintptr_t *)sl->Address;
|
||||
LFLRTmp->MemoryImage = (uintptr_t *)sl->MemoryImage;
|
||||
LFLRTmp->ParentElfFile = (uintptr_t *)ElfFile;
|
||||
LFLRTmp->ParentMemoryImage = (uintptr_t *)MemoryImage;
|
||||
LFLRTmp->Valid = true;
|
||||
debug("LIBRARY: %s, %#lx, %#lx", Library, LFLRTmp->ElfFile, LFLRTmp->MemoryImage);
|
||||
|
||||
LFLRTmp->Next = (LibAddressCollection *)ELFBase.TmpMem->RequestPages(TO_PAGES(sizeof(LibAddressCollection)), true);
|
||||
LFLRTmp = LFLRTmp->Next;
|
||||
memset(LFLRTmp, 0, sizeof(LibAddressCollection));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error("Couldn't get the parent node from path %s", vfs->GetPathFromNode(ExFile->Node));
|
||||
}
|
||||
}
|
||||
LFLRTmp->Next = (LibAddressCollection *)ELFBase.TmpMem->RequestPages(TO_PAGES(sizeof(LibAddressCollection)), true);
|
||||
LFLRTmp = LFLRTmp->Next;
|
||||
memset(LFLRTmp, 0, sizeof(LibAddressCollection));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error("Couldn't get the parent node from path %s", vfs->GetPathFromNode(ExFile->Node));
|
||||
}
|
||||
}
|
||||
|
||||
ELFAddLazyResolverToGOT(ElfFile, MemoryImage, LibsForLazyResolver);
|
||||
ELFAddLazyResolverToGOT(ElfFile, MemoryImage, LibsForLazyResolver);
|
||||
|
||||
|
Reference in New Issue
Block a user