原文
问题
我用一个新的表格更新了之前的问题。大家好,
我有以下LLVM IR:
@.str = private unnamed_addr constant [3 x i8] c"DS\00", section "llvm.metadata"
@llvm.global.annotations = appending global [1 x { i8*, i8*, i8*, i32 }] [{ i8*, i8*, i8*, i32 } { i8* bitcast (i32* @f to i8*), i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str1, i32 0, i32 0), i32 18 }], section "llvm.metadata"
我需要得到@f(或者我可以得到
@f = global i32 0, align 4
的定义),我还需要从
@.str
得到“DS”。在我的目标代码中,我有:
__attribute__((annotate("DS"))) int f=0;
我无法解析
@llvm.global.annotations
,我想我会用
@.str
。我试着:
- 代码
结果:for (Module::global_iterator I = F.global_begin(), E = F.global_end(); I != E; ++I) { if (I->getName() == "llvm.global.annotations") { Value *V = cast<Value>(I->getOperand(0)); errs()<<"\n "<<*(V)<<"\n"; errs()<<"\n "<<*(V->getType())<<"\n";
[1 x { i8*, i8*, i8*, i32 }] [{ i8*, i8*, i8*, i32 } { i8* bitcast (i32* @f to i8*), i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str1, i32 0, i32 0), i32 18 }] [1 x { i8*, i8*, i8*, i32 }]
- 代码:
结果errs()<<"\n "<<(V->getValueID())<<"\n"; if(V->getValueID() == Value::ConstantArrayVal) { ConstantArray *ca = (ConstantArray *)V; errs()<<"\n "<<(ca[0])<<"\n"; }
[1 x { i8*, i8*, i8*, i32 }] [{ i8*, i8*, i8*, i32 } { i8* bitcast (i32* @f to i8*), i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([9 x i8]* @.str1, i32 0, i32 0), i32 18 }]
欢迎任何帮助!谢谢你!
3个回答
- 如果你做这项工作请使用runOnModule()而不是runOnFunction()。或者,您可以使用模块。llvm.global.annotations是在函数外部定义的。在内部做类似的事情:
for (Module::global_iterator I = F.global_begin(), E = F.global_end(); I != E; ++I) { if (I->getName() == "llvm.global.annotations") { errs()<<"\nllvm.global.annotations\n"; //1. find out what global variable is by "parsing" the IR //2. get through the module till you find a load @f //3. you can add metadata to the load function and you can easily get the metadata from the normal pass } }
- 我解决了它。我将整个带注释的表达式转换为
。然后,为了避免像Value*
这样难看的东西,我检查是否getAsString()
,以便将它转换为V->getValueID() == Value::ConstantArrayVal
。因为它只包含ConstantArray
,所以我将array[0]
转换为array0>getOperand(0)
。因此,从ConstantStruct
你可以获得所有四个操作数。现在要做的就是从每个字段中获取ConstantStruct
的名称。这是由@f、@str
完成的。ConstantStruct->getOperand(0)->getOperand(0)
- 这是一个很晚才给出的答案,但是谷歌把我带到这里,我认为提供一个完整的LLVM pass来发现免费的文本注释是有帮助的。这个LLVM pass将只测试用_attribute((annotate(“someFreeTextAnnotation”)标记的函数。代码如下:
#include "llvm/Pass.h" #include "llvm/IR/Function.h" #include "llvm/Support/raw_ostream.h" #include "llvm/IR/Module.h" #include "llvm/IR/Constants.h" #include <set> using namespace llvm; const char *AnnotationString = "someFreeTextAnnotation"; namespace { struct Hello : public FunctionPass { static char ID; Hello() : FunctionPass(ID) {} std::set<Function*> annotFuncs; virtual bool doInitialization(Module &M)override{ getAnnotatedFunctions(&M); return false; } bool shouldInstrumentFunc(Function &F){ return annotFuncs.find(&F)!=annotFuncs.end(); } void getAnnotatedFunctions(Module *M){ for (Module::global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) { if (I->getName() == "llvm.global.annotations") { ConstantArray *CA = dyn_cast<ConstantArray>(I->getOperand(0)); for(auto OI = CA->op_begin(); OI != CA->op_end(); ++OI){ ConstantStruct *CS = dyn_cast<ConstantStruct>(OI->get()); Function *FUNC = dyn_cast<Function>(CS->getOperand(0)->getOperand(0)); GlobalVariable *AnnotationGL = dyn_cast<GlobalVariable>(CS->getOperand(1)->getOperand(0)); StringRef annotation = dyn_cast<ConstantDataArray>(AnnotationGL->getInitializer())->getAsCString(); if(annotation.compare(AnnotationString)==0){ annotFuncs.insert(FUNC); //errs() << "Found annotated function " << FUNC->getName()<<"\n"; } } } } } bool runOnFunction(Function &F) override { if(shouldInstrumentFunc(F)==false) return false; errs() << "Instrumenting " << F.getName() << "\n"; return false; } }; // end of struct Hello } // end of anonymous namespace char Hello::ID = 0; static RegisterPass<Hello> X("hello", "Discover annotation attribute", false /* Only looks at CFG */, false /* Analysis Pass */);