什么时候使用.ARM.exidx

use*_*988 11 arm stm32 linker-scripts codesourcery contiki

我正在使用mbxxx目标处理Contiki 2.7.在构建我的代码时,链接器抱怨.ARM.exidx和.data部分重叠.在使用链接器脚本contiki-2.7/cpu/stm32w108/gnu-stm32w108.ld进行了一些修补之后,我通过替换修复了问题:

__exidx_start = .;
__exidx_end = .;
Run Code Online (Sandbox Code Playgroud)

有:

.ARM.exidx : {
    __exidx_start = .;
    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    __exidx_end = .;
} >ROM_region
Run Code Online (Sandbox Code Playgroud)

后来当我试图通过使用objdump -h看到其他一些示例应用程序的标题列表时,我没有找到这个特定的.ARM.exidx部分,而它存在于我的应用程序中.谷歌搜索.ARM.exidx让我知道它用于一些c ++异常处理.由于我的代码是纯C代码,为什么这部分出现在我的代码中?通常.ARM.exidx存在于代码中,它的实用性是什么?

================================================== ================================

嗯不,我没有任何这样的编译器选项.我实际上正在使用AxTLS api并撕掉证书处理代码并将其移植到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);
}
Run Code Online (Sandbox Code Playgroud)

如果注释掉的部分(r变量赋值)被取消注释,则会出现.ARM.exidx,否则它不会!现在可以解释一下???

================================================== ================================

我没有发现在执行中使用的任何与众不同的东西alloc().有2个引用alloca()在代码中,我与取代的一些独立的区域使用malloc()free(),但它还是不解决问题.alloc()实现只调用malloc(),realloc()free()

tan*_*grs 16

.ARM.exidx是包含展开堆栈信息的部分.如果您的C程序具有打印堆栈回溯的功能,则这些功能可能取决于此部分是否存在.

也许在编译器选项中查找-funwind-tables-fexceptions标记.


art*_*ise 7

这个特性用在\'C\'中。ARM APCS 仅使用帧指针来恢复堆栈。较新的 AAPCS 有时会使用表格。堆栈展开、信号处理程序和其他异步“C”功能都使用这些机制。对于裸机嵌入式设备,它可用于跟踪堆栈。例如,Linux 的unwind.c同时使用exidxextab部分来进行堆栈跟踪。

\n

简而言之,这exidx是一个例程起始地址和extab表索引的排序表。通过二分查找exidx将找到相应的extab条目。该条目包含有关此例程中extab堆栈的详细信息Note1。它提供了有关例程在堆栈上存储的内容的详细信息。

\n
\n

如果注释掉的部分(r 变量赋值)未注释,则 .ARM.exidx 会出现,否则不会出现!现在可以解释一下了吗???

\n
\n

当您有该语句时*r++ = (comp)tmp;,编译器无法将所有变量保存在寄存器中,并且需要使用堆栈(或至少fp)。这会导致它发出 和exidxextab数据。

\n
\n

有一些解决方案。如果您不需要堆栈跟踪或异步功能,则可以丢弃两者exidxextab可以使用 gnu 工具/gcc 来完成更简单的堆栈展开-mapcs-frame;thenfp将始终用于存储前一个堆栈帧(其中存储其调用者fp等)。实际的桌子并没有那么大,放松的例程也相当简单。拥有不污染正常程序路径或使用像-mapcs-frame. 适用于具有高速缓存和通常更多内存的 Cortex-A cpu。

\n

参考:ATPCS链接和帧指针解释
\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0 \xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0 ARM extab 的结构

\n

注1:这是序言对堆栈进行调整之后的情况。
\n注2:ex针对异常,但不仅仅针对C++ 异常。

\n