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.

llvm-svn: 144741
This commit is contained in:
Sean Callanan 2011-11-16 00:20:50 +00:00
parent 2c523a6ff0
commit a6cbf06d0a
2 changed files with 78 additions and 3 deletions

View File

@ -423,6 +423,17 @@ public:
~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 @@ private:
// 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 @@ private:
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;

View File

@ -205,6 +205,12 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun,
name = g_memcpy_str;
}
break;
case Intrinsic::memset:
{
static lldb_private::ConstString g_memset_str ("memset");
name = g_memset_str;
}
break;
}
if (log && name)