在编译时更改源代码(使用LLVM) #包括 #包括 int foo(字符*a) {char-str[10]; 如果(斯特伦(a)

在编译时更改源代码(使用LLVM) #包括 #包括 int foo(字符*a) {char-str[10]; 如果(斯特伦(a),llvm,llvm-clang,llvm-ir,Llvm,Llvm Clang,Llvm Ir,现在,您可以使用例如my_printf(“我的名字是%s.”,“Bozo”);,默认情况下,它将编译为printf(“我的名字是%s.”,“Bozo”) 如果在头文件之前包含#define USE_BUFFER,它将在编译时将这些行转换为sprintf(BUFFER,“我的名字是%s.”,“Bozo”)。当然,变量BUFFER必须存在于上下文中 现在,您可以使用例如my_printf(“我的名字是%s.”,“Bozo”);,默认情况下,它将编译为printf(“我的名字是%s.”,“Bozo”)

现在,您可以使用例如
my_printf(“我的名字是%s.”,“Bozo”);
,默认情况下,它将编译为
printf(“我的名字是%s.”,“Bozo”)

如果在头文件之前包含
#define USE_BUFFER
,它将在编译时将这些行转换为
sprintf(BUFFER,“我的名字是%s.”,“Bozo”)
。当然,变量
BUFFER
必须存在于上下文中

现在,您可以使用例如
my_printf(“我的名字是%s.”,“Bozo”);
,默认情况下,它将编译为
printf(“我的名字是%s.”,“Bozo”)

如果在头文件之前包含
#define USE_BUFFER
,它将在编译时将这些行转换为
sprintf(BUFFER,“我的名字是%s.”,“Bozo”)
。当然,变量
BUFFER
必须存在于上下文中

现在,您可以使用例如
my_printf(“我的名字是%s.”,“Bozo”);
,默认情况下,它将编译为
printf(“我的名字是%s.”,“Bozo”)

如果在头文件之前包含
#define USE_BUFFER
,它将在编译时将这些行转换为
sprintf(BUFFER,“我的名字是%s.”,“Bozo”)
。当然,变量
BUFFER
必须存在于上下文中

现在,您可以使用例如
my_printf(“我的名字是%s.”,“Bozo”);
,默认情况下,它将编译为
printf(“我的名字是%s.”,“Bozo”)

如果在头文件之前包含
#define USE_BUFFER
,它将在编译时将这些行转换为
sprintf(BUFFER,“我的名字是%s.”,“Bozo”)
。当然变量
BUFFER
必须存在于上下文中。

简而言之

  • 检查函数中的所有说明
  • 如果指令是
    CallInst
    ,请检查它是否是对
    sprintf
    的调用(您只需检查它的名称即可)
  • 创建一个新的
    CallInst
    (这将调用
    printf
    而不是
    sprintf
    。我认为获取
    printf
    声明的
    值的最简单方法是使用
    Module::getOrCreate
    方法之一。
    printf
    的类型应该与
    sprintf
    的类型相同,减去第一个参数
  • 将新调用指令的操作数设置为与
    sprintf
    相同,减去第一个参数
  • 用新电话替换旧电话-可能是最方便的方式
  • 最后,您可能希望跟踪旧的第一个参数的用法,将它们全部删除,然后将其删除-这样您就可以摆脱
    put
    调用
  • 简言之

  • 检查函数中的所有说明
  • 如果指令是
    CallInst
    ,请检查它是否是对
    sprintf
    的调用(您只需检查它的名称即可)
  • 创建一个新的
    CallInst
    (这将调用
    printf
    而不是
    sprintf
    。我认为获取
    printf
    声明的
    值的最简单方法是使用
    Module::getOrCreate
    方法之一。
    printf
    的类型应该与
    sprintf
    的类型相同,减去第一个参数
  • 将新调用指令的操作数设置为与
    sprintf
    相同,减去第一个参数
  • 用新电话替换旧电话-可能是最方便的方式
  • 最后,您可能希望跟踪旧的第一个参数的用法,将它们全部删除,然后将其删除-这样您就可以摆脱
    put
    调用
  • 简言之

  • 检查函数中的所有说明
  • 如果指令是
    CallInst
    ,请检查它是否是对
    sprintf
    的调用(您只需检查它的名称即可)
  • 创建一个新的
    CallInst
    (这将调用
    printf
    而不是
    sprintf
    。我认为获取
    printf
    声明的
    值的最简单方法是使用
    Module::getOrCreate
    方法之一。
    printf
    的类型应该与
    sprintf
    的类型相同,减去第一个参数
  • 将新调用指令的操作数设置为与
    sprintf
    相同,减去第一个参数
  • 用新电话替换旧电话-可能是最方便的方式
  • 最后,您可能希望跟踪旧的第一个参数的用法,将它们全部删除,然后将其删除-这样您就可以摆脱
    put
    调用
  • 简言之

  • 检查函数中的所有说明
  • 如果指令是
    CallInst
    ,请检查它是否是对
    sprintf
    的调用(您只需检查它的名称即可)
  • 创建一个新的
    CallInst
    (这将调用
    printf
    而不是
    sprintf
    。我认为获取
    printf
    声明的
    值的最简单方法是使用
    Module::getOrCreate
    方法之一。
    printf
    的类型应该与
    sprintf
    的类型相同,减去第一个参数
  • 将新调用指令的操作数设置为与
    sprintf
    相同,减去第一个参数
  • 用新电话替换旧电话-可能是最方便的方式
  • 最后,您可能希望跟踪旧的第一个参数的用法,将它们全部删除,然后将其删除-这样您就可以摆脱
    put
    调用

  • 这没有任何意义。
    sprintf
    printf
    的原型是不同的。而且在您的示例中,您没有向
    sprintf
    传递足够的参数。您到底想完成什么?修复了它。我宁愿唱歌
    #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;
         }
        }
    
    #ifdef USE_BUFFER
    #define my_printf(...) sprintf(buffer, __VA_ARGS__)
    #else
    #define my_printf(...) printf(__VA_ARGS__)
    #endif