gdb remote stub
关于GDB的remote stub,这两天又有了一些新的认识:
1. 在ARM上,并不是所有的无法识别的指令都是未定义指令,譬如我前面写的那些指令,并不会导致未定义指令的异常。通过对GDB的一些观察,GDB使用如下 数字作为未定义指令: BEBE、E7FFDEFE。通过实验,可以确定,它们在VBA中会导致undefined中止,而之前的只是无法反汇编,不会导致中止。
2. 在GDB的remote调试中,设定断点的工作可以由GDB代劳,只要返回不能识别Z指令,则GDB会自动地使用写内存的方式设定断点。这样remote stub就可以非常简单,处理尽量少的指令。由于没有试过在Z指令时返回OK,我估计如果在Z指令时返回OK,则GDB会把设定断点的工作完全交给 remote stub,这样就可以用软中断的方式了。
到目前为止,关于GBA的undefined instruction的实验我已经做了很多次,在数次实验和不断google之后,我现在基本得出一个结论:在GBA上要使用undefined instruction,是需要一个专门的设备叫做DACS的。而普通的卡带是没有这种设备的,因此当GBA发生了undefined instruction之后会死机,而不是执行ROM上的内容。我不知道我的猜想是否正确,但至少在MappyVM上可以正确使用的程序烧到卡带上就不行 了。
因此,关于调试,就需要换新的方法了,目前可选的方法有以下几种:
1. SWI:在GBA上,由于BIOS已经完全占用了软中断,因此必须要使用一些特殊的技巧,譬如使用RAM中的某个位置作为软中断的向量。用软中断,应该可以调试各种程序。缺点是对程序可以使用的内存做出了限制,这导致使用者必须仔细地设定内存的使用方式。
2. 跳转:通过b或者bl指令跳转到指定的位置。如果使用b指令,则可以通过跳转到的不同位置来确定不同的断点,如果是bl指令,则在跳转后可以直接得到原先 的位置。这种调试方法的问题在于如果使用thumb模式,很多代码将无法调试,因为一个16位的thumb指令无法随意表达跳转的位置。即便是ARM模 式,也比较麻烦。
3. 在编译完成之后,在可执行代码中加入空代码:使每个指令之间的距离加大,从而可以加入更多的内容以便添加的断点。问题是必须要搞明白elf和调试信息的格式,只修改代码部分,修改完毕后,还需要修改各种调试信息的内容。
从上面三种情况来看,第一种是比较方便实现的,第三种是功能最强大的。