1

フラグが設定されていないMach-O オブジェクト ファイルを生成する最も簡単な方法は何ですか?SUBSECTIONS_VIA_SYMBOLSリンカ ( を使用-dead_strip) が後でテキスト セクションを切り分けて、どの部分が使用されているかを推測しようとしないようにするにはどうすればよいでしょうか?

llvm/gcc (4.2.1) へのコマンド ライン オプションを使用.subsections_via_symbolsして最初に発行されないようにするか、既存のオブジェクト ファイルからフラグを削除するコマンド ライン ツールを使用できます。

(Mach-O 仕様に基づいてそのようなツールを自分で作成することはオプションですが、可能であれば、車輪をそれほど難しく再発明したくありません)。

プラットフォーム: iOS、XCode 4.5 を使用した OSX からのクロスコンパイル。


背景:私たちは、他社がアプリに組み込む静的ライブラリを提供しています。私たちのライブラリで問題が発生すると、スタック トレースとその他の特定の重要な情報を含むクラッシュ レポートが生成されます (運が良ければ) 後で分析できます。通常、デプロイされたアプリはデバッグ情報が取り除かれているため、スタック トレースの解釈が問題になります。アプリを自分で作成する場合は、ストリッピング前の DWARF デバッグ データを保存し、それを使用して着信クラッシュ レポートのアドレスをデコードします。しかし、アプリ メーカーがリンク手順からそのようなデータを提供してくれることに頼ることはできません。

代わりに、選択した関数の実行時アドレスをクラッシュ レポートに含めるようにしています。そこから、リンカー マップ内のアドレスとクラッシュ レポート内のアドレスの間のオフセットを推測できます。.a; に詰め込む前に、ライブラリ全体を 1 つの .o に段階的にリンクしています。大きなことは 1 つしかないため、アプリが最終的にリンクされたときに、未使用の機能を削除しても節約できることはあまりありません。残念ながら、ライブラリには使用されない小さなコードがいくつかあります (メイン機能の代替 API エントリ ポイント、エラー コードを解釈するための小さなヘルパー関数など)。-dead_strip、最終的なアプリの相対オフセットがインクリメンタルリンク操作のリンカーマップと異なるというクラッシュレポートのアドレス再構築を妨げます。

すべてのアプリ開発者に、ビルド プロセスでデッド コード ストリッピングを無効にするように求めることは現実的には不可能です。そのため、.o を「デッド ストリッピング不可」としてマークし、最終的なアプリ リンクでそれを尊重することができれば、より良い方法と思われます。

4

1 に答える 1

1

私はそれを解決しました。

インクリメンタル リンク操作の出力には、すべての入力オブジェクトに MH_SUBSECTIONS_VIA_SYMBOLS が設定されている場合にのみ MH_SUBSECTIONS_VIA_SYMBOLS が設定されます。また、アセンブラー入力から生成されたオブジェクト ファイルには、明示的なディレクティブ セットがある場合にのみ、それが設定されます。したがって、空のアセンブラー入力とリンクすることでフラグを削除できます。

echo > empty.s
$(CC) $(CFLAGS) input.o empty.s -nostdlib -Wl,r -o output.o
于 2012-10-22T12:18:06.207 に答える