4

C++ で記述された Windows 8 メトロ アプリを ARM にコンパイルしようとしています。リンク中に、次のエラーの多くのインスタンスが表示されます。

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

MSDN サイトには、「この問題は、複数のイメージを作成するか、/ORDER オプションを使用して命令とターゲットを近づけることで解決できます」と記載されています。

しかし、私はそれを機能させる方法が本当にわかりません。問題のシンボルはコンパイラによって生成されたものであり、Itanium アーキテクチャが関与していないため、そのページの他の提案は適用されません。また、エラーのあるファイルは、プロジェクトに含まれる xaml ページからコンパイラによって生成された *.g.cpp ファイルです。

メトロ アプリケーションは 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 では発生しません。これらの命令セットには、プロセスのアドレス空間内の任意のアドレスに分岐できるジャンプ/呼び出し命令があるためです。

これに対する唯一の修正は、最終的な実行可能イメージで呼び出し元と呼び出し先を近づけることです。これを行う 1 つの方法は、ソース ファイル内でコードを移動することです。これは、通常、コンパイラとリンカは、関数がソースで宣言されているのと同じ順序で (1 つの変換単位内で) 関数コードを実行可能ファイルに配置するためです。最適化によってその順序が変更されることがよくありますが、ほとんどの場合、ほぼ正しいです。

あなたが提供したリンクに記載されている別のオプションは、リンカーの/ORDERコマンドラインオプションを使用して機能を手動で移動することです。オーダー ファイルを作成し、この問題が発生している関数をまとめます。自動生成されたコードを扱っているように聞こえるので、再生成されるたびにコードを編集する必要がないため、これがおそらく最良のオプションです。

バグ レポートをconnect.microsoft.comに投稿することもできます。これは、デフォルトのツールセットでは、この奇妙なエラー (ARM 命令セットの制限による非常に現実的なエラー) への対処を強制するべきではないためです。コンパイラのせいではありません)。

于 2012-07-13T21:00:02.623 に答える