void DisplayFunction() {
   
   if (DisplayedFunction)
     return;
   
   DisplayedFunction = true;
   
   // FIXME: Is getCodeDecl() always a named decl?
   if (isa<FunctionDecl>(getCodeDecl()) ||
       isa<ObjCMethodDecl>(getCodeDecl())) {
     NamedDecl *ND = cast<NamedDecl>(getCodeDecl());
     SourceManager &SM = getContext().getSourceManager();
     llvm::cerr << "ANALYZE: "
       << SM.getPresumedLoc(ND->getLocation()).getFilename()
       << ' ' << ND->getNameAsString() << '\n';
   }
 }
  void NetworkDriverRewriteVisitor::CreateCheckerFunction(FunctionDecl* funcDecl, string fdFile)
  {
    string device_str;
    Stmt *body = funcDecl->getBody();

    for (auto i = body->child_begin(), e = body->child_end(); i != e; ++i)
    {
      if (!isa<DeclStmt>(*i))
        continue;

      DeclStmt *declStmt = cast<DeclStmt>(*i);
      if (!declStmt->isSingleDecl() && !isa<VarDecl>(declStmt->getSingleDecl()))
        continue;

      VarDecl *varDecl = cast<VarDecl>(declStmt->getSingleDecl());
      if (!isa<ValueDecl>(varDecl))
        continue;

      ValueDecl *value = cast<ValueDecl>(varDecl);

      if (value->getType().getAsString(Context->getPrintingPolicy()) != "struct net_device *")
        continue;
      if (!isa<NamedDecl>(varDecl))
        continue;

      NamedDecl *named = cast<NamedDecl>(varDecl);
      device_str = named->getNameAsString();
      break;
    }

    if (device_str.empty())
      return;

    string shared_struct_str = GetSharedStructStrInFunctionBody(body, true);
    if (shared_struct_str.empty())
      return;

    FileID fileId = Context->getSourceManager().getFileID(funcDecl->getLocation());
    SourceLocation loc = Context->getSourceManager().getLocForEndOfFile(fileId);

    RW.InsertText(loc, "\n", true, true);
    RW.InsertText(loc, "void whoop$checker(", true, true);

    map<string, string> func_params;
    for (auto i = funcDecl->param_begin(), e = funcDecl->param_end(); i != e; ++i)
    {
      ValueDecl *paramVal = cast<ValueDecl>(*i);
      NamedDecl *paramNam = cast<NamedDecl>(*i);

      string paramType = paramVal->getType().getAsString(Context->getPrintingPolicy());
      string paramName = paramNam->getNameAsString();

      func_params[paramType] = paramName;

      if (i == funcDecl->param_begin())
        RW.InsertText(loc, paramType + " " + paramName + ", ", true, true);
      else
        RW.InsertText(loc, paramType + " " + paramName, true, true);
    }

    RW.InsertText(loc, ")\n", true, true);
    RW.InsertText(loc, "{\n", true, true);

    RW.InsertText(loc, "\tstruct net_device *dev;\n", true, true);
    RW.InsertText(loc, "\t" + shared_struct_str + "shared;\n", true, true);
    RW.InsertText(loc, "\tdev = alloc_etherdev(sizeof(*shared));\n\n", true, true);

    RW.InsertText(loc, "\tstruct sk_buff *whoop_skb = (struct sk_buff *) malloc(sizeof(struct sk_buff));\n", true, true);
    RW.InsertText(loc, "\tstruct ethtool_wolinfo *whoop_wolinfo = (struct ethtool_wolinfo *) malloc(sizeof(struct ethtool_wolinfo));\n", true, true);
    RW.InsertText(loc, "\tstruct ethtool_cmd *whoop_ecmd = (struct ethtool_cmd *) malloc(sizeof(struct ethtool_cmd));\n", true, true);
    RW.InsertText(loc, "\tstruct ifreq *whoop_ifreq = (struct ifreq *) malloc(sizeof(struct ifreq));\n", true, true);
    RW.InsertText(loc, "\tstruct rtnl_link_stats64 *whoop_rtnlsts64 = (struct rtnl_link_stats64 *) malloc(sizeof(struct rtnl_link_stats64));\n", true, true);
    RW.InsertText(loc, "\tstruct ethtool_regs *whoop_ethtoolregs = (struct ethtool_regs *) malloc(sizeof(struct ethtool_regs));\n", true, true);
    RW.InsertText(loc, "\tstruct ethtool_stats *whoop_ethtoolsts = (struct ethtool_stats *) malloc(sizeof(struct ethtool_stats));\n", true, true);
    RW.InsertText(loc, "\tstruct ethtool_drvinfo *whoop_ethtooldrvinfo = (struct ethtool_drvinfo *) malloc(sizeof(struct ethtool_drvinfo));\n", true, true);
    RW.InsertText(loc, "\tnetdev_features_t whoop_netdevfeat = NETIF_F_RXCSUM;\n\n", true, true);

    RW.InsertText(loc, "\tint whoop_int = __SMACK_nondet();\n", true, true);
    RW.InsertText(loc, "\t__SMACK_code(\"assume @ >= @;\", whoop_int, 0);\n\n", true, true);

    auto entry_points = DI->getInstance().GetEntryPoints();
    for(auto i = entry_points.rbegin(); i != entry_points.rend(); i++)
    {
      string entry_point_call;
      entry_point_call = "" + i->first + "(";

      if (find(i->second.begin(), i->second.end(), "struct net_device *") == i->second.end())
        entry_point_call += device_str + ", ";

      for(auto j = i->second.begin(); j != i->second.end(); j++)
      {
        if (*j == "struct net_device *")
          entry_point_call += device_str + ", ";
        else if (*j == "struct pci_dev *")
          entry_point_call += func_params["struct pci_dev *"] + ", ";
        else if (*j == "struct device *")
          entry_point_call += "&" + func_params["struct pci_dev *"] + "->dev, ";
        else if (*j == "void *")
          entry_point_call += "NULL, ";
        else if (*j == "u64 *")
          entry_point_call += "NULL, ";
        else if (*j == "u8 *")
          entry_point_call += "NULL, ";
        else if (*j == "struct sk_buff *")
          entry_point_call += "whoop_skb, ";
        else if (*j == "struct ethtool_wolinfo *")
          entry_point_call += "whoop_wolinfo, ";
        else if (*j == "struct ethtool_cmd *")
          entry_point_call += "whoop_ecmd, ";
        else if (*j == "struct ifreq *")
          entry_point_call += "whoop_ifreq, ";
        else if (*j == "struct rtnl_link_stats64 *")
          entry_point_call += "whoop_rtnlsts64, ";
        else if (*j == "struct ethtool_regs *")
          entry_point_call += "whoop_ethtoolregs, ";
        else if (*j == "struct ethtool_stats *")
          entry_point_call += "whoop_ethtoolsts, ";
        else if (*j == "struct ethtool_drvinfo *")
          entry_point_call += "whoop_ethtooldrvinfo, ";
        else if (*j == "netdev_features_t")
          entry_point_call += "whoop_netdevfeat, ";
        else if (*j == "int")
          entry_point_call += "whoop_int, ";
        else if (*j == "u32")
          entry_point_call += "whoop_int, ";
        else
          entry_point_call += *j + ", ";
      }

      entry_point_call.resize(entry_point_call.size() - 2);

      RW.InsertText(loc, "\t" + entry_point_call + ");\n", true, true);
    }

    RW.InsertText(loc, "}", true, true);
  }
Example #3
0
Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,
                                               IdentifierInfo *Name,
                                               SourceLocation NameLoc,
                                               bool IsSuper,
                                               bool HasTrailingDot,
                                               ParsedType &ReceiverType) {
  ReceiverType = ParsedType();

  // If the identifier is "super" and there is no trailing dot, we're
  // messaging super. If the identifier is "super" and there is a
  // trailing dot, it's an instance message.
  if (IsSuper && S->isInObjcMethodScope())
    return HasTrailingDot? ObjCInstanceMessage : ObjCSuperMessage;
  
  LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName);
  LookupName(Result, S);
  
  switch (Result.getResultKind()) {
  case LookupResult::NotFound:
    // Normal name lookup didn't find anything. If we're in an
    // Objective-C method, look for ivars. If we find one, we're done!
    // FIXME: This is a hack. Ivar lookup should be part of normal
    // lookup.
    if (ObjCMethodDecl *Method = getCurMethodDecl()) {
      ObjCInterfaceDecl *ClassDeclared;
      if (Method->getClassInterface()->lookupInstanceVariable(Name, 
                                                              ClassDeclared))
        return ObjCInstanceMessage;
    }
  
    // Break out; we'll perform typo correction below.
    break;

  case LookupResult::NotFoundInCurrentInstantiation:
  case LookupResult::FoundOverloaded:
  case LookupResult::FoundUnresolvedValue:
  case LookupResult::Ambiguous:
    Result.suppressDiagnostics();
    return ObjCInstanceMessage;

  case LookupResult::Found: {
    // If the identifier is a class or not, and there is a trailing dot,
    // it's an instance message.
    if (HasTrailingDot)
      return ObjCInstanceMessage;
    // We found something. If it's a type, then we have a class
    // message. Otherwise, it's an instance message.
    NamedDecl *ND = Result.getFoundDecl();
    QualType T;
    if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(ND))
      T = Context.getObjCInterfaceType(Class);
    else if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
      T = Context.getTypeDeclType(Type);
    else 
      return ObjCInstanceMessage;

    //  We have a class message, and T is the type we're
    //  messaging. Build source-location information for it.
    TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
    ReceiverType = CreateParsedType(T, TSInfo);
    return ObjCClassMessage;
  }
  }

  // Determine our typo-correction context.
  CorrectTypoContext CTC = CTC_Expression;
  if (ObjCMethodDecl *Method = getCurMethodDecl())
    if (Method->getClassInterface() &&
        Method->getClassInterface()->getSuperClass())
      CTC = CTC_ObjCMessageReceiver;
      
  if (DeclarationName Corrected = CorrectTypo(Result, S, 0, 0, false, CTC)) {
    if (Result.isSingleResult()) {
      // If we found a declaration, correct when it refers to an Objective-C
      // class.
      NamedDecl *ND = Result.getFoundDecl();
      if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(ND)) {
        Diag(NameLoc, diag::err_unknown_receiver_suggest)
          << Name << Result.getLookupName()
          << FixItHint::CreateReplacement(SourceRange(NameLoc),
                                          ND->getNameAsString());
        Diag(ND->getLocation(), diag::note_previous_decl)
          << Corrected;

        QualType T = Context.getObjCInterfaceType(Class);
        TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
        ReceiverType = CreateParsedType(T, TSInfo);
        return ObjCClassMessage;
      }
    } else if (Result.empty() && Corrected.getAsIdentifierInfo() &&
               Corrected.getAsIdentifierInfo()->isStr("super")) {
      // If we've found the keyword "super", this is a send to super.
      Diag(NameLoc, diag::err_unknown_receiver_suggest)
        << Name << Corrected
        << FixItHint::CreateReplacement(SourceRange(NameLoc), "super");
      return ObjCSuperMessage;
    }
  }
  
  // Fall back: let the parser try to parse it as an instance message.
  return ObjCInstanceMessage;
}
  void USBDriverRewriteVisitor::CreateCheckerFunction(FunctionDecl* funcDecl, string fdFile)
  {
    string device_str;
    string shared_struct_str;

    FileID fileId = Context->getSourceManager().getFileID(funcDecl->getLocation());
    SourceLocation loc = Context->getSourceManager().getLocForEndOfFile(fileId);

    RW.InsertText(loc, "\n", true, true);
    RW.InsertText(loc, "void whoop$checker(", true, true);

    map<string, string> func_params;
    for (auto i = funcDecl->param_begin(), e = funcDecl->param_end(); i != e; ++i)
    {
      if (i != funcDecl->param_begin())
        RW.InsertText(loc, ", ", true, true);

      ValueDecl *paramVal = cast<ValueDecl>(*i);
      NamedDecl *paramNam = cast<NamedDecl>(*i);

      string paramType = paramVal->getType().getAsString(Context->getPrintingPolicy());
      string paramName = paramNam->getNameAsString();

      func_params[paramType] = paramName;

      RW.InsertText(loc, paramType + " " + paramName, true, true);
    }

    RW.InsertText(loc, ")\n", true, true);
    RW.InsertText(loc, "{\n", true, true);

    RW.InsertText(loc, "\tstruct tty_struct *whoop_tty_struct = (struct tty_struct *) malloc(sizeof(struct tty_struct));\n", true, true);
    RW.InsertText(loc, "\tstruct usb_serial *whoop_usb_serial = (struct usb_serial *) malloc(sizeof(struct usb_serial));\n", true, true);
    RW.InsertText(loc, "\tstruct usb_serial_port *whoop_usb_serial_port = (struct usb_serial_port *) malloc(sizeof(struct usb_serial_port));\n", true, true);
    RW.InsertText(loc, "\tstruct usb_interface *whoop_usb_interface = (struct usb_interface *) malloc(sizeof(struct usb_interface));\n", true, true);
    RW.InsertText(loc, "\tstruct ktermios *whoop_ktermios = (struct ktermios *) malloc(sizeof(struct ktermios));\n", true, true);
    RW.InsertText(loc, "\tstruct urb *whoop_urb = (struct urb *) malloc(sizeof(struct urb));\n", true, true);
    RW.InsertText(loc, "\tconst char *whoop_buf = (char *) malloc(sizeof(char));\n\n", true, true);

    RW.InsertText(loc, "\tint whoop_int = __SMACK_nondet();\n", true, true);
    RW.InsertText(loc, "\t__SMACK_code(\"assume @ >= @;\", whoop_int, 0);\n\n", true, true);

    auto entry_points = DI->getInstance().GetEntryPoints();
    for(auto i = entry_points.rbegin(); i != entry_points.rend(); i++)
    {
      string entry_point_call;
      entry_point_call = "" + i->first + "(";

      for(auto j = i->second.begin(); j != i->second.end(); j++)
      {
        if (*j == "void")
          entry_point_call += "";
        else if (*j == "void *")
          entry_point_call += "NULL, ";
        else if (*j == "u64 *")
          entry_point_call += "NULL, ";
        else if (*j == "u8 *")
          entry_point_call += "NULL, ";
        else if (*j == "struct tty_struct *")
          entry_point_call += "whoop_tty_struct, ";
        else if (*j == "struct usb_serial *")
          entry_point_call += "whoop_usb_serial, ";
        else if (*j == "struct usb_serial_port *")
          entry_point_call += "whoop_usb_serial_port, ";
        else if (*j == "struct usb_interface *")
          entry_point_call += "whoop_usb_interface, ";
        else if (*j == "struct urb *")
          entry_point_call += "whoop_ktermios, ";
        else if (*j == "struct ktermios *")
          entry_point_call += "whoop_urb, ";
        else if (*j == "char *")
          entry_point_call += "whoop_buf, ";
        else if (*j == "const char *")
          entry_point_call += "whoop_buf, ";
        else if (*j == "size_t")
          entry_point_call += "whoop_int, ";
        else if (*j == "int")
          entry_point_call += "whoop_int, ";
        else if (*j == "unsigned int")
          entry_point_call += "whoop_int, ";
        else if (*j == "long")
          entry_point_call += "whoop_int, ";
        else if (*j == "unsigned long")
          entry_point_call += "whoop_int, ";
        else if (*j == "u32")
          entry_point_call += "whoop_int, ";
        else if (*j == "fmode_t")
          entry_point_call += "whoop_int, ";
        else
          entry_point_call += *j + ", ";
      }

      if (entry_point_call != i->first + "(")
      {
        entry_point_call.resize(entry_point_call.size() - 2);
      }

      RW.InsertText(loc, "\t" + entry_point_call + ");\n", true, true);
    }

    RW.InsertText(loc, "}", true, true);
  }