Ich bin neu in LLVM. Ich versuche, einen grundlegenden Pass zu schreiben, der die Argumente eines printf
-Aufrufs untersucht, wenn ihm die Intermediate-Repräsentation zugewiesen wird.
Wenn die Formatzeichenfolge kein Zeichenfolgenliteral ist, kann ich sie natürlich nicht prüfen. Aber ziemlich oft ist es.Wie erhalten Sie den Wert eines String-Literals in LLVM IR?
Die Probe IR ich zu inspizieren bin versucht:
@.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*, ...)
fand ich den bereits existierenden Pass ExternalFunctionsPassedConstants
genannt, die relevant schien:
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;
...
So habe ich den Code:
if (I->getName() == "printf") {
errs() << "printf() arg0 type: "
<< CS.getArgument(0)->getType()->getTypeID() << "\n";
}
So weit, so gut - ich sehe, dass die Typ-ID 14 ist, was bedeutet, dass es eineist.
Nun aber, wie bekomme ich die Inhalt des String-Literals, das als Argument übergeben wird, so kann ich die Anzahl der erwarteten Argumente gegen die tatsächlich angegebene Zahl validieren?
Oh großartig! 'getOperand' zeigte mir in die richtige Richtung! Es scheint, ich brauche 'cast (cast (cast (CS.getArgument (0)) -> getOperand (0)) -> getInitializer()) -> getAsCString()', die mir gibt die Saite. :) Ich danke dir sehr! –
Mehrdad