filename | src/loader.c |
changeset | 1300:d18488c8668b |
prev | 1298:d0eb2307b847 |
author | nkeynes |
date | Wed May 27 08:46:29 2015 +1000 (8 years ago) |
permissions | -rw-r--r-- |
last change | Add support for extracting the ELF symbol table and printing symbol names alongside the SH4 disassembly |
file | annotate | diff | log | raw |
1.1 --- a/src/loader.c Wed Feb 04 08:38:23 2015 +10001.2 +++ b/src/loader.c Wed May 27 08:46:29 2015 +10001.3 @@ -34,6 +34,7 @@1.4 #include "drivers/cdrom/cdrom.h"1.5 #include "drivers/cdrom/isofs.h"1.6 #include "gdrom/gdrom.h"1.7 +#include "sh4/sh4.h"1.9 const char bootstrap_magic[32] = "SEGA SEGAKATANA SEGA ENTERPRISES";1.10 const char iso_magic[6] = "\001CD001";1.11 @@ -242,6 +243,8 @@1.12 {1.13 Elf32_Ehdr head;1.14 Elf32_Phdr phdr;1.15 + Elf32_Shdr shdr;1.16 + Elf32_Sym sym;1.17 int i;1.19 if( read( fd, &head, sizeof(head) ) != sizeof(head) )1.20 @@ -265,6 +268,43 @@1.21 }1.22 }1.24 + /* Find symbol table */1.25 + uint32_t symtabOffset = 0, symtabSize = 0, symtabEntSize = 0;1.26 + uint32_t strtabOffset = 0, strtabSize = 0;1.27 + for( int i = 0; i < head.e_shnum; i++ ) {1.28 + lseek( fd, head.e_shoff + i * head.e_shentsize, SEEK_SET );1.29 + read( fd, &shdr, sizeof( shdr ) );1.30 + if( shdr.sh_type == SHT_SYMTAB ) {1.31 + symtabOffset = shdr.sh_offset;1.32 + symtabSize = shdr.sh_size;1.33 + symtabEntSize = shdr.sh_entsize;1.34 + } else if( shdr.sh_type == SHT_STRTAB ) {1.35 + strtabOffset = shdr.sh_offset;1.36 + strtabSize = shdr.sh_size;1.37 + }1.38 + }1.39 + /* Extract symbols */1.40 + if( symtabOffset != 0 && strtabOffset != 0 ) {1.41 + unsigned numSymtabEntries = symtabSize / symtabEntSize;1.42 + char *data = g_malloc( numSymtabEntries * sizeof( struct sh4_symbol ) + strtabSize );1.43 + struct sh4_symbol *symtab = ( struct sh4_symbol * )data;1.44 + char *strings = data + ( numSymtabEntries * sizeof( struct sh4_symbol ) );1.45 + lseek( fd, strtabOffset, SEEK_SET );1.46 + read( fd, strings, strtabSize );1.47 + strings[strtabSize-1] = '\0'; /* Should already be 0, but just in case */1.48 + for( int i = 0; i < numSymtabEntries; i++ ) {1.49 + lseek( fd, symtabOffset + ( i * symtabEntSize ), SEEK_SET );1.50 + read( fd, &sym, sizeof( sym ) );1.51 + if( sym.st_name < strtabSize )1.52 + symtab[i].name = &strings[sym.st_name];1.53 + else1.54 + symtab[i].name = NULL;1.55 + symtab[i].address = sym.st_value;1.56 + symtab[i].size = sym.st_size;1.57 + }1.58 + sh4_set_symbol_table( symtab, numSymtabEntries, ( sh4_symtab_destroy_cb )free );1.59 + }1.60 +1.61 file_load_postload( filename, head.e_entry );1.62 return TRUE;1.63 }
.