2013-11-24 3 views
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 вызывается вместо (с теми же аргументами) , Как я мог это сделать?Изменение исходного кода во время компиляции (с использованием LLVM)

+1

Это не имеет никакого смысла. Прототипы для 'sprintf' и' printf' различны. И вы не передаете достаточно аргументов в 'sprintf' в вашем примере. Что именно вы пытаетесь достичь? –

+1

Исправлено. Я предпочел бы, чтобы один printf() заменил {sprintf() + puts()} на проход LLVM. Я впервые пробовал LLVM, задавался вопросом, как можно это делать. – t7t0t0t7t

ответ

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
#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 должна существовать в контексте.

+0

Для этого требуется модификация исходного кода перед компиляцией, которая мне не нравится, как просил OP (хотя это было принято). – Oak