231 lines
7.0 KiB
Markdown
231 lines
7.0 KiB
Markdown
# 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)
|
||
- zsh shell (recommended to avoid issues with PowerShell)
|
||
|
||
## Build Script
|
||
|
||
Here's a reproducible build script that automates the entire process:
|
||
|
||
```bash
|
||
#!/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:
|
||
|
||
1. **Ensure you're using zsh shell**:
|
||
```bash
|
||
zsh
|
||
```
|
||
|
||
2. **Navigate to the GDB source directory**:
|
||
```bash
|
||
cd /home/crosstyan/third-party/gdb-14.2
|
||
```
|
||
|
||
3. **Clean any previous build artifacts**:
|
||
```bash
|
||
make distclean
|
||
```
|
||
|
||
4. **Configure GDB for cross-compilation with static linking**:
|
||
```bash
|
||
./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"
|
||
```
|
||
|
||
5. **Build only the gdbserver component**:
|
||
```bash
|
||
make -j$(nproc) all-gdbserver
|
||
```
|
||
|
||
6. **Verify the built binary**:
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
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:
|
||
```bash
|
||
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
|
||
|
||
```bash
|
||
/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
|
||
|
||
```c
|
||
#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:
|
||
|
||
```text
|
||
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](https://android.googlesource.com/kernel/msm/+/android-msm-flo-3.4-kitkat-mr0/arch/arm/include/asm/unistd.h#147) from Android source code.
|