Loose-Info.com

Last Update 2021/01/15


TOP - 各種テスト - gcc - -fno-builtinオプション

-fno-builtinオプション
接頭辞が __builtin_ で始まらない組み込み関数の認識を無効化

テスト概要

接頭辞が __builtin_ で始まる関数と始まらない関数を含むコードのコンパイルを実行
-fno-builtinの有無による生成されたバイナリファイルの内容を比較

実行環境

GCC-8.2.0
GNU C Library 2.28
GNU Binutils 2.31.1


コード例・出力内容中の表記

・実行例中の太字表記部分は、コマンドなどの入力された文字列を示します。
・「」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。
・出力例中の赤字のコメントは必要に応じて、改行した上で挿入しています。

使用ファイル


main.c
/* -fno-builtin オプション動作確認用ソースファイル */ #include <stdio.h> #include <stdlib.h> int main(void) { printf("printf[1]\n"); printf("printf[2] %d\n",1); __builtin_printf("__builtin_printf\n"); printf("abs %d\n", abs(-1)); printf("__builtin_abs %d\n", __builtin_abs(-2)); return 0; }

その1

-fno-builtinオプション無しでコンパイル

コンパイル実行
$ gcc -v -g -Wall main.c <--- デバッグ情報生成のため-gオプションを付加 Using built-in specs. /usr/libexec/gcc/x86_64-pc-linux-gnu/8.2.0/cc1 -quiet -v main.c ... GNU C17 (GCC) version 8.2.0 (x86_64-pc-linux-gnu) compiled by GNU C version 8.2.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version none as -v --64 -o /tmp/ccZlfzQL.o /tmp/ccT6YGtG.s /usr/libexec/gcc/x86_64-pc-linux-gnu/8.2.0/collect2 ... COLLECT_GCC_OPTIONS='-v' '-g' '-Wall' '-mtune=generic' '-march=x86-64' $ ./a.out printf[1] printf[2] 1 __builtin_printf abs 1 __builtin_abs 2 $ objdump -S -d a.out <--- objdumpで実行形式ファイルを逆アセンブル a.out: file format elf64-x86-64 Disassembly of section .plt: 0000000000401020 <.plt>: 401020: ff 35 e2 2f 00 00 pushq 0x2fe2(%rip) # 404008 <_GLOBAL_OFFSET_TABLE_+0x8> 401026: ff 25 e4 2f 00 00 jmpq *0x2fe4(%rip) # 404010 <_GLOBAL_OFFSET_TABLE_+0x10> 40102c: 0f 1f 40 00 nopl 0x0(%rax) 0000000000401030 <puts@plt>: <--- ソースファイル中に記述のないputs 401030: ff 25 e2 2f 00 00 jmpq *0x2fe2(%rip) # 404018 <puts@GLIBC_2.2.5> 401036: 68 00 00 00 00 pushq $0x0 40103b: e9 e0 ff ff ff jmpq 401020 <.plt> 0000000000401040 <printf@plt>: 401040: ff 25 da 2f 00 00 jmpq *0x2fda(%rip) # 404020 <printf@GLIBC_2.2.5> 401046: 68 01 00 00 00 pushq $0x1 40104b: e9 d0 ff ff ff jmpq 401020 <.plt> pltセクション内にabsの記述は無し 0000000000401122 <main>: #include <stdio.h> #include <stdlib.h> int main(void) { 401122: 55 push %rbp 401123: 48 89 e5 mov %rsp,%rbp printf("printf[1]\n"); 401126: bf 04 20 40 00 mov $0x402004,%edi 40112b: e8 00 ff ff ff callq 401030 <puts@plt> 1引数のprintfはputsに書き換え発生 printf("printf[2] %d\n",1); 401130: be 01 00 00 00 mov $0x1,%esi 401135: bf 0e 20 40 00 mov $0x40200e,%edi 40113a: b8 00 00 00 00 mov $0x0,%eax 40113f: e8 fc fe ff ff callq 401040 <printf@plt> 2引数はprintfの呼び出し __builtin_printf("__builtin_printf\n"); 401144: bf 1c 20 40 00 mov $0x40201c,%edi 401149: e8 e2 fe ff ff callq 401030 <puts@plt> __builtin_で始まるprintfは組み込み関数と認識されputsで置き換え printf("abs %d\n", abs(-1)); 40114e: be 01 00 00 00 mov $0x1,%esi abs関数ではなくコンパイラによる事前演算 401153: bf 2d 20 40 00 mov $0x40202d,%edi 401158: b8 00 00 00 00 mov $0x0,%eax 40115d: e8 de fe ff ff callq 401040 <printf@plt> printf("__builtin_abs %d\n", __builtin_abs(-2)); 401162: be 02 00 00 00 mov $0x2,%esi __builtin_で始まるabsは組み込み関数と認識されコンパイラにより事前演算 401167: bf 35 20 40 00 mov $0x402035,%edi 40116c: b8 00 00 00 00 mov $0x0,%eax 401171: e8 ca fe ff ff callq 401040 <printf@plt> return 0; 401176: b8 00 00 00 00 mov $0x0,%eax } 40117b: 5d pop %rbp 40117c: c3 retq 40117d: 0f 1f 00 nopl (%rax)

その2

-fno-builtinオプションを使用してコンパイル

コンパイル実行
$ gcc -v -g -Wall -fno-builtin main.c <--- デバッグ情報生成のため-gオプションを付加 Using built-in specs. /usr/libexec/gcc/x86_64-pc-linux-gnu/8.2.0/cc1 -quiet -v main.c ... -fno-builtin ... GNU C17 (GCC) version 8.2.0 (x86_64-pc-linux-gnu) compiled by GNU C version 8.2.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version none as -v --64 -o /tmp/ccgpiVi0.o /tmp/ccestti4.s /usr/libexec/gcc/x86_64-pc-linux-gnu/8.2.0/collect2 ... COLLECT_GCC_OPTIONS='-v' '-g' '-Wall' '-fno-builtin' '-mtune=generic' '-march=x86-64' $ ./a.out printf[1] printf[2] 1 __builtin_printf abs 1 __builtin_abs 2 $ objdump -S -d a.out <--- objdumpで実行形式ファイルを逆アセンブル a.out: file format elf64-x86-64 Disassembly of section .plt: 0000000000401020 <.plt>: 401020: ff 35 e2 2f 00 00 pushq 0x2fe2(%rip) # 404008 <_GLOBAL_OFFSET_TABLE_+0x8> 401026: ff 25 e4 2f 00 00 jmpq *0x2fe4(%rip) # 404010 <_GLOBAL_OFFSET_TABLE_+0x10> 40102c: 0f 1f 40 00 nopl 0x0(%rax) 0000000000401030 <puts@plt>: <--- ソースファイル中に記述のないputs 401030: ff 25 e2 2f 00 00 jmpq *0x2fe2(%rip) # 404018 <puts@GLIBC_2.2.5> 401036: 68 00 00 00 00 pushq $0x0 40103b: e9 e0 ff ff ff jmpq 401020 <.plt> 0000000000401040 <abs@plt>: 401040: ff 25 da 2f 00 00 jmpq *0x2fda(%rip) # 404020 <abs@GLIBC_2.2.5> 401046: 68 01 00 00 00 pushq $0x1 40104b: e9 d0 ff ff ff jmpq 401020 <.plt> 0000000000401050 <printf@plt>: 401050: ff 25 d2 2f 00 00 jmpq *0x2fd2(%rip) # 404028 <printf@GLIBC_2.2.5> 401056: 68 02 00 00 00 pushq $0x2 40105b: e9 c0 ff ff ff jmpq 401020 <.plt> 0000000000401132 <main>: #include <stdio.h> #include <stdlib.h> int main(void) { 401132: 55 push %rbp 401133: 48 89 e5 mov %rsp,%rbp printf("printf[1]\n"); 401136: bf 04 20 40 00 mov $0x402004,%edi 40113b: b8 00 00 00 00 mov $0x0,%eax 401140: e8 0b ff ff ff callq 401050 <printf@plt> 1引数のprintfが組み込み関数と認識されずにprintfの呼び出し printf("printf[2] %d\n",1); 401145: be 01 00 00 00 mov $0x1,%esi 40114a: bf 0f 20 40 00 mov $0x40200f,%edi 40114f: b8 00 00 00 00 mov $0x0,%eax 401154: e8 f7 fe ff ff callq 401050 <printf@plt> __builtin_printf("__builtin_printf\n"); 401159: bf 1d 20 40 00 mov $0x40201d,%edi 40115e: e8 cd fe ff ff callq 401030 <puts@plt> __builtin_で始まるprintfは組み込み関数と認識されputsで置き換え printf("abs %d\n", abs(-1)); 401163: bf ff ff ff ff mov $0xffffffff,%edi 401168: e8 d3 fe ff ff callq 401040 <abs@plt> <printf@plt> 組み込み関数と認識されずにabsの呼び出し 40116d: 89 c6 mov %eax,%esi 40116f: bf 2e 20 40 00 mov $0x40202e,%edi 401174: b8 00 00 00 00 mov $0x0,%eax 401179: e8 d2 fe ff ff callq 401050 <printf@plt> printf("__builtin_abs %d\n", __builtin_abs(-2)); 40117e: be 02 00 00 00 mov $0x2,%esi <puts@plt> __builtin_で始まるabsは組み込み関数と認識されコンパイラにより事前演算 401183: bf 36 20 40 00 mov $0x402036,%edi 401188: b8 00 00 00 00 mov $0x0,%eax 40118d: e8 be fe ff ff callq 401050 <printf@plt> return 0; 401192: b8 00 00 00 00 mov $0x0,%eax } 401197: 5d pop %rbp 401198: c3 retq 401199: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)