Подтвердить что ты не робот

Анализ и изменение кода LLVM IR

Я хочу прочитать (проанализировать) код LLVM IR (который сохраняется в текстовом файле) и добавить к нему некоторый мой собственный код. Мне нужен пример этого, то есть, как это делается, используя библиотеки, предоставленные LLVM для этой цели. Так что в основном я хочу читать в ИК-коде из текстового файла в память (возможно, библиотека LLVM представляет его в форме AST, я не знаю), вносите изменения, например добавляя еще несколько узлов в AST, а затем, наконец, пишите вернуть AST в текстовый файл IR.

Хотя мне нужно как читать, так и изменять IR-код, я был бы очень признателен, если бы кто-то мог предоставить или передать мне какой-то пример, который просто читал (анализирует) его.

4b9b3361

Ответ 1

Во-первых, чтобы устранить очевидное недоразумение: LLVM - это среда для управления кодом в формате IR. Нет АСТ в поле зрения (*) - вы читаете IR, трансформируете/манипулируете/анализируете его, и вы пишете IR назад.

Чтение IR очень просто:

int main(int argc, char** argv)
{
    if (argc < 2) {
        errs() << "Expected an argument - IR file name\n";
        exit(1);
    }

    LLVMContext &Context = getGlobalContext();
    SMDiagnostic Err;
    Module *Mod = ParseIRFile(argv[1], Err, Context);

    if (!Mod) {
        Err.print(argv[0], errs());
        return 1;
    }

    [...]
  }

Этот код принимает имя файла. Это должен быть IR файл LLVM (текстовый). Затем он анализирует его на Module, который представляет собой модуль IR в внутреннем формате LLVM в памяти. Затем это можно манипулировать с помощью различных пропусков, которые LLVM имеет или вы добавляете самостоятельно. Взгляните на некоторые примеры в базе кода LLVM (например, lib/Transforms/Hello/Hello.cpp) и прочитайте это - http://llvm.org/docs/WritingAnLLVMPass.html.

Прыгать IR обратно в файл еще проще. Класс Module просто записывается в поток:

 some_stream << *Mod;

Что это.

Теперь, если у вас есть какие-то конкретные вопросы о конкретных изменениях, которые вы хотите сделать для IR-кода, вы должны действительно спросить что-то более целенаправленное. Надеюсь, этот ответ покажет вам, как анализировать ИК-сигналы и записывать их обратно.


(*) IR не имеет представления АСТ внутри LLVM, потому что это простой ассемблерный язык. Если вы переходите на один уровень вверх, на C или С++, вы можете использовать Clang для разбора в AST, а затем выполнять манипуляции на уровне AST. Затем Кланг знает, как производить LLVM IR из своего АСТ. Однако вам нужно начинать с C/С++ здесь, а не LLVM IR. Если LLVM IR вам все равно, забудьте об AST.

Ответ 2

Это обычно делается путем реализации LLVM pass/transform. Таким образом, вам не нужно анализировать IR вообще, потому что LLVM сделает это за вас, и вы будете работать с OO-ориентированным представлением IR в памяти.

Это является точкой входа для записи пропуска LLVM. Затем вы можете посмотреть любой из уже реализованных стандартных проходов, которые поставляются в комплекте с LLVM (посмотрите lib/Transforms).

Ответ 3

Самый простой способ сделать это - посмотреть на один из существующих инструментов и украсть у него код. В этом случае вы можете посмотреть источник для llc. В качестве входных данных он может принимать либо биткод, либо файл .ll. Вы можете изменить входной файл любым способом, а затем записать файл, используя что-то похожее на код в llvm-dis, если вы хотите получить текстовый файл.

Ответ 4

Инструмент Opt принимает llvm IR-код, прогоняет его, а затем выплескивает преобразованный IRI IR с другой стороны.

Самый простой способ начать взлом - lib\Transforms\Hello\Hello.cpp. Взломайте его, запустите опцию с исходным файлом в качестве ввода, проверьте вывод.

Кроме того, документы для написания пропусков действительно неплохие.

Ответ 5

Как упоминалось выше, лучший способ написать пропуск. Но если вы хотите просто перебирать инструкции и делать что-то с LLVM, предоставляемым классом InstVisitor. Это класс, который реализует шаблон посетителя для инструкций. Это очень просто для пользователя, поэтому, если вы хотите не узнать, как реализовать пропуск, вы можете прибегнуть к этому.