//--- // fxBoot:loader:entry - ELF Loader entry //--- #include "fxBoot/hypervisor.h" #include "fxBoot/fs/smemfs.h" #include "fxBoot/elf.h" #include "fxBoot/terminal.h" #include #include #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); }