Cross compile gdb for MIPS

ยท 498 words ยท 3 minute read

Here is how to cross compile gdb or gdbserver on x86_64 for MIPS.

You will need the following: ๐Ÿ”—

  • Ubuntu Linux bare metal server or VM running x86_64 (a fairly later version; I used 22.04)
  • Root access to the server

Build steps: ๐Ÿ”—

1. Get all the sources ๐Ÿ”—

We are building from source. The versions are as of writing this post. Here is where I got the sources:

  1. gdb 15.1 - https://sourceware.org/pub/gdb/releases/gdb-15.1.tar.xz
  2. GNU GMP lib v6.3.0 - https://gmplib.org/download/gmp/gmp-6.3.0.tar.xz
  3. GNU MPFR lib v4.2.1 - https://www.mpfr.org/mpfr-current/mpfr-4.2.1.tar.xz

The two libraries are the GNU Multi Precision Arithmetic Library (gmplib) and the GNU Multi Precision Floating Point Library (libmpfr). These have to be built first before gdb. My assumption is that this is a throwaway server, so you can run all commands as root.

First, let’s get the host setup before we download the sources:

apt update && apt upgrade -y
apt install -y build-essential m4 gcc-mipsel-linux-gnu g++-mipsel-linux-gnu

I am building gdbserver for testing on a Ubiquiti EdgeRouter that is running mipsel, so I get the compiler for mipsel.

Now let’s get the sources:

wget https://sourceware.org/pub/gdb/releases/gdb-15.1.tar.xz
wget https://gmplib.org/download/gmp/gmp-6.3.0.tar.xz
wget https://www.mpfr.org/mpfr-current/mpfr-4.2.1.tar.xz

2. Building the libraries ๐Ÿ”—

We have to first build GMP because it is a requirement when building MPFR.

tar xvf gmp-6.3.0.tar.xz && cd gmp-6.3.0
./configure --host=mipsel-linux-gnu
make -j$((`nproc`+1))
make install
cd ..

Then we build MPFR:

tar xvf mpfr-4.2.1.tar.xz && cd mpfr-4.2.1
./configure --host=mipsel-linux-gnu --with-gmp-build=/root/gmp-6.3.0
make -j$((`nproc`+1))
make install
cd ..

3. Building gdbserver ๐Ÿ”—

Now we can finally build gdbserver:

tar xvf gdb-15.1.tar.xz && cd gdb-15.1
./configure --host=mipsel-linux-gnu --with-gmp-lib=/usr/local/lib --with-mpfr-lib=/usr/local/lib --with-gmp-include=/root/gmp-6.3.0 --with-mpfr-include=/root/mpfr-4.2.1/src
make -j$((`nproc`+1)) LDFLAGS=-static

You will then find gdbserver in the gdbserver directory or gdb in the gdb directory. I have not tested gdb using the steps above, but I think it will have to be built using the --target flag as specified in this link.

I build gdbserver statically so that it won’t depend on any libraries on the device which may or may not be there. The binary is slightly bigger, but the tradeoff is worth it in this case.

You can basically ctrl+c/ctrl+v these commands. I’ve tested them a couple of times and they work on a freshly installed Ubuntu 22.04 machine. See the errors section below in case you have problems.

Errors ๐Ÿ”—

If you get some errors during make, it may be possible that the -j flag is causing some jobs to work faster than others. Try again after running make clean and removing the -j flag completely. It may build slower, but it will likely build.

Next, I copy the file over to my router using scp and run it so I can remote debug processes on the router using IDA Pro or Binary Ninja:

vbash-4.1# ./gdbserver 0.0.0.0:9898 --attach 17638
Attached; pid = 17638
Listening on port 9898

This allows debugging pid 17638 when you connect to it using your debugger. For example in Binary Ninja, from the menu bar, choose Debugger > Connect to Remote Process

Then enter the host and port to connect and click Accept.

Connect to remote process