I have a Windows 8 metro app written in c++ that I'm trying to compile to ARM. During linking, I get many instances of the following error:
"error LNK2013: BLX23(T) fixup overflow. Target '<mangledName>' is out of range"
The MSDN site says: "You can resolve this problem by creating multiple images or by using the /ORDER option so the instruction and target are closer together."
But I don't really get it how to make that work. The symbols in question are compiler-generated and there is no Itanium Architecture involved, so the other suggestions on that page don't apply. Also, the files with errors are *.g.cpp files, generated by the compiler from xaml pages included in the project.
The metro application runs just fine on Win32 configuration, so I wonder if someone with more experience on ARM could have a better idea of how to solve this sort of issue.
The setup is Visual Studio 2012 RC on Windows 8 RP x64.
This is due to an unfortunate bug in incremental linking on ARM, and can be worked around by disabling incremental link. As mentioned in the other answer, this is because the called function and callsite are so far away from each other that the linker needs to insert long branch islands (and there is a very particular bug with creation of long branch islands when using incremental link).
To my knowledge, this bug was not fixed for RTM (when I discovered this issue myself it was too late to fix for the RTM release) but it is known and planned to be fixed for a future release.
The key problem is that the ARM instruction set only supports relative displacements for the instructions that the compiler is trying to use to generate the function call, and that those displacements have a limited number of bits in them. In your case, you have so much code that the called function and the call site are so far apart in address space that there aren't enough bits in the displacement for the compiler to generate a correct call instruction.
This can happen on ARM and IA64 (Itanium), but it cannot happen in x86 and x86-64 since those instruction sets have jump/call instructions which can branch to any possible address in the process' address space.
The only fix to this is to move the caller and the callee closer together in the final executable image. One way of doing this is to just move the code around in your source files, since usually the compiler and linker place function code into the executable in the same order in which the functions are declared in source (within one translation unit). Optimizations often alter that order, but for the most part it's approximately true.
Another option, as mentioned in the link you provided, is to use the linker's /ORDER
command line option to move functions around manually. Create an order file, and put together functions which are exhibiting this problem, assuming there's not too many of them. Since it sounds like you're dealing with autogenerated code, this is probably the best option, because you don't want to have to edit the code each time it's regenerated.
You may also want to post a bug report to connect.microsoft.com, since the default toolset really ought not to force you to deal with this rather strange error (which is a very real error due to the limitations the ARM instruction set -- it's not the compiler's fault).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With