diff --git a/24-Q4/02_linux-config.md b/24-Q4/02_linux-config.md new file mode 100644 index 0000000..1dd958c --- /dev/null +++ b/24-Q4/02_linux-config.md @@ -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 diff --git a/24-Q4/02_linux-config/script/01_copy_bc_files.sh b/24-Q4/02_linux-config/script/01_copy_bc_files.sh new file mode 100644 index 0000000..c583233 --- /dev/null +++ b/24-Q4/02_linux-config/script/01_copy_bc_files.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# 检查是否提供了两个参数 +if [ "$#" -ne 2 ]; then + echo "Usage: $0 " + 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 diff --git a/24-Q4/02_linux-config/script/02_convert_bc_to_ll.sh b/24-Q4/02_linux-config/script/02_convert_bc_to_ll.sh new file mode 100644 index 0000000..e534877 --- /dev/null +++ b/24-Q4/02_linux-config/script/02_convert_bc_to_ll.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# 检查是否提供了一个参数 +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + 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 diff --git a/24-Q4/02_linux-config/script/03_generate_dot_files.sh b/24-Q4/02_linux-config/script/03_generate_dot_files.sh new file mode 100644 index 0000000..0b8fc8d --- /dev/null +++ b/24-Q4/02_linux-config/script/03_generate_dot_files.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# 检查是否提供了一个参数 +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + 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 diff --git a/24-Q4/02_linux-config/script/04_process_dot_files.sh b/24-Q4/02_linux-config/script/04_process_dot_files.sh new file mode 100644 index 0000000..97da1a2 --- /dev/null +++ b/24-Q4/02_linux-config/script/04_process_dot_files.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +# 检查是否提供了一个参数 +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " + 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" diff --git a/24-Q4/image/02_linux-config/C-program.png b/24-Q4/image/02_linux-config/C-program.png new file mode 100644 index 0000000..9ea5a85 Binary files /dev/null and b/24-Q4/image/02_linux-config/C-program.png differ diff --git a/24-Q4/image/02_linux-config/bcfiles.png b/24-Q4/image/02_linux-config/bcfiles.png new file mode 100644 index 0000000..16f175b Binary files /dev/null and b/24-Q4/image/02_linux-config/bcfiles.png differ diff --git a/README.md b/README.md index f70f30a..acd0d27 100644 --- a/README.md +++ b/README.md @@ -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)