Two fixes for Objetive-C methods that return struct
types. First, I added handling for the memset intrinsic
in the IR, which is used to zero out the returned struct.
Second, I fixed the object-checking instrumentation
to objc_msgSend_stret, and generally tightened up how
the object-checking functions get inserted.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@144741 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/IRDynamicChecks.cpp b/source/Expression/IRDynamicChecks.cpp
index 1d6637d..0cf812f 100644
--- a/source/Expression/IRDynamicChecks.cpp
+++ b/source/Expression/IRDynamicChecks.cpp
@@ -423,6 +423,17 @@
~ObjcObjectChecker ()
{
}
+
+ enum msgSend_type
+ {
+ eMsgSend = 0,
+ eMsgSendSuper,
+ eMsgSendSuper_stret,
+ eMsgSend_fpret,
+ eMsgSend_stret
+ };
+
+ std::map <llvm::Instruction *, msgSend_type> msgSend_types;
private:
bool InstrumentInstruction(llvm::Instruction *inst)
@@ -437,8 +448,23 @@
// id objc_msgSend(id theReceiver, SEL theSelector, ...)
- llvm::Value *target_object = call_inst->getArgOperand(0);;
- llvm::Value *selector = call_inst->getArgOperand(1);
+ llvm::Value *target_object;
+ llvm::Value *selector;
+
+ switch (msgSend_types[inst])
+ {
+ case eMsgSend:
+ case eMsgSend_fpret:
+ target_object = call_inst->getArgOperand(0);
+ selector = call_inst->getArgOperand(1);
+ break;
+ case eMsgSend_stret:
+ target_object = call_inst->getArgOperand(1);
+ selector = call_inst->getArgOperand(2);
+ case eMsgSendSuper:
+ case eMsgSendSuper_stret:
+ return true;
+ }
// Insert an instruction to cast the receiver id to int8_t*
@@ -505,8 +531,51 @@
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)
+ std::string name_str = real_name->getAsString();
+ const char* name_cstr = name_str.c_str();
+
+ if (name_str.find("objc_msgSend") == std::string::npos)
+ return true;
+
+ if (!strcmp(name_cstr, "objc_msgSend"))
+ {
RegisterInstruction(i);
+ msgSend_types[&i] = eMsgSend;
+ return true;
+ }
+
+ if (!strcmp(name_cstr, "objc_msgSend_stret"))
+ {
+ RegisterInstruction(i);
+ msgSend_types[&i] = eMsgSend_stret;
+ return true;
+ }
+
+ if (!strcmp(name_cstr, "objc_msgSend_fpret"))
+ {
+ RegisterInstruction(i);
+ msgSend_types[&i] = eMsgSend_fpret;
+ return true;
+ }
+
+ if (!strcmp(name_cstr, "objc_msgSendSuper"))
+ {
+ RegisterInstruction(i);
+ msgSend_types[&i] = eMsgSendSuper;
+ return true;
+ }
+
+ if (!strcmp(name_cstr, "objc_msgSendSuper_stret"))
+ {
+ RegisterInstruction(i);
+ msgSend_types[&i] = eMsgSendSuper_stret;
+ return true;
+ }
+
+ if (log)
+ log->Printf("Function name '%s' contains 'objc_msgSend' but is not handled", name_str.c_str());
+
+ return true;
}
return true;
diff --git a/source/Expression/IRForTarget.cpp b/source/Expression/IRForTarget.cpp
index c6d7f2d..ba8df14 100644
--- a/source/Expression/IRForTarget.cpp
+++ b/source/Expression/IRForTarget.cpp
@@ -205,6 +205,12 @@
name = g_memcpy_str;
}
break;
+ case Intrinsic::memset:
+ {
+ static lldb_private::ConstString g_memset_str ("memset");
+ name = g_memset_str;
+ }
+ break;
}
if (log && name)