ios 如何在LLVM IR中获取Objectivc-C选择器名称?

drnojrws  于 2023-02-17  发布在  iOS
关注(0)|答案(1)|浏览(107)

我是LLVM的初学者。我正在尝试开发一个LLVM通道。这个通道会找到所有的比较“self.currentGameID == 2007”,并将其替换为“true”。我成功找到了比较,正确的操作数“2007”很容易确认,但当我检查函数名是否为“currentGameID”时,我只得到了“objc_msgsend”。以下是代码:

bool handleComp(ICmpInst *cmpInst) {
    if (!cmpInst->hasOneUse()) {
        return false;
    }
    APInt CmpC = cast<ConstantInt>(cmpInst->getOperand(1))->getValue();
    if (!CmpC) {
        return false;
    }
    auto constIntValue = CmpC.getSExtValue();
    if (constIntValue == 2007) {
        auto BasicBlock = cmpInst->getParent();
        auto preInstruction = cmpInst->getPrevNode();
        if (isa<CallInst>(preInstruction)) {
            CallInst *ci = cast<CallInst>(preInstruction);
            Function *function = ci->getCalledFunction();
            if (function) {
                StringRef name = function->getName();
                errs().write_escaped(name) << '\n';
            } else {
                Function *voidFunc = dyn_cast<Function>(ci->getCalledOperand()->stripPointerCasts());
                StringRef name = voidFunc->getName();
                errs().write_escaped(name) << '\n';
            }
        }
        return true;
    }
    return false;
}

我得到了voidFunc名称,它是“objc_msgsend”!
有没有人可以告诉我如何获得真正的选择器名称“currentGameID”?

omhiaaxx

omhiaaxx1#

访问self.currentGameID这样的属性与[self currentGameID]是一样的,也就是说,它们都产生相同的Objective-C运行时调用objc_msgSend(self, @selector(currentGameID))
Objective-C代码if (self.currentGameID == 2007)将产生(大致)以下IR:

%1 = load i8*, i8** @OBJC_SELECTOR_REFERENCES_.0 
%2 = call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*)*)(i8* %0, i8* %1)
%3 = icmp eq i64 %2, 2007

因此,要获得实际的选择器,您可以使用ci->getArgOperand(i),其中i为1或2,具体取决于您使用的LLVM版本。

相关问题