0
#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(使用相同的参数)。我怎么能这样做呢?

4

2 回答 2

2

简而言之,

  1. 浏览函数中的所有指令。
  2. 如果指令是 a CallInst,请检查它是否是对的调用sprintf(您可以检查它的名称)。
  3. 创建一个新的CallInst通过 CallInst::Create)调用printf而不是sprintf. 我认为获得声明的最简单方法Valueprintf使用其中一种Module::getOrCreate方法。的类型printf应该与sprintf减去第一个参数的类型相同。
  4. 将新调用指令的操作数设置为与 for 相同sprintf,减去第一个参数。
  5. 用新调用替换旧调用 - replaceInstWithInst(在 BasicBlockUtils.h 中)可能是最方便的方法。
  6. 最后,您可能想要跟踪旧的第一个参数的用法,将它们全部删除,然后将其删除 - 这样您就可以摆脱该puts调用。
于 2013-11-25T07:24:33.857 回答
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必须存在于上下文中。

于 2013-11-24T23:56:28.237 回答