boot: Add EFISTUB and refactor boot protocols

This commit is contained in:
2026-10-27 22:50:43 +01:00
parent 6827dc309e
commit 196543c3d3
40 changed files with 1923 additions and 208 deletions
+61
View File
@@ -0,0 +1,61 @@
// SPDX-License-Identifier: ISC
#include <bits/elf.h>
#include <stddef.h>
#include <stdint.h>
#include "efi.h"
efi_status efistub_relocate(uintptr_t base, const elf64_dyn_t* dynamic) {
uintptr_t rela = 0;
size_t rela_size = 0;
size_t rela_ent = sizeof(elf64_rela_t);
uintptr_t relr = 0;
size_t relr_size = 0;
for (const elf64_dyn_t* dyn = dynamic; dyn->d_tag != DT_NULL; dyn++) {
switch (dyn->d_tag) {
case DT_RELA:
rela = base + dyn->d_un.d_val;
break;
case DT_RELASZ:
rela_size = dyn->d_un.d_val;
break;
case DT_RELAENT:
rela_ent = dyn->d_un.d_val;
break;
case DT_RELR:
relr = base + dyn->d_un.d_val;
break;
case DT_RELRSZ:
relr_size = dyn->d_un.d_val;
break;
}
}
for (size_t off = 0; rela && off + rela_ent <= rela_size; off += rela_ent) {
const elf64_rela_t* r = (const elf64_rela_t*)(rela + off);
const uint32_t type = ELF64_R_TYPE(r->r_info);
if (type == R_NONE)
continue;
if (type != R_RELATIVE)
return EFI_LOAD_ERROR;
*(uint64_t*)(base + r->r_offset) = base + r->r_addend;
}
uint64_t* where = nullptr;
for (size_t off = 0; relr && off + sizeof(uint64_t) <= relr_size; off += sizeof(uint64_t)) {
uint64_t entry = *(const uint64_t*)(relr + off);
if (!(entry & 1)) {
where = (uint64_t*)(base + entry);
*where++ += base;
continue;
}
for (size_t i = 0; (entry >>= 1) != 0; i++) {
if (entry & 1)
where[i] += base;
}
where += 63;
}
return EFI_SUCCESS;
}