🦆

clangで"-finstrument-functions"オプションを使う

2021/06/06に公開

はじめに

clangで-finstrument-functionsオプションを使用してみます。

ドキュメント

https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-finstrument-functions

このドキュメントは1行しか書いていないので、gccの方を見てみます。

https://gcc.gnu.org/onlinedocs/gcc-9.3.0/gcc/Instrumentation-Options.html#index-finstrument-functions

サンプル

以下のようなコードを用意します。

sample.c
#include<stdio.h>

void __attribute__((no_instrument_function))
__cyg_profile_func_enter (void *this_fn, void *call_site)
{
      printf("[+]\n");
}

void __attribute__((no_instrument_function))
__cyg_profile_func_exit  (void *this_fn, void *call_site)
{
    printf("[-]\n");
}

int main()
{
    printf("HW\n");
    return 0;
}

オプションを付けずに、コンパイル、実行をします。

$ clang sample.c
$ ./a.out 
HW

次に-finstrument-functionsオプションを付けてみます。

$ clang -finstrument-functions sample.c
$ ./a.out 
[+]
HW
[-]

__cyg_profile_func_enter,__cyg_profile_func_exit の処理が呼ばれるようになりました。

llvm-objdumpで中身を見てみる

まずはオプションなしのバイナリ。

$ clang sample.c
$ llvm-objdump -D a.out

出力結果は以下(main関数の箇所のみ抜粋)。

0000000000401190 <main>:
  401190: 55                           	pushq	%rbp
  401191: 48 89 e5                     	movq	%rsp, %rbp
  401194: 48 83 ec 10                  	subq	$16, %rsp
  401198: c7 45 fc 00 00 00 00         	movl	$0, -4(%rbp)
  40119f: 48 bf 0e 20 40 00 00 00 00 00	movabsq	$4202510, %rdi
  4011a9: b0 00                        	movb	$0, %al
  4011ab: e8 80 fe ff ff               	callq	0x401030 <printf@plt>
  4011b0: 31 c0                        	xorl	%eax, %eax
  4011b2: 48 83 c4 10                  	addq	$16, %rsp
  4011b6: 5d                           	popq	%rbp
  4011b7: c3                           	retq
  4011b8: 0f 1f 84 00 00 00 00 00      	nopl	(%rax,%rax)

次にオプション有りの場合。

$ clang -finstrument-functions sample.c
$ llvm-objdump -D a.out

出力結果は以下のようになります。
printfの前後で__cyg_profile_func_enter,__cyg_profile_func_exitを呼び出す処理が追加されています。

0000000000401190 <main>:
  401190: 55                           	pushq	%rbp
  401191: 48 89 e5                     	movq	%rsp, %rbp
  401194: 48 83 ec 10                  	subq	$16, %rsp
  401198: 48 8b 75 08                  	movq	8(%rbp), %rsi
  40119c: 48 bf 90 11 40 00 00 00 00 00	movabsq	$4198800, %rdi
  4011a6: e8 85 ff ff ff               	callq	0x401130 <__cyg_profile_func_enter>
  4011ab: c7 45 fc 00 00 00 00         	movl	$0, -4(%rbp)
  4011b2: 48 bf 0e 20 40 00 00 00 00 00	movabsq	$4202510, %rdi
  4011bc: b0 00                        	movb	$0, %al
  4011be: e8 6d fe ff ff               	callq	0x401030 <printf@plt>
  4011c3: 48 8b 75 08                  	movq	8(%rbp), %rsi
  4011c7: 48 bf 90 11 40 00 00 00 00 00	movabsq	$4198800, %rdi
  4011d1: e8 8a ff ff ff               	callq	0x401160 <__cyg_profile_func_exit>
  4011d6: 31 c0                        	xorl	%eax, %eax
  4011d8: 48 83 c4 10                  	addq	$16, %rsp
  4011dc: 5d                           	popq	%rbp
  4011dd: c3                           	retq
  4011de: 66 90                        	nop

参考

以下のページが参考になりました。

https://qiita.com/naohikowatanabe/items/d559858734d8a02f0d8a

私としては、もっと単純なものから確認してみたかったので
この記事を書いてみました。

Discussion