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