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 HTYPE NB09GetTypeFromIndex ( LPEXG lpexg, THIDX index ) { HTYPE htype = (HTYPE)NULL; if (lpexg->lpalmTypes ) { assert ( lpexg->rgitd != NULL ); // adjust the pointer to an internal index index -= CV_FIRST_NONPRIM; // if type is in range, return it if( index < (THIDX) lpexg->citd ) { htype = (HTYPE) LpvFromAlmLfo ( lpexg->lpalmTypes, lpexg->rgitd [ index ] ); } } return htype; }
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 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 = (WORD)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 = (WORD)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); // BUGBUG need 64 bits db = (DWORD)(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 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; }