void SymbianDLLMapImp::OnUnload(void* pDLLEntryPoint) { DLLMapInfo* pInfo = FindInfo(pDLLEntryPoint); HX_ASSERT(pInfo); if (pInfo) { if (pInfo->OnUnload()) { // This was the last unload for this DLL. // Remove it from our list and destroy the info LISTPOSITION pos = m_libList.GetHeadPosition(); while(pInfo && pos) { if (pInfo == (DLLMapInfo*)m_libList.GetAt(pos)) { m_libList.RemoveAt(pos); HX_DELETE(pInfo); } else { m_libList.GetNext(pos); } } } } }
int wxIconStateInfoDB::GetIconId(const wxString& name, int state, bool enabled) const { wxIconStateInfo* info = FindInfo(name); if (!info) return -1; return info->GetIconId(state, enabled); }
void C4Language::LoadInfos(C4Group &hGroup) { char strEntry[_MAX_FNAME + 1]; char *strTable; // Look for language string tables hGroup.ResetSearch(); while (hGroup.FindNextEntry(C4CFN_Language, strEntry)) // For now, we will only load info on the first string table found for a given // language code as there is currently no handling for selecting different string tables // of the same code - the system always loads the first string table found for a given code if (!FindInfo(GetFilenameOnly(strEntry) + SLen(GetFilenameOnly(strEntry)) - 2)) // Load language string table if (hGroup.LoadEntry(strEntry, &strTable, 0, 1)) { // New language info C4LanguageInfo *pInfo = new C4LanguageInfo; // Get language code by entry name SCopy(GetFilenameOnly(strEntry) + SLen(GetFilenameOnly(strEntry)) - 2, pInfo->Code, 2); SCapitalize(pInfo->Code); // Get language name, info, fallback from table CopyResStr("IDS_LANG_NAME", strTable, pInfo->Name); CopyResStr("IDS_LANG_INFO", strTable, pInfo->Info); CopyResStr("IDS_LANG_FALLBACK", strTable, pInfo->Fallback); // Safety: pipe character is not allowed in any language info string SReplaceChar(pInfo->Name, '|', ' '); SReplaceChar(pInfo->Info, '|', ' '); SReplaceChar(pInfo->Fallback, '|', ' '); // Delete table delete [] strTable; // Add info to list pInfo->Next = Infos; Infos = pInfo; } }
bool wxIconStateInfoDB::SetIconId(const wxString& name, int state, bool enabled, int iconId) { wxIconStateInfo* info = FindInfo(name); if (!info) return FALSE; info->SetIconId(state, enabled, iconId); return TRUE; }
const LibInfo& LibMgr::GetInfo(Library lib) { if (s_LibInfos.find(lib) == s_LibInfos.end()) { FindInfo(lib); } return s_LibInfos.at(lib); }
// Easy way of initialising both the image list and the // info db. It will generate image ids itself while appending the icon. bool wxIconStateInfoDB::AddInfo(const wxString& name, const wxIcon& icon, int state, bool enabled) { wxASSERT (m_imageList != NULL); wxIconStateInfo* info = FindInfo(name); if (!info) { info = new wxIconStateInfo(name); Append(info); } info->SetIconId(state, enabled, m_imageList->Add(icon)); return TRUE; }
wxIcon wxIconStateInfoDB::GetIcon(const wxString& name, int state, bool enabled) const { wxASSERT( m_imageList != NULL ); wxIconStateInfo* info = FindInfo(name); if (!info) return wxNullIcon; int id = info->GetIconId(state, enabled); if (id < 0) return wxNullIcon; else return m_imageList->GetImage(id); // Doesn't exist }
/* * InfoSize -- return size of demand info section */ unsigned InfoSize( imp_image_handle *ii, imp_mod_handle im, unsigned item, unsigned entry ) { demand_info *dmnd; section_info *inf; dmnd = &ModPointer( ii, im )->di[item]; if( entry >= dmnd->u.entries ) return( 0 ); entry += dmnd->info_off; inf = FindInfo( ii, im ); return( DMND_SIZE( inf, entry ) ); }
int HashAdd(HashTable ht, void *data) /* Adds data to the specified hashtable. If an equivalent record (according to ht->compData() ) exists, no adding is done. Returns 1 on success, 0 on failure. */ { int retval = 1; unsigned int hashval = ht->calcIndx(data)%ht->size; HashInfoPtr newInfo; ErrPushFunc("HashAdd"); if(FindInfo(ht, data, hashval)) retval=0; else { if( (newInfo = (HashInfoPtr)malloc(sizeof(struct HiPtr))) != NULL ) { int error; newInfo->data = data; newInfo->next = ht->infoArray[hashval]; newInfo->firstCursor = NULL; #if defined (_POSIX_SEMAPHORES) && defined (_POSIX_THREADS) error = sem_init( &(newInfo->cursorListSemaphore), 0, 1 ); if (error != 0) { retval = 0; goto ERR_RETURN; } #endif /* I believe this is an atomic action and therefore needs not be protected by a semaphore to be thread-safe. Can this be guaranteed? What does the pthreads package say about atomicity? Anyway, the elementCount needs to be semaphored methinks. /Erl 981015 */ ht->infoArray[hashval] = newInfo; ht->elementCount++; } else { retval = 0; goto ERR_RETURN; } } ERR_RETURN: ErrPopFunc(); return(retval); }
void *HashFind(HashTable ht, void *data) /* If a data record matching 'data' is found in ht, a pointer to it is returned. Otherwise NULL. */ { void *foundData; HashInfoPtr tmp; /* ErrPushFunc("HashFind"); */ assert( ht != NULL && ht->size != 0 ); foundData=NULL; if((tmp = FindInfo(ht, data, ht->calcIndx(data) % ht->size)) != NULL) { foundData=tmp->data; } /* ErrPopFunc(); */ return(foundData); }
mod_info *ModPointer( imp_image_handle *ii, imp_mod_handle mod ) { info_block *blk; mod_table *tbl; unsigned index; section_info *inf; inf = FindInfo( ii, mod ); if( inf == NULL ) return( NULL ); index = mod - inf->mod_base_idx; for( blk = inf->mod_info; blk != NULL; blk = blk->next ) { tbl = blk->link; if( index < tbl->count ) { return( (mod_info *)((byte *)blk->info + tbl->mod_off[ index ]) ); } index -= tbl->count; } return( NULL ); }
/* // Return name pattern manipulator string */ static const char *GetNamePattern( SYM_HANDLE sym_handle ) { char *pattern; SYM_ENTRY sym; aux_info *inf; inf = FindInfo( &sym, sym_handle ); #ifdef __SEH__ if(( sym_handle == SymTryInit ) || ( sym_handle == SymTryFini ) || ( sym_handle == SymTryUnwind ) || ( sym_handle == SymExcept )) { pattern = "*"; } else { #endif inf = LangInfo( sym.mods, inf ); if( sym.flags & SYM_FUNCTION ) { pattern = inf->objname; #if ( _CPU == 386 ) || ( _CPU == 8086 ) if( VarFunc( &sym ) ) { if( inf == &DefaultInfo ) inf = DftCallConv; if( inf == &StdcallInfo ) { pattern = CdeclInfo.objname; } else if( inf == &FastcallInfo ) { pattern = CdeclInfo.objname; } } #endif if( pattern == NULL ) { pattern = TS_CODE_MANGLE; } } else { pattern = VarNamePattern( inf ); if( pattern == NULL ) { pattern = TS_DATA_MANGLE; } } #ifdef __SEH__ } // close that else #endif return( pattern ); }
void SymbianDLLMapImp::OnLoad(void* pDLLEntryPoint) { DLLMapInfo* pInfo = FindInfo(pDLLEntryPoint); if (!pInfo) { pInfo = new DLLMapInfo(pDLLEntryPoint); if (pInfo && !m_libList.AddHead(pInfo)) { // The AddHead() failed HX_DELETE(pInfo); } } if (pInfo) { pInfo->OnLoad(); } }
static walk_result WlkClear( imp_image_handle *ii, imp_mod_handle im, void *d ) { unsigned dmnd; mod_info *mp; section_info *sect; int entry; unsigned real_entry; pointer_int *lnk; d = d; mp = ModPointer( ii, im ); sect = FindInfo( ii, im ); for( dmnd = DMND_FIRST; dmnd < DMND_NUM; ++dmnd ) { for( entry = mp->di[dmnd].u.entries-1; entry >= 0; --entry ) { real_entry = entry + mp->di[dmnd].info_off; lnk = &GET_LINK( sect, real_entry ); if( IS_RESIDENT( *lnk ) ) { Unload( MK_DMND_PTR( *lnk ) ); } } } return( WR_CONTINUE ); }
search_result LookupGblAddr( imp_image_handle *ii, address addr, imp_sym_handle *is ) { section_info *inf; info_block *curr; search_result sr = SR_NONE; is->u.gbl = NULL; SET_GBLNAMEOFF( ii ); inf = FindInfo( ii, is->im ); curr = inf->gbl; for( ;; ) { if( curr == NULL ) break; if( addr.sect_id == 0 || addr.sect_id == inf->sect_id ) { sr = LkupGblAddr( curr, is, addr.mach ); if( sr == SR_EXACT ) break; } curr = curr->next; } if( is->u.gbl == NULL ) return( SR_NONE ); GblCreate( is, is->u.gbl ); return( sr == SR_EXACT ? SR_EXACT : SR_CLOSEST ); }
/* // This section is NOT 8086 and 386 , i.e., // _AXP // _PPC // _MIPS // // pass auxiliary information to back end */ CGPOINTER FEAuxInfo( CGPOINTER req_handle, int request ) { aux_info *inf; auto SYM_ENTRY sym; static hw_reg_set save_set; switch( request ) { case SOURCE_LANGUAGE: return( (CGPOINTER)"C" ); case OBJECT_FILE_NAME: return( (CGPOINTER)ObjFileName() ); case REVISION_NUMBER: return( (CGPOINTER)(pointer_int)II_REVISION ); case AUX_LOOKUP: return( req_handle ); case SOURCE_NAME: if( SrcFName == ModuleName ) { return( (CGPOINTER)FNameFullPath( FNames ) ); } else { return( (CGPOINTER)ModuleName ); } case CALL_CLASS: { static call_class cclass; cclass = GetCallClass( req_handle ); return( (CGPOINTER)&cclass ); } case NEXT_LIBRARY: case LIBRARY_NAME: return( NextLibrary( (int)(pointer_int)req_handle, request ) ); case NEXT_IMPORT: case IMPORT_NAME: return( NextImport( (int)(pointer_int)req_handle, request ) ); case NEXT_IMPORT_S: case IMPORT_NAME_S: return( NextImportS( (int)(pointer_int)req_handle, request ) ); case NEXT_ALIAS: case ALIAS_NAME: case ALIAS_SYMBOL: case ALIAS_SUBST_NAME: case ALIAS_SUBST_SYMBOL: return( NextAlias( (int)(pointer_int)req_handle, request ) ); case FREE_SEGMENT: return( NULL ); case TEMP_LOC_NAME: return( (CGPOINTER)(pointer_int)TEMP_LOC_QUIT ); case TEMP_LOC_TELL: return( NULL ); case NEXT_DEPENDENCY: if( CompFlags.emit_dependencies ) return( (CGPOINTER)NextDependency( (FNAMEPTR)req_handle ) ); return( NULL ); case DEPENDENCY_TIMESTAMP: return( (CGPOINTER)getFileDepTimeStamp( (FNAMEPTR)req_handle ) ); case DEPENDENCY_NAME: return( (CGPOINTER)FNameFullPath( (FNAMEPTR)req_handle ) ); default: break; } inf = FindInfo( &sym, req_handle ); switch( request ) { case SAVE_REGS: if( req_handle != 0 ) { inf = LangInfo( sym.mods, inf ); } else { sym.mods = 0; } save_set = inf->save; return( (CGPOINTER)&save_set ); case RETURN_REG: if( req_handle != 0 ) { inf = LangInfo( sym.mods, inf ); } return( (CGPOINTER)&inf->returns ); case CALL_BYTES: return( (CGPOINTER)inf->code ); case PARM_REGS: if( req_handle != 0 ) { inf = LangInfo( sym.mods, inf ); if( inf->code == NULL && VarFunc( &sym ) ) { return( (CGPOINTER)DefaultVarParms ); } } return( (CGPOINTER)inf->parms ); default: break; } return( NULL ); }
void *InfoLoad( imp_image_handle *ii, imp_mod_handle im, unsigned item, unsigned entry, void (*clear)(void *, void *) ) { demand_ctrl *section; demand_info *info; section_info *sect; unsigned long tmpoff; pointer_int *lnk; unsigned size; ++TimeStamp; if( TimeStamp == 0 ) { /* TimeStamp wrapped */ TimeStamp = 1; for(section = DemandList; section != NULL; section = section->link) { section->time_stamp = 0; } } info = &ModPointer( ii, im )->di[ item ]; if( entry >= info->u.entries ) return( NULL ); entry += info->info_off; sect = FindInfo( ii, im ); lnk = &GET_LINK( sect, entry ); if( IS_RESIDENT( *lnk ) ) { section = MK_DMND_PTR( *lnk ); } else { /* section not loaded */ size = DMND_SIZE( sect, entry ); if( (LastDemand->owner == NULL || LastDemand->size < size) && LastDemand->locks == 0 ) { /* keep largest section in LastDemand */ section = LastDemand; Unload( LastDemand ); } else { /* allocate some memory */ section = DCAlloc( _demand_size( size ) ); if( section == NULL ) { if( LastDemand->locks != 0 ) return( NULL ); /* no memory, use last chance */ section = LastDemand; Unload( LastDemand ); } } tmpoff = MK_DMND_OFFSET( *lnk ); if( InfoRead( sect, tmpoff, size, section->buff ) != DS_OK ) { if( section != LastDemand ) DCFree( section ); return( NULL ); } section->size = size; section->locks = 0; section->clear = clear; section->owner = lnk; section->save = *lnk; *lnk = STASH_DMND_PTR( section ); if( section != LastDemand ) { section->link = DemandList; DemandList = section; } } section->time_stamp = TimeStamp; /* for removal priority */ section->locks++; return( section->buff ); }
/* // pass auxiliary information to back end */ VOIDPTR FEAuxInfo( CGSYM_HANDLE cgsym_handle, int request ) { SYM_HANDLE sym_handle = cgsym_handle; struct aux_info *inf; auto SYM_ENTRY sym; static hw_reg_set save_set; switch( request ) { case SOURCE_LANGUAGE: return( "C" ); case OBJECT_FILE_NAME: return( (VOIDPTR)ObjFileName( OBJ_EXT ) ); case REVISION_NUMBER: return( (VOIDPTR)II_REVISION ); case AUX_LOOKUP: return( (VOIDPTR)sym_handle ); case SOURCE_NAME: if( SrcFName == ModuleName ) { return( FNameFullPath( FNames ) ); } else { return( ModuleName ); } case CALL_CLASS: GetCallClass( sym_handle ); return( &CallClass ); case NEXT_LIBRARY: case LIBRARY_NAME: return( NextLibrary( (int)sym_handle, request ) ); case NEXT_IMPORT: case IMPORT_NAME: return( NextImport( (int)sym_handle, request ) ); case NEXT_IMPORT_S: case IMPORT_NAME_S: return( NextImportS( (int)sym_handle, request ) ); case NEXT_ALIAS: case ALIAS_NAME: case ALIAS_SYMBOL: case ALIAS_SUBST_NAME: case ALIAS_SUBST_SYMBOL: return( NextAlias( (int)sym_handle, request ) ); case FREE_SEGMENT: return( NULL ); case TEMP_LOC_NAME: return( (char *)TEMP_LOC_QUIT ); case TEMP_LOC_TELL: return( NULL ); case NEXT_DEPENDENCY: /* 03-dec-92 */ if( CompFlags.emit_dependencies ) return( NextDependency( (FNAMEPTR) cgsym_handle ) ); return( NULL ); case DEPENDENCY_TIMESTAMP: return( getFileDepTimeStamp( (FNAMEPTR)cgsym_handle ) ); case DEPENDENCY_NAME: return( FNameFullPath( (FNAMEPTR)cgsym_handle ) ); default: break; } inf = FindInfo( &sym, sym_handle ); switch( request ) { case SAVE_REGS: if( sym_handle != 0 ) { inf = LangInfo( sym.attrib, inf ); } else { sym.attrib = 0; } save_set = inf->save; return( &save_set ); case RETURN_REG: if( sym_handle != 0 ) { inf = LangInfo( sym.attrib, inf ); } return( &inf->returns ); case CALL_BYTES: return( inf->code ); case PARM_REGS: if( sym_handle != 0 ) { inf = LangInfo( sym.attrib, inf ); if( inf->code == NULL && VarFunc( &sym ) ) { return( DefaultVarParms ); } } return( inf->parms ); default: break; } return( NULL ); }
struct aux_info *InfoLookup( SYMPTR sym ) { char *name; struct aux_info *inf; struct aux_entry *ent; name = sym->name; inf = &DefaultInfo; /* assume default */ if( name == NULL ) return( inf ); /* 01-jun-90 */ ent = AuxLookup( name ); if( ent != NULL ) inf = ent->info; if( ( ent == NULL ) || (sym->flags & SYM_INTRINSIC) ) { if( sym->flags & SYM_DEFINED ) return( inf ); if( !(sym->flags & SYM_INTRINSIC) ) { if( memcmp( name, "_inline_", 8 ) != 0 ) return( inf ); name += 8; } #if ( _CPU == 8086 ) || ( _CPU == 386 ) { struct inline_funcs *ifunc; ifunc = IF_Lookup( name ); if( ifunc == NULL ) return( inf ); #if ( _CPU == 8086 ) if( HW_CEqual( ifunc->returns, HW_DX_AX ) || HW_CEqual( ifunc->returns, HW_DS_SI ) || HW_CEqual( ifunc->returns, HW_ES_DI ) || HW_CEqual( ifunc->returns, HW_CX_DI ) ) { if( SizeOfArg( sym->sym_type->object ) != 4 ) { #else if( HW_CEqual( ifunc->returns, HW_DX_AX ) || HW_CEqual( ifunc->returns, HW_DS_ESI ) || HW_CEqual( ifunc->returns, HW_ES_EDI ) || HW_CEqual( ifunc->returns, HW_CX_DI ) ) { if( SizeOfArg( sym->sym_type->object ) != 6 ) { #endif return( inf ); } } inf = &InlineInfo; inf->cclass = (WatcallInfo.cclass & FAR) | MODIFY_EXACT; if( (sym->flags & SYM_INTRINSIC) && ( ent != NULL ) ) inf->cclass |= ent->info->cclass; inf->code = ifunc->code; inf->parms = ifunc->parms; inf->returns = ifunc->returns; #if ( _CPU == 8086 ) if( !HW_CEqual( inf->returns, HW_AX ) && !HW_CEqual( inf->returns, HW_EMPTY ) ) { #else if( !HW_CEqual( inf->returns, HW_EAX ) && !HW_CEqual( inf->returns, HW_EMPTY ) ) { #endif inf->cclass |= SPECIAL_RETURN; } HW_CAsgn( inf->streturn, HW_EMPTY ); inf->save = ifunc->save; inf->objname = WatcallInfo.objname; /* 26-jan-93 */ inf->use = 1; } #endif } return( inf ); } struct aux_info *FindInfo( SYM_ENTRY *sym, SYM_HANDLE sym_handle ) { SYM_ENTRY sym_typedef; struct aux_entry *ent; TYPEPTR typ; struct aux_info *inf; inf = &DefaultInfo; /* assume default */ if( sym_handle == 0 ) return( inf ); SymGet( sym, sym_handle ); #if _CPU == 386 if( (sym_handle == SymSTOSB) || (sym_handle == SymSTOSD) ) { return( &STOSBInfo ); } else if( sym_handle == SymFinally ) { static byte_seq FinallyCode = { 1, { 0xc3 } }; /* ret */ InlineInfo = WatcallInfo; InlineInfo.code = &FinallyCode; return( &InlineInfo ); } else if( sym_handle == SymTryFini ) { static hw_reg_set TryFiniParms[] = { HW_D( HW_EAX ), HW_D( HW_EMPTY ) }; static byte_seq TryFiniCode = { 6, { 0x64, 0xA3, 0, 0, 0, 0 } }; /* mov fs:[0],eax */ InlineInfo = WatcallInfo; InlineInfo.parms = TryFiniParms; InlineInfo.code = &TryFiniCode; return( &InlineInfo ); } #endif if( !(sym->flags & SYM_TEMP) ) { /* not an indirect func call*/ inf = InfoLookup( sym ); } if( inf == &DefaultInfo ) { typ = SkipDummyTypedef( sym->sym_type ); if( typ->decl_type == TYPE_TYPEDEF ) { SymGet( &sym_typedef, typ->u.typedefn ); if( sym_typedef.name != NULL ) { ent = AuxLookup( sym_typedef.name ); if( ent != NULL ) { inf = ent->info; } } } } #if _CPU == 386 if( ( inf->flags & AUX_FLAG_FAR16 ) || ( sym->attrib & FLAG_FAR16 ) ) { if( ( (sym->attrib & FLAG_LANGUAGES) == LANG_PASCAL ) || ( inf->cclass & REVERSE_PARMS ) ) { return( &Far16PascalInfo ); } else { return( &Far16CdeclInfo ); } } #endif return( inf ); } int FunctionAborts( SYM_ENTRY *sym, SYM_HANDLE sym_handle ) /* 09-apr-93 */ { struct aux_entry *ent; if( sym_handle != 0 ) { /* 19-apr-93 */ SymGet( sym, sym_handle ); ent = AuxLookup( SymName( sym, sym_handle ) ); if( ent != NULL ) { if( ent->info->cclass & SUICIDAL ) { return( 1 ); } } } return( 0 ); } void GetCallClass( SYM_HANDLE sym_handle ) { struct aux_info *inf; SYM_ENTRY sym; CallClass = DefaultInfo.cclass; if( sym_handle != 0 ) { inf = FindInfo( &sym, sym_handle ); if( sym.flags & SYM_FUNCTION ) { if( inf != &DefaultInfo ) { CallClass = inf->cclass; } else { CallClass = GetLangInfo( sym.attrib )->cclass; #if _CPU == 8086 if( TargSys == TS_WINDOWS ) { if( sym.attrib & (LANG_CDECL | LANG_PASCAL) ) { CallClass |= FAT_WINDOWS_PROLOG; } } #endif } #if ( _CPU == 8086 ) || ( _CPU == 386 ) if( CompFlags.emit_names ) { CallClass |= EMIT_FUNCTION_NAME; } if( sym.attrib & FLAG_FAR ) { CallClass |= FAR; if( sym.attrib & FLAG_NEAR ) { CallClass |= INTERRUPT; } } else if( sym.attrib & FLAG_NEAR ) { CallClass &= ~ FAR; } #endif #ifdef DLL_EXPORT if( sym.attrib & FLAG_EXPORT ) { /* 12-mar-90 */ CallClass |= DLL_EXPORT; } #endif #ifdef LOAD_DS_ON_ENTRY if( sym.attrib & FLAG_LOADDS ) { /* 26-apr-90 */ #if 0 /* John - 11-mar-93 */ /* 21-feb-93 */ if( TargSys == TS_WINDOWS ) { CallClass |= FAT_WINDOWS_PROLOG; } else { CallClass |= LOAD_DS_ON_ENTRY; } #else CallClass |= LOAD_DS_ON_ENTRY; #endif } #endif #ifdef MAKE_CALL_INLINE if( IsInLineFunc( sym_handle ) ) { CallClass |= MAKE_CALL_INLINE; } #endif if( VarFunc( &sym ) ) { CallClass |= CALLER_POPS | HAS_VARARGS; } } } #ifdef REVERSE CallClass &= ~ REVERSE_PARMS; /* 28-may-89 */ #endif #if ( _CPU == 8086 ) || ( _CPU == 386 ) if( sym_handle != 0 && sym.flags & SYM_FUNC_NEEDS_THUNK ) { CallClass |= THUNK_PROLOG; } #endif #ifdef PROLOG_HOOKS if( CompFlags.ep_switch_used != 0 ) { CallClass |= PROLOG_HOOKS; } #endif #ifdef EPILOG_HOOKS if( CompFlags.ee_switch_used != 0 ) { CallClass |= EPILOG_HOOKS; } #endif #ifdef GROW_STACK if( CompFlags.sg_switch_used ) { CallClass |= GROW_STACK; } #endif #ifdef TOUCH_STACK if( CompFlags.st_switch_used ) { CallClass |= TOUCH_STACK; } #endif } static time_t *getFileDepTimeStamp( FNAMEPTR flist ) { static time_t stamp; #if ( ( _CPU == 8086 ) || ( _CPU == 386 ) ) && ( COMP_CFG_COFF == 0 ) stamp = _timet2dos( flist->mtime ); #else stamp = flist->mtime; #endif return( &stamp ); } /* // NextLibrary // Called (indirectly) from the code generator to inject automagically defined symbols. // Inputs: // index (n-1) // Usually called from a loop until we return 0/NULL to show no more libraries // request // NEXT_LIBRARY // examines the current flags to see if any libraries should be // automagically referenced and returns the relevant index if so. // LIBRARY_NAME // returns the requested name. // */ static VOIDPTR NextLibrary( int index, aux_class request ) { struct library_list *liblist; char *name = NULL; int i; i = 0; if( request == NEXT_LIBRARY ) ++index; for( liblist = HeadLibs; liblist; liblist = liblist->next ) { name = &liblist->prio; ++i; if( i == index ) { break; } } if( liblist == NULL ) { switch( index - i ) { case 1: /* return 1 for CLIB */ name = CLIB_Name; if( CompFlags.emit_library_any ) break; if( CompFlags.emit_library_with_main ) { if( CompFlags.has_main ) break; if( CompFlags.has_winmain ) break; if( CompFlags.bd_switch_used ) break; if( CompFlags.has_libmain ) break; if( CompFlags.bm_switch_used ) break; /* JBS */ ++index; } else { name = NULL; index = 0; // indicate all done } break; /* // MATHLIB is always referenced as a default library because // the linker wont include anything without a 'real' referenced // symbol */ case 2: /* return 2 for MATHLIB */ name = MATHLIB_Name; break; case 3: /* return 3 for EMULIB */ name = EmuLib_Name; if( EmuLib_Name != NULL ) break; // fall through case 4: /* used to be PCODE */ name = NULL; index = 0; // indicate all done break; default: break; } } /* // return library name, or */ if( request == LIBRARY_NAME ) return( name ); /* // library index */ return( (char *)index ); } // NextAlias // Called (indirectly) from the code generator to go through the list of // linker aliases. // Inputs: // index (n-1) // Called from a loop until we return 0/NULL to show no more aliases // request // NEXT_ALIAS // returns the index of next alias in the list, or zero if none. // ALIAS_NAME // returns the alias name, or NULL if alias refers to a symbol. // ALIAS_SYMBOL // returns the alias symbol, or NULL if alias refers to a name. // ALIAS_SUBSTITUTE // returns the name to be substituted for the alias. // // Note: One of ALIAS_NAME and ALIAS_SYMBOL will always be 0/NULL and the other // will be valid, depending on which form of the pragma was used. static VOIDPTR NextAlias( int index, aux_class request ) { struct alias_list *aliaslist; SYM_HANDLE alias_sym = NULL; SYM_HANDLE subst_sym = NULL; const char *alias_name = NULL; const char *subst_name = NULL; int i; if( request == NEXT_ALIAS ) ++index; for( i = 1, aliaslist = AliasHead; aliaslist; aliaslist = aliaslist->next, ++i ) { alias_name = aliaslist->name; alias_sym = aliaslist->a_sym; subst_name = aliaslist->subst; subst_sym = aliaslist->s_sym; if( i == index ) { break; } } if( aliaslist == NULL ) index = 0; /* no (more) aliases */ if( request == ALIAS_NAME ) { return( (VOIDPTR)alias_name ); } else if( request == ALIAS_SYMBOL ) { return( (VOIDPTR)alias_sym ); } else if( request == ALIAS_SUBST_NAME ) { return( (VOIDPTR)subst_name ); } else if( request == ALIAS_SUBST_SYMBOL ) { return( (VOIDPTR)subst_sym ); } else { // this had better be a NEXT_ALIAS request return( (VOIDPTR)index ); } } /* Return the size of function parameters or -1 if size could * not be determined (symbol isn't a function or is variadic) */ static int GetParmsSize( CGSYM_HANDLE sym_handle ) { int total_parm_size = 0; int parm_size; TYPEPTR fn_typ; TYPEPTR *parm; TYPEPTR typ; SYM_ENTRY sym; SymGet( &sym, sym_handle ); fn_typ = sym.sym_type; SKIP_TYPEDEFS( fn_typ ); if( fn_typ->decl_type == TYPE_FUNCTION ) { parm = fn_typ->u.fn.parms; if( parm != NULL ) { for( ; (typ = *parm); ++parm ) { if( typ->decl_type == TYPE_DOT_DOT_DOT ) { total_parm_size = -1; break; } SKIP_TYPEDEFS( typ ); if( typ->decl_type == TYPE_VOID ) break; parm_size = TypeSize( typ ); parm_size = (parm_size + sizeof( target_int ) - 1) & -sizeof( target_int ); total_parm_size += parm_size; } } } else { total_parm_size = -1; } return( total_parm_size ); } /* // Return name pattern manipulator string */ static char *GetNamePattern( CGSYM_HANDLE sym_handle ) { char *pattern; SYM_ENTRY sym; struct aux_info *inf; inf = FindInfo( &sym, sym_handle ); #ifdef __SEH__ if(( sym_handle == SymTryInit ) || ( sym_handle == SymTryFini ) || ( sym_handle == SymTryUnwind ) || ( sym_handle == SymExcept )) { pattern = "*"; } else { #endif inf = LangInfo( sym.attrib, inf ); if( sym.flags & SYM_FUNCTION ) { pattern = inf->objname; #if ( _CPU == 386 ) || ( _CPU == 8086 ) if( VarFunc( &sym ) ) { if( inf == &DefaultInfo ) inf = DftCallConv; if( inf == &StdcallInfo ) { pattern = CdeclInfo.objname; } else if( inf == &FastcallInfo ) { pattern = CdeclInfo.objname; } } #endif if( pattern == NULL ) { pattern = TS_CODE_MANGLE; } } else { pattern = VarNamePattern( inf ); if( pattern == NULL ) { pattern = TS_DATA_MANGLE; } } #ifdef __SEH__ } // close that else #endif return( pattern ); }
/* // This section is for // 8086 // 386 // // pass auxiliary information to back end */ CGPOINTER FEAuxInfo( CGPOINTER req_handle, int request ) { aux_info *inf; auto SYM_ENTRY sym; static hw_reg_set save_set; switch( request ) { case SOURCE_LANGUAGE: return( (CGPOINTER)"C" ); case STACK_SIZE_8087: return( (CGPOINTER)(pointer_int)Stack87 ); case CODE_GROUP: return( (CGPOINTER)GenCodeGroup ); case DATA_GROUP: return( (CGPOINTER)DataSegName ); case OBJECT_FILE_NAME: return( (CGPOINTER)ObjFileName() ); case REVISION_NUMBER: return( (CGPOINTER)(pointer_int)II_REVISION ); case AUX_LOOKUP: return( req_handle ); case PROEPI_DATA_SIZE: return( (CGPOINTER)(pointer_int)ProEpiDataSize ); case DBG_PREDEF_SYM: return( (CGPOINTER)SymDFAbbr ); case P5_CHIP_BUG_SYM: return( (CGPOINTER)SymChipBug ); case CODE_LABEL_ALIGNMENT: { static unsigned char Alignment[] = { 2, 1, 1 }; if( OptSize == 0 ) Alignment[1] = TARGET_INT; return( (CGPOINTER)Alignment ); } case CLASS_NAME: return( (CGPOINTER)SegClassName( (segment_id)(pointer_int)req_handle ) ); case USED_8087: CompFlags.pgm_used_8087 = 1; return( NULL ); #if _CPU == 386 case P5_PROF_DATA: return( (CGPOINTER)FunctionProfileBlock ); case P5_PROF_SEG: return( (CGPOINTER)(pointer_int)FunctionProfileSegment ); #endif case SOURCE_NAME: if( SrcFName == ModuleName ) { return( (CGPOINTER)FNameFullPath( FNames ) ); } else { return( (CGPOINTER)ModuleName ); } case CALL_CLASS: { static call_class cclass; cclass = GetCallClass( req_handle ); return( (CGPOINTER)&cclass ); } case FREE_SEGMENT: return( NULL ); case NEXT_LIBRARY: case LIBRARY_NAME: return( NextLibrary( (int)(pointer_int)req_handle, request ) ); case NEXT_IMPORT: case IMPORT_NAME: return( NextImport( (int)(pointer_int)req_handle, request ) ); case NEXT_IMPORT_S: case IMPORT_NAME_S: return( NextImportS( (int)(pointer_int)req_handle, request ) ); case NEXT_ALIAS: case ALIAS_NAME: case ALIAS_SYMBOL: case ALIAS_SUBST_NAME: case ALIAS_SUBST_SYMBOL: return( NextAlias( (int)(pointer_int)req_handle, request ) ); case TEMP_LOC_NAME: return( (CGPOINTER)(pointer_int)TEMP_LOC_QUIT ); case TEMP_LOC_TELL: return( NULL ); case NEXT_DEPENDENCY: if( CompFlags.emit_dependencies ) return( (CGPOINTER)NextDependency( (FNAMEPTR)req_handle ) ); return( NULL ); case DEPENDENCY_TIMESTAMP: return( (CGPOINTER)getFileDepTimeStamp( (FNAMEPTR)req_handle ) ); case DEPENDENCY_NAME: return( (CGPOINTER)FNameFullPath( (FNAMEPTR)req_handle ) ); case PEGGED_REGISTER: return( (CGPOINTER)SegPeggedReg( (segment_id)(pointer_int)req_handle ) ); default: break; } inf = FindInfo( &sym, req_handle ); switch( request ) { case SAVE_REGS: if( req_handle != 0 ) { inf = LangInfo( sym.mods, inf ); } else { sym.mods = 0; } save_set = inf->save; if( sym.mods & FLAG_SAVEREGS ) { HW_CTurnOn( save_set, HW_SEGS ); } #ifdef __SEH__ if( (SYM_HANDLE)req_handle == SymTryInit ) { HW_CTurnOff( save_set, HW_SP ); } #endif return( (CGPOINTER)&save_set ); case RETURN_REG: if( req_handle != 0 ) { inf = LangInfo( sym.mods, inf ); } return( (CGPOINTER)&inf->returns ); case CALL_BYTES: return( (CGPOINTER)inf->code ); case PARM_REGS: #ifdef __SEH__ if(( (SYM_HANDLE)req_handle == SymTryInit ) || ( (SYM_HANDLE)req_handle == SymTryFini ) || ( (SYM_HANDLE)req_handle == SymTryUnwind ) || ( (SYM_HANDLE)req_handle == SymExcept )) { return( (CGPOINTER)TryParms ); } #endif if( req_handle != 0 ) { inf = LangInfo( sym.mods, inf ); if( inf->code == NULL && VarFunc( &sym ) ) { return( (CGPOINTER)DefaultVarParms ); } } return( (CGPOINTER)inf->parms ); case STRETURN_REG: if( req_handle != 0 ) { inf = LangInfo( sym.mods, inf ); } return( (CGPOINTER)&inf->streturn ); default: break; } return( NULL ); }
static aux_info *InfoLookup( SYMPTR sym ) { char *name; aux_info *inf; aux_entry *ent; name = sym->name; inf = &DefaultInfo; /* assume default */ if( name == NULL ) return( inf ); ent = AuxLookup( name ); if( ent != NULL ) inf = ent->info; if( ( ent == NULL ) || (sym->flags & SYM_INTRINSIC) ) { if( sym->flags & SYM_DEFINED ) return( inf ); if( (sym->flags & SYM_INTRINSIC) == 0 ) { if( memcmp( name, "_inline_", 8 ) != 0 ) return( inf ); name += 8; } #if ( _CPU == 8086 ) || ( _CPU == 386 ) { const inline_funcs *ifunc; ifunc = IF_Lookup( name ); if( ifunc == NULL ) return( inf ); #if ( _CPU == 8086 ) if( HW_CEqual( ifunc->returns, HW_DX_AX ) || HW_CEqual( ifunc->returns, HW_DS_SI ) || HW_CEqual( ifunc->returns, HW_ES_DI ) || HW_CEqual( ifunc->returns, HW_CX_DI ) ) { if( SizeOfArg( sym->sym_type->object ) != 4 ) { #else if( HW_CEqual( ifunc->returns, HW_DX_AX ) || HW_CEqual( ifunc->returns, HW_DS_ESI ) || HW_CEqual( ifunc->returns, HW_ES_EDI ) || HW_CEqual( ifunc->returns, HW_CX_DI ) ) { if( SizeOfArg( sym->sym_type->object ) != 6 ) { #endif return( inf ); } } inf = &InlineInfo; inf->cclass = (WatcallInfo.cclass & FAR_CALL) | MODIFY_EXACT; if( (sym->flags & SYM_INTRINSIC) && ( ent != NULL ) ) inf->cclass |= ent->info->cclass; inf->code = ifunc->code; inf->parms = ifunc->parms; inf->returns = ifunc->returns; #if ( _CPU == 8086 ) if( !HW_CEqual( inf->returns, HW_AX ) && !HW_CEqual( inf->returns, HW_EMPTY ) ) { #else if( !HW_CEqual( inf->returns, HW_EAX ) && !HW_CEqual( inf->returns, HW_EMPTY ) ) { #endif inf->cclass |= SPECIAL_RETURN; } HW_CAsgn( inf->streturn, HW_EMPTY ); inf->save = ifunc->save; inf->objname = WatcallInfo.objname; inf->use = 1; } #endif } return( inf ); } aux_info *FindInfo( SYMPTR sym, SYM_HANDLE sym_handle ) { SYM_ENTRY sym_typedef; aux_entry *ent; TYPEPTR typ; aux_info *inf; inf = &DefaultInfo; /* assume default */ if( sym_handle == SYM_NULL ) return( inf ); SymGet( sym, sym_handle ); #if _CPU == 386 if( (sym_handle == SymSTOSB) || (sym_handle == SymSTOSD) ) { return( &STOSBInfo ); } else if( sym_handle == SymFinally ) { InlineInfo = WatcallInfo; InlineInfo.code = (byte_seq *)&FinallyCode; return( &InlineInfo ); } else if( sym_handle == SymTryFini ) { InlineInfo = WatcallInfo; InlineInfo.parms = TryFiniParms; InlineInfo.code = (byte_seq *)&TryFiniCode; return( &InlineInfo ); } #endif if( (sym->flags & SYM_TEMP) == 0 ) { /* not an indirect func call*/ inf = InfoLookup( sym ); } if( inf == &DefaultInfo ) { typ = sym->sym_type; SKIP_DUMMY_TYPEDEFS( typ ); if( typ->decl_type == TYPE_TYPEDEF ) { SymGet( &sym_typedef, typ->u.typedefn ); if( sym_typedef.name != NULL ) { ent = AuxLookup( sym_typedef.name ); if( ent != NULL ) { inf = ent->info; } } } } #if _CPU == 386 if( (inf->flags & AUX_FLAG_FAR16) || (sym->mods & FLAG_FAR16) ) { if( (sym->mods & MASK_LANGUAGES) == LANG_PASCAL || (inf->cclass & REVERSE_PARMS) ) { return( &Far16PascalInfo ); } else { return( &Far16CdeclInfo ); } } #endif return( inf ); } bool FunctionAborts( SYMPTR sym, SYM_HANDLE sym_handle ) { aux_entry *ent; if( sym_handle != SYM_NULL ) { SymGet( sym, sym_handle ); ent = AuxLookup( SymName( sym, sym_handle ) ); if( ent != NULL ) { if( ent->info->cclass & SUICIDAL ) { return( TRUE ); } } } return( FALSE ); } call_class GetCallClass( SYM_HANDLE sym_handle ) { aux_info *inf; SYM_ENTRY sym; call_class cclass; cclass = DefaultInfo.cclass; if( sym_handle != SYM_NULL ) { inf = FindInfo( &sym, sym_handle ); if( sym.flags & SYM_FUNCTION ) { if( inf != &DefaultInfo ) { cclass = inf->cclass; } else { cclass = GetLangInfo( sym.mods )->cclass; #if _CPU == 8086 if( TargSys == TS_WINDOWS ) { if( sym.mods & (LANG_CDECL | LANG_PASCAL) ) { cclass |= FAT_WINDOWS_PROLOG; } } #endif } #if ( _CPU == 8086 ) || ( _CPU == 386 ) if( CompFlags.emit_names ) { cclass |= EMIT_FUNCTION_NAME; } if( sym.mods & FLAG_FAR ) { cclass |= FAR_CALL; if( sym.mods & FLAG_NEAR ) { cclass |= INTERRUPT; } } else if( sym.mods & FLAG_NEAR ) { cclass &= ~ FAR_CALL; } #endif #ifdef DLL_EXPORT if( sym.mods & FLAG_EXPORT ) { cclass |= DLL_EXPORT; } #endif #ifdef LOAD_DS_ON_ENTRY if( sym.mods & FLAG_LOADDS ) { #if 0 if( TargSys == TS_WINDOWS ) { cclass |= FAT_WINDOWS_PROLOG; } else { cclass |= LOAD_DS_ON_ENTRY; } #else cclass |= LOAD_DS_ON_ENTRY; #endif } #endif #ifdef MAKE_CALL_INLINE if( IsInLineFunc( sym_handle ) ) { cclass |= MAKE_CALL_INLINE; } #endif if( VarFunc( &sym ) ) { cclass |= CALLER_POPS | HAS_VARARGS; } } #if ( _CPU == 8086 ) || ( _CPU == 386 ) if( sym.flags & SYM_FUNC_NEEDS_THUNK ) { cclass |= THUNK_PROLOG; } #endif } #ifdef REVERSE cclass &= ~ REVERSE_PARMS; #endif #ifdef PROLOG_HOOKS if( CompFlags.ep_switch_used != 0 ) { cclass |= PROLOG_HOOKS; } #endif #ifdef EPILOG_HOOKS if( CompFlags.ee_switch_used != 0 ) { cclass |= EPILOG_HOOKS; } #endif #ifdef GROW_STACK if( CompFlags.sg_switch_used ) { cclass |= GROW_STACK; } #endif #ifdef TOUCH_STACK if( CompFlags.st_switch_used ) { cclass |= TOUCH_STACK; } #endif return( cclass ); }
CStdWindow *CStdWindow::Init(CStdApp *pApp, const char *Title, CStdWindow *pParent, bool HideCursor) { #ifndef USE_X11 return this; #else Active = true; dpy = pApp->dpy; if (!FindInfo()) return 0; // Various properties XSetWindowAttributes attr; attr.border_pixel = 0; attr.background_pixel = 0; // Which events we want to receive attr.event_mask = // EnterWindowMask | // LeaveWindowMask | StructureNotifyMask | FocusChangeMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask; attr.colormap = XCreateColormap(dpy, DefaultRootWindow(dpy), ((XVisualInfo *)Info)->visual, AllocNone); unsigned long attrmask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; Pixmap bitmap; if (HideCursor) { // Hide the mouse cursor XColor cursor_color; // We do not care what color the invisible cursor has memset(&cursor_color, 0, sizeof(cursor_color)); bitmap = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), "\000", 1, 1); attr.cursor = XCreatePixmapCursor(dpy, bitmap, bitmap, &cursor_color, &cursor_color, 0, 0); attrmask |= CWCursor; } wnd = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, 640, 480, 0, ((XVisualInfo *)Info)->depth, InputOutput, ((XVisualInfo *)Info)->visual, attrmask, &attr); if (HideCursor) { XFreeCursor(dpy, attr.cursor); XFreePixmap(dpy, bitmap); } if (!wnd) { Log("Error creating window."); return 0; } // Update the XWindow->CStdWindow-Map CStdAppPrivate::SetWindow(wnd, this); if (!pApp->Priv->xic && pApp->Priv->xim) { pApp->Priv->xic = XCreateIC( pApp->Priv->xim, XNClientWindow, wnd, XNFocusWindow, wnd, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNResourceName, STD_PRODUCT, XNResourceClass, STD_PRODUCT, NULL); if (!pApp->Priv->xic) { Log("Failed to create input context."); XCloseIM(pApp->Priv->xim); pApp->Priv->xim = 0; } else { long ic_event_mask; if (XGetICValues(pApp->Priv->xic, XNFilterEvents, &ic_event_mask, NULL) == NULL) attr.event_mask |= ic_event_mask; XSelectInput(dpy, wnd, attr.event_mask); XSetICFocus(pApp->Priv->xic); } } // We want notification of closerequests and be killed if we hang Atom WMProtocols[2]; char *WMProtocolnames[] = {"WM_DELETE_WINDOW", "_NET_WM_PING"}; XInternAtoms(dpy, WMProtocolnames, 2, false, WMProtocols); XSetWMProtocols(dpy, wnd, WMProtocols, 2); // Let the window manager know our pid so it can kill us Atom PID = XInternAtom(pApp->dpy, "_NET_WM_PID", false); int32_t pid = getpid(); if (PID != None) XChangeProperty(pApp->dpy, wnd, PID, XA_CARDINAL, 32, PropModeReplace, reinterpret_cast<const unsigned char *>(&pid), 1); // Title and stuff XTextProperty title_property; StdStrBuf tbuf; tbuf.Copy(Title ? Title : ""); char *tbufstr = tbuf.getMData(); // char * title = "Clonk Endeavour"; XStringListToTextProperty(&tbufstr, 1, &title_property); // State and Icon XWMHints *wm_hint = XAllocWMHints(); wm_hint->flags = StateHint | InputHint | IconPixmapHint | IconMaskHint; wm_hint->initial_state = NormalState; wm_hint->input = True; // Trust XpmCreatePixmapFromData to not modify the xpm... XpmCreatePixmapFromData(dpy, wnd, const_cast<char **>(c4x_xpm), &wm_hint->icon_pixmap, &wm_hint->icon_mask, 0); // Window class XClassHint *class_hint = XAllocClassHint(); class_hint->res_name = STD_PRODUCT; class_hint->res_class = STD_PRODUCT; XSetWMProperties(dpy, wnd, &title_property, &title_property, pApp->Priv->argv, pApp->Priv->argc, 0, wm_hint, class_hint); // Set "parent". Clonk does not use "real" parent windows, but multiple // toplevel windows. if (pParent) XSetTransientForHint(dpy, wnd, pParent->wnd); // Show window XMapWindow(dpy, wnd); // Clean up // The pixmap has to stay as long as the window exists, so it does not hurt to // never free it. // XFreePixmap(dpy,xwmh->icon_pixmap); // XFreePixmap(dpy,xwmh->icon_mask); XFree(title_property.value); Hints = wm_hint; XFree(class_hint); // Render into whole window renderwnd = wnd; return this; #endif // USE_X11 }