Files
static_utils/gdbserver.md

6.9 KiB
Raw Permalink Blame History

Building GDB Server for ARM Linux (Static Linking)

Note

This guide is generated by LLM. Please verify the correctness of the steps before using them.

This document outlines the process for cross-compiling GDB Server for ARM Linux (arm-linux-gnueabihf) with static linking.

Prerequisites

  • Linux development environment
  • ARM cross-compiler toolchain (in this case at /opt/gcc-arm-linux-guneabihf)
  • GDB source code (version 14.2 used in this example)

Build Script

Here's a reproducible build script that automates the entire process:

#!/bin/zsh

# Exit on error
set -e

# Configuration variables
GDB_VERSION="14.2"
GDB_SOURCE_DIR="/home/crosstyan/third-party/gdb-${GDB_VERSION}"
TOOLCHAIN_PREFIX="/opt/gcc-arm-linux-guneabihf"
TARGET="arm-linux-gnueabihf"
INSTALL_PREFIX="/home/crosstyan/Image/rootfs"

# Ensure we're in zsh
if [ -z "$ZSH_VERSION" ]; then
    echo "This script must be run in zsh shell!"
    echo "Please run: zsh $0"
    exit 1
fi

# Navigate to GDB source directory
cd $GDB_SOURCE_DIR

# Clean any previous build artifacts
echo "Cleaning previous build artifacts..."
make distclean || true

# Configure GDB for cross-compilation with static linking
echo "Configuring GDB for cross-compilation..."
./configure \
    --target=$TARGET \
    --host=$TARGET \
    --build=x86_64-linux-gnu \
    --prefix=$INSTALL_PREFIX \
    --disable-werror \
    --enable-gdbserver=yes \
    --disable-gdb \
    --disable-binutils \
    --disable-gas \
    --disable-ld \
    --disable-gold \
    --disable-gprof \
    LDFLAGS='-static' \
    CC=$TOOLCHAIN_PREFIX/bin/$TARGET-gcc \
    CXX=$TOOLCHAIN_PREFIX/bin/$TARGET-g++ \
    AR=$TOOLCHAIN_PREFIX/bin/$TARGET-ar \
    RANLIB=$TOOLCHAIN_PREFIX/bin/$TARGET-ranlib \
    CFLAGS="-O2"

# Build only the gdbserver component
echo "Building gdbserver..."
make -j$(nproc) all-gdbserver

# Verify the built binary
echo "Verifying the built binary..."
file gdbserver/gdbserver
readelf -h gdbserver/gdbserver

# Install gdbserver (optional)
# make install-gdbserver

echo "Build completed successfully!"
echo "The statically linked gdbserver binary is located at: $GDB_SOURCE_DIR/gdbserver/gdbserver"

Manual Build Process

If you prefer to build manually, follow these steps:

Navigate to the GDB source directory:

cd /home/crosstyan/third-party/gdb-14.2

Clean any previous build artifacts:

make distclean

Configure GDB for cross-compilation with static linking:

./configure \
    --target=arm-linux-gnueabihf \
    --host=arm-linux-gnueabihf \
    --build=x86_64-linux-gnu \
    --prefix=/home/crosstyan/Image/rootfs \
    --disable-werror \
    --enable-gdbserver=yes \
    --disable-gdb \
    --disable-binutils \
    --disable-gas \
    --disable-ld \
    --disable-gold \
    --disable-gprof \
    LDFLAGS='-static' \
    CC=/opt/gcc-arm-linux-guneabihf/bin/arm-linux-gnueabihf-gcc \
    CXX=/opt/gcc-arm-linux-guneabihf/bin/arm-linux-gnueabihf-g++ \
    AR=/opt/gcc-arm-linux-guneabihf/bin/arm-linux-gnueabihf-ar \
    RANLIB=/opt/gcc-arm-linux-guneabihf/bin/arm-linux-gnueabihf-ranlib \
    CFLAGS="-O2"

Build only the gdbserver component:

make -j$(nproc) all-gdbserver

Verify the built binary:

file gdbserver/gdbserver
readelf -h gdbserver/gdbserver

Configuration Options Explained

  • --target=arm-linux-gnueabihf: Specifies the target architecture
  • --host=arm-linux-gnueabihf: Specifies the host architecture (same as target for cross-compilation)
  • --build=x86_64-linux-gnu: Specifies the build system architecture
  • --prefix=/home/crosstyan/Image/rootfs: Installation directory
  • --disable-werror: Prevents warnings from being treated as errors
  • --enable-gdbserver=yes: Enables building gdbserver
  • --disable-gdb, --disable-binutils, etc.: Disables building other components
  • LDFLAGS='-static': Forces static linking
  • CC=..., CXX=...: Specifies the cross-compiler
  • AR=..., RANLIB=...: Specifies the cross-toolchain utilities
  • CFLAGS="-O2": Optimization level

Verification

After building, you can verify the binary with:

file gdbserver/gdbserver

Expected output:

gdbserver/gdbserver: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, BuildID[sha1]=613dd203a0dff4326f6bd325222a6d882afd6168, for GNU/Linux 3.2.0, with debug_info, not stripped

And check the ELF header:

readelf -h gdbserver/gdbserver

Look for:

Machine: ARM
Flags: 0x5000400, Version5 EABI, hard-float ABI

Notes

  • The build process requires the dependencies to be built in the correct order (handled automatically by the Makefile)
  • There may be warnings during the linking process about certain glibc functions in statically linked binaries
  • The resulting binary is statically linked but some functions may still require shared libraries at runtime

Troubleshooting

  • If you encounter "file format not recognized" errors, ensure you're using the correct cross-toolchain
  • If the build fails with missing dependencies, check that all required libraries are installed

Strip

/opt/gcc-arm-linux-guneabihf/bin/arm-linux-gnueabihf-strip <your-binary>

Notes

Note

This part is a human artifact. No LLM involved.

You might need to add

#ifndef __NR_sigreturn
#define __NR_SYSCALL_BASE	0
#define __NR_sigreturn			(__NR_SYSCALL_BASE+119)
#endif

to gdbserver/linux-arm-low.cc if you encounter the following error:

In file included from ./../gdbsupport/array-view.h:24,
                 from ./../gdbsupport/common-utils.h:27,
                 from ./../gdbsupport/common-defs.h:208,
                 from server.h:22,
                 from linux-arm-low.cc:19:
linux-arm-low.cc: In function CORE_ADDR arm_sigreturn_next_pc(regcache*, int, int*):
linux-arm-low.cc:890:29: error: __NR_sigreturn was not declared in this scope; did you mean sigreturn?
  890 |   gdb_assert (svc_number == __NR_sigreturn || svc_number == __NR_rt_sigreturn);
      |                             ^~~~~~~~~~~~~~
./../gdbsupport/gdb_assert.h:35:13: note: in definition of macro gdb_assert
   35 |   ((void) ((expr) ? 0 :                                                       \
      |             ^~~~
linux-arm-low.cc: In function CORE_ADDR get_next_pcs_syscall_next_pc(arm_get_next_pcs*):
linux-arm-low.cc:944:21: error: __NR_sigreturn was not declared in this scope; did you mean sigreturn?
  944 |   if (svc_number == __NR_sigreturn || svc_number == __NR_rt_sigreturn)
      |                     ^~~~~~~~~~~~~~
      |                     sigreturn
make: *** [Makefile:546: linux-arm-low.o] Error 1
make: *** Waiting for unfinished jobs....

See also asm/unistd.h from Android source code.