리눅스 커널 코드소스를 분석하다 보면 수많은 매크로를 만난다. 리눅스 커널을 캡슐화나 다형성과 같은 겍체지향 방식으로 구현하다 보니 매크로로 구현된 코드가 많다. 이 매크로가 소스 분석의 걸림돌 중 하나로 작용한다.
매크로는 컴퓨터 과학 분야에서 정해진 순서에 따라 어떻게 특정한 입력 시퀀스 가 출력 시퀀스 로 매핑되어야 하는지를 정의하는 규칙이나 패턴을 말한다.
전치리 코드는 이러한 매크로를 풀어서 표현한다. 소스코드를 편하게 분석할 수 있어 리눅스 커널 코드를 분석할 때는 전처리 코드를 함께 보는 것을 추천한다.
전처리 코드는 GCC 컴파일 오브젝트 생성 과정에서 추출된다.
커널에서 전처리 코드를 추출 하는 방법은 크게 두 가지 이다.
gcc
는 예전에는 GNU C Compiler의 약자였으나 지금은 GNU Compiler Collection의 약자이다.
gcc
는 Linux, 윈도우 등 수많은 운영체제를 지원 가능하여 높은 호환성을 가지고 있고, 자동 레지스터 할당, 반복적인 코드 제거, 상수 곱셈 최적화 등 많은 최적화를 수행하는 컴파일러이다
먼저 리눅스 커널의 전체 소스코드를 전처리 파일로 추출하는 방법을 보자
diff --git a/Makefile b/Makefile
index 3da5790..0414cb2 100644
--- a/Makefile
+++ b/Makefile
@@ -419,6 +419,7 @@ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -fno-common -fshort-wchar \
-Werror-implicit-function-declaration \
-Wno-format-security \
+ -save-temps=obj \
-std=gnu89
KBUILD_CPPFLAGS := -D__KERNEL__
KBUILD_AFLAGS_KERNEL :=
이 코드의 핵심은 -save-temps=obj \
이다
build_preprocess_rpi_kernel.sh
라는 이름으로 밑에 코드를 작성한다.
#!/bin/bash
echo "configure build output path"
KERNEL_TOP_PATH="$(cd "$(dirname "$0")" ; pwd -P )"
OUTPUT="$KERNEL_TOP_PATH/out"
echo "$OUTPUT"
KERNEL=kernel7
BUILD_LOG="$KERNEL_TOP_PATH/rpi_preprocess_build_log.txt"
PREPROCESS_FILE=$1
echo "build preprocessedd file: $PREPROCESS_FILE"
echo "move kernel source"
cd linux
echo "make defconfig"
make O=$OUTPUT bcm2709_defconfig
echo "kernel build"
make $PREPROCESS_FILE O=$OUTPUT zImage modules dtbs -j4 2>&1 | tee $BUILD_LOG
PREPROCESS_FILE=$1
echo "build preprocessedd file: $PREPROCESS_FILE"
: 셸 스크립트를 실행할 때 전달하는 소스코드의 이름이다.
make $PREPROCESS_FILE O=$OUTPUT zImage modules dtbs -j4 2>&1 | tee $BUILD_LOG
: 지정한 파일만 전처리 파일로 추출해라는 것이다.
build_preprocess_rpi_kernel.sh [파일이름.i]
로 사용할 수 있다.