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

📄 omfmunge.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        }

        sh->flags |= ORL_SEC_FLAG_COMDAT | ORL_SEC_FLAG_READ_PERMISSION |
                     ORL_SEC_FLAG_INITIALIZED_DATA;
        sh->assoc.seg.combine = ORL_SEC_COMBINE_COMDAT;

        switch( attr & COMDAT_ALLOC_MASK ) {
        case( COMDAT_EXPLICIT ):        /* in given segment */
            sh->assoc.seg.comdat.assoc_seg = findSegment( ofh, seg );
            if( !sh->assoc.seg.comdat.assoc_seg ) return( ORL_ERROR );
            sh->flags |= sh->assoc.seg.comdat.assoc_seg->flags;
            sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_ALLOC_EXPLIC;
            if( group ) {
                sh->assoc.seg.comdat.group = findGroup( ofh, group );
            }
            break;
        case( COMDAT_FAR_CODE ):        /* allocate CODE use16 segment */
            sh->flags |= ORL_SEC_FLAG_EXEC | ORL_SEC_FLAG_EXECUTE_PERMISSION;
            sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_ALLOC_CODE16;
            break;
        case( COMDAT_CODE32 ):          /* allocate CODE use32 segment */
            sh->flags |= ORL_SEC_FLAG_EXEC | ORL_SEC_FLAG_EXECUTE_PERMISSION;
            sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_ALLOC_CODE32;
            break;
        case( COMDAT_FAR_DATA ):        /* allocate DATA use16 segment */
            sh->flags |= ORL_SEC_FLAG_WRITE_PERMISSION;
            sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_ALLOC_DATA16;
            break;
        case( COMDAT_DATA32 ):          /* allocate DATA use32 segment */
            sh->flags |= ORL_SEC_FLAG_WRITE_PERMISSION;
            sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_ALLOC_DATA32;
            break;
        }

        /* Create symbol for section using its name, when looking up we will
         * need to match the indexes for proper matching
         */
        styp = ORL_SYM_TYPE_SECTION | ORL_SYM_TYPE_COMMON;
        switch( attr & COMDAT_MATCH_MASK ) {
        case( COMDAT_MATCH_NONE ):              /* don't match anyone */
            styp |= ORL_SYM_CDAT_NODUPLICATES;
            sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_PICK_NONE;
            break;
        case( COMDAT_MATCH_ANY ):               /* pick any instance */
            styp |= ORL_SYM_CDAT_ANY;
            sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_PICK_ANY;
            break;
        case( COMDAT_MATCH_SAME ):              /* must be same size */
            styp |= ORL_SYM_CDAT_SAME_SIZE;
            sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_PICK_SAME;
            break;
        case( COMDAT_MATCH_EXACT ):             /* must be exact match */
            styp |= ORL_SYM_CDAT_EXACT;
            sh->assoc.seg.combine |= ORL_SEC_COMBINE_COMDAT_PICK_EXACT;
            break;
        }

        slen = OmfGetLName( ofh->lnames, name, lname );
        if( slen < 0 ) return( ORL_ERROR );
        sym = newSymbol( ofh, styp, lname, slen );

        sym->seg = name;
        sym->idx = sh->assoc.seg.seg_id;
        sh->assoc.seg.sym = sym;
        sym->section = sh;
        if( flags & COMDAT_LOCAL ) {
            sym->binding = ORL_SYM_BINDING_LOCAL;
            sym->flags |= OMF_SYM_FLAGS_LOCAL;
        } else {
            sym->binding = ORL_SYM_BINDING_GLOBAL;
        }

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

    size = offset + len;
    if( size > sh->size ) {
        sh->size = size;
    }

    if( flags & COMDAT_ITERATED ) {
        err = OmfAddLIData( ofh, is32, sh->assoc.seg.seg_id, offset, buffer,
                            len, 1 );
    } else {
        err = OmfAddLEData( ofh, is32, sh->assoc.seg.seg_id, offset, buffer,
                            len, 1 );
    }

    return( err );
}


extern orl_return       OmfAddLineNum( omf_file_handle ofh, omf_idx seg,
                                       omf_idx name, unsigned_16 line,
                                       unsigned_32 offset )
{
    omf_sec_handle      sh;

    assert( ofh );

    sh = OmfFindSegOrComdat( ofh, seg, name );
    if( !sh ) return( ORL_ERROR );

    sh->assoc.seg.lines = checkArraySize( ofh, sh->assoc.seg.lines,
                                          sh->assoc.seg.num_lines, STD_INC,
                                          sizeof( orl_linnum ) );
    if( !sh->assoc.seg.lines ) return( ORL_OUT_OF_MEMORY );

    sh->assoc.seg.lines[ sh->assoc.seg.num_lines ].linnum = line;
    sh->assoc.seg.lines[ sh->assoc.seg.num_lines ].off = offset;
    sh->assoc.seg.num_lines++;

    return( ORL_OKAY );
}


orl_return              OmfAddSegDef( omf_file_handle ofh, int is32,
                                      orl_sec_alignment align, int combine,
                                      int use32, int max, orl_sec_frame frame,
                                      orl_sec_size size, omf_idx name,
                                      omf_idx class )
{
    omf_sec_handle      sh;
    omf_symbol_handle   sym;
    char                lname[257];
    int                 len;

    assert( ofh );

    sh = newSegSection( ofh, ORL_SEC_TYPE_PROG_BITS );
    if( !sh ) return( ORL_OUT_OF_MEMORY );

    sh->assoc.seg.name = name;
    sh->assoc.seg.class = class;
    sh->assoc.seg.alignment = align;
    sh->assoc.seg.combine = getCombine( combine );
    sh->assoc.seg.frame = frame;

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

    if( frame > ORL_SEC_NO_ABS_FRAME ) {
        sh->assoc.seg.seg_flags |= OMF_SEG_IS_ABS;
    }

    if( max ) {
        sh->assoc.seg.seg_flags |= OMF_SEG_IS_BIG;
        if( is32 ) {
            sh->size = 0xffffffff;
        } else {
            sh->size = 0x10000;
        }
    } else {
        sh->size = size;
    }

    sh->flags |= getSegSecFlags( ofh, name, class, align, combine, use32 );

    if( sh->flags & ORL_SEC_FLAG_UNINITIALIZED_DATA ) {
        sh->type = ORL_SEC_TYPE_NO_BITS;
    }

    /* Create symbol for section using its name, when looking up we will
     * need to match the indexes for proper matching
     */
    len = OmfGetLName( ofh->lnames, name, lname );
    if( len < 0 ) return( ORL_ERROR );
    sym = newSymbol( ofh, ORL_SYM_TYPE_SECTION, lname, len );

    sym->seg = name;
    sym->idx = sh->assoc.seg.seg_id;
    sh->assoc.seg.sym = sym;
    sym->section = sh;

    return( addToSymbolTable( ofh, sym ) );
}


orl_return              OmfAddPubDef( omf_file_handle ofh, int is32,
                                      omf_idx group, omf_idx seg,
                                      omf_frame frame, char *name, int len,
                                      orl_sec_offset offset, omf_rectyp typ )
{
    omf_symbol_handle   sym;
    orl_symbol_type     styp;

    is32 = is32;
    assert( ofh );
    assert( name );

    if( !seg && group ) {
        /* we currently don't handle this, presumably it does not occur.
         */
        return( ORL_ERROR );
    } else if( !seg && !group ) {
        styp = ORL_SYM_TYPE_ABSOLUTE;
    } else {
        styp = ORL_SYM_TYPE_DEFINED;
    }
    styp |= ORL_SYM_TYPE_OBJECT;

    sym = newSymbol( ofh, styp, name, len );
    if( !sym ) return( ORL_OUT_OF_MEMORY );

    sym->seg = seg;
    sym->frame = frame;
    sym->offset = offset;
    sym->rec_typ = typ;
    if( ( typ == CMD_LPUBDEF ) || ( typ == CMD_LPUBDEF32 ) ) {
        sym->flags |= OMF_SYM_FLAGS_LOCAL;
        sym->binding = ORL_SYM_BINDING_LOCAL;
    } else {
        sym->binding = ORL_SYM_BINDING_GLOBAL;
    }

    if( styp & ORL_SYM_TYPE_DEFINED ) {
        sym->section = findSegment( ofh, seg );
    }

    return( addToSymbolTable( ofh, sym ) );
}


orl_return              OmfAddGrpDef( omf_file_handle ofh, omf_idx name,
                                      omf_idx *segs, int size )
{
    omf_symbol_handle   sym;
    omf_sec_handle      sh;
    char                lname[257];
    int                 len;
    omf_grp_handle      gr;

    assert( ofh );
    assert( segs );

    if( !name ) return( ORL_ERROR );

    gr = newGroup( ofh );
    if( !gr ) return( ORL_OUT_OF_MEMORY );

    gr->segs = segs;
    gr->name = name;
    gr->size = size;

    while( size ) {
        size--;
        sh = findSegment( ofh, segs[size] );
        if( !sh ) return( ORL_ERROR );
        sh->flags |= ORL_SEC_FLAG_GROUPED;
        sh->assoc.seg.group = gr;
    }

    len = OmfGetLName( ofh->lnames, name, lname );
    if( len < 0 ) return( ORL_ERROR );

    sym = newSymbol( ofh, ORL_SYM_TYPE_GROUP, lname, len );
    if( !sym ) return( ORL_OUT_OF_MEMORY );

    sym->flags |= OMF_SYM_FLAGS_GRPDEF;
    sym->idx = gr->id;
    gr->sym = sym;

    return( addToSymbolTable( ofh, sym ) );
}


orl_return      OmfModEnd( omf_file_handle ofh )
{
    orl_return          err;
    omf_symbol_handle   sym;

    assert( ofh );

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

    sym = newSymbol( ofh, ORL_SYM_TYPE_FILE, ofh->modname, ofh->modnamelen );
    if( !sym ) return( ORL_OUT_OF_MEMORY );

    return( addToSymbolTable( ofh, sym ) );
}


extern orl_return       OmfAddComment( omf_file_handle ofh, uint_8 class,
                                       uint_8 flags, omf_bytes buff, long len )
{
    omf_sec_handle      sh;
    omf_comment_struct  *comment;

    assert( ofh );
    assert( buff );

    sh = ofh->comments;
    if( !sh ) {
        sh = newSection( ofh, OMF_SEC_COMMENT_INDEX, ORL_SEC_TYPE_NOTE );
        if( !sh ) return( ORL_OUT_OF_MEMORY );
        sh->flags |= ORL_SEC_FLAG_REMOVE;
        ofh->comments = sh;
    }

    sh->assoc.comment.comments = checkArraySize(ofh, sh->assoc.comment.comments,
                                                sh->assoc.comment.num, STD_INC,
                                                sizeof(omf_comment_struct *) );
    if( !sh->assoc.comment.comments ) return( ORL_OUT_OF_MEMORY );

    comment = _ClientAlloc( ofh, sizeof( omf_comment_struct ) + len );
    if( !comment ) return( ORL_OUT_OF_MEMORY );
    memset( comment, 0, sizeof( omf_comment_struct ) + len );

    comment->class = class;
    comment->flags = flags;
    comment->len = len;
    memcpy( comment->data, buff, len );
    comment->data[len] = 0;

    sh->assoc.comment.comments[sh->assoc.comment.num] = comment;
    sh->assoc.comment.num++;

    return( ORL_OKAY );
}


int             OmfGetLName( omf_sec_handle lnames, omf_idx idx, char *name )
{
    omf_string_struct   *tmp;

    assert( lnames );
    assert( name );
    assert( lnames->type == ORL_SEC_TYPE_STR_TABLE );

    *name = '\0';
    if( !idx ) {
        return( 0 );
    }

    idx--;
    tmp = getIdx2String( lnames, idx );
    if( !tmp ) {
        return( -1 );
    }
    memcpy( name, tmp->string, tmp->len );
    name[tmp->len] = '\0';
    return( tmp->len );
}


char                    *OmfGetPtrToLName( omf_file_handle ofh, omf_idx idx )
{
    omf_string_struct   *tmp;

    assert( ofh );

    if( !ofh->lnames || ( idx < 1 ) ) return( NULL );

    idx--;
    tmp = getIdx2String( ofh->lnames, idx );
    if( !tmp ) return( NULL );

    return( tmp->string );
}


omf_sec_handle          OmfFindSegOrComdat( omf_file_handle ofh, omf_idx seg,
                                            omf_idx comdat_lname )
{
    omf_quantity        x;

    assert( ofh );

    if( seg ) {
        return( findSegment( ofh, seg ) );
    } else {
        assert( comdat_lname );

        for( x = 0; x < ofh->num_comdats; x++ ) {
            if( nameCmp(ofh, ofh->comdats[x]->assoc.seg.name, comdat_lname) == 0 ) {
                return( ofh->comdats[x] );
            }
        }
    }
    return( NULL );
}


orl_return      OmfExportSegmentContents( omf_sec_handle sh )
{
    assert( sh );

    if( sh->size > 0 ) {
        return( checkSegmentLength( sh, sh->size ) );
    }
    return( ORL_OKAY );
}

⌨️ 快捷键说明

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