저는 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임을 알았습니다. 이는임을 의미합니다..
그러나 이제 내용을 인수로 전달되는 문자열 리터럴으로 가져와 실제로 주어진 숫자와 예상되는 인수의 수를 확인할 수 있습니까?
굉장해! 'getOperand'는 올바른 방향으로 나를 가리켰다! 저에게 제공하는'cast (cast (cast (CS.getArgument (0)) -> getOperand (0)) -> getInitializer()) -> getAsCString 문자열. :) 정말 고맙습니다! –
Mehrdad