Git Product home page Git Product logo

android-kernel-clang's Introduction

Compiling an Android kernel with Clang

Background

Google compiles the Pixel 2 kernel with Clang. They shipped the device on Android 8.0 with a kernel compiled with Clang 4.0 (build.config commit and prebuilt kernel commit) and upgraded to Android 8.1 with a kernel compiled with Clang 5.0 (build.config commit and prebuilt kernel commit).

Google uses Clang's link-time optimization and control flow integrity in the Pixel 3 kernel, hardening it against return oriented programming attacks (LTO commit, CFI commit).

Google started compiling all Chromebook 4.4 kernels with Clang in R67 (commit, LKML) and going forward, Clang is the default compiler for all future versions of the kernel (commit).

Further information including videos of talks on the motive behind compiling with Clang can be found in the ClangBuiltLinux wiki.

TL;DR: Helps find bugs, easier for Google since all of AOSP is compiled with Clang, compiler specific features such as link-time optimization, and better static analysis for higher code quality.

Requirements

  • A compatible kernel (4.4 or 4.9 LTS work best)
  • arm64 or x86_64
  • Patience

msm-4.14 and newer uses clang by default so there is no need for a patch stack.

How to compile the kernel with Clang (standalone)

NOTE: I am not going to write this for beginnings. I assume if you are smart enough to pick some commits, you are smart enough to know how to run git clone and know the paths of your system.

  1. Add the Clang commits to your kernel source
  2. Download/build a compatible Clang toolchain
  3. Download/build a copy of binutils
  4. Compile the kernel (for arm64, x86_64 is similar - example using AOSP's toolchains):
make O=out ARCH=arm64 <defconfig>

PATH="<path to clang folder>/bin:<path to 64-bit gcc folder>/bin:<path to 32-bit gcc folder>/bin:${PATH}" \
make -j$(nproc --all) O=out \
                      ARCH=arm64 \
                      CC=clang \
                      CLANG_TRIPLE=aarch64-linux-gnu- \
                      CROSS_COMPILE=aarch64-linux-android- \
                      CROSS_COMPILE_ARM32=arm-linux-androideabi-

After compiling, you can verify the toolchain used by opening out/include/generated/compile.h and looking at the LINUX_COMPILER option.

A couple of notes:

  1. CLANG_TRIPLE is only needed when using AOSP's version of Clang.
  2. export CC=clang does not work. You need to pass CC=clang to make like above.
  3. CROSS_COMPILE_ARM32 is needed in recent kernels to support the new compat vDSO.

How to compile the kernel with Clang (inline with a custom ROM)

  1. Add the Clang commits to your kernel source
  2. Make sure your ROM has this commit
  3. Add the following to your BoardConfig.mk file in your device tree: TARGET_KERNEL_CLANG_COMPILE := true

To test and verify everything is working:

  1. Build a kernel image: m kernel or m bootimage
  2. Open the out/target/product/*/obj/KERNEL_OBJ/include/generated/compile.h file and look at the LINUX_COMPILER option.

Getting the Clang patchset

The core Clang patchset comes from mainline. It has been backported to three places:

If your kernel has 4.4.165 or 4.9.139 and newer, you automatically have the patchset and can start building with Clang!

Branch information

The branches in this repository will be dedicated to adding this patchset when it does not exist and enhancing it by fixing all of the warnings from Clang (from mainline, the Pixel 2 and 3, msm-4.9/msm-4.14, and my own knowledge).

The general structure of these commits is as follows:

  1. The core compilation support (if needed)
  2. Fixing Qualcomm specific drivers to compile with Clang
  3. Fixing warnings that come from code in mainline
  4. Fixing warnings that come from code outside of mainline

You should pick the commits that I have committed (nathanchance).

Additionally, there are fixes for:

Every time there is a branch update upstream, the branch will be rebased, there is no stable history here! Ideally, I will not need to add any commits but I will do my best to keep everything in the same order.

NOTE: 3.18 Clang is not supported officially by an OEM. I've merely added it here as I decided to support it with my Pixel XL kernel.

How to get a Clang toolchain

You can either use a prebuilt version of Clang (like from AOSP) or build a version yourself from the upstream sources.

For prebuilts, I recommend AOSP's Clang, which is used for both the kernel and the platform so it is highly tested. You can git clone that repo to always have access to the latest version available, which is what I recommend. That is currently Clang 9.0.8. If you would like to just download the minimum version of Clang supported for the branches in this repo, direct tarball links are provided below:

If you would like to build the latest version of Clang, you can do so with tc-build. There are a lot of fixes for the Linux kernel that happen in LLVM/Clang so staying up to date is critical. If you experience any issues with Clang and an Android kernel, please report them to this repo.

How to get binutils

binutils are used for assembling (and usually linking) the Linux kernel right now. When using AOSP Clang, you should use AOSP's GCC to avoid weird incompatibility issues. If you want source-built binutils, there is a build-binutils.py script available in tc-build.

Getting help

The preferred method for getting help is either opening an issue on this repository or joining the Linux kernel newbies chat on Telegram.

android-kernel-clang's People

Contributors

nathanchance avatar pablomh avatar rajatgupta1998 avatar vasishath avatar yarost12 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

android-kernel-clang's Issues

vdsomunge: Not a shared object

Hi! I am trying to fix various warnings on my kernel and am currently compiling with proton clang. If I use GCC4 together with clang, it compiles just fine. If I however use https://github.com/arter97/arm64-gcc (GCC 10) with Clang, I just get

arch/arm64/kernel/vdso32/../../../arm/vdso/vdsomunge: Not a shared object

Compiling with GCC10 alone is fine.

Facing the compilation error after following the mentioned steps

Hi

I am getting the following error after compiling the kernel using the mentioned steps

./drivers/firmware/efi/libstub/lib.a(arm64-stub.stub.o): In function __efistub_handle_kernel_image': __efistub_arm64-stub.c:(.init.init.text+0x1c): undefined reference to __efistub___stack_chk_guard'
__efistub_arm64-stub.c:(.init.init.text+0x20): undefined reference to __efistub___stack_chk_guard' __efistub_arm64-stub.c:(.init.init.text+0x1d0): undefined reference to __efistub___stack_chk_guard'
__efistub_arm64-stub.c:(.init.init.text+0x1d8): undefined reference to __efistub___stack_chk_guard' __efistub_arm64-stub.c:(.init.init.text+0x21c): undefined reference to __efistub___stack_chk_fail'
./drivers/firmware/efi/libstub/lib.a(arm-stub.stub.o): In function __efistub_efi_open_volume': __efistub_arm-stub.c:(.init.text+0x14): undefined reference to __efistub___stack_chk_guard'
__efistub_arm-stub.c:(.init.text+0x18): undefined reference to __efistub___stack_chk_guard' __efistub_arm-stub.c:(.init.text+0xa0): undefined reference to __efistub___stack_chk_guard'
__efistub_arm-stub.c:(.init.text+0xa8): undefined reference to __efistub___stack_chk_guard' __efistub_arm-stub.c:(.init.text+0xd0): undefined reference to __efistub___stack_chk_fail'
./drivers/firmware/efi/libstub/lib.a(arm-stub.stub.o): In function __efistub_efi_file_size': __efistub_arm-stub.c:(.init.text+0x11c): undefined reference to __efistub___stack_chk_guard'
__efistub_arm-stub.c:(.init.text+0x120): undefined reference to __efistub___stack_chk_guard' __efistub_arm-stub.c:(.init.text+0x258): undefined reference to __efistub___stack_chk_guard'
__efistub_arm-stub.c:(.init.text+0x260): undefined reference to __efistub___stack_chk_guard' __efistub_arm-stub.c:(.init.text+0x2b8): undefined reference to __efistub___stack_chk_fail'
./drivers/firmware/efi/libstub/lib.a(arm-stub.stub.o): In function __efistub_efi_entry': __efistub_arm-stub.c:(.init.text+0x2f0): undefined reference to __efistub___stack_chk_guard'
__efistub_arm-stub.c:(.init.text+0x2f4): undefined reference to __efistub___stack_chk_guard' __efistub_arm-stub.c:(.init.text+0x388): undefined reference to __efistub___stack_chk_guard'
__efistub_arm-stub.c:(.init.text+0x390): undefined reference to __efistub___stack_chk_guard' __efistub_arm-stub.c:(.init.text+0x618): undefined reference to __efistub___stack_chk_fail'
./drivers/firmware/efi/libstub/lib.a(random.stub.o): In function __efistub_efi_get_random_bytes': __efistub_random.c:(.init.text+0x10): undefined reference to __efistub___stack_chk_guard'
__efistub_random.c:(.init.text+0x14): undefined reference to __efistub___stack_chk_guard' __efistub_random.c:(.init.text+0x6c): undefined reference to __efistub___stack_chk_guard'
__efistub_random.c:(.init.text+0x74): undefined reference to __efistub___stack_chk_guard' __efistub_random.c:(.init.text+0x94): undefined reference to __efistub___stack_chk_fail'
./drivers/firmware/efi/libstub/lib.a(random.stub.o): In function __efistub_efi_random_alloc': __efistub_random.c:(.init.text+0xb0): undefined reference to __efistub___stack_chk_guard'
__efistub_random.c:(.init.text+0xb4): undefined reference to __efistub___stack_chk_guard' __efistub_random.c:(.init.text+0x1d8): undefined reference to __efistub___stack_chk_guard'
__efistub_random.c:(.init.text+0x1e0): undefined reference to __efistub___stack_chk_guard' __efistub_random.c:(.init.text+0x260): undefined reference to __efistub___stack_chk_fail'
./drivers/firmware/efi/libstub/lib.a(efi-stub-helper.stub.o): In function __efistub_efi_printk': __efistub_efi-stub-helper.c:(.init.text+0x20): undefined reference to __efistub___stack_chk_guard'
__efistub_efi-stub-helper.c:(.init.text+0x24): undefined reference to __efistub___stack_chk_guard' __efistub_efi-stub-helper.c:(.init.text+0x80): undefined reference to __efistub___stack_chk_guard'

Then I commented out the CONFIG_CC_STACKPROTECTOR_STRONG=y in config file, compilation is successful , Is it okay to do that? any implications from that?

Kernel panic due to broken patch

After applying clang patches, I decicded to first do an regular GCC4 build to sort out issues with the patches. Well, I got a kernel panic about accessing userspace memory after it tried to play the touch sound. After way to much debugging, I found the problematic patch:
n4archive/OptimKernel@da944ad
I tried this alternative commit:
n4archive/OptimKernel@fd1ac4e
It doesn't crash anymore, but sound remains silent. Completely.
(I still use GCC 4!)
Without any of those 2 patches, it's fine again. No crash and no silence.

Well, how to properly fix the warning?

Google GCC is removed

Google GCC is removed from the repo, now this repo only contains the OWNERS file. can you please update the steps for compiling the Kernel, thanks.

compile android-4.9-q

This repo is pretty cool! However, I still have some problems when I compile msm-4.9-android-10.
The first command runs pretty well: make O=out oldconfig ARCH=arm64 -Werror
But I encounter a problem when I run:

PATH="/home/yuexiao/Documents/research/diffcvss/LLVM/latest_clang/tc-build/install/bin:/home/yuexiao/Documents/research/diffcvss/LLVM/aarch64-linux-android-4.9/bin:${PATH}" \
make -j$(nproc --all) O=out \
                      ARCH=arm64 \
                      CC=clang \
                      CLANG_TRIPLE=aarch64-linux-gnu- \
                      CROSS_COMPILE=aarch64-linux-android- \
                      CROSS_COMPILE_ARM32=arm-linux-androideabi-

It said ../security/apparmor/crypto.c:37:8: error: fields must have a constant size: I am pretty new to complie Android Kernel with Clang. Any response wil be appreciated!!

CC [M]  fs/ceph/mds_client.o
  CC      security/apparmor/lsm.o
  GEN     security/apparmor/rlim_names.h
  CC      security/apparmor/sid.o
  CC [M]  fs/cifs/file.o
  CC [M]  fs/btrfs/root-tree.o
  CC      security/apparmor/file.o
  CC [M]  fs/coda/file.o
  CC [M]  fs/ceph/mdsmap.o
  CC      security/apparmor/crypto.o
  CC [M]  fs/coda/upcall.o
  CC [M]  fs/btrfs/dir-item.o
../security/apparmor/crypto.c:37:8: error: fields must have a constant size: 'variable length array in structure' extension will never be supported
                char ctx[crypto_shash_descsize(apparmor_tfm)];
                     ^
1 error generated.
make[4]: *** [../scripts/Makefile.build:335: security/apparmor/crypto.o] Error 1
make[4]: *** Waiting for unfinished jobs....
  CC [M]  fs/btrfs/file-item.o
make[3]: *** [../scripts/Makefile.build:648: security/apparmor] Error 2
make[2]: *** [/home/yuexiao/Documents/research/diffcvss/LLVM/andoid_mainline/kernel_common/Makefile:1090: security] Error 2
make[2]: *** Waiting for unfinished jobs....
  CC [M]  fs/btrfs/inode-item.o
  CC [M]  fs/ceph/strings.o
  CC [M]  fs/coda/coda_linux.o
  CC [M]  fs/ceph/ceph_frag.o
  CC [M]  fs/btrfs/inode-map.o


Faild to build flame kernel

Hi there:
I tried to build the floral_defconfig (from my understanding is used for coral and flame)
Everything seems going well when following your guide “How to compile the kernel with Clang (standalone)".

Unfortunately I got a error as below:
aarch64-linux-android-ld.gold: error: LLVMgold.so: could not load plugin library: LLVMgold.so: cannot open shared object file: No such file or directory
../scripts/Makefile.build:613: recipe for target 'arch/arm64/lib/lib-ksyms.o' failed
make[2]: *** [arch/arm64/lib/lib-ksyms.o] Error 1
/home/dongtaotao/msm/Makefile:1153: recipe for target 'arch/arm64/lib' failed
make[1]: *** [arch/arm64/lib] Error 2

Would you mind let me know anything I need to check?

Failed to build goldfish kernel

Hi the guide is pretty cool. But I met a failure when I make kernel:

make O=out ARCH=x86_64 CC=clang CLANG_TRIPLE=x86_64-linux-gnu x86_64_defconfig

make[1]: Entering directory '/data/kernel-android-emulator/goldfish/out'
  GEN     Makefile
#
# No change to .config
#
make[1]: Leaving directory '/data/kernel-android-emulator/goldfish/out'

make -j64 O=out ARCH=x86_64 CC=clang CLANG_TRIPLE=x86_64-linux-gnu- CROSS_COMPILE=x86_64-linux-android-

root@chrome-server:/data/kernel-android-emulator/goldfish# make -j64 O=out  ARCH=x86_64 CC=clang CLANG_TRIPLE=x86_64-linux-gnu- CROSS_COMPILE=x86_64-linux-android-
make[1]: Entering directory '/data/kernel-android-emulator/goldfish/out'
  GEN     Makefile
scripts/kconfig/conf  --syncconfig Kconfig
scripts/Kconfig.include:39:  gold linker 'x86_64-linux-android-ld' not supported
make[3]: *** [../scripts/kconfig/Makefile:73: syncconfig] Error 1
make[2]: *** [../Makefile:571: syncconfig] Error 2
make[1]: *** [/data/kernel-android-emulator/goldfish/Makefile:691: include/config/auto.conf.cmd] Error 2
make[1]: Leaving directory '/data/kernel-android-emulator/goldfish/out'
make: *** [Makefile:179: sub-make] Error 2
root@chrome-server:/data/kernel-android-emulator/goldfish#

I have not much experience on compiling Android or cross build kernel, so could you please guide me more ? Great thank.

Before the code change, I can cross build kernel 4.19 with gcc, but i have no idea how to do that with CLang.

Thanks
--Yi

Are there any patches availible for 4.14.117 kernel?

Can I apply the patches you provided in the readme file to a 4.14.117 kernel or it would have lots of conflicts?
Can you provide all of these patches in one patch file?
Do these patches work with Qualcomm llvm?

compile other version of android kernel

Hi Nathan,

May I ask a question about compilation other version of android kernel?

Followed by this tutorial, I can successfully compile android-4.4 and android-4.9. However, Is it possible to compile any versions of android kernel(eg., 4.10.0) if I properly add the Clang commits to this kernel source ?

Best,
Yue

undefined reference to `stpcpy' problem during compilation

Thanks for providing such cool tutorial! However, I encounter a problem in linking process. It says undefined reference to stpcpy. Then, I search stpcpy in the android source code, I did not see any definition. I have been stuck for the whole day, could you give some hints if possible?

  CC [M]  drivers/scsi/st.o
  LD [M]  drivers/net/wireless/realtek/rtlwifi/rtlwifi.o
  LD [M]  drivers/net/wireless/realtek/rtlwifi/rtl_pci.o
  CC [M]  drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.o
  CC [M]  drivers/net/wireless/realtek/rtlwifi/rtl8723be/table.o
  LD [M]  drivers/net/wireless/realtek/rtlwifi/rtl_usb.o
  CC [M]  drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.o
  CC [M]  drivers/scsi/ch.o
  CC [M]  drivers/scsi/ses.o
  CC [M]  drivers/scsi/scsi_debug.o
  LD [M]  drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rtl8821ae.o
  LD      drivers/scsi/scsi_mod.o
  LD      drivers/scsi/sd_mod.o
  LD      drivers/scsi/sr_mod.o
  LD [M]  drivers/net/wireless/realtek/rtlwifi/rtl8723be/rtl8723be.o
  LD      drivers/net/wireless/built-in.o
  LD      drivers/net/built-in.o
  LD [M]  drivers/scsi/qla2xxx/qla2xxx.o
  LD      drivers/scsi/built-in.o
  LD      drivers/built-in.o
  GEN     .version
  LD      vmlinux.o
  MODPOST vmlinux.o
  CHK     include/generated/compile.h
  UPD     include/generated/compile.h
  CC      init/version.o
  LD      init/built-in.o
drivers/built-in.o: In function `devspec_show':
/home/yuexiao/Documents/research/diffcvss/LLVM/andoid_mainline/kernel_common/out/../drivers/pci/pci-sysfs.c:440: undefined reference to `stpcpy'
drivers/built-in.o: In function `tty_line_name':
/home/yuexiao/Documents/research/diffcvss/LLVM/andoid_mainline/kernel_common/out/../drivers/tty/tty_io.c:1360: undefined reference to `stpcpy'
/home/yuexiao/Documents/research/diffcvss/LLVM/andoid_mainline/kernel_common/out/../drivers/tty/tty_io.c:1360: undefined reference to `stpcpy'
/home/yuexiao/Documents/research/diffcvss/LLVM/andoid_mainline/kernel_common/out/../drivers/tty/tty_io.c:1360: undefined reference to `stpcpy'
drivers/built-in.o: In function `get_ata_class_names':
/home/yuexiao/Documents/research/diffcvss/LLVM/andoid_mainline/kernel_common/out/../drivers/ata/libata-transport.c:149: undefined reference to `stpcpy'
security/built-in.o:/home/yuexiao/Documents/research/diffcvss/LLVM/andoid_mainline/kernel_common/out/../security/apparmor/lsm.c:818: more undefined references to `stpcpy' follow
make[1]: *** [/home/yuexiao/Documents/research/diffcvss/LLVM/andoid_mainline/kernel_common/Makefile:1071: vmlinux] Error 1
make[1]: Leaving directory '/home/yuexiao/Documents/research/diffcvss/LLVM/andoid_mainline/kernel_common/out'
make: *** [Makefile:152: sub-make] Error 2

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.