Skip to content

Commit

Permalink
linux config analyze
Browse files Browse the repository at this point in the history
  • Loading branch information
6eanut committed Nov 16, 2024
1 parent af8baec commit 981788b
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 0 deletions.
73 changes: 73 additions & 0 deletions 24-Q4/02_linux-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Linux Config Analyze

本篇内容:

1. 编译Linux
2. 获取Linux的Control Flow Graph
3. 统计CFG的BasicBlock

## 0-编译Linux

Linux源码tarball下载[地址](https://kernel.org/)

```shell
# 安装基本工具
apt install llvm lld clang graphviz build-essential python-is-python3 python3-pip python3.12-venv flex bison libelf-dev libssl-dev

# 下载Linux源码
wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.4.285.tar.xz
tar -xvf linux-5.4.285.tar.xz

# 配置及编译
cd linux-5.4.285
make defconfig
make
```

编译成果即为linux-5.4.285目录下的vmlinux文件

## 1-获取Linux的Control Flow Graph

### 1-1 获取单个C语言程序的CFG

![1731762851879](image/02_linux-config/C-program.png)

### 1-2 获取Linux的CFG

借助[wllvm](https://github.com/travitch/whole-program-llvm)工具

```shell
# 配置python虚拟环境并安装wllvm
python -m venv ~/venv00
source ~/venv00/bin/activate
pip install wllvm

# wllvm编译Linux
cd linux-5.4.284
export LLVM_COMPILER=clang
make CC=wllvm defconfig
make CC=wllvm LLVM=1

# 获取vmlinux.bc
extract-bc vmlinux

# 获取vmlinux.ll
llvm-dis vmlinux.bc

# 获取dot文件
opt -passes=dot-cfg vmlinux.bc
```

在wllvm编译Linux这一步之后,就可以在各个目录下看到bc文件,然后可以对某个bc文件进行opt从而得到dot文件

![1731763268300](image/02_linux-config/bcfiles.png)

## 2-统计CFG的BasicBlock

把bc文件整理到目的文件夹下:[copy_bc_files.sh](02_linux-config/script/01_copy_bc_files.sh) /pathto/linux-5.4.284 /pathto/bcfiles

把bc文件转换成方便阅读的ll文件:[convert_bc_to_ll.sh](02_linux-config/script/02_convert_bc_to_ll.sh) /pathto/bcfiles

将所有bc文件转换成dot文件:[generate_dot_files.sh ](02_linux-config/script/03_generate_dot_files.sh)/pathto/bcfiles

统计cfg的基本块情况:[process_dot_files.sh](02_linux-config/script/04_process_dot_files.sh) /pathto/bcfiles
26 changes: 26 additions & 0 deletions 24-Q4/02_linux-config/script/01_copy_bc_files.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash

# 检查是否提供了两个参数
if [ "$#" -ne 2 ]; then
echo "Usage: $0 <source_directory> <destination_directory>"
exit 1
fi

# 从命令行参数获取源目录和目标目录
src_dir="$1"
dst_dir="$2"

# 创建目标目录(如果不存在的话)
mkdir -p "$dst_dir"

# 使用find命令查找所有.bc文件并处理
find "$src_dir" -type f -name "*.bc" | while read file; do
# 计算相对于源目录的相对路径
relpath=$(realpath --relative-to="$src_dir" "$file")
# 构建目标文件路径
dstfile="$dst_dir/$relpath"
# 确保目标文件所在的目录存在
mkdir -p "$(dirname "$dstfile")"
# 复制文件
cp "$file" "$dstfile"
done
21 changes: 21 additions & 0 deletions 24-Q4/02_linux-config/script/02_convert_bc_to_ll.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

# 检查是否提供了一个参数
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <source_directory>"
exit 1
fi

# 从命令行参数获取源目录
src_dir="$1"

# 使用find命令查找所有.bc文件并处理
find "$src_dir" -type f -name "*.bc" | while read file; do
# 获取文件的基本路径(去掉扩展名)
basefile="${file%.bc}"
# 构建目标文件路径
llfile="${basefile}.ll"
# 使用 llvm-dis 将 .bc 文件转换为 .ll 文件
llvm-dis "$file" -o "$llfile"
echo "Converted $file to $llfile"
done
29 changes: 29 additions & 0 deletions 24-Q4/02_linux-config/script/03_generate_dot_files.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash

# 检查是否提供了一个参数
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <source_directory>"
exit 1
fi

# 从命令行参数获取源目录
src_dir="$1"

# 使用find命令查找所有.bc文件并处理
find "$src_dir" -type f -name "*.bc" | while read file; do
# 获取文件所在目录
dir=$(dirname "$file")

# 切换到文件所在目录
cd "$dir" || { echo "Failed to cd to $dir"; continue; }

# 获取文件名(不包括路径)
base=$(basename "$file" .o.bc)
base01="${base#.}"_dot
mkdir -p "$base01"
cd "$base01" || { echo "Failed to cd to $base01"; continue; }

# 使用 opt 工具生成 .dot 文件
opt -passes=dot-cfg "$file"
echo "Generated .dot files for $file at $dir/$base01"
done
34 changes: 34 additions & 0 deletions 24-Q4/02_linux-config/script/04_process_dot_files.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash

# 检查是否提供了一个参数
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <source_directory>"
exit 1
fi

# 从命令行参数获取源目录,并确保结尾有斜杠
src_dir="$1"
src_dir=${src_dir%/}/ # 如果结尾没有斜杠,则添加一个

# 初始化总基本块计数器
total_blocks=0

# 使用 find 命令从 src_dir 开始递归查找所有 .dot 文件
while IFS= read -r -d '' file; do
if [ -f "$file" ]; then
# 获取相对路径
rel_file="${file#$src_dir}"

# 使用 grep 命令查找所有包含 [shape=record,color= 的行
num_blocks=$(grep -c '\[shape=record,color=' "$file")

# 打印当前文件的基本块数量
echo "File: $rel_file, Number of basic blocks: $num_blocks"

# 累加到总基本块计数器
total_blocks=$((total_blocks + num_blocks))
fi
done < <(find "$src_dir" -type f -name "*.dot" -print0)

# 打印总的基本块数量
echo "Total number of basic blocks in all .dot files: $total_blocks"
Binary file added 24-Q4/image/02_linux-config/C-program.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added 24-Q4/image/02_linux-config/bcfiles.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# 24-Q4

[02 Linux Config Analyze](24-Q4/02_linux-config.md)

[01 sysMaster](24-Q4/01_sysMaster.md)

[00 Classification of ISA](24-Q4/00_ClassificationofISA.md)
Expand Down

0 comments on commit 981788b

Please sign in to comment.