Exemplo n.º 1
0
// #pragma alias(id1/"name1", id2/"name2")
//
// Causes linker to replace references to id1/name1 with references
// to id2/name2. Both the alias and the substituted symbol may be defined
// either as a string name or an id of existing symbol.
//
static void PragAlias( void )
/***************************/
{
    SYM_HANDLE      alias_sym;
    SYM_HANDLE      subst_sym;
    const char      *alias_name;
    const char      *subst_name;
    alias_list      **alias;
    alias_list      *new_alias;

    alias_name = subst_name = NULL;
    alias_sym  = subst_sym  = NULL;

    if( ExpectingToken( T_LEFT_PAREN ) ) {
        PPCTL_ENABLE_MACROS();
        PPNextToken();
        if( CurToken == T_ID ) {
            alias_sym = SymLook( HashValue, Buffer );
            if( alias_sym == 0 ) {
                CErr2p( ERR_UNDECLARED_SYM, Buffer );
            }
        } else if( CurToken == T_STRING ) {
            alias_name = CStrSave( Buffer );
        }
        PPNextToken();
        MustRecog( T_COMMA );
        if( CurToken == T_ID ) {
            subst_sym = SymLook( HashValue, Buffer );
            if( subst_sym == 0 ) {
                CErr2p( ERR_UNDECLARED_SYM, Buffer );
            }
        } else if( CurToken == T_STRING ) {
            subst_name = CStrSave( Buffer );
        }
        PPNextToken();
        PPCTL_DISABLE_MACROS();
        MustRecog( T_RIGHT_PAREN );
    }

    /* Add a new alias record - if it's valid - to the list */
    if( ( alias_name != NULL || alias_sym != NULL ) && ( subst_name != NULL || subst_sym != NULL ) ) {
        for( alias = &AliasHead; *alias != NULL; alias = &(*alias)->next )
            ; /* nothing to do */
        new_alias = (void *)CMemAlloc( sizeof( alias_list ) );
        new_alias->next = NULL;
        if( alias_name ) {
            new_alias->name = alias_name;
        } else {
            new_alias->a_sym = alias_sym;
        }
        if( subst_name ) {
            new_alias->subst = subst_name;
        } else {
            new_alias->s_sym = subst_sym;
        }
        *alias = new_alias;
    }
}
Exemplo n.º 2
0
static void PragIntrinsic( int intrinsic )              /* 09-oct-92 */
/****************************************/
{
    SYM_HANDLE  sym_handle;
    SYM_ENTRY   sym;

    if( ExpectingToken( T_LEFT_PAREN ) ) {
        NextToken();
        while( IS_ID_OR_KEYWORD( CurToken ) ) {
            sym_handle = SymLook( HashValue, Buffer );
            if( sym_handle != 0 ) {
                SymGet( &sym, sym_handle );
                sym.flags &= ~ SYM_INTRINSIC;
                if( intrinsic )
                    sym.flags |= SYM_INTRINSIC;
                SymReplace( &sym, sym_handle );
            }
            NextToken();
            if( CurToken != T_COMMA )
                break;
            NextToken();
        }
        MustRecog( T_RIGHT_PAREN );
    }
}
Exemplo n.º 3
0
enum sym_type AsmQueryType( char *name )
/**************************************/
{
    SYM_HANDLE  sym_handle;
    SYM_ENTRY   sym;

    sym_handle = SymLook( CalcHash( name, strlen( name ) ), name );
    if( sym_handle == 0 ) return( SYM_INT1 );
    SymGet( &sym, sym_handle );
    return( AsmType( sym.sym_type, sym.attrib ) );
}
Exemplo n.º 4
0
static void parseExtRef ( void )
/******************************/
{
    SYM_HANDLE   extref_sym;

    if( CurToken == T_STRING ) {
        AddExtRefN( Buffer );
    } else {
        extref_sym = SymLook( HashValue, Buffer );
        if( extref_sym != NULL ) {
            AddExtRefS( extref_sym );
        } else {
            CErr2p( ERR_UNDECLARED_SYM, Buffer );
        }
    }
}
Exemplo n.º 5
0
enum sym_state AsmQueryExternal( char *name )
/*******************************************/
{
    SYM_HANDLE  sym_handle;
    SYM_ENTRY   sym;

    sym_handle = SymLook( CalcHash( name, strlen( name ) ), name );
    if( sym_handle == 0 )
        return( SYM_UNDEFINED );
    SymGet( &sym, sym_handle );
    if( !(sym.flags & SYM_REFERENCED) ) {
        sym.flags |= SYM_REFERENCED;
        SymReplace( &sym, sym_handle );
    }
    switch( sym.stg_class ) {
    case SC_AUTO:
    case SC_REGISTER:
        return( SYM_STACK );
    }
    return( SYM_EXTERNAL );
}
Exemplo n.º 6
0
void SetCurrInfo( char *name )
/****************************/
{
    SYM_HANDLE      sym_handle;
    SYM_ENTRY       sym;
    type_modifiers  sym_attrib = FLAG_NONE;

    CurrInfo = MagicKeyword( name );
    if( CurrInfo == NULL ) {
        if( CurrAlias == NULL ) {
            sym_handle = SymLook( HashValue, name );
            if( sym_handle != 0 ) {
                SymGet( &sym, sym_handle );
                sym_attrib = sym.mods;
            }
            CurrAlias = GetLangInfo( sym_attrib );
        }
        CreateAux( name );
    } else if( CurrAlias == NULL ) {
        CurrAlias = CurrInfo;
    }
}
Exemplo n.º 7
0
void PragEnding( void )
/*********************/
{
    if( CurrEntry == NULL )
        return;
    CurrInfo->use = CurrAlias->use; /* for compare */
    if( memcmp( CurrAlias, CurrInfo, sizeof( aux_info ) ) == 0 ) {
        CurrEntry->info = CurrAlias;
        CurrAlias->use++;
        CMemFree( CurrInfo );
    } else {
        CopyParms();
        CopyLinkage();
        CopyCode();
        CopyObjName();
#if _CPU == _AXP
        CopyExceptRtn();
#endif
        CurrInfo->use = 1;
        CurrEntry->info = CurrInfo;
    }

    /* If this pragma defines code, check to see if we already have a function body */   
    if( CurrEntry->name != NULL && CurrEntry->info != NULL && CurrEntry->info->code != NULL ) {
        SYM_HANDLE  sym_handle;
        SYM_ENTRY   sym;

        if( 0 != (sym_handle = SymLook( CalcHash( CurrEntry->name, strlen( CurrEntry->name ) ), CurrEntry->name )) ) {
            SymGet( &sym, sym_handle );
            if( ( sym.flags & SYM_DEFINED ) && ( sym.flags & SYM_FUNCTION ) ) {
                CErr2p( ERR_SYM_ALREADY_DEFINED, CurrEntry->name );
            }
        }
    }

    CurrEntry->next = AuxList;
    AuxList = CurrEntry;
}
Exemplo n.º 8
0
static int InsertFixups( unsigned char *buff, unsigned i, byte_seq **code )
/*************************************************************************/
{
                        /* additional slop in buffer to simplify the code */
    unsigned char       temp[MAXIMUM_BYTESEQ + 1 + 2 * sizeof( long )];
    struct asmfixup     *fix;
    struct asmfixup     *head;
    struct asmfixup     *chk;
    struct asmfixup     *next;
    struct asmfixup     **owner;
    unsigned char       *dst;
    unsigned char       *src;
    unsigned char       *end;
    byte_seq            *seq;
    byte_seq_len        perform_fixups;
    unsigned char       cg_fix;
    SYM_HANDLE          sym_handle;
    SYM_ENTRY           sym;
    char                *name;
    unsigned            skip;
    int                 mutate_to_segment;
    int                 uses_auto;
#if _CPU == 8086
    int                 fixup_padding;
#endif

    sym_handle = 0;
    uses_auto = 0;
    perform_fixups = 0;
    head = FixupHead;
    if( head != NULL ) {
        FixupHead = NULL;
        /* sort the fixup list in increasing fixup_loc's */
        for( fix = head; fix != NULL; fix = next ) {
            owner = &FixupHead;
            for( ;; ) {
                chk = *owner;
                if( chk == NULL ) break;
                if( chk->fixup_loc > fix->fixup_loc ) break;
                owner = &chk->next;
            }
            next = fix->next;
            fix->next = *owner;
            *owner = fix;
        }
        dst = temp;
        src = buff;
        end = src + i;
        fix = FixupHead;
        owner = &FixupHead;
        /* insert fixup escape sequences */
        while( src < end ) {
            if( fix != NULL && fix->fixup_loc == (src - buff) ) {
                name = fix->name;
                if( name != NULL ) {
                    sym_handle = SymLook( CalcHash( name, strlen( name ) ),
                                name );
                    if( sym_handle == 0 ) {
                        CErr2p( ERR_UNDECLARED_SYM, name );
                        return( 0 );
                    }
                    SymGet( &sym, sym_handle );
                    sym.flags |= SYM_REFERENCED | SYM_ADDR_TAKEN;
                    switch( sym.stg_class ) {
                    case SC_REGISTER:
                    case SC_AUTO:
                        sym.flags |= SYM_USED_IN_PRAGMA;
                        CurFuncNode->op.func.flags &= ~FUNC_OK_TO_INLINE;
                        uses_auto = 1;
                        break;
                    }
                    SymReplace( &sym, sym_handle );
                }
                /* insert fixup information */
                skip = 0;
                *dst++ = FLOATING_FIXUP_BYTE;
                mutate_to_segment = 0;
#if _CPU == 8086
                fixup_padding = 0;
#endif
                switch( fix->fixup_type ) {
                case FIX_FPPATCH:
                    *dst++ = fix->offset;
                    break;
                case FIX_SEG:
                    if( name == NULL ) {
                        // special case for floating point fixup
                        if( ( src[0] == 0x90 ) && ( src[1] == 0x9B ) ) {
                           // inline assembler FWAIT instruction 0x90, 0x9b
                            *dst++ = FIX_FPP_WAIT;
                        } else if( src[0] == 0x9b && (src[1] & 0xd8) == 0xd8 ) {
                           // FWAIT as first byte and FPU instruction opcode as second byte
                            *dst++ = FIX_FPP_NORMAL;
                        } else if( src[0] == 0x9b && (src[2] & 0xd8) == 0xd8 ) {
                           // FWAIT as first byte and FPU instruction opcode as third byte
                           // second byte should be segment override prefix
                            switch( src[1] ) {
                            case PREFIX_ES: *dst++ = FIX_FPP_ES;    break;
                            case PREFIX_CS: *dst++ = FIX_FPP_CS;    break;
                            case PREFIX_SS: *dst++ = FIX_FPP_SS;    break;
                            case PREFIX_DS: *dst++ = FIX_FPP_DS;    break;
                            case PREFIX_GS: *dst++ = FIX_FPP_GS;    break;
                            case PREFIX_FS: *dst++ = FIX_FPP_FS;    break;
                            default: --dst; break;  // skip FP patch
                            }
                        } else {
                            // skip FP patch
                            --dst;
                        }
                    } else {
                        skip = 2;
                        cg_fix = FIX_SYM_SEGMENT;
                    }
                    break;
                case FIX_RELOFF16:
                    skip = 2;
                    cg_fix = FIX_SYM_RELOFF;
                    break;
                case FIX_RELOFF32:
                    skip = 4;
                    cg_fix = FIX_SYM_RELOFF;
#if _CPU == 8086
                    fixup_padding = 1;
#endif
                    break;
                case FIX_PTR16:
                    mutate_to_segment = 1;
                    /* fall through */
                case FIX_OFF16:
                    skip = 2;
                    cg_fix = FIX_SYM_OFFSET;
                    break;
                case FIX_PTR32:
                    mutate_to_segment = 1;
                    /* fall through */
                case FIX_OFF32:
                    skip = 4;
                    cg_fix = FIX_SYM_OFFSET;
#if _CPU == 8086
                    fixup_padding = 1;
#endif
                    break;
                default:
                    CErr2p( ERR_UNREACHABLE_SYM, name );
                    break;
                }
                if( skip != 0 ) {
                    *dst++ = cg_fix;
                    *((CGSYM_HANDLE *)dst) = sym_handle;
                    dst += sizeof( CGSYM_HANDLE );
                    *((unsigned long *)dst) = fix->offset;
                    dst += sizeof( long );
                    src += skip;
                }
#if _CPU == 8086
                if( fixup_padding ) {
                    // add offset fixup padding to 32-bit
                    // cg create only 16-bit offset fixup
                    *dst++ = 0;
                    *dst++ = 0;
                    //
                }
#endif
                if( mutate_to_segment ) {
                    /*
                        Since the CG escape sequences don't allow for
                        FAR pointer fixups, we have to split them into two.
                        This is done by doing the offset fixup first, then
                        mutating the fixup structure to look like a segment
                        fixup one near pointer size later.
                    */
                    fix->fixup_type = FIX_SEG;
                    fix->fixup_loc += skip;
                    fix->offset = 0;
                } else {
                    head = fix;
                    fix = fix->next;
                    if( head->external ) {
                        *owner = fix;
                        if( head->name != NULL ) {
                            CMemFree( head->name );
                        }
                        CMemFree( head );
                    } else {
                        owner = &head->next;
                    }
                }
            } else {
                if( *src == FLOATING_FIXUP_BYTE ) {
                    *dst++ = FLOATING_FIXUP_BYTE;
                }
                *dst++ = *src++;
            }
            if( dst > &temp[MAXIMUM_BYTESEQ] ) {
                CErr1( ERR_TOO_MANY_BYTES_IN_PRAGMA );
                return( 0 );
            }
        }
        buff = temp;
        i = dst - temp;
        perform_fixups = DO_FLOATING_FIXUPS;
    }
    seq = (byte_seq *)CMemAlloc( sizeof( byte_seq ) + i );
    seq->length = i | perform_fixups;
    memcpy( &seq->data[0], buff, i );
    *code = seq;
    return( uses_auto );
}