在编译时更改源代码(使用LLVM)

时间:2013-11-24 23:47:34

标签: llvm llvm-clang llvm-ir

#include <stdio.h>
#include <string.h>    
int foo(char* a)
    { char str[10];
      if (strlen(a)<10) 
     { 
       sprintf(str,"Yes");
       puts(str);
       return 0;
     }
     else
     {
       sprintf(str,"No");
       puts(str);
       return 1;
     }
    }

现在,让我们说在编写LLVM传递时,我想确保不是调用 sprintf 而是调用 printf (使用相同的参数)。我怎么能这样做呢?

2 个答案:

答案 0 :(得分:2)

简而言之,

  1. 查看函数中的所有说明。
  2. 如果说明是CallInst,请检查是否是对sprintf的调用(您只需检查其名称)。
  3. 创建一个新的CallInst via CallInst::Create),调用printf而不是sprintf。我认为获取Value printf的最简单方法声明是使用Module::getOrCreate方法之一。printf的类型应与sprintf减去第一个参数的类型相同。
  4. 将新呼叫指令的操作数设置为与sprintf相同,减去第一个参数。
  5. 使用新来电替换旧通话 - replaceInstWithInst (in BasicBlockUtils.h)可能是最方便的方式。
  6. 最后,您可能希望跟踪旧的第一个参数的用法,将它们全部删除然后将其删除 - 这样您就可以摆脱puts次呼叫。

答案 1 :(得分:1)

#ifdef USE_BUFFER
#define my_printf(...) sprintf(buffer, __VA_ARGS__)
#else
#define my_printf(...) printf(__VA_ARGS__)
#endif

现在您可以使用例如my_printf("My name is %s.", "Bozo");,默认情况下它将编译为printf("My name is %s.", "Bozo")

如果在标题之前包含#define USE_BUFFER,则会在编译时将这些行转换为sprintf(buffer, "My name is %s.", "Bozo")。当然,变量buffer必须存在于上下文中。