Skip to content

Commit 9c523ce

Browse files
Trying whatever i can to run busybox 😭
1 parent 361d5e2 commit 9c523ce

3 files changed

Lines changed: 161 additions & 1 deletion

File tree

‎source/kernel/C/executables/elf.c‎

Lines changed: 135 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
*/
1111
#include <executables/elf.h>
1212
#include <fdlfcn.h>
13-
#include <graphics.h>
1413
#include <memory.h>
1514
#include <stdint.h>
1615
#include <heap.h>
@@ -131,6 +130,132 @@ static int elf_load_tls_template_from_vfs(const char* path, elf_image_info_t* in
131130
return 0;
132131
}
133132

133+
typedef uint64_t (*elf_ifunc_resolver_t)(void);
134+
135+
static int elf_apply_relocation_entries(const Elf64_Rela* relocs, uint64_t reloc_count)
136+
{
137+
if (!relocs || reloc_count == 0)
138+
return 0;
139+
140+
for (uint64_t i = 0; i < reloc_count; ++i) {
141+
const Elf64_Rela* reloc = &relocs[i];
142+
uint32_t reloc_type = ELF64_R_TYPE(reloc->r_info);
143+
uint64_t* target = (uint64_t*)reloc->r_offset;
144+
145+
if (!target) {
146+
eprintf("elf: invalid relocation target");
147+
return -1;
148+
}
149+
150+
switch (reloc_type) {
151+
case R_X86_64_RELATIVE:
152+
*target = (uint64_t)reloc->r_addend;
153+
break;
154+
155+
case R_X86_64_IRELATIVE: {
156+
elf_ifunc_resolver_t resolver = (elf_ifunc_resolver_t)(uint64_t)reloc->r_addend;
157+
*target = resolver ? resolver() : 0;
158+
break;
159+
}
160+
161+
default:
162+
break;
163+
}
164+
}
165+
166+
return 0;
167+
}
168+
169+
static int elf_apply_relocations_from_memory(void* file_base_address, uint64_t file_size, const Elf64_Ehdr* header)
170+
{
171+
if (!file_base_address || !header || header->e_shoff == 0 || header->e_shnum == 0)
172+
return 0;
173+
174+
uint64_t shdr_bytes = (uint64_t)header->e_shnum * header->e_shentsize;
175+
if (header->e_shentsize != sizeof(Elf64_Shdr) || header->e_shoff + shdr_bytes > file_size) {
176+
eprintf("elf: invalid section header table");
177+
return -1;
178+
}
179+
180+
Elf64_Shdr* shdrs = (Elf64_Shdr*)((uint8_t*)file_base_address + header->e_shoff);
181+
for (uint16_t i = 0; i < header->e_shnum; ++i) {
182+
Elf64_Shdr* sh = &shdrs[i];
183+
if (sh->sh_type != SHT_RELA || sh->sh_size == 0)
184+
continue;
185+
186+
if (sh->sh_offset + sh->sh_size > file_size || (sh->sh_size % sizeof(Elf64_Rela)) != 0) {
187+
eprintf("elf: invalid SHT_RELA bounds");
188+
return -1;
189+
}
190+
191+
if (elf_apply_relocation_entries((Elf64_Rela*)((uint8_t*)file_base_address + sh->sh_offset),
192+
sh->sh_size / sizeof(Elf64_Rela)) != 0)
193+
return -1;
194+
}
195+
196+
return 0;
197+
}
198+
199+
static int elf_apply_relocations_from_vfs(const char* path, uint32_t file_size, const Elf64_Ehdr* header)
200+
{
201+
if (!path || !header || header->e_shoff == 0 || header->e_shnum == 0)
202+
return 0;
203+
204+
uint64_t shdr_bytes = (uint64_t)header->e_shnum * header->e_shentsize;
205+
if (header->e_shentsize != sizeof(Elf64_Shdr) || header->e_shoff + shdr_bytes > file_size) {
206+
eprintf("elf: invalid section header table");
207+
return -1;
208+
}
209+
210+
Elf64_Shdr* shdrs = kmalloc(shdr_bytes);
211+
if (!shdrs) {
212+
eprintf("elf: failed to allocate section headers");
213+
return -1;
214+
}
215+
216+
if (elf_vfs_read_exact_path(path, (uint32_t)header->e_shoff, shdrs, (uint32_t)shdr_bytes) != 0) {
217+
eprintf("elf: failed to read section headers");
218+
kfree(shdrs);
219+
return -1;
220+
}
221+
222+
for (uint16_t i = 0; i < header->e_shnum; ++i) {
223+
Elf64_Shdr* sh = &shdrs[i];
224+
if (sh->sh_type != SHT_RELA || sh->sh_size == 0)
225+
continue;
226+
227+
if (sh->sh_offset + sh->sh_size > file_size || (sh->sh_size % sizeof(Elf64_Rela)) != 0) {
228+
eprintf("elf: invalid SHT_RELA bounds");
229+
kfree(shdrs);
230+
return -1;
231+
}
232+
233+
Elf64_Rela* relocs = kmalloc(sh->sh_size);
234+
if (!relocs) {
235+
eprintf("elf: failed to allocate relocations");
236+
kfree(shdrs);
237+
return -1;
238+
}
239+
240+
if (elf_vfs_read_exact_path(path, (uint32_t)sh->sh_offset, relocs, (uint32_t)sh->sh_size) != 0) {
241+
eprintf("elf: failed to read relocations");
242+
kfree(relocs);
243+
kfree(shdrs);
244+
return -1;
245+
}
246+
247+
int rc = elf_apply_relocation_entries(relocs, sh->sh_size / sizeof(Elf64_Rela));
248+
kfree(relocs);
249+
if (rc != 0) {
250+
kfree(shdrs);
251+
return -1;
252+
}
253+
}
254+
255+
kfree(shdrs);
256+
return 0;
257+
}
258+
134259
static uint64_t elf_runtime_addr_for_offset(Elf64_Phdr* headers, uint16_t phnum, uint64_t file_offset)
135260
{
136261
for (uint16_t i = 0; i < phnum; ++i) {
@@ -170,6 +295,7 @@ static void elf_log_load_progress(uint16_t current, uint16_t total, Elf64_Phdr*
170295
ph ? ph->p_offset : 0);
171296
}
172297

298+
173299
static uint64_t elf_stage_phdrs_for_user(Elf64_Phdr* headers, uint64_t phdr_bytes)
174300
{
175301
if (!headers || phdr_bytes == 0)
@@ -365,6 +491,9 @@ void* elf_load_from_memory_ex(void* file_base_address, uint64_t file_size, elf_i
365491
return NULL;
366492
}
367493

494+
if (elf_apply_relocations_from_memory(file_base_address, file_size, &header) != 0)
495+
return NULL;
496+
368497
return (void*)header.e_entry;
369498
}
370499

@@ -467,6 +596,11 @@ void* elf_load_from_vfs_ex(const char* path, elf_image_info_t* info)
467596
}
468597
}
469598

599+
if (elf_apply_relocations_from_vfs(path, size, &header) != 0) {
600+
kfree(program_headers);
601+
return NULL;
602+
}
603+
470604
kfree(program_headers);
471605
void* entry = (void*)header.e_entry;
472606
return entry;

‎source/kernel/C/interrupts/isr.c‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <memory.h>
1515
#include <drivers/rtl8139.h>
1616
#include <syscalls.h>
17+
#include <debugger.h>
1718

1819
irq_handler interrupt_handlers[256];
1920

@@ -53,6 +54,27 @@ static void log_page_fault_details(InterruptFrame* frame) {
5354
(int)((err >> 4) & 0x1));
5455
}
5556

57+
static int emulate_syscall_instruction_if_present(InterruptFrame* frame) {
58+
if (!frame)
59+
return 0;
60+
61+
if ((frame->cs & 0x3) != 0x3)
62+
return 0;
63+
64+
uint8_t* ip = (uint8_t*)frame->rip;
65+
if (!ip)
66+
return 0;
67+
68+
if (ip[0] == 0x0F && ip[1] == 0x05) {
69+
debug_printf("isr: emulating SYSCALL as int 0x80 at rip=%u nr=%u\n", frame->rip, frame->rax);
70+
syscalls_handler(frame);
71+
frame->rip += 2;
72+
return 1;
73+
}
74+
75+
return 0;
76+
}
77+
5678
void exceptionHandler(InterruptFrame* frame) {
5779
enable_logging = false; // disables logger as fast as it can to get the last instance of panic.
5880
log_page_fault_details(frame);
@@ -67,6 +89,9 @@ void exceptionHandler(InterruptFrame* frame) {
6789
case 6:
6890
if (skip_endbr64_if_present(frame))
6991
return;
92+
if(emulate_syscall_instruction_if_present(frame))
93+
return;
94+
7095
meltdown_screen("Invalid opcode detected!", __FILE__, __LINE__, frame->err_code, getCR2(), frame->int_no, frame);
7196
break;
7297
case 8:

‎source/kernel/C/syscalls.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,7 @@ void syscalls_handler(InterruptFrame* frame){
13201320
break;
13211321
default:
13221322
warn(linux_syscalls_prefix "Unknown, returning -ENOSYS", __FILE__);
1323+
debug_printf(linux_syscalls_prefix "Unknown : requested %u\n", frame->rax);
13231324
frame->rax = -LINUX_ENOSYS;
13241325
break;
13251326
}

0 commit comments

Comments
 (0)