📄 coffload.c
字号:
_ClientFree( coff_file_hnd, reloc_sec_offset );
_ClientFree( coff_file_hnd, reloc_sec_size );
return( ORL_OUT_OF_MEMORY );
}
coff_sec_hnd->name_alloced = COFF_TRUE;
strncpy( coff_sec_hnd->name, s_hdr->name, COFF_SEC_NAME_LEN );
coff_sec_hnd->name[COFF_SEC_NAME_LEN] = 0;
} else {
coff_sec_hnd->name = s_hdr->name;
coff_sec_hnd->name_alloced = COFF_FALSE;
}
coff_sec_hnd->file_format = ORL_COFF;
coff_sec_hnd->relocs_done = COFF_FALSE;
coff_sec_hnd->coff_file_hnd = coff_file_hnd;
coff_sec_hnd->size = s_hdr->size;
coff_sec_hnd->base = s_hdr->offset;
coff_sec_hnd->offset = s_hdr->rawdata_ptr;
coff_sec_hnd->hdr = s_hdr;
determine_section_specs( coff_sec_hnd, s_hdr );
coff_sec_hnd->contents = NULL;
coff_sec_hnd->assoc.normal.reloc_sec = NULL;
reloc_sec_offset[loop] = s_hdr->reloc_ptr;
if( s_hdr->num_relocs > 0 ) {
num_reloc_secs++;
}
reloc_sec_size[loop] = s_hdr->num_relocs * sizeof( coff_reloc );
s_hdr++;
}
/* There are num_reloc_secs + 2 additional section handles to create
(one each for the symbol and string tables) */
coff_file_hnd->coff_sec_hnd = (coff_sec_handle *) _ClientAlloc( coff_file_hnd, sizeof( coff_sec_handle ) * (coff_file_hnd->num_sections + num_reloc_secs + 2) );
if( !(coff_file_hnd->coff_sec_hnd) ) {
free_coff_sec_handles( coff_file_hnd, coff_file_hnd->num_sections );
_ClientFree( coff_file_hnd, reloc_sec_offset );
_ClientFree( coff_file_hnd, reloc_sec_size );
return( ORL_OUT_OF_MEMORY );
}
memcpy( coff_file_hnd->coff_sec_hnd, coff_file_hnd->orig_sec_hnd, sizeof( coff_sec_handle ) * coff_file_hnd->num_sections );
reloc_secs_created = 0;
for( loop = 0; loop < coff_file_hnd->num_sections; loop++ ) {
if( reloc_sec_size[loop] > 0 ) {
reloc_secs_created++;
// create a reloc section
coff_file_hnd->coff_sec_hnd[coff_file_hnd->num_sections + reloc_secs_created] = (coff_sec_handle) _ClientAlloc( coff_file_hnd, sizeof( coff_sec_handle_struct ) );
coff_reloc_sec_hnd = coff_file_hnd->coff_sec_hnd[coff_file_hnd->num_sections + reloc_secs_created];
if( !coff_reloc_sec_hnd ) {
free_coff_sec_handles( coff_file_hnd, coff_file_hnd->num_sections + reloc_secs_created );
_ClientFree( coff_file_hnd, reloc_sec_offset );
_ClientFree( coff_file_hnd, reloc_sec_size );
return( ORL_OUT_OF_MEMORY );
}
coff_reloc_sec_hnd->file_format = ORL_COFF;
coff_reloc_sec_hnd->coff_file_hnd = coff_file_hnd;
coff_reloc_sec_hnd->name = SectionNames[0];
coff_reloc_sec_hnd->name_alloced = COFF_FALSE;
coff_reloc_sec_hnd->relocs_done = COFF_FALSE;
coff_reloc_sec_hnd->size = reloc_sec_size[loop];
coff_reloc_sec_hnd->base = 0;
coff_reloc_sec_hnd->offset = reloc_sec_offset[loop];
coff_reloc_sec_hnd->type = ORL_SEC_TYPE_RELOCS;
coff_reloc_sec_hnd->flags = ORL_SEC_FLAG_NONE;
coff_reloc_sec_hnd->hdr = NULL;
coff_reloc_sec_hnd->assoc.reloc.orig_sec = coff_file_hnd->coff_sec_hnd[loop];
coff_reloc_sec_hnd->assoc.reloc.relocs = NULL;
coff_file_hnd->coff_sec_hnd[loop]->assoc.normal.reloc_sec = coff_reloc_sec_hnd;
coff_file_hnd->coff_sec_hnd[coff_file_hnd->num_sections + reloc_secs_created - 1] = coff_reloc_sec_hnd;
}
}
// create the symbol table section
coff_file_hnd->symbol_table = (coff_sec_handle) _ClientAlloc( coff_file_hnd, sizeof( coff_sec_handle_struct ) );
if( !(coff_file_hnd->symbol_table) ) {
free_coff_sec_handles( coff_file_hnd, loop + coff_file_hnd->num_sections );
_ClientFree( coff_file_hnd, reloc_sec_offset );
_ClientFree( coff_file_hnd, reloc_sec_size );
return( ORL_OUT_OF_MEMORY );
}
coff_file_hnd->symbol_table->file_format = ORL_COFF;
coff_file_hnd->symbol_table->coff_file_hnd = coff_file_hnd;
coff_file_hnd->symbol_table->name = SectionNames[1];
coff_file_hnd->symbol_table->name_alloced = COFF_FALSE;
coff_file_hnd->symbol_table->relocs_done = COFF_FALSE;
coff_file_hnd->symbol_table->size = f_hdr->num_symbols * sizeof( coff_symbol );
coff_file_hnd->symbol_table->base = 0;
coff_file_hnd->symbol_table->offset = f_hdr->sym_table;
coff_file_hnd->symbol_table->hdr = NULL;
coff_file_hnd->symbol_table->assoc.normal.reloc_sec = NULL;
coff_file_hnd->symbol_table->type = ORL_SEC_TYPE_SYM_TABLE;
coff_file_hnd->symbol_table->flags = ORL_SEC_FLAG_NONE;
coff_file_hnd->coff_sec_hnd[coff_file_hnd->num_sections + reloc_secs_created] = coff_file_hnd->symbol_table;
loop++;
// create the string table section
coff_file_hnd->string_table = (coff_sec_handle) _ClientAlloc( coff_file_hnd, sizeof( coff_sec_handle_struct ) );
if( !(coff_file_hnd->string_table) ) {
free_coff_sec_handles( coff_file_hnd, loop + coff_file_hnd->num_sections );
_ClientFree( coff_file_hnd, reloc_sec_offset );
_ClientFree( coff_file_hnd, reloc_sec_size );
return( ORL_OUT_OF_MEMORY );
}
coff_file_hnd->string_table->file_format = ORL_COFF;
coff_file_hnd->string_table->coff_file_hnd = coff_file_hnd;
coff_file_hnd->string_table->name = SectionNames[2];
coff_file_hnd->string_table->name_alloced = COFF_FALSE;
coff_file_hnd->string_table->relocs_done = COFF_FALSE;
if( coff_file_hnd->type == ORL_FILE_TYPE_OBJECT ) {
coff_file_hnd->string_table->size = 4; // for now
} else {
coff_file_hnd->string_table->size = 0; // for now
}
coff_file_hnd->string_table->base = 0;
coff_file_hnd->string_table->offset = coff_file_hnd->symbol_table->offset + coff_file_hnd->symbol_table->size;
coff_file_hnd->string_table->hdr = NULL;
coff_file_hnd->string_table->assoc.normal.reloc_sec = NULL;
coff_file_hnd->string_table->type = ORL_SEC_TYPE_STR_TABLE;
coff_file_hnd->string_table->flags = ORL_SEC_FLAG_NONE;
coff_file_hnd->coff_sec_hnd[coff_file_hnd->num_sections + reloc_secs_created + 1] = coff_file_hnd->string_table;
_ClientFree( coff_file_hnd, reloc_sec_offset );
_ClientFree( coff_file_hnd, reloc_sec_size );
coff_file_hnd->num_sections += num_reloc_secs + 2;
return( ORL_OKAY );
}
orl_return CoffLoadFileStructure( coff_file_handle coff_file_hnd )
/****************************************************************/
{
orl_return error;
coff_file_header * f_hdr;
coff_quantity sec_header_table_size;
coff_quantity buf_size;
coff_sec_offset string_table_index;
coff_sec_handle last_sec_hnd;
coff_sec_handle coff_sec_hnd;
int loop;
int loop_limit;
pe_header * pe_hdr;
char * PE;
orl_file_offset PEoffset=0;
pe_hdr = _ClientRead( coff_file_hnd, 2 );
_ClientSeek( coff_file_hnd, -2, SEEK_CUR );
if( pe_hdr->MZ[0] == 'M' && pe_hdr->MZ[1] == 'Z' ) {
pe_hdr = _ClientRead( coff_file_hnd, sizeof( pe_header ) );
_ClientSeek( coff_file_hnd, pe_hdr->offset - sizeof( pe_header ), SEEK_CUR );
PE = _ClientRead( coff_file_hnd, 4 );
if( PE[0] == 'P' && PE[1] == 'E' && PE[2] == '\0' && PE[3] == '\0' ) {
PEoffset = pe_hdr->offset + 4;
} else {
_ClientSeek( coff_file_hnd, -pe_hdr->offset-4, SEEK_CUR );
}
}
coff_file_hnd->f_hdr_buffer = _ClientRead( coff_file_hnd, sizeof( coff_file_header ) );
if( !(coff_file_hnd->f_hdr_buffer) ) return( ORL_OUT_OF_MEMORY );
f_hdr = (coff_file_header *) coff_file_hnd->f_hdr_buffer;
if (determine_file_specs( coff_file_hnd, f_hdr )) {
// we have identified an import_object_header
// convert short import library structures to long import
// library structures, change _ClientRead and _ClientSeek
// macros to read from converted metadata
error = convert_import_library( coff_file_hnd );
if ( error != ORL_OKAY ) {
return( error );
}
// reread new converted file header and next process as normal
coff_file_hnd->f_hdr_buffer = _ClientRead( coff_file_hnd, sizeof( coff_file_header ) );
if( !(coff_file_hnd->f_hdr_buffer) ) return( ORL_OUT_OF_MEMORY );
f_hdr = (coff_file_header *) coff_file_hnd->f_hdr_buffer;
determine_file_specs( coff_file_hnd, f_hdr );
}
if( f_hdr->opt_hdr_size > 0 ) { // skip optional header
pe_opt_hdr *opt_hdr = (pe_opt_hdr *)_ClientRead(coff_file_hnd, f_hdr->opt_hdr_size);
if( (opt_hdr->magic == 0x10b) || (opt_hdr->magic == 0x20b) ) {
coff_file_hnd->export_table_rva = opt_hdr->export_table_rva;
} else {
coff_file_hnd->export_table_rva = 0L;
}
}
coff_file_hnd->initial_size = sizeof( coff_file_header ) + f_hdr->opt_hdr_size + PEoffset;
switch( coff_file_hnd->machine_type ) {
case ORL_MACHINE_TYPE_UNKNOWN:
return( ORL_ERROR );
default:
break;
}
coff_file_hnd->num_symbols = f_hdr->num_symbols;
coff_file_hnd->num_sections = f_hdr->num_sections;
sec_header_table_size = coff_file_hnd->num_sections * sizeof( coff_section_header );
if( coff_file_hnd->num_sections > 0 ) {
coff_file_hnd->s_hdr_table_buffer = _ClientRead( coff_file_hnd,
sec_header_table_size);
if( !(coff_file_hnd->s_hdr_table_buffer) ) {
return( ORL_ERROR );
}
}
error = load_coff_sec_handles( coff_file_hnd, f_hdr );
if( error != ORL_OKAY ) {
return( error );
}
last_sec_hnd = coff_file_hnd->coff_sec_hnd[coff_file_hnd->num_sections - 1];
coff_file_hnd->initial_size += sec_header_table_size;
buf_size = 0;
for( loop=0; loop < coff_file_hnd->num_sections; loop++ ) {
coff_sec_hnd = coff_file_hnd->coff_sec_hnd[loop];
if( (coff_sec_hnd->offset + coff_sec_hnd->size) > buf_size &&
!(coff_sec_hnd->flags & ORL_SEC_FLAG_UNINITIALIZED_DATA) ) {
buf_size = coff_sec_hnd->offset + coff_sec_hnd->size;
}
}
coff_file_hnd->size = buf_size;
buf_size -= coff_file_hnd->initial_size;
coff_file_hnd->rest_of_file_buffer = _ClientRead( coff_file_hnd, buf_size );
if( !(coff_file_hnd->rest_of_file_buffer ) ) {
return( ORL_ERROR );
}
loop_limit = coff_file_hnd->num_sections;
if( last_sec_hnd == coff_file_hnd->string_table &&
coff_file_hnd->type == ORL_FILE_TYPE_OBJECT ) {
memcpy( &(last_sec_hnd->size), coff_file_hnd->rest_of_file_buffer + last_sec_hnd->offset - coff_file_hnd->initial_size, sizeof( coff_sec_size ) );
if( last_sec_hnd->size < 4 ) {
last_sec_hnd->size = 0;
}
if( last_sec_hnd->size != 0 ) {
last_sec_hnd->size -= sizeof( coff_sec_size );
}
if( last_sec_hnd->size > 0 && last_sec_hnd->offset != 0 ) {
if( last_sec_hnd->offset == buf_size +
coff_file_hnd->initial_size - 4 ) {
last_sec_hnd->contents = _ClientRead( coff_file_hnd,
last_sec_hnd->size );
coff_file_hnd->size += last_sec_hnd->size;
} else {
last_sec_hnd->contents = coff_file_hnd->rest_of_file_buffer +
last_sec_hnd->offset - coff_file_hnd->initial_size +
sizeof( coff_sec_size );
}
if( !(last_sec_hnd->contents ) ) {
return( ORL_ERROR );
}
} else {
last_sec_hnd->contents = NULL;
}
loop_limit--;
}
// determine contents pointers of all sections
for( loop = 0; loop < loop_limit; loop++ ) {
coff_sec_hnd = coff_file_hnd->coff_sec_hnd[loop];
if( (coff_sec_hnd->size > 0
|| coff_sec_hnd->type == ORL_SEC_TYPE_STR_TABLE)
&& coff_sec_hnd->offset != 0 ) {
coff_sec_hnd->contents = coff_file_hnd->rest_of_file_buffer +
coff_sec_hnd->offset - coff_file_hnd->initial_size;
}
}
if( last_sec_hnd != coff_file_hnd->string_table ) {
memcpy( &(coff_file_hnd->string_table->size),
coff_file_hnd->string_table->contents, sizeof(coff_sec_size) );
if( coff_file_hnd->string_table->size != 0 ) {
coff_file_hnd->string_table->size -= sizeof( coff_sec_size );
coff_file_hnd->string_table->contents += sizeof( coff_sec_size );
}
}
// determine section names
for( loop = 0; loop < coff_file_hnd->num_sections; loop++ ) {
coff_sec_hnd = coff_file_hnd->coff_sec_hnd[loop];
if( coff_sec_hnd->name[0] == '/' ) {
// change pointer to point into string table
string_table_index = atoi( &(coff_sec_hnd->name[1]) )
- sizeof(coff_sec_size);
coff_sec_hnd->name = &(coff_file_hnd->string_table->contents[string_table_index]);
}
}
return( ORL_OKAY );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -