第14回 GCC2.95から追加変更のあったオプションの補足と検証(その3)

岸 哲夫

 前回に引き続きGCC2.95から追加変更のあったオプションの補足と検証を行う.今回は,「コード生成規約に対するオプション」の続きを扱う. (筆者)

space

-fleading-underscore

 このオプション,およびその否定のオプションである-fno-leading-underscoreは,オブジェクトファイルの中でCのシンボルが表現される方法を強制的に変更します.古いアセンブラコードとのリンクをサポートします.coff環境やi386用のクロスコンパイルでも使用します.

 ターゲットすべてに有効であるわけではないので,理解して使わないと混乱を招きます.

 Windowsの開発言語であるVisual C++は,アンダースコア付きシンボル名を生成します.よって,Cygwin環境で使用する場合には,Visual C++で作成されたDLLの呼び出しの際に注意しなくてはなりません.

 ソースと生成されたコードをリスト1リスト2に示します.

 このようにシンボル名の先頭に_(アンダースコア)が付いています.リスト3に,オプションなしで生成されたソースを示します.

-fno-common

 初期化済みでないグローバル変数をオブジェクトファイル中のbssセクションに割り当てます.

 コードと生成されたソースをリスト4リスト6に示します.

 生成されたアセンブラ上で疑似命令である.bssでセクションの指定がされています(リスト6).

 こちらのアセンブラソース上では共有領域をメモリに確保する疑似命令である.commが使われています.

 また,二つの異なるコンパイル単位の中でexternを使わずに同一のグローバル変数が宣言されている場合,リンク時エラーを発生させることができます.

-fno-gnu-linker

 GNUのリンカを使用しないときにこのオプションを指定します.注意すべきなのは,このオプションを指定すると,C++のコンストラクタやデコンストラクタをGNUのリンカで使われる形で出力しない点です.

-fnon-call-exceptions

 このオプションに関してはC++を説明する際に扱います.throw exceptionsをトラップするために使います.

-funwind-tables

 C++で作成されたモジュールとリンクし,なおかつ例外処理を行っている場合,このオプションを指定することが必要になります.

 使用している関数に対してフレーム解放のための情報が生成されます.

 -fexceptionsとの違いは,ライブラリ関数に対してはその情報が生成されないことです.

 ただし,CやC++のすべてのモジュールがGCCで作成された場合,それを意識しなくても良いはずです.そして,まったく別の環境で作成されたオブジェクトファイルとリンクさせる場合にも,その言語環境で同じような機能を用意しているかもしれません.

 コードと生成されたソースをリスト7リスト9に示します.このようにフレーム解放のための情報が生成されます.

-fasynchronous-unwind-tables

 フレーム解放のための情報をdwarf2フォーマットで生成することができます.もちろん,ターゲット側がdwarf2フォーマットに対応していることが前提となります.

 そして,非同期イベントが発生したときにフレームの巻き戻しを行うことが可能になります.

 基本的に,-funwind-tablesと同様の機能です.

-finstrument-functions

 このオプションを付けると,関数の出口と入口でトレース用の関数を呼び出す命令を付加します.関数の入口では,

  void __cyg_profile_func_enter (
              void *this_fn,void *call_site);

以上を,関数の出口では,

  void __cyg_profile_func_exit (
              void *this_fn,void *call_site0);

以上を,それぞれ呼び出します.

 この関数をトレースに利用することができます.しかし,単純なトレースならばGDBを使ったほうが早いと思います.

 コードをリスト10に示します.

 生成されたソースを後で示しますが,付加された関数,

  void __cyg_profile_func_enter(
              void *this_fn,void *call_site)

以上が関数の入り口で呼び出されるので,次のように情報を取得できます.

 当該関数のアドレスを標準出力に,

  printf("%p\n",this_fn);

以上を,当該関数から戻った箇所を標準出力に,

  printf("%p\n",call_site);

以上を,それぞれ出力しています.

 コンパイルと実行の結果を次に示します.

  $ gcc test198.c -o test198
       -finstrument-functions -Xlinker
          -Map -Xlinker test198.map

 上のようにコンパイルすると,マップファイル(リスト11)が出力され,実行結果は次のようになります.

  $ ./test198
  0x80483d4
  0x42015574
  0x8048441
  0x80483fd
  100
  0x804847b
  0x8048412
  0x80484ca
  0x804849a
  300
  200
  $

 また,次のようにコマンドを入力するとtest198.txt(リスト12)に実行形式の逆アセンブラリストが出力されます.

  $ objdump -d a.out > test198.txt

 オブジェクトファイルのシンボルを表示したい場合は次のようにコマンドを入力します.test198.lst(リスト13)に出力されます.

  $ nm -a test198 > test198.lst

 実行結果とtest198.txtを付き合わせると次のことがわかります.

  0x80483d4 関数mainのアドレス
  0x42015574 戻った先の次の命令
  0x8048441 関数test1のアドレス
  0x80483fd 戻った先の次の命令
  100 main中での最初のprintfの結果
        (関数test1から抜けた)
  0x804847b 関数test2のアドレス
  0x8048412 戻った先の次の命令
  0x80484ca 関数test21のアドレス
  0x804849a 戻った先の次の命令
  300 関数test2中でのprintfの結果
        (関数test21から抜けた)
  200 関数main中での2番目のprintfの結果
        (関数test2から抜けた)

 このようにトレースに使うことができます.関数の作り方によっては実行時間の計測も可能です.リスト10から生成されたソースをリスト14に示します.

 次のような行が付加されています.

  call __cyg_profile_func_enter
  call __cyg_profile_func_exit

 なお,比較対象として,オプションなしで生成したソースをリスト15に示します.

-fshort-wchar

 wchar_t型は通常4バイトです.しかし,Windowsではwchar_t型をshort unsigned int(2バイト)として扱わなければなりません.このオプションを指定すると,wchar_t型を2バイトとして扱います.CygwinなどでWindows環境とリンクする場合,またはWINEなどのWindowsエミュレータを使う場合に使用します.

 コードと生成されたソースをリスト16リスト17に示します.また,オプションなしでコンパイルした結果をリスト18に示します.

 リスト17からわかるように,変数dataは内部で2バイトとして扱われています.

 そして,変数dataは内部で4バイトとして扱われています.

 コンパイルと実行の結果を次に示します.

  $ gcc test199.c
  $ ./a.out
  wchar_tのサイズは4です
  $ gcc test199.c -fshort-wchar
  $ ./a.out

  wchar_tのサイズは2です

*          *

 次号では引き続き「コード生成規約に対するオプション」の補足,および「最適化オプション」の補足を行います.


NEW記事内インデックス    連載インデックスはこちら   Interfaceのトップ
◆コード生成規約に対するオプションの補足つづき
リスト

Copyright 2004 岸 哲夫

Copyright 1997-2017 CQ Publishing Co.,Ltd.