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

📄 omfmunge.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
            flags |= ORL_SEC_FLAG_READ_PERMISSION;
            slen = OmfGetLName( ofh->lnames, name, lname );
            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;
            }
        }
    } else {
        flags |= ORL_SEC_FLAG_READ_PERMISSION;
    }

    if( use32 ) {
        flags |= ORL_SEC_FLAG_USE_32;
    }

    return( flags );
}


orl_return              OmfAddLIData( omf_file_handle ofh, int is32,
                                      omf_idx seg, orl_sec_offset offset,
                                      omf_bytes buffer, long len, int comdat )
{
    omf_sec_handle      sh;
    orl_return          err;
    orl_sec_offset      size;
    orl_sec_offset      tmpsize;
    omf_bytes           tmp;
    int                 tmplen;

    assert( ofh );
    assert( buffer );
    assert( seg );

    err = finishPrevWork( ofh );
    if( err != ORL_OKAY ) return( err );

    if( comdat ) {
        sh = findComDat( ofh, seg );
    } else {
        sh = findSegment( ofh, seg );
    }
    if( !sh ) return( ORL_ERROR );
    if( len < 0 ) return( ORL_ERROR );

    tmp = buffer;
    tmplen = len;
    size = 0;

    while( tmplen > 0 ) {
        if( ofh->status & OMF_STATUS_EASY_OMF ) {
            tmpsize = calcLIDataLength( 0, &tmp, &tmplen );
        } else {
            tmpsize = calcLIDataLength( is32, &tmp, &tmplen );
        }
        if( tmpsize == 0 ) return( ORL_ERROR );
        size += tmpsize;
    }

    err = checkSegmentLength( sh, offset + size );
    if( err != ORL_OKAY ) return( err );

    /* we put off expanding the lidata until all the fixups are in
     */
    if( !ofh->lidata ) {
        ofh->lidata = _ClientAlloc( ofh, sizeof( omf_tmp_lidata_struct ) );
        if( !ofh->lidata ) return( ORL_OUT_OF_MEMORY );
    }

    memset( ofh->lidata, 0, sizeof( omf_tmp_lidata_struct ) );
    ofh->lidata->size = len;
    ofh->lidata->is32 = is32;

    sh->assoc.seg.cur_offset = offset;
    memcpy( sh->contents + offset, buffer, len );

    ofh->status |= OMF_STATUS_ADD_LIDATA;
    ofh->work_sec = sh;

    return( err );
}


orl_return              OmfAddLEData( omf_file_handle ofh, int is32,
                                      omf_idx seg, orl_sec_offset offset,
                                      omf_bytes buffer, long len, int comdat )
{
    omf_sec_handle      sh;
    orl_return          err;

    is32 = is32;
    assert( ofh );
    assert( buffer );
    assert( seg );

    err = finishPrevWork( ofh );
    if( err != ORL_OKAY ) return( err );

    if( comdat ) {
        sh = findComDat( ofh, seg );
    } else {
        sh = findSegment( ofh, seg );
    }
    if( !sh ) return( ORL_ERROR );
    if( len < 0 ) return( ORL_ERROR );

    err = checkSegmentLength( sh, offset + len );
    if( err != ORL_OKAY ) return( err );

    sh->assoc.seg.cur_offset = offset;
    memcpy( sh->contents + offset, buffer, len );
    ofh->work_sec = sh;

    return( err );
}


orl_return              OmfAddLName( omf_file_handle ofh, omf_bytes buffer,
                                     unsigned int len, omf_rectyp typ )
{
    assert( ofh );
    assert( buffer );

    typ = typ;
    if( !ofh->lnames ) {
        ofh->lnames = newStringTable( ofh, OMF_SEC_LNAME_INDEX );
        if( !ofh->lnames ) return( ORL_OUT_OF_MEMORY );
        ofh->lnames->flags = ORL_SEC_FLAG_REMOVE;
    }

    return( addString( ofh->lnames, buffer, len ) );
}


orl_return              OmfAddFixupp( omf_file_handle ofh, int is32, int mode,
                                      int location, orl_sec_offset offset,
                                      int fmethod, omf_idx fidx, int tmethod,
                                      omf_idx tidx, orl_sec_offset disp )
{
    omf_tmp_fixup       tfr;
    omf_reloc_handle    orel;
    omf_sec_handle      sh;
    omf_grp_handle      gr;

    assert( ofh );

    if( ofh->status & OMF_STATUS_ADD_LIDATA ) {
        assert( ofh->work_sec );
        assert( ofh->lidata );

        tfr = _ClientAlloc( ofh, sizeof( omf_tmp_fixup_struct ) );
        if( !tfr ) return( ORL_OUT_OF_MEMORY );
        memset( tfr, 0, sizeof( omf_tmp_fixup_struct ) );

        if( fmethod == FRAME_LOC ) {
            fmethod = FRAME_SEG;
            fidx = ofh->work_sec->assoc.seg.seg_id;
        }

        tfr->is32 = is32;
        tfr->mode = mode;
        tfr->location = location;
        tfr->offset = offset;
        tfr->fmethod = fmethod;
        tfr->fidx = fidx;
        tfr->tmethod = tmethod;
        tfr->tidx = tidx;
        tfr->disp = disp;

        if( ofh->lidata->last_fixup ) {
            ofh->lidata->last_fixup->next = tfr;
        } else {
            ofh->lidata->first_fixup = tfr;
        }
        ofh->lidata->last_fixup = tfr;
        return( ORL_OKAY );
    }

    orel = _ClientAlloc( ofh, sizeof( omf_reloc_handle_struct ) );
    if( !orel ) return( ORL_OUT_OF_MEMORY );
    memset( orel, 0, sizeof( omf_reloc_handle_struct ) );

    switch( location ) {
    case( LOC_OFFSET_LO ):              /* relocate lo byte of offset   */
        /* should be 8 rather then 16, fix later
         */
        if( mode ) {
            orel->type = ORL_RELOC_TYPE_WORD_8;
        } else {
            orel->type = ORL_RELOC_TYPE_REL_8;
        }
        break;
    case( LOC_OFFSET ):                 /* relocate offset              */
        if( mode ) {
            orel->type = ORL_RELOC_TYPE_WORD_16;
        } else {
            orel->type = ORL_RELOC_TYPE_REL_16;
        }
        break;
    case( LOC_BASE ):                   /* relocate segment             */
            orel->type = ORL_RELOC_TYPE_SEGMENT;
        break;
    case( LOC_BASE_OFFSET ):            /* relocate segment and offset  */
        if( mode ) {
            orel->type = ORL_RELOC_TYPE_WORD_16_SEG;
        } else {
            orel->type = ORL_RELOC_TYPE_REL_16_SEG;
        }
        break;
    case( LOC_OFFSET_HI ):              /* relocate hi byte of offset   */
        if( mode ) {
            orel->type = ORL_RELOC_TYPE_WORD_HI_8;
        } else {
            orel->type = ORL_RELOC_TYPE_REL_HI_8;
        }
        break;
    case( LOC_OFFSET_32 ):              /* relocate 32-bit offset       */
    case( LOC_MS_OFFSET_32 ):           /* MS 32-bit offset             */
    case( LOC_MS_LINK_OFFSET_32 ):      /* like OFFSET_32, ldr resolved */
        if( mode ) {
            orel->type = ORL_RELOC_TYPE_WORD_32;
        } else {
            orel->type = ORL_RELOC_TYPE_REL_32;
        }
        break;
    case( LOC_BASE_OFFSET_32 ):         /* relocate seg and 32bit offset*/
    case( LOC_MS_BASE_OFFSET_32 ):      /* MS 48-bit pointer            */
        if( mode ) {
            orel->type = ORL_RELOC_TYPE_WORD_32_SEG;
        } else {
            orel->type = ORL_RELOC_TYPE_REL_32_SEG;
        }
        break;
    default:
        return( ORL_ERROR );
    }

    /* no section for fixups to refer to
     */
    if( !ofh->work_sec ) return( ORL_ERROR );

    orel->offset = offset + ofh->work_sec->assoc.seg.cur_offset;
    orel->section = (orl_sec_handle)(ofh->work_sec);
    orel->addend = disp;

    if( fmethod == FRAME_LOC ) {
        fmethod = FRAME_SEG;
        fidx = ofh->work_sec->assoc.seg.seg_id;
    }

    switch( tmethod ) {
    case( TARGET_SEGWD ):            /* segment index with displacement      */
    case( TARGET_SEG ):              /* segment index, no displacement       */
        sh = findSegment( ofh, tidx );
        if( !sh ) return( ORL_ERROR );
        orel->symbol = (orl_symbol_handle)(sh->assoc.seg.sym);
        break;
    case( TARGET_GRPWD ):            /* group index with displacement        */
    case( TARGET_GRP ):              /* group index, no displacement         */
        gr = findGroup( ofh, tidx );
        if( !gr ) return( ORL_ERROR );
        orel->symbol = (orl_symbol_handle)(gr->sym);
        break;
    case( TARGET_EXTWD ):            /* external index with displacement     */
    case( TARGET_EXT ):              /* external index, no displacement      */
        orel->symbol = (orl_symbol_handle)(findExtDefSym( ofh, tidx ));
        if( !orel->symbol ) return( ORL_ERROR );
        break;
    case( TARGET_ABSWD ):            /* abs frame num with displacement      */
    case( TARGET_ABS ):              /* abs frame num, no displacement       */
        break;
    default:
        return( ORL_ERROR );
    }

    switch( fmethod ) {
    case( FRAME_SEG ):                      /* segment index                */
        sh = findSegment( ofh, fidx );
        if( !sh ) return( ORL_ERROR );
        orel->frame = (orl_symbol_handle)(sh->assoc.seg.sym);
        break;
    case( FRAME_GRP ):                      /* group index                  */
        gr = findGroup( ofh, fidx );
        if( !gr ) return( ORL_ERROR );
        orel->frame = (orl_symbol_handle)(gr->sym);
        break;
    case( FRAME_EXT ):                      /* external index               */
        orel->frame = (orl_symbol_handle)(findExtDefSym( ofh, fidx ));
        if( !orel->frame ) return( ORL_ERROR );
        break;
    case( FRAME_ABS ):                      /* absolute frame number        */
        /* fix this up to do somehting later */
        orel->frame = NULL;
        break;
    case( FRAME_TARG ):                     /* frame same as target         */
        orel->frame = orel->symbol;
        break;
    case( FRAME_LOC ):                      /* frame containing location    */
        assert( 0 );
    }

    return( addReloc( ofh, orel ) );
}


orl_return              OmfAddExtDef( omf_file_handle ofh, omf_bytes buffer,
                                      unsigned int len, omf_rectyp typ )
{
    omf_symbol_handle   sym;
    orl_return          err;
    orl_symbol_type     styp;

    assert( ofh );
    assert( buffer );

    typ = typ;
    if( !ofh->extdefs ) {
        ofh->extdefs = newStringTable( ofh, OMF_SEC_IMPORT_INDEX );
        if( !ofh->extdefs ) return( ORL_OUT_OF_MEMORY );
        ofh->extdefs->flags = ORL_SEC_FLAG_REMOVE;
    }

    styp = ORL_SYM_TYPE_OBJECT;
    if( ( typ == CMD_COMDEF ) || ( typ == CMD_LCOMDEF ) ) {
        styp |= ORL_SYM_TYPE_COMMON;
    } else {
        styp |= ORL_SYM_TYPE_UNDEFINED;
    }
    sym = newSymbol( ofh, styp, buffer, len );
    if( !sym ) return( ORL_OUT_OF_MEMORY );

    sym->idx = ofh->extdefs->assoc.string.num + 1;
    sym->rec_typ = typ;
    switch( typ ) {
    case( CMD_COMDEF ):
    case( CMD_LCOMDEF ):
        sym->flags |= OMF_SYM_FLAGS_COMDEF;
        sym->binding = ORL_SYM_BINDING_GLOBAL;
        if( typ == CMD_COMDEF ) break;
    case( CMD_LEXTDEF ):
    case( CMD_LEXTDEF32 ):
        sym->flags |= OMF_SYM_FLAGS_LOCAL;
        sym->binding = ORL_SYM_BINDING_LOCAL;
    }

    err = addToSymbolTable( ofh, sym );
    if( err != ORL_OKAY ) return( err );

    return( addString( ofh->extdefs, buffer, len ) );
}


orl_return              OmfAddComDat( omf_file_handle ofh, int is32, int flags,
                                      int attr, int align,
                                      orl_sec_offset offset, omf_idx seg,
                                      omf_idx group, omf_frame frame,
                                      omf_idx name, omf_bytes buffer, long len,
                                      omf_rectyp typ )
{
    orl_return          err;
    omf_sec_handle      sh;
    omf_symbol_handle   sym;
    char                lname[257];
    int                 slen;
    orl_symbol_type     styp;
    long                size;

    typ = typ;
    assert( ofh );
    assert( buffer );

    err = finishPrevWork( ofh );
    if( err != ORL_OKAY ) return( err );

    if( align == -1 ) {
        if( !seg ) return( ORL_ERROR );
        sh = findSegment( ofh, seg );
        if( !sh ) return( ORL_ERROR );
        align = sh->assoc.seg.alignment;
    }

    if( flags & COMDAT_CONTINUE ) {
        sh = findComDatByName( ofh, name );
        if( !sh ) return( ORL_ERROR );
    } else {
        /* Create new Comdat
         */
        sh = newComDatSection( ofh );
        if( !sh ) return( ORL_OUT_OF_MEMORY );

        sh->assoc.seg.name = name;
        sh->assoc.seg.comdat.frame = frame;
        sh->assoc.seg.alignment = align;

        if( is32 ) {
            sh->assoc.seg.seg_flags |= OMF_SEG_IS_32;

⌨️ 快捷键说明

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