objorl.c

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

C
935
字号
// NYI
{
    dummy = dummy;
    return ORL_OKAY;
}

static void AllocSeg( void *_snode, void *dummy )
/***********************************************/
{
    segnode *           snode = _snode;
    segdata *           sdata;
    char *              clname;
    char *              sname;
    group_entry *       group;
    bool                isdbi;

    dummy = dummy;
    sdata = snode->entry;
    if( sdata == NULL ) return;
    sname = sdata->u.name;
    if( CurrMod->modinfo & MOD_IMPORT_LIB ) {
        if( sdata->isidata || sdata->iscode ) {
            if( sdata->iscode ) {
                snode->info |= SEG_CODE;
            }
            snode->info |= SEG_DEAD;
            snode->entry = NULL;
            FreeSegData( sdata );
            return;
        }
    }
    isdbi = FALSE;
    if( memicmp( CoffDebugPrefix, sdata->u.name,
                 sizeof(CoffDebugPrefix) - 1 ) == 0 ) {
        if( CurrMod->modinfo & MOD_IMPORT_LIB ) {
            snode->info |= SEG_DEAD;
            snode->entry = NULL;
            FreeSegData( sdata );
            return;
        }
        isdbi = TRUE;
        if( stricmp(CoffDebugSymName, sdata->u.name ) == 0 ) {
            clname = _MSLocalClass;
        } else if( stricmp(CoffDebugTypeName, sdata->u.name ) == 0 ) {
            clname = _MSTypeClass;
        } else {
            clname = _DwarfClass;
        }
    } else if( memicmp( TLSSegPrefix, sdata->u.name,
                        sizeof(TLSSegPrefix) - 1 ) == 0 ) {
        clname = TLSClassName;
    } else if( sdata->iscode ) {
        clname = CodeClassName;
    } else if( sdata->isuninit ) {
        clname = BSSClassName;
    } else {
        clname = DataClassName;
        if( memcmp( sname, CoffPDataSegName, sizeof(CoffPDataSegName) ) == 0 ) {
            sdata->ispdata = TRUE;
        } else if( memcmp(sname, CoffReldataSegName,
                                   sizeof(CoffReldataSegName) ) == 0 ) {
            sdata->isreldata = TRUE;
        }
    }
    AllocateSegment( snode, clname );
    if( clname == TLSClassName ) {
        group = GetGroup( TLSGrpName );
        AddToGroup( group, snode->entry->u.leader );
    } else if( !sdata->iscode && !isdbi ) {
        group = GetGroup( DataGrpName );
        AddToGroup( group, snode->entry->u.leader );
    }
    if( sdata->isuninit ) {
        snode->contents = NULL;
    } else {
        snode->entry->u.leader->info |= SEG_LXDATA_SEEN;
        if( !sdata->isdead ) {
            ORLSecGetContents( snode->handle, &snode->contents );
            if( !sdata->iscdat && ( snode->contents != NULL )) {
                PutInfo( sdata->data, snode->contents, sdata->length );
            }
        }
    }
}

static void DefNosymComdats( void *_snode, void *dummy )
/******************************************************/
{
    segnode *           snode = _snode;
    segdata *           sdata;

    dummy = dummy;
    sdata = snode->entry;
    if( sdata == NULL || snode->info & SEG_DEAD ) return;
    if( sdata->iscdat && !sdata->hascdatsym && ( snode->contents != NULL )) {
        sdata->data = AllocStg( sdata->length );
        PutInfo( sdata->data, snode->contents, sdata->length );
    }
}

static orl_return DeclareSegment( orl_sec_handle sec )
/****************************************************/
// declare the "segment"
{
    segdata *           sdata;
    segnode *           snode;
    char *              name;
    unsigned_32 UNALIGN *contents;
    size_t              len;
    orl_sec_flags       flags;
    orl_sec_type        type;
    unsigned            numlines;
    unsigned            segidx;

    type = ORLSecGetType( sec );
    if( type != ORL_SEC_TYPE_NO_BITS && type != ORL_SEC_TYPE_PROG_BITS ) {
         return ORL_OKAY;
    }
    flags = ORLSecGetFlags( sec );
    name = ORLSecGetName( sec );
    sdata = AllocSegData();
    segidx = ORLCvtSecHdlToIdx( sec );
    snode = AllocNodeIdx( SegNodes, segidx );
    snode->entry = sdata;
    snode->handle = sec;
    sdata->iscdat = (flags & ORL_SEC_FLAG_COMDAT) != 0;
    len = sizeof(CoffIDataSegName) - 1;
    if( strnicmp(CoffIDataSegName, name, len) == 0 ) {
        SeenDLLRecord();
        CurrMod->modinfo |= MOD_IMPORT_LIB;
        if( name[len + 1] == '6' ) {    // it is the segment containg the name
            ORLSecGetContents( sec, &ImpExternalName );
            ImpExternalName += 2;
        } else if( name[len + 1] == '4' ) {     // it is an import by ordinal
            ORLSecGetContents( sec, (void *) &contents );
            ImpOrdinal = *contents;
        }
        sdata->isdead = TRUE;
        sdata->isidata = TRUE;
    }
    sdata->combine = COMBINE_ADD;
    if( flags & ORL_SEC_FLAG_NO_PADDING ) {
        sdata->align = 0;
    } else {
        sdata->align = ORLSecGetAlignment( sec );
    }
    sdata->is32bit = TRUE;
    sdata->length = ORLSecGetSize( sec );
    sdata->u.name = name;
    if( flags & ORL_SEC_FLAG_EXEC ) {
        sdata->iscode = TRUE;
    } else if( flags & ORL_SEC_FLAG_UNINITIALIZED_DATA ) {
        sdata->isuninit = TRUE;
#if _DEVELOPMENT == _ON
    } else {
        unsigned namelen;

        namelen = strlen(name);
        if( namelen >= 3 && memicmp(name + namelen - 3, "bss", 3) == 0 ) {
            LnkMsg( ERR+MSG_INTERNAL, "s", "Initialized BSS found" );
        }
#endif
    }
    numlines = ORLSecGetNumLines( sec );
    if( numlines > 0 ) {
        numlines *= sizeof(orl_linnum);
        DBIAddLines( sdata, ORLSecGetLines( sec ), numlines, TRUE );
    }
    return ORL_OKAY;
}

static segnode * FindSegNode( orl_sec_handle sechdl )
/***************************************************/
{
    orl_table_index     idx;

    if( sechdl == NULL ) return NULL;
    idx = ORLCvtSecHdlToIdx( sechdl );
    if( idx == 0 ) {
        return NULL;
    } else {
        return FindNode( SegNodes, idx );
    }
}

#define PREFIX_LEN (sizeof(ImportSymPrefix) - 1)

static void ImpProcSymbol( segnode * snode, orl_symbol_type type, char *name,
                           int namelen )
/***************************************************************************/
{
    if( type & ORL_SYM_TYPE_UNDEFINED ) {
        if( namelen > sizeof(CoffImportRefName) - 1 ) {
            namelen -= sizeof(CoffImportRefName) - 1;
            if( memicmp( name + namelen, CoffImportRefName,
                         sizeof(CoffImportRefName) - 1 ) == 0 ) {
                _ChkAlloc( ImpModName, namelen + 5 );
                memcpy( ImpModName, name, namelen );
                if( memicmp( CurrMod->name + strlen(CurrMod->name)
                             - 4, ".drv", 4 ) == 0 ) { //KLUDGE!!
                    memcpy( ImpModName + namelen, ".drv", 5 );
                } else {
                    memcpy( ImpModName + namelen, ".dll", 5 );
                }
            }
        }
    } else if( snode != NULL && snode->info & SEG_CODE ) {
        if( FirstCodeSymName == NULL ) {
            FirstCodeSymName = name;
        }
    } else {
        if( FirstDataSymName == NULL &&
                memcmp( name, ImportSymPrefix, PREFIX_LEN ) == 0 ) {
            FirstDataSymName = name + PREFIX_LEN;
        }
    }
}

static void DefineComdatSym( segnode *seg, symbol *sym, orl_symbol_value value )
/******************************************************************************/
{
    unsigned    select;
    segdata *   sdata;

    sdata = seg->entry;
    sdata->hascdatsym = TRUE;
    select = sdata->select;
    if( select == 0 ) {
        select = SYM_CDAT_SEL_ANY;
    } else {
        select = (select - 1) << SYM_CDAT_SEL_SHIFT;
    }
    DefineComdat( sdata, sym, value, select, seg->contents );
}

static orl_return ProcSymbol( orl_symbol_handle symhdl )
/******************************************************/
{
    orl_symbol_type     type;
    char *              name;
    orl_symbol_value    value;
    orl_sec_handle      sechdl;
    symbol *            sym;
    size_t              namelen;
    sym_flags           symop;
    extnode *           newnode;
    segnode *           snode;
    bool                isweak;
    orl_symbol_handle   assocsymhdl;
    symbol *            assocsym;
    orl_symbol_binding  binding;

    sechdl = ORLSymbolGetSecHandle( symhdl );
    snode = FindSegNode( sechdl );
    type = ORLSymbolGetType( symhdl );
    name = ORLSymbolGetName( symhdl );
    if( type & ORL_SYM_TYPE_FILE ) {
        if( !(CurrMod->modinfo & MOD_GOT_NAME) ) {
            CurrMod->modinfo |= MOD_GOT_NAME;
            _LnkFree( CurrMod->name );
            CurrMod->name = StringStringTable( &PermStrings,
                                                name );
        }
        return ORL_OKAY;
    }
    if( type & ORL_SYM_TYPE_DEBUG ) return ORL_OKAY;
    if( type & (ORL_SYM_TYPE_OBJECT|ORL_SYM_TYPE_FUNCTION) ||
        (type & (ORL_SYM_TYPE_NOTYPE|ORL_SYM_TYPE_UNDEFINED) &&
         name != NULL)) {
        namelen = strlen( name );
        if( namelen == 0 ) {
            BadObject();
        }
        if( CurrMod->modinfo & MOD_IMPORT_LIB ) {
            ImpProcSymbol( snode, type, name, namelen );
            return ORL_OKAY;
        }
        newnode = AllocNode( ExtNodes );
        newnode->handle = symhdl;
        binding = ORLSymbolGetBinding( symhdl );
        symop = ST_CREATE;
        if( binding == ORL_SYM_BINDING_LOCAL ) {
            symop = ST_STATIC;
        }
        if( type & ORL_SYM_TYPE_UNDEFINED && binding != ORL_SYM_BINDING_ALIAS ){
            symop |= ST_REFERENCE;
        } else {
            symop |= ST_NOALIAS;
        }
        sym = SymOp( symop, name, namelen );
        CheckIfTocSym( sym );
        if( type & ORL_SYM_TYPE_COMMON ) {
            value = ORLSymbolGetValue( symhdl );
            sym = MakeCommunalSym( sym, value, FALSE, TRUE );
        } else if( type & ORL_SYM_TYPE_UNDEFINED ) {
            DefineReference( sym );
            isweak = FALSE;
            switch( binding ) {
            case ORL_SYM_BINDING_WEAK:
                isweak = TRUE;
            case ORL_SYM_BINDING_ALIAS:
            case ORL_SYM_BINDING_LAZY:
                assocsymhdl = ORLSymbolGetAssociated( symhdl );
                name = ORLSymbolGetName( assocsymhdl );
                namelen = strlen(name);
                if( binding == ORL_SYM_BINDING_ALIAS ) {
                    name = ChkMemDup( name, namelen + 1 );
                    MakeSymAlias( sym->name, strlen(sym->name), name,
                                    namelen );
                } else {
                    assocsym = SymOp(ST_CREATE|ST_REFERENCE, name, namelen);
                    DefineLazyExtdef( sym, assocsym, isweak );

⌨️ 快捷键说明

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