Реализация обработки исключений LLVM

Просто чтобы отметить, я прочитал questions и прочитал сообщения в блоге, и я также ссылался на ABI.

Я полностью не понимаю, как это взаимодействует с LLVM EH intrinsics. Страница LLVM EH дает очень смутный обзор - не совсем контрольный список "Реализация X, Y, Z".

Страница LLVM EH ссылается на Itanium ABI напрямую. Это означало бы, что LLVM поддерживает только исключения Itanium ABI. Но я уже знаю, что Clang поддерживает ARM и развивает поддержку Microsoft ABI. Так точно, насколько конкретна реализация LLVM EH для Itanium ABI?

Когда вы ссылаетесь на материал _Unwind, определенный Itanium ABI, это обязано быть предоставлено бэкэндом или я должен реализовать его для себя?

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

Короче говоря, как именно вы переходите из LSDA, EH-контекстов и от _Unwind_RaiseException до landingpad и resume?

Изменить: просто для справки, я собираюсь выполнить JIT-код в Windows.

Ответы

Ответ 1

Короткий ответ: LLVM эффективно поддерживает жесткие коды для каждого EH ABI, который он хочет поддерживать: ARM, Itanium, SEH и т.д. Таким образом, в то время как материал landingpad теоретически может быть несколько абстрактным, он действительно не абстрактный вообще очень тесно связаны, потому что другая половина материала, который вам нужно сделать, должна выполняться библиотекой поддержки Itanium ABI EH, которую вам нужно сделать явно.

LLVM генерирует практически все детали реализации EH, но вы также должны ссылаться на библиотеку поддержки Itanium EH во время выполнения. Помимо этого, IR действительно является тем, что он показывает, - никаких дополнительных усилий, требуемых от имени программиста.

Я предполагаю, что все становится более липким, если вы хотите использовать не-Itanium.

Ответ 2

В настоящее время Itanium С++ ABI является стандартным стандартом С++ ABI, используемым на многих других платформ. Itanium С++ ABI поддерживает технологию обработки исключений с нулевой стоимостью, который является наиболее распространенным методом на сегодняшний день.

Для поддержки обработки исключений необходимо изменить семантику функции вызов. Теперь вызовы вызывают поток выполнения. Одна ветвь берется, когда все нормально, а вторая ветвь берется в случае исключения. В LLVM IR есть команда invoke для вызова функций, которые могут вызывать.

При выполнении второй ветки может выполняться несколько видов действий:

  • деструкторы вызовов (очистка)
  • продолжить раскрутку стека (возобновить)
  • применять спецификации броска (фильтр)
  • восстановить нормальный поток управления (catch).

Понятно, что для выполнения этих действий необходимо создать дополнительный код. Вот почему у нас есть инструкция landingpad. Это первый команда, которая должна быть выполнена после invoke, заканчивается исключением.

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

Как вы, наверное, знаете, все эти данные (индивидуальная процедура, уловленные типы, спецификация броска, действия по очистке) уже указаны в landingpad инструкции, поэтому никакие дополнительные данные не должны передаваться на сервер для генерации разделы, связанные с исключением в объектном файле.