何时使用is.ARM.exidx

何时使用is.ARM.exidx,arm,stm32,linker-scripts,contiki,codesourcery,Arm,Stm32,Linker Scripts,Contiki,Codesourcery,我正在使用mbxxx目标开发Contiki 2.7。在构建代码时,链接器抱怨.ARM.exidx和.data部分重叠。在修改链接器脚本contiki-2.7/cpu/stm32w108/gnu-stm32w108.ld后,我通过替换以下内容修复了问题: __exidx_start = .; __exidx_end = .; 与: 后来,当我试图使用objdump-h查看一些其他示例应用程序的标题列表时,我没有找到这个特定的.ARM.exidx部分,而它存在于我的应用程序中。ARM.exidx让

我正在使用mbxxx目标开发Contiki 2.7。在构建代码时,链接器抱怨.ARM.exidx和.data部分重叠。在修改链接器脚本contiki-2.7/cpu/stm32w108/gnu-stm32w108.ld后,我通过替换以下内容修复了问题:

__exidx_start = .;
__exidx_end = .;
与:

后来,当我试图使用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);
}
静态bigint*bi\u int\u乘法(bi\u CTX*CTX,bigint*bia,comp b)
{
int j=0,n=bia->size;
bigint*biR=alloc(ctx,n+1);
复合进位=5;
comp*r=biR->comps;
comp*a=bia->comps;
检查(bia);
/*先把事情弄清楚*/
memset(r,0,((n+1)*复合字节大小);
做
{
long_comp tmp=*r+(long_comp)a[j]*b+进位;
//*r++=(comp)tmp;/*缩小规模*/
进位=(补偿)(tmp>>补偿位大小);
}而(++j
如果注释掉的部分(r变量赋值)未注释,则会显示.ARM.exidx thingy,否则不会显示!现在可以解释一下吗

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


alloc()
的实现中,我没有发现任何异常情况。在代码的某个单独区域中使用了两个
alloca()
的引用,我将其替换为
malloc()
free()
,但这也不能解决问题
alloc()
实现只调用
malloc()
realloc()
free()
。ARM.exidx
是包含展开堆栈信息的部分。如果您的C程序具有打印堆栈回溯的函数,则这些函数可能取决于本节的存在


可能在编译器选项中查找
-funwind tables
-feexceptions
标志。

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


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

此功能用于“C”。ARM APCS仅使用帧指针来恢复堆栈。较新的AAPC有时会使用表格。堆栈展开、信号处理程序和其他异步“C”特性使用这些机制。对于裸机嵌入式设备,它可以用来跟踪堆栈。例如,Linux使用
exidx
extab
部分来进行堆栈跟踪

简而言之,
exidx
是例行程序开始地址的排序表和
extab
表索引。通过
exidx
进行二进制搜索将找到相应的
extab
条目。
extab
条目包含此例程中堆栈的详细信息Note1。它给出了例程在堆栈上存储的内容的详细信息

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

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



有一些解决办法。如果不需要堆栈跟踪或异步功能,可以同时放弃
exidx
extab
。使用gnu工具/gcc,使用
-mapcs frame
,可以实现更简单的堆栈展开;然后,
fp
将始终用于存储上一个堆栈帧(它存储其调用者
fp
等)。实际的表并没有那么大,要展开的例程也相当简单。它可能是Hello@user2668988!作为提示,如果你想为你的问题添加更多细节,你可以在这里提问。
biR
是使用
alloca()
还是如何实现
alloc()
?编译器可以使用相同的C++机制来跟踪<代码> ALOLCAR()/<代码>类型分配。当您注释掉
r
时,通过优化,
alloc()
将不会发生。我在
alloc()
的实现中没有发现任何异常情况。在代码的某个单独区域中使用了两个
alloca()
的引用,我将其替换为
malloc()
free()
,但这也不能解决问题
alloc()
实现只调用了
malloc()
realloc()
free()
我相信
-funwind tables
选项在默认情况下是打开的,至少在最近几年的CodeSourcery工具链中是这样。没有它,调试器中的回溯跟踪相当困难。那么如何禁用此选项?找到标志并将其删除?您不能“删除”隐式标志,但有时可以添加cointer标志(如
-fno unwind tables
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);
}