void PutMsg( FILE *fp, int severity, int msgnum, va_list args ) /********************************************************************/ { int i,j; char *type; char msgbuf[MAXMSGSIZE]; char buffer[MAX_LINE_LEN]; if( fp != NULL ) { MsgGet( msgnum, msgbuf ); switch (severity ) { case 1: type = MsgGetEx( MSG_FATAL_PREFIX ); break; case 2: type = MsgGetEx( MSG_ERROR_PREFIX ); break; case 4: type = MsgGetEx( MSG_WARNING_PREFIX ); break; default: type = NULL; i = 0; break; } if ( type ) i = sprintf( buffer, "%s A%4u: ", type, severity * 1000 + msgnum ); i += vsprintf( buffer+i, msgbuf, args ); //buffer[i] = NULLC; if ( severity && (j = GetCurrSrcPos( msgbuf ))) { fwrite( msgbuf, 1, j, fp ); } else j = 0; fwrite( buffer, 1, i, fp ); fwrite( "\n", 1, 1, fp ); /* if in Pass 1, add the error msg to the listing */ if ( FileInfo.file[LST] && severity && Parse_Pass == PASS_1 && fp == FileInfo.file[ERR] ) { LstWrite( LSTTYPE_DIRECTIVE, GetCurrOffset(), 0 ); LstPrintf( " %s", buffer ); LstNL(); } } }
int InternalError( const char *file, unsigned line ) /**************************************************/ // it's used by myassert() function in debug version { char buffer[MAX_LINE_LEN]; DebugMsg(("InternalError enter\n")); ModuleInfo.error_count++; GetCurrSrcPos( buffer ); fprintf( errout, "%s", buffer ); fprintf( errout, MsgGetEx( INTERNAL_ERROR ), file, line ); close_files(); exit( EXIT_FAILURE ); return(0); }
void LstInit( void ) /******************/ { const struct fname_item *fn; const char *buffer; list_pos = 0; if( Options.write_listing ) { int namelen; buffer = MsgGetEx( MSG_HJWASM ); list_pos = strlen( buffer ); fwrite( buffer, 1, list_pos, CurrFile[LST] ); LstNL(); fn = GetFName( ModuleInfo.srcfile ); namelen = strlen( fn->fname ); fwrite( fn->fname, 1, namelen, CurrFile[LST] ); list_pos += namelen; LstNL(); } }
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 ); }
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 */ }
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() ); }