📄 elfload.c
字号:
for( loop = 0; loop < num_alloced; loop++ ) {
_ClientFree( elf_file_hnd, elf_file_hnd->orig_sec_hnd[loop] );
}
}
_ClientFree( elf_file_hnd, elf_file_hnd->orig_sec_hnd );
}
static orl_return load_elf_sec_handles( elf_file_handle elf_file_hnd, orl_sec_offset *name_index )
{
Elf32_Shdr *s_hdr;
elf_sec_handle elf_sec_hnd;
int loop;
orl_sec_offset *associated_index;
orl_sec_offset *associated2_index;
associated_index = (orl_sec_offset *) _ClientAlloc( elf_file_hnd, sizeof( Elf32_Word ) * elf_file_hnd->num_sections );
if( !associated_index ) return( ORL_OUT_OF_MEMORY );
associated2_index = (orl_sec_offset *) _ClientAlloc( elf_file_hnd, sizeof( Elf32_Word ) * elf_file_hnd->num_sections );
if( !associated2_index ) {
_ClientFree( elf_file_hnd, associated_index );
return( ORL_OUT_OF_MEMORY );
}
elf_file_hnd->symbol_table = NULL;
elf_file_hnd->elf_sec_hnd = NULL;
elf_file_hnd->orig_sec_hnd = (elf_sec_handle *) _ClientAlloc( elf_file_hnd, sizeof( elf_sec_handle ) * elf_file_hnd->num_sections );
if( !( elf_file_hnd->orig_sec_hnd ) ) {
_ClientFree( elf_file_hnd, associated_index );
_ClientFree( elf_file_hnd, associated2_index );
return( ORL_OUT_OF_MEMORY );
}
s_hdr = (Elf32_Shdr *) elf_file_hnd->s_hdr_table_buffer;
s_hdr++; // skip over index 0
for( loop = 0; loop < elf_file_hnd->num_sections; loop++ ) {
fix_shdr_byte_order( elf_file_hnd, s_hdr );
elf_sec_hnd = (elf_sec_handle) _ClientAlloc( elf_file_hnd, sizeof( elf_sec_handle_struct ) );
if( !elf_sec_hnd ) {
free_elf_sec_handles( elf_file_hnd, loop );
_ClientFree( elf_file_hnd, associated_index );
_ClientFree( elf_file_hnd, associated2_index );
_ClientFree( elf_file_hnd, elf_file_hnd->orig_sec_hnd );
return( ORL_OUT_OF_MEMORY );
}
elf_file_hnd->orig_sec_hnd[loop] = elf_sec_hnd;
name_index[loop] = s_hdr->sh_name;
elf_sec_hnd->file_format = ORL_ELF;
elf_sec_hnd->elf_file_hnd = elf_file_hnd;
elf_sec_hnd->size = s_hdr->sh_size;
elf_sec_hnd->base = s_hdr->sh_addr;
elf_sec_hnd->index = loop + 1;
elf_sec_hnd->offset = s_hdr->sh_offset;
switch( s_hdr->sh_addralign ) {
case 0:
case 1:
elf_sec_hnd->alignment = 0;
break;
case 2:
elf_sec_hnd->alignment = 1;
break;
case 4:
elf_sec_hnd->alignment = 2;
break;
case 8:
elf_sec_hnd->alignment = 3;
break;
case 16:
elf_sec_hnd->alignment = 4;
break;
case 32:
elf_sec_hnd->alignment = 5;
break;
case 64:
elf_sec_hnd->alignment = 6;
break;
case 128:
elf_sec_hnd->alignment = 7;
break;
case 256:
elf_sec_hnd->alignment = 8;
break;
}
elf_sec_hnd->contents = NULL;
memset( &(elf_sec_hnd->assoc), '\0', sizeof( elf_sec_hnd->assoc ) );
determine_section_specs( elf_sec_hnd, s_hdr );
switch( elf_sec_hnd->type ) {
case ORL_SEC_TYPE_SYM_TABLE:
elf_file_hnd->symbol_table = elf_sec_hnd;
case ORL_SEC_TYPE_DYN_SYM_TABLE:
case ORL_SEC_TYPE_IMPORT:
case ORL_SEC_TYPE_EXPORT:
associated_index[loop] = s_hdr->sh_link - 1;
break;
case ORL_SEC_TYPE_RELOCS:
case ORL_SEC_TYPE_RELOCS_EXPADD:
// Certain funky toolchains produce two reloc sections for each
// section containing relocations (both .rel and .rela) and one of
// them is empty. We have to ignore the empty one!
if( s_hdr->sh_size != 0 ) {
associated_index[loop] = s_hdr->sh_info - 1;
associated2_index[loop] = s_hdr->sh_link - 1;
} else {
associated_index[loop] = -1;
associated2_index[loop] = -1;
}
break;
default:
break;
}
s_hdr++;
}
for( loop = 0; loop < elf_file_hnd->num_sections; loop++ ) {
elf_sec_hnd = elf_file_hnd->orig_sec_hnd[loop];
switch( elf_sec_hnd->type ) {
case ORL_SEC_TYPE_SYM_TABLE:
case ORL_SEC_TYPE_DYN_SYM_TABLE:
elf_sec_hnd->assoc.sym.string_table = elf_file_hnd->orig_sec_hnd[associated_index[loop]];
break;
case ORL_SEC_TYPE_IMPORT:
elf_sec_hnd->assoc.import.string_table = elf_file_hnd->orig_sec_hnd[associated_index[loop]];
break;
case ORL_SEC_TYPE_EXPORT:
elf_sec_hnd->assoc.export.symbol_table = elf_file_hnd->orig_sec_hnd[associated_index[loop]];
break;
case ORL_SEC_TYPE_RELOCS:
case ORL_SEC_TYPE_RELOCS_EXPADD:
elf_sec_hnd->assoc.reloc.symbol_table = elf_file_hnd->orig_sec_hnd[associated2_index[loop]];
// some silly people create reloc sections with no associated section
if( associated_index[loop] != -1 ) {
elf_sec_hnd->assoc.reloc.orig_sec = elf_file_hnd->orig_sec_hnd[associated_index[loop]];
elf_file_hnd->orig_sec_hnd[associated_index[loop]]->assoc.normal.reloc_sec = elf_sec_hnd;
}
break;
default:
break;
}
}
elf_file_hnd->elf_sec_hnd = (elf_sec_handle *) _ClientAlloc( elf_file_hnd, sizeof( elf_sec_handle ) * elf_file_hnd->num_sections );
if( !( elf_file_hnd->elf_sec_hnd ) ) {
_ClientFree( elf_file_hnd, associated_index );
_ClientFree( elf_file_hnd, associated2_index );
_ClientFree( elf_file_hnd, elf_file_hnd->orig_sec_hnd );
return( ORL_OUT_OF_MEMORY );
}
memcpy( elf_file_hnd->elf_sec_hnd, elf_file_hnd->orig_sec_hnd, sizeof( elf_sec_handle ) * elf_file_hnd->num_sections );
_ClientFree( elf_file_hnd, associated_index );
_ClientFree( elf_file_hnd, associated2_index );
return( ORL_OKAY );
}
static int sec_compare( const void *_first_sec, const void *_second_sec )
{
const elf_sec_handle *first_sec = _first_sec;
const elf_sec_handle *second_sec = _second_sec;
if( (*first_sec)->offset > (*second_sec)->offset ) {
return( 1 );
} else if( (*first_sec)->offset < (*second_sec)->offset ) {
return( -1 );
} else {
return( 0 );
}
}
orl_return ElfLoadFileStructure( elf_file_handle elf_file_hnd )
{
orl_return error;
Elf32_Ehdr *e_hdr;
elf_sec_handle elf_sec_hnd;
elf_quantity contents_size1;
elf_quantity contents_size2;
elf_quantity sec_header_table_size;
int loop;
orl_sec_offset *name_index;
char *string_table;
elf_file_hnd->e_hdr_buffer = _ClientRead( elf_file_hnd, sizeof(Elf32_Ehdr));
if( !(elf_file_hnd->e_hdr_buffer) )
return( ORL_ERROR );
e_hdr = (Elf32_Ehdr *) elf_file_hnd->e_hdr_buffer;
determine_file_class( elf_file_hnd, e_hdr );
fix_ehdr_byte_order( elf_file_hnd, e_hdr );
determine_file_specs( elf_file_hnd, e_hdr );
elf_file_hnd->num_sections = e_hdr->e_shnum - 1; // -1 to ignore shdr table index
contents_size1 = e_hdr->e_shoff - e_hdr->e_ehsize;
sec_header_table_size = e_hdr->e_shentsize * e_hdr->e_shnum;
// e_ehsize might not be the same as sizeof(Elf32_Ehdr) (different versions)
_ClientSeek( elf_file_hnd, e_hdr->e_ehsize - sizeof(Elf32_Ehdr), SEEK_CUR );
if( contents_size1 > 0 ) {
elf_file_hnd->contents_buffer1 = _ClientRead( elf_file_hnd,
contents_size1 );
if( !(elf_file_hnd->contents_buffer1) ) {
return( ORL_ERROR );
}
} else {
elf_file_hnd->contents_buffer1 = NULL;
}
elf_file_hnd->s_hdr_table_buffer = _ClientRead( elf_file_hnd,
sec_header_table_size );
if( !(elf_file_hnd->s_hdr_table_buffer) )
return( ORL_ERROR );
name_index = _ClientAlloc( elf_file_hnd,
sizeof(orl_sec_offset) * elf_file_hnd->num_sections );
if( !name_index )
return( ORL_OUT_OF_MEMORY );
error = load_elf_sec_handles( elf_file_hnd, name_index );
if( error != ORL_OKAY ) {
_ClientFree( elf_file_hnd, name_index );
return( error );
}
// now sort the section handles by file offset
qsort( elf_file_hnd->elf_sec_hnd, elf_file_hnd->num_sections,
sizeof( elf_sec_handle ), sec_compare );
elf_sec_hnd = elf_file_hnd->elf_sec_hnd[elf_file_hnd->num_sections - 1];
contents_size2 = elf_sec_hnd->offset + elf_sec_hnd->size - e_hdr->e_shoff
- sec_header_table_size;
if( contents_size2 > 0 ) {
elf_file_hnd->size = elf_sec_hnd->offset + elf_sec_hnd->size;
elf_file_hnd->contents_buffer2 = _ClientRead( elf_file_hnd,
contents_size2 );
if( !(elf_file_hnd->contents_buffer2) ) {
_ClientFree( elf_file_hnd, name_index );
return( ORL_ERROR );
}
} else {
elf_file_hnd->size = e_hdr->e_shoff + sec_header_table_size;
}
// determine contents pointers of all sections
for( loop = 0; loop < elf_file_hnd->num_sections; loop++ ) {
elf_sec_hnd = elf_file_hnd->elf_sec_hnd[loop];
if( elf_sec_hnd->size > 0 ) {
if( elf_sec_hnd->offset < e_hdr->e_shoff ) {
elf_sec_hnd->contents = elf_file_hnd->contents_buffer1
+ elf_sec_hnd->offset - e_hdr->e_ehsize;
} else {
elf_sec_hnd->contents = elf_file_hnd->contents_buffer2
+ elf_sec_hnd->offset - e_hdr->e_shoff
- sec_header_table_size;
}
}
}
// determine section names
string_table = elf_file_hnd->orig_sec_hnd[e_hdr->e_shstrndx - 1]->contents;
for( loop = 0; loop < elf_file_hnd->num_sections; loop++ ) {
elf_file_hnd->orig_sec_hnd[loop]->name = string_table +name_index[loop];
}
_ClientFree( elf_file_hnd, name_index );
return( ORL_OKAY );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -