📄 omfentr.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 <assert.h>
#include "omfentr.h"
#include "omfload.h"
#include "omfmunge.h"
#include "omfflhn.h"
#include "orlhash.h"
#include "omfdrctv.h"
#define _IsSegType( t ) ( ( t == ORL_SEC_TYPE_PROG_BITS ) || \
( t == ORL_SEC_TYPE_NO_BITS ) )
omf_handle OMFENTRY OmfInit( orl_funcs * funcs )
{
omf_handle oh;
assert( funcs );
oh = funcs->alloc( sizeof( omf_handle_struct ) );
if( !oh ) return( NULL );
oh->funcs = funcs;
oh->first_file_hnd = NULL;
return( oh );
}
orl_return OMFENTRY OmfFini( omf_handle oh )
{
orl_return err;
assert( oh );
while( oh->first_file_hnd != NULL ) {
err = OmfRemoveFileLinks( oh->first_file_hnd );
if( err != ORL_OKAY ) return( err );
}
oh->funcs->free( oh );
return( ORL_OKAY );
}
omf_file_handle OMFENTRY OmfFileInit( omf_handle oh, void *file )
{
omf_file_handle ofh;
assert( oh );
ofh = oh->funcs->alloc( sizeof( omf_file_handle_struct ) );
if( !ofh ) return( NULL );
memset( ofh, 0, sizeof( omf_file_handle_struct ) );
ofh->file = file;
OmfAddFileLinks( oh, ofh );
if( OmfLoadFileStructure( ofh ) != ORL_OKAY ) {
OmfRemoveFileLinks( ofh );
return( NULL );
}
return( ofh );
}
orl_return OMFENTRY OmfFileFini( omf_file_handle ofh )
{
assert( ofh );
return( OmfRemoveFileLinks( ofh ) );
}
orl_return OMFENTRY OmfFileScan( omf_file_handle ofh, char *desired,
orl_sec_return_func func )
{
orl_hash_data_struct *ds;
omf_sec_handle sh;
omf_symbol_handle sym;
orl_return err;
assert( ofh );
assert( func );
if( !desired ) {
/* global request */
sh = ofh->first_sec;
while( sh ) {
// string tables are internal sections which are not seen by
// the user code
if( sh->type != ORL_SEC_TYPE_STR_TABLE ) {
err = func( (orl_sec_handle)sh );
if( err != ORL_OKAY ) return( err );
}
sh = sh->next;
}
} else if( ofh->symbol_table ) {
assert( ofh->symbol_table->assoc.sym.hash_tab );
ds = ORLHashTableQuery( ofh->symbol_table->assoc.sym.hash_tab,
(orl_hash_value) desired );
while( ds != NULL ) {
sym = ds->data;
if( ( sym->typ == ORL_SYM_TYPE_SECTION ) &&
!( sym->flags | OMF_SYM_FLAGS_GRPDEF ) ) {
err = func( (orl_sec_handle) sym->section );
if( err != ORL_OKAY ) return( err );
}
ds = ds->next;
}
}
return( ORL_OKAY );
}
orl_machine_type OMFENTRY OmfFileGetMachineType( omf_file_handle ofh )
{
assert( ofh );
return( ofh->machine_type );
}
orl_file_flags OMFENTRY OmfFileGetFlags( omf_file_handle ofh )
{
assert( ofh );
return( ofh->flags );
}
orl_file_type OMFENTRY OmfFileGetType( omf_file_handle ofh )
{
assert( ofh );
return( ofh->type );
}
orl_file_size OMFENTRY OmfFileGetSize( omf_file_handle ofh )
{
assert( ofh );
return( ofh->size );
}
omf_sec_handle OMFENTRY OmfFileGetSymbolTable( omf_file_handle ofh )
{
assert( ofh );
return( ofh->symbol_table );
}
char * OMFENTRY OmfSecGetName( omf_sec_handle sh )
{
assert( sh );
if( _IsSegType( sh->type ) ) {
assert( sh->assoc.seg.sym );
return( sh->assoc.seg.sym->name );
}
return( NULL );
}
orl_sec_offset OMFENTRY OmfSecGetBase( omf_sec_handle sh )
{
sh = sh;
assert( sh );
// Ask Jim
return( 0 );
}
orl_sec_size OMFENTRY OmfSecGetSize( omf_sec_handle sh )
{
assert( sh );
return( sh->size );
}
orl_sec_type OMFENTRY OmfSecGetType( omf_sec_handle sh )
{
assert( sh );
return( sh->type );
}
orl_sec_flags OMFENTRY OmfSecGetFlags( omf_sec_handle sh )
{
assert( sh );
return( sh->flags );
}
orl_sec_alignment OMFENTRY OmfSecGetAlignment( omf_sec_handle sh )
{
assert( sh );
if( _IsSegType( sh->type ) ) {
return( sh->assoc.seg.alignment );
}
return( 0 );
}
char * OMFENTRY OmfSecGetClassName( omf_sec_handle sh )
{
assert( sh );
if( _IsSegType( sh->type ) ) {
return( OmfGetPtrToLName( sh->omf_file_hnd, sh->assoc.seg.class ) );
}
return( NULL );
}
orl_sec_combine OMFENTRY OmfSecGetCombine( omf_sec_handle sh )
{
assert( sh );
if( _IsSegType( sh->type ) ) {
return( sh->assoc.seg.combine );
}
return( ORL_SEC_COMBINE_NONE );
}
orl_sec_frame OMFENTRY OmfSecGetAbsFrame( omf_sec_handle sh )
{
assert( sh );
if( _IsSegType( sh->type ) ) {
return( sh->assoc.seg.frame );
}
return( ORL_SEC_NO_ABS_FRAME );
}
orl_sec_handle OMFENTRY OmfSecGetAssociated( omf_sec_handle sh )
{
assert( sh );
if( _IsSegType( sh->type ) && ( sh->flags & ORL_SEC_FLAG_COMDAT ) ) {
return( (orl_sec_handle)(sh->assoc.seg.comdat.assoc_seg) );
}
return( NULL );
}
orl_group_handle OMFENTRY OmfSecGetGroup( omf_sec_handle sh )
{
assert( sh );
if( _IsSegType( sh->type ) ) {
if( sh->flags & ORL_SEC_FLAG_COMDAT ) {
return( (orl_group_handle)(sh->assoc.seg.comdat.group) );
} else if( sh->flags & ORL_SEC_FLAG_GROUPED ) {
return( (orl_group_handle)(sh->assoc.seg.group) );
}
}
return( NULL );
}
omf_sec_handle OMFENTRY OmfSecGetStringTable( omf_sec_handle sh )
{
assert( sh );
assert( sh->omf_file_hnd );
if( sh == sh->omf_file_hnd->lnames ) {
return( sh );
} else if( sh == sh->omf_file_hnd->extdefs ) {
return( sh );
}
return( NULL );
}
omf_sec_handle OMFENTRY OmfSecGetSymbolTable( omf_sec_handle sh )
{
assert( sh );
assert( sh->omf_file_hnd );
return( sh->omf_file_hnd->symbol_table );
}
omf_sec_handle OMFENTRY OmfSecGetRelocTable( omf_sec_handle sh )
{
assert( sh );
assert( sh->omf_file_hnd );
if( sh->type == ORL_SEC_TYPE_PROG_BITS ) {
return( sh->omf_file_hnd->relocs );
}
return( NULL );
}
orl_return OMFENTRY OmfSecGetContents( omf_sec_handle sh, char **buffer )
{
orl_return err;
assert( sh );
if( ( sh->contents != NULL ) || ( sh->type == ORL_SEC_TYPE_PROG_BITS ) ) {
err = OmfExportSegmentContents( sh );
if( err != ORL_OKAY ) return( err );
*buffer = sh->contents;
return( ORL_OKAY );
}
return( ORL_ERROR );
}
static orl_return OMFENTRY relocScan( omf_sec_handle sh, omf_sec_offset offset,
orl_reloc_return_func func, int check )
{
uint_32 x;
uint_32 num;
orl_reloc **relocs;
orl_return err;
int global;
omf_sec_handle rsh;
assert( sh );
assert( sh->omf_file_hnd );
assert( func );
if( !sh->omf_file_hnd->relocs ) return( ORL_FALSE );
relocs = sh->omf_file_hnd->relocs->assoc.reloc.relocs;
num = sh->omf_file_hnd->relocs->assoc.reloc.num;
if( num ) {
assert( relocs );
} else {
return( ORL_FALSE );
}
global = sh->index == sh->omf_file_hnd->relocs->index;
for( x = 0; x < num; x++ ) {
rsh = (omf_sec_handle)(relocs[x]->section);
if( global || ( sh->index == rsh->index ) ) {
if( !check || ( relocs[x]->offset == offset ) ) {
err = func( relocs[x] );
if( err != ORL_OKAY ) return( err );
}
}
}
return( ORL_TRUE );
}
orl_return OMFENTRY OmfSecQueryReloc( omf_sec_handle sh, omf_sec_offset offset,
orl_reloc_return_func func )
{
assert( sh );
assert( func );
if( sh->type != ORL_SEC_TYPE_PROG_BITS ) return( ORL_ERROR );
return( relocScan( sh, offset, func, 1 ) );
}
orl_return OMFENTRY OmfSecScanReloc( omf_sec_handle sh,
orl_reloc_return_func func )
{
assert( sh );
assert( func );
if( sh->type != ORL_SEC_TYPE_PROG_BITS ) return( ORL_ERROR );
return( relocScan( sh, 0, func, 0 ) );
}
// ask jim for next 2 calls
// One of these should be implimented O(1), but the section handles
// get reordered in OmfLoad.
orl_table_index OMFENTRY OmfCvtSecHdlToIdx( omf_sec_handle sh )
{
assert( sh );
return( sh->index );
}
omf_sec_handle OMFENTRY OmfCvtIdxToSecHdl( omf_file_handle ofh,
orl_table_index idx )
{
omf_sec_handle sh;
assert( ofh );
sh = ofh->first_sec;
while( sh ) {
if( sh->index == idx ) return( sh );
sh = sh->next;
}
return( NULL );
}
orl_return OMFENTRY OmfRelocSecScan( omf_sec_handle sh,
orl_reloc_return_func func )
{
assert( sh );
assert( func );
if( sh->type != ORL_SEC_TYPE_RELOCS ) return( ORL_ERROR );
return( relocScan( sh, 0, func, 0 ) );
}
orl_return OMFENTRY OmfSymbolSecScan( omf_sec_handle sh,
orl_symbol_return_func func )
{
int x;
orl_return err;
omf_symbol_handle *syms;
assert( sh );
assert( func );
if( sh->type != ORL_SEC_TYPE_SYM_TABLE ) return( ORL_ERROR );
syms = sh->assoc.sym.syms;
if( !syms ) return( ORL_ERROR );
for( x = 0; x < sh->assoc.sym.num; x++ ) {
err = func( (orl_symbol_handle) syms[x] );
if( err != ORL_OKAY ) return( err );
}
return( ORL_OKAY );
}
orl_table_index OMFENTRY OmfSecGetNumLines( omf_sec_handle sh )
{
assert( sh );
if( sh->type == ORL_SEC_TYPE_PROG_BITS ) {
return( sh->assoc.seg.num_lines );
} else {
return( 0 );
}
}
orl_linnum * OMFENTRY OmfSecGetLines( omf_sec_handle sh )
{
assert( sh );
if( sh->type == ORL_SEC_TYPE_PROG_BITS ) {
return( sh->assoc.seg.lines );
} else {
return( NULL );
}
}
char * OMFENTRY OmfSymbolGetName( omf_symbol_handle sym )
{
assert( sym );
return( sym->name );
}
orl_symbol_value OMFENTRY OmfSymbolGetValue( omf_symbol_handle sym )
{
assert( sym );
return( sym->offset );
}
orl_symbol_binding OMFENTRY OmfSymbolGetBinding( omf_symbol_handle sym )
{
assert( sym );
return( sym->binding );
}
orl_symbol_type OMFENTRY OmfSymbolGetType( omf_symbol_handle sym )
{
assert( sym );
return( sym->typ );
}
unsigned char OMFENTRY OmfSymbolGetRawInfo( omf_symbol_handle sym )
{
sym = sym;
assert( sym );
return( 0 );
}
omf_sec_handle OMFENTRY OmfSymbolGetSecHandle( omf_symbol_handle sym )
{
assert( sym );
return( sym->section );
}
orl_return OMFENTRY OmfNoteSecScan( omf_sec_handle hnd, orl_note_callbacks *cb,
void *cookie )
{
assert( hnd );
assert( cb );
if( hnd->type != ORL_SEC_TYPE_NOTE ) return ORL_ERROR;
return( OmfParseComments( hnd, cb, cookie ) );
}
orl_return OMFENTRY OmfGroupsScan( omf_file_handle hnd,
orl_group_return_func func )
{
orl_table_index idx;
orl_return err;
assert( hnd );
assert( func );
err = ORL_OKAY;
for( idx = 0; idx < hnd->num_groups; idx++ ) {
assert( hnd->groups );
err = func( (orl_group_handle)hnd->groups[idx] );
if( err != ORL_OKAY ) break;
}
return( err );
}
char * OMFENTRY OmfGroupName( omf_grp_handle hnd )
{
assert( hnd );
assert( hnd->sym );
return( hnd->sym->name );
}
orl_table_index OMFENTRY OmfGroupSize( omf_grp_handle hnd )
{
assert( hnd );
return( hnd->size );
}
char * OMFENTRY OmfGroupMember( omf_grp_handle hnd,
orl_table_index idx )
{
omf_sec_handle sh;
assert( hnd );
if( ( hnd->size > 0 ) && ( idx < hnd->size ) ) {
assert( hnd->segs );
if( hnd->segs[idx] ) {
sh = OmfFindSegOrComdat( hnd->omf_file_hnd, hnd->segs[idx], 0 );
if( sh ) {
assert( sh->assoc.seg.sym );
return( sh->assoc.seg.sym->name );
}
}
}
return( NULL );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -