2012-08-26 4 views
6

저는 LLVM을 처음 사용합니다. 중급 표현이 주어지면 printf 호출의 인수를 검사 할 기본 Pass를 작성하려고합니다.
형식 문자열이 문자열 리터럴이 아니면 물론 검사 할 수 없습니다. 그러나 아주 자주, 그렇습니다.LLVM IR에서 문자열 리터럴 값을 얻는 방법은 무엇입니까?

내가 검사하기 위해 노력하고있어 샘플 IR은 다음과 같습니다

:
struct ExternalFunctionsPassedConstants : public ModulePass { 
    static char ID; // Pass ID, replacement for typeid 
    ExternalFunctionsPassedConstants() : ModulePass(ID) {} 
    virtual bool runOnModule(Module &M) { 
    for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { 
     if (!I->isDeclaration()) continue; 

     bool PrintedFn = false; 
     for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); 
      UI != E; ++UI) { 
     Instruction *User = dyn_cast<Instruction>(*UI); 
     if (!User) continue; 

     CallSite CS(cast<Value>(User)); 
     if (!CS) continue; 

     ... 

그래서 나는 코드를 추가 :

@.str = private unnamed_addr constant [7 x i8] c"Hi %u\0A\00", align 1 

define i32 @main() nounwind { 
entry: 
    %retval = alloca i32, align 4 
    store i32 0, i32* %retval 
    %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0), i32 1) 
    ret i32 0 
} 

declare i32 @printf(i8*, ...) 

가 나는 기존의 패스 관련 보였다 ExternalFunctionsPassedConstants 라 불리는 발견

 if (I->getName() == "printf") { 
      errs() << "printf() arg0 type: " 
       << CS.getArgument(0)->getType()->getTypeID() << "\n"; 
     } 

지금까지 매우 좋았습니다. 유형 ID가 14임을 알았습니다. 이는임을 의미합니다..

그러나 이제 내용을 인수로 전달되는 문자열 리터럴으로 가져와 실제로 주어진 숫자와 예상되는 인수의 수를 확인할 수 있습니까?

답변

6
CS.getArgument(0) 

는 GetElementPtrConstantExpr

i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0) 

는, 그것이 사용자 개체입니다 나타냅니다. 원하는 문자열 (예 : @ .str)은 GetElementPtrConstantExpr의 첫 번째 피연산자입니다.

그래서, 당신은 그러나

CS.getArgument(0).getOperand(0) 

을 통해 리터럴 문자열을 얻을 수 있습니다,이 코드를 테스트하지 않았습니다. 실수가 있으면 알려주세요.

+2

굉장해! 'getOperand'는 올바른 방향으로 나를 가리켰다! 저에게 제공하는'cast (cast (cast (CS.getArgument (0)) -> getOperand (0)) -> getInitializer()) -> getAsCString 문자열. :) 정말 고맙습니다! – Mehrdad