准备
- 有问题的代码一份
- 编译机一台
- GDB(至少会
start
,c
,b
,bt
,n
,s
,fin
,建议会-tui
,layout
,info
) - (推荐)Instruction set manual
- (推荐)Online cross referencer一个
- (可选)参考书任意
- 官方文档 重要!!!!!
- 深入分析GCC
编译
安装
apt install -y curl mutt git autogen build-essential lsb-release zlib1g-dev texinfo bison flex expat libexpat1-dev libisl-dev libgmp-dev m4 dejagnu libmpc-dev libmpfr-dev
拉取
git clone https://github.com/gcc-mirror/gcc.git
# for cross building
git clone https://github.com/mirror/newlib-cygwin.git
git clone https://github.com/bminor/binutils-gdb
编译
只是调试gcc大可以只看asm输出结果。
mkdir gcc/build
cd gcc/build
../configure --prefix=/opt/<triplet> --program-prefix=<triplet>- --with-sysroot=/opt/<triplet>/<triplet> --target=<triplet> --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,c++ --disable-multilib --enable-lto --disable-shared --with-newlib
make all-gcc "inhibit_libc=true"
sudo make install-gcc
以下是为了生成cross binary。
mkdir binutils-gdb/build
cd binutils-gdb/build
../configure --prefix=/opt/<triplet> --program-prefix=<triplet>- --with-sysroot=/opt/<triplet> --target=<triplet>
make
sudo make install
mkdir newlib-cygwin/build
cd newlib-cygwin/build
PATH=/opt/<triplet>/bin:"$PATH" ../configure --prefix=/opt/<triplet> --target=<triplet>
PATH=/opt/<triplet>/bin:"$PATH" make
PATH=/opt/<triplet>/bin:"$PATH" make install
cd gcc/build
../configure --prefix=/opt/<triplet> --program-prefix=<triplet>- --with-sysroot=/opt/<triplet>/<triplet> --target=<triplet> --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,c++ --disable-multilib --enable-lto --disable-shared --with-newlib
make
make install
cd newlib-cygwin/build
PATH=/opt/<triplet>/bin:"$PATH" ../configure --prefix=/opt/<triplet> --target=<triplet>
PATH=/opt/<triplet>/bin:"$PATH" make
PATH=/opt/<triplet>/bin:"$PATH" make install
调试
export PATH=/opt/<triplet>/bin:"$PATH"
只看asm(对没编译stage2和libc是必须的):
<triplet>-gcc -S -o - test.c
- GDB调试
cc1
:
https://gcc.gnu.org/wiki/DebuggingGCC
<triplet>-gcc <parameters> -wrapper gdb,--args
调试时pwd推荐位于gcc/gcc/
。
- 编译过程:
非常精炼的pass介绍:http://stffrdhrn.github.io/software/embedded/openrisc/2018/06/03/gcc_passes.html
- 看pass:
https://gcc.gnu.org/onlinedocs/gcc/Developer-Options.html
- IPA:
-fdump-ipa-all
- Tree:
-fdump-tree-all
以上pass基本不用关心,有问题自会别有人修。以下是架构相关调试的重点。
- RTL:
-fdump-rtl-all
以上选项后再加-all
(比如-fdump-ipa-all-all
)输出更多信息。
- 架构无关结果:
-fdump-final-insns
- 看不懂RTL -> https://gcc.gnu.org/onlinedocs/gccint/RTL.html
- 尤其是
SI
/DI
-> https://gcc.gnu.org/onlinedocs/gccint/Machine-Modes.html - 以及
/u
//v
-> https://gcc.gnu.org/onlinedocs/gccint/Flags.html
- 尤其是
Final轮已无调试信息,需看gcc/gcc/final.cc
。有些源文件动态生成在gcc/build/gcc
,尤其注意gcc/build/gcc/insn-*
,基本会对应于gcc/gcc/config/<arch>
。