bool BPatch_typeEnum::isCompatibleInt(BPatch_type *otype) { BPatch_typeTypedef *otypedef = dynamic_cast<BPatch_typeTypedef *>(otype); if (otypedef != NULL) return isCompatibleInt(otypedef->getConstituentType()); BPatch_typeEnum *oEnumtype = dynamic_cast<BPatch_typeEnum *>(otype); if (oEnumtype == NULL) return false; if( name && oEnumtype->name && !strcmp( name, oEnumtype->name) && (ID == oEnumtype->ID)) return true; const BPatch_Vector<BPatch_field *> * fields1 = this->getComponents(); const BPatch_Vector<BPatch_field *> * fields2 = oEnumtype->getComponents(); //BPatch_Vector<BPatch_field *> * fields2 = &oEnumtype->fieldList; if( fields1->size() != fields2->size()) { BPatch_reportError(BPatchWarning, 112, "enumerated type mismatch "); return false; } //need to compare componment by component to verify compatibility for(unsigned int i=0;i<fields1->size();i++){ BPatch_field * field1 = (*fields1)[i]; BPatch_field * field2 = (*fields2)[i]; if( (field1->getValue() != field2->getValue()) || (strcmp(field1->getName(), field2->getName()))) BPatch_reportError(BPatchWarning, 112, "enum element mismatch "); return false; } // Everything matched so they are the same return true; }
bool BPatch_typeUnion::isCompatibleInt(BPatch_type *otype) { BPatch_typeTypedef *otypedef = dynamic_cast<BPatch_typeTypedef *>(otype); if (otypedef != NULL) return isCompatibleInt(otypedef->getConstituentType()); BPatch_typeUnion *oUniontype = dynamic_cast<BPatch_typeUnion *>(otype); if (oUniontype == NULL) return false; const BPatch_Vector<BPatch_field *> * fields1 = this->getComponents(); const BPatch_Vector<BPatch_field *> * fields2 = oUniontype->getComponents(); //const BPatch_Vector<BPatch_field *> * fields2 = (BPatch_Vector<BPatch_field *> *) &(otype->fieldList); if (fields1->size() != fields2->size()) { BPatch_reportError(BPatchWarning, 112, "struct/union numer of elements mismatch "); return false; } //need to compare componment by component to verify compatibility for (unsigned int i=0;i<fields1->size();i++) { BPatch_field * field1 = (*fields1)[i]; BPatch_field * field2 = (*fields2)[i]; BPatch_type * ftype1 = (BPatch_type *)field1->getType(); BPatch_type * ftype2 = (BPatch_type *)field2->getType(); if(!(ftype1->isCompatibleInt(ftype2))) { BPatch_reportError(BPatchWarning, 112, "struct/union field type mismatch "); return false; } } return true; }
BPatch_Vector<BPatch_function *> * BPatch_module::findFunctionByAddressInt(void *addr, BPatch_Vector<BPatch_function *> &funcs, bool notify_on_failure, bool incUninstrumentable) { if (hasBeenRemoved_) return NULL; int_function *pdfunc = NULL; BPatch_function *bpfunc = NULL; pdfunc = mod->findFuncByAddr((Address)addr); if (!pdfunc) { if (notify_on_failure) { char msg[1024]; sprintf(msg, "%s[%d]: Module %s: unable to find function %p", __FILE__, __LINE__, mod->fileName().c_str(), addr); BPatch_reportError(BPatchSerious, 100, msg); } return NULL; } if (incUninstrumentable || pdfunc->isInstrumentable()) { bpfunc = proc->findOrCreateBPFunc(pdfunc, this); if (bpfunc) { funcs.push_back(bpfunc); } } return &funcs; }
BPatch_Vector<BPatch_function *> * BPatch_image::findFunctionWithSieve(BPatch_Vector<BPatch_function *> &funcs, BPatchFunctionNameSieve bpsieve, void *user_data, int showError, bool incUninstrumentable) { pdvector<int_function *> all_funcs; proc->llproc->getAllFunctions(all_funcs); for (unsigned ai = 0; ai < all_funcs.size(); ai++) { int_function *func = all_funcs[ai]; // If it matches, push onto the vector // Check all pretty names (and then all mangled names if there is no match) bool found_match = false; for (unsigned piter = 0; piter < func->prettyNameVector().size(); piter++) { const pdstring &pName = func->prettyNameVector()[piter]; if ((*bpsieve)(pName.c_str(), user_data)) { if (func->isInstrumentable() || incUninstrumentable) { BPatch_function *foo = proc->findOrCreateBPFunc(func, NULL); funcs.push_back(foo); } found_match = true; break; } } if (found_match) continue; // Don't check mangled names #if 0 // Apparently don't check mangled at all for (unsigned miter = 0; miter < func->symTabNameVector().size(); miter++) { const pdstring &mName = func->symTabNameVector()[miter]; int err; if (0 == (err = regexec(&comp_pat, mName.c_str(), 1, NULL, 0 ))) { if (func->isInstrumentable() || incUninstrumentable) { BPatch_function *foo = proc->findOrCreateBPFunc(func, NULL); funcs.push_back(foo); } found_match = true; break; } } #endif } if (funcs.size() > 0) { return &funcs; } if (showError) { const char *msg = "No function matches for sieve provided"; BPatch_reportError(BPatchSerious, 100, msg); } return NULL; }
bool BPatch_typePointer::isCompatibleInt(BPatch_type *otype) { BPatch_typeTypedef *otypedef = dynamic_cast<BPatch_typeTypedef *>(otype); if (otypedef != NULL) return isCompatibleInt(otypedef->getConstituentType()); BPatch_typePointer *oPointertype = dynamic_cast<BPatch_typePointer *>(otype); if (oPointertype == NULL) { BPatch_reportError(BPatchWarning, 112, "Pointer and non-Pointer are not type compatible"); return false; } // verify type that each one points to is compatible return ptr->isCompatibleInt(oPointertype->ptr); }
/* * BPatch_thread::oneTimeCode * * Have the mutatee execute specified code expr once. Wait until done. * */ void *BPatch_thread::oneTimeCode(const BPatch_snippet &expr, bool *err) { if( !llthread->isLive() ) { if ( err ) *err = true; return NULL; } if( !proc->isStopped() ) { BPatch_reportError(BPatchWarning, 0, "oneTimeCode failing because process is not stopped"); if( err ) *err = true; return NULL; } return proc->oneTimeCodeInternal(expr, this, NULL, NULL, true, err, true); }
bool BPatch_typeArray::isCompatibleInt(BPatch_type *otype) { BPatch_typeTypedef *otypedef = dynamic_cast<BPatch_typeTypedef *>(otype); if (otypedef != NULL) return isCompatibleInt(otypedef->getConstituentType()); BPatch_typeArray *oArraytype = dynamic_cast<BPatch_typeArray *>(otype); if (oArraytype == NULL) { BPatch_reportError(BPatchWarning, 112, "Array and non-array are not type compatible"); return false; } unsigned int ec1, ec2; ec1 = atoi(hi) - atoi(low) + 1; ec2 = atoi(oArraytype->hi) - atoi(oArraytype->low) + 1; if (ec1 != ec2) { char message[80]; sprintf(message, "Incompatible number of elements [%s..%s] vs. [%s..%s]", this->low, this->hi, oArraytype->low, oArraytype->hi); BPatch_reportError(BPatchWarning, 112, message); return false; } return arrayElem->isCompatibleInt(oArraytype->arrayElem); }
char *BPatch_type::getName(char *buffer, int max) const { if (!name) { strncpy(buffer, "bad type name", (max > strlen("bad_type_name")) ? (strlen("bad_type_name") +1) : max); char msg[256]; sprintf(msg, "%s[%d]: bad type name!", __FILE__, __LINE__); BPatch_reportError(BPatchWarning, 112, msg); return buffer; } if (max > strlen(name)) { strcpy (buffer, name); return buffer; } else { strncpy (buffer, name, max-1)[max-1] = '\0'; } return NULL; }
BPatch_Vector<BPatch_function *> * BPatch_module::findFunctionInt(const char *name, BPatch_Vector<BPatch_function *> & funcs, bool notify_on_failure, bool regex_case_sensitive, bool incUninstrumentable, bool dont_use_regex) { if (hasBeenRemoved_) return NULL; unsigned size = funcs.size(); if (!name) { char msg[512]; sprintf(msg, "%s[%d]: Module %s: findFunction(NULL)... failing", __FILE__, __LINE__, mod->fileName().c_str()); BPatch_reportError(BPatchSerious, 100, msg); return NULL; } // Do we want regex? if (dont_use_regex || (NULL == strpbrk(name, REGEX_CHARSET))) { pdvector<int_function *> int_funcs; if (mod->findFuncVectorByPretty(name, int_funcs)) { for (unsigned piter = 0; piter < int_funcs.size(); piter++) { if (incUninstrumentable || int_funcs[piter]->isInstrumentable()) { BPatch_function * bpfunc = proc->findOrCreateBPFunc(int_funcs[piter], this); funcs.push_back(bpfunc); } } } else { if (mod->findFuncVectorByMangled(name, int_funcs)) { for (unsigned miter = 0; miter < int_funcs.size(); miter++) { if (incUninstrumentable || int_funcs[miter]->isInstrumentable()) { BPatch_function * bpfunc = proc->findOrCreateBPFunc(int_funcs[miter], this); funcs.push_back(bpfunc); } } } } if (size != funcs.size()) return &funcs; } else { // Regular expression search. As with BPatch_image, we handle it here #if !defined(i386_unknown_nt4_0) && !defined(mips_unknown_ce2_11) // no regex for M$ // REGEX falls through: regex_t comp_pat; int err, cflags = REG_NOSUB | REG_EXTENDED; if( !regex_case_sensitive ) cflags |= REG_ICASE; //cerr << "compiling regex: " <<name<<endl; if (0 != (err = regcomp( &comp_pat, name, cflags ))) { char errbuf[80]; regerror( err, &comp_pat, errbuf, 80 ); if (notify_on_failure) { cerr << __FILE__ << ":" << __LINE__ << ": REGEXEC ERROR: "<< errbuf << endl; pdstring msg = pdstring("Image: Unable to find function pattern: ") + pdstring(name) + ": regex error --" + pdstring(errbuf); BPatch_reportError(BPatchSerious, 100, msg.c_str()); } // remove this line //cerr << __FILE__ << ":" << __LINE__ << ": REGEXEC ERROR: "<< errbuf << endl; return NULL; } // Regular expression search. This used to be handled at the image // class level, but was moved up here to simplify semantics. We // have to iterate over every function known to the process at some // point, so it might as well be top-level. This is also an // excellent candidate for a "value-added" library. const pdvector<int_function *> &int_funcs = mod->getAllFunctions(); for (unsigned ai = 0; ai < int_funcs.size(); ai++) { int_function *func = int_funcs[ai]; // If it matches, push onto the vector // Check all pretty names (and then all mangled names if there is no match) bool found_match = false; for (unsigned piter = 0; piter < func->prettyNameVector().size(); piter++) { const pdstring &pName = func->prettyNameVector()[piter]; int err; if (0 == (err = regexec(&comp_pat, pName.c_str(), 1, NULL, 0 ))){ if (func->isInstrumentable() || incUninstrumentable) { BPatch_function *foo = proc->findOrCreateBPFunc(func, NULL); funcs.push_back(foo); } found_match = true; break; } } if (found_match) continue; // Don't check mangled names for (unsigned miter = 0; miter < func->symTabNameVector().size(); miter++) { const pdstring &mName = func->symTabNameVector()[miter]; int err; if (0 == (err = regexec(&comp_pat, mName.c_str(), 1, NULL, 0 ))){ if (func->isInstrumentable() || incUninstrumentable) { BPatch_function *foo = proc->findOrCreateBPFunc(func, NULL); funcs.push_back(foo); } found_match = true; break; } } } regfree(&comp_pat); if (funcs.size() != size) { return &funcs; } if (notify_on_failure) { pdstring msg = pdstring("Unable to find pattern: ") + pdstring(name); BPatch_reportError(BPatchSerious, 100, msg.c_str()); } #endif } if(notify_on_failure) { char msg[1024]; sprintf(msg, "%s[%d]: Module %s: unable to find function %s", __FILE__, __LINE__, mod->fileName().c_str(), name); BPatch_reportError(BPatchSerious, 100, msg); } return &funcs; }
/* * BPatch_image::findVariable * * Returns a BPatch_variableExpr* representing the given variable in the * application image. If no such variable exists, returns NULL. * * name The name of the variable to look up. * * First look for the name with an `_' prepended to it, and if that is not * found try the original name. */ BPatch_variableExpr *BPatch_image::findVariableInt(const char *name, bool showError) { pdvector<int_variable *> vars; process *llproc = proc->llproc; if (!llproc->findVarsByAll(name, vars)) { // _name? pdstring under_name = pdstring("_") + pdstring(name); if (!llproc->findVarsByAll(under_name, vars)) { // "default Namespace prefix? if (defaultNamespacePrefix) { pdstring prefix_name = pdstring(defaultNamespacePrefix) + pdstring(".") + pdstring(name); if (!llproc->findVarsByAll(prefix_name, vars)) { if (showError) { pdstring msg = pdstring("Unable to find variable: ") + pdstring(prefix_name); showErrorCallback(100, msg); } return NULL; } } else { if (showError) { pdstring msg = pdstring("Unable to find variable: ") + pdstring(name); showErrorCallback(100, msg); } return NULL; } } } assert(vars.size()); if (vars.size() > 1) { cerr << "Warning: found multiple matches for var " << name << endl; } int_variable *var = vars[0]; BPatch_variableExpr *bpvar = AddrToVarExpr->hash[var->getAddress()]; if (bpvar) { return bpvar; } // XXX - should this stuff really be by image ??? jkh 3/19/99 BPatch_Vector<BPatch_module *> *mods = getModules(); BPatch_type *type = NULL; // XXX look up the type off of the int_variable's module BPatch_module *module = NULL; for (unsigned int m = 0; m < mods->size(); m++) { if( (*mods)[m]->lowlevel_mod() == var->mod() ) { module = (*mods)[m]; break; } } if(module) { type = module->getModuleTypes()->findVariableType(name); } else { bperr("findVariable: failed look up module %s\n", var->mod()->fileName().c_str()); } if(!type) { // if we can't find the type in the module, check the other modules // (fixes prob on alpha) -- actually seems like most missing types // end up in DEFAULT_MODULE for (unsigned int m = 0; m < mods->size(); m++) { BPatch_module *tm = (*mods)[m]; type = tm->getModuleTypes()->findVariableType(name); if (type) { #if 0 char buf1[1024], buf2[1024]; tm->getName(buf1, 1024); module->getName(buf2, 1024); fprintf(stderr, "%s[%d]: found type for %s in module %s, not %s\n", FILE__, __LINE__, name, buf2, buf1); #endif break; } } if (!type) { char buf[128]; sprintf(buf, "%s[%d]: cannot find type for var %s\n", FILE__, __LINE__, name); BPatch_reportError(BPatchWarning, 0, buf); type = BPatch::bpatch->type_Untyped; } } char *nameCopy = strdup(name); assert(nameCopy); BPatch_variableExpr *ret = new BPatch_variableExpr((char *) nameCopy, proc, (void *)var->getAddress(), type); AddrToVarExpr->hash[var->getAddress()] = ret; return ret; }
BPatch_Vector<BPatch_function*> *BPatch_image::findFunctionInt(const char *name, BPatch_Vector<BPatch_function*> &funcs, bool showError, bool regex_case_sensitive, bool incUninstrumentable) { process *llproc = proc->llproc; if (NULL == strpbrk(name, REGEX_CHARSET)) { // usual case, no regex pdvector<int_function *> foundIntFuncs; if (!llproc->findFuncsByAll(pdstring(name), foundIntFuncs)) { // Error callback... if (showError) { pdstring msg = pdstring("Image: Unable to find function: ") + pdstring(name); BPatch_reportError(BPatchSerious, 100, msg.c_str()); } return NULL; } // We have a list; if we don't want to include uninstrumentable, // scan and check for (unsigned int fi = 0; fi < foundIntFuncs.size(); fi++) { if (foundIntFuncs[fi]->isInstrumentable() || incUninstrumentable) { BPatch_function *foo = proc->findOrCreateBPFunc(foundIntFuncs[fi], NULL); funcs.push_back(foo); } } if (funcs.size() > 0) { return &funcs; } else { if (showError) { pdstring msg = pdstring("Image: Unable to find function: ") + pdstring(name); BPatch_reportError(BPatchSerious, 100, msg.c_str()); } return NULL; } } #if !defined(i386_unknown_nt4_0) && !defined(mips_unknown_ce2_11) // no regex for M$ // REGEX falls through: regex_t comp_pat; int err, cflags = REG_NOSUB | REG_EXTENDED; if( !regex_case_sensitive ) cflags |= REG_ICASE; //cerr << "compiling regex: " <<name<<endl; if (0 != (err = regcomp( &comp_pat, name, cflags ))) { char errbuf[80]; regerror( err, &comp_pat, errbuf, 80 ); if (showError) { cerr << __FILE__ << ":" << __LINE__ << ": REGEXEC ERROR: "<< errbuf << endl; pdstring msg = pdstring("Image: Unable to find function pattern: ") + pdstring(name) + ": regex error --" + pdstring(errbuf); BPatch_reportError(BPatchSerious, 100, msg.c_str()); } // remove this line cerr << __FILE__ << ":" << __LINE__ << ": REGEXEC ERROR: "<< errbuf << endl; return NULL; } // Regular expression search. This used to be handled at the image // class level, but was moved up here to simplify semantics. We // have to iterate over every function known to the process at some // point, so it might as well be top-level. This is also an // excellent candidate for a "value-added" library. pdvector<int_function *> all_funcs; llproc->getAllFunctions(all_funcs); for (unsigned ai = 0; ai < all_funcs.size(); ai++) { int_function *func = all_funcs[ai]; // If it matches, push onto the vector // Check all pretty names (and then all mangled names if there is no match) bool found_match = false; for (unsigned piter = 0; piter < func->prettyNameVector().size(); piter++) { const pdstring &pName = func->prettyNameVector()[piter]; int err; if (0 == (err = regexec(&comp_pat, pName.c_str(), 1, NULL, 0 ))) { if (func->isInstrumentable() || incUninstrumentable) { BPatch_function *foo = proc->findOrCreateBPFunc(func, NULL); funcs.push_back(foo); } found_match = true; break; } } if (found_match) continue; // Don't check mangled names for (unsigned miter = 0; miter < func->symTabNameVector().size(); miter++) { const pdstring &mName = func->symTabNameVector()[miter]; int err; if (0 == (err = regexec(&comp_pat, mName.c_str(), 1, NULL, 0 ))) { if (func->isInstrumentable() || incUninstrumentable) { BPatch_function *foo = proc->findOrCreateBPFunc(func, NULL); funcs.push_back(foo); } found_match = true; break; } } } regfree(&comp_pat); if (funcs.size() > 0) { return &funcs; } if (showError) { pdstring msg = pdstring("Unable to find pattern: ") + pdstring(name); BPatch_reportError(BPatchSerious, 100, msg.c_str()); } #endif return NULL; }