Skip to content

Commit ee44d1e

Browse files
committed
Added somewhat decent dyn library loading
1 parent e44f469 commit ee44d1e

File tree

5 files changed

+141
-90
lines changed

5 files changed

+141
-90
lines changed

source/boot/limine.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ TERM_FONT=boot:///iso.f16
2121
COMMENT=This mode randomize the memory location where the kernel is loaded. Architecture: ${ARCH}
2222
PROTOCOL=limine
2323

24-
# MODULE_PATH=${FDMold}
24+
MODULE_PATH=${FDMold}
2525
MODULE_PATH=${FDM}
2626

2727
# Path to the kernel to boot. boot:/// represents the partition on which limine.cfg is located.
@@ -35,7 +35,7 @@ TERM_FONT=boot:///iso.f16
3535
# Disable KASLR (it is enabled by default for relocatable kernels)
3636
KASLR=no
3737

38-
# MODULE_PATH=${FDMold}
38+
MODULE_PATH=${FDMold}
3939
MODULE_PATH=${FDM}
4040

4141
KERNEL_PATH=${WING_KERNEL}

source/includes/fdlfcn.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ typedef struct
1212
Elf64_Rela* relocations;
1313

1414
int symtab_index;
15+
void* string_table_data;
1516
void* text_section_data;
1617
void* data_section_data;
1718
void* rodata_section_data;
19+
void* symtab_str_section_data;
1820

1921
Elf64_Shdr* text_section_header;
2022
Elf64_Shdr* data_section_header;

source/kernel/C/fdlfcn.c

Lines changed: 115 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1+
#include <graphics.h>
12
#include <memory2.h>
23
#include <fdlfcn.h>
34
#include <stdint.h>
45
#include <stddef.h>
56
#include <heap.h>
67
#include <elf.h>
78

8-
#define READ_FROM_MEMORY(dest, base, offset, size) memcpy(dest, (void*)( (uint8_t*)base + offset ), size)
9+
#define READ_FROM_MEMORY(dest, base, offset, size) printf("reading at address 0x%x", (uint64_t)base + (uint64_t)offset); memcpy(dest, (void*)( (uint64_t)base + (uint64_t)offset ), size)
910

1011
void* fdl_load_section(void* filedata, Elf64_Shdr* section_header)
1112
{
1213
void* section_data = malloc(section_header->sh_size);
13-
if (section_data == NULL) {
14-
error("fdlopen: malloc failed for section");
14+
if (section_data == NULL)
15+
{
16+
error("fdlopen: malloc failed for section", __FILE__);
1517
return NULL;
1618
}
1719

@@ -22,94 +24,111 @@ void* fdl_load_section(void* filedata, Elf64_Shdr* section_header)
2224

2325
int fdl_apply_relocations(fdlfcn_handle* lib, int reloc_section_index)
2426
{
27+
if (lib == NULL || reloc_section_index == -1)
28+
return 1;
29+
2530
Elf64_Ehdr* elf_header = &lib->ehdr;
2631
Elf64_Shdr* section_headers = lib->shdrs;
2732
Elf64_Sym* symbols = lib->symbols;
2833
Elf64_Rela* relocations = lib->relocations;
2934

30-
// Get number of relocations
3135
int num_relocations = section_headers[reloc_section_index].sh_size / sizeof(Elf64_Rela);
3236

33-
for (int i = 0; i < num_relocations; i++) {
37+
for (int i = 0; i < num_relocations; i++)
38+
{
3439
Elf64_Rela* reloc = &relocations[i];
3540

36-
// Get symbol index
3741
int sym_index = ELF64_R_SYM(reloc->r_info);
3842
Elf64_Sym* sym = &symbols[sym_index];
3943

40-
// Get relocation type
4144
int reloc_type = ELF64_R_TYPE(reloc->r_info);
42-
43-
// Get target address
4445
uintptr_t target_addr = 0;
4546

46-
// Determine target address based on relocation type
47-
switch (reloc_type) {
48-
case R_X86_64_64:
49-
target_addr = (uintptr_t)sym->st_value;
50-
break;
51-
case R_X86_64_PC32:
52-
target_addr = (uintptr_t)sym->st_value - (uintptr_t)(lib->address + reloc->r_offset + 4);
53-
break;
54-
case R_X86_64_PLT32:
55-
// Simplified handling - Adjust based on actual PLT implementation
56-
target_addr = (uintptr_t)sym->st_value;
57-
break;
58-
case R_X86_64_GOTPCREL:
59-
// Simplified handling - Adjust based on actual GOT implementation
60-
target_addr = (uintptr_t)sym->st_value;
61-
break;
62-
default:
63-
error("fdlopen: Unsupported relocation type: %d", reloc_type);
64-
return -1;
47+
if (reloc_type == R_X86_64_64)
48+
target_addr = (uintptr_t)sym->st_value;
49+
else if (reloc_type == R_X86_64_PC32)
50+
target_addr = (uintptr_t)sym->st_value - (uintptr_t)(lib->address + reloc->r_offset + 4);
51+
else if (reloc_type == R_X86_64_PLT32)
52+
target_addr = (uintptr_t)sym->st_value;
53+
else if (reloc_type == R_X86_64_GOTPCREL)
54+
target_addr = (uintptr_t)sym->st_value;
55+
else
56+
{
57+
printf("fdlopen: Unsupported relocation type: %d: %s", reloc_type, __FILE__);
58+
return -1;
6559
}
6660

67-
// Apply relocation
6861
uintptr_t* ptr = (uintptr_t*)(lib->address + reloc->r_offset);
6962
*ptr += target_addr + reloc->r_addend;
7063
}
7164

72-
return 0; // Relocation successful
65+
return 0;
7366
}
7467

7568
void* fdlsym(fdlfcn_handle* handle, const char* symbol_name)
7669
{
77-
for (int i = 0; i < handle->ehdr.e_shnum; i++) {
78-
if (strcmp(handle->shdrs[i].sh_name, ".symtab") == 0) {
79-
Elf64_Shdr symtab_section = handle->shdrs[i];
80-
Elf64_Sym* symbols = handle->symbols;
81-
82-
for (int j = 0; j < symtab_section.sh_size / sizeof(Elf64_Sym); j++) {
83-
char* symbol_name_str = (char*)((Elf64_Shdr*)((char*)handle->shdrs + handle->ehdr.e_shstrndx))->sh_addr + symbols[j].st_name;
84-
if (strcmp(symbol_name_str, symbol_name) == 0) {
85-
// Handle symbol versioning (if needed)
86-
// ...
87-
88-
// Calculate symbol address
89-
uintptr_t symbol_address = (uintptr_t)handle->address + symbols[j].st_value;
90-
return (void*)symbol_address;
91-
}
92-
}
70+
if (handle == NULL)
71+
return NULL;
72+
73+
Elf64_Sym* symbols = handle->symbols;
74+
75+
int symtab_index = -1;
76+
for (int i = 0; i < handle->ehdr.e_shnum; i++)
77+
{
78+
if (handle->shdrs[i].sh_type == SHT_SYMTAB)
79+
{
80+
symtab_index = i;
9381
break;
9482
}
9583
}
9684

97-
error("fdlsym: Symbol '%s' not found", symbol_name);
85+
if (symtab_index == -1)
86+
{
87+
printf("Symbol '%s' not found", symbol_name);
88+
return NULL;
89+
}
90+
91+
Elf64_Shdr symtab_section = handle->shdrs[symtab_index];
92+
93+
for (int j = 0; j < symtab_section.sh_size / sizeof(Elf64_Sym); j++)
94+
{
95+
char* symbol_name_str = (char*)((uint64_t)handle->symtab_str_section_data + symbols[j].st_name);
96+
if (strcmp(symbol_name_str, symbol_name) == 0 && ELF64_ST_BIND(symbols[j].st_info) != STB_LOCAL)
97+
{
98+
uintptr_t symbol_address = (uintptr_t)handle->text_section_data + symbols[j].st_value;
99+
printf("Found symbol '%s'", symbol_name);
100+
return (void*)symbol_address;
101+
}
102+
}
103+
104+
printf("fdlsym: Symbol '%s' not found", symbol_name);
98105
return NULL;
99106
}
100107

101108
int fdlclose(fdlfcn_handle* handle)
102109
{
103-
if (handle->text_section_data)
110+
if (handle == NULL)
111+
return 1;
112+
113+
return 0; /// TODO: somehow all the free calls cause a gp fault, fix that
114+
115+
if (handle->text_section_data != NULL)
104116
free(handle->text_section_data);
105-
if (handle->data_section_data)
117+
if (handle->data_section_data != NULL)
106118
free(handle->data_section_data);
107-
if (handle->rodata_section_data)
119+
if (handle->rodata_section_data != NULL)
108120
free(handle->rodata_section_data);
121+
if (handle->string_table_data != NULL)
122+
free(handle->string_table_data);
123+
if (handle->symtab_str_section_data != NULL)
124+
free(handle->symtab_str_section_data);
125+
if (handle->shdrs != NULL)
126+
free(handle->shdrs);
127+
if (handle->symbols != NULL)
128+
free(handle->symbols);
129+
if (handle->relocations != NULL)
130+
free(handle->relocations);
109131

110-
free(handle->shdrs);
111-
free(handle->symbols);
112-
free(handle->relocations);
113132
free(handle);
114133

115134
return 0;
@@ -123,30 +142,41 @@ fdlfcn_handle* fdlopen(void* filedata, int flags)
123142
fdlfcn_handle* handle = malloc(sizeof(fdlfcn_handle));
124143
if (handle == NULL)
125144
{
126-
error("Could not allocate memory for shared object file handle");
145+
error("Could not allocate memory for shared object file handle", __FILE__);
127146
return NULL;
128147
}
129148
memset(handle, 0, sizeof(fdlfcn_handle));
130149

131-
// Read ELF header
132150
Elf64_Ehdr elf_header;
133151
memcpy(&elf_header, filedata, sizeof(Elf64_Ehdr));
134152

135-
// Read section headers
153+
if (memcmp(&elf_header.e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0 || elf_header.e_ident[EI_CLASS] != ELFCLASS64 || elf_header.e_type != ET_DYN ||
154+
elf_header.e_machine != EM_X86_64 || elf_header.e_version != EV_CURRENT)
155+
{
156+
error("Not a valid .so file", __FILE__);
157+
free(handle);
158+
return NULL;
159+
}
160+
136161
Elf64_Shdr* section_headers = malloc(elf_header.e_shnum * sizeof(Elf64_Shdr));
162+
if (section_headers == NULL)
163+
{
164+
free(handle);
165+
return NULL;
166+
}
137167
READ_FROM_MEMORY(section_headers, filedata, elf_header.e_shoff, elf_header.e_shnum * sizeof(Elf64_Shdr));
138168

139-
// Find important section indices
140169
int strtab_index = elf_header.e_shstrndx;
141170
int symtab_index = -1;
142171
int text_section_index = -1;
143172
int data_section_index = -1;
144173
int rodata_section_index = -1;
145174
int reloc_section_index = -1;
146175

176+
void* strtableAddr = fdl_load_section(filedata, &section_headers[strtab_index]);
147177
for (int i = 0; i < elf_header.e_shnum; i++)
148178
{
149-
char* section_name = (char*)((Elf64_Shdr*)((char*)section_headers + strtab_index))->sh_addr + section_headers[i].sh_name;
179+
char* section_name = (char*)strtableAddr + section_headers[i].sh_name;
150180
if (strcmp(section_name, ".text") == 0)
151181
text_section_index = i;
152182
else if (strcmp(section_name, ".data") == 0)
@@ -161,10 +191,10 @@ fdlfcn_handle* fdlopen(void* filedata, int flags)
161191
reloc_section_index = i;
162192
}
163193

164-
// Load sections into memory
165194
void* text_section_data = NULL;
166195
void* data_section_data = NULL;
167196
void* rodata_section_data = NULL;
197+
void* symtab_str_section_data = NULL;
168198

169199
if (text_section_index != -1)
170200
{
@@ -204,37 +234,52 @@ fdlfcn_handle* fdlopen(void* filedata, int flags)
204234
}
205235
}
206236

207-
// Read symbol table
208237
if (symtab_index != -1)
209238
{
210239
Elf64_Shdr symtab_section = section_headers[symtab_index];
211240
handle->symbols = malloc(symtab_section.sh_size);
212241
READ_FROM_MEMORY(handle->symbols, filedata, symtab_section.sh_offset, symtab_section.sh_size);
213-
} else {
214-
handle->symbols = NULL;
242+
symtab_str_section_data = fdl_load_section(filedata, &section_headers[symtab_section.sh_link]);
215243
}
244+
else
245+
handle->symbols = NULL;
216246

217-
// Read relocation entries
218-
if (reloc_section_index != -1) {
247+
if (reloc_section_index != -1)
248+
{
219249
Elf64_Shdr reloc_section = section_headers[reloc_section_index];
220250
handle->relocations = malloc(reloc_section.sh_size);
221251
READ_FROM_MEMORY(handle->relocations, filedata, reloc_section.sh_offset, reloc_section.sh_size);
222-
} else {
223-
handle->relocations = NULL;
224252
}
253+
else
254+
handle->relocations = NULL;
225255

226-
handle->address = (void*)section_headers[text_section_index].sh_addr;
256+
handle->address = text_section_data;
257+
handle->text_section_data = text_section_data;
258+
handle->symtab_str_section_data = symtab_str_section_data;
259+
handle->text_section_header = &section_headers[text_section_index];
260+
handle->data_section_data = data_section_data;
261+
handle->data_section_header = &section_headers[data_section_index];
262+
handle->rodata_section_data = rodata_section_data;
263+
handle->rodata_section_header = &section_headers[rodata_section_index];
264+
handle->string_table_data = strtableAddr;
265+
handle->ehdr = elf_header;
266+
handle->shdrs = section_headers;
267+
handle->symtab_index = symtab_index;
227268

228-
if (fdl_apply_relocations(handle, reloc_section_index) != 0)
269+
if (fdl_apply_relocations(handle, reloc_section_index) != 0 && reloc_section_index != -1)
229270
{
230-
error("fdlopen: Relocation failed");
271+
error("fdlopen: Relocation failed", __FILE__);
231272

232273
if (text_section_data)
233274
free(text_section_data);
234275
if (data_section_data)
235276
free(data_section_data);
236277
if (rodata_section_data)
237278
free(rodata_section_data);
279+
if (strtableAddr)
280+
free(strtableAddr);
281+
if (symtab_str_section_data)
282+
free(symtab_str_section_data);
238283

239284
free(section_headers);
240285
free(handle->symbols);
@@ -243,16 +288,7 @@ fdlfcn_handle* fdlopen(void* filedata, int flags)
243288
return NULL;
244289
}
245290

246-
handle->text_section_data = text_section_data;
247-
handle->text_section_header = &section_headers[text_section_index];
248-
handle->data_section_data = data_section_data;
249-
handle->data_section_header = &section_headers[data_section_index];
250-
handle->rodata_section_data = rodata_section_data;
251-
handle->rodata_section_header = &section_headers[rodata_section_index];
252-
253-
handle->ehdr = elf_header;
254-
handle->shdrs = section_headers;
255-
handle->symtab_index = symtab_index; // Store symtab index for later use
291+
info("fdlopen: Successfully loaded .so file", __FILE__);
256292

257293
return handle;
258294
}

source/kernel/C/kernel.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -381,16 +381,21 @@ void main(void) {
381381
// int* test3 = malloc(sizeof(int));
382382
// int* test4 = malloc(sizeof(int));
383383

384-
// void* file_addr = module_request.response->modules[0]->address;
385-
// elf_load_from_memory(file_addr);
386-
// fdlfcn_handle* handle = fdlopen(file_addr, FDL_IMMEDIATE);
387-
// if (handle != NULL)
388-
// info("IT'S WORKING", __FILE__);
384+
void* file_addr = module_request.response->modules[0]->address;
385+
elf_load_from_memory(file_addr);
386+
fdlfcn_handle* handle = fdlopen(file_addr, FDL_IMMEDIATE);
387+
void* startFunction = fdlsym(handle, "frostedwm_create_context");
388+
if (startFunction != NULL)
389+
info("Successfully loaded function from .so file", __FILE__);
390+
fdlclose(handle);
389391

390392
int failed_attempts = 0;
391393

392-
int (*execute_binary)() = (int (*)())module_request.response->modules[1]->address;
394+
// void* binaddress = module_request.response->modules[1]->address;
395+
// printf("binary addr: 0x%x", binaddress);
396+
// int (*execute_binary)(void) = binaddress;
393397
// int status_code = execute_binary();
398+
// printf("return code: 0x%x", status_code);
394399

395400
// glCreateContext();
396401
// glCreateContextCustom(front_buffer, framebuffer->width, framebuffer->height);

0 commit comments

Comments
 (0)