Search
lxdream.org :: lxdream/src/loader.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/loader.c
changeset 1300:d18488c8668b
prev1298:d0eb2307b847
author nkeynes
date Fri May 29 18:47:05 2015 +1000 (8 years ago)
permissions -rw-r--r--
last change Fix test case
file annotate diff log raw
1.1 --- a/src/loader.c Wed Feb 04 08:38:23 2015 +1000
1.2 +++ b/src/loader.c Fri May 29 18:47:05 2015 +1000
1.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.8
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.18
1.19 if( read( fd, &head, sizeof(head) ) != sizeof(head) )
1.20 @@ -265,6 +268,43 @@
1.21 }
1.22 }
1.23
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 + else
1.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 }
.