Posts tagged - clang

static code analysis with scan-build while cross-compiling

The LLVM static code analyzer scan-build is easy to use, right? All you do is prepend scan-build in front of your make command. Well, there a certain circumstances where it will not work. For example, if your Makefile was generated by Eclipse for your cross-compile, scan-build will output some error messages and report zero bugs. You may be wondering, why does scan-build work with other Makefiles? To understand that, one must understand the inner workings of make and scan-build. When one runs make, it defines a bunch of rules and environmental variables. One such variable is the CC variable, which is for defining the C-Compiler. It is good practice to define the CC variable to the compiler (CC := gcc) in the Makefile and use $(CC) for the compile command. The scan-build program works by inserting itself between the compile command, which is done by replacing the CC variable with the clang analyzer.

First we should determine what targets supported by LLVM with the following command.

llc --version

Since ARM is a supported target, we’ll assume we are cross-compiling for an embedded system without an OS.

If you run the following command, it will tell you what make sets CC to. It will return cc, which is really just gcc—for the host machine. Therefore, we’ll need to set CC to the ARM cross-compiler in the Makefile.

make --print-data-base | grep '^CC ='

Anything clang doesn’t support will need to be changed. The following script converts the Eclipse generated Makefiles and source to ones that agree with clang, which serves as an example of some of the changes needed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/bin/bash
 
echo "Setting CC variable to arm-none-eabi-gcc..."
sed -i 's/RM := .*/&\nCC := arm-none-eabi-gcc/g' Debug/makefile
 
 
echo "Replacing compiler with CC variable..."
for mkfile in $(grep -rl --exclude=makefile arm-none-eabi-gcc Debug)
do
    sed -i 's/arm-none-eabi-gcc/$(CC)/g' $mkfile
done
 
 
echo "replacing -Og with one clang recognizes..."
for mkfile in $(grep -rl '\-Og' Debug)
do
    sed -i 's/-Og/-O2/g' $mkfile
done
 
 
FIND='\([ \t]*\)\(.*:[ ]"r"[ ](\)\([a-zA-Z0-9_]*\)\()[ ]:[ ]"vfpcc");\)'
REPLACE='#ifdef __clang__\n\1__builtin_arm_set_fpscr(\3);\n#else\n&\n#endif'
 
echo "replacing vfpcc with clang builtin"
for srcfile in $(grep -rl vfpcc .)
do
if [[ $srcfile != *$0 ]]
then
    echo "add clang builtin for vfpcc $srcfile"
    sed -i 's/'"$FIND"'/'"$REPLACE"'/g' $srcfile
fi
done
 
echo -e "you can use scan-build for analysis.\n\n"

Assuming you’re in the Eclipse project directory, you should be able to run the analyzer with the following command—after you’ve run the script above. If you run into errors, you’ll need to resolve them and eventually add the fixes to the script. For example, you might run to an ASM goto issue.

scan-build --use-cc=/usr/bin/arm-none-eabi-gcc --analyzer-target=arm-none-eabi make -C Debug

No Comments

static code analysis of kernel modules with LLVM

When one attempts to build an out-of-tree/proprietary kernel module, it may not build or work… Static code analysis is a great way to find bugs and therefore improve product quality. One of my preferred code analysis tools is scan-build (aka clang-analyzer) because its easy to use and has great HTML output. All one has to do is prepend scan-build to your build command: scan-build make. Unfortunately, the LLVM compiler infrastructure doesn’t support the gcc extension asm goto. Therefore, if your kernel was compiled with CONFIG_JUMP_LABEL set, there will probably be numerous errors from scan-build. Fortunately, there is a workaround: undefine CC_HAVE_ASM_GOTO.

Example command-line to analyze a kernel module with scan-build.
scan-build make CFLAGS="-UCC_HAVE_ASM_GOTO"

No Comments