Esempio n. 1
0
static ret_code SubStrFunc( struct macro_instance *mi, char *buffer, struct asm_tok tokenarray[] )
/************************************************************************************************/
{
    int pos;
    int size;
    char *src = mi->parm_array[0];

    DebugMsg1(("@SubStr( %s, %s, %s)\n",
              src ? src : "",
              mi->parm_array[1] ? mi->parm_array[1] : "",
              mi->parm_array[2] ? mi->parm_array[2] : "" ));

    if ( GetNumber( mi->parm_array[1], &pos, tokenarray ) == ERROR )
        return( ERROR );

    if ( pos <= 0 ) {
        /* Masm doesn't check if index is < 0;
         * might cause an "internal assembler error".
         * v2.09: negative index no longer silently changed to 1.
         */
        if ( pos ) {
            return( EmitErr( INDEX_VALUE_PAST_END_OF_STRING, pos ) );
        }
        DebugMsg(( "@SubStr(): index value 0 changed to 1\n", pos ));
        pos = 1;
    }

    size = strlen( src );
    if ( pos > size ) {
        return( EmitErr( INDEX_VALUE_PAST_END_OF_STRING, pos ) );
    }

    size = size - pos + 1;

    if ( mi->parm_array[2] ) {
        int sizereq;
        if ( GetNumber( mi->parm_array[2], &sizereq, tokenarray ) == ERROR )
            return( ERROR );
        if ( sizereq < 0 ) {
            return( EmitError( COUNT_MUST_BE_POSITIVE_OR_ZERO ) );
        }
        if ( sizereq > size ) {
            return( EmitError( COUNT_VALUE_TOO_LARGE ) );
        }
        size = sizereq;
    }
#if 1
    memcpy( buffer, src + pos - 1, size );
    *(buffer+size) = NULLC;
#else
    for( src += pos - 1; size; size-- )
        *buffer++ = *src++;
    *buffer = NULLC;
#endif
    return( NOT_ERROR );
}
Esempio n. 2
0
static struct asym *CreateProto( int i, struct asm_tok tokenarray[], const char *name, enum lang_type langtype )
/**************************************************************************************************************/
{
    struct asym      *sym;
    struct dsym      *dir;

    DebugMsg1(("CreateProto( i=%u, name=%s, lang=%u )\n", i, name ? name : "NULL", langtype ));
    sym = SymSearch( name );

    /* the symbol must be either NULL or state
     * - SYM_UNDEFINED
     * - SYM_EXTERNAL + isproc == FALSE ( previous EXTERNDEF )
     * - SYM_EXTERNAL + isproc == TRUE ( previous PROTO )
     * - SYM_INTERNAL + isproc == TRUE ( previous PROC )
     */
    if( sym == NULL ||
       sym->state == SYM_UNDEFINED ||
       ( sym->state == SYM_EXTERNAL && sym->weak == TRUE && sym->isproc == FALSE )) {
        if ( NULL == ( sym = CreateProc( sym, name, SYM_EXTERNAL ) ) )
            return( NULL ); /* name was probably invalid */
    } else if ( sym->isproc == FALSE ) {
        EmitErr( SYMBOL_REDEFINITION, sym->name );
        return( NULL );
    }
    dir = (struct dsym *)sym;

    /* a PROTO typedef may be used */
    if ( tokenarray[i].token == T_ID ) {
        struct asym * sym2;
        sym2 = SymSearch( tokenarray[i].string_ptr );
        if ( sym2 && sym2->state == SYM_TYPE && sym2->mem_type == MT_PROC ) {
            i++;
            if ( tokenarray[i].token != T_FINAL ) {
                EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr );
                return( NULL );
            }
            CopyPrototype( dir, (struct dsym *)sym2->target_type );
            return( sym );
        }
    }
    /* sym->isproc is set inside ParseProc() */
    //sym->isproc = TRUE;

    if ( Parse_Pass == PASS_1 ) {
        if ( ParseProc( dir, i, tokenarray, FALSE, langtype ) == ERROR )
            return( NULL );
#if DLLIMPORT
        sym->dll = ModuleInfo.CurrDll;
#endif
    } else {
        sym->isdefined = TRUE;
    }
    return( sym );
}
Esempio n. 3
0
struct asym *CreateIntSegment( const char *name, const char *classname, uint_8 alignment, uint_8 Ofssize, bool add_global )
/*************************************************************************************************************************/
{
    struct dsym *seg;
    if ( add_global ) {
        seg = (struct dsym *)SymSearch( name );
        if ( seg == NULL || seg->sym.state == SYM_UNDEFINED )
            seg = CreateSegment( seg, name, add_global );
        else if ( seg->sym.state != SYM_SEG ) {
            EmitErr( SYMBOL_REDEFINITION, name );
            return( NULL );
        }
    } else
        seg = CreateSegment( NULL, name, FALSE );
    if ( seg ) {
        if( seg->e.seginfo->lname_idx == 0 ) {
            seg->e.seginfo->seg_idx = ++ModuleInfo.g.num_segs;
            seg->e.seginfo->lname_idx = ++LnamesIdx;
            AddLnameData( &seg->sym );
        }
        seg->sym.segment = &seg->sym;
        seg->e.seginfo->alignment = alignment;
        seg->e.seginfo->Ofssize = Ofssize;
        SetSegmentClass( (struct asym *)seg, classname );
        return( &seg->sym );
    }
    return( NULL );
}
Esempio n. 4
0
static ret_code SetCurrSeg( int i, struct asm_tok tokenarray[] )
/**************************************************************/
{
    struct asym *sym;

    sym = SymSearch( tokenarray[0].string_ptr );
    DebugMsg1(("SetCurrSeg(%s) sym=%p\n", tokenarray[0].string_ptr, sym));
    if ( sym == NULL || sym->state != SYM_SEG ) {
        EmitErr( SEG_NOT_DEFINED, tokenarray[0].string_ptr );
        return( ERROR );
    }
    /* v2.04: added */
    sym->isdefined = TRUE;
    if ( CurrSeg && Options.output_format == OFORMAT_OMF ) {
        omf_FlushCurrSeg();
        if ( Options.no_comment_data_in_code_records == FALSE )
            omf_OutSelect( FALSE );
    }
    push_seg( (struct dsym *)sym );

    if ( ModuleInfo.list )
        LstWrite( LSTTYPE_LABEL, 0, NULL );

    return( SetOfssize() );
}
Esempio n. 5
0
static ret_code CloseSeg( const char *name )
/******************************************/
{
    //struct asym      *sym;

    DebugMsg1(("CloseSeg(%s) enter\n", name));

    if( CurrSeg == NULL || ( SymCmpFunc( CurrSeg->sym.name, name, CurrSeg->sym.name_size ) != 0 ) ) {
        DebugMsg(("CloseSeg(%s): nesting error, CurrSeg=%s\n", name, CurrSeg ? CurrSeg->sym.name : "(null)" ));
        EmitErr( BLOCK_NESTING_ERROR, name );
        return( ERROR );
    }

    DebugMsg1(("CloseSeg(%s): current ofs=%" FX32 "\n", name, CurrSeg->e.seginfo->current_loc));

    if ( write_to_file && ( Options.output_format == OFORMAT_OMF ) ) {

        //if ( !omf_FlushCurrSeg() ) /* v2: error check is obsolete */
        //    EmitErr( INTERNAL_ERROR, "CloseSeg", 1 ); /* coding error! */
        omf_FlushCurrSeg();
        if ( Options.no_comment_data_in_code_records == FALSE )
            omf_OutSelect( FALSE );
    }

    pop_seg();

    return( NOT_ERROR );
}
Esempio n. 6
0
static struct dsym *CreateGroup( const char *name )
/*************************************************/
{
    struct dsym    *grp;

    grp = (struct dsym *)SymSearch( name );

    if( grp == NULL || grp->sym.state == SYM_UNDEFINED ) {
        if ( grp == NULL )
            grp = (struct dsym *)SymCreate( name );
        else
            sym_remove_table( &SymTables[TAB_UNDEF], grp );

        grp->sym.state = SYM_GRP;
        grp->e.grpinfo = LclAlloc( sizeof( struct grp_info ) );
        grp->e.grpinfo->seglist = NULL;
        //grp->e.grpinfo->grp_idx = 0;
        //grp->e.grpinfo->lname_idx = 0;
        grp->e.grpinfo->numseg = 0;
        sym_add_table( &SymTables[TAB_GRP], grp );

        grp->sym.list = TRUE;
        grp->e.grpinfo->grp_idx = ++grpdefidx;
        grp->e.grpinfo->lname_idx = ++LnamesIdx;
        AddLnameData( &grp->sym );
    } else if( grp->sym.state != SYM_GRP ) {
        EmitErr( SYMBOL_REDEFINITION, name );
        return( NULL );
    }
    grp->sym.isdefined = TRUE;
    return( grp );
}
Esempio n. 7
0
/* preprocessor directive or macro procedure is preceded
 * by a code label.
 */
ret_code WriteCodeLabel( char *line, struct asm_tok tokenarray[] )
/****************************************************************/
{
    int oldcnt;
    int oldtoken;
    char oldchar;

    if ( tokenarray[0].token != T_ID ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[0].string_ptr ) );
    }
    /* ensure the listing is written with the FULL source line */
    if ( CurrFile[LST] ) LstWrite( LSTTYPE_LABEL, 0, NULL );
    /* v2.04: call ParseLine() to parse the "label" part of the line */
    oldcnt = Token_Count;
    oldtoken = tokenarray[2].token;
    oldchar = *tokenarray[2].tokpos;
    Token_Count = 2;
    tokenarray[2].token = T_FINAL;
    *tokenarray[2].tokpos = NULLC;
    ParseLine( tokenarray );
    if ( Options.preprocessor_stdout == TRUE )
        WritePreprocessedLine( line );
    Token_Count = oldcnt;
    tokenarray[2].token = oldtoken;
    *tokenarray[2].tokpos = oldchar;
    return( NOT_ERROR );
}
Esempio n. 8
0
ret_code ListMacroDirective( int i, struct asm_tok tokenarray[] )
/***************************************************************/
{
    if ( tokenarray[i+1].token != T_FINAL ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i+1].string_ptr ) );
    }

    ModuleInfo.list_macro = GetSflagsSp( tokenarray[i].tokval );

    return( NOT_ERROR );
}
Esempio n. 9
0
ret_code SegmentModuleExit( void )
/********************************/
{
    if ( ModuleInfo.model != MODEL_NONE )
        ModelSimSegmExit();
    /* if there's still an open segment, it's an error */
    if ( CurrSeg ) {
        EmitErr( BLOCK_NESTING_ERROR, CurrSeg->sym.name );
        /* but close the still open segments anyway */
        while( CurrSeg && ( CloseSeg( CurrSeg->sym.name ) == NOT_ERROR ) );
    }

    return( NOT_ERROR );
}
Esempio n. 10
0
ret_code EndsDir( int i, struct asm_tok tokenarray[] )
/****************************************************/
{
    if( CurrStruct != NULL ) {
        return( EndstructDirective( i, tokenarray ) );
    }
    /* a label must precede ENDS */
    if( i != 1 ) {
        EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr );
        return( ERROR );
    }
    if ( Parse_Pass != PASS_1 ) {
        if ( ModuleInfo.list )
            LstWrite( LSTTYPE_LABEL, 0, NULL );
    }
    if ( CloseSeg( tokenarray[0].string_ptr ) == ERROR )
        return( ERROR );
    i++;
    if ( tokenarray[i].token != T_FINAL ) {
        EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr );
    }
    return( SetOfssize() );
}
Esempio n. 11
0
/* SizeStr()
 * defines a numeric variable which contains size of a string
 */
ret_code SizeStrDir( int i, struct asm_tok tokenarray[] )
/*******************************************************/
{
    struct asym *sym;
    int sizestr;

    DebugMsg1(("SizeStrDir entry\n"));
    DebugCmd( sizstrcnt++ );

    if ( i != 1 ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
    }
#if 0 /* this is checked in ParseLine() */
    if ( tokenarray[0].token != T_ID ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[0].string_ptr ) );
    }
#endif
    if ( tokenarray[2].token != T_STRING || tokenarray[2].string_delim != '<' ) {
        return( TextItemError( &tokenarray[2] ) );
    }
    if ( Token_Count > 3 ) {
        DebugMsg(("SizeStrDir: syntax error, name=%s, Token_Count=%u\n", tokenarray[0].string_ptr, Token_Count));
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[3].string_ptr ) );
    }

    //sizestr = GetLiteralValue( StringBufferEnd, tokenarray[2].string_ptr );
    sizestr = tokenarray[2].stringlen;

    if ( sym = CreateVariable( tokenarray[0].string_ptr, sizestr ) ) {
        DebugMsg1(("SizeStrDir(%s) exit, value=%u\n", tokenarray[0].string_ptr, sizestr));
        LstWrite( LSTTYPE_EQUATE, 0, sym );
        return( NOT_ERROR );
    }
    return( ERROR );

}
Esempio n. 12
0
int TextItemError( struct asm_tok *item )
/***************************************/
{
    if ( item->token == T_STRING && *item->string_ptr == '<' ) {
        return( EmitError( MISSING_ANGLE_BRACKET_OR_BRACE_IN_LITERAL ) );
    }
    /* v2.05: better error msg if (text) symbol isn't defined */
    if ( item->token == T_ID ) {
        struct asym *sym = SymSearch( item->string_ptr );
        if ( sym == NULL || sym->state == SYM_UNDEFINED ) {
            return( EmitErr( SYMBOL_NOT_DEFINED, item->string_ptr ) );
        }
    }
    return( EmitError( TEXT_ITEM_REQUIRED ) );
}
Esempio n. 13
0
ret_code ProtoDirective( int i, struct asm_tok tokenarray[] )
/***********************************************************/
{
    if( Parse_Pass != PASS_1 ) {
        struct asym *sym;
        /* v2.04: set the "defined" flag */
        if ( ( sym = SymSearch( tokenarray[0].string_ptr ) ) && sym->isproc == TRUE )
            sym->isdefined = TRUE;
        return( NOT_ERROR );
    }
    if( i != 1 ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
    }

    return( CreateProto( 2, tokenarray, tokenarray[0].string_ptr, ModuleInfo.langtype ) ? NOT_ERROR : ERROR );
}
Esempio n. 14
0
/* internal @InStr macro function
 * syntax: @InStr( [num], literal, literal )
 * the result is returned as string in current radix
 */
static ret_code InStrFunc( struct macro_instance *mi, char *buffer, struct asm_tok tokenarray[] )
/***********************************************************************************************/
{
    int pos = 1;
    char *p;
    uint_32 found;

    DebugMsg1(("@InStr( %s, %s, %s)\n",
              mi->parm_array[0] ? mi->parm_array[0] : "",
              mi->parm_array[1] ? mi->parm_array[1] : "",
              mi->parm_array[2] ? mi->parm_array[2] : "" ));

    /* init buffer with "0" */
    *buffer = '0';
    *(buffer+1) = NULLC;

    if ( mi->parm_array[0] ) {
        if ( GetNumber( mi->parm_array[0], &pos, tokenarray ) == ERROR )
            return( ERROR );
        if ( pos == 0 ) {
            /* adjust index 0. Masm also accepts 0 (and any negative index),
             * but the result will always be 0 then */
            DebugMsg(( "@InStr(): index value is 0, changed to 1\n" ));
            pos++;
        }
    }

    if ( pos > strlen( mi->parm_array[1] ) ) {
        return( EmitErr( INDEX_VALUE_PAST_END_OF_STRING, pos ) );
    }
    /* v2.08: if() added, empty searchstr is to return 0 */
    if ( *(mi->parm_array[2]) != NULLC ) {
        p = strstr( mi->parm_array[1] + pos - 1, mi->parm_array[2] );
        if ( p ) {
            found = p - mi->parm_array[1] + 1;
            myltoa( found, buffer, ModuleInfo.radix, FALSE, TRUE );
        }
    }

    DebugMsg1(( "@InStr()=>%s<\n", buffer ));

    return( NOT_ERROR );
}
Esempio n. 15
0
static ret_code GetNumber( char *string, int *pi, struct asm_tok tokenarray[] )
/*****************************************************************************/
{
    struct expr opndx;
    int i;
    int last;

    last = Tokenize( string, Token_Count+1, tokenarray, TOK_RESCAN );
    i = Token_Count+1;
    if( EvalOperand( &i, tokenarray, last, &opndx, EXPF_NOUNDEF ) == ERROR ) {
        return( ERROR );
    }
    /* v2.11: string constants are accepted ( although hardly useful ) */
    //if( opndx.kind != EXPR_CONST || opndx.quoted_string != NULL || tokenarray[i].token != T_FINAL ) {
    if( opndx.kind != EXPR_CONST || tokenarray[i].token != T_FINAL ) {
        return( EmitErr( SYNTAX_ERROR_EX, string ) );
    }
    *pi = opndx.value;
    return( NOT_ERROR );
}
Esempio n. 16
0
static direct_idx SetSegmentClass( struct asym *seg, const char *classname )
/**************************************************************************/
{
    direct_idx          classidx;

    classidx = FindLnameIdx( classname );
    if( classidx == LNAME_NULL ) {
        classidx = InsertClassLname( classname );
        if( classidx == LNAME_NULL ) {
            return( ERROR );
        }
    }
    /* default class name index is 1, which is the NULL class name */
    if ( ((struct dsym *)seg)->e.seginfo->class_name_idx == 1 )
        ((struct dsym *)seg)->e.seginfo->class_name_idx = classidx;
    else if ( ((struct dsym *)seg)->e.seginfo->class_name_idx != classidx ) {
        EmitErr( SEGDEF_CHANGED, seg->name, MsgGetEx( TXT_CLASS ) );
        return( ERROR );
    }
    return( classidx );
}
Esempio n. 17
0
File: input.c Progetto: JWasm/JWasm
/* read one line from current source file.
 * returns NULL if EOF has been detected and no char stored in buffer
 * v2.08: 00 in the stream no longer causes an exit. Hence if the
 * char occurs in the comment part, everything is ok.
 */
static char *my_fgets( char *buffer, int max, FILE *fp )
/******************************************************/
{
    char        *ptr = buffer;
    char        *last = buffer + max;
    int         c;

    c = getc( fp );
    while( ptr < last ) {
        switch ( c ) {
        case '\r':
            break; /* don't store CR */
        case '\n':
            /* fall through */
        //case '\0': /* v2.08: */
#ifdef DEBUG_OUT
            if ( Parse_Pass == PASS_1 )
                cntflines++;
#endif
            *ptr = NULLC;
            return( buffer );
#if DETECTCTRLZ
        case 0x1a:
            /* since source files are opened in binary mode, ctrl-z
             * handling must be done here.
             */
            /* no break */
#endif
        case EOF:
            *ptr = NULLC;
            return( ptr > buffer ? buffer : NULL );
        default:
            *ptr++ = c;
        }
        c = getc( fp );
    }
    EmitErr( LINE_TOO_LONG );
    *(ptr-1) = NULLC;
    return( buffer );
}
Esempio n. 18
0
ret_code PublicDirective( int i, struct asm_tok tokenarray[] )
/************************************************************/
{
#if MANGLERSUPP
    char                *mangle_type = NULL;
#endif
    char                *token;
    struct asym         *sym;
    //struct dsym       *dir;
    char                skipitem;
    enum lang_type      langtype;

    DebugMsg1(("PublicDirective(%u) enter\n", i));
    i++; /* skip PUBLIC directive */
#if MANGLERSUPP
    mangle_type = Check4Mangler( &i, tokenarray );
#endif
    do {

        /* read the optional language type */
        langtype = ModuleInfo.langtype;
        GetLangType( &i, tokenarray, &langtype );

        if ( tokenarray[i].token != T_ID ) {
            return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
        }
        /* get the symbol name */
        token = tokenarray[i++].string_ptr;

        DebugMsg1(("PublicDirective: sym=%s\n", token ));

        /* Add the public name */
        sym = SymSearch( token );
        if ( Parse_Pass == PASS_1 ) {
            if ( sym == NULL ) {
                if ( sym = SymCreate( token ) ) {
                    sym_add_table( &SymTables[TAB_UNDEF], (struct dsym *)sym );
                    DebugMsg1(("PublicDirective(%s): new symbol\n", sym->name ));
                } else
                    return( ERROR ); /* name was too long */
            }
            skipitem = FALSE;
        } else {
            if ( sym == NULL || sym->state == SYM_UNDEFINED ) {
                EmitErr( SYMBOL_NOT_DEFINED, token );
                //return( ERROR ); /* v2.04: dont exit */
            }
        }
        if ( sym ) {
            switch ( sym->state ) {
            case SYM_UNDEFINED:
                break;
            case SYM_INTERNAL:
                if ( sym->scoped == TRUE ) {
                    EmitErr( CANNOT_DECLARE_SCOPED_CODE_LABEL_AS_PUBLIC, sym->name );
                    skipitem = TRUE;
                    //return( ERROR );
                }
                break;
            case SYM_EXTERNAL:
                if ( sym->iscomm == TRUE ) {
                    EmitErr( CANNOT_DEFINE_AS_PUBLIC_OR_EXTERNAL, sym->name );
                    skipitem = TRUE;
                    //return( ERROR );
                } else if ( sym->weak == FALSE ) {
                    /* for EXTERNs, emit a different error msg */
                    EmitErr( SYMBOL_REDEFINITION, sym->name );
                    skipitem = TRUE;
                    //return( ERROR );
                }
                break;
            default:
                EmitErr( CANNOT_DEFINE_AS_PUBLIC_OR_EXTERNAL, sym->name );
                skipitem = TRUE;
                //return( ERROR );
            }
            if( Parse_Pass == PASS_1 && skipitem == FALSE ) {
                if ( sym->ispublic == FALSE ) {
                    sym->ispublic = TRUE;
                    AddPublicData( sym ); /* put it into the public table */
                }
                SetMangler( sym, langtype, mangle_type );
            }
        }

        if ( tokenarray[i].token != T_FINAL )
            if ( tokenarray[i].token == T_COMMA ) {
                if ( (i + 1) < Token_Count )
                    i++;
            } else {
                return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos ) );
            }

    } while ( i < Token_Count );

    return( NOT_ERROR );
}
Esempio n. 19
0
/* .[NO|X]LIST, .[NO|X]CREF, .LISTALL, 
 * .[NO]LISTIF, .[LF|SF|TF]COND,
 * PAGE, TITLE, SUBTITLE, SUBTTL directives
 */
ret_code ListingDirective( int i, struct asm_tok tokenarray[] )
/*************************************************************/
{
    int directive = tokenarray[i].tokval;
    i++;

    switch ( directive ) {
    case T_DOT_LIST:
        if ( CurrFile[LST] )
            ModuleInfo.list = TRUE;
        break;
    case T_DOT_CREF:
        ModuleInfo.cref = TRUE;
        break;
    case T_DOT_NOLIST:
    case T_DOT_XLIST:
        ModuleInfo.list = FALSE;
        break;
    case T_DOT_NOCREF:
    case T_DOT_XCREF:
        if ( i == Token_Count ) {
            ModuleInfo.cref = FALSE;
            break;
        }
        do {
            struct asym *sym;
            if ( tokenarray[i].token != T_ID ) {
                return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos ) );
            }
            /* the name may be a forward reference. In this case it will
             * be created here.
             * v2.11: function call cannot fail. no need for checks.
             */
            sym = SymLookup( tokenarray[i].string_ptr );
            sym->list = FALSE;
            i++;
            if ( i < Token_Count ) {
                if ( tokenarray[i].token != T_COMMA )
                    return( EmitErr( EXPECTING_COMMA, tokenarray[i].tokpos ) );

                /* if there's nothing after the comma, don't increment */
                if ( i < ( Token_Count - 1 ) )
                    i++;
            }
        } while ( i < Token_Count );
        break;
    case T_DOT_LISTALL: /* list false conditionals and generated code */
        if ( CurrFile[LST] )
            ModuleInfo.list = TRUE;
        ModuleInfo.list_generated_code = TRUE;
        /* fall through */
    case T_DOT_LISTIF:
    case T_DOT_LFCOND: /* .LFCOND is synonym for .LISTIF */
        ModuleInfo.listif = TRUE;
        break;
    case T_DOT_NOLISTIF:
    case T_DOT_SFCOND: /* .SFCOND is synonym for .NOLISTIF */
        ModuleInfo.listif = FALSE;
        break;
    case T_DOT_TFCOND: /* .TFCOND toggles .LFCOND, .SFCOND */
        ModuleInfo.listif = !ModuleInfo.listif;
        break;
    case T_PAGE:
    default: /* TITLE, SUBTITLE, SUBTTL */
        /* tiny checks to ensure that these directives
         aren't used as code labels or struct fields */
        if ( tokenarray[i].token == T_COLON )
            break;
        /* this isn't really Masm-compatible, but ensures we don't get
         * struct fields with names page, title, subtitle, subttl.
         */
        if( CurrStruct ) {
            return( EmitError( STATEMENT_NOT_ALLOWED_INSIDE_STRUCTURE_DEFINITION ) );
        }
        if ( Parse_Pass == PASS_1 )
            EmitWarn( 4, DIRECTIVE_IGNORED, tokenarray[i-1].string_ptr );
        while ( tokenarray[i].token != T_FINAL) i++;
    }

    if ( tokenarray[i].token != T_FINAL ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
    }

    return( NOT_ERROR );
}
Esempio n. 20
0
ret_code ExternDirective( int i, struct asm_tok tokenarray[] )
/************************************************************/
{
    char                *token;
#if MANGLERSUPP
    char                *mangle_type = NULL;
#endif
    char                *altname;
    struct asym         *sym;
    enum lang_type      langtype;
    struct qualified_type ti;

    DebugMsg1(("ExternDirective(%u) enter\n", i));
    i++; /* skip EXT[E]RN token */
#if MANGLERSUPP
    mangle_type = Check4Mangler( &i, tokenarray );
#endif
    do {

        altname = NULL;

        /* get the symbol language type if present */
        langtype = ModuleInfo.langtype;
        GetLangType( &i, tokenarray, &langtype );

        /* get the symbol name */
        if( tokenarray[i].token != T_ID ) {
            return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
        }
        token = tokenarray[i++].string_ptr;

        /* go past the optional alternative name (weak ext, default resolution) */
        if( tokenarray[i].token == T_OP_BRACKET ) {
            i++;
            if ( tokenarray[i].token != T_ID ) {
                return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
            }
            altname = tokenarray[i].string_ptr;
            i++;
            if( tokenarray[i].token != T_CL_BRACKET ) {
                return( EmitErr( EXPECTED, ")" ) );
            }
            i++;
        }

        /* go past the colon */
        if( tokenarray[i].token != T_COLON ) {
            return( EmitError( COLON_EXPECTED ) );
        }
        i++;
        sym = SymSearch( token );

        ti.mem_type = MT_EMPTY;
        ti.size = 0;
        ti.is_ptr = 0;
        ti.is_far = FALSE;
        ti.ptr_memtype = MT_EMPTY;
        ti.symtype = NULL;
        ti.Ofssize = ModuleInfo.Ofssize;

        if ( tokenarray[i].token == T_ID && ( 0 == _stricmp( tokenarray[i].string_ptr, "ABS" ) ) ) {
            //ti.mem_type = MT_ABS;
            i++;
        } else if ( tokenarray[i].token == T_DIRECTIVE && tokenarray[i].tokval == T_PROTO ) {
            /* dont scan this line further */
            /* CreateProto() will define a SYM_EXTERNAL */
            sym = CreateProto( i + 1, tokenarray, token, langtype );
            DebugMsg1(("ExternDirective(%s): CreateProto()=%X\n", token, sym));
            if ( sym == NULL )
                return( ERROR );
            if ( sym->state == SYM_EXTERNAL ) {
                sym->weak = FALSE;
                return( HandleAltname( altname, sym ) );
            } else {
                /* unlike EXTERNDEF, EXTERN doesn't allow a PROC for the same name */
                return( EmitErr( SYMBOL_REDEFINITION, sym->name ) );
            }
        } else if ( tokenarray[i].token != T_FINAL && tokenarray[i].token != T_COMMA ) {
            if ( GetQualifiedType( &i, tokenarray, &ti ) == ERROR )
                return( ERROR );
        }

        DebugMsg1(("ExternDirective(%s): mem_type=%Xh\n", token, ti.mem_type ));

        if( sym == NULL || sym->state == SYM_UNDEFINED ) {
            /* v2.04: emit the error at the PUBLIC directive */
            //if ( sym && sym->public == TRUE ) {
            //    EmitErr( CANNOT_DEFINE_AS_PUBLIC_OR_EXTERNAL, sym->name );
            //    return( ERROR );
            //}
            if(( sym = MakeExtern( token, ti.mem_type,
                                  ti.mem_type == MT_TYPE ? ti.symtype : NULL, sym,
                                  ti.is_ptr ? ModuleInfo.Ofssize : ti.Ofssize )) == NULL )
                return( ERROR );

            /* v2.05: added to accept type prototypes */
            if ( ti.is_ptr == 0 && ti.symtype && ti.symtype->isproc ) {
                CreateProc( sym, NULL, SYM_EXTERNAL );
                sym->weak = FALSE; /* v2.09: reset the weak bit that has been set inside CreateProc() */
                CopyPrototype( (struct dsym *)sym, (struct dsym *)ti.symtype );
                ti.mem_type = ti.symtype->mem_type;
                ti.symtype = NULL;
                DebugMsg1(("ExternDirective(%s): prototype copied, memtype=%X\n", token, ti.mem_type ));
            }

        } else {
#if MASM_EXTCOND
            /* allow internal AND external definitions for equates */
            //if ( sym->state == SYM_INTERNAL && sym->mem_type == MT_ABS )
            if ( sym->state == SYM_INTERNAL && sym->mem_type == MT_EMPTY )
                ;
            else
#endif
            if ( sym->state != SYM_EXTERNAL ) {
                DebugMsg(("ExternDirective: symbol %s redefinition, state=%u\n", token, sym->state ));
                return( EmitErr( SYMBOL_REDEFINITION, token ) );
            }
            /* v2.05: added to accept type prototypes */
            if ( ti.is_ptr == 0 && ti.symtype && ti.symtype->isproc ) {
                ti.mem_type = ti.symtype->mem_type;
                ti.symtype = NULL;
            }

            if( sym->mem_type != ti.mem_type ||
               sym->is_ptr != ti.is_ptr ||
               sym->isfar != ti.is_far ||
               ( sym->is_ptr && sym->ptr_memtype != ti.ptr_memtype ) ||
               ((sym->mem_type == MT_TYPE) ? sym->type : sym->target_type) != ti.symtype ||
               ( langtype != LANG_NONE && sym->langtype != LANG_NONE && sym->langtype != langtype )) {
                DebugMsg(("ExternDirective: memtype:%X-%X ptr=%X-%X far=%X-%X ptr_memtype=%X-%X lang=%u-%u\n",
                          sym->mem_type, ti.mem_type,
                          sym->is_ptr, ti.is_ptr,
                          sym->isfar, ti.is_far,
                          sym->ptr_memtype, ti.ptr_memtype,
                          sym->langtype, langtype
                         ));
                return( EmitErr( SYMBOL_TYPE_CONFLICT, token ) );
            }
        }

        sym->isdefined = TRUE;
        sym->Ofssize = ti.Ofssize;

        if ( ti.is_ptr == 0 && ti.Ofssize != ModuleInfo.Ofssize ) {
            sym->seg_ofssize = ti.Ofssize;
            if ( sym->segment && ((struct dsym *)sym->segment)->e.seginfo->Ofssize != sym->seg_ofssize )
                sym->segment = NULL;
        }

        sym->mem_type = ti.mem_type;
        sym->is_ptr = ti.is_ptr;
        sym->isfar = ti.is_far;
        sym->ptr_memtype = ti.ptr_memtype;
        if ( ti.mem_type == MT_TYPE )
            sym->type = ti.symtype;
        else
            sym->target_type = ti.symtype;

        HandleAltname( altname, sym );

        SetMangler( sym, langtype, mangle_type );

        if ( tokenarray[i].token != T_FINAL )
            if ( tokenarray[i].token == T_COMMA &&  ( (i + 1) < Token_Count ) ) {
                i++;
            } else {
                return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
            }
    }  while ( i < Token_Count );

    return( NOT_ERROR );
}
Esempio n. 21
0
ret_code CommDirective( int i, struct asm_tok tokenarray[] )
/**********************************************************/
{
    char            *token;
#if MANGLERSUPP
    char            *mangle_type = NULL;
#endif
    bool            isfar;
    //int             distance;
    int             tmp;
    uint_32         size;  /* v2.12: changed from 'int' to 'uint_32' */
    uint_32         count; /* v2.12: changed from 'int' to 'uint_32' */
    struct asym     *sym;
    struct expr     opndx;
    enum lang_type  langtype;

    DebugMsg1(("CommDirective(%u) enter\n", i));
    i++; /* skip COMM token */
    for( ; i < Token_Count; i++ ) {
#if MANGLERSUPP
        mangle_type = Check4Mangler( &i, tokenarray );
#endif
        /* get the symbol language type if present */
        langtype = ModuleInfo.langtype;
        GetLangType( &i, tokenarray, &langtype );

        /* get the -optional- distance ( near or far ) */
        isfar = FALSE;
        if ( tokenarray[i].token == T_STYPE )
            switch ( tokenarray[i].tokval ) {
            case T_FAR:
            case T_FAR16:
            case T_FAR32:
                if ( ModuleInfo.model == MODEL_FLAT ) {
                    EmitError( FAR_NOT_ALLOWED_IN_FLAT_MODEL_COMM_VARIABLES );
                } else
                    isfar = TRUE;
                /* no break */
            case T_NEAR:
            case T_NEAR16:
            case T_NEAR32:
                i++;
            }

        /* v2.08: ensure token is a valid id */
        if( tokenarray[i].token != T_ID ) {
            return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
        }
        /* get the symbol name */
        token = tokenarray[i++].string_ptr;

        /* go past the colon */
        if( tokenarray[i].token != T_COLON ) {
            return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
        }
        i++;
        /* the evaluator cannot handle a ':' so scan for one first */
        for ( tmp = i; tmp < Token_Count;tmp++ )
            if ( tokenarray[tmp].token == T_COLON )
                break;
        /* v2.10: expression evaluator isn't to accept forward references */
        //if ( EvalOperand( &i, tokenarray, tmp, &opndx, 0 ) == ERROR )
        if ( EvalOperand( &i, tokenarray, tmp, &opndx, EXPF_NOUNDEF ) == ERROR )
            return( ERROR );

        /* v2.03: a string constant is accepted by Masm */
        /* v2.11: don't accept NEAR or FAR */
        /* v2.12: check for too large value added */
        //if ( opndx.kind != EXPR_CONST || opndx.string != NULL ) {
        if ( opndx.kind != EXPR_CONST )
            EmitError( CONSTANT_EXPECTED );
        else if ( ( opndx.mem_type & MT_SPECIAL_MASK) == MT_ADDRESS )
            EmitErr( INVALID_TYPE_FOR_DATA_DECLARATION, token );
        else if ( opndx.hvalue != 0 && opndx.hvalue != -1 )
            EmitConstError( &opndx );
        else if ( opndx.uvalue == 0 )
            EmitError( POSITIVE_VALUE_EXPECTED );

        size = opndx.uvalue;

        count = 1;
        if( tokenarray[i].token == T_COLON ) {
            i++;
            /* get optional count argument */
            /* v2.10: expression evaluator isn't to accept forward references */
            //if ( EvalOperand( &i, tokenarray, Token_Count, &opndx, 0 ) == ERROR )
            if ( EvalOperand( &i, tokenarray, Token_Count, &opndx, EXPF_NOUNDEF ) == ERROR )
                return( ERROR );

            /* v2.03: a string constant is acceptable! */
            /* v2.12: check for too large value added */
            //if ( opndx.kind != EXPR_CONST || opndx.string != NULL ) {
            if ( opndx.kind != EXPR_CONST )
                EmitError( CONSTANT_EXPECTED );
            else if ( opndx.hvalue != 0 && opndx.hvalue != -1 )
                EmitConstError( &opndx );
            else if ( opndx.uvalue == 0 )
                EmitError( POSITIVE_VALUE_EXPECTED );

            count = opndx.uvalue;
        }

        sym = SymSearch( token );
        if( sym == NULL || sym->state == SYM_UNDEFINED ) {
            sym = MakeComm( token, sym, size, count, isfar );
            if ( sym == NULL )
                return( ERROR );
        } else if ( sym->state != SYM_EXTERNAL || sym->iscomm != TRUE ) {
            return( EmitErr( SYMBOL_REDEFINITION, sym->name ) );
        } else {
            tmp = sym->total_size / sym->total_length;
            if( count != sym->total_length || size != tmp ) {
                return( EmitErr( NON_BENIGN_XXX_REDEFINITION, szCOMM, sym->name ) );
            }
        }
        sym->isdefined = TRUE;
        SetMangler( sym, langtype, mangle_type );

        if ( tokenarray[i].token != T_FINAL && tokenarray[i].token != T_COMMA ) {
            return( EmitErr( EXPECTING_COMMA, tokenarray[i].tokpos ) );
        }
    }
    return( NOT_ERROR );
}
Esempio n. 22
0
static ret_code DoPatch( struct asym *sym, struct fixup *fixup )
/**************************************************************/
{
    long                disp;
    long                max_disp;
    unsigned            size;
    struct dsym         *seg;
#if LABELOPT
    struct asym         *sym2;
    struct fixup        *fixup2;
#endif

    /* all relative fixups should occure only at first pass and they signal forward references
     * they must be removed after patching or skiped ( next processed as normal fixup )
     */

    DebugMsg(("DoPatch(%u, %s): fixup sym=%s type=%u ofs=%" FX32 "h loc=%" FX32 "h opt=%u def_seg=%s\n",
              Parse_Pass + 1, sym->name,
              fixup->sym ? fixup->sym->name : "NULL",
              fixup->type,
              fixup->offset,
              fixup->location,
              fixup->option,
              fixup->def_seg ? fixup->def_seg->sym.name : "NULL" ));
    seg = GetSegm( sym );
    if( seg == NULL || fixup->def_seg != seg ) {
        /* if fixup location is in another segment, backpatch is possible, but
         * complicated and it's a pretty rare case, so nothing's done.
         */
        DebugMsg(("DoPatch: skipped due to seg incompat: %s - %s\n",
                  fixup->def_seg ? fixup->def_seg->sym.name : "NULL",
                  seg ? seg->sym.name : "NULL" ));
        SkipFixup();
        return( NOT_ERROR );
    }

    if( Parse_Pass == PASS_1 ) {
        if( sym->mem_type == MT_FAR && fixup->option == OPTJ_CALL ) {
            /* convert near call to push cs + near call,
             * (only at first pass) */
            DebugMsg(("DoPatch: Phase error! caused by far call optimization\n"));
            ModuleInfo.PhaseError = TRUE;
            sym->offset++;  /* a PUSH CS will be added */
            /* todo: insert LABELOPT block here */
            OutputByte( 0 ); /* it's pass one, nothing is written */
            FreeFixup( fixup );
            return( NOT_ERROR );
            //} else if( sym->mem_type == MT_NEAR ) {
        } else {
            /* forward reference, only at first pass */
            switch( fixup->type ) {
            case FIX_RELOFF32:
            case FIX_RELOFF16:
                FreeFixup( fixup );
                DebugMsg(("DoPatch: FIX_RELOFF32/FIX_RELOFF16, return\n"));
                return( NOT_ERROR );
            case FIX_OFF8:  /* push <forward reference> */
                if ( fixup->option == OPTJ_PUSH ) {
                    size = 1;    /* size increases from 2 to 3/5 */
                    DebugMsg(("DoPatch: FIX_OFF8\n"));
                    goto patch;
                }
            }
        }
    }
    size = 0;
    switch( fixup->type ) {
    case FIX_RELOFF32:
        size = 2; /* will be 4 finally */
    /* fall through */
    case FIX_RELOFF16:
        size++; /* will be 2 finally */
    /* fall through */
    case FIX_RELOFF8:
        size++;
        /* calculate the displacement */
        // disp = fixup->offset + GetCurrOffset() - fixup->location - size;
        disp = fixup->offset + fixup->sym->offset - fixup->location - size - 1;
        max_disp = (1UL << ((size * 8)-1)) - 1;
        if( disp > max_disp || disp < (-max_disp-1) ) {
patch:
            DebugMsg(("DoPatch(%u): Phase error, disp=%X, fixup=%s(%X), loc=%X!\n", Parse_Pass + 1, disp, fixup->sym->name, fixup->sym->offset, fixup->location ));
            ModuleInfo.PhaseError = TRUE;
            /* ok, the standard case is: there's a forward jump which
             * was assumed to be SHORT, but it must be NEAR instead.
             */
            switch( size ) {
            case 1:
                size = 0;
                switch( fixup->option ) {
                case OPTJ_EXPLICIT:
#if 0 /* don't display the error at the destination line! */
                    sym->fixup = NULL;
                    DebugMsg(("DoPatch: jump out of range, disp=%d\n", disp ));
                    EmitErr( JUMP_OUT_OF_RANGE, disp - max_disp );
                    return( ERROR );
#else
                    return( NOT_ERROR ); /* nothing to do */
#endif
                case OPTJ_EXTEND: /* Jxx for 8086 */
                    size++;       /* will be 3/5 finally */
                /* fall through */
                case OPTJ_JXX: /* Jxx for 386 */
                    size++;
                /* fall through */
                default: /* normal JMP (and PUSH) */
                    // if( CodeInfo->Ofssize ) /* v1.96: don't use CodeInfo here! */
                    if( seg->e.seginfo->Ofssize )
                        size += 2; /* NEAR32 instead of NEAR16 */
                    size++;
#if LABELOPT
                    /* v2.04: if there's an ORG between src and dst, skip
                     * the optimization!
                     */
                    if ( Parse_Pass == PASS_1 ) {
                        for ( fixup2 = seg->e.seginfo->FixupListHead; fixup2; fixup2 = fixup2->nextrlc ) {
                            if ( fixup2->orgoccured ) {
                                DebugMsg(("DoPatch: ORG/ALIGN detected, optimization canceled\n" ));
                                return( NOT_ERROR );
                            }
                            /* do this check after the check for ORG! */
                            if ( fixup2->location <= fixup->location )
                                break;
                        }
                    }
                    /* scan the segment's label list and adjust all labels
                     * which are between the fixup loc and the current sym.
                     * ( PROCs are NOT contained in this list because they
                     * use the <next>-field of dsym already!)
                     */
                    for ( sym2 = seg->e.seginfo->labels; sym2; sym2 = (struct asym *)((struct dsym *)sym2)->next ) {
                        //if ( sym2 == sym )
                        //    continue;
                        /* v2.0: location is at least 1 byte too low, so
                         * use the "<=" operator instead of "<"!
                         */
                        //if ( sym2->offset < fixup->location )
                        if ( sym2->offset <= fixup->location )
                            break;
                        sym2->offset += size;
                        DebugMsg(("DoPatch(loc=%" FX32 "): sym %s, offset changed %" FX32 " -> %" FX32 "\n", fixup->location, sym2->name, sym2->offset - size, sym2->offset));
                    }
                    /* v2.03: also adjust fixup locations located between the
                     * label reference and the label. This should reduce the
                     * number of passes to 2 for not too complex sources.
                     */
                    if ( Parse_Pass == PASS_1 ) /* v2.04: added, just to be safe */
                        for ( fixup2 = seg->e.seginfo->FixupListHead; fixup2; fixup2 = fixup2->nextrlc ) {
                            if ( fixup2->sym == sym )
                                continue;
                            if ( fixup2->location <= fixup->location )
                                break;
                            fixup2->location += size;
                            DebugMsg(("for sym=%s fixup loc %" FX32 " changed to %" FX32 "\n", fixup2->sym->name, fixup2->location - size, fixup2->location ));
                        }
#else
                    DebugMsg(("DoPatch: sym %s, offset changed %" FX32 " -> %" FX32 "\n", sym->name, sym->offset, sym->offset + size));
                    sym->offset += size;
#endif
                    /*  it doesn't matter what's actually "written" */
                    for ( ; size; size-- )
                        OutputByte( 0xCC );
                    break;
                }
                break;
            case 2:
            case 4:
                DebugMsg(("DoPatch: jump out of range, disp=%d\n", disp ));
                EmitWarn( 4, JUMP_OUT_OF_RANGE, disp - max_disp );
                break;
            }
        }
#ifdef DEBUG_OUT
        else
            DebugMsg(("DoPatch, loc=%" FX32 ": displacement still short: %Xh\n", fixup->location, disp ));
#endif
        /* v2.04: fixme: is it ok to remove the fixup?
         * it might still be needed in a later backpatch.
         */
        FreeFixup( fixup );
        break;
    default:
        DebugMsg(("DoPatch: default branch, unhandled fixup type=%u\n", fixup->type ));
        SkipFixup();
        break;
    }
    return( NOT_ERROR );
}
Esempio n. 23
0
static ret_code HandleAltname( char *altname, struct asym *sym )
/**************************************************************/
{
    struct asym *symalt;

    if ( altname && sym->state == SYM_EXTERNAL ) {

        symalt = SymSearch( altname );

        /* altname symbol changed? */
        if ( sym->altname && sym->altname != symalt ) {
            return( EmitErr( SYMBOL_REDEFINITION, sym->name ) );
        }

        if ( Parse_Pass > PASS_1 ) {
            if ( symalt->state == SYM_UNDEFINED ) {
                EmitErr( SYMBOL_NOT_DEFINED, altname );
            } else if (symalt->state != SYM_INTERNAL && symalt->state != SYM_EXTERNAL ) {
                EmitErr( SYMBOL_TYPE_CONFLICT, altname );
            } else {
#if COFF_SUPPORT || ELF_SUPPORT
                if ( symalt->state == SYM_INTERNAL && symalt->ispublic == FALSE )
                    if ( Options.output_format == OFORMAT_COFF
#if ELF_SUPPORT
                        || Options.output_format == OFORMAT_ELF
#endif
                       ) {
                        EmitErr( MUST_BE_PUBLIC_OR_EXTERNAL, altname );
                    }
#endif
                if ( sym->mem_type != symalt->mem_type )
                    EmitErr( SYMBOL_TYPE_CONFLICT, altname );
            }
        } else {

            if ( symalt ) {
                DebugMsg(("HandleAltname: symbol '%s' found, state=%u\n", altname, symalt->state ));
                if ( symalt->state != SYM_INTERNAL &&
                    symalt->state != SYM_EXTERNAL &&
                    symalt->state != SYM_UNDEFINED ) {
                    return( EmitErr( SYMBOL_TYPE_CONFLICT, altname ) );
                }
            } else {
                symalt = SymCreate( altname );
                sym_add_table( &SymTables[TAB_UNDEF], (struct dsym *)symalt );
            }
            /* make sure the alt symbol becomes strong if it is an external
             * v2.11: don't do this for OMF ( maybe neither for COFF/ELF? )
             */
            if ( Options.output_format != OFORMAT_OMF )
                symalt->used = TRUE;
            /* symbol inserted in the "weak external" queue?
             * currently needed for OMF only.
             */
            if ( sym->altname == NULL ) {
                sym->altname = symalt;
#if 0 /* v2.11: removed. Member nextext wasn't free to use */
                DebugMsg1(("HandleAltname: symbol '%s' added to AltQueue\n", sym->name ));
                ((struct dsym *)sym)->nextext = NULL;
                if ( ModuleInfo.g.AltQueue.head == NULL )
                    ModuleInfo.g.AltQueue.head = ModuleInfo.g.AltQueue.tail = (struct dsym *)sym;
                else {
                    ((struct dsym *)ModuleInfo.g.AltQueue.tail)->nextext = (struct dsym *)sym;
                    ModuleInfo.g.AltQueue.tail = (struct dsym *)sym;
                }
#endif
            }
        }
    }
    return( NOT_ERROR );
}
Esempio n. 24
0
ret_code ExterndefDirective( int i, struct asm_tok tokenarray[] )
/***************************************************************/
{
    char                *token;
#if MANGLERSUPP
    char                *mangle_type = NULL;
#endif
    struct asym         *sym;
    enum lang_type      langtype;
    char isnew;
    struct qualified_type ti;

    DebugMsg1(("ExterndefDirective(%u) enter\n", i));

    i++; /* skip EXTERNDEF token */
#if MANGLERSUPP
    mangle_type = Check4Mangler( &i, tokenarray );
#endif
    do {

        ti.Ofssize = ModuleInfo.Ofssize;

        /* get the symbol language type if present */
        langtype = ModuleInfo.langtype;
        GetLangType( &i, tokenarray, &langtype );

        /* get the symbol name */
        if( tokenarray[i].token != T_ID ) {
            return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
        }
        token = tokenarray[i++].string_ptr;

        /* go past the colon */
        if( tokenarray[i].token != T_COLON ) {
            return( EmitError( COLON_EXPECTED ) );
        }
        i++;
        sym = SymSearch( token );

        //typetoken = tokenarray[i].string_ptr;
        ti.mem_type = MT_EMPTY;
        ti.size = 0;
        ti.is_ptr = 0;
        ti.is_far = FALSE;
        ti.ptr_memtype = MT_EMPTY;
        ti.symtype = NULL;
        ti.Ofssize = ModuleInfo.Ofssize;

        if ( tokenarray[i].token == T_ID && ( 0 == _stricmp( tokenarray[i].string_ptr, "ABS" ) ) ) {
            /* v2.07: MT_ABS is obsolete */
            //ti.mem_type = MT_ABS;
            i++;
        } else if ( tokenarray[i].token == T_DIRECTIVE && tokenarray[i].tokval == T_PROTO ) {
            /* dont scan this line further!
             * CreateProto() will either define a SYM_EXTERNAL or fail
             * if there's a syntax error or symbol redefinition.
             */
            sym = CreateProto( i + 1, tokenarray, token, langtype );
#if 0 /* global queue is obsolete */
            if ( sym && sym->isglobal == FALSE ) {
                sym->isglobal = TRUE;
                QAddItem( &ModuleInfo.g.GlobalQueue, sym );
            }
#endif
            return( sym ? NOT_ERROR : ERROR );
        } else if ( tokenarray[i].token != T_FINAL && tokenarray[i].token != T_COMMA ) {
            if ( GetQualifiedType( &i, tokenarray, &ti ) == ERROR )
                return( ERROR );
        }

        isnew = FALSE;
        if ( sym == NULL || sym->state == SYM_UNDEFINED ) {
            sym = CreateExternal( sym, token, TRUE );
            isnew = TRUE;
        }

        /* new symbol? */

        if ( isnew ) {
            DebugMsg1(("ExterndefDirective(%s): memtype=%X set, ofssize=%X\n", token, ti.mem_type, ti.Ofssize ));

            /* v2.05: added to accept type prototypes */
            if ( ti.is_ptr == 0 && ti.symtype && ti.symtype->isproc ) {
                CreateProc( sym, NULL, SYM_EXTERNAL );
                CopyPrototype( (struct dsym *)sym, (struct dsym *)ti.symtype );
                ti.mem_type = ti.symtype->mem_type;
                ti.symtype = NULL;
            }
            switch ( ti.mem_type ) {
            //case MT_ABS:
            case MT_EMPTY:
                /* v2.04: hack no longer necessary */
                //if ( sym->weak == TRUE )
                //    sym->equate = TRUE; /* allow redefinition by EQU, = */
                break;
            case MT_FAR:
                /* v2.04: don't inherit current segment for FAR externals
                 * if -Zg is set.
                 */
                if ( Options.masm_compat_gencode )
                    break; 
                /* fall through */
            default:
                //SetSymSegOfs( sym );
                sym->segment = &CurrSeg->sym;
            }
            sym->Ofssize = ti.Ofssize;

            if ( ti.is_ptr == 0 && ti.Ofssize != ModuleInfo.Ofssize ) {
                sym->seg_ofssize = ti.Ofssize;
                if ( sym->segment && ((struct dsym *)sym->segment)->e.seginfo->Ofssize != sym->seg_ofssize )
                    sym->segment = NULL;
            }

            sym->mem_type = ti.mem_type;
            sym->is_ptr = ti.is_ptr;
            sym->isfar = ti.is_far;
            sym->ptr_memtype = ti.ptr_memtype;
            if ( ti.mem_type == MT_TYPE )
                sym->type = ti.symtype;
            else
                sym->target_type = ti.symtype;

            /* v2.04: only set language if there was no previous definition */
            SetMangler( sym, langtype, mangle_type );

        } else if ( Parse_Pass == PASS_1 ) {

            /* v2.05: added to accept type prototypes */
            if ( ti.is_ptr == 0 && ti.symtype && ti.symtype->isproc ) {
                ti.mem_type = ti.symtype->mem_type;
                ti.symtype = NULL;
            }
            /* ensure that the type of the symbol won't change */

            if ( sym->mem_type != ti.mem_type ) {
                /* if the symbol is already defined (as SYM_INTERNAL), Masm
                 won't display an error. The other way, first externdef and
                 then the definition, will make Masm complain, however */
                DebugMsg(("ExterndefDirective: type conflict for %s. mem_types old-new: %X-%X\n", sym->name, sym->mem_type, ti.mem_type));
                EmitWarn( 1, SYMBOL_TYPE_CONFLICT, sym->name );
            } else if ( sym->mem_type == MT_TYPE && sym->type != ti.symtype ) {
                struct asym *sym2 = sym;
                /* skip alias types and compare the base types */
                DebugMsg(("ExterndefDirective(%s): types differ: %X (%s) - %X (%s)\n", sym->name, sym->type, sym->type->name, ti.symtype, ti.symtype->name));
                while ( sym2->type )
                    sym2 = sym2->type;
                while ( ti.symtype->type )
                    ti.symtype = ti.symtype->type;
                if ( sym2 != ti.symtype ) {
                    DebugMsg(("ExterndefDirective(%s): type conflict old-new: %X (%s) - %X (%s)\n", sym->name, sym2, sym2->name, ti.symtype, ti.symtype->name));
                    EmitWarn( 1, SYMBOL_TYPE_CONFLICT, sym->name );
                }
            }

            /* v2.04: emit a - weak - warning if language differs.
             * Masm doesn't warn.
             */
            if ( langtype != LANG_NONE && sym->langtype != langtype )
                EmitWarn( 3, LANGUAGE_ATTRIBUTE_CONFLICT, sym->name );
        }
        sym->isdefined = TRUE;

#if 0
        /* write a global entry if none has been written yet */
        if ( sym->state == SYM_EXTERNAL && sym->weak == FALSE )
            ;/* skip EXTERNDEF if a real EXTERN/COMM was done */
        else if ( sym->isglobal == FALSE ) {
            sym->isglobal = TRUE;
            DebugMsg1(("ExterndefDirective(%s): writing a global entry\n", sym->name));
            QAddItem( &ModuleInfo.g.GlobalQueue, sym );
        }
#else
        if ( sym->state == SYM_INTERNAL && sym->ispublic == FALSE ) {
            sym->ispublic = TRUE;
            AddPublicData( sym );
        }
#endif

        if ( tokenarray[i].token != T_FINAL )
            if ( tokenarray[i].token == T_COMMA ) {
                if ( (i + 1) < Token_Count )
                    i++;
            } else {
                return( EmitErr( EXPECTING_COMMA, tokenarray[i].tokpos ) );
            }

    } while ( i < Token_Count );

    return( NOT_ERROR );
}
Esempio n. 25
0
int main( int argc, char **argv )
/*******************************/
{
    char    *pEnv;
    int     numArgs = 0;
    int     numFiles = 0;
    int     rc = 0;
#if WILDCARDS
    long    fh; /* _findfirst/next/close() handle, must be long! */
    struct  _finddata_t finfo;
    char    drv[_MAX_DRIVE];
    char    dir[_MAX_DIR];
    char    fname[_MAX_PATH];
#endif

#if 0 //def DEBUG_OUT    /* DebugMsg() cannot be used that early */
    int i;
    for ( i = 1; i < argc; i++ ) {
        printf("argv[%u]=>%s<\n", i, argv[i] );
    }
#endif

    pEnv = getenv( "JWASM" );
    if ( pEnv == NULL )
        pEnv = "";
    argv[0] = pEnv;

#ifndef DEBUG_OUT
    signal(SIGSEGV, genfailure);
#endif

#if CATCHBREAK
    signal(SIGBREAK, genfailure);
#else
    signal(SIGTERM, genfailure);
#endif

    MsgInit();

    while ( 1 ) {
        if ( ParseCmdline( (const char **)argv, &numArgs ) == NULL )
            break;  /* exit if no source file name supplied */
        numFiles++;
        write_logo();
#if WILDCARDS
        if ((fh = _findfirst( Options.names[ASM], &finfo )) == -1 ) {
            DebugMsg(("main: _findfirst(%s) failed\n", Options.names[ASM] ));
            EmitErr( CANNOT_OPEN_FILE, Options.names[ASM], ErrnoStr() );
            break;
        }
        _splitpath( Options.names[ASM], drv, dir, NULL, NULL );
        DebugMsg(("main: _splitpath(%s): drv=\"%s\" dir=\"%s\"\n", Options.names[ASM], drv, dir ));
        do {
            _makepath( fname, drv, dir, finfo.name, NULL );
            DebugMsg(("main: _makepath(\"%s\", \"%s\", \"%s\")=\"%s\"\n", drv, dir, finfo.name, fname ));
            rc = AssembleModule( fname );  /* assemble 1 module */
        } while ( ( _findnext( fh, &finfo ) != -1 ) );
        _findclose( fh );
#else
        rc = AssembleModule( Options.names[ASM] );
#endif
    };
    CmdlineFini();
    if ( numArgs == 0 ) {
        write_logo();
        printf( MsgGetEx( MSG_USAGE ) );
    } else if ( numFiles == 0 )
        EmitError( NO_FILENAME_SPECIFIED );

    MsgFini();
    return( 1 - rc ); /* zero if no errors */
}
Esempio n. 26
0
/* handle .model directive
 * syntax: .MODEL <FLAT|TINY|SMALL...> [,<C|PASCAL|STDCALL...>][,<NEARSTACK|FARSTACK>][,<OS_DOS|OS_OS2>]
 * sets fields
 * - ModuleInfo.model
 * - ModuleInfo.language
 * - ModuleInfo.distance
 * - ModuleInfo.ostype
 * if model is FLAT, defines FLAT pseudo-group
 * set default segment names for code and data
 */
ret_code ModelDirective( int i, struct asm_tok tokenarray[] )
/***********************************************************/
{
    enum model_type model;
    enum lang_type language;
    enum dist_type distance;
    enum os_type ostype;
    int index;
    uint_8 init;
    uint_8 initv;

    DebugMsg1(("ModelDirective enter\n"));
    /* v2.03: it may occur that "code" is defined BEFORE the MODEL
     * directive (i.e. DB directives in AT-segments). For FASTPASS,
     * this may have caused errors because contents of the ModuleInfo
     * structure was saved before the .MODEL directive.
     */
    //if( Parse_Pass != PASS_1 ) {
    if( Parse_Pass != PASS_1 && ModuleInfo.model != MODEL_NONE ) {
        /* just set the model with SetModel() if pass is != 1.
         * This won't set the language ( which can be modified by
         * OPTION LANGUAGE directive ), but the language in ModuleInfo
         * isn't needed anymore once pass one is done.
         */
        SetModel();
        return( NOT_ERROR );
    }

    i++;
    if ( tokenarray[i].token == T_FINAL ) {
        EmitError( EXPECTED_MEMORY_MODEL );
        return( ERROR );
    }
    /* get the model argument */
    index = FindToken( tokenarray[i].string_ptr, ModelToken, sizeof( ModelToken )/sizeof( ModelToken[0] ) );
    if( index >= 0 ) {
        if( ModuleInfo.model != MODEL_NONE ) {
            EmitWarn( 2, MODEL_DECLARED_ALREADY );
            return( NOT_ERROR );
        }
        model = index + 1;
        i++;
    } else {
        EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr );
        return( ERROR );
    }

    /* get the optional arguments: language, stack distance, os */
    init = 0;
    while ( i < ( Token_Count - 1 ) && tokenarray[i].token == T_COMMA ) {
        i++;
        if ( tokenarray[i].token != T_COMMA ) {
            if ( GetLangType( &i, tokenarray, &language ) == NOT_ERROR ) {
                initv = INIT_LANG;
            } else {
                index = FindToken( tokenarray[i].string_ptr, ModelAttr, sizeof( ModelAttr )/sizeof( ModelAttr[0] ) );
                if ( index < 0 )
                    break;
                initv = ModelAttrValue[index].init;
                switch ( initv ) {
                case INIT_STACK:
                    if ( model == MODEL_FLAT ) {
                        EmitError( INVALID_MODEL_PARAM_FOR_FLAT );
                        return( ERROR );
                    }
                    distance = ModelAttrValue[index].value;
                    break;
                case INIT_OS:
                    ostype = ModelAttrValue[index].value;
                    break;
                }
                i++;
            }
            /* attribute set already? */
            if ( initv & init ) {
                i--;
                break;
            }
            init |= initv;
        }
    }
    /* everything parsed successfully? */
    if ( tokenarray[i].token != T_FINAL ) {
        EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos );
        return( ERROR );
    }

    if ( model == MODEL_FLAT ) {
        if ( ( ModuleInfo.curr_cpu & P_CPU_MASK) < P_386 ) {
            EmitError( INSTRUCTION_OR_REGISTER_NOT_ACCEPTED_IN_CURRENT_CPU_MODE );
            return( ERROR );
        }
        DefineFlatGroup();
    }

    ModuleInfo.model = model;
    if ( init & INIT_LANG ) {
        ModuleInfo.langtype = language;
#if AMD64_SUPPORT
        /* v2.03: set header and fastcall type to win64 if x64 is active.
         * This is rather hackish, but currently there's no other possibility
         * to enable the win64 ABI from the source.
         */
        if ( ( ModuleInfo.curr_cpu & P_CPU_MASK ) == P_64 )
            if ( language == LANG_FASTCALL &&
                model == MODEL_FLAT &&
                Options.output_format != OFORMAT_ELF ) {
                DebugMsg(("ModelDirective: FASTCALL type set to WIN64\n"));
                ModuleInfo.header_format = HFORMAT_WIN64;
                ModuleInfo.fctype = FCT_WIN64;
            }
#endif
    }
    if ( init & INIT_STACK )
        ModuleInfo.distance = distance;
    if ( init & INIT_OS )
        ModuleInfo.ostype = ostype;

    SetModelDefaultSegNames();
    SetModel();

    return( NOT_ERROR );
}
Esempio n. 27
0
ret_code AssumeDirective( int i, struct asm_tok tokenarray[] )
/************************************************************/
/* Handles ASSUME
 * syntax is :
 * - ASSUME
 * - ASSUME NOTHING
 * - ASSUME segregister : seglocation [, segregister : seglocation ]
 * - ASSUME dataregister : qualified type [, dataregister : qualified type ]
 * - ASSUME register : ERROR | NOTHING | FLAT
 */
{
    int             reg;
    int             j;
    int             size;
    uint_32         flags;
    struct assume_info *info;
    bool            segtable;
    struct qualified_type ti;

    DebugMsg1(( "AssumeDirective enter, pass=%u\n", Parse_Pass+1 ));

    for( i++; i < Token_Count; i++ ) {

        if( ( tokenarray[i].token == T_ID )
            && (0 == _stricmp( tokenarray[i].string_ptr, szNothing )) ) {
            AssumeInit();
            i++;
            break;
        }

        /*---- get the info ptr for the register ----*/

        info = NULL;
        if ( tokenarray[i].token == T_REG ) {
            reg = tokenarray[i].tokval;
            j = GetRegNo( reg );
            flags = GetValueSp( reg );
            if ( flags & OP_SR ) {
                info = &SegAssumeTable[j];
                segtable = TRUE;
            } else if ( flags & OP_R ) {
                info = &StdAssumeTable[j];
                segtable = FALSE;
            }
        }
        if ( info == NULL ) {
            EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr );
            return( ERROR );
        }

        if( ( ModuleInfo.curr_cpu & P_CPU_MASK ) < GetCpuSp( reg ) ) {
            EmitError( INSTRUCTION_OR_REGISTER_NOT_ACCEPTED_IN_CURRENT_CPU_MODE );
            return( ERROR );
        }

        i++; /* go past register */

        if( tokenarray[i].token != T_COLON ) {
            EmitError( COLON_EXPECTED );
            return( ERROR );
        }
        i++;

        if( tokenarray[i].token == T_FINAL ) {
            EmitError( SYNTAX_ERROR );
            return( ERROR );
        }

        /* check for ERROR and NOTHING */

        if( 0 == _stricmp( tokenarray[i].string_ptr, szError )) {
            if ( segtable ) {
                info->flat = FALSE;
                info->error = TRUE;
            } else
                info->error |= (( reg >= T_AH && reg <= T_BH ) ? RH_ERROR : ( flags & OP_R ));
            info->symbol = NULL;
            i++;
        } else if( 0 == _stricmp( tokenarray[i].string_ptr, szNothing )) {
            if ( segtable ) {
                info->flat = FALSE;
                info->error = FALSE;
            } else
                info->error &= ~(( reg >= T_AH && reg <= T_BH ) ? RH_ERROR : ( flags & OP_R ));
            info->symbol = NULL;
            i++;
        } else if ( segtable == FALSE ) {

            /* v2.05: changed to use new GetQualifiedType() function */
            ti.size = 0;
            ti.is_ptr = 0;
            ti.is_far = FALSE;
            ti.mem_type = MT_EMPTY;
            ti.ptr_memtype = MT_EMPTY;
            ti.symtype = NULL;
            ti.Ofssize = ModuleInfo.Ofssize;
            if ( GetQualifiedType( &i, tokenarray, &ti ) == ERROR )
                return( ERROR );

            /* v2.04: check size of argument! */
            size = OperandSize( flags, NULL );
            if ( ( ti.is_ptr == 0 && size != ti.size ) ||
                ( ti.is_ptr > 0 && size < CurrWordSize ) ) {
                EmitError( TYPE_IS_WRONG_SIZE_FOR_REGISTER );
                return( ERROR );
            }
            info->error &= ~(( reg >= T_AH && reg <= T_BH ) ? RH_ERROR : ( flags & OP_R ));
            if ( stdsym[j] == NULL ) {
                stdsym[j] = CreateTypeSymbol( NULL, "", FALSE );
                stdsym[j]->typekind = TYPE_TYPEDEF;
            }

            stdsym[j]->total_size = ti.size;
            stdsym[j]->mem_type   = ti.mem_type;
            stdsym[j]->is_ptr     = ti.is_ptr;
            stdsym[j]->isfar      = ti.is_far;
            stdsym[j]->Ofssize    = ti.Ofssize;
            stdsym[j]->ptr_memtype = ti.ptr_memtype; /* added v2.05 rc13 */
            if ( ti.mem_type == MT_TYPE )
                stdsym[j]->type = ti.symtype;
            else
                stdsym[j]->target_type = ti.symtype;

            info->symbol = stdsym[j];

        } else { /* segment register */
            struct expr opnd;

            /* v2.08: read expression with standard evaluator */
            if( EvalOperand( &i, tokenarray, Token_Count, &opnd, 0 ) == ERROR )
                return( ERROR );
            switch ( opnd.kind ) {
            case EXPR_ADDR:
                if ( opnd.sym == NULL || opnd.indirect == TRUE || opnd.value ) {
                    EmitError( SEGMENT_GROUP_OR_SEGREG_EXPECTED );
                    return( ERROR );
                } else if ( opnd.sym->state == SYM_UNDEFINED ) {
                    /* ensure that directive is rerun in pass 2
                     * so an error msg can be emitted.
                     */
                    FStoreLine(0);
                    info->symbol = opnd.sym;
                } else if ( ( opnd.sym->state == SYM_SEG || opnd.sym->state == SYM_GRP ) && opnd.instr == EMPTY ) {
                    info->symbol = opnd.sym;
                } else if ( opnd.instr == T_SEG ) {
                    info->symbol = opnd.sym->segment;
                } else {
                    EmitError( SEGMENT_GROUP_OR_SEGREG_EXPECTED );
                    return( ERROR );
                }
                info->flat = ( info->symbol == &ModuleInfo.flat_grp->sym );
                break;
            case EXPR_REG:
                if ( GetValueSp( opnd.base_reg->tokval ) & OP_SR ) {
                    info->symbol = SegAssumeTable[ GetRegNo( opnd.base_reg->tokval ) ].symbol;
                    info->flat = SegAssumeTable[ GetRegNo( opnd.base_reg->tokval ) ].flat;
                    break;
                }
            default:
                EmitError( SEGMENT_GROUP_OR_SEGREG_EXPECTED );
                return( ERROR );
            }
            info->error = FALSE;
        }

        /* comma expected */
        if( i < Token_Count && tokenarray[i].token != T_COMMA )
            break;
    }
    if ( i < Token_Count ) {
        EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos );
        return( ERROR );
    }
    return( NOT_ERROR );
}
Esempio n. 28
0
/* handle .model directive
 * syntax: .MODEL <FLAT|TINY|SMALL...> [,<C|PASCAL|STDCALL...>][,<NEARSTACK|FARSTACK>][,<OS_DOS|OS_OS2>]
 * sets fields
 * - ModuleInfo.model
 * - ModuleInfo.language
 * - ModuleInfo.distance
 * - ModuleInfo.ostype
 * if model is FLAT, defines FLAT pseudo-group
 * set default segment names for code and data
 */
ret_code ModelDirective( int i, struct asm_tok tokenarray[] )
/***********************************************************/
{
    enum model_type model;
    enum lang_type language;
    enum dist_type distance;
    enum os_type ostype;
    int index;
    uint_8 init;
    uint_8 initv;

    DebugMsg1(("ModelDirective enter\n"));
    /* v2.03: it may occur that "code" is defined BEFORE the MODEL
     * directive (i.e. DB directives in AT-segments). For FASTPASS,
     * this may have caused errors because contents of the ModuleInfo
     * structure was saved before the .MODEL directive.
     */
    //if( Parse_Pass != PASS_1 ) {
    if( Parse_Pass != PASS_1 && ModuleInfo.model != MODEL_NONE ) {
        /* just set the model with SetModel() if pass is != 1.
         * This won't set the language ( which can be modified by
         * OPTION LANGUAGE directive ), but the language in ModuleInfo
         * isn't needed anymore once pass one is done.
         */
        SetModel();
        return( NOT_ERROR );
    }

    i++;
    if ( tokenarray[i].token == T_FINAL ) {
        return( EmitError( EXPECTED_MEMORY_MODEL ) );
    }
    /* get the model argument */
    index = FindToken( tokenarray[i].string_ptr, ModelToken, sizeof( ModelToken )/sizeof( ModelToken[0] ) );
    if( index >= 0 ) {
        if( ModuleInfo.model != MODEL_NONE ) {
            //if ( Parse_Pass == PASS_1 ) /* not needed, this code runs in pass one only */
            EmitWarn( 2, MODEL_DECLARED_ALREADY );
        }
        model = index + 1; /* model is one-base ( 0 is MODEL_NONE ) */
        i++;
    } else {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
    }

    /* get the optional arguments: language, stack distance, os */
    init = 0;
    while ( i < ( Token_Count - 1 ) && tokenarray[i].token == T_COMMA ) {
        i++;
        if ( tokenarray[i].token != T_COMMA ) {
            if ( GetLangType( &i, tokenarray, &language ) == NOT_ERROR ) {
                initv = INIT_LANG;
            } else {
                index = FindToken( tokenarray[i].string_ptr, ModelAttr, sizeof( ModelAttr )/sizeof( ModelAttr[0] ) );
                if ( index < 0 )
                    break;
                initv = ModelAttrValue[index].init;
                switch ( initv ) {
                case INIT_STACK:
                    if ( model == MODEL_FLAT ) {
                        return( EmitError( INVALID_MODEL_PARAM_FOR_FLAT ) );
                    }
                    distance = ModelAttrValue[index].value;
                    break;
                case INIT_OS:
                    ostype = ModelAttrValue[index].value;
                    break;
                }
                i++;
            }
            /* attribute set already? */
            if ( initv & init ) {
                i--;
                break;
            }
            init |= initv;
        }
    }
    /* everything parsed successfully? */
    if ( tokenarray[i].token != T_FINAL ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos ) );
    }

    if ( model == MODEL_FLAT ) {
        if ( ( ModuleInfo.curr_cpu & P_CPU_MASK) < P_386 ) {
            return( EmitError( INSTRUCTION_OR_REGISTER_NOT_ACCEPTED_IN_CURRENT_CPU_MODE ) );
        }
#if AMD64_SUPPORT
        if ( ( ModuleInfo.curr_cpu & P_CPU_MASK ) >= P_64 ) /* cpu 64-bit? */
            switch ( Options.output_format ) {
            case OFORMAT_COFF: ModuleInfo.fmtopt = &coff64_fmtopt; break;
            case OFORMAT_ELF:  ModuleInfo.fmtopt = &elf64_fmtopt;  break;
            };
#endif
        /* v2.11: define FLAT symbol is to early here, because defOfssize isn't set yet */
        //DefineFlatGroup();
    }

    ModuleInfo.model = model;
    if ( init & INIT_LANG )
        ModuleInfo.langtype = language;
    if ( init & INIT_STACK )
        ModuleInfo.distance = distance;
    if ( init & INIT_OS )
        ModuleInfo.ostype = ostype;

    SetModelDefaultSegNames();
    SetModel();

    return( NOT_ERROR );
}
Esempio n. 29
0
ret_code SafeSEHDirective( int i, struct asm_tok tokenarray[] )
/*************************************************************/
{
    struct asym    *sym;
    struct qnode   *node;

    if ( Options.output_format != OFORMAT_COFF ) {
        if ( Parse_Pass == PASS_1)
            EmitWarn( 2, DIRECTIVE_IGNORED_WITHOUT_X, "coff" );
        return( NOT_ERROR );
    }
    if ( Options.safeseh == FALSE ) {
        if ( Parse_Pass == PASS_1)
            EmitWarn( 2, DIRECTIVE_IGNORED_WITHOUT_X, "safeseh" );
        return( NOT_ERROR );
    }
    i++;
    if ( tokenarray[i].token != T_ID ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
    }
    sym = SymSearch( tokenarray[i].string_ptr );

    /* make sure the argument is a true PROC */
    if ( sym == NULL || sym->state == SYM_UNDEFINED ) {
        if ( Parse_Pass != PASS_1 ) {
            return( EmitErr( SYMBOL_NOT_DEFINED, tokenarray[i].string_ptr ) );
        }
    } else if ( sym->isproc == FALSE ) {
        return( EmitErr( SAFESEH_ARGUMENT_MUST_BE_A_PROC, tokenarray[i].string_ptr ) );
    }

    if ( Parse_Pass == PASS_1 ) {
        if ( sym ) {
            for ( node = ModuleInfo.g.SafeSEHQueue.head; node; node = node->next )
                if ( node->elmt == sym )
                    break;
        } else {
            sym = SymCreate( tokenarray[i].string_ptr );
            node = NULL;
        }
        if ( node == NULL ) {
            sym->used = TRUE; /* make sure an external reference will become strong */
#if 0 /* v2.11: use QAddItem() */
            node = LclAlloc( sizeof( struct qnode ) );
            node->elmt = sym;
            node->next = NULL;
            if ( ModuleInfo.g.SafeSEHQueue.head == 0 )
                ModuleInfo.g.SafeSEHQueue.head = ModuleInfo.g.SafeSEHQueue.tail = node;
            else {
                ((struct qnode *)ModuleInfo.g.SafeSEHQueue.tail)->next = node;
                ModuleInfo.g.SafeSEHQueue.tail = node;
            }
#else
            QAddItem( &ModuleInfo.g.SafeSEHQueue, sym );
#endif
        }
    }
    i++;
    if ( tokenarray[i].token != T_FINAL ) {
        return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
    }

    return( NOT_ERROR );
}
Esempio n. 30
0
File: input.c Progetto: JWasm/JWasm
FILE *SearchFile( const char *path, bool queue )
/**********************************************/
{
    FILE        *file = NULL;
    struct src_item *fl;
    const char  *fn;
    bool        isabs;
    char        fullpath[FILENAME_MAX];

    DebugMsg1(("SearchFile(%s) enter\n", path ));

    //_splitpath( path, drive, dir, fname, ext );
    //DebugMsg1(("SearchFile(): drive=%s, dir=%s, fname=%s, ext=%s\n", drive, dir, fname, ext ));
    fn = GetFNamePart( path );

    /* if no absolute path is given, then search in the directory
     * of the current source file first!
     * v2.11: various changes because field fullpath has been removed.
     */

    isabs = ISABS( path );
    //if ( dir[0] != '\\' && dir[0] != '/' ) {
    if ( !isabs ) {
        for ( fl = src_stack; fl ; fl = fl->next ) {
            if ( fl->type == SIT_FILE ) {
                const char  *fn2;
                char        *src;
                //_splitpath( GetFName( fl->srcfile )->fname, drive2, dir2, NULL, NULL );
                //DebugMsg1(("SearchFile(): curr src=%s, split into drive=%s, dir=%s\n", GetFName( fl->srcfile)->fname, drive2, dir2 ));
                src = GetFName( fl->srcfile )->fname;
                fn2 = GetFNamePart( src );
                if ( fn2 != src ) {
                    int i = fn2 - src;
                    /* v2.10: if there's a directory part, add it to the directory part of the current file.
                     * fixme: check that both parts won't exceed FILENAME_MAX!
                     * fixme: 'path' is relative, but it may contain a drive letter!
                     */
                    memcpy( fullpath, src, i );
                    strcpy( fullpath + i, path );
                    if ( (file = fopen( fullpath, "rb" )) != NULL ) {
                        DebugMsg1(("SearchFile(): file found, fopen(%s)=%X\n", fullpath, file ));
                        path = fullpath;
                    }
#ifdef DEBUG_OUT
                    else
                        DebugMsg1(("SearchFile(): fopen(%s) failed\n", fullpath ));
#endif
                }
                break;
            }
        }
    }
    if ( file == NULL ) {
        fullpath[0] = NULLC;
        file = fopen( path, "rb" );
        DebugMsg1(("SearchFile(): fopen(%s)=%X\n", path, file ));

        /* if the file isn't found yet and include paths have been set,
         * and NO absolute path is given, then search include dirs
         */
        if( file == NULL && ModuleInfo.g.IncludePath != NULL && !isabs ) {
            if ( (file = open_file_in_include_path( path, fullpath )) != NULL ) {
                DebugMsg1(("SearchFile(): open_file_in_include_path(%s)=%X [%s]\n", path, file, fullpath ));
                path = fullpath;
            }
#ifdef DEBUG_OUT
            else
                DebugMsg1(("SearchFile(): open_file_in_include_path(%s)=NULL\n", path ));
#endif
        }
        if( file == NULL ) {
            EmitErr( CANNOT_OPEN_FILE, path, ErrnoStr() );
            return( NULL );
        }
    }
    /* is the file to be added to the file stack?
     * assembly files usually are, but binary files ( INCBIN ) aren't.
     */
    if ( queue ) {
        fl = PushSrcItem( SIT_FILE, file );
        fl->srcfile = AddFile( path );
        FileCur->string_ptr = GetFName( fl->srcfile )->fname;
#if FILESEQ
        if ( Options.line_numbers && Parse_Pass == PASS_1 )
            AddFileSeq( fl->srcfile );
#endif
    }
    return( file );
}