4

我有一个用 c++ 编写的 Windows 8 Metro 应用程序,我正在尝试编译到 ARM。在链接期间,我收到以下错误的许多实例:

"error LNK2013: BLX23(T) fixup overflow.  Target '<mangledName>' is out of range"

MSDN 网站说:“您可以通过创建多个图像或使用 /ORDER 选项来解决此问题,以便指令和目标更接近。”

但我真的不明白如何使它工作。有问题的符号是编译器生成的,不涉及安腾架构,因此该页面上的其他建议不适用。此外,有错误的文件是 *.g.cpp 文件,由编译器从项目中包含的 xaml 页面生成。

Metro 应用程序在 Win32 配置上运行得很好,所以我想知道是否有更多 ARM 经验的人可以更好地了解如何解决此类问题。

设置是 Windows 8 RP x64 上的 Visual Studio 2012 RC。

4

2 回答 2

8

这是由于 ARM 上的增量链接中的一个不幸错误,可以通过禁用增量链接来解决。正如另一个答案中提到的,这是因为被调用函数和调用站点彼此相距太远,以至于链接器需要插入长分支岛(并且在使用增量链接时创建长分支岛存在一个非常特殊的错误) .

据我所知,这个错误并没有针对 RTM 修复(当我自己发现这个问题时,修复 RTM 版本为时已晚),但它是已知的并计划在未来的版本中修复。

于 2012-08-02T16:48:48.500 回答
2

关键问题是 ARM 指令集仅支持编译器试图用来生成函数调用的指令的相对位移,并且这些位移中的位数有限。在您的情况下,您的代码太多,以至于被调用函数和调用站点在地址空间中相距甚远,以至于位移中没有足够的位供编译器生成正确的调用指令。

这可能发生在 ARM 和 IA64 (Itanium) 上,但不会发生在 x86 和 x86-64 中,因为这些指令集具有跳转/调用指令,可以分支到进程地址空间中的任何可能地址。

解决此问题的唯一方法是在最终的可执行映像中将调用者和被调用者靠得更近。这样做的一种方法是在源文件中移动代码,因为通常编译器和链接器将函数代码放入可执行文件中的顺序与在源文件中声明函数的顺序相同(在一个翻译单元内)。优化通常会改变该顺序,但在大多数情况下,它几乎是正确的。

如您提供的链接中所述,另一个选项是使用链接器的/ORDER命令行选项手动移动函数。创建一个订单文件,并将出现此问题的函数放在一起,假设它们没有太多。由于听起来您正在处理自动生成的代码,这可能是最好的选择,因为您不希望每次重新生成代码时都必须对其进行编辑。

您可能还想向connect.microsoft.com发布错误报告,因为默认工具集确实不应该强迫您处理这个相当奇怪的错误(由于 ARM 指令集的限制,这是一个非常真实的错误 -这不是编译器的错)。

于 2012-07-13T21:00:02.623 回答