[lcrash] ADD: Dynamic linker for cckernel
This commit is contained in:
parent
1ab0e55277
commit
dd850450cc
@ -17,6 +17,24 @@
|
|||||||
#define PT_PHDR 6
|
#define PT_PHDR 6
|
||||||
#define PT_TLS 7
|
#define PT_TLS 7
|
||||||
|
|
||||||
|
#define SHT_NULL 0
|
||||||
|
#define SHT_PROGBITS 1
|
||||||
|
#define SHT_SYMTAB 2
|
||||||
|
#define SHT_STRTAB 3
|
||||||
|
#define SHT_RELA 4
|
||||||
|
#define SHT_HASH 5
|
||||||
|
#define SHT_DYNAMIC 6
|
||||||
|
#define SHT_NOTE 7
|
||||||
|
#define SHT_NOBITS 8
|
||||||
|
#define SHT_REL 9
|
||||||
|
#define SHT_SHLIB 10
|
||||||
|
#define SHT_DYNSYM 11
|
||||||
|
#define SHT_INIT_ARRAY 14
|
||||||
|
#define SHT_FINI_ARRAY 15
|
||||||
|
#define SHT_PREINIT_ARRAY 16
|
||||||
|
#define SHT_GROUP 17
|
||||||
|
#define SHT_SYMTAB_SHNDX 18
|
||||||
|
|
||||||
struct [[gnu::packed]] Elf64_Ehdr {
|
struct [[gnu::packed]] Elf64_Ehdr {
|
||||||
c8 e_ident[16];
|
c8 e_ident[16];
|
||||||
u16 e_type;
|
u16 e_type;
|
||||||
@ -30,7 +48,7 @@ struct [[gnu::packed]] Elf64_Ehdr {
|
|||||||
u16 e_phentsize;
|
u16 e_phentsize;
|
||||||
u16 e_phnum;
|
u16 e_phnum;
|
||||||
u16 e_shentsize;
|
u16 e_shentsize;
|
||||||
u16 e_shentnum;
|
u16 e_shnum;
|
||||||
u16 e_shstrndx;
|
u16 e_shstrndx;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -45,4 +63,53 @@ struct [[gnu::packed]] Elf64_Phdr {
|
|||||||
u64 p_align;
|
u64 p_align;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct [[gnu::packed]] Elf64_Shdr {
|
||||||
|
u32 sh_name;
|
||||||
|
u32 sh_type;
|
||||||
|
u64 sh_flags;
|
||||||
|
u64 sh_addr;
|
||||||
|
u64 sh_offset;
|
||||||
|
u64 sh_size;
|
||||||
|
u32 sh_link;
|
||||||
|
u32 sh_info;
|
||||||
|
u64 sh_addralign;
|
||||||
|
u64 sh_entsize;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ELF64_R_SYM(info) ((info)>>32);
|
||||||
|
#define ELF64_R_TYPE(info) ((u32)info)
|
||||||
|
#define ELF64_R_AMD64_NONE 0
|
||||||
|
#define ELF64_R_AMD64_64 1
|
||||||
|
#define ELF64_R_AMD64_PC32 2
|
||||||
|
#define ELF64_R_AMD64_GOT32 3
|
||||||
|
#define ELF64_R_AMD64_PLT32 4
|
||||||
|
#define ELF64_R_AMD64_COPY 5
|
||||||
|
#define ELF64_R_AMD64_GLOB_DAT 6
|
||||||
|
#define ELF64_R_AMD64_JUMP_SLOT 7
|
||||||
|
#define ELF64_R_AMD64_RELATIVE 8
|
||||||
|
#define ELF64_R_AMD64_GOTPCREL 9
|
||||||
|
#define ELF64_R_AMD64_32 10
|
||||||
|
#define ELF64_R_AMD64_32S 11
|
||||||
|
#define ELF64_R_AMD64_16 12
|
||||||
|
#define ELF64_R_AMD64_PC16 13
|
||||||
|
#define ELF64_R_AMD64_8 14
|
||||||
|
#define ELF64_R_AMD64_PC8 15
|
||||||
|
#define ELF64_R_AMD64_PC64 24
|
||||||
|
#define ELF64_R_AMD64_GOTOFF64 25
|
||||||
|
#define ELF64_R_AMD64_GOTPC32 26
|
||||||
|
#define ELF64_R_AMD64_SIZE32 32
|
||||||
|
#define ELF64_R_AMD64_SIZE64 33
|
||||||
|
struct [[gnu::packed]] Elf64_Rela {
|
||||||
|
u64 r_offset;
|
||||||
|
u64 r_info;
|
||||||
|
s64 r_addend;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct [[gnu::packed]] Elf64_Sym {
|
||||||
|
u32 st_name;
|
||||||
|
u8 st_info;
|
||||||
|
u8 st_other;
|
||||||
|
u16 st_shndx;
|
||||||
|
u64 st_value;
|
||||||
|
u64 st_size;
|
||||||
|
};
|
||||||
|
@ -5,6 +5,15 @@ ENTRY(entry64)
|
|||||||
SECTIONS {
|
SECTIONS {
|
||||||
. = 0;
|
. = 0;
|
||||||
|
|
||||||
|
.dynsym : { *(.dynsym); }
|
||||||
|
|
||||||
|
.rela.dyn : {
|
||||||
|
*(.rela.text);
|
||||||
|
*(.rela.rodata);
|
||||||
|
*(.rela.data .rela.data.*);
|
||||||
|
*(.rela.bss);
|
||||||
|
}
|
||||||
|
|
||||||
.text : {
|
.text : {
|
||||||
_text = .;
|
_text = .;
|
||||||
*(.text);
|
*(.text);
|
||||||
@ -19,7 +28,7 @@ SECTIONS {
|
|||||||
|
|
||||||
.data : {
|
.data : {
|
||||||
_data = .;
|
_data = .;
|
||||||
*(.data);
|
*(.data .data.*);
|
||||||
_edata = .;
|
_edata = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,39 @@ void ElfExecute(void* Binary, void* LoadAddr, struct boot_params* BootParams) {
|
|||||||
ProgramHeaders += ElfHeader->e_phentsize;
|
ProgramHeaders += ElfHeader->e_phentsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dynamically link ourself
|
||||||
|
void* SectionHeaders = Binary + ElfHeader->e_shoff;
|
||||||
|
for (int i = 0; i < ElfHeader->e_shnum; i++) {
|
||||||
|
struct Elf64_Shdr* SectionHeader = (struct Elf64_Shdr*)SectionHeaders;
|
||||||
|
|
||||||
|
// Find RELA segments
|
||||||
|
if (SectionHeader->sh_type == SHT_RELA) {
|
||||||
|
struct Elf64_Shdr* SymbolTable = (struct Elf64_Shdr*)(Binary + ElfHeader->e_shoff + ElfHeader->e_shentsize * SectionHeader->sh_link);
|
||||||
|
|
||||||
|
void* RelocTab = Binary + SectionHeader->sh_offset;
|
||||||
|
void* SymblTab = Binary + SymbolTable->sh_offset;
|
||||||
|
|
||||||
|
for (int RelocOffset = 0; RelocOffset < SectionHeader->sh_size; RelocOffset += SectionHeader->sh_entsize) {
|
||||||
|
struct Elf64_Rela* Reloc = RelocTab + RelocOffset;
|
||||||
|
[[maybe_unused]] struct Elf64_Sym* Symbol = SymblTab + SymbolTable->sh_entsize * ELF64_R_SYM(Reloc->r_info);
|
||||||
|
|
||||||
|
void* Target = LoadAddr + Reloc->r_offset;
|
||||||
|
|
||||||
|
switch (ELF64_R_TYPE(Reloc->r_info)) {
|
||||||
|
case ELF64_R_AMD64_RELATIVE: {
|
||||||
|
*((u64*)Target) = (u64)(LoadAddr + Reloc->r_addend);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
while (1) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SectionHeaders += ElfHeader->e_shentsize;
|
||||||
|
}
|
||||||
|
|
||||||
// Collect entry point
|
// Collect entry point
|
||||||
[[noreturn]] void fake_dont_call(struct boot_params*); // stupid hack
|
[[noreturn]] void fake_dont_call(struct boot_params*); // stupid hack
|
||||||
typeof(fake_dont_call)* KernelEntry = LoadAddr + ElfHeader->e_entry;
|
typeof(fake_dont_call)* KernelEntry = LoadAddr + ElfHeader->e_entry;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user