3

私は最近、文字列ルーチン (memcpy、memset、および memmove) のいくつかの置換を作成しました。これらのルーチンを含むライブラリがコンパイル/リンク行で指定されている場合、これらは同じ名前のシステム標準ライブラリ ルーチンよりも優先されることを理解しています。すでに間違っている場合は、お知らせください。

これは、私が行ったすべてのテストで正しく機能します (正しいルーチンが存在し、glibc ルーチンが存在しないことを逆アセンブルによって確認しました)。

1)-gを使用して同じライブラリに別のファイルを構築します(-O2を構築していました)

2) このファイルには memset への明示的な呼び出しがあります

3a) コンパイル時のオプションが、この memset が gcc によってインライン化されるように機能する場合、すべて問題ありません

3b) ただし、オプションによって memset 呼び出しのインライン化が無効になり、それがなければインライン化される場合、ライブラリはビルドされますが、ライブラリを使用してアプリケーションを静的にリンクすると、重複シンボル リンカ エラーが発生します。シンボルの他のインスタンスはシステム ライブラリの memset。

基本的に、ライブラリの 2 つのバージョン (数百のソース ファイル) をビルドできます。1 つのディレクトリの make CFLAGS を -O1 -g から -g に変更することで、このライブラリを使用するとリンカー エラーをトリガーできます。

作業バージョンを取得して nm で実行すると、テスト ケースにリンクされているルーチンを含む memset への未定義の参照が多数あることがわかります。したがって、作業ケースで memset を解決しようとする必要があることがわかります。これを壊れたライブラリの nm 出力と比較すると、いくつかの余分な未定義の memcpy および memset 参照が表示されます。memset が最初のケース (私のルーチン) で解決された場合、2 番目のケースで解決されるはずです。

詳細なコンパイラ出力も調べて、この 1 つのライブラリへのパスを除いて、リンク行が両方のケースでまったく同じであることを確認しました。

ここには、非常に不可解なことが 2 つあります (その他の無数の問題の中でも)。

1) -O1 -g で構築されたライブラリ内のファイルが -g とは異なる方法でリンクされるのはなぜですか?

2) ユーザー ライブラリ内の交換 memset がシステム memset と競合するのはなぜですか?

大賞の場合、1) はどのように 2) を引き起こしますか?

4

2 に答える 2