vxBoot - 1.1.1 : GOT patch
@update <> CMakeList.txt : dump version + add new sources files <> include/vxBoot/loader : remove useless define and add Elf32_Sym @fix <> vxBoot/loader/got : relocalize the .got section to _GLOBAL_OFFSET_TABLE_
This commit is contained in:
parent
7bbb33f50f
commit
3971b78a29
|
@ -1,5 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.15)
|
||||
project(vxBoot VERSION 1.1.0 LANGUAGES C)
|
||||
project(vxBoot VERSION 1.1.1 LANGUAGES C)
|
||||
|
||||
include(GenerateG1A)
|
||||
include(GenerateG3A)
|
||||
|
|
|
@ -94,24 +94,35 @@ typedef struct {
|
|||
|
||||
/* Legal values for sh_type (section type). */
|
||||
|
||||
#define SHT_NULL 0 /* Section header table entry unused */
|
||||
#define SHT_PROGBITS 1 /* Program data */
|
||||
#define SHT_SYMTAB 2 /* Symbol table */
|
||||
#define SHT_STRTAB 3 /* String table */
|
||||
#define SHT_RELA 4 /* Relocation entries with addends */
|
||||
#define SHT_HASH 5 /* Symbol hash table */
|
||||
#define SHT_DYNAMIC 6 /* Dynamic linking information */
|
||||
#define SHT_NOTE 7 /* Notes */
|
||||
#define SHT_NOBITS 8 /* Program space with no data (bss) */
|
||||
#define SHT_REL 9 /* Relocation entries, no addends */
|
||||
#define SHT_SHLIB 10 /* Reserved */
|
||||
#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
|
||||
#define SHT_INIT_ARRAY 14 /* Array of constructors */
|
||||
#define SHT_FINI_ARRAY 15 /* Array of destructors */
|
||||
#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
|
||||
#define SHT_GROUP 17 /* Section group */
|
||||
#define SHT_SYMTAB_SHNDX 18 /* Extended section indices */
|
||||
#define SHT_NUM 19 /* Number of defined types. */
|
||||
#define SHT_NULL 0 /* Section header table entry unused */
|
||||
#define SHT_PROGBITS 1 /* Program data */
|
||||
#define SHT_SYMTAB 2 /* Symbol table */
|
||||
#define SHT_STRTAB 3 /* String table */
|
||||
#define SHT_RELA 4 /* Relocation entries with addends */
|
||||
#define SHT_HASH 5 /* Symbol hash table */
|
||||
#define SHT_DYNAMIC 6 /* Dynamic linking information */
|
||||
#define SHT_NOTE 7 /* Notes */
|
||||
#define SHT_NOBITS 8 /* Program space with no data (bss) */
|
||||
#define SHT_REL 9 /* Relocation entries, no addends */
|
||||
#define SHT_SHLIB 10 /* Reserved */
|
||||
#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
|
||||
#define SHT_INIT_ARRAY 14 /* Array of constructors */
|
||||
#define SHT_FINI_ARRAY 15 /* Array of destructors */
|
||||
#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
|
||||
#define SHT_GROUP 17 /* Section group */
|
||||
#define SHT_SYMTAB_SHNDX 18 /* Extended section indices */
|
||||
#define SHT_NUM 19 /* Number of defined types. */
|
||||
|
||||
/* Symbol table entry. */
|
||||
|
||||
typedef struct {
|
||||
uint32_t st_name; /* Symbol name (string tbl index) */
|
||||
uint32_t st_value; /* Symbol value */
|
||||
uint32_t st_size; /* Symbol size */
|
||||
unsigned char st_info; /* Symbol type and binding */
|
||||
unsigned char st_other; /* Symbol visibility */
|
||||
uint16_t st_shndx; /* Section index */
|
||||
} Elf32_Sym;
|
||||
|
||||
//---
|
||||
// Loader API
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
/* loader_got_patch() : Try to patch the GOT section */
|
||||
int loader_got_patch(
|
||||
|
||||
/* loader_get_section() : Try to find section information using its name */
|
||||
static int loader_get_section(
|
||||
Elf32_Shdr *shdr,
|
||||
char const * const name,
|
||||
struct smemfs_inode const * restrict const inode,
|
||||
struct kernel_info * const kernel,
|
||||
Elf32_Ehdr *hdr
|
||||
) {
|
||||
Elf32_Shdr shdr;
|
||||
uintptr_t *got;
|
||||
char name[5];
|
||||
char buff[16];
|
||||
off_t stroff;
|
||||
off_t shoff;
|
||||
|
||||
|
@ -22,28 +22,88 @@ int loader_got_patch(
|
|||
/* find the section string table ".strtable" */
|
||||
smemfs_pread(
|
||||
inode,
|
||||
&shdr, sizeof(Elf32_Shdr),
|
||||
shdr, sizeof(Elf32_Shdr),
|
||||
shoff + (sizeof(Elf32_Shdr) * hdr->e_shstrndx)
|
||||
);
|
||||
stroff = shdr.sh_offset;
|
||||
stroff = shdr->sh_offset;
|
||||
|
||||
/* walk throught each section and find the .got section */
|
||||
for (int i = 0; i < hdr->e_shnum; ++i) {
|
||||
smemfs_pread(inode, &shdr, sizeof(Elf32_Shdr), shoff);
|
||||
smemfs_pread(inode, name, 5, shdr.sh_name + stroff);
|
||||
if (strcmp(name, ".got") != 0) {
|
||||
shoff += sizeof(Elf32_Shdr);
|
||||
continue;
|
||||
}
|
||||
got = kernel->memory.program.start;
|
||||
got = (void*)((uintptr_t)got + (uintptr_t)shdr.sh_addr);
|
||||
terminal_write(" GOT section found at %p...\n", got);
|
||||
for (uint32_t j = 0 ; j < shdr.sh_size >> 2 ; ++j) {
|
||||
terminal_write(" path symbols %p...\n", got[j]);
|
||||
got[j] += (uintptr_t)kernel->hardware.ram.physical.kernel_addr;
|
||||
got[j] |= (uintptr_t)0x80000000;
|
||||
}
|
||||
return (0);
|
||||
smemfs_pread(inode, shdr, sizeof(Elf32_Shdr), shoff);
|
||||
smemfs_pread(inode, buff, 16, shdr->sh_name + stroff);
|
||||
if (strcmp(buff, name) == 0)
|
||||
return (0);
|
||||
shoff += sizeof(Elf32_Shdr);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
/* loader_get_symbols() : get symbols information */
|
||||
static int loader_get_symbol(
|
||||
Elf32_Sym *sym,
|
||||
char const * const name,
|
||||
struct smemfs_inode const * restrict const inode,
|
||||
Elf32_Ehdr *hdr
|
||||
){
|
||||
Elf32_Shdr symhdr;
|
||||
Elf32_Shdr strhdr;
|
||||
char buff[64];
|
||||
int off;
|
||||
|
||||
/* frist, find the symtab section */
|
||||
loader_get_section(&symhdr, ".symtab", inode, hdr);
|
||||
loader_get_section(&strhdr, ".strtab", inode, hdr);
|
||||
|
||||
/* walk throut the table */
|
||||
off = symhdr.sh_offset;
|
||||
for (uint32_t i = 0 ; i < symhdr.sh_size / sizeof(Elf32_Sym) ; ++i) {
|
||||
smemfs_pread(inode, sym, sizeof(Elf32_Sym), off);
|
||||
smemfs_pread(inode, buff, 64, sym->st_name + strhdr.sh_offset);
|
||||
if (strcmp(buff, name) == 0)
|
||||
return (0);
|
||||
off += sizeof(Elf32_Sym);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
/* loader_got_patch() : Try to patch the GOT/PLT section */
|
||||
int loader_got_patch(
|
||||
struct smemfs_inode const * restrict const inode,
|
||||
struct kernel_info * const kernel,
|
||||
Elf32_Ehdr *hdr
|
||||
) {
|
||||
Elf32_Shdr shdr;
|
||||
Elf32_Sym sym;
|
||||
uintptr_t *__got__;
|
||||
uintptr_t *got;
|
||||
uintptr_t addr;
|
||||
|
||||
/* first, try to find the __GLOBAL_OFFSET_TABLE__ symbol */
|
||||
if (loader_get_symbol(&sym, "_GLOBAL_OFFSET_TABLE_", inode, hdr)) {
|
||||
terminal_write("_GLOBAL_OFFSET_TABLE_ not found...\n");
|
||||
return (0);
|
||||
}
|
||||
__got__ = kernel->memory.program.start;
|
||||
__got__ = (void*)((uintptr_t)__got__ + (uintptr_t)sym.st_value);
|
||||
terminal_write(" __GOT__ found at %p...\n", __got__);
|
||||
|
||||
|
||||
/* and we need to relocalise the "real" GOT section and update the
|
||||
hardcoded address in the same time */
|
||||
loader_get_section(&shdr, ".got", inode, hdr);
|
||||
got = kernel->memory.program.start;
|
||||
got = (void*)((uintptr_t)got + (uintptr_t)shdr.sh_addr);
|
||||
terminal_write(" GOT found at %p...\n", got);
|
||||
|
||||
/* perform transation */
|
||||
for (uint32_t i = 0 ; i < shdr.sh_size >> 2 ; ++i) {
|
||||
terminal_write(" path symbols %p...\n", got[i]);
|
||||
addr = got[i];
|
||||
addr += (uintptr_t)kernel->hardware.ram.physical.kernel_addr;
|
||||
addr |= (uintptr_t)0x80000000;
|
||||
__got__[i] = addr;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue