マシンコードでの場所の検索(gcc / objdump -d)
-
08-07-2019 - |
質問
マシン出力で調べる特定のCコード行がある場合、objdump出力でそれをどのように見つけますか。以下に例を示します
if (cond)
foo;
bar();
そして、私が望むようにバーがインライン化されたかどうかを見たいです。 または、objdumpの代わりに別のツールを使用しますか?
解決
-S
オプション(" objdump -Sd a.out"
など)を使用してobjdumpを起動できます。コードがコンパイルされたソースファイルが利用可能な場合、アセンブラコードと混在するソースコードを表示します。
代わりに、次の方法を使用できます:
int main(void) {
int a = 0;
asm("#");
return a;
}
なる
.file "a.c"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $16, %esp
movl <*>, -8(%ebp)
#APP
# 3 "a.c" 1
#
# 0 "" 2
#NO_APP
movl -8(%ebp), %eax
addl $16, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (GNU) 4.3.2"
.section .note.GNU-stack,"",@progbits
他のヒント
デバッグシンボルを使用してコンパイルした場合は、デバッガーでソースコードと一致するアセンブリを確認することもできます。これはgccオプション-gおよびgdb disassコマンドです。
gccでコンパイルする場合は、-Sを使用してアセンブリファイルを直接生成できます。このファイルには通常、関数名やコードの行番号(使用するコンパイルオプションによって異なります)など、いくつかの有用な情報が含まれています。
関数呼び出しは、共通関数プロローグによってアセンブリ内で検出されます。
i386では
55 push %ebp
89 e5 mov %esp, %ebp
...
c9 leave # optional
c3 ret
amd64 / x86_64の場合も同様です(クワッドプレフィックス 48
のみ):
55 push %rbp
48 89 e5 mov %rsp,%rbp
..
c9 leaveq # optional
c3 retq
したがって、 objdump -S bla.o
内でそれを検出すると
または
gcc bla.c -g -fs -temps -fverbose-asm
メイン関数の出力
また、バーの場合、バーはインライン化されません。また、メインにコールまたはジャンプがある場合
禁止するには、インライン化されません。
あなたの場合、バーにローカル変数があるかどうかを確認できます
ローカルスタック。 barがインライン化されている場合、スタックは調整します(例: sub $ 0x8、%esp
)
メインのプロローグの直後に行われ、メインはその変数にアクセスできます。
そうでない場合は、bar専用です。