📄 omfmunge.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 <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifdef _BSD_SOURCE
#define stricmp strcasecmp
#endif
#include "omfload.h"
#include "omfmunge.h"
#include "orlhash.h"
#include "pcobj.h"
/* Local definitions
*/
#define STD_INC 256
#define STD_CODE_SIZE 4096
#define _IsSymPub( t ) ( t & ( ORL_SYM_TYPE_DEFINED | ORL_SYM_TYPE_ABSOLUTE ) )
static orl_sec_combine getCombine( int combine )
{
switch( combine ) {
case( COMB_INVALID ):
return( ORL_SEC_COMBINE_PRIVATE );
case( COMB_ADDOFF ):
case( COMB_FOUR ):
return( ORL_SEC_COMBINE_PUBLIC );
case( COMB_STACK ):
return( ORL_SEC_COMBINE_STACK );
case( COMB_COMMON ):
return( ORL_SEC_COMBINE_COMMON );
default:
return( ORL_SEC_COMBINE_NONE );
}
}
static int nameCmp( omf_file_handle ofh, omf_idx n1, omf_idx n2 )
{
char name1[257];
char name2[257];
int len1;
int len2;
assert( ofh );
assert( n1 );
assert( n2 );
if( n1 == n2 ) return( 0 );
len1 = OmfGetLName( ofh->lnames, n1, name1 );
if( len1 < 0 ) return( 1 );
len2 = OmfGetLName( ofh->lnames, n2, name2 );
if( len1 != len2 ) return( 1 );
return( stricmp( name1, name2 ) );
}
static void *checkArraySize( omf_file_handle ofh, void *old_arr,
long num, long inc, long elem )
{
long size;
void *new_arr;
assert( ofh );
assert( num >= 0 );
assert( inc > 0 );
assert( elem > 0 );
if( !( num % inc ) ) {
size = ( num + inc ) * elem;
new_arr = _ClientAlloc( ofh, size );
if( !new_arr ) return( NULL );
memset( new_arr, 0, size );
if( num ) {
assert( old_arr );
size = num * elem;
memcpy( new_arr, old_arr, size );
_ClientFree( ofh, old_arr );
}
old_arr = new_arr;
}
return( old_arr );
}
static omf_symbol_handle findExtDefSym( omf_file_handle ofh, omf_idx ext )
{
omf_sec_handle sh;
omf_string_struct *st;
orl_hash_data_struct *hd;
omf_symbol_handle sym;
assert( ofh );
if( !ofh->extdefs ) return( NULL );
sh = ofh->extdefs;
if( !ext || ( ext > sh->assoc.string.num ) ) return( NULL );
assert( sh->assoc.string.strings );
st = sh->assoc.string.strings[ext - 1];
if( !st ) return( NULL );
hd = ORLHashTableQuery( ofh->symbol_table->assoc.sym.hash_tab,
(orl_hash_value)(st->string) );
if( !hd ) return( NULL );
while( hd ) {
sym = (omf_symbol_handle)( hd->data );
if( sym ) {
if( sym->typ & ( ORL_SYM_TYPE_UNDEFINED | ORL_SYM_TYPE_COMMON ) ) {
return( sym );
}
}
hd = hd->next;
}
return( NULL );
}
static omf_grp_handle findGroup( omf_file_handle ofh, omf_idx grp )
{
assert( ofh );
if( !grp || ( grp > ofh->num_groups ) ) return( NULL );
assert( ofh->groups );
return( ofh->groups[grp-1] );
}
static omf_sec_handle findComDat( omf_file_handle ofh, omf_idx seg )
{
assert( ofh );
if( !seg || ( seg > ofh->num_comdats ) ) return( NULL );
assert( ofh->comdats );
return( ofh->comdats[seg-1] );
}
static omf_sec_handle findComDatByName( omf_file_handle ofh, omf_idx nameidx )
{
unsigned index;
assert( ofh );
assert( ofh->comdats );
if( !nameidx ) return( NULL );
for( index = 0; index < ofh->num_comdats; index++ ) {
if( ofh->comdats[index]->assoc.seg.name == nameidx ) {
return ofh->comdats[index];
}
}
return NULL;
}
static omf_sec_handle findSegment( omf_file_handle ofh, omf_idx seg )
{
assert( ofh );
if( !seg || ( seg > ofh->num_segs ) ) return( NULL );
assert( ofh->segs );
return( ofh->segs[seg-1] );
}
static omf_symbol_handle newSymbol( omf_file_handle ofh, orl_symbol_type typ,
char *name, int len )
{
omf_symbol_handle sym;
assert( ofh );
assert( name );
assert( len >= 0 );
sym = _ClientAlloc( ofh, sizeof( omf_symbol_handle_struct ) + len );
if( !sym ) return( sym );
memset( sym, 0, sizeof( omf_symbol_handle_struct ) + len );
sym->namelen = len;
sym->typ = typ;
sym->file_format = ORL_OMF;
sym->omf_file_hnd = ofh;
memcpy( sym->name, name, len );
return( sym );
}
static omf_sec_handle newSection( omf_file_handle ofh, omf_quantity idx,
orl_sec_type typ )
{
omf_sec_handle sh;
assert( ofh );
assert( idx >= OMF_SEC_NEXT_AVAILABLE );
if( idx == OMF_SEC_NEXT_AVAILABLE ) {
if( ofh->next_idx < OMF_SEC_DATA_CODE_START ) {
ofh->next_idx = OMF_SEC_DATA_CODE_START;
}
idx = ofh->next_idx;
ofh->next_idx++;
} else if( idx >= ofh->next_idx ) {
ofh->next_idx = idx + 1;
}
sh = _ClientAlloc( ofh, sizeof( omf_sec_handle_struct ) );
if( !sh ) return( sh );
memset( sh, 0, sizeof( omf_sec_handle_struct ) );
sh->file_format = ORL_OMF;
sh->omf_file_hnd = ofh;
sh->type = typ;
sh->index = idx;
if( ofh->first_sec ) {
ofh->last_sec->next = sh;
} else {
ofh->first_sec = sh;
}
ofh->last_sec = sh;
ofh->num_sections++;
return( sh );
}
static omf_sec_handle newComDatSection( omf_file_handle ofh )
{
omf_sec_handle sh;
assert( ofh );
ofh->comdats = checkArraySize( ofh, ofh->comdats, ofh->num_comdats, STD_INC,
sizeof( omf_sec_handle ) );
if( !ofh->comdats ) return( NULL );
sh = newSection( ofh, OMF_SEC_NEXT_AVAILABLE, ORL_SEC_TYPE_PROG_BITS );
if( !sh ) return( sh );
ofh->comdats[ofh->num_comdats] = sh;
ofh->num_comdats++;
sh->assoc.seg.seg_id = ofh->num_comdats;
return( sh );
}
static omf_sec_handle newSegSection( omf_file_handle ofh, orl_sec_type typ )
{
omf_sec_handle sh;
assert( ofh );
ofh->segs = checkArraySize( ofh, ofh->segs, ofh->num_segs, STD_INC,
sizeof( omf_sec_handle ) );
if( !ofh->segs ) return( NULL );
sh = newSection( ofh, OMF_SEC_NEXT_AVAILABLE, typ );
if( !sh ) return( sh );
ofh->segs[ofh->num_segs] = sh;
ofh->num_segs++;
sh->assoc.seg.seg_id = ofh->num_segs;
return( sh );
}
static omf_grp_handle newGroup( omf_file_handle ofh )
{
omf_grp_handle gr;
assert( ofh );
ofh->groups = checkArraySize( ofh, ofh->groups, ofh->num_groups, STD_INC,
sizeof( omf_grp_handle ) );
if( !ofh->groups ) return( NULL );
gr = _ClientAlloc( ofh, sizeof( omf_grp_handle_struct ) );
if( !gr ) return( gr );
memset( gr, 0, sizeof( omf_grp_handle_struct ) );
ofh->groups[ofh->num_groups] = gr;
ofh->num_groups++;
gr->id = ofh->num_groups;
gr->file_format = ORL_OMF;
gr->omf_file_hnd = ofh;
return( gr );
}
static orl_sec_offset getUWord( omf_bytes buffer, int wordsize )
{
orl_sec_offset result = 0;
assert( buffer );
switch( wordsize ) {
case( 4 ):
result |= buffer[3] << 24;
result |= buffer[2] << 16;
case( 2 ):
result |= buffer[1] << 8;
default:
result |= buffer[0];
}
return( result );
}
static omf_string_struct *getIdx2String( omf_sec_handle sh, omf_idx idx )
{
assert( sh );
if( idx < sh->assoc.string.num ) {
return( sh->assoc.string.strings[idx] );
}
return( NULL );
}
static omf_sec_handle newStringTable( omf_file_handle ofh, omf_quantity idx )
{
omf_sec_handle sh;
assert( ofh );
sh = newSection( ofh, idx, ORL_SEC_TYPE_STR_TABLE );
if( sh ) {
sh->flags = ORL_SEC_FLAG_REMOVE;
}
return( sh );
}
static orl_return addString( omf_sec_handle sh, omf_bytes buffer,
unsigned int len )
{
omf_string_struct *str;
omf_file_handle ofh;
assert( sh );
assert( buffer );
ofh = sh->omf_file_hnd;
/* Check if we need to allocate more string table
*/
sh->assoc.string.strings = checkArraySize( ofh, sh->assoc.string.strings,
sh->assoc.string.num, STD_INC,
sizeof( omf_string_struct * ) );
if( !sh->assoc.string.strings ) return( ORL_OUT_OF_MEMORY );
str = _ClientAlloc( ofh, sizeof( omf_string_struct ) + len );
if( !str ) return( ORL_OUT_OF_MEMORY );
memset( str, 0, sizeof( omf_string_struct ) + len );
str->len = len;
memcpy( str->string, buffer, len );
str->string[len] = '\0';
sh->assoc.string.strings[sh->assoc.string.num] = str;
sh->assoc.string.num++;
return( ORL_OKAY );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -