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 ); }
/* create external. * sym must be NULL or of state SYM_UNDEFINED! */ static struct asym *CreateExternal( struct asym *sym, const char *name, char weak ) /*********************************************************************************/ { if ( sym == NULL ) sym = SymCreate( name ); else sym_remove_table( &SymTables[TAB_UNDEF], (struct dsym *)sym ); if ( sym ) { sym->state = SYM_EXTERNAL; sym->seg_ofssize = ModuleInfo.Ofssize; sym->iscomm = FALSE; sym->weak = weak; sym_add_table( &SymTables[TAB_EXT], (struct dsym *)sym ); /* add EXTERNAL */ } return( sym ); }
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 ); }
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 ); }