静态编译的EXE重定位项不能多于65535个

去年(2014年)9月份,我收到来自网友的错误报告,说易语言代码行数超过4万,静态编译的EXE启动时异常崩溃。他那个源码是在一个子程序里面写了4万多行代码,每一行都调用Win32 API函数MessageBoxA。

我(Liigo)当时仔细检查了易语言5.x静态编译相关的源代码,分析后得出初步结论:整个易程序就一个代码段(.text),编译成OBJ也位于一个Section内,而其中最多只能有65535个重定位项(WORD NumberOfRelocations)。如果代码过多,重定位数目过多(程序内的函数、变量、常量都可能需要重定位项),这个WORD值(16bits无符号整数)很可能会溢出,导致EXE重定位不正常,进而导致指针访问越界并且崩溃。详见MSDN上对结构体IMAGE_SECTION_HEADER 的定义。

如果需要修改的话,可能需要在易语言静态编译时,拆分成多个代码段,静态链接也要更新做相应的处理。但是这样也仍然不能解决本质问题:如果程序员执意要在同一个函数/子程序里写几万行代码,导致生成过多的重定位项,编译链接系统也是没有办法的,总不能把这个函数定义切分放到不同的Section去吧?

所以这个问题根本就是无解。归根揭底是C/C++编译链接系统COFF格式OBJ文件结构设计不合理。不止易语言程序,它们Visaul Studio编译出来的C/C++程序同样也会受到该问题的困扰。要解决,只能程序员去解决,把函数/子程序分割,提炼出小的函数/子程序,通过这种方式减少重定位项的数目。但无论如何,易语言把整个程序放进同一个Section内,是一种取巧,并且让问题更容易暴露出来:C/C++程序是每个函数不能重定位项超量,易语言程序是整个程序不能重定位项超量。

我当时也跟吴涛吴总进行过沟通。他基本认可我的分析结果,同时也认为这类情况是一种特例,易语言没有为此更新的必要。

前几天易语言论坛又有人遇到了类似的错误。我联想到之前的情况,写出本文算是一个交待。就是这样,谢谢。


----


续篇:《再议易语言静态编译重定位数目过多》 2018-06-28 by Liigo.


发布了275 篇原创文章 · 获赞 442 · 访问量 244万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章