In this section, I will detail the steps I performed to prepare a Linux system as a debugging host for the Mac OS X kernel:
Because Apple’s GNU Debugger (gdb) version that I used needs a GNU C Compiler (gcc) less than version 3 to build correctly, I downloaded and installed an ancient Red Hat 7.3 Linux system.[95] To install the Red Hat system, I chose the installation type Custom. When I was asked to select the packages to install (Package Group Selection), I chose only the packages Network Support and Software Development, as well as OpenSSH server from the individual package selection. These packages include all the necessary development tools and libraries to build Apple’s gdb under Linux. During the installation, I added an unprivileged user called tk
with a home directory under /home/tk.
After I had successfully installed the Linux host, I downloaded the following software packages:
Source code of Apple’s custom gdb version.[96]
Standard gdb source code from GNU.[97]
A patch for Apple’s gdb to compile under Linux.[98]
The appropriate source code version of the XNU kernel. I prepared the Linux debugging host to research the kernel bug described in Chapter 7, so I downloaded the XNU version 792.13.8.[99]
The appropriate version of Apple’s Kernel Debug Kit. I found the bug explored in Chapter 7 on Mac OS X 10.4.8, so I downloaded the corresponding Kernel Debug Kit version 10.4.8 (Kernel_Debug_Kit_10.4.8_8L2127.dmg).
After I downloaded the necessary software packages onto the Linux host, I unpacked the two versions of gdb:
linux$tar xvzf gdb-292.tar.gz
linux$tar xvzf gdb-5.3.tar.gz
Then I replaced the mmalloc directory of Apple’s source tree with the one from GNU gdb:
linux$mv gdb-292/src/mmalloc gdb-292/src/old_mmalloc
linux$cp -R gdb-5.3/mmalloc gdb-292/src/
I applied the patch to Apple’s gdb version:
linux$cd gdb-292/src/
linux$patch -p2 < ../../osx_gdb.patch
patching file gdb/doc/stabs.texinfo patching file gdb/fix-and-continue.c patching file gdb/mach-defs.h patching file gdb/macosx/macosx-nat-dyld.h patching file gdb/mi/mi-cmd-stack.c
I used the following commands to build the necessary libraries:
linux$su
Password: linux#pwd
/home/tk/gdb-292/src linux#cd readline
linux#./configure; make
linux#cd ../bfd
linux#./configure --target=i386-apple-darwin
--program-suffix=_osx; make;
→make install
linux#cd ../mmalloc
linux#./configure; make; make install
linux#cd ../intl
linux#./configure; make; make install
linux#cd ../libiberty
linux#./configure; make; make install
linux#cd ../opcodes
linux#./configure --target=i386-apple-darwin --program
-suffix=_osx; make;
→make install
To build the debugger itself, I needed to copy some header files from the XNU kernel source code to the include directory of the Linux host:
linux#cd /home/tk
linux#tar -zxvf xnu-792.13.8.tar.gz
linux#cp -R xnu-792.13.8/osfmk/i386/ /usr/include/
linux#cp -R xnu-792.13.8/bsd/i386/ /usr/include/
cp: overwrite `/usr/include/i386/Makefile'?y
cp: overwrite `/usr/include/i386/endian.h'?y
cp: overwrite `/usr/include/i386/exec.h'?y
cp: overwrite `/usr/include/i386/setjmp.h'?y
linux#cp -R xnu-792.13.8/osfmk/mach /usr/include/
I then commented some typedefs in the new _types.h file to avoid compile-time conflicts (see line 39, lines 43 to 49, and lines 78 to 81):
linux#vi +38 /usr/include/i386/_types.h
[..] 38 #ifdef __GNUC__39 // typedef __signed char __int8_t;
40 #else /* !__GNUC__ */ 41 typedef char __int8_t; 42 #endif /* !__GNUC__ */43 // typedef unsigned char __uint8_t;
44 // typedef short __int16_t;
45 // typedef unsigned short __uint16_t;
46 // typedef int __int32_t;
47 // typedef unsigned int __uint32_t;
48 // typedef long long __int64_t;
49 // typedef unsigned long long __uint64_t;
..78 //typedef union {
79 // char __mbstate8[128];
80 // long long _mbstateL; /* for alignment */
81 //} __mbstate_t;
[..]
I added a new include
to the file /home/tk/gdb-292/src/gdb/macosx/i386-macosx-tdep.c (see line 24):
linux#vi +24 /home/tk/gdb-292/src/gdb/macosx/i386-macosx-tdep.c
[..]24 #include <string.h>
25 #include "defs.h" 26 #include "frame.h" 27 #include "inferior.h" [..]
Finally, I compiled the debugger with the following commands:
linux#cd gdb-292/src/gdb/
linux#./configure --target=i386-apple-darwin --program-suffix=_osx --disable-gdbtk
linux#make; make install
After the compilation completed, I ran the new debugger as root so that the necessary directories could be created under /usr/local/bin/:
linux#cd /home/tk
linux#gdb_osx -q
(gdb)quit
After that, the debugger was ready.
I unpacked the downloaded Kernel Debug Kit disk image file (dmg) under Mac OS X, transferred the files per scp
to the Linux host, and named the directory KernelDebugKit_10.4.8. I also copied the XNU source code into the search path of the debugger:
linux#mkdir /SourceCache
linux#mkdir /SourceCache/xnu
linux#mv xnu-792.13.8 /SourceCache/xnu/
In Chapter 7, I described how the newly built kernel debugger can be used to connect to a Mac OS X machine.
[91] See the Solaris Modular Debugger Guide at http://dlc.sun.com/osol/docs/content/MODDEBUG/moddebug.html.
[92] See http://www.vmware.com/.
[95] There are still a few download mirror sites available where you can get the Red Hat 7.3 ISO images. Here are a few, as of this writing: http://ftp-stud.hs-esslingen.de/Mirrors/archive.download.redhat.com/redhat/linux/7.3/de/iso/i386/, http://mirror.fraunhofer.de/archive.download.redhat.com/redhat/linux/7.3/en/iso/i386/, and http://mirror.cs.wisc.edu/pub/mirrors/linux/archive.download.redhat.com/redhat/linux/7.3/en/iso/i386/.
[96] Apple’s custom gdb version can be downloaded at http://www.opensource.apple.com/tarballs/gdb/gdb-292.tar.gz.
[97] The standard gdb version from GNU can be downloaded at http://ftp.gnu.org/pub/gnu/gdb/gdb-5.3.tar.gz.
[98] The patch for Apple’s GNU debugger is available at http://www.trapkit.de/books/bhd/osx_gdb.patch.
[99] The XNU version 792.13.8 can be downloaded at http://www.opensource.apple.com/tarballs/xnu/xnu-792.13.8.tar.gz.