@ -18,7 +18,8 @@
# include <map>
# include <cerrno>
std : : map < std : : string , uint64_t > load_elf ( const char * fn , memif_t * memif , reg_t * entry , unsigned required_xlen = 0 )
std : : map < std : : string , uint64_t > load_elf ( const char * fn , memif_t * memif , reg_t * entry ,
reg_t load_offset , unsigned required_xlen = 0 )
{
int fd = open ( fn , O_RDONLY ) ;
struct stat s ;
@ -41,10 +42,14 @@ std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t*
throw incompat_xlen ( required_xlen , xlen ) ;
}
assert ( IS_ELFLE ( * eh64 ) | | IS_ELFBE ( * eh64 ) ) ;
assert ( IS_ELF_EXEC ( * eh64 ) ) ;
assert ( IS_ELF_EXEC ( * eh64 ) | | IS_ELF_DYN ( * eh64 ) ) ;
assert ( IS_ELF_RISCV ( * eh64 ) | | IS_ELF_EM_NONE ( * eh64 ) ) ;
assert ( IS_ELF_VCURRENT ( * eh64 ) ) ;
if ( IS_ELF_EXEC ( * eh64 ) ) {
load_offset = 0 ;
}
std : : vector < uint8_t > zeros ;
std : : map < std : : string , uint64_t > symbols ;
@ -52,19 +57,19 @@ std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t*
do { \
ehdr_t * eh = ( ehdr_t * ) buf ; \
phdr_t * ph = ( phdr_t * ) ( buf + bswap ( eh - > e_phoff ) ) ; \
* entry = bswap ( eh - > e_entry ) ; \
* entry = bswap ( eh - > e_entry ) + load_offset ; \
assert ( size > = bswap ( eh - > e_phoff ) + bswap ( eh - > e_phnum ) * sizeof ( * ph ) ) ; \
for ( unsigned i = 0 ; i < bswap ( eh - > e_phnum ) ; i + + ) { \
if ( bswap ( ph [ i ] . p_type ) = = PT_LOAD & & bswap ( ph [ i ] . p_memsz ) ) { \
reg_t load_addr = bswap ( ph [ i ] . p_paddr ) + load_offset ; \
if ( bswap ( ph [ i ] . p_filesz ) ) { \
assert ( size > = bswap ( ph [ i ] . p_offset ) + bswap ( ph [ i ] . p_filesz ) ) ; \
memif - > write ( bswap ( ph [ i ] . p_paddr ) , bswap ( ph [ i ] . p_filesz ) , \
memif - > write ( load_addr , bswap ( ph [ i ] . p_filesz ) , \
( uint8_t * ) buf + bswap ( ph [ i ] . p_offset ) ) ; \
} \
if ( size_t pad = bswap ( ph [ i ] . p_memsz ) - bswap ( ph [ i ] . p_filesz ) ) { \
zeros . resize ( pad ) ; \
memif - > write ( bswap ( ph [ i ] . p_paddr ) + bswap ( ph [ i ] . p_filesz ) , pad , \
zeros . data ( ) ) ; \
memif - > write ( load_addr + bswap ( ph [ i ] . p_filesz ) , pad , zeros . data ( ) ) ; \
} \
} \
} \
@ -96,7 +101,7 @@ std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t*
bswap ( sh [ strtabidx ] . sh_size ) - bswap ( sym [ i ] . st_name ) ; \
assert ( bswap ( sym [ i ] . st_name ) < bswap ( sh [ strtabidx ] . sh_size ) ) ; \
assert ( strnlen ( strtab + bswap ( sym [ i ] . st_name ) , max_len ) < max_len ) ; \
symbols [ strtab + bswap ( sym [ i ] . st_name ) ] = bswap ( sym [ i ] . st_value ) ; \
symbols [ strtab + bswap ( sym [ i ] . st_name ) ] = bswap ( sym [ i ] . st_value ) + load_offset ; \
} \
} \
} while ( 0 )