一种检测运行栈与静态数据区重叠的方法

文档序号:6638320阅读:136来源:国知局
专利名称:一种检测运行栈与静态数据区重叠的方法
技术领域
本发明涉及嵌入式系统中程序运行时错误的检测,特别涉及一种检测运行栈与静态数据区重叠的方法。
背景技术
由于价格和应用的原因,嵌入式系统中的指令内存和数据内存都比较小,所以在执行程序时,在数据内存中就可能出现不同类型数据(如静态数据区、堆和运行栈)重叠的情况。静态数据区(static data sections)包括ELF可执行文件中的各个数据区。这些数据区的加载地址通常是在链接脚本(linker script)中指定的。在简单的嵌入式系统中,运行程序只是把ELF可执行文件中的指令和数据部分加载进来,丢弃了存放ELF文件中各个区大小信息的区头表(Section Header Table)。然而这种简单的嵌入式系统大多不支持动态分配内存空间,所以在数据内存中就不会出现堆。程序执行时运行栈从数据内存顶部向下增长,很可能出现与数据内存底部的静态数据区重叠的运行错误。在图1、图2中,箭头表示运行栈的增长方向,其中图1中还未发生运行栈与静态数据区重叠的运行错误,图2中已发生运行栈与静态数据区重叠的运行错误。
在嵌入式工具链开发过程中,测试是一个重要的阶段。通常测试并不是直接在硬件上运行,而是首先编写嵌入式系统的软件模拟器,只有在模拟器上测试通过后才能进行最终的硬件测试。
在简单的嵌入式系统软件模拟器中,由于缺少静态数据区大小信息,导致在程序执行时无法检测运行栈与静态数据区重叠的运行时错误。而寻找该错误的原因比较麻烦,因此需要有方法来方便快捷地检测这种运行时错误。
已知的方法有多种,最简单的解决方法就是在编译时静态得到每个函数对应栈帧的大小。一个函数的栈帧大小是固定的,在函数序言(Function Prologue)的生成处就能得到具体数值。但这种方法只能在当栈帧很大时警告程序员发生运行栈和静态数据区的概率比较高,并不能动态反映运行栈的变化情况,因此该种方法准确性不好。如果一个函数递归调用层次过多,即使该函数栈帧本身并不大,也很有可能出现运行栈和数据区重叠的情况。
另一种常见的方法是在软件模拟器中添加一种新的指令,该指令能显示实时的栈指针值。在函数的生成代码中,运行栈的增长是在序言处进行的。如果在序言处运行栈增长后加入这种新的指令,就可以得到当前的栈指针值。测试人员将该值与ELF文件中静态数据区的末尾比较,就可以判断是否出现运行栈和数据区重叠的情况。该方法虽然比前一种方法准确了许多,但还是有比较大的缺点缺点一,需要测试人员来进行比较,而且还要求测试人员知晓静态数据区的大小,所以该方法易用性不好;缺点二,添加指令需要占用指令内存,对指令内存压力较大的程序不适合;缺点三,嵌入式CPU的指令集中实际上并不支持这种新指令,技术人员只能是在软件模拟器中支持,此时生成的可执行文件不能在实际的硬件环境下运行。
因此就需要一种检测运行栈与静态数据区重叠的改进方法,该方法不再需要测试人员来进行比较,不要求测试人员知道静态数据区的大小;该方法可以适合对指令内存压力较大的程序;该方法生成的可执行文件可以在实际的硬件环境下运行。

发明内容
本发明的目的是克服现有技术的不足,提供一种改进的检测运行栈与静态数据区重叠的方法。
为了达到上述目的,本发明采取如下技术方案一种检测运行栈与静态数据区重叠的方法,该方法在链接器中对运行栈和静态数据区在数据内存中的布局进行调整,调整后的结果如图3所示,然后在软件模拟器中进行运行时检测,具体步骤包括1、在链接器统计出静态数据区中各个区的大小后为每个区分配一个新的加载地址并计算出新的栈指针初始值;2、在链接器中计算出新的栈指针初始值并写入到可执行文件中对栈指针初始化定值的指令处;3、在链接器中修改被调整的各个区中重定位条目的地址计算公式,加上所在区加载地址的变化量;
4、在软件模拟器中添加判断栈指针值与数据内存最低地址大小关系的代码;如果栈指针值小于数据内存最低地址,就说明发生了运行栈下溢,在原程序中出现运行栈与静态数据区重叠的错误,发送错误报告。
本发明在链接器中对运行栈和静态数据区在数据内存中的布局进行调整,调整后的结果如图3所示,虽然内存程序映像发生了变化,但并没有改变原程序的语义,也就是说调整后程序的执行结果和原程序一致。运行栈和静态数据区重叠就等价转换成运行栈下溢。模拟器执行时当栈指针值小于数据内存低地址即发生了运行栈下溢,在原来的数据内存布局下执行时就会出现运行栈和静态数据区的重叠,如图2所示。运行栈下溢在软件模拟器中是可以非常方便地被检测发现,具体将在具体实施方式
中详述,使得测试人员不再需要长时间调试程序来发现错误的原因。
与现有技术相比,本发明具有如下优点1)在模拟器中只需要添加判断栈指针值与数据内存基址大小关系的代码,当程序执行中发生运行栈下溢的情况时就可以自动报告错误;2)本发明没有带来内存开销,避免了不能检查指令内存压力较大程序的情况;3)生成的可执行文件可以加载到硬件上运行,增加了硬件环境下验证该问题的功能。


图1简单嵌入式系统中未发生运行栈与静态数据区重叠错误的程序内存映象;图2简单嵌入式系统中已发生运行栈与静态数据区重叠错误的程序内存映象;图3本发明的调整布局后简单嵌入式系统中的程序内存映象。
具体实施例方式
下面结合附图和具体实施方式
对本发明作进一步详细描述本发明建立在如下两个基本原则上一是保证程序语义在调整前后不变;二是尽可能保证运行栈的可增长空间大小在调整前后不变。
一种检测运行栈与静态数据区重叠的方法,包括如下具体步骤1、在链接器统计出静态数据区中各个区的大小后为每个区分配一个新的加载地址并计算出新的栈指针初始值;该步骤还包括如下子步骤
步骤1.1得到要调整的各个区的原加载地址和大小;步骤1.2从数据内存空间的最高地址开始由高往低为每个区分配新的加载地址。
步骤1.3计算每个区加载地址的变化量。
2、在链接器中计算出新的栈指针初始值并写入到可执行文件中对栈指针初始化定值的指令处;该步骤还包括如下子步骤步骤2.1根据步骤1.2中计算出的静态数据区中地址最低的区的加载地址,把数据内存中紧靠静态数据区的最高地址作为新的栈指针值;步骤2.2得到初始化栈指针指令在生成的可执行文件中的位置;步骤2.3把新的栈指针值写到可执行文件的目标位置上。
3、在链接器中修改被调整的各个区中重定位条目的地址计算公式,加上所在区加载地址的变化量;该步骤还包括如下子步骤步骤3.1判别重定位条目的目标位置所在的区;步骤3.2得到步骤1.3中已经计算好的重定位条目的目标位置所在区的加载地址变化量;步骤3.3把得到的区加载地址变化量和原来重定位条目中的参与地址计算的偏移量相加,结果就是调整后对应的参与地址计算的偏移量。调整后的结果如图3所示。
4、在软件模拟器中添加判断栈指针值与数据内存最低地址大小关系的代码;该步骤还包括如下子步骤步骤4.1定义一个全局变量,赋值为数据内存的最低地址。
步骤4.2在执行运行栈扩展的指令时栈指针减小,在此处添加栈指针与步骤4.1中定义的全局量比较大小的代码,当栈指针值小于该全局量时发生运行栈下溢,对应原程序中发生运行栈与静态数据区重叠的错误,发送错误报告。
权利要求
1.一种检测运行栈与静态数据区重叠的方法,该方法在链接器中对运行栈和静态数据区在数据内存中的布局进行调整,然后在软件模拟器中进行运行时检测,具体步骤包括1)在链接器统计出静态数据区中各个区的大小后为每个区分配一个新的加载地址并计算出新的栈指针初始值;2)在链接器中计算出新的栈指针初始值并写入到可执行文件中对栈指针初始化定值的指令处;3)在链接器中修改被调整的各个区中重定位条目的地址计算公式,加上所在区加载地址的变化量;4)在软件模拟器中添加判断栈指针值与数据内存最低地址大小关系的代码;如果栈指针值小于数据内存最低地址,就说明发生了运行栈下溢,在原程序中出现运行栈与静态数据区重叠的错误,发送错误报告。
2.根据权利要求1所述的检测运行栈与静态数据区重叠的方法,其特征在于,所述步骤1)包括以下子步骤步骤1.1得到要调整的各个区的原加载地址和大小;步骤1.2从数据内存空间的最高地址开始由高往低为每个区分配新的加载地址;步骤1.3计算每个区加载地址的变化量。
3.根据权利要求2所述的检测运行栈与静态数据区重叠的方法,其特征在于,所述步骤2)包括以下子步骤步骤2.1根据步骤1.2中计算出的静态数据区中地址最低的区的加载地址,把数据内存中紧靠静态数据区的最高地址作为新的栈指针值;步骤2.2得到初始化栈指针指令在生成的可执行文件中的位置;步骤2.3把新的栈指针值写到可执行文件的目标位置上。
4.根据权利要求2所述的检测运行栈与静态数据区重叠的方法,其特征在于,所述步骤3)包括如下子步骤步骤3.1判别重定位条目的目标位置所在的区;步骤3.2得到步骤1.3中已经计算好的重定位条目的目标位置所在区的加载地址变化量;步骤3.3把得到的区加载地址变化量和原来重定位条目中的参与地址计算的偏移量相加,结果就是调整后对应的参与地址计算的偏移量。
5.根据权利要求1所述的检测运行栈与静态数据区重叠的方法,其特征在于,所述步骤1)包括以下子步骤步骤1.1得到要调整的各个区的原加载地址和大小;步骤1.2从数据内存空间的最高地址开始由高往低为每个区分配新的加载地址;步骤1.3计算每个区加载地址的变化量;所述步骤2)包括以下子步骤步骤2.1根据步骤1.2中计算出的静态数据区中地址最低的区的加载地址,把数据内存中紧靠静态数据区的最高地址作为新的栈指针值;步骤2.2得到初始化栈指针指令在生成的可执行文件中的位置;步骤2.3把新的栈指针值写到可执行文件的目标位置上;所述步骤3)包括如下子步骤步骤3.1判别重定位条目的目标位置所在的区;步骤3.2得到步骤1.3中已经计算好的重定位条目的目标位置所在区的加载地址变化量;步骤3.3把得到的区加载地址变化量和原来重定位条目中的参与地址计算的偏移量相加,结果就是调整后对应的参与地址计算的偏移量。
6.根据权利要求1或5所述的检测运行栈与静态数据区重叠的方法,其特征在于,所述步骤4)包括如下子步骤步骤4.1定义一个全局变量,赋值为数据内存的最低地址;步骤4.2在执行运行栈扩展的指令时栈指针减小,在此处添加栈指针与步骤4.1中定义的全局量比较大小的代码,当栈指针值小于该全局量时发生运行栈下溢,对应原程序中发生运行栈与静态数据区重叠的错误,发送错误报告。
全文摘要
本发明公开了一种检测运行栈与静态数据区重叠的方法。该方法在链接器中对运行栈和静态数据区在数据内存中的布局进行调整,然后在软件模拟器中进行运行时检测,在软件模拟器中添加判断栈指针值与数据内存最低地址大小关系的代码,如果栈指针值小于数据内存最低地址,就说明发生了运行栈下溢,在原程序中出现运行栈与静态数据区重叠的错误。本发明的优点1)在模拟器中只需要添加判断栈指针值与数据内存基址大小关系的代码,当程序执行中发生运行栈下溢的情况时就可以自动报告错误;2)没有带来内存开销;3)生成的可执行文件可以加载到硬件上运行。
文档编号G06F9/455GK1920792SQ200510093280
公开日2007年2月28日 申请日期2005年8月23日 优先权日2005年8月23日
发明者谷晓铭, 霍玮, 桂剑, 贾耀仓, 张兆庆, 冯晓兵 申请人:中国科学院计算技术研究所
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1