157 lines
3.9 KiB
C
157 lines
3.9 KiB
C
//---
|
|
// fxBoot:loader:entry - ELF Loader entry
|
|
//---
|
|
#include "fxBoot/hypervisor.h"
|
|
#include "fxBoot/fs/smemfs.h"
|
|
#include "fxBoot/elf.h"
|
|
#include "fxBoot/terminal.h"
|
|
|
|
#include <gint/std/stdlib.h>
|
|
#include <gint/std/string.h>
|
|
|
|
#include "./src/hypervisor/internal/elf.h"
|
|
|
|
/* elf_dump_section(): Dump one section */
|
|
static void *elf_dump_section(struct smemfs_inode *inode, Elf32_Shdr *shdr)
|
|
{
|
|
void *section;
|
|
|
|
section = malloc(shdr->sh_size);
|
|
if (section == NULL)
|
|
return (NULL);
|
|
if (smemfs_pread(inode, section, shdr->sh_size, shdr->sh_offset)
|
|
!= (ssize_t)shdr->sh_size) {
|
|
free(section);
|
|
return (NULL);
|
|
}
|
|
return (section);
|
|
}
|
|
|
|
/* elf_rela_check(): Check rela section */
|
|
static void elf_rela_check(struct smemfs_inode *inode, Elf32_Shdr *shdr)
|
|
{
|
|
Elf32_Rela rela;
|
|
Elf32_Word i;
|
|
off_t offset;
|
|
|
|
for (i = 0; i < shdr->sh_size / shdr->sh_entsize; ++i) {
|
|
offset = shdr->sh_offset + (i * shdr->sh_entsize);
|
|
if (smemfs_pread(inode, &rela, shdr->sh_entsize, offset)
|
|
!= (ssize_t)shdr->sh_entsize) {
|
|
terminal_write("rela sectio size error\n");
|
|
return;
|
|
}
|
|
terminal_write("%p %p %d %d %d\n", rela.r_offset,
|
|
rela.r_info,
|
|
ELF32_R_SYM(rela.r_info),
|
|
ELF32_R_TYPE(rela.r_info),
|
|
rela.r_addend);
|
|
}
|
|
}
|
|
|
|
/* hypervisor_elf_loader_dynamic_check(): Display all .dynshr */
|
|
int hypervisor_elf_loader_dynamic_check(struct smemfs_inode *inode)
|
|
{
|
|
Elf32_Ehdr ehdr;
|
|
Elf32_Shdr shdr;
|
|
Elf32_Shdr dynamichdr;
|
|
Elf32_Dyn *dynamic;
|
|
char *shstrtab;
|
|
char *dynstr;
|
|
char *dynsym;
|
|
off_t offset;
|
|
void **tmp;
|
|
int err;
|
|
|
|
/* Try to get the ELF header information */
|
|
err = hypervisor_elf_loader_header_get(inode, &ehdr);
|
|
if (err != 0)
|
|
return (-2);
|
|
|
|
/* get ELF section header string table */
|
|
offset = ehdr.e_shoff + (ehdr.e_shstrndx * ehdr.e_shentsize);
|
|
if (smemfs_pread(inode, &shdr, ehdr.e_shentsize, offset)
|
|
!= ehdr.e_shentsize) {
|
|
terminal_write("shdr size\n");
|
|
return (-1);
|
|
}
|
|
shstrtab = elf_dump_section(inode, &shdr);
|
|
if (shstrtab == NULL) {
|
|
terminal_write("cannot get the shstrtab section\n");
|
|
return (-2);
|
|
}
|
|
|
|
/* get ELF information */
|
|
dynstr = NULL;
|
|
dynamic = NULL;
|
|
for (int i = 1 ; i < ehdr.e_shnum ; ++i) {
|
|
offset = ehdr.e_shoff + (i * ehdr.e_shentsize);
|
|
if (smemfs_pread(inode, &shdr, ehdr.e_shentsize, offset)
|
|
!= ehdr.e_shentsize) {
|
|
terminal_write("section %d size error\n", i);
|
|
continue;
|
|
}
|
|
if (shdr.sh_type == SHT_RELA) {
|
|
elf_rela_check(inode, &shdr);
|
|
continue;
|
|
}
|
|
tmp = NULL;
|
|
if (strcmp(".dynamic", &shstrtab[shdr.sh_name]) == 0) {
|
|
memcpy(&dynamichdr, &shdr, sizeof(Elf32_Shdr));
|
|
tmp = (void*)&dynamic;
|
|
}
|
|
if (strcmp(".dynstr", &shstrtab[shdr.sh_name]) == 0)
|
|
tmp = (void*)&dynstr;
|
|
if (strcmp(".dynsym", &shstrtab[shdr.sh_name]) == 0)
|
|
tmp = (void*)&dynsym;
|
|
if (tmp == NULL)
|
|
continue;
|
|
*tmp = elf_dump_section(inode, &shdr);
|
|
if (*tmp == NULL) {
|
|
terminal_write("warning: '%s' dump error\n",
|
|
&shstrtab[shdr.sh_name]);
|
|
}
|
|
}
|
|
if (dynstr == NULL || dynamic == NULL) {
|
|
terminal_write(".dynstr or .dynamic not found\n");
|
|
return (-3);
|
|
}
|
|
|
|
#if 0
|
|
/* display information */
|
|
Elf32_Word i;
|
|
terminal_write("%10s %8s Name/Value\n", "TAG", "Type");
|
|
for (i = 0; i < dynamichdr.sh_size / dynamichdr.sh_entsize; ++i) {
|
|
if (dynamic[i].d_tag == DT_NULL) {
|
|
terminal_write("%p %8s %d\n",
|
|
dynamic[i].d_tag, "NULL",
|
|
dynamic[i].d_un.d_val);
|
|
break;
|
|
}
|
|
if (dynamic[i].d_tag == DT_NEEDED) {
|
|
terminal_write("%p %8s %s\n",
|
|
dynamic[i].d_tag, "NEEDED",
|
|
&dynstr[dynamic[i].d_un.d_val]);
|
|
continue;
|
|
}
|
|
if (dynamic[i].d_tag == DT_STRTAB) {
|
|
terminal_write("%p %8s %p\n",
|
|
dynamic[i].d_tag, "STRTAB",
|
|
dynamic[i].d_un.d_ptr);
|
|
continue;
|
|
}
|
|
if (dynamic[i].d_tag == DT_SYMTAB) {
|
|
terminal_write("%x %8s %p\n",
|
|
dynamic[i].d_tag, "SYMTAB",
|
|
dynamic[i].d_un.d_ptr);
|
|
continue;
|
|
}
|
|
terminal_write("%p %8s %p\n",
|
|
dynamic[i].d_tag, type,
|
|
dynamic[i].d_un.d_val);
|
|
}
|
|
terminal_write("dynamic symbols - %d\n", i);
|
|
#endif
|
|
return (0);
|
|
}
|