[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