静态编译的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 的定义。windows

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

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

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

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


----blog


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