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

📄 omfmunge.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
static orl_return       addToSymbolTable( omf_file_handle ofh,
                                          omf_symbol_handle sym )
{
    omf_sec_handle      sh;

    assert( ofh );
    assert( sym );

    sh = ofh->symbol_table;
    if( !sh ) {
        sh = newSection( ofh, OMF_SEC_SYM_TABLE_INDEX, ORL_SEC_TYPE_SYM_TABLE );
        if( !sh ) return( ORL_OUT_OF_MEMORY );
        ofh->symbol_table = sh;
        sh->flags |= ORL_SEC_FLAG_REMOVE;
        sh->assoc.sym.hash_tab = ORLHashTableCreate( ofh->omf_hnd->funcs, 257,
                                        ORL_HASH_STRING,
                                        (orl_hash_comparison_func)stricmp );
        if( !sh->assoc.sym.hash_tab ) return( ORL_OUT_OF_MEMORY );
    }
    assert( sh->assoc.sym.hash_tab );

    sh->assoc.sym.syms = checkArraySize( ofh, sh->assoc.sym.syms,
                                         sh->assoc.sym.num, STD_INC,
                                         sizeof( omf_symbol_handle ) );
    if( !sh->assoc.sym.syms ) return( ORL_OUT_OF_MEMORY );

    sh->assoc.sym.syms[sh->assoc.sym.num] = sym;
    sh->assoc.sym.num++;
    return( ORLHashTableInsert( sh->assoc.sym.hash_tab,
                                (orl_hash_value)sym->name, sym ) );
}


static orl_return       addReloc( omf_file_handle ofh, omf_reloc_handle orh )
{
    omf_sec_handle      sh;

    assert( ofh );
    assert( orh );

    if( !ofh->relocs ) {
        ofh->relocs = newSection( ofh, OMF_SEC_RELOC_INDEX,
                                  ORL_SEC_TYPE_RELOCS );
        if( !ofh->relocs ) return( ORL_OUT_OF_MEMORY );
        ofh->relocs->flags |= ORL_SEC_FLAG_REMOVE;
    }

    sh = ofh->relocs;
    sh->assoc.reloc.relocs = checkArraySize( ofh, sh->assoc.reloc.relocs,
                                             sh->assoc.reloc.num, STD_INC,
                                             sizeof( omf_reloc_handle ) );
    if( !sh->assoc.reloc.relocs ) return( ORL_OUT_OF_MEMORY );

    sh->assoc.reloc.relocs[sh->assoc.reloc.num] = orh;
    sh->assoc.reloc.num++;

    return( ORL_OKAY );
}


static omf_tmp_fixup    findMatchingFixup( omf_tmp_fixup tf, int lo, int hi )
{
    if( hi < lo ) {
        hi = lo;
    }

    while( tf ) {
        if( ( tf->offset >= lo ) && ( tf->offset <= hi ) ) break;
        tf = tf->next;
    }

    return( tf );
}


static orl_return       writeAndFixupLIData( omf_file_handle ofh,
                                             omf_sec_handle sh,
                                             omf_bytes buffer )
{
    int                 wordsize;
    long                tmp;
    uint_32             repeat;
    long                block;
    int                 size;
    int                 used;
    int                 hi;
    int                 lo;
    omf_bytes           ptr;
    orl_return          err = ORL_OKAY;
    omf_tmp_fixup       ftr;
    omf_tmp_fixup       ntr;
    int                 x;

    assert( ofh );
    assert( ofh->lidata );
    assert( sh );
    assert( sh->contents );
    assert( buffer );

    if( ofh->status & OMF_STATUS_EASY_OMF ) {
        wordsize = OmfGetWordSize( 0 );
    } else {
        wordsize = OmfGetWordSize( ofh->lidata->is32 );
    }
    tmp = wordsize + 2;

    if( ofh->lidata->size < tmp ) return( ORL_ERROR );
    used = ofh->lidata->used;
    size = ofh->lidata->size;
    ptr = buffer + used;

    repeat = getUWord( ptr, wordsize );
    ptr += wordsize;
    block = getUWord( ptr, 2 );
    ptr += 2;

    lo = used;
    hi = lo + tmp;
    size -= tmp;
    used += tmp;

    if( findMatchingFixup( ofh->lidata->first_fixup, lo, hi ) ) {
        return( ORL_ERROR );
    } else if( block ) {
        while( repeat ) {
            repeat--;
            ofh->lidata->used = used;
            ofh->lidata->size = size;
            for( x = 0; x < block; x++ ) {
                err = writeAndFixupLIData( ofh, sh, buffer );
                if( err != ORL_OKAY ) break;
            }
        }
    } else {
        tmp = *ptr;
        ptr++;
        used++;
        size--;

        lo = used;
        hi = used + tmp - 1;

        while( repeat ) {
            buffer = sh->contents + sh->assoc.seg.cur_offset;
            memcpy( buffer, ptr, tmp );

            /* create appropriate fixup records
             */
            ftr = findMatchingFixup( ofh->lidata->first_fixup, lo, hi );
            while( ftr ) {
                ntr = _ClientAlloc( ofh, sizeof( omf_tmp_fixup_struct ) );
                if( !ntr ) return( ORL_OUT_OF_MEMORY );
                memcpy( ntr, ftr, sizeof( omf_tmp_fixup_struct ) );

                /* determine new offset as if this was an LEData we were
                 * doing a fixup for
                 */
                ntr->offset = ofh->lidata->offset - used + ftr->offset;

                /* insert into new fixup queue
                 */
                if( ofh->lidata->new_fixup ) {
                    ofh->lidata->last_fixup->next = ntr;
                } else {
                    ofh->lidata->new_fixup = ntr;
                }
                ofh->lidata->last_fixup = ntr;

                ftr = findMatchingFixup( ftr->next, lo, hi );
            }

            ofh->lidata->offset += tmp;
            sh->assoc.seg.cur_offset += tmp;
            repeat--;
        }

        ofh->lidata->size = size - tmp;
        ofh->lidata->used = used + tmp;
        err = ORL_OKAY;
    }

    return( err );
}


static orl_return       expandPrevLIData( omf_file_handle ofh )
{
    omf_sec_handle      sh;
    int                 size;
    omf_bytes           buffer;
    orl_return          err = ORL_OKAY;
    unsigned char       tmp[1024];
    omf_tmp_fixup       ftr;
    orl_sec_offset      offset;

    assert( ofh );
    assert( ofh->work_sec );
    assert( ofh->lidata );

    sh = ofh->work_sec;
    size = ofh->lidata->size;

    if( size > 1024 ) {
        buffer = _ClientAlloc( ofh, size );
        if( !buffer ) return( ORL_OUT_OF_MEMORY );
    } else {
        buffer = tmp;
    }

    /* we must remember to save the current offset of the lidata and then
     * restore it
     */
    ofh->lidata->last_fixup = NULL;
    offset = sh->assoc.seg.cur_offset;

    /* make a working copy of the LIDATA
     */
    memcpy( buffer, sh->contents + offset, size );

    while( ofh->lidata->size > 0 ) {
        err = writeAndFixupLIData( ofh, sh, buffer );
        if( err != ORL_OKAY ) return( err );
    }
    sh->assoc.seg.cur_offset = offset;

    if( size > 1024 ) {
        _ClientFree( ofh, buffer );
    }

    assert( !( ofh->status & OMF_STATUS_ADD_MASK ) );

    /* Destroy original fixups
     */
    while( ofh->lidata->first_fixup ) {
        ftr = ofh->lidata->first_fixup;
        ofh->lidata->first_fixup = ftr->next;
        _ClientFree( ofh, ftr );
    }

    /* Add the generated fixups
     */
    while( ofh->lidata->new_fixup ) {
        ftr = ofh->lidata->new_fixup;
        err = OmfAddFixupp( ofh, ftr->is32, ftr->mode, ftr->location,
                            ftr->offset, ftr->fmethod, ftr->fidx, ftr->tmethod,
                            ftr->tidx, ftr->disp );
        if( err != ORL_OKAY ) break;
        ofh->lidata->new_fixup = ftr->next;
        _ClientFree( ofh, ftr );
    }

    ofh->lidata->last_fixup = NULL;

    return( err );
}


static orl_return       finishPrevWork( omf_file_handle ofh )
{
    orl_return  err = ORL_OKAY;

    assert( ofh );

    if( ofh->status & OMF_STATUS_ADD_LIDATA ) {
        ofh->status &= ~OMF_STATUS_ADD_LIDATA;
        err = expandPrevLIData( ofh );
    }
    assert( !( ofh->status & OMF_STATUS_ADD_MASK ) );
    return( err );
}


static orl_sec_offset   calcLIDataLength( int is32, omf_bytes *input, int *len )
{
    int         size;
    omf_bytes   buffer;
    int         wordsize;
    long        tmp;
    uint_32     repeat;
    long        block;
    long        result = 0;

    assert( input );
    assert( *input );
    assert( len );

    buffer = *input;
    size = *len;
    wordsize = OmfGetWordSize( is32 );
    tmp = wordsize + 2;

    if( size < tmp ) return( 0 );
    repeat = getUWord( buffer, wordsize );
    buffer += wordsize;
    block = getUWord( buffer, 2 );
    buffer += 2;
    size -= tmp;

    if( block ) {
        while( block ) {
            tmp = calcLIDataLength( is32, &buffer, &size );
            if( !tmp ) return( 0 );
            result += tmp;
            block--;
        }
    } else {
        result = buffer[0];
        size -= ( result + 1 );
        if( size < 0 ) return( 0 );
        buffer += result + 1;
    }

    result *= repeat;
    *input = buffer;
    *len = size;

    return( result );
}


static orl_return       checkSegmentLength( omf_sec_handle sh, uint_32 max )
{
    omf_bytes   conts;

    assert( sh );

    if( max > sh->size ) return( ORL_ERROR );
    if( max > sh->assoc.seg.cur_size ) {
        max = ( max / STD_CODE_SIZE ) + 1;
        max *= STD_CODE_SIZE;
        conts = _ClientAlloc( sh->omf_file_hnd, max );
        if( !conts ) return( ORL_OUT_OF_MEMORY );
        memset( conts, 0, max );
        if( sh->contents ) {
            memcpy( conts, sh->contents, sh->assoc.seg.cur_size );
            _ClientFree( sh->omf_file_hnd, sh->contents );
        }
        sh->contents = conts;
        sh->assoc.seg.cur_size = max;
    }
    return( ORL_OKAY );
}


static omf_bytes        strNUpper( omf_bytes buffer, int len )
{
    assert( buffer );

    len--;
    while( len >= 0 ) {
        buffer[ len ] = toupper( buffer[ len ] );
        len--;
    }
    return( buffer );
}


static orl_sec_flags    getSegSecFlags( omf_file_handle ofh, omf_idx name,
                                        omf_idx class, orl_sec_alignment align,
                                        int combine, int use32 )
{
    char                lname[257];
    int                 slen;
    orl_sec_flags       flags = 0;

    align = align; combine = combine;
    assert( ofh );

    slen = OmfGetLName( ofh->lnames, class, lname );
    if( slen > 0 ) {
        lname[slen] = '\0';
        strNUpper( lname, slen );
        if( ( slen > 3 ) &&
            ( !strcmp( "CODE", &lname[slen - 4] ) ||
              !strcmp( "TEXT", &lname[slen - 4] ) ) ) {
            flags |= ORL_SEC_FLAG_EXEC | ORL_SEC_FLAG_EXECUTE_PERMISSION |
                     ORL_SEC_FLAG_READ_PERMISSION;
        } else if( ( slen > 3 ) && !strcmp( "DATA", &lname[slen - 4] ) ) {
            flags |= ORL_SEC_FLAG_READ_PERMISSION;
            slen = OmfGetLName( ofh->lnames, name, lname );
            if( slen > 0 ) {
                lname[slen] = '\0';
                strNUpper( lname, slen );
                if( strstr( "CONST", lname ) ) {
                        flags |= ORL_SEC_FLAG_INITIALIZED_DATA;
                }
            }
        } else if( ( slen > 4 ) && !strcmp( "CONST", &lname[slen - 5] ) ) {
            flags |= ORL_SEC_FLAG_READ_PERMISSION |
                     ORL_SEC_FLAG_INITIALIZED_DATA;
        } else if( ( slen > 2 ) && !strcmp( "BSS", &lname[slen - 3] ) ) {
            flags |= ORL_SEC_FLAG_READ_PERMISSION |
                     ORL_SEC_FLAG_WRITE_PERMISSION |
                     ORL_SEC_FLAG_UNINITIALIZED_DATA;
        } else if( ( slen > 4 ) && !strcmp( "STACK", &lname[slen - 5] ) ) {
            flags |= ORL_SEC_FLAG_READ_PERMISSION |
                     ORL_SEC_FLAG_WRITE_PERMISSION |
                     ORL_SEC_FLAG_UNINITIALIZED_DATA;
        } else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -