Когда используется.ARM.exidx
Я работаю над Contiki 2.7 с целью mbxxx. При создании моего кода компоновщик жаловался на перекрытие разделов.ARM.exidx и.data. После некоторой работы со скриптом компоновщика contiki-2.7/cpu/stm32w108/gnu-stm32w108.ld я исправил проблему, заменив:
__exidx_start = .;
__exidx_end = .;
с:
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} >ROM_region
Позже, когда я попытался просмотреть список заголовков некоторых других примеров приложений с помощью objdump -h, я не нашел этот конкретный раздел.ARM.exidx, хотя он присутствует в моем приложении. Поиск в Google.ARM.exidx привел меня к тому факту, что он используется для обработки некоторых исключений в C++. Поскольку мой код является чистым кодом C, почему этот раздел присутствует в моем коде? Когда, как правило,.ARM.exidx присутствует в коде и в чем его полезность?
================================================== ================================
Ну нет, у меня нет таких опций компилятора. Я на самом деле использую API AxTLS, вырвал код обработки сертификата и портировал его на contiki. При дальнейшем копании я обнаружил подозрительное поведение в реализации bigint. Чтобы быть кратким... вот тело функции из файла bigint.c:
static bigint *bi_int_multiply(BI_CTX *ctx, bigint *bia, comp b)
{
int j = 0, n = bia->size;
bigint *biR = alloc(ctx, n + 1);
comp carry = 5;
comp *r = biR->comps;
comp *a = bia->comps;
check(bia);
/* clear things to start with */
memset(r, 0, ((n+1)*COMP_BYTE_SIZE));
do
{
long_comp tmp = *r + (long_comp)a[j]*b + carry;
// *r++ = (comp)tmp; /* downsize */
carry = (comp)(tmp >> COMP_BIT_SIZE);
} while (++j < n);
// *r = carry;
bi_free(ctx, bia);
return trim(biR);
}
если закомментированные части (присвоение переменной r) не закомментированы, появляется вещь.ARM.exidx, в противном случае это не так! Теперь это можно объяснить???
================================================== ================================
Я не нашел ничего необычного в реализации alloc()
, Было 2 упоминания alloca()
используется в какой-то отдельной области кода, который я заменил malloc()
а также free()
, но это тоже не решило проблему. alloc()
реализация имеет только призывы к malloc()
,realloc()
а также free()
2 ответа
.ARM.exidx
это раздел, содержащий информацию для разматывания стека. Если в вашей C-программе есть функции, которые выводят обратный след стека, функции, скорее всего, будут зависеть от наличия этого раздела.
Может быть, искать -funwind-tables
или же -fexceptions
пометьте в настройках вашего компилятора.
Эта функция используется в 'C'. ARM APCS использует только указатель кадра для восстановления стека. Более новый AAPCS иногда использует таблицы. Размотка стека, обработчики сигналов и другие асинхронные функции C используют этот механизм. В случае встроенного устройства без покрытия его можно использовать для трассировки стека. Например, в Linux unwind.c используются обаexidx
а также extab
разделы для трассировки стека.
Вкратце exidx
представляет собой отсортированную таблицу стандартных начальных адресов и extab
указатель таблицы. Бинарный поиск поexidx
найдет соответствующий extab
вход. Вextab
запись содержит подробную информацию о стеке в этой подпрограммеПримечание1. Он дает подробную информацию о том, что процедура хранит в стеке.
если закомментированные части (присвоение переменной r) раскомментированы, появится.ARM.exidx, в противном случае - нет! Теперь это можно объяснить???
Когда у вас есть заявление *r++ = (comp)tmp;
, компилятор не может хранить все переменные в регистрах и должен использовать стек (или, по крайней мере, fp
). Это заставляет его излучать иexidx
а также extab
данные.
Есть несколько решений. Это нормально отказаться от обоихexidx
а также extab
если вам не нужна трассировка стека или асинхронная функциональность. Более простая раскрутка стека может быть выполнена с помощью gnu tools / gcc, используя-mapcs-frame
; тогдаfp
всегда будет использоваться для хранения предыдущего кадра стека (в котором хранятся его вызывающие fp
, так далее). Фактические столы не такие уж большие, а процедуры раскрутки довольно просты. Это может быть <3% накладных расходов, чтобы иметь таблицы, которые не загрязняют нормальный путь к программе или не используют регистр, например-mapcs-frame
. Желательно для процессора Cortex-A с кешем и обычно большим объемом памяти.
Ссылка: Объяснение указателя ссылки и кадра ATPCS
Примечание 1: это происходит после того, как пролог вносит изменения в стек.
Примечание 2:ex
предназначен для исключения, но не только для исключений C++.
Добавляя к ответу tangrs, если вы используете gcc -v, вы можете сбросить параметры по умолчанию, используемые во время компиляции.
Все опции (неявные и явные) опции GCC передаются в программу cc1 GCC.