Skip to content

Commit b1dd9a5

Browse files
committed
elf: Move symbols to heap
1 parent ae62abe commit b1dd9a5

2 files changed

Lines changed: 18 additions & 118 deletions

File tree

src/crt/c_abi.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void _init_c_runtime()
5151
/// init backtrace functionality
5252
extern void _move_elf_symbols(void*, void*);
5353
extern void _apply_parser_data(void*);
54-
// there is a 640k memory hole at the beginning of memory
54+
// there is a 640k conventional memory hole at the beginning of memory
5555
// put symbols at 40k
5656
void* SYM_LOCATION = (void*) 0xA000;
5757
// move pruned symbols to unused memory
@@ -94,8 +94,12 @@ void _init_c_runtime()
9494
extern void __register_frame(void*);
9595
__register_frame(&__eh_frame_start);
9696

97-
// set parser location here (after initializing everything else)
98-
_apply_parser_data(SYM_LOCATION);
97+
// move symbols (again) to heap
98+
extern void* _relocate_to_heap(void*);
99+
void* symheap = _relocate_to_heap(SYM_LOCATION);
100+
101+
// set ELF symbols location here (after initializing everything else)
102+
_apply_parser_data(symheap);
99103

100104
/// call global constructors emitted by compiler
101105
extern void _init();

src/kernel/elf.cpp

Lines changed: 11 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -347,121 +347,6 @@ struct relocate_header {
347347
StrTab strtab;
348348
};
349349

350-
void _relocate_sections(char* new_location, SymTab& symtab, StrTab& strtab)
351-
{
352-
auto& hdr = *(relocate_header*) new_location;
353-
hdr.symtab = symtab;
354-
hdr.strtab = strtab;
355-
356-
// move symbols
357-
char* symloc = new_location + sizeof(relocate_header);
358-
memcpy(symloc, symtab.base, symtab.entries * sizeof(Elf32_Sym));
359-
360-
// move strings
361-
char* strloc = symloc + symtab.entries * sizeof(Elf32_Sym);
362-
memcpy(strloc, strtab.base, strtab.size);
363-
364-
hdr.symtab.base = (Elf32_Sym*) symloc;
365-
hdr.strtab.base = strloc;
366-
}
367-
static void _relocate_pruned_sections(char* new_location, SymTab& symtab, StrTab& strtab)
368-
{
369-
auto& hdr = *(relocate_header*) new_location;
370-
hdr.symtab = symtab;
371-
hdr.strtab = strtab;
372-
373-
// first prune symbols
374-
auto* symloc = (Elf32_Sym*) (new_location + sizeof(relocate_header));
375-
size_t symidx = 0;
376-
for (size_t i = 0; i < symtab.entries; i++)
377-
{
378-
auto& cursym = symtab.base[i];
379-
if (ELF32_ST_TYPE(cursym.st_info) == STT_FUNC)
380-
{
381-
symloc[symidx++] = cursym;
382-
}
383-
}
384-
// new total symbol entries
385-
hdr.symtab.base = symloc;
386-
hdr.symtab.entries = symidx;
387-
388-
// move strings (one by one)
389-
char* strloc = (char*) &symloc[hdr.symtab.entries];
390-
size_t index = 0;
391-
for (size_t i = 0; i < hdr.symtab.entries; i++)
392-
{
393-
auto& sym = hdr.symtab.base[i];
394-
// get original location and length
395-
const char* org = &strtab.base[sym.st_name];
396-
size_t len = strlen(org) + 1;
397-
// set new symbol name location
398-
sym.st_name = index; // = distance from start
399-
// insert string into new location
400-
memcpy(&strloc[index], org, len);
401-
index += len;
402-
}
403-
// new entry base and total length
404-
hdr.strtab.base = strloc;
405-
hdr.strtab.size = index;
406-
}
407-
408-
#include <malloc.h>
409-
410-
extern "C"
411-
void* _relocate_to_heap(char* temp_location)
412-
{
413-
auto& hdr = *(relocate_header*) temp_location;
414-
415-
size_t total = sizeof(hdr) + hdr.symtab.entries * sizeof(Elf32_Sym) + hdr.strtab.size;
416-
void* heap_location = malloc(total);
417-
418-
_relocate_sections((char*) heap_location, hdr.symtab, hdr.strtab);
419-
return heap_location;
420-
}
421-
422-
static relocate_header init_header;
423-
424-
extern "C"
425-
int _init_elf_parser(void* temp_location)
426-
{
427-
SymTab symtab { nullptr, 0 };
428-
StrTab strtab { nullptr, 0 };
429-
auto& elf_hdr = elf_header();
430-
431-
// enumerate all section headers
432-
auto* shdr = (Elf32_Shdr*) (ELF_START + elf_hdr.e_shoff);
433-
for (Elf32_Half i = 0; i < elf_hdr.e_shnum; i++)
434-
{
435-
switch (shdr[i].sh_type) {
436-
case SHT_SYMTAB:
437-
symtab = { (Elf32_Sym*) (ELF_START + shdr[i].sh_offset),
438-
shdr[i].sh_size / sizeof(Elf32_Sym) };
439-
break;
440-
case SHT_STRTAB:
441-
strtab = { (char*) (ELF_START + shdr[i].sh_offset),
442-
shdr[i].sh_size };
443-
break;
444-
case SHT_DYNSYM:
445-
default:
446-
// don't care tbh
447-
break;
448-
}
449-
}
450-
451-
init_header.symtab = symtab;
452-
init_header.strtab = strtab;
453-
454-
// nothing to do if stripped
455-
if (symtab.entries == 0 || strtab.size == 0) return 1;
456-
457-
// hide sections to prevent them getting overwritten
458-
// this is a temporary fix, until the sections get loaded from disk
459-
if (temp_location)
460-
_relocate_pruned_sections((char*) temp_location, symtab, strtab);
461-
//_relocate_sections((char*) temp_location, symtab, strtab);
462-
return 0;
463-
}
464-
465350
extern "C"
466351
int _get_elf_section_size(const void* location)
467352
{
@@ -481,6 +366,17 @@ void _move_elf_symbols(void* old_location, void* new_location)
481366
newhdr->strtab.base = &base[newhdr->symtab.entries * sizeof(Elf32_Sym)];
482367
}
483368

369+
#include <malloc.h>
370+
extern "C"
371+
void* _relocate_to_heap(void* old_location)
372+
{
373+
int total = _get_elf_section_size(old_location);
374+
void* heap_location = malloc(total);
375+
376+
_move_elf_symbols(old_location, heap_location);
377+
return heap_location;
378+
}
379+
484380
extern "C"
485381
void _apply_parser_data(char* location)
486382
{

0 commit comments

Comments
 (0)