原文
問題
我用一個新的表格更新了之前的問題。大家好,
我有以下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 */);