⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 omfmunge.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************
*
*                            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 + -