//----------------------------------------------------------------------------------- FastFile *FastFileFind (char *fname, long &fastFileHandle) { if (g_fastFiles) { DWORD thisHash = elfHash(fname); long currentFastFile = 0; long tempHandle = -1; while (currentFastFile < g_numFastFiles) { tempHandle = g_fastFiles[currentFastFile]->openFast(thisHash,fname); if (tempHandle != -1) { fastFileHandle = tempHandle; return g_fastFiles[currentFastFile]; } currentFastFile++; } } return NULL; }
uint cElement::nameHash() const { if ( !nameHashKey ) nameHashKey = elfHash( name_.toLatin1() ); return nameHashKey; }
QString QTranslatorPrivate::do_translate(const char *context, const char *sourceText, const char *comment, int n) const { if (context == 0) context = ""; if (sourceText == 0) sourceText = ""; if (comment == 0) comment = ""; if (!offsetLength) return QString(); /* Check if the context belongs to this QTranslator. If many translators are installed, this step is necessary. */ if (contextLength) { quint16 hTableSize = read16(contextArray); uint g = elfHash(context) % hTableSize; const uchar *c = contextArray + 2 + (g << 1); quint16 off = read16(c); c += 2; if (off == 0) return QString(); c = contextArray + (2 + (hTableSize << 1) + (off << 1)); for (;;) { quint8 len = read8(c++); if (len == 0) return QString(); if (match(c, context, len)) break; c += len; } } size_t numItems = offsetLength / (2 * sizeof(quint32)); if (!numItems) return QString(); int numerus = 0; if (n >= 0) numerus = numerusHelper(n, numerusRulesArray, numerusRulesLength); for (;;) { quint32 h = elfHash(QByteArray(sourceText) + comment); const uchar *start = offsetArray; const uchar *end = start + ((numItems-1) << 3); while (start <= end) { const uchar *middle = start + (((end - start) >> 4) << 3); uint hash = read32(middle); if (h == hash) { start = middle; break; } else if (hash < h) { start = middle + 8; } else { end = middle - 8; } } if (start <= end) { // go back on equal key while (start != offsetArray && read32(start) == read32(start-8)) start -= 8; while (start < offsetArray + offsetLength) { quint32 rh = read32(start); start += 4; if (rh != h) break; quint32 ro = read32(start); start += 4; QString tn = getMessage(messageArray + ro, messageArray + messageLength, context, sourceText, comment, numerus); if (!tn.isNull()) return tn; } } if (!comment[0]) break; comment = ""; } return QString(); }
unsigned addElfHook(const char* soName, const char* symbol, void* replaceFunc) { struct SoInfo *si = NULL; Elf32_Rel *rel = NULL; Elf32_Sym *s = NULL; unsigned int sym_offset = 0; size_t i; // since we know the module is already loaded and mostly // we DO NOT want its constructors to be called again, // ise RTLD_NOLOAD to just get its soinfo address. si = (struct SoInfo *)dlopen( soName, RTLD_GLOBAL/* RTLD_NOLOAD */ ); if( !si ){ LOGE( "dlopen error: %s.", dlerror() ); return 0; } s = soInfoElfLookUp( si, elfHash(symbol), symbol ); if( !s ){ return 0; } sym_offset = s - si->symtab; LOGD("the sym offset is %d", sym_offset); // loop reloc table to find the symbol by index for( i = 0, rel = si->plt_rel; i < si->plt_rel_count; ++i, ++rel ) { unsigned type = ELF32_R_TYPE(rel->r_info); unsigned sym = ELF32_R_SYM(rel->r_info); unsigned reloc = (unsigned)(rel->r_offset + si->base); if( sym_offset == sym ) { switch(type) { case R_ARM_JUMP_SLOT: return patchAddress( reloc, replaceFunc ); default: LOGE( "Expected R_ARM_JUMP_SLOT, found 0x%X", type ); } } } unsigned original = 0; // loop dyn reloc table for( i = 0, rel = si->rel; i < si->rel_count; ++i, ++rel ) { unsigned type = ELF32_R_TYPE(rel->r_info); unsigned sym = ELF32_R_SYM(rel->r_info); unsigned reloc = (unsigned)(rel->r_offset + si->base); if( sym_offset == sym ) { switch(type) { case R_ARM_ABS32: case R_ARM_GLOB_DAT: original = patchAddress( reloc, replaceFunc ); default: LOGE( "Expected R_ARM_ABS32 or R_ARM_GLOB_DAT, found 0x%X", type ); } } } if( original == 0 ){ LOGE( "Unable to find symbol in the reloc tables ( plt_rel_count=%u - rel_count=%u ).", si->plt_rel_count, si->rel_count ); } return original; }