extern void AsNumLabelEmit( uint_32 label_num, owl_section_handle section, owl_offset offset, owl_sym_type type ) { //***************************************************************************************************************** // These symbols are used for matching l^ & h^ garbage. sym_handle new_fw_sym; // forward char *new_fw_name; sym_reloc reloc; int_32 numlabel_ref; new_fw_name = AsNumLabelMakeName( label_num ); new_fw_sym = SymLookup( new_fw_name ); if( new_fw_sym ) { // check if it still has some unemitted relocs if( new_fw_sym->hi_relocs ) { Error( UNMATCHED_HIGH_RELOC, "<numeric reference>" ); while( new_fw_sym->hi_relocs ) { SymDestroyReloc( new_fw_sym, new_fw_sym->hi_relocs ); } } if( new_fw_sym->lo_relocs ) { _DBGMSG1( "emitting all the unemitted l^relocs\n" ); while( ( reloc = new_fw_sym->lo_relocs ) != NULL ) { numlabel_ref = AsNumLabelGetNum( SymName( new_fw_sym ) ); #ifdef _STANDALONE_ ObjDirectEmitReloc( reloc->location.section, #else ObjDirectEmitReloc( #endif reloc->location.offset, &numlabel_ref, OWL_RELOC_HALF_LO, FALSE ); SymDestroyReloc( new_fw_sym, reloc ); reloc = new_fw_sym->lo_relocs; } } assert( new_fw_sym->hi_relocs == NULL && new_fw_sym->lo_relocs == NULL ); } else {
void GSPProlog( void ) { //=================== // Generate a subprogram prologue. SetArgAddrs(); ReturnValue = SymLookup( "$@RVAL", 6 ); ReturnValue->u.ns.flags |= SY_REFERENCED; ReturnValue->u.ns.u1.s.xflags |= SY_DEFINED; }
sym_id LkBlkData( void ) { //=================== // Look up default block data name in symbol table. sym_id sym; sym = SymLookup( BlkData, BLKDAT_LEN ); sym->ns.flags = SY_USAGE | SY_SUBPROGRAM | SY_BLOCK_DATA | SY_PENTRY | SY_UNNAMED | SY_REFERENCED; return( sym ); }
sym_id LkProgram( void ) { //=================== // Look up default program name in symbol table. Don't set any flag bits. sym_id sym; sym = SymLookup( ProgName, PROG_LEN ); sym->ns.flags = SY_USAGE | SY_SUBPROGRAM | SY_PROGRAM | SY_PENTRY | SY_UNNAMED | SY_REFERENCED; return( sym ); }
static void doReloc( asmreloc *reloc ) { //************************************** sym_handle sym; uint_32 bit_mask; uint_32 *data; owl_offset displacement; sym = SymLookup( reloc->name ); displacement = relocTargetDisp( reloc->offset, getSymOffset( sym ) ); bit_mask = relocBitMask( reloc ); data = (uint_32 *)&AsmCodeBuffer[ reloc->offset ]; *data = (*data&~bit_mask)|(((displacement&bit_mask)+(*data&bit_mask))&bit_mask); }
void GEPProlog( void ) { //=================== // Generate an entry point prologue. sym_id ep; char *ptr; char name[MAX_SYMLEN+3]; ep = ArgList->id; ep->u.ns.si.sp.u.entry = NextLabel(); GLabel( ep->u.ns.si.sp.u.entry ); // by the time we define the label for the entry point, the code that // references it will have been executed FreeLabel( ep->u.ns.si.sp.u.entry ); SetArgAddrs(); if( CommonEntry == NULL ) { ptr = name; *ptr = '$'; ptr++; ptr = STGetName( SubProgId, ptr ); *ptr = '.'; ptr++; *ptr = NULLCHAR; CommonEntry = SymLookup( name, SubProgId->u.ns.u2.name_len + 2 ); if( (SubProgId->u.ns.flags & SY_SUBPROG_TYPE) == SY_SUBROUTINE ) { CommonEntry->u.ns.flags = SY_USAGE | SY_SUBPROGRAM | SY_SUBROUTINE | SY_SENTRY | SY_REFERENCED; } else { CommonEntry->u.ns.flags = SY_USAGE | SY_SUBPROGRAM | SY_FUNCTION | SY_SENTRY | SY_REFERENCED; } EPValue = SymLookup( "$@EVAL", 6 ); EPValue->u.ns.flags |= SY_REFERENCED; EPValue->u.ns.u1.s.xflags |= SY_DEFINED; } }
static void resolveRelativeRelocs( void ) { //***************************************** // Do all relative relocs within the inline code and // complain about references that are not internal and not defined by the // compiler. asmreloc *curr_reloc; asmreloc **last; char *keep_name; enum sym_state state; curr_reloc = AsmRelocs; last = &AsmRelocs; while( curr_reloc ) { if( SymLocationKnown( SymLookup( curr_reloc->name ) ) ) { if( IS_RELOC_RELATIVE( curr_reloc->type ) ) { doReloc( curr_reloc ); } else { // If not relative, we won't do it! (?) Error( ABS_REF_NOT_ALLOWED, curr_reloc->name ); } } else { // See if it's defined outside. state = AsmQueryState( AsmQuerySymbol( curr_reloc->name ) ); if( state == SYM_UNDEFINED ) { Error( SYMBOL_NOT_DECLARED, curr_reloc->name ); } else { if( IS_RELOC_RELATIVE( curr_reloc->type ) && state == SYM_STACK ) { Error( CANNOT_JUMP_TO_STACKVAR ); } else { // Leave these in the list... //Warning( "'%s' is left for CC to take care of", curr_reloc->name ); keep_name = MemAlloc( strlen( curr_reloc->name ) + 1 ); strcpy( keep_name, curr_reloc->name ); curr_reloc->name = keep_name; last = &curr_reloc->next; curr_reloc = curr_reloc->next; continue; } } } *last = curr_reloc->next; MemFree( curr_reloc ); curr_reloc = *last; } }
sym_id LkSym( void ) { //=============== // Look up symbol in symbol table and set flag bits. sym_id sym; sym = SymLookup( CITNode->opnd, CITNode->opnd_size ); CITNode->sym_ptr = sym; CITNode->flags = sym->ns.flags; CITNode->size = sym->ns.xt.size; CITNode->typ = sym->ns.typ; if( ( sym->ns.name_len > STD_SYMLEN ) && ( ( ExtnSw & XS_LONG_NAME ) == 0 ) ) { NameExt( VA_NAME_LEN_EXT, sym ); ExtnSw |= XS_LONG_NAME; } return( sym ); }
extern sym_handle AsNumLabelSymLookup( int_32 *label_num ) { //********************************************************** // Look/Cook up symbol handles for both forward and backward references for // each label_num. sym_handle sym; char *sym_name; if( *label_num > 0 ) { ++numLabelCounts[ *label_num - 1 ]; // flip "e"/"o" if forward } sym_name = AsNumLabelMakeName( *label_num ); if( *label_num > 0 ) { --numLabelCounts[ *label_num - 1 ]; // change back "e"/"o" } sym = SymLookup( sym_name ); if( sym ) return( sym ); return( SymAdd( sym_name, SYM_LABEL ) ); }
static void doEmitReloc( owl_offset offset, void *target, owl_reloc_type type, bool named_sym ) { //*********************************************************************************************** asmreloc *reloc; int_32 label_num; if( named_sym ) { assert( SymLookup( target ) != NULL ); reloc = newReloc( offset, target, type ); if( AsmRelocs == NULL ) { AsmRelocs = reloc; lastReloc = reloc; } else { lastReloc->next = reloc; lastReloc = reloc; } } else { label_num = *(int_32 *)target; AsNumLabelReloc( NULL, offset, label_num, type ); } }
static void doEmitReloc( owl_section_handle section, owl_offset offset, void *target, owl_reloc_type type, bool named_sym ) { //*************************************************************************************************************************** obj_section_handle ref_section; sym_handle sym; int_32 label_num; if( named_sym ) { if( ( ref_section = SectionLookup( target ) ) != NULL ) { // We only handle backward reference to a section // So we have to define a section before we can refer to it. OWLEmitMetaReloc( section, offset, SectionOwlHandle( ref_section ), type ); } else { sym = SymLookup( target ); assert( sym != NULL ); OWLEmitReloc( section, offset, SymObjHandle( sym ), type ); } } else { label_num = *(int_32 *)target; AsNumLabelReloc( section, offset, label_num, type ); } }
/* .[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 ); }
if( !strcmp( sym_name, sym->name ) ) break; sym = sym->next; } return( sym ); } extern sym_handle SymAdd( const char *sym_name, sym_class class ) { //***************************************************************** // Add a symbol with the given name and class to our symbol table. // Other symbol attrs will have to be added individually. sym_handle sym; sym_handle *bucket; assert( SymLookup( sym_name ) == NULL ); bucket = &hashTable[ symHash( sym_name ) ]; sym = symAlloc( sym_name ); sym->class = class; sym->flags = SF_EXTERN; sym->linkage = SL_UNKNOWN; sym->hi_relocs = sym->lo_relocs = NULL; sym->obj_hdl = NULL; sym->next = *bucket; *bucket = sym; return( sym ); } #ifndef _STANDALONE_ extern bool SymLocationKnown( sym_handle sym ) { //**********************************************