问题 什么时候使用.ARM.exidx


我正在使用mbxxx目标处理Contiki 2.7。在构建我的代码时,链接器抱怨了 .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部分,而它存在于我的应用程序中。谷歌搜索.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);
}

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

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

我没有发现在执行中使用的任何与众不同的东西 alloc()。有2个引用 alloca() 在代码的某个单独区域中使用,我替换为 malloc() 和 free(),但这也没有解决问题。 alloc() 实现只有调用 malloc()realloc() 和 free()


6902
2018-02-03 12:17


起源

您好@ user2668988!就像抬头一样,如果你想为你的问题添加更多细节,你可以 编辑 你的问题在这里。 - Chris Forrence
是 biR 运用 alloca() 或者怎么样 alloc() 实施?编译器可以使用相同的C ++机制进行跟踪 alloca() 类型分配。当你评论出来 r,优化, alloc() 不会发生。 - artless noise
我没有发现在执行中使用的任何与众不同的东西 alloc()。有2个引用 alloca() 在代码的某个单独区域中使用,我替换为 malloc() 和 free(),但这也没有解决问题。 alloc() 实现只有调用 malloc(),realloc() 和 free() - user2668988


答案:


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

也许找一个 -funwind-tables 要么 -fexceptions 在您的编译器选项中标记。


10
2018-02-03 12:45



我相信 -funwind-tables 默认情况下,选项处于启用状态,至少在近年来的CodeSourcery工具链中是这样。没有它,调试器中的反向跟踪非常困难。 - ams
如何禁用此选项呢? - user2668988
找到标志并将其删除? - tangrs
你不能“删除”隐式标志,但有时可以添加cointer标志(如 -fno-unwind-tables) - kwesolowski


添加tangrs的响应,如果你使用gcc -v,你可以转储编译期间使用的默认选项。

GCC的所有选项(隐式和显式)选项都传递给GCC的cc1程序。


2
2018-01-27 09:48