Added support for dynamic sanity checking in
expressions.  Values used by the expression are
checked by validation functions which cause the
program to crash if the values are unsafe.

Major changes:

- Added IRDynamicChecks.[ch], which contains the
  core code related to this feature

- Modified CommandObjectExpression to install the
  validator functions into the target process.

- Added an accessor to Process that gets/sets the
  helper functions


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@112690 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ClangExpressionParser.cpp b/source/Expression/ClangExpressionParser.cpp
index 7c4cc6a..1bc8866 100644
--- a/source/Expression/ClangExpressionParser.cpp
+++ b/source/Expression/ClangExpressionParser.cpp
@@ -13,8 +13,10 @@
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Disassembler.h"
 #include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamString.h"
 #include "lldb/Expression/ClangASTSource.h"
 #include "lldb/Expression/ClangExpression.h"
+#include "lldb/Expression/IRDynamicChecks.h"
 #include "lldb/Expression/IRForTarget.h"
 #include "lldb/Expression/IRToDWARF.h"
 #include "lldb/Expression/RecordingMemoryManager.h"
@@ -409,6 +411,15 @@
             err.SetErrorString("Couldn't convert the expression to DWARF");
             return err;
         }
+        
+        IRDynamicChecks ir_dynamic_checks(*exe_ctx.process->GetDynamicCheckers(), m_expr.FunctionName());
+        
+        if (!ir_dynamic_checks.runOnModule(*module))
+        {
+            err.SetErrorToGenericError();
+            err.SetErrorString("Couldn't add dynamic checks to the expression");
+            return err;
+        }        
     }
     
     m_jit_mm = new RecordingMemoryManager();
diff --git a/source/Expression/ClangUtilityFunction.cpp b/source/Expression/ClangUtilityFunction.cpp
index 3acd3f2..17ba7db 100644
--- a/source/Expression/ClangUtilityFunction.cpp
+++ b/source/Expression/ClangUtilityFunction.cpp
@@ -37,7 +37,9 @@
 ClangUtilityFunction::ClangUtilityFunction (const char *text, 
                                             const char *name) :
     m_function_text(text),
-    m_function_name(name)
+    m_function_name(name),
+    m_jit_begin(LLDB_INVALID_ADDRESS),
+    m_jit_end(LLDB_INVALID_ADDRESS)
 {
 }
 
@@ -56,7 +58,13 @@
 bool
 ClangUtilityFunction::Install (Stream &error_stream,
                                ExecutionContext &exe_ctx)
-{    
+{
+    if (m_jit_begin != LLDB_INVALID_ADDRESS)
+    {
+        error_stream.PutCString("error: already installed\n");
+        return false;
+    }
+    
     ////////////////////////////////////
     // Set up the target and compiler
     //
diff --git a/source/Expression/IRDynamicChecks.cpp b/source/Expression/IRDynamicChecks.cpp
new file mode 100644
index 0000000..21fd7d2
--- /dev/null
+++ b/source/Expression/IRDynamicChecks.cpp
@@ -0,0 +1,117 @@
+//===-- IRDynamicChecks.cpp -------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Expression/IRDynamicChecks.h"
+#include "lldb/Expression/ClangUtilityFunction.h"
+
+#include "lldb/Core/Log.h"
+
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Function.h"
+#include "llvm/Module.h"
+#include "llvm/Value.h"
+
+using namespace llvm;
+using namespace lldb_private;
+
+static char ID;
+
+static const char valid_pointer_check_text[] = 
+    "extern \"C\" void "
+    "___clang_valid_pointer_check (unsigned char *ptr)"
+    "{"
+        "unsigned char val = *ptr;"
+    "}";
+
+static const char valid_pointer_check_name[] = 
+    "___clang_valid_pointer_check";
+
+DynamicCheckerFunctions::DynamicCheckerFunctions ()
+{
+    m_valid_pointer_check.reset(new ClangUtilityFunction(valid_pointer_check_text,
+                                                         valid_pointer_check_name));
+}
+
+DynamicCheckerFunctions::~DynamicCheckerFunctions ()
+{
+}
+
+bool
+DynamicCheckerFunctions::Install(Stream &error_stream,
+                                 ExecutionContext &exe_ctx)
+{
+    if (!m_valid_pointer_check->Install(error_stream, exe_ctx))
+        return false;
+        
+    return true;
+}
+
+IRDynamicChecks::IRDynamicChecks(DynamicCheckerFunctions &checker_functions,
+                                 const char *func_name) :
+    ModulePass(&ID),
+    m_checker_functions(checker_functions),
+    m_func_name(func_name)
+{
+}
+
+/* A handy utility function used at several places in the code */
+
+static std::string 
+PrintValue(llvm::Value *V, bool truncate = false)
+{
+    std::string s;
+    raw_string_ostream rso(s);
+    V->print(rso);
+    rso.flush();
+    if (truncate)
+        s.resize(s.length() - 1);
+    return s;
+}
+
+IRDynamicChecks::~IRDynamicChecks()
+{
+}
+
+bool
+IRDynamicChecks::runOnModule(llvm::Module &M)
+{
+    lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
+    
+    llvm::Function* function = M.getFunction(StringRef(m_func_name.c_str()));
+    
+    if (!function)
+    {
+        if (log)
+            log->Printf("Couldn't find %s() in the module", m_func_name.c_str());
+        
+        return false;
+    }
+    
+    llvm::Function::iterator bbi;
+    
+    for (bbi = function->begin();
+         bbi != function->end();
+         ++bbi)
+    {
+    }
+    
+    return true;    
+}
+
+void
+IRDynamicChecks::assignPassManager(PMStack &PMS,
+                                   PassManagerType T)
+{
+}
+
+PassManagerType
+IRDynamicChecks::getPotentialPassManagerType() const
+{
+    return PMT_ModulePassManager;
+}