// ph.cxx // // Copyright 1989-94, Microsoft Corporation // // [01] 03-dec-91 DavidGra // Correct the BSearch to return the nearest element // less than the key element when there is not an // exact match. // // [00] 15-nov-91 DavidGra // Suppress hashing when the SSTR_NoHash bit it set. // // 11/1/94 BryanT // Merge in NT changes // Remove fChild arg from SHFindNameInGlobal (unused) #include "shinc.hpp" #pragma hdrstop BOOL VerifyHexe (HEXE); ULONG GSTBSearch (UOFFSET, LPALM, ULONG, ULONG, UOFFSET *); __inline SYMPTR FindNameLinearInGlobs (LPEXG, SYMPTR, LPSSTR, PFNCMP, SHFLAG); __inline SYMPTR FindNameLinearInPubs (LPEXG, SYMPTR, LPSSTR, PFNCMP, SHFLAG); SYMPTR GSTFindNameLinear (LPEXG, LPGST, SYMPTR, LPSSTR, PFNCMP, SHFLAG); __inline SYMPTR FindNameHashedInGlobs(LPEXG, SYMPTR, LPSSTR, PFNCMP, SHFLAG, HMOD *); __inline SYMPTR FindNameHashedInStatics(LPEXG, SYMPTR, LPSSTR, PFNCMP, SHFLAG, HMOD *); __inline SYMPTR FindNameHashedInPubs (LPEXG, SYMPTR, LPSSTR, PFNCMP, SHFLAG, HMOD *); SYMPTR GSTFindNameHashed (LPEXG, LPGST, SYMPTR, LPSSTR, PFNCMP, SHFLAG, HMOD *); __inline SYMPTR FindNearest (LPEXG, LPADDR, LPL); SYMPTR GSTFindNearest (LPEXG, LPGST, LPADDR, LPL); SYMPTR PsymFromRef (LPEXG, SYMPTR, HMOD *); BOOL GSTCmpName (SYMPTR, LPSSTR, PFNCMP, SHFLAG); SYMPTR GSIFindNameLinear (LPEXG, GSI*, SYMPTR, LPSSTR, PFNCMP, SHFLAG); SYMPTR GSIFindNameHashed (LPEXG, GSI*, SYMPTR, LPSSTR, PFNCMP, SHFLAG, HMOD *); __inline void lpStrToSz(LPSSTR lpsstr, char* sz) { assert(lpsstr->cb < 256); memcpy(sz, lpsstr->lpName, lpsstr->cb); sz[lpsstr->cb] = 0; } // PHExactCmp // // Purpose: Compare two strings. // // Input: // lsz Zero terminated string for compare // hsym -- not used -- // lstz Zero terminated length prefixed string for compare // fCase Perform case sensitive compare? // // Output: Return ZERO if strings are equal, else non-zero. SHFLAG PHExactCmp( HVOID hvStr, HVOID hvSym, LSZ lpb, SHFLAG fCase ) { LPSSTR lpsstr = (LPSSTR) hvStr; size_t cb; SHFLAG shf = TRUE; Unreferenced (hvSym); if (lpb) { cb = (size_t)*lpb; // if length is diff, they are not equal if (lpsstr && (size_t) lpsstr->cb == cb) { if (fCase) { shf = (SHFLAG) memcmp (lpb + 1, lpsstr->lpName, cb); } else { shf = (SHFLAG) _tcsnicmp(lpb + 1, (_TXCHAR *)lpsstr->lpName, cb); } } } return shf; } // PHGetNearestHsym // // Purpose: To find a public symbol within a module // // Input: // paddr - The address of the symbol to find // hExe - The exe to look in for the symbol in // phsym - The symbol pointer // // Output: // Returns How far (in bytes) the found symbol is from the address. // CV_MAXOFFSET is returned if non is found. CV_uoff32_t PHGetNearestHsym( LPADDR lpaddr, HEXE hexe, PHSYM phsym ) { CV_uoff32_t dCur = CV_MAXOFFSET; LPEXE lpexe; LPEXG lpexg; *phsym = NULL; if (!VerifyHexe (hexe)) { return dCur; } lpexe = (LPEXE) LLLock (hexe); if (lpexe->hexg != hexgNull) { lpexg = (LPEXG) LLLock (lpexe->hexg); *phsym = FindNearest (lpexg, lpaddr, (LPL) &dCur); LLUnlock(lpexe->hexg); } LLUnlock(hexe); return dCur; } BOOL PHGetAddr( LPADDR paddr, LSZ lszName ) { HSYM hsym = NULL; HEXE hexe = 0; SSTR sstr = {0}; if (lszName == NULL || *lszName == '\0') { return FALSE; } sstr.lpName = (LPB) lszName; sstr.cb = (BYTE) _tcslen (lszName); if (!(hsym = PHFindNameInPublics (NULL, hexe = SHGetNextExe (hexeNull), (LPSSTR) &sstr, TRUE, PHExactCmp))) { return FALSE; } SHAddrFromHsym (paddr, hsym); assert (hexe); emiAddr (*paddr) = (HEMI) hexe; return TRUE; } // PHFindNameInPublics // // Purpose: To find a public symbol // // Input: // hsym - This must be NULL! In the future this routine may // be a find first find next behavior. For a first // find use NULL, for a next find use the last symbol. // hExe - The exe to search // hInfo - The info packet to give to the comparison routine // fCase - If TRUE do a case sensitive search. // pfnCm - A pointer to the comparison function // // Output: // Returns A public symbol or NULL on error // // Exceptions: For now, the input hsym MUST BE NULL! #define dwrd_toupper(dw) (dw & 0xDFDFDFDF) #define byt_toupper(b) (b & 0xDF) #define HASHFUNC(i,lpsstr,wModulo,lpul) \ ((i==6)?DWordXor(lpsstr,wModulo,lpul):DWordXorShift(lpsstr,wModulo,lpul)) ushort DWordXor( LPSSTR lpsstr, WORD wModulo, LPUL lpul ) { LPB lpbName = lpsstr->lpName; UNALIGNED ULONG * lpulName = (UNALIGNED ULONG*) lpbName; int cb = lpsstr->cb; int cul; int iul; ULONG ulSum = 0; ULONG ulEnd = 0; while (cb & 3) { ulEnd |= byt_toupper (lpbName [ cb - 1 ]); ulEnd <<= 8; cb -= 1; } cul = cb / 4; for (iul = 0; iul < cul; iul++) { ulSum ^= dwrd_toupper(lpulName[iul]); } ulSum ^= ulEnd; *lpul = ulSum; return (ushort) (ulSum % wModulo); } ushort DWordXorShift( LPSSTR lpsstr, WORD wModulo, LPUL lpul ) { LPB lpbName = lpsstr->lpName; UNALIGNED ULONG* lpulName = (UNALIGNED ULONG*) lpbName; int cb = lpsstr->cb; int cul; int iul; ULONG ulSum = 0; ULONG ulEnd = 0; while (cb & 3) { ulEnd |= byt_toupper (lpbName [ cb - 1 ]); ulEnd <<= 8; cb -= 1; } cul = cb / 4; for (iul = 0; iul < cul; iul++) { ulSum ^= dwrd_toupper(lpulName[iul]); ulSum = _lrotl (ulSum, 4); } ulSum ^= ulEnd; *lpul = ulSum; return (ushort) (ulSum % wModulo); } HSYM PHFindNameInPublics( HSYM hsym, HEXE hexe, LPSSTR lpsstr, SHFLAG fCase, PFNCMP pfnCmp ) { SYMPTR psym = (SYMPTR) hsym; LPEXE lpexe; LPEXG lpexg; if (hexe == hexeNull) { return NULL; } lpexe = (LPEXE) LLLock (hexe); if (lpexe->hexg == hexgNull) { psym = (SYMPTR)NULL; } else { lpexg = (LPEXG) LLLock (lpexe->hexg); if (lpsstr->searchmask & SSTR_NoHash) psym = FindNameLinearInPubs (lpexg, psym, lpsstr, pfnCmp, fCase); else psym = FindNameHashedInPubs (lpexg, psym, lpsstr, pfnCmp, fCase, NULL); LLUnlock (lpexe->hexg); } LLUnlock (hexe); return psym; } int SHPublicNameToAddr( PADDR loc, PADDR pMpAddr, LSZ lszName ) { CXT cxt = {0}; HSYM hsym = NULL; int wRet = FALSE; ADDR addr = *loc; SSTR sstr = {0}; sstr.lpName = (LPB) lszName; sstr.cb = (BYTE) _tcslen (lszName); // Look for the name in the public symbols of that .EXE hsym = PHFindNameInPublics( NULL, (HEXE) emiAddr(addr), &sstr, 0, PHExactCmp); if (hsym) { SYMPTR psym = (SYMPTR) hsym; switch (psym->rectyp) { case S_PUB16: ADDRSEG16 (*pMpAddr); SetAddrSeg (pMpAddr, ((DATAPTR16)psym)->seg); SetAddrOff (pMpAddr, ((DATAPTR16)psym)->off); break; case S_PUB32: ADDRLIN32 (*pMpAddr); SetAddrSeg (pMpAddr, ((DATAPTR32)psym)->seg); SetAddrOff (pMpAddr, ((DATAPTR32)psym)->off); break; } ADDR_IS_LI (*pMpAddr) = TRUE; emiAddr (*pMpAddr) = emiAddr (addr); wRet = TRUE; } return wRet; } ULONG GSTBSearch( UOFFSET uoffKey, LPALM lpalm, ULONG ibBase, ULONG cb, UOFFSET *lpoff ) { ULONG ibLow; ULONG ibHigh; ULONG ibMid = 0; ULONG cbWidth = sizeof (ULP); ULONG uoffFound = 0; LPULP lpulp = NULL; ibLow = 0; ibHigh = cb; while (ibLow < ibHigh) { ibMid = (ibLow + ibHigh) / 2; uoffFound = ((LPULP) (LpvFromAlmLfo (lpalm, ibBase + ibMid * cbWidth)))->ulId; if (uoffFound > uoffKey) { ibHigh = ibMid; } else if (uoffKey > uoffFound) { ibLow = ibMid + 1; } else { break; } } if (uoffFound > uoffKey && ibMid != 0) { ibMid -= 1; } lpulp = (LPULP) LpvFromAlmLfo (lpalm, ibBase + ibMid * cbWidth); *lpoff = lpulp->ulId; return lpulp->ib; } __inline SYMPTR FindNameLinearInGlobs( LPEXG lpexg, SYMPTR psym, LPSSTR lpsstr, PFNCMP pfnCmp, SHFLAG fCase ) { if (lpexg->pgsiGlobs) { return GSIFindNameLinear(lpexg, lpexg->pgsiGlobs, psym, lpsstr, pfnCmp, fCase); } else { return GSTFindNameLinear(lpexg, &lpexg->gstGlobals, psym, lpsstr, pfnCmp, fCase); } } __inline SYMPTR FindNameLinearInPubs( LPEXG lpexg, SYMPTR psym, LPSSTR lpsstr, PFNCMP pfnCmp, SHFLAG fCase ) { if (lpexg->pgsiPubs) { return GSIFindNameLinear(lpexg, lpexg->pgsiPubs, psym, lpsstr, pfnCmp, fCase); } else { return GSTFindNameLinear(lpexg, &lpexg->gstPublics, psym, lpsstr, pfnCmp, fCase); } } SYMPTR GSTFindNameLinear( LPEXG lpexg, LPGST lpgst, SYMPTR psym, LPSSTR lpsstr, PFNCMP pfnCmp, SHFLAG fCase ) { SYMPTR psymRet = NULL; if (lpgst->lpalm == NULL) return (SYMPTR)NULL; if (psym == NULL) { psym = (SYMPTR) LpvFromAlmLfo (lpgst->lpalm, 0); } else { psym = GetNextSym (psym, lpgst->lpalm); } while (psym != NULL) { SYMPTR psymT = psym; // NOTE: Don't find referenced procs/data in linear search if (psym->rectyp != S_PROCREF && psym->rectyp != S_DATAREF && GSTCmpName (psymT, lpsstr, pfnCmp, fCase)) { psymRet = psymT; break; } psym = GetNextSym (psym, lpgst->lpalm); } return psym; } SYMPTR GSIFindNameLinear( LPEXG lpexg, GSI* pgsi, SYMPTR psym, LPSSTR lpsstr, PFNCMP pfnCmp, SHFLAG fCase ) { SYMPTR psymRet = NULL; if (pgsi == NULL) return (SYMPTR)NULL; psym = (SYMPTR) GSINextSym (pgsi, (PB) psym); while (psym != NULL) { SYMPTR psymT = psym; // NOTE: Don't find referenced procs/data in linear search if ((psym->rectyp != S_PROCREF) && (psym->rectyp != S_LPROCREF) && GSTCmpName (psymT, lpsstr, pfnCmp, fCase) ) { psymRet = psymT; break; } psym = (SYMPTR) GSINextSym (pgsi, (PB) psym); } return psym; } __inline SYMPTR FindNameHashedInGlobs( LPEXG lpexg, SYMPTR psym, LPSSTR lpsstr, PFNCMP pfnCmp, SHFLAG fCase, HMOD *lphmod ) { if (lpexg->pgsiGlobs) { return GSIFindNameHashed (lpexg, lpexg->pgsiGlobs, psym, lpsstr, pfnCmp, fCase, lphmod); } else { return GSTFindNameHashed (lpexg, &lpexg->gstGlobals, psym, lpsstr, pfnCmp, fCase, lphmod); } } __inline SYMPTR FindNameHashedInStatics( LPEXG lpexg, SYMPTR psym, LPSSTR lpsstr, PFNCMP pfnCmp, SHFLAG fCase, HMOD *lphmod ) { if (lpexg->pgsiGlobs) // this assumes that the client has already completed an unsucessful search // thru the globals return (SYMPTR)NULL; else return GSTFindNameHashed(lpexg, &lpexg->gstStatics, psym, lpsstr, pfnCmp, fCase, lphmod ); } __inline SYMPTR FindNameHashedInPubs( LPEXG lpexg, SYMPTR psym, LPSSTR lpsstr, PFNCMP pfnCmp, SHFLAG fCase, HMOD *lphmod ) { if (lpexg->pgsiPubs) { return GSIFindNameHashed (lpexg, lpexg->pgsiPubs, psym, lpsstr, pfnCmp, fCase, lphmod); } else { return GSTFindNameHashed (lpexg, &lpexg->gstPublics, psym, lpsstr, pfnCmp, fCase, lphmod); } } SYMPTR GSTFindNameHashed( LPEXG lpexg, LPGST lpgst, SYMPTR psym, LPSSTR lpsstr, PFNCMP pfnCmp, SHFLAG fCase, HMOD *lphmod ) { LPSHT lpsht = &lpgst->shtName; if (lpsht->HashIndex == 0) { // No hash exists. Punt to the linear code. return(GSTFindNameLinear(lpexg, lpgst, psym, lpsstr, pfnCmp, fCase)); } ULONG ulId = 0; WORD iib = 0; SYMPTR psymRet = NULL; ULONG ib = 0; ULONG culp = 0; ULONG iulp = 0; BOOL fNext = psym != NULL; if ((lpsht->ccib == 0) ||(lpgst->lpalm == NULL)) return (SYMPTR)NULL; iib = HASHFUNC(lpsht->HashIndex, lpsstr, lpsht->ccib, &ulId); ib = lpsht->rgib [ iib ]; culp = lpsht->rgcib [ iib ]; // Loop through all the entries in this bucket for (iulp = 0; iulp < culp; iulp++) { LPULP lpulp = (LPULP) LpvFromAlmLfo (lpsht->lpalm, ib + (iulp * sizeof (ULP))); if (lpulp == NULL) { return NULL; } if (lpulp->ulId == ulId) { HMOD hmodT = hmodNull; // Checksums match, now check the symbols themselves SYMPTR psymT = (SYMPTR) LpvFromAlmLfo (lpgst->lpalm, lpulp->ib); if (psymT == NULL) { return NULL; } if (psymT->rectyp == S_PROCREF || psymT->rectyp == S_DATAREF) { psymT = PsymFromRef (lpexg, psymT, &hmodT); // catch case where there are no module symbols... [rm] if (psymT == NULL) return NULL; } if (fNext) { // We need to get back to the Current hsym before get can // get just one more. Soon as we are there we know we can // get the next one. if (psymT == psym) { fNext = FALSE; } continue; } if (GSTCmpName (psymT, lpsstr, pfnCmp, fCase)) { if (lphmod) *lphmod = hmodT; psymRet = psymT; break; } } } return psymRet; } SYMPTR GSIFindNameHashed( LPEXG lpexg, GSI* pgsi, SYMPTR psym, LPSSTR lpsstr, PFNCMP pfnCmp, SHFLAG fCase, HMOD *lphmod ) { HMOD hmodT = hmodNull; char szBuf[256]; SYMPTR psymGS; SYMPTR psymRet; BOOL fNext = psym != NULL; if (!pgsi) return (SYMPTR)NULL; lpStrToSz(lpsstr, szBuf); psymGS = (SYMPTR) GSIHashSym(pgsi, szBuf, (PB) psym); for (; psymGS; psymGS = (SYMPTR) GSIHashSym(pgsi, szBuf, (PB) psymGS)) { assert(psymGS->rectyp != S_DATAREF); // no datarefs if ((psymGS->rectyp == S_PROCREF) || (psymGS->rectyp == S_LPROCREF)) { psymRet = PsymFromRef (lpexg, psymGS, &hmodT); // catch case where there are no module symbols... [rm] if (psymRet == NULL) return NULL; } else psymRet = psymGS; if (fNext) { // We need to get back to the Current hsym before get can // get just one more. Soon as we are there we know we can // get the next one. if (psymRet == psym) { fNext = FALSE; } continue; } if (GSTCmpName (psymRet, lpsstr, pfnCmp, fCase)) { if (lphmod) *lphmod = hmodT; return psymRet; } } return NULL; } __inline SYMPTR FindNearest( LPEXG lpexg, LPADDR lpaddr, LPL lpdb ) { SYMPTR symptr; if (lpexg->pgsiPubs) { #pragma message ("Need to search pgsiGlobals in FindNearest for NB10") return (SYMPTR) GSINearestSym (lpexg->pgsiPubs, GetAddrSeg(*lpaddr), GetAddrOff(*lpaddr), lpdb); } else { SYMPTR symptrT; LONG db; // Search first in globals symptr = GSTFindNearest(lpexg, &lpexg->gstGlobals, lpaddr, lpdb); // Search in publics symptrT = GSTFindNearest(lpexg, &lpexg->gstPublics, lpaddr, &db); // If there's an entry in the publics AND there was either // no match in the globals or the delta for the public is // less than the delta for the global, use the public if (symptrT && (!symptr || labs(db) < labs (*lpdb))) { *lpdb = db; symptr = symptrT; } } return symptr; } SYMPTR GSTFindNearest( LPEXG lpexg, LPGST lpgst, LPADDR lpaddr, LPL lpdb ) { SYMPTR psym; ULONG db = CV_MAXOFFSET; LPSHT lpsht = &lpgst->shtAddr; WORD iseg; ULONG ibSym = 0; OFFSET off = GetAddrOff (*lpaddr); if (lpgst->lpalm == NULL) return NULL; // See if there's a hash index. If not, do a linear search. if (lpsht->HashIndex == 0) { SYMPTR psymClosest = NULL, psymT, psymEnd; HMOD hmodT; psym = (SYMPTR) LpvFromAlmLfo(lpgst->lpalm, ibSym); psymEnd = (SYMPTR) ((LPB) psym + lpgst->lpalm->cb); iseg = GetAddrSeg (*lpaddr); for (; psym < psymEnd; psym = NEXTSYM(SYMPTR, psym)) { if ((psym->rectyp == S_PROCREF) || (psym->rectyp == S_DATAREF)) { hmodT = hmodNull; psymT = PsymFromRef(lpexg, psym, &hmodT); if (psymT) { psymT = psym; } } else { psymT = psym; } switch (psymT->rectyp) { case S_PUB16: if ((iseg == ((DATAPTR16)psymT)->seg) && ((long) (off - ((DATAPTR16)psymT)->off) >= 0) && (db > (off - ((DATAPTR16)psymT)->off ))) { // we are closer, so save this symbol and offset db = (ULONG)(off - ((DATAPTR16)psymT)->off); psymClosest = psymT; } break; case S_PUB32: if ((iseg == ((DATAPTR32)psymT)->seg) && ((off - ((DATAPTR16)psymT)->off) >= 0) && (db > (off - ((DATAPTR32)psymT)->off))) { // we are closer, so save this symbol and offset db = (ULONG) (off - ((DATAPTR32)psymT)->off); psymClosest = psymT; } break; } if (db == 0) { // Got an exact match. break; } } psym = psymClosest; } else { iseg = GetAddrSeg (*lpaddr) - 1; if (iseg != 0xFFFF && iseg < lpsht->ccib && lpsht->rgcib [ iseg ] > 0) { UOFFSET offT = 0; ibSym = GSTBSearch (off, lpsht->lpalm, lpsht->rgib [ iseg ], (WORD) lpsht->rgcib [ iseg ], &offT); db = (off - offT); psym = (SYMPTR) LpvFromAlmLfo (lpgst->lpalm, ibSym); if (psym->rectyp == S_PROCREF || psym->rectyp == S_DATAREF) { HMOD hmodT = hmodNull; psym = PsymFromRef(lpexg, psym, &hmodT); // Couldn't get the ref, set the db to what // would be returned in an error condition if (!psym) { db = CV_MAXOFFSET; } } } } *lpdb = (LONG) db; return psym; } SYMPTR PsymFromRef( LPEXG lpexg, SYMPTR psymRef, HMOD *lphmod ) { REFSYM *lpref = (REFSYM *) psymRef; LPB lpbSymbols; LPMDS lpmds; assert(lpref->imod <= lpexg->cMod); lpmds = &lpexg->rgMod[lpref->imod - 1]; lpbSymbols = (LPB) GetSymbols (lpmds); if (lphmod) { *lphmod = (HMOD) lpmds; } // catch case where there are no module symbols... if (lpbSymbols == NULL) return NULL; // catch the case where the ibSym is beyond the symbol array if (lpref->ibSym > lpmds->cbSymbols) { return(NULL); } return (SYMPTR) (lpbSymbols + (WORD) lpref->ibSym); } BOOL GSTCmpName( SYMPTR psym, LPSSTR lpsstr, PFNCMP pfnCmp, SHFLAG fCase ) { LSZ lsz = NULL; // We are basically ignoring publics with set == 0 if ((psym->rectyp == S_PUB16 && ((DATAPTR16) psym)->seg == 0) || (psym->rectyp == S_PUB32 && ((DATAPTR32) psym)->seg == 0)) { return FALSE; } lsz = (LSZ) SHlszGetSymName (psym); if (lsz != NULL) { return (!(lpsstr->searchmask & SSTR_symboltype) || (psym->rectyp == lpsstr->symtype)) && !(*pfnCmp) (lpsstr, psym, lsz, fCase); } else { return FALSE; } } // SHFindNameInGlobal // // Purpose: To look for the name in the global symbol table. // // Input: // hSym - The starting symbol, if NULL, then the first symbol // in the global symbol table is used. (NULL is find first). // pCXT - The context to do the search. // lpsstr - pointer to search parameters (passed to the compare routine) // fCaseSensitive - TRUE/FALSE on a case sensitive search // pfnCmp - A pointer to the comparison routine // fChild - TRUE if all child block are to be searched, FALSE if // only the current block is to be searched. // // Output: // pCXTOut - The context generated // // Returns: // - A handle to the symbol found, NULL if not found // // Notes: // If an hSym is specified, the hMod, hGrp and addr MUST be // valid and consistant with each other! If hSym is NULL only // the hMod must be valid. The specification of an hSym // forces a search from the next symbol to the end of the // module scope. Continues searches may only be done at // module scope. // // If an hGrp is given it must be consistant with the hMod! HSYM SHFindNameInGlobal( HSYM hsym, PCXT pcxt, LPSSTR lpsstr, SHFLAG fCase, PFNCMP pfnCmp, PCXT pcxtOut ) { HEXG hexg; LPEXG lpexg; HEXE hexe; LPEXE lpexe; HMOD hmod = hmodNull; LPGST lpgst = NULL; SYMPTR psym = NULL; *pcxtOut = *pcxt; pcxtOut->hProc = NULL; pcxtOut->hBlk = NULL; if (!pcxt->hMod) { return NULL; } hexe = SHHexeFromHmod(pcxt->hGrp ? pcxt->hGrp : pcxt->hMod); lpexe = (LPEXE) LLLock(hexe); hexg = lpexe->hexg; lpexg = (LPEXG) LLLock (hexg); LLUnlock(hexe); // Make sure these symbols are loaded. // SHWantSymbols(hexe); if (lpsstr->searchmask & SSTR_NoHash) { psym = FindNameLinearInGlobs (lpexg, (SYMPTR) hsym, lpsstr, pfnCmp, fCase); } else { psym = FindNameHashedInGlobs (lpexg, (SYMPTR) hsym, lpsstr, pfnCmp, fCase, &hmod); if (hmod != hmodNull) { pcxtOut->hMod = pcxt->hGrp = hmod; switch (psym->rectyp) { case S_LPROC32: case S_GPROC32: case S_LPROC16: case S_GPROC16: case S_LPROCMIPS: case S_GPROCMIPS: emiAddr (pcxtOut->addr) = (HEMI) SHHexeFromHmod (hmod); SHAddrFromHsym (&pcxtOut->addr, psym); SHHPROCFrompCXT(pcxtOut) = psym; break; default: { LPMDS lpmds = (LPMDS) hmod; SetAddrFromMod(lpmds, &pcxtOut->addr); emiAddr (pcxtOut->addr) = (HEMI) SHHexeFromHmod (hmod); ADDR_IS_LI (pcxtOut->addr) = TRUE; break; } } } } LLUnlock (hexg); return psym; } HSYM FindNameInStatics( HSYM hsym, PCXT pcxt, LPSSTR lpsstr, SHFLAG fCase, PFNCMP pfnCmp, PCXT pcxtOut ) { HEXG hexg = hexgNull; HMOD hmod = hmodNull; LPEXG lpexg = NULL; LPGST lpgst = NULL; SYMPTR psym = NULL; *pcxtOut = *pcxt; pcxtOut->hProc = NULL; pcxtOut->hBlk = NULL; if (!pcxt->hGrp) { return NULL; } hexg = SHHexgFromHmod (pcxt->hGrp); lpexg = (LPEXG) LLLock (hexg); psym = FindNameHashedInStatics(lpexg, (SYMPTR) hsym, lpsstr, pfnCmp, fCase, &hmod); if (hmod != hmodNull) { pcxtOut->hMod = pcxt->hGrp = hmod; switch (psym->rectyp) { case S_LPROC32: case S_GPROC32: case S_LPROC16: case S_GPROC16: case S_LPROCMIPS: case S_GPROCMIPS: emiAddr (pcxtOut->addr) = (HEMI) SHHexeFromHmod (hmod); SHAddrFromHsym (&pcxtOut->addr, psym); SHHPROCFrompCXT(pcxtOut) = psym; break; default: { LPMDS lpmds = (LPMDS) hmod; SetAddrFromMod(lpmds, &pcxtOut->addr); emiAddr (pcxtOut->addr) = (HEMI) SHHexeFromHmod (hmod); ADDR_IS_LI (pcxtOut->addr) = TRUE; break; } } } LLUnlock (hexg); return psym; } BOOL VerifyHexe( HEXE hexe ) { HEXE hexeT = 0; static BOOL fFound = FALSE; static HEXE hexeSave = 0; if (hexe == hexeNull) { return FALSE; } if (hexe == hexeSave) { return fFound; } hexeSave = hexe; fFound = FALSE; while(!fFound && (hexeT = SHGetNextExe(hexeT))) { if (hexeT == hexe) { fFound = TRUE; } } return fFound; } // SHFindNameInTypes // // Purpose: To look for the name in the UDT table. // // Input: // pCXT - The context to do the search. // lpsstr - pointer to search parameters (passed to the compare routine) // fCaseSensitive - TRUE/FALSE on a case sensitive search // pfnCmp - A pointer to the comparison routine // // Output: // pCXTOut - The context generated // // Returns: // - A handle to the type found, NULL if not found // // Notes: // The hMod in the context must be valid. HSYM SHFindNameInTypes( PCXT pcxt, LPSSTR lpsstr, SHFLAG fCase, PFNCMP pfnCmp, PCXT pcxtOut ) { HEXG hexg = hexgNull; LPEXG lpexg = NULL; UDTPTR psym = NULL; char szBuf[256]; unsigned iHash; TI ti; *pcxtOut = *pcxt; pcxtOut->hProc = NULL; pcxtOut->hBlk = NULL; if (!pcxt->hMod || ( lpsstr->searchmask & SSTR_NoHash )) return NULL; hexg = SHHexgFromHmod ( pcxt->hMod ); lpexg = (LPEXG)LLLock ( hexg ); if (!lpexg->ptpi) { LLUnlock ( hexg ); return NULL; } if (!STABFindUDTSym(lpexg->pstabUDTSym, lpsstr, pfnCmp, fCase, &psym, &iHash)) { lpStrToSz(lpsstr, szBuf); assert(lpexg->ptpi); if (!TypesQueryTiForUDT(lpexg->ptpi, szBuf, fCase, &ti) || !STABAddUDTSym(lpexg->pstabUDTSym, lpsstr, iHash, &psym)) { LLUnlock ( hexg ); return NULL; } assert(psym); psym->typind = ti; } LLUnlock ( hexg ); return (SYMPTR) psym; }