Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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);
}
Beispiel #6
0
/*
 * 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);
}
Beispiel #7
0
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);
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
/*
 * 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;
}
Beispiel #11
0
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;
}