

cコンパイラでコンパイルしたオブジェクトコードがソースコードに対応していることを確認する方法はないでしょうか？

## 追記

多くの回答を頂きありがとうございます。環境はMac上でiOS開発です。


CC BY-SA 4.0
2019-10-22T06:17:56.923
59869
2019-10-23T03:57:59.070
2019-10-22T21:43:19.913
19110
36300
question
c
ソースコードとオブジェクトコードが対応していることを確認する


そのオブジェクトをコンパイルしたのと同じコンパイル環境があるのであれば、再コンパイルしてオブジェクトの diff
を見てみればいいと思います。同じソースコード・環境でコンパイルされたものであればファイルの内容は完全に一致します。


CC BY-SA 4.0
2019-10-22T11:39:15.863
59876
2019-10-22T11:39:15.863
4388
59869
answer


条件をそろえないと判定は難しそうです。

オブジェクトファイルの比較には、`cmp`も使えます。

[code]

    cmp -s 比較対照オブジェクトファイル 比較用にコンパイルしたオブジェクトファイル
    echo $?
    
    ※bashで実行した場合
    
    
[/code]

比較には同じコンパイルオプションを使用する必要があります。  
※`-O`や`-g`などオプションが変わればオブジェクトファイルの内容も変わる可能性が高いです。

同じコンパイラを使う必要があります。  
`gcc`と`clang`で生成したオブジェクトファイルはサイズが違いました。

調査に使用したコマンド  
clang version 9.0.0 (trunk 362692) (llvm/trunk 362690)  
gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0  
cmp (GNU diffutils) 3.6


CC BY-SA 4.0
2019-10-22T11:58:45.740
59877
2019-10-22T11:58:45.740
35558
59869
answer


[RCS](https://ja.wikipedia.org/wiki/Revision_Control_System)や[CVS](https://ja.wikipedia.org/wiki/Concurrent_Versions_System)などの古めのソース管理システムですと、キーワード置換と言ってソースコード中に`$Id$`のようなキーワードを記述すると、コミット時に

[code]

     $Id: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $
    
[/code]

のような文字列に置換してくれる機能があります。これを使用してソースコード中に

[code]

    const char id[] = "$Id: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $";
    
[/code]

等の記述をすれば自動的にオブジェクトコードにも同一の文字列が埋め込まれることになります。この方法でソースコードとオブジェクトコードの対応を確認していた時代もあります。

* * *

Visual
Studioでは、オブジェクトファイル内のデバッグ情報内にソースコードのチェックサムを保持しているため、デバッガーなどはオブジェクトコード、デバッグ情報とソースコードとが一致しているかを確認しています。[コンパイルオプション`/ZH`](https://docs.microsoft.com/en-
us/cpp/build/reference/zh?view=vs-2019)でハッシュアルゴリズムを選択できることからもこの様子を覗い知ることができます。


CC BY-SA 4.0
2019-10-22T13:20:48.367
59880
2019-10-22T13:20:48.367
4236
59869
answer


質問者です。とりあえず参考までに逆アセンブルしてみたいと思っています。


CC BY-SA 4.0
2019-10-22T18:15:39.977
59885
2019-10-22T21:44:09.020
2019-10-22T21:44:09.020
19110
36300
59869
answer


短い答え：「一致している」を定義してから始めましょう。

長い答え：こういうのは要件っつか要求次第で違います。とりあえず、元オブジェクトファイルを作ったときと同一開発環境（同一コンパイラ・同一ヘッダ）があって
`Makefile` 等によりコンパイルオプションが既知である前提であるとします（無いと不可能なので）

当該ソースコードを以前と同一のコンパイラ・ヘッダ・コンパイルオプションでコンパイルしたなら、まあ普通には全く同一のオブジェクトファイルができそうな気がします。そして実際、オブジェクトファイルの内容を比較して同一のものが生成される環境もあります。が、例外として次のような状況が考えられます。

  1. `__DATE__` や `__TIME__` はコンパイル時刻を出力するので毎回異なる
  2. コンパイルしたときのタイムスタンプを埋め込むことがある
  3. ソースファイルやヘッダファイルのフルパス名を埋め込むことがある
  4. アセンブラが `tmpfile()` 等で作られたアセンブラ一時ファイル名を埋め込むことがある

なのでオブジェクトファイルのバイト内容の物理的一致で判断すると誤ることがあります。よってなにがどう一致していたら良いかは事前に定義しておく必要があります。

逆アセンブルした内容が一致する、というのは良いアイデアですが微妙に冗長かも。  
[gcc](/questions/tagged/gcc "'gcc' のタグが付いた質問を表示") の `make compare` は stageN
オブジェクトの一致性比較を事前に自己調査しています。ウチの `hppa2.0w-hp-hpux11.11` では `cmp --ignore-
initial=16` でヘッダ部をスキップしたファイル内容で行っている様子。  
Visual C++ はコンパイル時タイムスタンプを埋め込む (2.) のでこれを除外する必要があります。

などなど、事前に情報収集の上、仕様を決めておく必要があります。


CC BY-SA 4.0
2019-10-23T03:57:59.070
59900
2019-10-23T03:57:59.070
8589
59869
answer