Esempio n. 1
0
int directive( int i, long direct )
/* Handle all directives */
{
    int         ret;

    /* no expansion on the following */
    switch( direct ) {
    case T_MASM:
        Options.mode &= ~MODE_IDEAL;
        return( NOT_ERROR );
    case T_IDEAL:
        Options.mode |= MODE_IDEAL;
        return( NOT_ERROR );
    case T_DOT_286C:
        direct = T_DOT_286;
    case T_DOT_8086:
    case T_DOT_186:
    case T_DOT_286:
    case T_DOT_286P:
    case T_DOT_386:
    case T_DOT_386P:
    case T_DOT_486:
    case T_DOT_486P:
    case T_DOT_586:
    case T_DOT_586P:
    case T_DOT_686:
    case T_DOT_686P:
    case T_DOT_8087:
    case T_DOT_287:
    case T_DOT_387:
    case T_DOT_NO87:
    case T_DOT_K3D:
    case T_DOT_MMX:
    case T_DOT_XMM:
    case T_DOT_XMM2:
    case T_DOT_XMM3:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        } else {
            ret = cpu_directive(direct);
            if( Parse_Pass != PASS_1 )
                ret = NOT_ERROR;
            return( ret );
        }
    case T_P286N:
        direct = T_P286;
    case T_P8086:
    case T_P186:
    case T_P286:
    case T_P286P:
    case T_P386:
    case T_P386P:
    case T_P486:
    case T_P486P:
    case T_P586:
    case T_P586P:
    case T_P686:
    case T_P686P:
    case T_P8087:
    case T_P287:
    case T_P387:
    case T_PK3D:
    case T_PMMX:
    case T_PXMM:
    case T_PXMM2:
    case T_PXMM3:
        ret = cpu_directive(direct);
        if( Parse_Pass != PASS_1 )
            ret = NOT_ERROR;
        return( ret );
    case T_DOT_DOSSEG:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_DOSSEG:
        Globals.dosseg = TRUE;
        return( NOT_ERROR );
    case T_PUBLIC:
        /* special case - expanded inside iff it is an EQU to a symbol */
        return( Parse_Pass == PASS_1 ? PubDef(i+1) : NOT_ERROR );
    case T_ELSE:
    case T_ELSEIF:
    case T_ELSEIF1:
    case T_ELSEIF2:
    case T_ELSEIFB:
    case T_ELSEIFDEF:
    case T_ELSEIFE:
    case T_ELSEIFNB:
    case T_ELSEIFNDEF:
    case T_ELSEIFDIF:
    case T_ELSEIFDIFI:
    case T_ELSEIFIDN:
    case T_ELSEIFIDNI:
    case T_ENDIF:
    case T_IF:
    case T_IF1:
    case T_IF2:
    case T_IFB:
    case T_IFDEF:
    case T_IFE:
    case T_IFNB:
    case T_IFNDEF:
    case T_IFDIF:
    case T_IFDIFI:
    case T_IFIDN:
    case T_IFIDNI:
        return( conditional_assembly_directive( i ) );
    case T_DOT_ERR:
    case T_DOT_ERRB:
    case T_DOT_ERRDEF:
    case T_DOT_ERRDIF:
    case T_DOT_ERRDIFI:
    case T_DOT_ERRE:
    case T_DOT_ERRIDN:
    case T_DOT_ERRIDNI:
    case T_DOT_ERRNB:
    case T_DOT_ERRNDEF:
    case T_DOT_ERRNZ:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_ERR:
    case T_ERRIFB:
    case T_ERRIFDEF:
    case T_ERRIFDIF:
    case T_ERRIFDIFI:
    case T_ERRIFE:
    case T_ERRIFIDN:
    case T_ERRIFIDNI:
    case T_ERRIFNDEF:
        return( conditional_error_directive( i ) );
    case T_ENDS:
        if( Definition.struct_depth != 0 )
            return( StructDef( i ) );
        // else fall through to T_SEGMENT
    case T_SEGMENT:
        return( Parse_Pass == PASS_1 ? SegDef(i) : SetCurrSeg(i) );
    case T_GROUP:
        return( Parse_Pass == PASS_1 ? GrpDef(i) : NOT_ERROR );
    case T_PROC:
        return( ProcDef( i, TRUE ) );
    case T_ENDP:
        return( ProcEnd(i) );
    case T_ENUM:
        return( EnumDef( i ) );
    case T_DOT_CODE:
    case T_DOT_STACK:
    case T_DOT_DATA:
    case T_DOT_DATA_UN:
    case T_DOT_FARDATA:
    case T_DOT_FARDATA_UN:
    case T_DOT_CONST:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_CODESEG:
    case T_STACK:
    case T_DATASEG:
    case T_UDATASEG:
    case T_FARDATA:
    case T_UFARDATA:
    case T_CONST:
        return( SimSeg(i) );
    case T_WARN:
    case T_NOWARN:
        return( NOT_ERROR ); /* Not implemented yet */
    case T_DOT_ALPHA:
    case T_DOT_SEQ:
    case T_DOT_LIST:
    case T_DOT_LISTALL:
    case T_DOT_LISTIF:
    case T_DOT_LISTMACRO:
    case T_DOT_LISTMACROALL:
    case T_DOT_NOLIST:
    case T_DOT_XLIST:
    case T_DOT_TFCOND:
    case T_DOT_SFCOND:
    case T_DOT_LFCOND:
    case T_DOT_CREF:
    case T_DOT_XCREF:
    case T_DOT_NOCREF:
    case T_DOT_SALL:
    case T_PAGE:
    case T_TITLE:
    case T_SUBTITLE:
    case T_SUBTTL:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
        AsmWarn( 4, IGNORING_DIRECTIVE );
        return( NOT_ERROR );
    case T_DOT_BREAK:
    case T_DOT_CONTINUE:
    case T_DOT_ELSE:
    case T_DOT_ENDIF:
    case T_DOT_ENDW:
    case T_DOT_IF:
    case T_DOT_RADIX:
    case T_DOT_REPEAT:
    case T_DOT_UNTIL:
    case T_DOT_WHILE:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_ECHO:
    case T_HIGH:
    case T_HIGHWORD:
    case T_LOW:
    case T_LOWWORD:
    case T_ADDR:
    case T_BOUND:
    case T_CASEMAP:
    case T_INVOKE:
    case T_LROFFSET:
    case T_OPATTR:
    case T_OPTION:
    case T_POPCONTEXT:
    case T_PUSHCONTEXT:
    case T_PROTO:
    case T_THIS:
    case T_WIDTH:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_CATSTR:
    case T_MASK:
    case T_PURGE:
    case T_RECORD:
    case T_TYPEDEF:
    case T_UNION:
        AsmError( NOT_SUPPORTED );
        return( ERROR );
    case T_ORG:
        ExpandTheWorld( 0, FALSE, TRUE );
        break;
    case T_TEXTEQU:     /* TEXTEQU */
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_EQU2:        /* = */
    case T_EQU:         /* EQU */
        /* expand any constants and simplify any expressions */
        ExpandTheConstant( 0, FALSE, TRUE );
        break;
    case T_NAME:        /* no expand parameters */
        break;
    case T_DOT_STARTUP:
    case T_DOT_EXIT:
        if( Options.mode & MODE_IDEAL ) {
            AsmError( UNKNOWN_DIRECTIVE );
            return( ERROR );
        }
    case T_STARTUPCODE:
    case T_EXITCODE:
    default:
        /* expand any constants in all other directives */
        ExpandAllConsts( 0, FALSE );
        break;
    }

    switch( direct ) {
    case T_ALIAS:
        if( Parse_Pass == PASS_1 )
            return( AddAlias( i ) );
        return( NOT_ERROR );
    case T_EXTERN:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_EXTRN:
        return( Parse_Pass == PASS_1 ? ExtDef( i+1, FALSE ) : NOT_ERROR );
    case T_COMM:
        return( Parse_Pass == PASS_1 ? CommDef(i+1) : NOT_ERROR );
    case T_EXTERNDEF:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_GLOBAL:
        return( Parse_Pass == PASS_1 ? ExtDef( i+1, TRUE ) : NOT_ERROR );
    case T_DOT_MODEL:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_MODEL:
        return( Model(i) );
    case T_INCLUDE:
        return( Include(i+1) );
    case T_INCLUDELIB:
        return( Parse_Pass == PASS_1 ? IncludeLib(i+1) : NOT_ERROR );
    case T_ASSUME:
        return( SetAssume(i) );
    case T_END:
        return( ModuleEnd(Token_Count) );
    case T_EQU:
        return( DefineConstant( i-1, FALSE, FALSE ) );
    case T_EQU2:
        return( DefineConstant( i-1, TRUE, FALSE ) );
    case T_TEXTEQU:
        return( DefineConstant( i-1, TRUE, TRUE ) );
    case T_MACRO:
        return( MacroDef(i, FALSE ) );
    case T_ENDM:
        return( MacroEnd( FALSE ) );
    case T_EXITM:
        return( MacroEnd( TRUE ) );
    case T_ARG:
        return( Parse_Pass == PASS_1 ? ArgDef(i) : NOT_ERROR );
    case T_USES:
        return( Parse_Pass == PASS_1 ? UsesDef(i) : NOT_ERROR );
    case T_LOCAL:
        return( Parse_Pass == PASS_1 ? LocalDef(i) : NOT_ERROR );
    case T_COMMENT:
        if( Options.mode & MODE_IDEAL )
            break;
        return( Comment( START_COMMENT, i ) );
    case T_STRUCT:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_STRUC:
        return( StructDef( i ) );
    case T_NAME:
        return( Parse_Pass == PASS_1 ? NameDirective(i) : NOT_ERROR );
    case T_LABEL:
        return( LabelDirective( i ) );
    case T_ORG:
        return( OrgDirective( i ) );
    case T_ALIGN:
    case T_EVEN:
        return( AlignDirective( direct, i ) );
    case T_FOR:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_IRP:
        return( ForDirective ( i+1, IRP_WORD ) );
    case T_FORC:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_IRPC:
        return( ForDirective ( i+1, IRP_CHAR ) );
    case T_REPEAT:
        if( Options.mode & MODE_IDEAL ) {
            break;
        }
    case T_REPT:
        return( ForDirective ( i+1, IRP_REPEAT ) );
    case T_DOT_STARTUP:
    case T_DOT_EXIT:
    case T_STARTUPCODE:
    case T_EXITCODE:
        return( Startup ( i ) );
    case T_LOCALS:
    case T_NOLOCALS:
        return( Locals( i ) );
    }
    AsmError( UNKNOWN_DIRECTIVE );
    return( ERROR );
}
Esempio n. 2
0
ret_code SegmentDir( int i, struct asm_tok tokenarray[] )
/*******************************************************/
{
    char                is_old;
    char                *token;
    int                 typeidx;
    const struct typeinfo *type;          /* type of option */
    int                 temp;
    int                 temp2;
    uint                initstate = 0;  /* flags for attribute initialization */
    unsigned char       oldreadonly;    /* readonly value of a defined segment */
    //unsigned char       oldsegtype;
    unsigned char       oldOfssize;
    char                oldalign;
    char                oldcombine;
    uint                oldclassidx;
    uint_8              oldcharacteristics;
    struct dsym         *dir;
    char                *name;
    struct asym         *sym;
    struct expr         opndx;

    if ( Parse_Pass != PASS_1 )
        return( SetCurrSeg( i, tokenarray ) );

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

    name = tokenarray[0].string_ptr;

    DebugMsg1(("SegmentDir(%s) enter: ModuleInfo.Ofssize=%u, num_seg=%u\n", name, ModuleInfo.Ofssize, ModuleInfo.g.num_segs ));

    /* See if the segment is already defined */
    sym = SymSearch( name );
    if( sym == NULL || sym->state == SYM_UNDEFINED ) {
        /* segment is not defined (yet) */
        sym = (struct asym *)CreateSegment( (struct dsym *)sym, name, TRUE );
        sym->list = TRUE; /* always list segments */
        dir = (struct dsym *)sym;
        dir->e.seginfo->seg_idx = ++ModuleInfo.g.num_segs;
        is_old = FALSE;
        /*
         * initialize segment with values from the one without suffix
         */
#if COFF_SUPPORT || ELF_SUPPORT
        if (Options.output_format == OFORMAT_COFF
#if ELF_SUPPORT
            || Options.output_format == OFORMAT_ELF
#endif
           ) {
            char *p;
            if ( p = strchr(sym->name, '$') ) {
                char buffer[MAX_ID_LEN+1];
                struct dsym *dir2;
                memcpy(buffer, sym->name, p - sym->name);
                buffer[p - sym->name] = NULLC;
                if ((dir2 = (struct dsym *)SymSearch(buffer)) && dir2->sym.state == SYM_SEG) {
                    dir->e.seginfo->readonly = dir2->e.seginfo->readonly;
                    dir->e.seginfo->segtype  = dir2->e.seginfo->segtype;
                    dir->e.seginfo->Ofssize  = dir2->e.seginfo->Ofssize;
                    dir->e.seginfo->alignment= dir2->e.seginfo->alignment;
                    dir->e.seginfo->characteristics = dir2->e.seginfo->characteristics;
                    dir->e.seginfo->combine         = dir2->e.seginfo->combine;
                    dir->e.seginfo->class_name_idx  = dir2->e.seginfo->class_name_idx;
                }
            }
        }
#endif
    } else if ( sym->state == SYM_SEG ) {
        /* segment already defined */
        dir = (struct dsym *)sym;
        is_old = TRUE;
        oldreadonly = dir->e.seginfo->readonly;
        //oldsegtype  = dir->e.seginfo->segtype;
        oldOfssize  = dir->e.seginfo->Ofssize;
        oldalign    = dir->e.seginfo->alignment;
        oldcharacteristics = dir->e.seginfo->characteristics;
        oldcombine  = dir->e.seginfo->combine;
        oldclassidx = dir->e.seginfo->class_name_idx;
        if( dir->e.seginfo->lname_idx == 0 ) {
            /* segment was mentioned in a group statement, but not really set up */
            is_old = FALSE;
            /* the segment list is to be sorted.
             * So unlink the segment and add it at the end.
             */
            UnlinkSeg( dir );
            dir->e.seginfo->seg_idx = ++ModuleInfo.g.num_segs;
            dir->next = NULL;
            if ( SymTables[TAB_SEG].head == NULL )
                SymTables[TAB_SEG].head = SymTables[TAB_SEG].tail = dir;
            else {
                SymTables[TAB_SEG].tail->next = dir;
                SymTables[TAB_SEG].tail = dir;
            }
        }
    } else {
        /* symbol is different kind, error */
        DebugMsg(("SegmentDir(%s): symbol redefinition\n", name ));
        EmitErr( SYMBOL_REDEFINITION, name );
        return( ERROR );
    }

    i++; /* go past SEGMENT */

    for( ; i < Token_Count; i++ ) {
        token = tokenarray[i].string_ptr;
        DebugMsg1(("SegmentDir(%s): i=%u, string=%s token=%X\n", name, i, token, tokenarray[i].token ));
        if( tokenarray[i].token == T_STRING ) {

            /* the class name - the only token which is of type STRING */
            /* string must be delimited by [double]quotes */
            if ( tokenarray[i].string_delim != '"' &&
                tokenarray[i].string_delim != '\'' ) {
                EmitErr( SYNTAX_ERROR_EX, token );
                continue;
            }
            /* remove the quote delimiters */
            token++;
            *(token+tokenarray[i].stringlen) = NULLC;

            SetSegmentClass( &dir->sym, token );

            DebugMsg1(("SegmentDir(%s): class found: %s\n", name, token ));
            continue;
        }

        /* check the rest of segment attributes.
         */
        typeidx = FindToken( token, SegAttrToken, sizeof( SegAttrToken )/sizeof( SegAttrToken[0] ) );
        if( typeidx < 0 ) {
            EmitErr( UNKNOWN_SEGMENT_ATTRIBUTE, token );
            continue;
        }
        type = &SegAttrValue[typeidx];

        /* initstate is used to check if any field is already
         * initialized
         */
        if( initstate & INIT_EXCL_MASK & type->init ) {
            EmitErr( SEGMENT_ATTRIBUTE_DEFINED_ALREADY, token );
            continue;
        } else {
            initstate |= type->init; /* mark it initialized */
        }

        switch ( type->init ) {
        case INIT_ATTR:
            dir->e.seginfo->readonly = TRUE;
            break;
        case INIT_ALIGN:
            DebugMsg1(("SegmentDir(%s): align attribute found\n", name ));
            dir->e.seginfo->alignment = type->value;
            break;
        case INIT_ALIGN_PARAM:
            DebugMsg1(("SegmentDir(%s): ALIGN() found\n", name ));
            if ( Options.output_format == OFORMAT_OMF ) {
                EmitErr( NOT_SUPPORTED_WITH_OMF_FORMAT, tokenarray[i].string_ptr );
                i = Token_Count; /* stop further parsing of this line */
                break;
            }
            i++;
            if ( tokenarray[i].token != T_OP_BRACKET ) {
                EmitErr( EXPECTED, "(" );
                break;
            }
            i++;
            if ( EvalOperand( &i, tokenarray, Token_Count, &opndx, 0 ) == ERROR )
                break;
            if ( tokenarray[i].token != T_CL_BRACKET ) {
                EmitErr( EXPECTED, ")" );
                break;
            }
            if ( opndx.kind != EXPR_CONST ) {
                EmitError( CONSTANT_EXPECTED );
                break;
            }
            /*
             COFF allows alignment values
             1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192
             */
            for( temp = 1, temp2 = 0; temp < opndx.value && temp < 8192 ; temp <<= 1, temp2++ );
            if( temp != opndx.value ) {
                EmitError( POWER_OF_2 );
            }
            dir->e.seginfo->alignment = temp2;
            break;
        case INIT_COMBINE:
            DebugMsg1(("SegmentDir(%s): combine attribute found\n", name ));
            dir->e.seginfo->combine = type->value;
            break;
        case INIT_COMBINE_AT:
            DebugMsg1(("SegmentDir(%s): AT found\n", name ));
            dir->e.seginfo->combine = type->value;
            /* v2.05: always use MAX_SEGALIGNMENT */
            //dir->e.seginfo->alignment = -1;
            dir->e.seginfo->alignment = MAX_SEGALIGNMENT;
            i++;
            if ( EvalOperand( &i, tokenarray, Token_Count, &opndx, 0 ) != ERROR ) {
                if ( opndx.kind == EXPR_CONST ) {
                    dir->e.seginfo->abs_frame = opndx.value;
                    dir->e.seginfo->abs_offset = 0;
                } else {
                    EmitError( CONSTANT_EXPECTED );
                }
            }
            break;
#if COMDATSUPP
        case INIT_COMBINE_COMDAT:
            DebugMsg1(("SegmentDir(%s): COMDAT found\n", name ));
            if ( Options.output_format != OFORMAT_COFF ) {
                EmitErr( NOT_SUPPORTED_WITH_CURR_FORMAT, tokenarray[i].string_ptr );
                i = Token_Count; /* stop further parsing of this line */
                break;
            }
            i++;
            if ( tokenarray[i].token != T_OP_BRACKET ) {
                EmitErr( EXPECTED, "(" );
                break;
            }
            i++;
            if ( EvalOperand( &i, tokenarray, Token_Count, &opndx, 0 ) == ERROR )
                break;
            if ( opndx.kind != EXPR_CONST ) {
                EmitError( CONSTANT_EXPECTED );
                i = Token_Count; /* stop further parsing of this line */
                break;
            }
            if ( opndx.value < 1 || opndx.value > 6 ) {
                EmitErr( VALUE_NOT_WITHIN_ALLOWED_RANGE, "1-6" );
            } else {
                /* if value is IMAGE_COMDAT_SELECT_ASSOCIATIVE,
                 * get the associated segment name argument.
                 */
                if ( opndx.value == 5 ) {
                    struct asym *sym2;
                    if ( tokenarray[i].token != T_COMMA ) {
                        EmitError( EXPECTING_COMMA );
                        i = Token_Count; /* stop further parsing of this line */
                        break;
                    }
                    i++;
                    if ( tokenarray[i].token != T_ID ) {
                        EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr );
                        i = Token_Count; /* stop further parsing of this line */
                        break;
                    }
                    /* associated segment must be COMDAT, but not associative */
                    sym2 = SymSearch( tokenarray[i].string_ptr );
                    if ( sym2 == NULL ||
                        sym2->state != SYM_SEG ||
                        ((struct dsym *)sym2)->e.seginfo->comdat_selection == 0 ||
                        ((struct dsym *)sym2)->e.seginfo->comdat_selection == 5 )
                        EmitErr( INVALID_ASSOCIATED_SEGMENT, tokenarray[i].string_ptr );
                    else
                        dir->e.seginfo->comdat_number = ((struct dsym *)sym2)->e.seginfo->seg_idx;
                    i++;
                }
            }
            if ( tokenarray[i].token != T_CL_BRACKET ) {
                EmitErr( EXPECTED, ")" );
                break;
            }
            dir->e.seginfo->comdat_selection = opndx.value;
            dir->e.seginfo->combine = type->value;
            break;
#endif
        case INIT_OFSSIZE:
        case INIT_OFSSIZE_FLAT:
            /* v2.07: check for compatible cpu mode */
            if ( type->value == USE32 && ( ( ModuleInfo.curr_cpu & P_CPU_MASK ) < P_386 )
#if AMD64_SUPPORT
                || type->value == USE64 && ( ( ModuleInfo.curr_cpu & P_CPU_MASK ) < P_64 )
#endif
               ) {
                EmitError( INSTRUCTION_OR_REGISTER_NOT_ACCEPTED_IN_CURRENT_CPU_MODE );
                break;
            }
            if ( type->init == INIT_OFSSIZE_FLAT ) {
                DefineFlatGroup();
#if AMD64_SUPPORT
                dir->e.seginfo->Ofssize = ModuleInfo.defOfssize;
#else
                dir->e.seginfo->Ofssize = USE32;
#endif
                /* put the segment into the FLAT group.
                 * this is not quite Masm-compatible, because trying to put
                 * the segment into another group will cause an error.
                 */
                dir->e.seginfo->group = &ModuleInfo.flat_grp->sym;
            } else
                dir->e.seginfo->Ofssize = type->value;
            break;
#if COFF_SUPPORT || ELF_SUPPORT
        case INIT_CHAR_INFO:
            dir->e.seginfo->info = TRUE;
            break;
        case INIT_CHAR:
            DebugMsg1(("SegmentDir(%s): characteristics found\n", name ));
            ; /* characteristics are restricted to COFF/ELF */
            if ( Options.output_format == OFORMAT_OMF || Options.output_format == OFORMAT_BIN ) {
                EmitErr( NOT_SUPPORTED_WITH_CURR_FORMAT, tokenarray[i].string_ptr );
            } else
                dir->e.seginfo->characteristics |= type->value;
            break;
        case INIT_ALIAS:
            DebugMsg1(("SegmentDir(%s): ALIAS found\n", name ));
            if ( Options.output_format != OFORMAT_COFF &&
                Options.output_format != OFORMAT_ELF ) {
                EmitErr( NOT_SUPPORTED_WITH_CURR_FORMAT, tokenarray[i].string_ptr );
                i = Token_Count; /* stop further parsing of this line */
                break;
            }
            i++;
            if ( tokenarray[i].token != T_OP_BRACKET ) {
                EmitErr( EXPECTED, "(" );
                break;
            }
            i++;
            if ( tokenarray[i].token != T_STRING ||
                ( tokenarray[i].string_delim != '"' &&
                tokenarray[i].string_delim != '\'' ) ) {
                EmitErr( SYNTAX_ERROR_EX, token );
                i = Token_Count; /* stop further parsing of this line */
                break;
            }
            temp = i;
            i++;
            if ( tokenarray[i].token != T_CL_BRACKET ) {
                EmitErr( EXPECTED, ")" );
                break;
            }
            dir->e.seginfo->aliasname = LclAlloc( tokenarray[temp].stringlen );
            memcpy( dir->e.seginfo->aliasname, tokenarray[temp].string_ptr+1, tokenarray[temp].stringlen );
            *(dir->e.seginfo->aliasname+tokenarray[temp].stringlen) = NULLC;
            break;
#endif
#ifdef DEBUG_OUT
        default: /* shouldn't happen */
            myassert( 0 );
            break;
#endif
        }
    } /* end for */

    /* make a guess about the segment's type */
    if( dir->e.seginfo->segtype != SEGTYPE_CODE ) {
        enum seg_type res;

        token = GetLname( dir->e.seginfo->class_name_idx );
        res = TypeFromClassName( dir, token );
        if( res != SEGTYPE_UNDEF ) {
            dir->e.seginfo->segtype = res;
        }
#if 0 /* v2.03: removed */
        else {
            res = TypeFromSegmentName( name );
            dir->e.seginfo->segtype = res;
        }
#endif
    }

    if( is_old ) {
        int txt = 0;

        /* Check if new definition is different from previous one */

        // oldobj = dir->e.seginfo->segrec;
        if(  oldreadonly      != dir->e.seginfo->readonly )
            txt = TXT_READONLY;
        else if ( oldalign    != dir->e.seginfo->alignment )
            txt = TXT_ALIGNMENT;
        else if ( oldcombine  != dir->e.seginfo->combine )
            txt = TXT_COMBINE;
        else if ( oldOfssize  != dir->e.seginfo->Ofssize )
            txt = TXT_SEG_WORD_SIZE;
        else if ( oldclassidx != dir->e.seginfo->class_name_idx )
            txt = TXT_CLASS; /* Masm warns only! */
        else if ( oldcharacteristics != dir->e.seginfo->characteristics )
            txt = TXT_CHARACTERISTICS;

        if ( txt ) {
            EmitErr( SEGDEF_CHANGED, dir->sym.name, MsgGetEx( txt ) );
            //return( ERROR ); /* v2: display error, but continue */
        }

    } else {
        /* A new definition */

        sym = &dir->sym;
        sym->isdefined = TRUE;
        sym->segment = sym;
        sym->offset = 0;
        if( dir->e.seginfo->lname_idx == 0 ) {
            dir->e.seginfo->lname_idx = ++LnamesIdx;
            AddLnameData( sym );
        }

    }
    push_seg( dir ); /* set CurrSeg */

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

    return( SetOfssize() );
}