天天看點

llvm得到annotations

原文

問題

我用一個新的表格更新了之前的問題。大家好,

我有以下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 }]
               

歡迎任何幫助!謝謝你!

3個回答

  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
    }
    
    } 
               
  2. 我解決了它。我将整個帶注釋的表達式轉換為

    Value*

    。然後,為了避免像

    getAsString()

    這樣難看的東西,我檢查是否

    V->getValueID() == Value::ConstantArrayVal

    ,以便将它轉換為

    ConstantArray

    。因為它隻包含

    array[0]

    ,是以我将

    array0>getOperand(0)

    轉換為

    ConstantStruct

    。是以,從

    ConstantStruct

    你可以獲得所有四個操作數。現在要做的就是從每個字段中擷取

    @f、@str

    的名稱。這是由

    ConstantStruct->getOperand(0)->getOperand(0)

    完成的。
  3. 這是一個很晚才給出的答案,但是谷歌把我帶到這裡,我認為提供一個完整的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 */);
               

繼續閱讀