Skip to content

Commit c2d51d1

Browse files
fixed module loader
1 parent ebf17b0 commit c2d51d1

File tree

7 files changed

+96
-50
lines changed

7 files changed

+96
-50
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ set(HARD_DISK_IMAGE "../../harddisk0" CACHE STRING "Path to hard disk image when
1212
set(CMAKE_VERBOSE_MAKEFILE OFF)
1313
set(CMAKE_C_COMPILER gcc)
1414
set(CMAKE_C_LINK_EXECUTABLE "ld -m elf_x86_64 -nostdlib -no-pie --export-dynamic -T ${CMAKE_CURRENT_SOURCE_DIR}/buildtools/linker.ld <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
15-
set(CMAKE_ASM_FLAGS "-pipe -g -fno-PIC -Wall -Wextra -Wno-unused-parameter -Wno-int-to-pointer-cast -nostdlib -ffreestanding -nostartfiles -nodefaultlibs -mcmodel=large -mno-red-zone")
15+
set(CMAKE_ASM_FLAGS "-pipe -g -fno-PIC -Wall -Wextra -Wl,--export-dynamic -Wno-unused-parameter -Wno-int-to-pointer-cast -nostdlib -ffreestanding -nostartfiles -nodefaultlibs -mcmodel=large -mno-red-zone")
1616

1717
set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
1818

buildtools/linker.ld

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,17 @@ SECTIONS {
2626
__CTOR_LIST__ = .;
2727
*(.ctors)
2828
__CTOR_END__ = .;
29-
29+
3030
. = ALIGN(8);
3131
__DTOR_LIST__ = .;
3232
*(.dtors)
3333
__DTOR_END__ = .;
34-
34+
3535
. = ALIGN(8);
3636
__INIT_LIST__ = .;
3737
KEEP (*(.init_array))
3838
__INIT_END__ = .;
39-
39+
4040
. = ALIGN(8);
4141
__FINI_LIST__ = .;
4242
KEEP (*(.fini_array))
@@ -48,14 +48,18 @@ SECTIONS {
4848
__stop_kw_array = .;
4949

5050
. = ALIGN(8);
51+
__dynstr_start = .;
52+
KEEP(*(.dynstr))
5153
__dynsym_start = .;
5254
KEEP(*(.dynsym))
5355
__dynsym_stop = .;
5456

5557
. = ALIGN(8);
56-
__dynstr_start = .;
57-
KEEP(*(.dynstr))
58-
__dynstr_stop = .;
58+
__strtab_start = .;
59+
KEEP(*(.strtab))
60+
__symtab_start = .;
61+
KEEP(*(.symtab))
62+
__symtab_stop = .;
5963

6064
. = ALIGN(0x1000);
6165
}
@@ -75,7 +79,7 @@ SECTIONS {
7579
}
7680

7781
_edata = .;
78-
82+
7983
.bss : AT(ADDR(.bss) - KERNEL_VMA) {
8084
_bss = .;
8185
*(.bss*)

include/debugger.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,6 @@ bool set_debug_signal(bool status);
6464
bool get_debug_signal();
6565
void gdb_decode(char* out, const uint8_t* in, size_t len);
6666
void gdb_emit();
67-
uint32_t gdb_trace(const char* str);
67+
uint32_t gdb_trace(const char* str);
68+
69+
uint64_t findsymbol_addr(const char *name);

src/debugger.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,39 @@ const char* findsymbol(uint64_t address, uint64_t* offset) {
389389
return NULL;
390390
}
391391

392+
/* reverse lookup: name -> address (64-bit kernel VA)
393+
* returns 0 if not found
394+
*/
395+
uint64_t findsymbol_addr(const char *name) {
396+
if (!symbol_table || !name) {
397+
return 0;
398+
}
399+
400+
/* derive the current kernel high-half from any known kernel code pointer */
401+
const uint64_t kernel_hi = ((uint64_t)(uintptr_t)&findsymbol_addr) & 0xffffffff00000000ull;
402+
403+
for (symbol_t *s = symbol_table; s; s = s->next) {
404+
if (!s->name) {
405+
continue;
406+
}
407+
if (strcmp(s->name, name) != 0) {
408+
continue;
409+
}
410+
411+
uint64_t a = s->address;
412+
413+
/* if the sym file only carried low 32 bits, graft on the current high half */
414+
if ((a & 0xffffffff00000000ull) == 0) {
415+
a = kernel_hi | (a & 0xffffffffull);
416+
}
417+
418+
return a;
419+
}
420+
421+
return 0;
422+
}
423+
424+
392425
void backtrace()
393426
{
394427
stack_frame_t *frame;

src/init.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,4 @@ void init()
4141
profile_init(kmalloc(sizeof(profile_entry) * PROFILE_MAX_FUNCS), kmalloc(sizeof(profile_edge) * PROFILE_MAX_EDGES));
4242
dprintf("Initialising profiler done!\n");
4343
#endif
44-
4544
}

src/kernel.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,23 @@ void kmain()
2828
preboot_fail("Failed to mount boot drive to VFS!");
2929
}
3030

31+
/*module test;
32+
fs_directory_entry_t * f = fs_get_file_info("/system/modules/test.ko");
33+
if (f) {
34+
dprintf("*** MOD TEST: Got info on test.ko size %lu\n", f->size);
35+
void* module_content = kmalloc(f->size);
36+
if (fs_read_file(f, 0, f->size, module_content)) {
37+
dprintf("*** LOADING TEST MODULE test.ko ***\n");
38+
if (module_load_from_memory(module_content, f->size, &test)) {
39+
module_unload(&test);
40+
}
41+
dprintf("*** DONE WITH TEST MODULE test.ko ***\n");
42+
} else {
43+
dprintf("Couldnt read test.ko\n");
44+
}
45+
} else {
46+
dprintf("*** MOD TEST: Cant get info on test.ko\n");
47+
}*/
48+
3149
init_process();
3250
}

src/module_loader.c

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,11 @@
11
#include <kernel.h>
22

3-
/* .dynsym/.dynstr in the image */
4-
extern const elf_sym __dynsym_start[];
5-
extern const elf_sym __dynsym_stop[];
6-
extern const char __dynstr_start[];
7-
83
const void *kernel_dlsym(const char *name) {
9-
const elf_sym *s;
10-
11-
if (name == NULL) {
4+
if (!name) {
125
return NULL;
136
}
14-
15-
for (s = __dynsym_start; s < __dynsym_stop; s++) {
16-
unsigned bind;
17-
18-
if (s->st_name == 0) {
19-
continue;
20-
}
21-
22-
bind = ELF64_ST_BIND(s->st_info);
23-
if (bind != STB_GLOBAL && bind != STB_WEAK) {
24-
continue;
25-
}
26-
27-
if (s->st_shndx == SHN_UNDEF || s->st_shndx >= SHN_LORESERVE) {
28-
continue;
29-
}
30-
31-
if (strcmp(__dynstr_start + s->st_name, name) == 0) {
32-
return (const void *) (uintptr_t) s->st_value; /* higher-half VMA */
33-
}
34-
}
35-
36-
return NULL;
7+
uint64_t a = findsymbol_addr(name);
8+
return a ? (const void *) (uintptr_t) a : NULL;
379
}
3810

3911
bool parse_elf_rel_headers(const uint8_t *file, size_t len, const elf_ehdr **eh, const elf_shdr **sh, size_t *shnum, const char **shstr) {
@@ -236,15 +208,21 @@ bool module_apply_relocations(const uint8_t *file, const elf_shdr *sh, size_t sh
236208
}
237209

238210
uint16_t tgt_index = (uint16_t) sh[i].sh_info;
239-
uint8_t *tgt_base = module_section_base(m, tgt_index);
240-
const elf_rela *rela = (const elf_rela *) (file + sh[i].sh_offset);
241-
size_t count = (size_t) (sh[i].sh_size / sizeof(elf_rela));
242211

212+
/* NEW: ignore relocations for non-ALLOC target sections (e.g. .debug*) */
213+
if (tgt_index >= shnum || !is_alloc_section(&sh[tgt_index])) {
214+
continue;
215+
}
216+
217+
uint8_t *tgt_base = module_section_base(m, tgt_index);
243218
if (tgt_base == NULL) {
244-
dprintf("module_apply_relocations: target section base not found\n");
219+
dprintf("module_apply_relocations: target section base not found (idx=%u)\n", tgt_index);
245220
return false;
246221
}
247222

223+
const elf_rela *rela = (const elf_rela *) (file + sh[i].sh_offset);
224+
size_t count = (size_t) (sh[i].sh_size / sizeof(elf_rela));
225+
248226
for (size_t j = 0; j < count; j++) {
249227
uint32_t type = (uint32_t) ELF64_R_TYPE(rela[j].r_info);
250228
uint32_t si = (uint32_t) ELF64_R_SYM(rela[j].r_info);
@@ -263,10 +241,10 @@ bool module_apply_relocations(const uint8_t *file, const elf_shdr *sh, size_t sh
263241
}
264242

265243
switch (type) {
266-
case R_X86_64_64: {
244+
case R_X86_64_64:
267245
*(uint64_t *) P = (uint64_t) ((uint64_t) S + (uint64_t) A);
268246
break;
269-
}
247+
270248
case R_X86_64_PC32: {
271249
int64_t val = (int64_t) S + A - (int64_t) P;
272250
if (val < INT_MIN || val > INT_MAX) {
@@ -276,6 +254,18 @@ bool module_apply_relocations(const uint8_t *file, const elf_shdr *sh, size_t sh
276254
*(int32_t *) P = (int32_t) val;
277255
break;
278256
}
257+
258+
/* Compilers often emit PLT32 for extern calls */
259+
case 4 /* R_X86_64_PLT32 */: {
260+
int64_t val = (int64_t) S + A - (int64_t) P;
261+
if (val < INT_MIN || val > INT_MAX) {
262+
dprintf("module_apply_relocations: PLT32 overflow\n");
263+
return false;
264+
}
265+
*(int32_t *) P = (int32_t) val;
266+
break;
267+
}
268+
279269
case R_X86_64_32: {
280270
uint64_t val = (uint64_t) S + (uint64_t) A;
281271
if (val > UINT_MAX) {
@@ -285,6 +275,7 @@ bool module_apply_relocations(const uint8_t *file, const elf_shdr *sh, size_t sh
285275
*(uint32_t *) P = (uint32_t) val;
286276
break;
287277
}
278+
288279
case R_X86_64_32S: {
289280
int64_t val = (int64_t) S + A;
290281
if (val < INT_MIN || val > INT_MAX) {
@@ -294,14 +285,13 @@ bool module_apply_relocations(const uint8_t *file, const elf_shdr *sh, size_t sh
294285
*(int32_t *) P = (int32_t) val;
295286
break;
296287
}
297-
default: {
288+
289+
default:
298290
dprintf("module_apply_relocations: unsupported reloc type: %u\n", type);
299291
return false;
300-
}
301292
}
302293
}
303294
}
304-
305295
return true;
306296
}
307297

0 commit comments

Comments
 (0)