質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.09%

Linux kernel を -O0 でコンパイルするとアセンブラでエラーになる

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 3,020

kenz_san

score 33

raspberry pi 向けの qemu の開発をしており、一部機能の不具合対応(ext4 でマウントエラーが発生)のため kernel を最適化なし(-O0)でコンパイルしたいのですが、コンパイルエラーが発生してしまっています。(-O1や-O2ではコンパイルできます)

解決策を探しているのですが、見つかっていません。どなたか情報を持っていないでしょうか?(「 -O0 はサポートしていないよ」とか)

../include/linux/compiler-gcc4.h:77:38: error: impossible constraint in ‘asm’
 #define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
                                      ^
...
In file included from ../include/linux/linkage.h:4:0,
                 from ../include/linux/fs.h:5,
                 from ../fs/ext4/ext4_jbd2.h:18,
                 from ../fs/ext4/mballoc.c:24:
In function__list_add_rcu’,
    inlined from ‘list_add_tail_rcu’ at ../include/linux/rculist.h:102:16,
    inlined from ‘ext4_mb_add_n_trim’ at ../fs/ext4/mballoc.c:4301:21:
../include/linux/compiler.h:412:20: error: call to ‘__compiletime_assert_54’ declared with attribute error: Need native word sized 
stores/loads for atomicity.
    prefix ## suffix();    \
                    ^

他にも、以下のような note や warning が出ていますが、関連がわかっていません。

../arch/arm/include/asm/jump_label.h: In function ‘ext4_mb_init_cache’:
../include/linux/compiler-gcc4.h:77:38: warning: asm operand 0 probably doesn’t match constraints [enabled by default]
 #define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
                                      ^
../arch/arm/include/asm/jump_label.h:18:2: note: in expansion of macroasm_volatile_goto’
  asm_volatile_goto("1:\n\t"
  ^
../include/linux/compiler-gcc4.h:77:38: warning: asm operand 0 probably doesn’t match constraints [enabled by default]
 #define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
                                      ^
../arch/arm/include/asm/jump_label.h:18:2: note: in expansion of macroasm_volatile_goto’
  asm_volatile_goto("1:\n\t"
  ^
...
../include/linux/compiler.h:417:2: note: in expansion of macro__compiletime_assert’
  __compiletime_assert(condition, msg, prefix, suffix)
  ^
...
../arch/arm/include/asm/barrier.h:68:2: note: in expansion of macrocompiletime_assert_atomic_type’
  compiletime_assert_atomic_type(*p);    \
  ^

開発環境は以下のような感じです。

 項目   内容 
 kernel   4.1.21 
 gcc   4.8.3 
 host   linux mint 17.3 64bit 
 コンパイル   make -j8 CFLAGS_mballoc.o="-O0" 

よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • yohhoy

    2016/07/30 15:46

    コンパイル時assert「Need native word sized stores/loads for atomicity.」が出ていますが、-O0以外ではコンパイルで来ているのでしょうか?

    キャンセル

  • kenz_san

    2016/08/06 12:29

    本文に追記しました。 -O1 や -O2 ではコンパイルできています。

    キャンセル

回答 1

checkベストアンサー

+1

-O0を使って、どういうことをやろうとしているのか分からないので、的外れかもしれませんが、
#pragma GCC optimize ("Ox")を使って、ファイル中の必要ところに、必要な最適化オプションを適用してしまうのはどうでしょうか?

"ext4_jbd2.h"と<trace/events/ext4.h>の箇所を -O2設定にすることで、
make CFLAGS_mballoc.o="-O0"でコンパイルは、通りました(※)。

  • 例:linux/fs/ext4/mballoc.c
...
#pragma GCC push_options
#pragma GCC optimize ("O2")
#include "ext4_jbd2.h"
#pragma GCC pop_options
#include "mballoc.h"
#include <linux/log2.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/backing-dev.h>
#pragma GCC push_options
#pragma GCC optimize ("O2")
#include <trace/events/ext4.h>
#pragma GCC pop_options

...
  • 以下のような警告が出ますが、だいじょぶっぽい?
warning: #pragma GCC target is not supported for this machine [-Wpragmas]
#pragma GCC pop_options

(※) 環境

  • ホスト: Ubuntu 16.04
    $ cat /etc/lsb-release 
    DISTRIB_ID=Ubuntu
    DISTRIB_RELEASE=16.04
    DISTRIB_CODENAME=xenial
    DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS"

  • Raspberry Pi カーネルソース (試した時点で最新 commit: db84877)
    $ head -5 Makefile 
    VERSION = 4
    PATCHLEVEL = 4
    SUBLEVEL = 16
    EXTRAVERSION =
    NAME = Blurry Fish Butt

  • クロスコンパイラ 
    $ ../tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc --version
    arm-linux-gnueabihf-gcc (crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03) 4.8.3 20140303 (prerelease)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/08/10 08:40 編集

    回答ありがとうございます。

    GCC にそんな拡張があったことを知りませんでした。奥が深いですね。

    教えていただいたコードを適用したのですが、質問したものと別のエラーが発生してしまい、まだ動作確認までたどり着いていません。

    ```
    ### これまでエラーのなかった CFLAGS_mballoc.o="-O1" でも同様のエラーになる
    $ make -j8 CFLAGS_mballoc.o="-O0"
    ...
    CC fs/ext4/mballoc.o
    CHK kernel/config_data.h
    ../fs/ext4/mballoc.c:27:9: warning: #pragma GCC target is not supported for this machine [-Wpragmas]
    #pragma GCC pop_options
    ^
    ../fs/ext4/mballoc.c: In function ‘ext4_exit_mballoc’:
    ../fs/ext4/mballoc.c:2866:1: internal compiler error: in dwarf2out_frame_debug_adjust_cfa, at dwarf2cfi.c:1078
    }
    ^
    Please submit a full bug report,
    with preprocessed source if appropriate.
    See <https://bugs.launchpad.net/gcc-linaro> for instructions.
    make[4]: *** [fs/ext4/mballoc.o] Error 1
    ```

    mt08 さんとは kernel バージョンが異なるため、そのあたりを引き続き掘り下げていこうと思っています。

    ちなみに、 `-O0` でやりたいことは、qemu を経由して GDB による kernel のデバッグを行うことです。( `-O1` 以上の最適化が入ると変数の参照などがまともにできなかったので)

    キャンセル

  • 2016/08/10 09:03

    kenz_sanさん、

    `git clone --depth=1 https://github.com/raspberrypi/linux.git -b rpi-4.1.y`で取得してみました。エラーでますね。

    `#include`を全部、"-O2"にしたら、、コンパイル通るみたいですよ。

    ```
    #pragma GCC push_options
    #pragma GCC optimize ("O2")
    #include "ext4_jbd2.h"
    #include "mballoc.h"
    #include <linux/log2.h>
    #include <linux/module.h>
    #include <linux/slab.h>
    #include <trace/events/ext4.h>
    #pragma GCC pop_options
    ```


    $ head -5 Makefile
    VERSION = 4
    PATCHLEVEL = 1
    SUBLEVEL = 21
    EXTRAVERSION =
    NAME = Series 4800

    キャンセル

  • 2016/08/11 21:42

    mt08 さん

    確認ありがとうございます。同様にヘッダをすべて push_options / pop_options で囲ってみましたが、エラーは解消されませんでした。。

    ソース、コンパイラはともに最新のコミットを利用しているため、差異はないはずなのですが。。

    エラーの発生していた `ext4_exit_mballoc` と対になる `ext4_init_mballoc` を push_options / pop_options で `O1` にしたらコンパイルは通った( `O2` ではダメでした)のですが、また別のエラーが、、

    ```
    LD init/built-in.o
    fs/built-in.o: 関数 `kmalloc_large' 内:
    /home/tkenji/Workspace/raspi/linux-rpi-4.1.y/raspi-build/../include/linux/slab.h:361: `____ilog2_NaN' に対する定義されていない参照です
    /home/tkenji/Workspace/raspi/linux-rpi-4.1.y/raspi-build/../include/linux/slab.h:361: `____ilog2_NaN' に対する定義されていない参照です
    make[2]: *** [vmlinux] Error 1
    ```

    エラー自体は既知の問題のようなので(多くの情報はgccのバグとして解決済みになっているようですが、、)回避策を探ってみます。

    キャンセル

  • 2016/08/16 11:22

    `____ilog2_NaN` については、最終的に削除することで対処しました。

    コンパイルしたカーネルをQEMUで起動し、最適化のかかっていない状態でデバッグできるようになりました。ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.09%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる