📄 coffentr.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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include "coffentr.h"
#include "coffflhn.h"
#include "cofflwlv.h"
#include "coffload.h"
#include "orlhash.h"
coff_handle COFFENTRY CoffInit( orl_funcs * funcs )
{
coff_handle coff_hnd;
coff_hnd = (coff_handle) funcs->alloc( sizeof( coff_handle_struct ) );
if( !coff_hnd ) return( NULL );
coff_hnd->funcs = funcs;
coff_hnd->first_file_hnd = NULL;
return( coff_hnd );
}
orl_return COFFENTRY CoffFini( coff_handle coff_hnd )
{
orl_return error;
while( coff_hnd->first_file_hnd != NULL ) {
error = CoffRemoveFileLinks( coff_hnd->first_file_hnd );
if( error != ORL_OKAY ) return( error );
}
coff_hnd->funcs->free( coff_hnd );
return( ORL_OKAY );
}
coff_file_handle COFFENTRY CoffFileInit( coff_handle coff_hnd, void *file )
{
coff_file_handle coff_file_hnd;
orl_return return_val;
coff_file_hnd = (coff_file_handle) coff_hnd->funcs->alloc( sizeof( coff_file_handle_struct ) );
if( !coff_file_hnd ) return( NULL );
coff_file_hnd->coff_sec_hnd = NULL;
coff_file_hnd->orig_sec_hnd = NULL;
coff_file_hnd->file = file;
coff_file_hnd->sec_name_hash_table = NULL;
coff_file_hnd->symbol_handles = NULL;
coff_file_hnd->implib_data = NULL;
CoffAddFileLinks( coff_hnd, coff_file_hnd );
return_val = CoffLoadFileStructure( coff_file_hnd );
if( return_val != ORL_OKAY ) {
CoffRemoveFileLinks( coff_file_hnd );
return( NULL );
}
return( coff_file_hnd );
}
orl_return COFFENTRY CoffFileFini( coff_file_handle coff_file_hnd )
{
return( CoffRemoveFileLinks( coff_file_hnd ) );
}
orl_return COFFENTRY CoffFileScan( coff_file_handle coff_file_hnd, char *desired, orl_sec_return_func return_func )
{
orl_hash_data_struct * data_struct;
int loop;
orl_return error;
if( !desired ) {
/* global request */
for( loop = 0; loop < coff_file_hnd->num_sections; loop++ ) {
error = return_func( (orl_sec_handle) coff_file_hnd->coff_sec_hnd[loop] );
if( error != ORL_OKAY ) return( error );
}
} else {
if( !(coff_file_hnd->sec_name_hash_table) ) {
error = CoffBuildSecNameHashTable( coff_file_hnd );
if( error != ORL_OKAY ) return( error );
}
data_struct = ORLHashTableQuery( coff_file_hnd->sec_name_hash_table, (orl_hash_value) desired );
while( data_struct != NULL ) {
error = return_func( (orl_sec_handle) data_struct->data );
if( error != ORL_OKAY ) return( error );
data_struct = data_struct->next;
}
}
return( ORL_OKAY );
}
unsigned long COFFENTRY CoffExportTableRVA(coff_file_handle coff_file_hnd)
{
return coff_file_hnd->export_table_rva;
}
orl_machine_type COFFENTRY CoffFileGetMachineType( coff_file_handle coff_file_hnd )
{
return( coff_file_hnd->machine_type );
}
orl_file_flags COFFENTRY CoffFileGetFlags( coff_file_handle coff_file_hnd )
{
return( coff_file_hnd->flags );
}
orl_file_type COFFENTRY CoffFileGetType( coff_file_handle coff_file_hnd )
{
return( coff_file_hnd->type );
}
orl_file_size COFFENTRY CoffFileGetSize( coff_file_handle coff_file_hnd )
{
return( coff_file_hnd->size );
}
coff_sec_handle COFFENTRY CoffFileGetSymbolTable( coff_file_handle coff_file_hnd )
{
return( coff_file_hnd->symbol_table );
}
coff_sec_handle COFFENTRY CoffSecGetStringTable( coff_sec_handle coff_sec_hnd )
{
return( coff_sec_hnd->coff_file_hnd->string_table );
}
coff_sec_handle COFFENTRY CoffSecGetSymbolTable( coff_sec_handle coff_sec_hnd )
{
return( coff_sec_hnd->coff_file_hnd->symbol_table );
}
char * COFFENTRY CoffSecGetName( coff_sec_handle coff_sec_hnd )
{
return( coff_sec_hnd->name );
}
orl_sec_offset COFFENTRY CoffSecGetBase( coff_sec_handle coff_sec_hnd )
{
return( coff_sec_hnd->base );
}
orl_sec_size COFFENTRY CoffSecGetSize( coff_sec_handle coff_sec_hnd )
{
return( coff_sec_hnd->size );
}
orl_sec_type COFFENTRY CoffSecGetType( coff_sec_handle coff_sec_hnd )
{
return( coff_sec_hnd->type );
}
orl_sec_flags COFFENTRY CoffSecGetFlags( coff_sec_handle coff_sec_hnd )
{
return( coff_sec_hnd->flags );
}
orl_sec_alignment COFFENTRY CoffSecGetAlignment( coff_sec_handle coff_sec_hnd )
{
return( coff_sec_hnd->align );
}
coff_sec_handle COFFENTRY CoffSecGetRelocTable( coff_sec_handle coff_sec_hnd )
{
if( coff_sec_hnd->type != ORL_SEC_TYPE_RELOCS ) {
return( coff_sec_hnd->assoc.normal.reloc_sec );
}
return( NULL );
}
orl_table_index COFFENTRY CoffSecGetNumLines( coff_sec_handle coff_sec_hnd )
{
if( coff_sec_hnd->hdr != NULL ) {
return( coff_sec_hnd->hdr->num_lineno );
}
return( 0 );
}
orl_linnum * COFFENTRY CoffSecGetLines( coff_sec_handle coff_sec_hnd )
{
orl_table_index numlines;
numlines = CoffSecGetNumLines( coff_sec_hnd );
if( numlines > 0 ) {
return CoffConvertLines( coff_sec_hnd, numlines );
}
return( NULL );
}
orl_sec_offset COFFENTRY CoffSecGetOffset( coff_sec_handle coff_sec_hnd )
{
if( coff_sec_hnd->hdr != NULL ) {
return( coff_sec_hnd->hdr->offset );
}
return( 0 );
}
orl_return COFFENTRY CoffSecGetContents( coff_sec_handle coff_sec_hnd, char **buffer )
{
if( coff_sec_hnd->contents != NULL ) {
*buffer = coff_sec_hnd->contents;
return( ORL_OKAY );
}
return( ORL_ERROR );
}
orl_return COFFENTRY CoffSecQueryReloc( coff_sec_handle coff_sec_hnd, coff_sec_offset sec_offset, orl_reloc_return_func return_func )
{
int index;
coff_sec_handle reloc_sec_hnd;
orl_reloc * reloc;
orl_return return_val;
if( coff_sec_hnd->type != ORL_SEC_TYPE_PROG_BITS ) return( ORL_ERROR );
reloc_sec_hnd = coff_sec_hnd->assoc.normal.reloc_sec;
if( reloc_sec_hnd == NULL ) return( ORL_FALSE );
if( reloc_sec_hnd->assoc.reloc.relocs == NULL ) {
return_val = CoffCreateRelocs( coff_sec_hnd, reloc_sec_hnd );
if( return_val != ORL_OKAY ) return( return_val );
}
reloc = reloc_sec_hnd->assoc.reloc.relocs;
return_val = ORL_FALSE;
for( index = 0; index < reloc_sec_hnd->assoc.reloc.num_relocs; index++ ) {
if( reloc->offset == sec_offset ) {
return_val = return_func( reloc );
if( return_val != ORL_OKAY ) return( return_val );
}
reloc++;
}
return( return_val );
}
orl_table_index COFFENTRY CoffCvtSecHdlToIdx( coff_sec_handle shdl )
/******************************************************************/
// NYI: would be nice to have a O(1) way of doing this.
{
orl_table_index index;
orl_table_index limit;
coff_file_handle fhdl;
fhdl = shdl->coff_file_hnd;
limit = fhdl->f_hdr_buffer->num_sections;
for( index = 0; index < limit; index++ ) {
if( fhdl->orig_sec_hnd[index] == shdl ) return index + 1;
}
return 0;
}
coff_sec_handle COFFENTRY CoffCvtIdxToSecHdl( coff_file_handle fhdl,
orl_table_index idx )
/******************************************************************/
{
return fhdl->orig_sec_hnd[idx - 1];
}
orl_return COFFENTRY CoffSecScanReloc( coff_sec_handle coff_sec_hnd, orl_reloc_return_func return_func )
{
int index;
coff_sec_handle reloc_sec_hnd;
orl_reloc * reloc;
orl_return return_val;
if( coff_sec_hnd->type != ORL_SEC_TYPE_PROG_BITS ) return( ORL_ERROR );
reloc_sec_hnd = coff_sec_hnd->assoc.normal.reloc_sec;
if( reloc_sec_hnd == NULL ) return( ORL_FALSE );
if( reloc_sec_hnd->assoc.reloc.relocs == NULL ) {
return_val = CoffCreateRelocs( coff_sec_hnd, reloc_sec_hnd );
if( return_val != ORL_OKAY ) return( return_val );
}
reloc = reloc_sec_hnd->assoc.reloc.relocs;
return_val = ORL_FALSE;
for( index = 0; index < reloc_sec_hnd->assoc.reloc.num_relocs; index++ ) {
return_val = return_func( reloc );
if( return_val != ORL_OKAY ) return( return_val );
reloc++;
}
return( return_val );
}
orl_return COFFENTRY CoffRelocSecScan( coff_sec_handle coff_sec_hnd, orl_reloc_return_func return_func )
{
int index;
orl_reloc * reloc;
orl_return return_val;
if( coff_sec_hnd->type != ORL_SEC_TYPE_RELOCS ) return( ORL_ERROR );
if( coff_sec_hnd->assoc.reloc.relocs == NULL ) {
return_val = CoffCreateRelocs( coff_sec_hnd->assoc.reloc.orig_sec, coff_sec_hnd );
if( return_val != ORL_OKAY ) return( return_val );
}
reloc = coff_sec_hnd->assoc.reloc.relocs;
return_val = ORL_FALSE;
for( index = 0; index < coff_sec_hnd->assoc.reloc.num_relocs; index++ ) {
return_val = return_func( reloc );
if( return_val != ORL_OKAY ) return( return_val );
reloc++;
}
return( return_val );
}
orl_return COFFENTRY CoffSymbolSecScan( coff_sec_handle coff_sec_hnd, orl_symbol_return_func return_func )
{
int index;
orl_return error;
coff_symbol_handle coff_symbol_hnd;
if( coff_sec_hnd->type != ORL_SEC_TYPE_SYM_TABLE ) return( ORL_ERROR );
if( !(coff_sec_hnd->coff_file_hnd->symbol_handles) ) {
error = CoffCreateSymbolHandles( coff_sec_hnd->coff_file_hnd );
if( error != ORL_OKAY ) return( error );
}
for( index = 0; index < coff_sec_hnd->coff_file_hnd->num_symbols; index++ ) {
coff_symbol_hnd = &(coff_sec_hnd->coff_file_hnd->symbol_handles[index]);
error = return_func( (orl_symbol_handle) coff_symbol_hnd );
if( error != ORL_OKAY ) return( error );
index += coff_symbol_hnd->symbol->num_aux;
}
return( ORL_OKAY );
}
orl_return COFFENTRY CoffNoteSecScan( coff_sec_handle hnd,
orl_note_callbacks *cb, void *cookie )
/**************************************************************************/
{
if( hnd->type != ORL_SEC_TYPE_NOTE ) return ORL_ERROR;
if( strcmp( hnd->name, ".drectve" ) != 0 ) return ORL_OKAY;
if( hnd->size == 0 ) return ORL_OKAY;
return CoffParseDrectve( hnd->contents, hnd->size, cb, cookie );
}
char * COFFENTRY CoffSymbolGetName( coff_symbol_handle coff_symbol_hnd )
{
if( coff_symbol_hnd->type & ORL_SYM_TYPE_FILE ) {
return (char *) (coff_symbol_hnd->symbol + 1);
}
return( coff_symbol_hnd->name );
}
orl_symbol_value COFFENTRY CoffSymbolGetValue( coff_symbol_handle coff_symbol_hnd )
{
return( coff_symbol_hnd->symbol->value );
}
orl_symbol_binding COFFENTRY CoffSymbolGetBinding( coff_symbol_handle coff_symbol_hnd )
{
return( coff_symbol_hnd->binding );
}
orl_symbol_type COFFENTRY CoffSymbolGetType( coff_symbol_handle coff_symbol_hnd )
{
return( coff_symbol_hnd->type );
}
coff_sec_handle COFFENTRY CoffSymbolGetSecHandle( coff_symbol_handle coff_symbol_hnd )
{
if( coff_symbol_hnd->symbol->sec_num < 1 ) return( NULL );
return( coff_symbol_hnd->coff_file_hnd->orig_sec_hnd[coff_symbol_hnd->symbol->sec_num - 1]);
}
coff_symbol_handle COFFENTRY CoffSymbolGetAssociated( coff_symbol_handle hnd )
{
coff_sym_weak * weak;
weak = (coff_sym_weak *) (hnd->symbol + 1);
return &hnd->coff_file_hnd->symbol_handles[weak->tag_index];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -