10

バックグラウンド

Linux カーネル内の特定のドライバーをコンパイルしようとしています: drm ( drivers/gpu/drm/drm_drv.o) および radeon ( drivers/gpu/drm/radeon/) gpu ドライバー。copy_to/from_user()静的分析 (呼び出しで使用される引数の追跡) の目的で LLVM を使用しています。

これまでのところ、以下に示すように、Makefile を使用して実際のモジュールをコンパイルできます。

make CC=clang CFLAGS=-emit-llvm drivers/gpu/drm/radeon/

しかし、これは実際には llvm ビットコードを出力しません。.bcパスを実行するにはファイルが必要ですopt

.bc私はclangを直接使用する場合(以下のように)にのみファイルを生成する方法を知っていますが、Makefilesでは知りません...

clang -emit-llvm hello.c -c -o hello.bc

それが機能したので、GNU make 操作の詳細な出力を取得し、 に変更gccして実行し、ファイルclangを作成しました。これも機能しました。.bc

clang -emit-llvm [[大量の CFLAGS]] -c -o drm_drv.bc drivers/gpu/drm/drm_drv.c

唯一の問題は、カーネル モジュールで一度に 1 つの C ファイルしか処理できないことです。また、このアプローチを行うのは非常に面倒です...

主な問題

.bcこれが私の主な質問につながります:カーネルの Makefile を使用してllvm ビットコード ファイルを発行するにはどうすればよいですか?

または、.bcビットコードの作成をファイルごとに行う必要がある場合、カーネル モジュール内optのすべてのファイルの集合体で LLVM パスを実行できるように、最後にそれらをすべてリンクするにはどうすればよいでしょうか?.bc

4

2 に答える 2

2

Clang からビットコード形式で LLVM IR を取得する最良の方法は、-fltoコマンド ライン フラグを使用して LTO を実行することです。

複数の翻訳単位がある場合は、llvm-ltoツールを使用してそれらを結合し、ビットコード ファイルを「リンク」できます。通常はコードを生成しますが、マージされた LLVM IR モジュールを-save-merged-moduleフラグでドロップするように取得できます。

しかし、これは実際にサポートされているインターフェースではありません。これが非常に有用なワークフローである場合は、LLVM 開発者に ld に似たものをサポートするように相談する必要があります-r

于 2016-05-31T05:27:54.293 に答える
0

ext2 モジュールをインストルメント化するために clang を使用しました。やりたいことが 3 つあります。 opt.o ファイル。

これに加えて、clang でコンパイルされた Linux バージョンも必要です。いくつかのモジュールを無効にした後、clang バージョン 3.8.1 でコンパイルされた Linux 4.17 を取得できました。ここで入手できます

それでは、ステップ1に移りましょう - あなたが言ったように、詳細モードでMakeを実行してください

make V=1 M=fs/ext2

Makefileによって吐き出されるすべてのオプションを取得します。デフォルトのコンパイラは gcc です。gcc を clang に置き換え、--emit-llvm コマンドを追加し、.o を .bc に置き換えます。私のマシンでの結果のコンパイルコマンドは次のようになります。

cd ../../ && clang -emit-llvm -Wp,-MD,fs/ext2/.all.o.d  -nostdinc -isystem /usr/local/bin/../lib/clang/3.8.1/include -I./arch/x86/include -Iarch/x86/include/generated/uapi -Iarch/x86/include/generated  -Iinclude -I./arch/x86/include/uapi -Iarch/x86/include/generated/uapi -I./include/uapi -Iinclude/generated/uapi -include ./include/linux/kconfig.h -D__KERNEL__ -Qunused-arguments -Wno-unknown-warning-option -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -no-integrated-as -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -O2 -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-variable -Wno-format-invalid-specifier -Wno-gnu -Wno-asm-operand-widths -Wno-initializer-overrides -fno-builtin -Wno-tautological-compare -mno-global-merge -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Wno-initializer-overrides -Wno-unused-value -Wno-format -Wno-unknown-warning-option -Wno-sign-compare -Wno-format-zero-length -Wno-uninitialized  -DMODULE  -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(all)"  -D"KBUILD_MODNAME=KBUILD_STR(ext2)" -mcmodel=kernel -c -o fs/ext2_instrumented/all.bc fs/ext2/all.c && cd -

これにより、.bc ファイルが作成されます。結果の .bc コード ディレクトリを ext2_instrumented に変更したことに注意してください。つまり、bc ファイルは fs/ext2 ではなく、fs/ext2_instrumented という別のフォルダに作成されます。これは私の作業フォルダです。このフォルダーには .c ファイルを含めず、.bc ファイルのみを含めます。デフォルトの KBuild システムはフォルダー内の .c ファイルを検索するため、これが必要です。これについては後で詳しく説明します。

ステップ 2: 次のように opt コマンドを使用して、結果の ext2-instrumented.bc ファイルですべての最適化パスを実行します。

opt -load $(DIR)/build/FSlice.so -constprop -sccp -mergereturn -sink -licm -reg2mem all.bc -o all.inst.bc llvm-link -o all.inst2.bc $(DIR)/ build/libFSlice.bc all.inst.bc clang -mcmodel=kernel -c all.inst2.bc -o all.o

これは .o ファイルになり、次のステップで .ko ファイルにコンパイルします。

ステップ 3:

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) ext2instrumented.ko

Kbuild システムは理解するのが難しく、変更を加えるのはさらに困難です。この 2 フォルダー ハック (最初のフォルダーで .bc ファイルを作成し、2 番目のフォルダーで .o および .ko ファイルを作成) を使用することをお勧めします。要約すると、ext2_instrumented フォルダーにある結果のメイクファイルは次のとおりです。

DIR=/home/fslice/fslice

obj-m += ext2instrumented.o

ext2instrumented-objs := all.o

all:
        cd ../../ && clang -emit-llvm -Wp,-MD,fs/ext2/.all.o.d  -nostdinc -isystem /usr/local/bin/../lib/clang/3.8.1/include -I./arch/x86/include -Iarch/x86/include/generated/uapi -Iarch/x86/include/generated  -Iinclude -I./arch/x86/include/uapi -Iarch/x86/include/generated/uapi -I./include/uapi -Iinclude/generated/uapi -include ./include/linux/kconfig.h -D__KERNEL__ -Qunused-arguments -Wno-unknown-warning-option -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -no-integrated-as -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -O2 -Wframe-larger-than=1024 -fno-stack-protector -Wno-unused-variable -Wno-format-invalid-specifier -Wno-gnu -Wno-asm-operand-widths -Wno-initializer-overrides -fno-builtin -Wno-tautological-compare -mno-global-merge -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Wno-initializer-overrides -Wno-unused-value -Wno-format -Wno-unknown-warning-option -Wno-sign-compare -Wno-format-zero-length -Wno-uninitialized  -DMODULE  -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(all)"  -D"KBUILD_MODNAME=KBUILD_STR(ext2)" -mcmodel=kernel -c -o fs/ext2_instrumented/all.bc fs/ext2/all.c && cd -
        opt -load $(DIR)/build/FSlice.so -constprop -sccp -mergereturn -sink -licm -reg2mem all.bc -o all.inst.bc
        llvm-link -o all.inst2.bc $(DIR)/build/libFSlice.bc all.inst.bc
        clang -mcmodel=kernel -c all.inst2.bc -o all.o
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) ext2instrumented.ko

clean:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
        rm -rf *.bc
于 2016-10-09T18:27:41.610 に答える