* nixで実行可能ファイルを作成するために使用されたコンパイラとフラグを確認する方法はありますか?古いバージョンのコードをコンパイルしましたが、最適化の有無にかかわらずコンパイルされたかどうかを確認したいと思います。Googleはあまり役に立ちませんでしたが、正しいキーワードを使用しているかどうかはわかりません。
7 に答える
gccにはその-frecord-gcc-switches
ためのオプションがあります:
-frecord-gcc-switches
This switch causes the command line that was used to invoke the compiler to
be recorded into the object file that is being created. This switch is only
implemented on some targets and the exact format of the recording is target
and binary file format dependent, but it usually takes the form of a section
containing ASCII text.
その後、ELF実行可能ファイルには.GCC.command.line
その情報を含むセクションが含まれます。
$ gcc -O2 -frecord-gcc-switches a.c
$ readelf -p .GCC.command.line a.out
String dump of section '.GCC.command.line':
[ 0] a.c
[ 4] -mtune=generic
[ 13] -march=x86-64
[ 21] -O2
[ 25] -frecord-gcc-switches
もちろん、そのオプションなしでコンパイルされた実行可能ファイルでは機能しません。
最適化の単純なケースでは、ファイルがデバッグ情報を使用してコンパイルされている場合は、デバッガーを使用してみることができます。少しステップスルーすると、一部の変数が「最適化」されていることに気付くかもしれません。これは、最適化が行われたことを示しています。
フラグを使用してコンパイルする場合-frecord-gcc-switches
、コマンドラインコンパイラオプションは、メモセクションのバイナリに書き込まれます。ドキュメントも参照してください。
別のオプションは-grecord-gcc-swtichesです(-fではなく-gに注意してください)。gcc docsによると、dwarfデバッグ情報にフラグを設定します。また、gcc4.8以降はデフォルトで有効になっているようです。
私はdwarfdumpプログラムがそれらのcflagsを抽出するのに役立つことを発見しました。文字列プログラムはそれらを認識しないことに注意してください。ドワーフ情報が圧縮されているようです。
これは、コンパイラのサポートが必要になるものです。使用しているコンパイラについては言及していませんが、質問linux
にタグを付けたので、gccを使用していると想定します。これは、要求している機能のデフォルトではありません(ただし、-frecord-gcc-switchesはこれを実行するためのオプションです)。 )。
バイナリを検査する場合、strings
コマンドはファイル内で読み取り可能な文字列のように見えるすべてのものを表示します。
実行可能ファイルがオプション付きのgccによってコンパイルされている限り-g
、次の方法でうまくいくはずです。
readelf --debug-dump=info /path/to/executable | grep "DW_AT_producer"
例えば:
% cat test.c
int main() {
return 42;
}
% gcc -g test.c -o test
% readelf --debug-dump=info ./test | grep "DW_AT_producer"
<c> DW_AT_producer : (indirect string, offset: 0x2a): GNU C17 10.2.0 -mtune=generic -march=x86-64 -g
悲しいことに、少なくともバージョン10では、clangは同様の方法でオプションを記録していないようです。
もちろん、strings
これも明らかになりますが、実世界のバイナリのすべての文字列を肉眼で検査することは通常非現実的であるため、何を探すべきかについて少なくともある程度のアイデアが必要です。たとえば、上記の例のバイナリを使用します。
% strings ./test | grep march
GNU C17 10.2.0 -mtune=generic -march=x86-64 -g -O3
使用したコンパイラ(同じバージョン)がまだあり、フラグが1つしかない場合は、フラグを付けた場合と付けない場合で、コードのコンパイルを再試行できます。次に、実行可能ファイルを比較できます。古いものは、新しいものの1つと同一、または非常に類似している必要があります。
私はそれが可能であると強く疑っています:
int main()
{
}
でコンパイルした場合:
gcc -O3 -ffast-math -g main.c -o main
生成されたオブジェクトには、どのパラメーターも見つかりません。
strings main | grep -O3
(no output)