2013-02-27 44 views
2

我更新了我的上一個問題在一個新的形式。 大家好,llvm獲得註釋

我有以下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。我的嘗試:

1.

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 }] 

2.

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 }] 

歡迎任何幫助!謝謝 !

回答

0

我解決了它。 我將整個帶註釋的表達式轉換爲值*。然後,爲了避免像getAsString()這樣的醜陋事情,我檢查V->getValueID() == Value::ConstantArrayVal是否將它轉換爲ConstantArray。因爲它只包含數組[0],所以我投射array0> getOperand(0)到ConstantStruct。因此,從ConstantStruct你可以得到所有的四個操作數。現在要做的只是從每個字段獲取@f,@str的名稱。這由ConstantStruct->getOperand(0)->getOperand(0)完成。

1

如果您這樣做,請使用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 
} 

} 
+0

感謝您的回覆。我試圖按照你的路線,我更新了我的問題。 – Alex 2013-02-28 11:02:49

+0

我更新了我的回答。我將在小問題解決後編輯它。 – Alex 2013-03-01 12:35:40

0

這是一個很晚的答案,但Google在這裏引導我,我認爲提供一個完整的LLVM傳遞發現自由文本註釋會有所幫助。 此LLVM傳遞只會記錄帶有__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 */);