我有一个用c ++编写的Windows 8 metro应用程序,我正在尝试编译到ARM。在链接期间,我收到以下错误的许多实例:
"error LNK2013: BLX23(T) fixup overflow. Target '<mangledName>' is out of range"
MSDN site说: “您可以通过创建多个图像或使用/ ORDER选项来解决此问题,以便指令和目标更加接近。”
但我真的不明白如何做到这一点。有问题的符号是编译器生成的,并且没有涉及Itanium体系结构,因此该页面上的其他建议不适用。此外,有错误的文件是* .g.cpp文件,由编译器从项目中包含的xaml页面生成。
Metro应用程序在Win32配置上运行得很好,所以我想知道在ARM上有更多经验的人是否可以更好地了解如何解决这类问题。
安装程序是Windows 8 RP x64上的Visual Studio 2012 RC。
答案 0 :(得分:8)
这是因为ARM上的增量链接存在一个不幸的错误,可以通过禁用增量链接来解决。正如在另一个答案中所提到的,这是因为被调用的函数和调用点彼此相距太远,以至于链接器需要插入长分支岛(并且在使用增量链接时存在一个非常特殊的错误,即创建长分支岛)
据我所知,这个错误并没有为RTM修复(当我自己发现这个问题时,为RTM版本修复已经太晚了),但它已知并计划在未来版本中修复。
答案 1 :(得分:2)
关键问题是ARM指令集仅支持编译器尝试用于生成函数调用的指令的相对位移,并且这些位移具有有限的位数他们。在你的情况下,你有这么多的代码,被调用的函数和调用站点在地址空间相距太远,以至于位移中没有足够的位来让编译器生成正确的调用指令。
这可能发生在ARM和IA64(Itanium)上,但它不会发生在x86和x86-64中,因为这些指令集具有跳转/调用指令,可以分支到进程的地址空间中的任何可能的地址。
唯一的解决方法是在最终的可执行映像中将调用者和被调用者移动得更近。实现此目的的一种方法是仅在源文件中移动代码,因为通常编译器和链接器将函数代码放入可执行文件中,其顺序与在源中声明函数的顺序相同(在一个转换单元内)。优化通常会改变这种顺序,但在大多数情况下,它几乎都是正确的。
如您提供的链接中所述,另一个选项是使用链接器的/ORDER
命令行选项手动移动函数。创建一个订单文件,并将表现出这个问题的功能放在一起,假设它们不是太多。因为它听起来像是在处理自动生成的代码,所以这可能是最好的选择,因为您不希望每次重新生成时都要编辑代码。
您可能还想将错误报告发布到connect.microsoft.com,因为默认工具集实际上不应该强迫您处理这个相当奇怪的错误(由于ARM指令的限制,这是一个非常真实的错误set - 这不是编译器的错误。)