📄 coffload.c
字号:
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Load COFF Object into memory structures for next processing
*
*
****************************************************************************/
#include "coffload.h"
#include "coffimpl.h"
static char SectionNames[3][COFF_SEC_NAME_LEN] =
{ ".rel", ".symtab", ".strtab" };
static int determine_file_specs( coff_file_handle coff_file_hnd,
coff_file_header *f_hdr )
/***************************************************************/
{
uint_16 cpu_type;
uint_16 flags;
int flag_import_library;
if( (f_hdr->cpu_type == IMAGE_FILE_MACHINE_UNKNOWN) &&
(f_hdr->num_sections == IMPORT_OBJECT_HDR_SIG2) ) {
// COFF import library
cpu_type = ((coff_import_object_header *)f_hdr)->machine;
flags = 0;
flag_import_library = 1;
} else {
// other COFF objects
cpu_type = f_hdr->cpu_type;
flags = f_hdr->flags;
flag_import_library = 0;
}
switch( cpu_type ) {
case IMAGE_FILE_MACHINE_I860:
coff_file_hnd->machine_type = ORL_MACHINE_TYPE_I860;
break;
case IMAGE_FILE_MACHINE_I386:
coff_file_hnd->machine_type = ORL_MACHINE_TYPE_I386;
break;
case IMAGE_FILE_MACHINE_R3000:
coff_file_hnd->machine_type = ORL_MACHINE_TYPE_R3000;
break;
case IMAGE_FILE_MACHINE_R4000:
coff_file_hnd->machine_type = ORL_MACHINE_TYPE_R4000;
break;
case IMAGE_FILE_MACHINE_ALPHA:
coff_file_hnd->machine_type = ORL_MACHINE_TYPE_ALPHA;
break;
case IMAGE_FILE_MACHINE_POWERPC:
coff_file_hnd->machine_type = ORL_MACHINE_TYPE_PPC601;
break;
case IMAGE_FILE_MACHINE_AMD64:
coff_file_hnd->machine_type = ORL_MACHINE_TYPE_AMD64;
break;
case IMAGE_FILE_MACHINE_UNKNOWN:
coff_file_hnd->machine_type = ORL_MACHINE_TYPE_NONE;
break;
default:
coff_file_hnd->machine_type = ORL_MACHINE_TYPE_UNKNOWN;
break;
}
if( flags & IMAGE_FILE_DLL ) {
coff_file_hnd->type = ORL_FILE_TYPE_DLL;
} else if( flags & IMAGE_FILE_EXECUTABLE_IMAGE ) {
coff_file_hnd->type = ORL_FILE_TYPE_EXECUTABLE;
} else {
coff_file_hnd->type = ORL_FILE_TYPE_OBJECT;
}
coff_file_hnd->flags = ORL_FILE_FLAG_NONE;
if( flags & IMAGE_FILE_RELOCS_STRIPPED ) {
coff_file_hnd->flags |= ORL_FILE_FLAG_RELOCS_STRIPPED;
}
if( flags & IMAGE_FILE_LINE_NUMS_STRIPPED ) {
coff_file_hnd->flags |= ORL_FILE_FLAG_LINE_NUMS_STRIPPED;
}
if( flags & IMAGE_FILE_LOCAL_SYMS_STRIPPED ) {
coff_file_hnd->flags |= ORL_FILE_FLAG_LOCAL_SYMS_STRIPPED;
}
if( flags & IMAGE_FILE_DEBUG_STRIPPED ) {
coff_file_hnd->flags |= ORL_FILE_FLAG_DEBUG_STRIPPED;
}
if( flags & IMAGE_FILE_16BIT_MACHINE ) {
coff_file_hnd->flags |= ORL_FILE_FLAG_16BIT_MACHINE;
}
if( flags & IMAGE_FILE_32BIT_MACHINE ) {
coff_file_hnd->flags |= ORL_FILE_FLAG_32BIT_MACHINE;
}
if( flags & IMAGE_FILE_SYSTEM ) {
coff_file_hnd->flags |= ORL_FILE_FLAG_SYSTEM;
}
/*
if( flags & IMAGE_FILE_BYTES_REVERSED_LO ) {
coff_file_hnd->flags |= ORL_FILE_FLAG_LITTLE_ENDIAN;
}
*/
if( flags & IMAGE_FILE_BYTES_REVERSED_HI ) {
coff_file_hnd->flags |= ORL_FILE_FLAG_BIG_ENDIAN;
} else {
// inserting a default here
coff_file_hnd->flags |= ORL_FILE_FLAG_LITTLE_ENDIAN;
}
/*
At this point, we have filled in
coff_file_hnd->type
coff_file_hnd->machine_type
coff_file_hnd->flags
*/
return flag_import_library;
}
static void determine_section_specs( coff_sec_handle coff_sec_hnd,
coff_section_header *s_hdr )
/****************************************************************/
{
coff_sec_hnd->flags = ORL_SEC_FLAG_NONE;
if( s_hdr->flags & IMAGE_SCN_LNK_INFO ) {
coff_sec_hnd->type = ORL_SEC_TYPE_NOTE;
} else if( s_hdr->flags & IMAGE_SCN_CNT_CODE ) {
coff_sec_hnd->type = ORL_SEC_TYPE_PROG_BITS;
coff_sec_hnd->flags |= ORL_SEC_FLAG_EXEC;
} else if( s_hdr->flags & IMAGE_SCN_CNT_INITIALIZED_DATA ) {
coff_sec_hnd->type = ORL_SEC_TYPE_PROG_BITS;
coff_sec_hnd->flags |= ORL_SEC_FLAG_INITIALIZED_DATA;
} else if( s_hdr->flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA ) {
coff_sec_hnd->type = ORL_SEC_TYPE_PROG_BITS;
coff_sec_hnd->flags |= ORL_SEC_FLAG_UNINITIALIZED_DATA;
} else {
coff_sec_hnd->type = ORL_SEC_TYPE_NONE;
}
// if( s_hdr->flags & IMAGE_SCN_TYPE_GROUP ) { // no MS support
// coff_sec_hnd->flags |= ORL_SEC_FLAG_GROUPED;
// }
if( s_hdr->flags & IMAGE_SCN_TYPE_NO_PAD ) {
coff_sec_hnd->flags |= ORL_SEC_FLAG_NO_PADDING;
}
// if( s_hdr->flags & IMAGE_SCN_LNK_OVER ) { // no MS support
// coff_sec_hnd->flags |= ORL_SEC_FLAG_OVERLAY;
// }
if( s_hdr->flags & IMAGE_SCN_LNK_REMOVE ) {
coff_sec_hnd->flags |= ORL_SEC_FLAG_REMOVE;
}
if( s_hdr->flags & IMAGE_SCN_LNK_COMDAT ) {
coff_sec_hnd->flags |= ORL_SEC_FLAG_COMDAT;
}
if( s_hdr->flags & IMAGE_SCN_MEM_DISCARDABLE ) {
coff_sec_hnd->flags |= ORL_SEC_FLAG_DISCARDABLE;
}
if( s_hdr->flags & IMAGE_SCN_MEM_NOT_CACHED ) {
coff_sec_hnd->flags |= ORL_SEC_FLAG_NOT_CACHED;
}
if( s_hdr->flags & IMAGE_SCN_MEM_NOT_PAGED ) {
coff_sec_hnd->flags |= ORL_SEC_FLAG_NOT_PAGEABLE;
}
if( s_hdr->flags & IMAGE_SCN_MEM_SHARED ) {
coff_sec_hnd->flags |= ORL_SEC_FLAG_SHARED;
}
if( s_hdr->flags & IMAGE_SCN_MEM_EXECUTE ) {
coff_sec_hnd->flags |= ORL_SEC_FLAG_EXECUTE_PERMISSION;
}
if( s_hdr->flags & IMAGE_SCN_MEM_READ ) {
coff_sec_hnd->flags |= ORL_SEC_FLAG_READ_PERMISSION;
}
if( s_hdr->flags & IMAGE_SCN_MEM_WRITE ) {
coff_sec_hnd->flags |= ORL_SEC_FLAG_WRITE_PERMISSION;
}
coff_sec_hnd->align = (s_hdr->flags & IMAGE_SCN_ALIGN_MASK)
>> COFF_SEC_FLAG_ALIGN_SHIFT;
if( coff_sec_hnd->align == 0 ) {
coff_sec_hnd->align = 4;
} else {
coff_sec_hnd->align -= 1;
}
}
static void free_coff_sec_handles( coff_file_handle coff_file_hnd,
int num_alloced )
/****************************************************************/
{
int loop;
if( coff_file_hnd->coff_sec_hnd != NULL ) {
for( loop = 0; loop < num_alloced; loop++ ) {
if( coff_file_hnd->coff_sec_hnd[loop]->name_alloced ) {
_ClientFree( coff_file_hnd,
coff_file_hnd->coff_sec_hnd[loop]->name );
}
_ClientFree( coff_file_hnd, coff_file_hnd->coff_sec_hnd[loop] );
}
_ClientFree( coff_file_hnd, coff_file_hnd->coff_sec_hnd );
} else {
for( loop = 0; loop < num_alloced; loop++ ) {
_ClientFree( coff_file_hnd, coff_file_hnd->orig_sec_hnd[loop] );
}
}
_ClientFree( coff_file_hnd, coff_file_hnd->orig_sec_hnd );
}
static orl_return load_coff_sec_handles( coff_file_handle coff_file_hnd,
coff_file_header * f_hdr )
/**********************************************************************/
{
coff_section_header * s_hdr;
coff_sec_handle coff_sec_hnd;
coff_sec_handle coff_reloc_sec_hnd;
int loop;
coff_quantity num_reloc_secs = 0;
orl_file_offset * reloc_sec_offset;
orl_sec_size * reloc_sec_size;
coff_quantity reloc_secs_created;
if( coff_file_hnd->num_sections == 0 ) {
reloc_sec_offset = NULL;
reloc_sec_size = NULL;
coff_file_hnd->orig_sec_hnd = NULL;
} else {
reloc_sec_offset = (orl_file_offset *) _ClientAlloc( coff_file_hnd, sizeof( orl_file_offset ) * coff_file_hnd->num_sections );
if( !(reloc_sec_offset) ) return( ORL_OUT_OF_MEMORY );
reloc_sec_size = (orl_sec_size *) _ClientAlloc( coff_file_hnd, sizeof( orl_sec_size ) * coff_file_hnd->num_sections );
if( !(reloc_sec_size) ) {
_ClientFree( coff_file_hnd, reloc_sec_offset );
return( ORL_OUT_OF_MEMORY );
}
memset( reloc_sec_offset, 0, sizeof( orl_file_offset ) * coff_file_hnd->num_sections );
memset( reloc_sec_size, 0, sizeof( orl_sec_size ) * coff_file_hnd->num_sections );
coff_file_hnd->orig_sec_hnd = (coff_sec_handle *) _ClientAlloc( coff_file_hnd, sizeof( coff_sec_handle ) * coff_file_hnd->num_sections );
if( !( coff_file_hnd->orig_sec_hnd ) ) {
_ClientFree( coff_file_hnd, reloc_sec_offset );
_ClientFree( coff_file_hnd, reloc_sec_size );
return( ORL_OUT_OF_MEMORY );
}
}
coff_file_hnd->coff_sec_hnd = NULL;
s_hdr = (coff_section_header *) coff_file_hnd->s_hdr_table_buffer;
for( loop = 0; loop < coff_file_hnd->num_sections; loop++ ) {
coff_sec_hnd = (coff_sec_handle) _ClientAlloc( coff_file_hnd, sizeof( coff_sec_handle_struct ) );
if( !coff_sec_hnd ) {
free_coff_sec_handles( coff_file_hnd, loop );
_ClientFree( coff_file_hnd, reloc_sec_offset );
_ClientFree( coff_file_hnd, reloc_sec_size );
return( ORL_OUT_OF_MEMORY );
}
coff_file_hnd->orig_sec_hnd[loop] = coff_sec_hnd;
if( s_hdr->name[0] != '/' ) {
coff_sec_hnd->name = _ClientAlloc( coff_file_hnd, COFF_SEC_NAME_LEN + 1 );
if( !(coff_sec_hnd->name) ) {
free_coff_sec_handles( coff_file_hnd, loop );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -