可可 可用于评估各种程序的覆盖范围。在这里,我们展示了 Linux内核模块.

先决条件

本演示使用Debian OS上的Linux Kernel版本4.19.0-9。作为前提条件,必须在计算机上安装用于构建内核和使用Coco的软件包。

Linux模块构建系统

The build system contains different steps that are necessary 至 build a .ko kernel module file, displayed graphically below:

Linux模块构建系统

生成文件示例

ifneq ($(KERNELRELEASE),)
obj-m := my_module.o
my_module-y := foo.o bar.o
else
KDIR := /lib/modules/`uname -r`/build
PWD := $(shell pwd)
all:
    $(MAKE) -C $(KDIR) M=$(PWD) modules 
clean:
    $(MAKE) -C $(KDIR) M=$(PWD) clean
endif

调整代码

We’我们已经为静态内存分配和覆盖数据的处理创建了相应的代码。“coverage.h”,可从下面下载。唯一必要的步骤是将以下行添加到现有模块源代码中:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/slab.h>

#ifdef __COVERAGESCANNER__
#include "coverage.h"
#endif
.....
static int __init my_module_init(void)
{
#ifdef __COVERAGESCANNER__
    coverage_init(NULL, NULL);
#endif
    .....
}
.....
static void __exit my_module_exit(void)
{
    .....
#ifdef __COVERAGESCANNER__
    coverage_exit();
#endif
    return;
}
.....
module_init( my_module_init );
module_exit( my_module_exit );
.....

使包含可用于

链接器需要一些使用Coco时未提供的库:

ln -s /usr/src/linux-headers-$(uname -r)-common/arch/x86/include/asm/ \
/usr/src/linux-headers-$(uname -r)-common/include/
ln -s /usr/src/linux-headers-$(uname -r)-common/arch/x86/include/uapi/asm/ \
/usr/src/linux-headers-$(uname -r)-common/include/uapi/
ln -s /usr/lib/gcc/x86_64-linux-gnu/8/include/stdarg.h \
/usr/src/linux-headers-$(uname -r)-common/include/stdarg.h

调整对象工具

由于构建系统会临时更改构建中的.o文件的名称,因此 .tmp_filename.o文件名,我们需要让Coco更改相应名称 .csmes 文件。为此,我们将 objtool 用一个小的bash脚本。但首先,我们需要重命名 objtoolorig_objtool 为这个脚本工作。

我们将以下脚本放在文件夹中 /usr/lib/linux-kbuild-4.19/tools/objtool/ 名称 objtool.

#! /bin/bash
## This wrapper basically takes the last command and renames the corresponding .tmp_(NAME).csmes file 至  the name that 可可 expects
LASTCOMMAND=${@: -1}
## Cutting the ".tmp_" out of the csmes file for the target
B=$( echo "$LASTCOMMAND" | sed -rn 's/(.*)\.tmp_(.*)$/\1\2/p' )
B="$B.csmes"
## Renaming the csmes file
mv $LASTCOMMAND.csmes $B &amp;> /dev/null
## Normal 处理essing
D=$(dirname "$0")
$D/orig_objtool [email protected]

This script should have the x flag. You can revert the changes by invoking:

sudo apt-get install linux-kbuild-4.19 --reinstall

重新安装 objtool.

添加正确的.cspro文件开关

将以下行添加到 /opt/SquishCoco/bin/gcc.cspro:

DEACTIVATE_COVERAGESCANNER_OPTION_NO_ARG[LinuxKernel]=-M;-MM;-;-S;-dumpversion;-dumpmachine;-E;--version;-print-file-name=include

将以下行添加到 /opt/SquishCoco/bin/ld.cspro:

COMPILER_CMD[LinuxKernel]=gcc -c -O2 $LIBGEN$ -w $SOURCE$ -o $DESTINATION$ -fno-common
CUSTOM_SETUP[LinuxKernel]=NONE
DEACTIVATE_COVERAGESCANNER_OPTION_ONE_ARG[LinuxKernel]=--build-id
LINK_ADDITIONAL_ARGUMENTS[LinuxKernel]=
PLUGIN_REGISTRATION_API[LinuxKernel]=NO
FILE_FORMAT_SPECIFIER[LinuxKernel]=NO

使用可可’使用静态内存的功能

可可 usually makes use of the user-space functions malloc and free 至 allocate memory for coverage data. Those calls could be replaced with the kmalloc and kfree Kernel variants. But for simplicity we will allocate a static memory buffer. For that purpose, we need 至 set the environment variable COVERAGESCANNER_ARGS.

为了更容易设置 COVERAGESCANNER_ARGS,我们可以使用一个简短的脚本, 环境变量:

#!/bin/bash
export COVERAGESCANNER_ARGS="--cs-architecture=LinuxKernel --cs-memory-pool=64000 --cs-exclude=coverage.h"

更改文件夹的权限

由于Coco在标头文件夹中创建临时文件,因此我们需要允许Coco写入标头文件夹。为此,请键入以下命令并更改 用户 您的用户名的空格:

sudo chown 用户:USER -R /usr/src/linux-headers-4.19.0-9-*

使用环境变量调用make

source 环境变量

Now invoke make with:

make CC=csgcc LD=csld

现在按预期安装模块

insmod my_module.ko

输出覆盖率数据

在此展示中,可通过 处理 目录。通过运行以下命令,将当前coverage写入特定文件:

cat /proc/coverage/coverage_file > my_module.csexe

Now the generated my_module.o.csmes file and the my_module.csexe can be loaded and viewed in the 浏览器 或通过Coco命令行工具进行计算。

在这里获取coverage.h:

下载‘coverage.h’

支持

如果对Coco或本演示有任何疑问,请随时给我们写一封电子邮件 [email protected].

发表评论

您的电子邮件地址不会被公开。 必需的地方已做标记 *

复制链接