2

以前の質問を新しいフォームで更新しました。こんにちは、みんな、

私は次のLLVMIRを持っています:

@.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)。また、から「DS」を取得する必要があり@.strます。私のターゲットコードには:

__attribute__((annotate("DS"))) int f=0;

@ llvm.global.annotationsの解析に問題があり、@。strで問題が発生すると思います。私が試したこと:

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

どんな助けでも大歓迎です!ありがとうございました !

4

3 に答える 3

1

その場合は、runOnFunction()の代わりにrunOnModule()を使用してください。または、モジュールを受講することもできます。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
}

} 
于 2013-02-27T17:41:55.487 に答える
1

かなり遅い答えですが、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 */);
于 2017-12-19T06:30:07.797 に答える
0

私はそれを解決しました。注釈付きの式全体をValue*にキャストしました。次に、getAsString()のような醜いものを避けるために、V->getValueID() == Value::ConstantArrayValそれをにキャストするかどうかを確認しConstantArrayます。array [0]しか含まれていないため、array0> getOperand(0)をにキャストしConstantStructます。したがって、からConstantStruct4つのオペランドすべてを取得できます。ここで行うことは、すべてのフィールドから@ f、@strの名前を取得することだけです。これはによって行われConstantStruct->getOperand(0)->getOperand(0)ます。

于 2013-03-01T12:34:17.070 に答える