Статический анализ исходного кода с LLVM

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

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

Править:

С моим анализом я на самом деле хочу извлечь вызов функции caller/callee. В случае указателя функции я хотел бы возвратить ряд возможного вызываемого. и вызывающая сторона и вызываемый должны быть, определяют в исходном коде (это не включает стороннюю функцию в библиотеку).

16
задан Phong 2 March 2010 в 00:08
поделиться

5 ответов

Вам стоит взглянуть на Эльзу . Его относительно легко расширить, и он позволяет довольно легко анализировать AST. Он обрабатывает весь синтаксический анализ, лексирование и генерацию AST, а затем позволяет вам перемещаться по дереву, используя шаблон Visitor.

class CallGraphGenerator : public ASTVisitor
{
  //...
  virtual bool visitFunction(Function *func);
  virtual bool visitExpression(Expression *expr);
}

Затем вы можете обнаруживать объявления функций и, возможно, обнаруживать использование указателя функции. Наконец, вы можете проверить объявления указателей функций и сгенерировать список объявленных функций, которые могли быть вызваны с использованием этого указателя.

5
ответ дан 30 November 2019 в 22:31
поделиться

Думаю, ваш вопрос неверен. В названии написано «Статический анализ исходного кода». Тем не менее, ваша основная причина, по-видимому, заключается в построении (части) графа вызовов, включая вызовы через указатель функции. Суть указателей на функции заключается в том, что вы не можете узнать их значения во время компиляции, то есть в момент, когда вы проводите статический анализ исходного кода. Рассмотрим этот фрагмент кода:

void (*pFoo)() = GetFoo();
pFoo();

Статический анализ кода не может сказать вам, что GetFoo () возвращает во время выполнения, хотя он может сказать вам, что результат впоследствии используется для вызова функции.

Какие значения может вернуть GetFoo ()? Вы просто не можете сказать это вообще (эквивалентно решению проблемы остановки). Вы сможете угадывать несколько тривиальных случаев. Предполагаемый процент, конечно, будет расти в зависимости от того, сколько усилий вы готовы вложить.

1
ответ дан 30 November 2019 в 22:31
поделиться

Я думаю, что Clang (анализатор, являющийся частью LLVM) ориентирован на обнаружение ошибок, что означает, что анализатор пытается вычислить возможные значения некоторые выражения (для уменьшения количества ложных срабатываний), но иногда он отказывается (в данном случае не выдаёт сигнал тревоги, чтобы избежать потока ложных срабатываний).

Если ваша программа работает только на C, я рекомендую вам взглянуть на анализ значений в Frama-C . Он вычисляет надмножества возможных значений для любого l-значения в каждой точке программы при некоторых гипотезах, которые подробно объясняются здесь .Сложность в анализируемой программе означает только то, что возвращенные надмножества являются более приближенными, но они по-прежнему содержат все возможные значения времени выполнения (пока вы остаетесь в рамках вышеупомянутых гипотез).

РЕДАКТИРОВАТЬ: если вас интересуют возможные значения указателей функций с целью разрезания анализируемой программы, вам обязательно следует взглянуть на существующие зависимости и вычисления нарезки в Frama-C. На веб-сайте нет хороших примеров для нарезки, вот один из обсуждения в списке рассылки

7
ответ дан 30 November 2019 в 22:31
поделиться

В нашем проекте мы выполняем статический анализ исходного кода путем преобразования байт-кода LLVM в код C с помощью программы llc , которая поставляется с LLVM. Затем мы анализируем код C с помощью CIL (C Intermediate Language) , но для языка C доступно множество инструментов. Ошибка в том, что код, сгенерированный llc , имеет вид AWFUL и страдает большой потерей точности. Но все же это один путь.

Edit: на самом деле, я бы никому не рекомендовал отказываться от этого. Но все же, для записи ...

4
ответ дан 30 November 2019 в 22:31
поделиться

Набор DMS Software Reengineering Toolkit предоставляет различные типы управления, потока данных и анализаторов глобальных точек для больших систем кода C и строит графы вызовов, используя эти глобальные точки. -на анализ (с соответствующими консервативными допущениями). Более подробное обсуждение и примеры анализов можно найти на веб-сайте.

DMS был протестирован на монолитных системах кода C с 25 миллионами строк. (В графе вызовов этого монстра было 250 000 функций).

Разработка всего этого механизма из базовых AST C и таблиц символов - это огромная работа; был там, сделал это. Вы не захотите делать это сами, если у вас есть что-то еще, связанное с вашей жизнью, например, реализация других приложений.

1
ответ дан 30 November 2019 в 22:31
поделиться