[Lldb-commits] [lldb] r113789 - in /lldb/trunk: include/lldb/Expression/ source/Commands/ source/Expression/

Sean Callanan scallanan at apple.com
Mon Sep 13 14:34:22 PDT 2010


Author: spyffe
Date: Mon Sep 13 16:34:21 2010
New Revision: 113789

URL: http://llvm.org/viewvc/llvm-project?rev=113789&view=rev
Log:
Bugfixes to the expression parser.  Fixes include:

 - If you put a semicolon at the end of an expression,
   this no longer causes the expression parser to
   error out.  This was a two-part fix: first,
   ClangExpressionDeclMap::Materialize now handles
   an empty struct (such as when there is no return
   value); second, ASTResultSynthesizer walks backward
   from the end of the ASTs until it reaches something
   that's not a NullStmt.

 - ClangExpressionVariable now properly byte-swaps when
   printing itself.

 - ClangUtilityFunction now cleans up after itself when
   it's done compiling itself.

 - Utility functions can now use external functions just
   like user expressions.

 - If you end your expression with a statement that does
   not return a value, the expression now runs correctly
   anyway.

Also, added the beginnings of an Objective-C object
validator function, which is neither installed nor used
as yet.

Modified:
    lldb/trunk/include/lldb/Expression/ClangExpression.h
    lldb/trunk/include/lldb/Expression/ClangFunction.h
    lldb/trunk/include/lldb/Expression/ClangUserExpression.h
    lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h
    lldb/trunk/include/lldb/Expression/IRDynamicChecks.h
    lldb/trunk/include/lldb/Expression/IRForTarget.h
    lldb/trunk/source/Commands/CommandObjectExpression.cpp
    lldb/trunk/source/Expression/ASTResultSynthesizer.cpp
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Expression/ClangExpressionParser.cpp
    lldb/trunk/source/Expression/ClangExpressionVariable.cpp
    lldb/trunk/source/Expression/ClangUserExpression.cpp
    lldb/trunk/source/Expression/ClangUtilityFunction.cpp
    lldb/trunk/source/Expression/IRDynamicChecks.cpp
    lldb/trunk/source/Expression/IRForTarget.cpp

Modified: lldb/trunk/include/lldb/Expression/ClangExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpression.h?rev=113789&r1=113788&r2=113789&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpression.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpression.h Mon Sep 13 16:34:21 2010
@@ -94,6 +94,24 @@
     //------------------------------------------------------------------
     virtual StreamString &
     DwarfOpcodeStream () = 0;
+    
+    //------------------------------------------------------------------
+    /// Flags
+    //------------------------------------------------------------------
+    
+    //------------------------------------------------------------------
+    /// Return true if validation code should be inserted into the
+    /// expression.
+    //------------------------------------------------------------------
+    virtual bool
+    NeedsValidation () = 0;
+    
+    //------------------------------------------------------------------
+    /// Return true if external variables in the expression should be
+    /// resolved.
+    //------------------------------------------------------------------
+    virtual bool
+    NeedsVariableResolution () = 0;
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/include/lldb/Expression/ClangFunction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangFunction.h?rev=113789&r1=113788&r2=113789&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangFunction.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangFunction.h Mon Sep 13 16:34:21 2010
@@ -564,6 +564,26 @@
         return *((StreamString*)0);
     }
     
+    //------------------------------------------------------------------
+    /// Return true if validation code should be inserted into the
+    /// expression.
+    //------------------------------------------------------------------
+    bool
+    NeedsValidation ()
+    {
+        return false;
+    }
+    
+    //------------------------------------------------------------------
+    /// Return true if external variables in the expression should be
+    /// resolved.
+    //------------------------------------------------------------------
+    bool
+    NeedsVariableResolution ()
+    {
+        return false;
+    }
+    
 private:
 	//------------------------------------------------------------------
 	// For ClangFunction only

Modified: lldb/trunk/include/lldb/Expression/ClangUserExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangUserExpression.h?rev=113789&r1=113788&r2=113789&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangUserExpression.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangUserExpression.h Mon Sep 13 16:34:21 2010
@@ -149,6 +149,26 @@
     //------------------------------------------------------------------
     StreamString &
     DwarfOpcodeStream ();
+    
+    //------------------------------------------------------------------
+    /// Return true if validation code should be inserted into the
+    /// expression.
+    //------------------------------------------------------------------
+    bool
+    NeedsValidation ()
+    {
+        return true;
+    }
+    
+    //------------------------------------------------------------------
+    /// Return true if external variables in the expression should be
+    /// resolved.
+    //------------------------------------------------------------------
+    bool
+    NeedsVariableResolution ()
+    {
+        return true;
+    }
 
 private:
     std::string                                 m_expr_text;            ///< The text of the expression, as typed by the user

Modified: lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h?rev=113789&r1=113788&r2=113789&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h Mon Sep 13 16:34:21 2010
@@ -126,7 +126,7 @@
     ClangExpressionDeclMap *
     DeclMap ()
     {
-        return NULL;
+        return m_expr_decl_map.get();
     }
     
     //------------------------------------------------------------------
@@ -163,12 +163,34 @@
         return *((StreamString*)NULL);
     }
     
+    //------------------------------------------------------------------
+    /// Return true if validation code should be inserted into the
+    /// expression.
+    //------------------------------------------------------------------
+    bool
+    NeedsValidation ()
+    {
+        return false;
+    }
+    
+    //------------------------------------------------------------------
+    /// Return true if external variables in the expression should be
+    /// resolved.
+    //------------------------------------------------------------------
+    bool
+    NeedsVariableResolution ()
+    {
+        return false;
+    }
+    
 private:
-    std::string     m_function_text;    ///< The text of the function.  Must be a well-formed translation unit.
-    std::string     m_function_name;    ///< The name of the function.
+    std::auto_ptr<ClangExpressionDeclMap>   m_expr_decl_map;    ///< The map to use when parsing and materializing the expression.
+    
+    std::string                             m_function_text;    ///< The text of the function.  Must be a well-formed translation unit.
+    std::string                             m_function_name;    ///< The name of the function.
     
-    lldb::addr_t    m_jit_begin;        ///< The address of the JITted code.  LLDB_INVALID_ADDRESS if invalid.
-    lldb::addr_t    m_jit_end;          ///< The end of the JITted code.  LLDB_INVALID_ADDRESS if invalid.
+    lldb::addr_t                            m_jit_begin;        ///< The address of the JITted code.  LLDB_INVALID_ADDRESS if invalid.
+    lldb::addr_t                            m_jit_end;          ///< The end of the JITted code.  LLDB_INVALID_ADDRESS if invalid.
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/include/lldb/Expression/IRDynamicChecks.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRDynamicChecks.h?rev=113789&r1=113788&r2=113789&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/IRDynamicChecks.h (original)
+++ lldb/trunk/include/lldb/Expression/IRDynamicChecks.h Mon Sep 13 16:34:21 2010
@@ -75,6 +75,7 @@
                   ExecutionContext &exe_ctx);
     
     std::auto_ptr<ClangUtilityFunction> m_valid_pointer_check;
+    std::auto_ptr<ClangUtilityFunction> m_objc_object_check;
 };
 
 //----------------------------------------------------------------------
@@ -99,6 +100,10 @@
     ///
     /// @param[in] func_name
     ///     The name of the function to prepare for execution in the target.
+    ///
+    /// @param[in] decl_map
+    ///     The mapping used to look up entities in the target process. In
+    ///     this case, used to find objc_msgSend
     //------------------------------------------------------------------
     IRDynamicChecks(DynamicCheckerFunctions &checker_functions,
                     const char* func_name = "___clang_expr");

Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRForTarget.h?rev=113789&r1=113788&r2=113789&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/IRForTarget.h (original)
+++ lldb/trunk/include/lldb/Expression/IRForTarget.h Mon Sep 13 16:34:21 2010
@@ -59,9 +59,15 @@
     ///
     /// @param[in] func_name
     ///     The name of the function to prepare for execution in the target.
+    ///
+    /// @param[in] resolve_vars
+    ///     True if the external variable references (including persistent
+    ///     variables) should be resolved.  If not, only external functions
+    ///     are resolved.
     //------------------------------------------------------------------
     IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
                 const llvm::TargetData *target_data,
+                bool resolve_vars,
                 const char* func_name = "___clang_expr");
     
     //------------------------------------------------------------------
@@ -294,10 +300,13 @@
     bool replaceVariables(llvm::Module &M,
                           llvm::Function &F);
     
-    std::string m_func_name;                            ///< The name of the function to translate
-    lldb_private::ClangExpressionDeclMap *m_decl_map;   ///< The DeclMap containing the Decls 
-    const llvm::TargetData *m_target_data;              ///< The TargetData for use in determining type sizes
-    llvm::Constant *m_sel_registerName;                 ///< The address of the function sel_registerName, cast to the appropriate function pointer type
+    /// Flags
+    bool                                    m_resolve_vars;         ///< True if external variable references and persistent variable references should be resolved
+    
+    std::string                             m_func_name;            ///< The name of the function to translate
+    lldb_private::ClangExpressionDeclMap   *m_decl_map;             ///< The DeclMap containing the Decls 
+    const llvm::TargetData                 *m_target_data;          ///< The TargetData for use in determining type sizes
+    llvm::Constant                         *m_sel_registerName;     ///< The address of the function sel_registerName, cast to the appropriate function pointer type
 };
 
 #endif

Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=113789&r1=113788&r2=113789&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Mon Sep 13 16:34:21 2010
@@ -219,7 +219,7 @@
         return false;
     }
     
-    ClangExpressionVariable *expr_result;
+    ClangExpressionVariable *expr_result = NULL;
     
     if (!user_expression.Execute (error_stream, m_exe_ctx, expr_result))
     {
@@ -249,7 +249,6 @@
     }
     else
     {
-        error_stream.Printf ("Expression produced no result\n");
         if (result)
             result->SetStatus (eReturnStatusSuccessFinishNoResult);
     }

Modified: lldb/trunk/source/Expression/ASTResultSynthesizer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ASTResultSynthesizer.cpp?rev=113789&r1=113788&r2=113789&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ASTResultSynthesizer.cpp (original)
+++ lldb/trunk/source/Expression/ASTResultSynthesizer.cpp Mon Sep 13 16:34:21 2010
@@ -113,6 +113,18 @@
     if (!function_decl)
         return false;
     
+    if (log)
+    {
+        std::string s;
+        raw_string_ostream os(s);
+        
+        function_decl->print(os);
+        
+        os.flush();
+        
+        log->Printf("Function AST before transforming:\n%s", s.c_str());
+    }
+    
     Stmt *function_body = function_decl->getBody();
     CompoundStmt *compound_stmt = dyn_cast<CompoundStmt>(function_body);
     
@@ -125,6 +137,15 @@
     Stmt **last_stmt_ptr = compound_stmt->body_end() - 1;
     Stmt *last_stmt = *last_stmt_ptr;
     
+    while (dyn_cast<NullStmt>(last_stmt))
+    {
+        if (last_stmt_ptr != compound_stmt->body_begin())
+        {
+            last_stmt_ptr--;
+            last_stmt = *last_stmt_ptr;
+        }
+    }
+    
     Expr *last_expr = dyn_cast<Expr>(last_stmt);
     
     if (!last_expr)

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=113789&r1=113788&r2=113789&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Mon Sep 13 16:34:21 2010
@@ -401,6 +401,16 @@
         return LLDB_INVALID_ADDRESS;
     }
     
+    if (!m_struct_size)
+    {
+        if (log)
+            log->PutCString("Not bothering to allocate a struct because no arguments are needed");
+        
+        m_allocated_area = NULL;
+        
+        return true;
+    }
+    
     const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
     
     if (!dematerialize)

Modified: lldb/trunk/source/Expression/ClangExpressionParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionParser.cpp?rev=113789&r1=113788&r2=113789&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionParser.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionParser.cpp Mon Sep 13 16:34:21 2010
@@ -403,7 +403,10 @@
         
         std::auto_ptr<llvm::TargetMachine> target_machine(target->createTargetMachine(m_target_triple, ""));
         
-        IRForTarget ir_for_target(decl_map, target_machine->getTargetData(), m_expr.FunctionName());
+        IRForTarget ir_for_target(decl_map, 
+                                  target_machine->getTargetData(),
+                                  m_expr.NeedsVariableResolution(),
+                                  m_expr.FunctionName());
         
         if (!ir_for_target.runOnModule(*module))
         {
@@ -412,14 +415,17 @@
             return err;
         }
         
-        IRDynamicChecks ir_dynamic_checks(*exe_ctx.process->GetDynamicCheckers(), m_expr.FunctionName());
-        
-        if (!ir_dynamic_checks.runOnModule(*module))
+        if (m_expr.NeedsValidation())
         {
-            err.SetErrorToGenericError();
-            err.SetErrorString("Couldn't add dynamic checks to the expression");
-            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();

Modified: lldb/trunk/source/Expression/ClangExpressionVariable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionVariable.cpp?rev=113789&r1=113788&r2=113789&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionVariable.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionVariable.cpp Mon Sep 13 16:34:21 2010
@@ -18,6 +18,8 @@
 #include "lldb/Core/DataExtractor.h"
 #include "lldb/Core/Stream.h"
 #include "lldb/Core/Value.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
 
 using namespace lldb_private;
 using namespace clang;
@@ -79,6 +81,12 @@
     DataExtractor data;
     Error expr_error = val.GetValueAsData (&exe_ctx, ast_context, data, 0);
     
+    
+    // Set byte order and pointer size to TARGET byte order and pointer size!
+    
+    data.SetByteOrder(exe_ctx.process->GetByteOrder());
+    data.SetAddressByteSize(exe_ctx.process->GetAddressByteSize());
+    
     if (!expr_error.Success ())
     {
         err.SetErrorToGenericError ();

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=113789&r1=113788&r2=113789&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Mon Sep 13 16:34:21 2010
@@ -196,13 +196,16 @@
             
             Error dump_error;
             
-            if (!m_expr_decl_map->DumpMaterializedStruct(&exe_ctx, args, dump_error))
+            if (struct_address)
             {
-                log->Printf("Couldn't extract variable values : %s", dump_error.AsCString("unknown error"));
-            }
-            else
-            {
-                log->Printf("Structure contents:\n%s", args.GetData());
+                if (!m_expr_decl_map->DumpMaterializedStruct(&exe_ctx, args, dump_error))
+                {
+                    log->Printf("Couldn't extract variable values : %s", dump_error.AsCString("unknown error"));
+                }
+                else
+                {
+                    log->Printf("Structure contents:\n%s", args.GetData());
+                }
             }
         }
         

Modified: lldb/trunk/source/Expression/ClangUtilityFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUtilityFunction.cpp?rev=113789&r1=113788&r2=113789&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUtilityFunction.cpp (original)
+++ lldb/trunk/source/Expression/ClangUtilityFunction.cpp Mon Sep 13 16:34:21 2010
@@ -17,6 +17,7 @@
 
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/Stream.h"
+#include "lldb/Expression/ClangExpressionDeclMap.h"
 #include "lldb/Expression/ClangExpressionParser.h"
 #include "lldb/Expression/ClangUtilityFunction.h"
 #include "lldb/Host/Host.h"
@@ -93,6 +94,8 @@
     //////////////////////////
     // Parse the expression
     //
+    
+    m_expr_decl_map.reset(new ClangExpressionDeclMap(&exe_ctx));
         
     ClangExpressionParser parser(target_triple.GetCString(), *this);
     
@@ -101,6 +104,9 @@
     if (num_errors)
     {
         error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
+        
+        m_expr_decl_map.reset();
+        
         return false;
     }
     
@@ -110,6 +116,8 @@
         
     Error jit_error = parser.MakeJIT (m_jit_begin, m_jit_end, exe_ctx);
     
+    m_expr_decl_map.reset();
+    
     if (jit_error.Success())
     {
         return true;

Modified: lldb/trunk/source/Expression/IRDynamicChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRDynamicChecks.cpp?rev=113789&r1=113788&r2=113789&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRDynamicChecks.cpp (original)
+++ lldb/trunk/source/Expression/IRDynamicChecks.cpp Mon Sep 13 16:34:21 2010
@@ -8,9 +8,12 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/Expression/IRDynamicChecks.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
 
+#include "lldb/Core/ConstString.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/StackFrame.h"
 
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Function.h"
@@ -23,6 +26,9 @@
 
 static char ID;
 
+static const char valid_pointer_check_name[] = 
+"___clang_valid_pointer_check";
+
 static const char valid_pointer_check_text[] = 
     "extern \"C\" void "
     "___clang_valid_pointer_check (unsigned char *ptr)"
@@ -30,13 +36,57 @@
         "unsigned char val = *ptr;"
     "}";
 
-static const char valid_pointer_check_name[] = 
-    "___clang_valid_pointer_check";
+static const char objc_object_check_name[] =
+    "___clang_objc_object_check";
+
+static bool FunctionExists(const SymbolContext &sym_ctx, const char *name)
+{
+    ConstString name_cs(name);
+
+    SymbolContextList sym_ctxs;
+    
+    sym_ctx.FindFunctionsByName(name_cs, false, sym_ctxs);
+
+    return (sym_ctxs.GetSize() != 0);
+}
+
+static const char *objc_object_check_text(ExecutionContext &exe_ctx)
+{
+    std::string ret;
+    
+    if (!exe_ctx.frame)
+        return "extern \"C\" void ___clang_objc_object_check (unsigned char *obj) { }";
+    
+    const SymbolContext &sym_ctx(exe_ctx.frame->GetSymbolContext(lldb::eSymbolContextEverything));
+
+    if (FunctionExists(sym_ctx, "gdb_object_getClass"))
+    {
+        return  "extern \"C\" void "
+                "___clang_objc_object_check(uint8_t *obj)"
+                "{"
+                    ""
+                "}";
+    }
+    else if (FunctionExists(sym_ctx, "gdb_class_getClass"))
+    {
+        return  "extern \"C\" void "
+                "___clang_objc_object_check(uint8_t *obj)"
+                "{"
+                    ""
+                "}";
+    }
+    else
+    {
+        return  "extern \"C\" void "
+                "___clang_objc_object_check(uint8_t *obj)"
+                "{"
+                    ""
+                "}";
+    }
+}
 
 DynamicCheckerFunctions::DynamicCheckerFunctions ()
 {
-    m_valid_pointer_check.reset(new ClangUtilityFunction(valid_pointer_check_text,
-                                                         valid_pointer_check_name));
 }
 
 DynamicCheckerFunctions::~DynamicCheckerFunctions ()
@@ -47,6 +97,9 @@
 DynamicCheckerFunctions::Install(Stream &error_stream,
                                  ExecutionContext &exe_ctx)
 {
+    m_valid_pointer_check.reset(new ClangUtilityFunction(valid_pointer_check_text,
+                                                         valid_pointer_check_name));
+    
     if (!m_valid_pointer_check->Install(error_stream, exe_ctx))
         return false;
         
@@ -104,7 +157,8 @@
     Instrumenter (llvm::Module &module,
                   DynamicCheckerFunctions &checker_functions) :
         m_module(module),
-        m_checker_functions(checker_functions)
+        m_checker_functions(checker_functions),
+        m_i8ptr_ty(NULL)
     {
     }
     
@@ -222,12 +276,42 @@
         return true;
     }
     
+    //------------------------------------------------------------------
+    /// Build a function pointer for a function with signature 
+    /// void (*)(uint8_t*) with a given address
+    ///
+    /// @param[in] start_address
+    ///     The address of the function.
+    ///
+    /// @return
+    ///     The function pointer, for use in a CallInst.
+    //------------------------------------------------------------------
+    llvm::Value *BuildPointerValidatorFunc(lldb::addr_t start_address)
+    {
+        std::vector<const llvm::Type*> params;
+        
+        const IntegerType *intptr_ty = llvm::Type::getIntNTy(m_module.getContext(),
+                                                             (m_module.getPointerSize() == llvm::Module::Pointer64) ? 64 : 32);
+        
+        if (!m_i8ptr_ty)
+            m_i8ptr_ty = llvm::Type::getInt8PtrTy(m_module.getContext());
+        
+        params.push_back(m_i8ptr_ty);
+        
+        FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true);
+        PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
+        Constant *fun_addr_int = ConstantInt::get(intptr_ty, start_address, false);
+        return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
+    }
+    
     typedef std::vector <llvm::Instruction *>   InstVector;
     typedef InstVector::iterator                InstIterator;
     
     InstVector                  m_to_instrument;        ///< List of instructions the inspector found
     llvm::Module               &m_module;               ///< The module which is being instrumented
     DynamicCheckerFunctions    &m_checker_functions;    ///< The dynamic checker functions for the process
+
+    const PointerType          *m_i8ptr_ty;
 };
 
 class ValidPointerChecker : public Instrumenter
@@ -249,21 +333,7 @@
                         PrintValue(inst).c_str());
         
         if (!m_valid_pointer_check_func)
-        {
-            std::vector<const llvm::Type*> params;
-            
-            const IntegerType *intptr_ty = llvm::Type::getIntNTy(m_module.getContext(),
-                                                                 (m_module.getPointerSize() == llvm::Module::Pointer64) ? 64 : 32);
-            
-            m_i8ptr_ty = llvm::Type::getInt8PtrTy(m_module.getContext());
-            
-            params.push_back(m_i8ptr_ty);
-            
-            FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true);
-            PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
-            Constant *fun_addr_int = ConstantInt::get(intptr_ty, m_checker_functions.m_valid_pointer_check->StartAddress(), false);
-            m_valid_pointer_check_func = ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
-        }
+            m_valid_pointer_check_func = BuildPointerValidatorFunc(m_checker_functions.m_valid_pointer_check->StartAddress());
         
         llvm::Value *dereferenced_ptr;
         
@@ -305,6 +375,104 @@
     }
     
     llvm::Value         *m_valid_pointer_check_func;
+};
+
+class ObjcObjectChecker : public Instrumenter
+{
+public:
+    ObjcObjectChecker(llvm::Module &module,
+                        DynamicCheckerFunctions &checker_functions) :
+        Instrumenter(module, checker_functions),
+        m_objc_object_check_func(NULL)
+    {
+    }
+private:
+    bool InstrumentInstruction(llvm::Instruction *inst)
+    {
+        CallInst *call_inst = dyn_cast<CallInst>(inst);
+        
+        if (!call_inst)
+            return false; // this really should be true, because otherwise InspectInstruction wouldn't have registered it
+        
+        if (!m_objc_object_check_func)
+            m_objc_object_check_func = BuildPointerValidatorFunc(m_checker_functions.m_objc_object_check->StartAddress());
+        
+        llvm::Value *target_object;
+        
+        // id objc_msgSend(id theReceiver, SEL theSelector, ...)
+        
+        target_object = call_inst->getArgOperand(0);
+        
+        // Insert an instruction to cast the receiver id to int8_t*
+        
+        BitCastInst *bit_cast = new BitCastInst(target_object,
+                                                m_i8ptr_ty,
+                                                "",
+                                                inst);
+        
+        // Insert an instruction to call the helper with the result
+        
+        SmallVector <llvm::Value*, 1> args;
+        args.push_back(bit_cast);
+        
+        CallInst::Create(m_objc_object_check_func, 
+                         args.begin(),
+                         args.end(),
+                         "",
+                         inst);
+        
+        return true;
+    }
+    
+    bool InspectInstruction(llvm::Instruction &i)
+    {
+        lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
+
+        CallInst *call_inst = dyn_cast<CallInst>(&i);
+        
+        if (call_inst)
+        {
+            // This metadata is set by IRForTarget::MaybeHandleCall().
+            
+            MDNode *metadata = call_inst->getMetadata("lldb.call.realName");
+                        
+            if (!metadata)
+                return true;
+            
+            if (metadata->getNumOperands() != 1)
+            {
+                if (log)
+                    log->Printf("Function call metadata has %d operands for [%p] %s", metadata->getNumOperands(), call_inst, PrintValue(call_inst).c_str());
+                return false;
+            }
+            
+            ConstantArray *real_name = dyn_cast<ConstantArray>(metadata->getOperand(0));
+            
+            if (!real_name)
+            {
+                if (log)
+                    log->Printf("Function call metadata is not a ConstantArray for [%p] %s", call_inst, PrintValue(call_inst).c_str());
+                return false;
+            }
+            
+            if (!real_name->isString())
+            {
+                if (log)
+                    log->Printf("Function call metadata is not a string for [%p] %s", call_inst, PrintValue(call_inst).c_str());
+                return false;
+            }
+            
+            if (log)
+                log->Printf("Found call to %s: %s\n", real_name->getAsString().c_str(), PrintValue(call_inst).c_str());
+            
+            if (real_name->getAsString().find("objc_msgSend") != std::string::npos)
+                RegisterInstruction(i);
+        }
+        
+        return true;
+    }
+    
+    llvm::Value         *m_objc_object_check_func;
     const PointerType   *m_i8ptr_ty;
 };
 
@@ -343,6 +511,16 @@
     if (!vpc.Instrument())
         return false;
     
+    /*
+    ObjcObjectChecker ooc(M, m_checker_functions);
+    
+    if (!ooc.Inspect(*function))
+        return false;
+    
+    if (!ooc.Instrument())
+        return false;
+    */
+    
     if (log)
     {
         std::string s;

Modified: lldb/trunk/source/Expression/IRForTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=113789&r1=113788&r2=113789&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRForTarget.cpp (original)
+++ lldb/trunk/source/Expression/IRForTarget.cpp Mon Sep 13 16:34:21 2010
@@ -32,12 +32,14 @@
 
 IRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
                          const TargetData *target_data,
+                         bool resolve_vars,
                          const char *func_name) :
     ModulePass(&ID),
     m_decl_map(decl_map),
     m_target_data(target_data),
     m_sel_registerName(NULL),
-    m_func_name(func_name)
+    m_func_name(func_name),
+    m_resolve_vars(resolve_vars)
 {
 }
 
@@ -65,7 +67,10 @@
 {
     lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
     
-    // Find the result variable
+    if (!m_resolve_vars)
+        return true;
+    
+    // Find the result variable.  If it doesn't exist, we can give up right here.
             
     Value *result_value = M.getNamedValue("___clang_expr_result");
     
@@ -73,9 +78,10 @@
     {
         if (log)
             log->PutCString("Couldn't find result variable");
-        return false;
+                
+        return true;
     }
-    
+        
     if (log)
         log->Printf("Found result in the IR: %s", PrintValue(result_value, false).c_str());
     
@@ -429,6 +435,9 @@
 IRForTarget::rewritePersistentAllocs(llvm::Module &M,
                                      llvm::BasicBlock &BB)
 {
+    if (!m_resolve_vars)
+        return true;
+    
     lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
     
     BasicBlock::iterator ii;
@@ -649,6 +658,17 @@
     
     C->setCalledFunction(fun_addr_ptr);
     
+    ConstantArray *func_name = (ConstantArray*)ConstantArray::get(M.getContext(), fun->getName());
+    
+    Value *values[1];
+    values[0] = func_name;
+    MDNode *func_metadata = MDNode::get(M.getContext(), values, 1);
+    
+    C->setMetadata("lldb.call.realName", func_metadata);
+    
+    if (log)
+        log->Printf("Set metadata for %p [%d, %s]", C, func_name->isString(), func_name->getAsString().c_str());
+    
     return true;
 }
 
@@ -667,13 +687,16 @@
     {
         Instruction &inst = *ii;
         
-        if (LoadInst *load = dyn_cast<LoadInst>(&inst))
-            if (!MaybeHandleVariable(M, load->getPointerOperand(), false))
-                return false;
+        if (m_resolve_vars)
+        {
+            if (LoadInst *load = dyn_cast<LoadInst>(&inst))
+                if (!MaybeHandleVariable(M, load->getPointerOperand(), false))
+                    return false;
             
-        if (StoreInst *store = dyn_cast<StoreInst>(&inst))
-            if (!MaybeHandleVariable(M, store->getPointerOperand(), true))
-                return false;
+            if (StoreInst *store = dyn_cast<StoreInst>(&inst))
+                if (!MaybeHandleVariable(M, store->getPointerOperand(), true))
+                    return false;
+        }
         
         if (CallInst *call = dyn_cast<CallInst>(&inst))
             if (!MaybeHandleCall(M, call))
@@ -886,6 +909,9 @@
 bool 
 IRForTarget::replaceVariables(Module &M, Function &F)
 {
+    if (!m_resolve_vars)
+        return true;
+    
     lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
 
     m_decl_map->DoStructLayout();





More information about the lldb-commits mailing list