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

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

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

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

EDIT:

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

4b9b3361

Ответ 1

Вы должны взглянуть на Elsa. Это относительно легко расширить и позволяет легко анализировать АСТ. Он обрабатывает весь процесс синтаксического анализа, лексинга и генерации АСТ, а затем позволяет вам перемещаться по дереву с помощью шаблона посетителя.

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

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

Ответ 2

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

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

EDIT: если вас интересуют возможные значения указателей функций для нарезки анализируемой программы, вам обязательно нужно взглянуть на существующие зависимости и вычисления среза в Frama-C. На веб-сайте нет хорошего примера для нарезки, здесь один из обсуждения в списке рассылки

Ответ 3

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

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

Ответ 4

Я думаю, что ваш вопрос испорчен. Название гласит: "Статический анализ исходного кода". Тем не менее, ваша основная причина заключается в построении (части) графика вызова, включающего вызовы с помощью указателя функции. Суть указателей функций заключается в том, что вы не можете знать их значения во время компиляции, то есть в точке, где вы выполняете статический анализ исходного кода. Рассмотрим этот бит кода:

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

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

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

Ответ 5

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

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

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