objomf.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,112 行 · 第 1/3 页

C
1,112
字号
    case LDIR_OPT_FAR_CALLS:
        seg = (segnode *)FindNode( SegNodes, GetIdx() );
        seg->entry->canfarcall = TRUE;
        seg->entry->iscode = TRUE;
        break;
    case LDIR_FLAT_ADDRS:
        CurrMod->modinfo |= MOD_FLATTEN_DBI;
        break;
    case LDIR_OPT_UNSAFE:
        ObjFormat |= FMT_UNSAFE_FIXUPP;
        break;
    }
}

static void ReadName( length_name *ln_name )
/******************************************/
{
    ln_name->len = *(unsigned char *)ObjBuff;
    ObjBuff += sizeof( unsigned char );
    ln_name->name = ObjBuff;
    ObjBuff += ln_name->len;
}

#define EXPDEF_ORDINAL  0x80

static void ProcExportKeyword( void )
/***********************************/
{
    unsigned_8  flags;
    length_name intname;
    length_name expname;
    unsigned    ordinal;

    flags = *ObjBuff++;
    ReadName( &expname );
    ReadName( &intname );
    ordinal = 0;
    if( flags & EXPDEF_ORDINAL ) {
        ordinal = GET_U16_UN(ObjBuff);
    }
    HandleExport( &expname, &intname, flags, ordinal );
}

static void ProcImportKeyword( void )
/***********************************/
{
    length_name intname;
    length_name modname;
    length_name extname;
    unsigned_8  info;

    info = *(unsigned char *)ObjBuff;
    ObjBuff += sizeof( unsigned char );
    ReadName( &intname );
    ReadName( &modname );
    if( info == DLL_RELOC_NAME ) {
        if( *ObjBuff == 0 ) {   /* use internal name */
            HandleImport( &intname, &modname, &intname, NOT_IMP_BY_ORDINAL );
        } else {
            ReadName( &extname );
            HandleImport( &intname, &modname, &extname, NOT_IMP_BY_ORDINAL );
        }
    } else {
        HandleImport(&intname, &modname, &extname, GET_U16_UN(ObjBuff) );
    }
}


static void DoMSOMF( void )
/***********************************/
/* Figure out debug info type and handle it accordingly later. */
{
    if (ObjBuff == EOObjRec)
        CurrMod->omfdbg = OMF_DBG_CODEVIEW;    /* Assume MS style */
    else {
        unsigned_8  version;
        char        *dbgtype;

        version = *ObjBuff++;
        dbgtype = ObjBuff;
        ObjBuff += 2;
        if( strncmp( dbgtype, "CV", 2 ) == 0 ) {
            CurrMod->omfdbg = OMF_DBG_CODEVIEW;
        } else if( strncmp( dbgtype, "HL", 2 ) == 0 ) {
            CurrMod->omfdbg = OMF_DBG_HLL;
        }
        else {
            CurrMod->omfdbg = OMF_DBG_UNKNOWN;
        }
    }
}

static void Comment( void )
/*************************/
/* Process a comment record. */
{
    unsigned char       attribute;
    unsigned char       class;
    int                 proc;
    unsigned char       which;

    attribute = *(unsigned char *)ObjBuff;
    ObjBuff += sizeof( unsigned char );
    class = *(unsigned char *)ObjBuff;
    ObjBuff += sizeof( unsigned char );

    switch( class ) {
    case CMT_DLL_ENTRY:
        which = *ObjBuff;
        ObjBuff += sizeof( unsigned char );
        switch( which ) {
        case MOMF_IMPDEF:
        case MOMF_EXPDEF:
            SeenDLLRecord();
            if( which == MOMF_EXPDEF ) {
                ProcExportKeyword();
            } else {
                ProcImportKeyword();
            }
            break;
        case MOMF_PROT_LIB:
            if( FmtData.type & MK_WINDOWS ) {
                FmtData.u.os2.is_private_dll = TRUE;
            }
            break;
        }
        break;
    case CMT_WAT_PROC_MODEL:
    case CMT_MS_PROC_MODEL:
        proc = GET_U8_UN( ObjBuff ) - '0';
        if( proc > FmtData.cpu_type ) FmtData.cpu_type = proc;
        break;
    case CMT_DOSSEG:
        LinkState |= DOSSEG_FLAG;
        break;
    case CMT_DEFAULT_LIBRARY:
        AddCommentLib( ObjBuff, EOObjRec - ObjBuff, 0xfe );
        break;
    case CMT_LINKER_DIRECTIVE:
        LinkDirective();
        break;
    case CMT_WKEXT:
        DoLazyExtdef( TRUE );
        break;
    case CMT_LZEXT:
        DoLazyExtdef( FALSE );
        break;
    case CMT_EASY_OMF:
        if( memcmp( ObjBuff, EASY_OMF_SIGNATURE, 5 ) == 0 ) {
            ObjFormat |= FMT_EASY_OMF;
        }
        break;
    case CMT_SOURCE_NAME:
        DBIComment();
        break;
    case CMT_MS_OMF:
        DoMSOMF();
        break;
    case 0x80:      /* Code Gen used to put bytes out in wrong order */
        if( attribute == CMT_SOURCE_NAME ) {    /* no longer generated */
            DBIComment();
        } else if( attribute == CMT_LINKER_DIRECTIVE ) {  /* linker directive */
            LinkDirective();
        }
        break;
    }
}

static void ProcAlias( void )
/***************************/
/* process a symbol alias directive */
{
    char *      alias;
    int         aliaslen;
    char *      target;
    int         targetlen;
    symbol *    sym;

    while( ObjBuff < EOObjRec ) {
        aliaslen = *ObjBuff;
        ObjBuff++;
        alias = ObjBuff;
        ObjBuff += aliaslen;
        targetlen = *ObjBuff;
        ObjBuff++;
        sym = SymXOp( ST_FIND | ST_NOALIAS, alias, aliaslen );
        if( !sym || !(sym->info & SYM_DEFINED) ) {
            _ChkAlloc( target, targetlen + 1 );
            memcpy( target, ObjBuff, targetlen );
            target[targetlen] = '\0';
            MakeSymAlias( alias, aliaslen, target, targetlen );
        }
        ObjBuff += targetlen;
    }
}

static void ProcModuleEnd( void )
/*******************************/
{
    byte        frame;
    byte        target;
    unsigned    targetidx;
    segnode *   seg;
    extnode *   ext;
    bool        hasdisp;

    if( StartInfo.user_specd ) return;
    if( *ObjBuff & 0x40 ) {
        ObjBuff++;
        if( ObjBuff == EOObjRec ) return;       /* CSet/2 stupidity */
        frame = (*ObjBuff >> 4) & 0x7;
        target = *ObjBuff & 0x3;
        hasdisp = (*ObjBuff & 0x4) == 0;
        ObjBuff++;
        if( frame <= 2 ) {              /* frame requires an index */
            SkipIdx();
        }
        targetidx = GetIdx();
        switch( target ) {
        case TARGET_SEGWD:
            if( StartInfo.type != START_UNDEFED ) {
                LnkMsg( LOC+ERR+MSG_MULT_START_ADDRS, NULL );
                return;                 // <-------- NOTE: premature return
            }
            seg = (segnode *)FindNode( SegNodes, targetidx );
            StartInfo.type = START_IS_SDATA;
            StartInfo.targ.sdata= seg->entry;
            if( seg->info & SEG_CODE && LinkFlags & STRIP_CODE ) {
                RefSeg( (segdata *) seg->entry );
            }
            StartInfo.mod = CurrMod;
            break;
        case TARGET_EXTWD:
            ext = (extnode *) FindNode( ExtNodes, targetidx );
            SetStartSym( ext->entry->name );
            break;
        case TARGET_ABSWD:
        case TARGET_GRPWD:
            BadObject();        // no one does these, right???
            break;
        }
        if( hasdisp ) {
            if( ObjFormat & FMT_32BIT_REC ) {
                _TargU32toHost( _GetU32UN( ObjBuff ), StartInfo.off );
            } else {
                _TargU16toHost( _GetU16UN( ObjBuff ), StartInfo.off );
            }
        }
    }
}

static void AddNames( void )
/**************************/
/* Process NAMES record */
{
    int                 name_len;
    list_of_names **    entry;

    DEBUG(( DBG_OLD, "AddNames()" ));
    while( ObjBuff < EOObjRec ) {
        name_len = ( (obj_name UNALIGN *) ObjBuff )->len;
        entry = AllocNode( NameNodes );
        *entry = MakeListName( ((obj_name UNALIGN *)ObjBuff)->name, name_len );
        ObjBuff += name_len + sizeof( byte );
    }
}

static void ProcSegDef( void )
/****************************/
/* process a segdef record */
{
    segdata *           sdata;
    segnode *           snode;
    list_of_names *     clname;
    list_of_names *     name;
    byte                acbp;
    unsigned            comb;

    DEBUG(( DBG_OLD, "ProcSegDef()" ));
    sdata = AllocSegData();
    acbp = *ObjBuff;
    ++ObjBuff;
    comb = (acbp >> 2) & 7;
    if( comb == COMB_INVALID || comb == COMB_BAD ) {
        sdata->combine = COMBINE_INVALID;
    } else if( comb == COMB_COMMON ) {
        sdata->combine = COMBINE_COMMON;
    } else {
        sdata->combine = COMBINE_ADD;
    }
    sdata->align = OMFAlignTab[acbp >> 5];
    if( ObjFormat & FMT_EASY_OMF ) {   // set USE_32 flag.
        sdata->is32bit = TRUE;
    } else if( acbp & 1 ) {
        sdata->is32bit = TRUE;
    }
    switch( acbp >> 5 ) {
    case ALIGN_ABS:
        _TargU16toHost( _GetU16UN( ObjBuff ), sdata->a.frame );
        sdata->isabs = TRUE;
        ObjBuff += sizeof( unsigned_16 );
        ObjBuff += sizeof( byte );
        break;
    case ALIGN_LTRELOC:
// in 32 bit object files, ALIGN_LTRELOC is actually ALIGN_4KPAGE
        if( ObjFormat & FMT_32BIT_REC ) break;
        sdata->align = OMFAlignTab[ALIGN_PARA];
        ObjBuff += 5;   /*  step over ltldat, max_seg_len, grp_offs fields */
        break;
    }
    if( ObjFormat & FMT_32BIT_REC ) {
        if( acbp & 2 ) {
            BadObject();        // we can't handle 4 GB segments properly
            return;
        }
        _TargU32toHost( _GetU32UN( ObjBuff ), sdata->length );
        ObjBuff += sizeof( unsigned_32 );
    } else {
        if( acbp & 2 ) {
            sdata->length = 65536;          // 64k segment
        } else {
            _TargU16toHost( _GetU16UN( ObjBuff ), sdata->length );
        }
        ObjBuff += sizeof( unsigned_16 );
    }
    name = FindName( GetIdx() );
    sdata->u.name = name->name;
    clname = FindName( GetIdx() );
    if( ObjFormat & FMT_EASY_OMF ) {
        SkipIdx();        // skip overlay name index
        if( ObjBuff < EOObjRec ) {      // the optional attribute field present
            if( !(*ObjBuff & 0x4) ) {      // if USE32 bit not set;
                sdata->is32bit = FALSE;
            }
        }
    }
    sdata->iscode = IsCodeClass( clname->name, strlen(clname->name) );
    snode = AllocNode( SegNodes );
    snode->entry = sdata;
    AllocateSegment( snode, clname->name );
}

static void DefineGroup( void )
/*****************************/
/* Define a group. */
{
    int                 num_segs;
    byte *              anchor;
    segnode *           seg;
    list_of_names *     grp_name;
    grpnode *           newnode;
    group_entry *       group;

    grp_name = FindName( GetIdx() );
    DEBUG(( DBG_OLD, "DefineGroup() - %s", grp_name->name ));
    anchor = ObjBuff;
    num_segs = 0;
    for(;;) {
        if( ObjBuff >= EOObjRec ) break;
        if( *ObjBuff != GRP_SEGIDX ) {
            BadObject();
            return;
        }
        ++ObjBuff;
        SkipIdx();/*  skip segment index */
        ++num_segs;
    }
    newnode = AllocNode( GrpNodes );
    group = SearchGroups( grp_name->name );
    if( group == NULL ) {
        if( num_segs == 0 ) {

⌨️ 快捷键说明

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