From b4c559e7d48b57c609e96b6f8aadfbd8edd50c17 Mon Sep 17 00:00:00 2001 From: Guy Shimko Date: Wed, 4 Dec 2024 21:26:00 +0200 Subject: [PATCH] gdb with python support integration This commits enables gdb's python support. In order to make it work, we had to create a python fork with some patches to the buildsystem, and also had to patch gdb as well. --- Dockerfile | 7 ++++ Makefile | 14 ++----- src/build.sh | 87 +++++++++++++++++++++++++++++++++++----- src/download_packages.sh | 14 +++++-- src/gdb_static.patch | 70 -------------------------------- src/patch_gdb.sh | 57 -------------------------- 6 files changed, 96 insertions(+), 153 deletions(-) delete mode 100644 src/gdb_static.patch delete mode 100755 src/patch_gdb.sh diff --git a/Dockerfile b/Dockerfile index 25a5cf3..45686b9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,6 +2,9 @@ FROM ubuntu:24.04 # Install dependencies RUN apt update && apt install -y \ + bison \ + file \ + flex \ g++ \ g++-aarch64-linux-gnu \ g++-arm-linux-gnueabi \ @@ -14,10 +17,14 @@ RUN apt update && apt install -y \ gcc-mips-linux-gnu \ gcc-mipsel-linux-gnu \ gcc-powerpc-linux-gnu \ + git \ libncurses-dev \ m4 \ make \ patch \ + pkg-config \ + python3.12 \ + libpython3-dev \ texinfo \ wget \ xz-utils diff --git a/Makefile b/Makefile index 38f8a76..cc2ec48 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ ARCHS := x86_64 arm aarch64 powerpc mips mipsel TARGETS := $(addprefix build-, $(ARCHS)) PACK_TARGETS := $(addprefix pack-, $(ARCHS)) -.PHONY: clean help download_packages build patch-gdb build-docker-image $(TARGETS) $(PACK_TARGETS) +.PHONY: clean help download_packages build build-docker-image $(TARGETS) $(PACK_TARGETS) help: @echo "Usage:" @@ -32,21 +32,13 @@ build/download-packages.stamp: build/build-docker-image.stamp src/download_packa download-packages: build/download-packages.stamp -build/patch-gdb.stamp: build/build-docker-image.stamp src/gdb_static.patch build/download-packages.stamp - docker run --user $(shell id -u):$(shell id -g) \ - --rm --volume .:/app/gdb gdb-static env TERM=xterm-256color \ - /app/gdb/src/patch_gdb.sh /app/gdb/build/packages/gdb /app/gdb/src/gdb_static.patch - touch build/patch-gdb.stamp - -patch-gdb: build/patch-gdb.stamp - build: $(TARGETS) -$(TARGETS): build-%: download-packages patch-gdb build-docker-image +$(TARGETS): build-%: download-packages build-docker-image mkdir -p build docker run --user $(shell id -u):$(shell id -g) \ --rm --volume .:/app/gdb gdb-static env TERM=xterm-256color \ - /app/gdb/src/build.sh $* /app/gdb/build/ /app/gdb/src/gdb_static.patch + /app/gdb/src/build.sh $* /app/gdb/build/ /app/gdb/src pack: $(PACK_TARGETS) diff --git a/src/build.sh b/src/build.sh index 25f8f64..506510a 100755 --- a/src/build.sh +++ b/src/build.sh @@ -2,7 +2,7 @@ # Include utils library script_dir=$(dirname "$0") -. "$script_dir/utils.sh" +source "$script_dir/utils.sh" function set_compliation_variables() { # Set compilation variables such as which compiler to use. @@ -208,6 +208,64 @@ function build_ncurses() { popd > /dev/null } +function build_python() { + # Build python. + # + # Parameters: + # $1: python package directory + # $2: target architecture + # + # Echoes: + # The python build directory + # + # Returns: + # 0: success + # 1: failure + local python_dir="$1" + local target_arch="$2" + local python_lib_dir="$(realpath "$python_dir/build-$target_arch")" + + echo "$python_lib_dir" + mkdir -p "$python_lib_dir" + + # Having a python-config file is an indication that we successfully built python. + if [[ -f "$python_lib_dir/python-config" ]]; then + >&2 echo "Skipping build: libpython already built for $target_arch" + return 0 + fi + + pushd "$python_lib_dir" > /dev/null + >&2 fancy_title "Building python for $target_arch" + + export LINKFORSHARED=" " + export MODULE_BUILDTYPE="static" + export CONFIG_SITE="$python_dir/config.site-static" + >&2 CFLAGS="-static" LDFLAGS="-static" ../configure \ + --prefix=$(realpath .) \ + --disable-test-modules \ + --with-ensurepip=no \ + --without-decimal-contextvar \ + --build=x86_64-pc-linux-gnu \ + --host=$HOST \ + --with-build-python=/usr/bin/python3.12 \ + --disable-ipv6 \ + --disable-shared + + >&2 make -j $(nproc) + if [[ $? -ne 0 ]]; then + return 1 + fi + + # Install python (in build dir using the prefix set above), in order to have a bash (for cross-compilation) python3-config that works. + >&2 make install + if [[ $? -ne 0 ]]; then + return 1 + fi + + >&2 fancy_title "Finished building python for $target_arch" + popd > /dev/null +} + function build_libmpfr() { # Build libmpfr. # @@ -298,7 +356,8 @@ function build_gdb() { >&2 fancy_title "Building gdb for $target_arch" - ../configure --enable-static --enable-tui --with-static-standard-libraries --disable-inprocess-agent \ + ../configure -C --enable-static --with-static-standard-libraries --disable-inprocess-agent \ + --enable-tui --with-python=/app/gdb/build/packages/cpython-static/build-$target_arch/bin/python3-config \ "--with-libiconv-prefix=$libiconv_prefix" --with-libiconv-type=static \ "--with-gmp=$libgmp_prefix" \ "--with-mpfr=$libmpfr_prefix" \ @@ -395,9 +454,11 @@ function build_gdb_with_dependencies() { # Parameters: # $1: target architecture # $2: build directory + # $3: src directory local target_arch="$1" local build_dir="$2" + local source_dir="$3" local packages_dir="$build_dir/packages" local artifacts_dir="$build_dir/artifacts" @@ -427,15 +488,19 @@ function build_gdb_with_dependencies() { if [[ $? -ne 0 ]]; then return 1 fi - set_ncurses_link_variables "$ncursesw_build_dir" - build_and_install_gdb "$packages_dir/gdb" \ - "$iconv_build_dir/lib/.libs/" \ - "$gmp_build_dir/.libs/" \ - "$mpfr_build_dir/src/.libs/" \ - "$artifacts_dir" \ - "$target_arch" + python_build_dir="$(build_python "$packages_dir/cpython-static" "$target_arch")" + if [[ $? -ne 0 ]]; then + return 1 + fi + + build_and_install_gdb "$packages_dir/binutils-gdb" \ + "$iconv_build_dir/lib/.libs/" \ + "$gmp_build_dir/.libs/" \ + "$mpfr_build_dir/src/.libs/" \ + "$artifacts_dir" \ + "$target_arch" if [[ $? -ne 0 ]]; then return 1 fi @@ -443,11 +508,11 @@ function build_gdb_with_dependencies() { function main() { if [[ $# -ne 3 ]]; then - >&2 echo "Usage: $0 " + >&2 echo "Usage: $0 " exit 1 fi - build_gdb_with_dependencies "$1" "$2" + build_gdb_with_dependencies "$1" "$2" "$3" if [[ $? -ne 0 ]]; then >&2 echo "Error: failed to build gdb with dependencies" exit 1 diff --git a/src/download_packages.sh b/src/download_packages.sh index 8fb689e..9327902 100755 --- a/src/download_packages.sh +++ b/src/download_packages.sh @@ -5,11 +5,10 @@ script_dir=$(dirname "$0") . "$script_dir/utils.sh" # List of package URLs to download -PACKAGE_URLS=( +SOURCE_URLS=( "https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.17.tar.gz" "https://ftp.gnu.org/pub/gnu/gmp/gmp-6.3.0.tar.xz" "https://ftp.gnu.org/pub/gnu/mpfr/mpfr-4.2.1.tar.xz" - "https://ftp.gnu.org/gnu/gdb/gdb-15.2.tar.xz" "https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.5.tar.gz" ) @@ -188,7 +187,7 @@ function download_gdb_packages() { fancy_title "Starting download of GDB packages" - for url in "${PACKAGE_URLS[@]}"; do + for url in "${SOURCE_URLS[@]}"; do package_dir=$(package_url_to_dir "$url") download_and_extract_package "$url" "$package_dir" & download_pids+=($!) @@ -202,8 +201,15 @@ function download_gdb_packages() { fi done - fancy_title "Finished downloading GDB packages" + if [[ ! -d gdb-static ]]; then + git clone https://github.com/guyush1/binutils-gdb.git --single-branch --branch gdb-static + fi + if [[ ! -d python3.12-static ]]; then + git clone https://github.com/guyush1/cpython-static.git --single-branch --branch python3.12-static + fi + + fancy_title "Finished downloading GDB packages" popd } diff --git a/src/gdb_static.patch b/src/gdb_static.patch deleted file mode 100644 index a814e5a..0000000 --- a/src/gdb_static.patch +++ /dev/null @@ -1,70 +0,0 @@ -diff --git a/Makefile.in b/Makefile.in -index f12c251f9c8..eed512b2d18 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -31593,7 +31593,7 @@ configure-readline: - $$s/$$module_srcdir/configure \ - --srcdir=$${topdir}/$$module_srcdir \ - $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ -- --target=${target_alias} \ -+ --target=${target_alias} --enable-static \ - || exit 1 - @endif readline - -@@ -40793,7 +40793,7 @@ configure-libcc1: - $$s/$$module_srcdir/configure \ - --srcdir=$${topdir}/$$module_srcdir \ - $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \ -- --target=${target_alias} --enable-shared \ -+ --target=${target_alias} --enable-static --disable-shared \ - || exit 1 - @endif libcc1 - -diff --git a/configure b/configure -index 6466b97f3ec..2ab23dcb81e 100755 ---- a/configure -+++ b/configure -@@ -9398,7 +9398,7 @@ case " $configdirs " in - *" lto-plugin "* | *" libcc1 "* | *" gdbserver "*) - # When these are to be built as shared libraries, the same applies to - # libiberty. -- extra_host_libiberty_configure_flags=--enable-shared -+ extra_host_libiberty_configure_flags="--enable-static --disable-shared" - ;; - esac - -diff --git a/gdb/Makefile.in b/gdb/Makefile.in -index 84bc54b303e..c81269ced78 100644 ---- a/gdb/Makefile.in -+++ b/gdb/Makefile.in -@@ -148,7 +148,7 @@ LIBTOOL = @LIBTOOL@ - # Set this up with gcc if you have gnu ld and the loader will print out - # line numbers for undefined references. - #CC_LD = g++ -static --CC_LD = $(LIBTOOL) $(SILENT_FLAG) --mode=link $(CXX) $(CXX_DIALECT) -+CC_LD = $(LIBTOOL) $(SILENT_FLAG) --mode=link $(CXX) -all-static $(CXX_DIALECT) - - # Where is our "include" directory? Typically $(srcdir)/../include. - # This is essentially the header file directory for the library -diff --git a/gdbserver/Makefile.in b/gdbserver/Makefile.in -index 6148ccf9121..2a9c9720d1a 100644 ---- a/gdbserver/Makefile.in -+++ b/gdbserver/Makefile.in -@@ -83,7 +83,7 @@ COMPILE = $(ECHO_CXX) $(COMPILE.pre) $(INTERNAL_CFLAGS) $(INCLUDE_SERVER_H) \ - # Set this up with gcc if you have gnu ld and the loader will print out - # line numbers for undefinded refs. - #CC_LD = g++ -static --CC_LD = $(CXX) $(CXX_DIALECT) -+CC_LD = $(CXX) -static $(CXX_DIALECT) - - # Where is the "include" directory? Traditionally ../include or ./include - INCLUDE_DIR = ${srcdir}/../include -@@ -405,7 +405,7 @@ IPA_LIB = libinproctrace.so - - $(IPA_LIB): $(sort $(IPA_OBJS)) ${CDEPS} - $(SILENCE) rm -f $(IPA_LIB) -- $(ECHO_CXXLD) $(CC_LD) -shared -fPIC -Wl,--soname=$(IPA_LIB) \ -+ $(ECHO_CXXLD) $(CC_LD) -static -fPIC -Wl,--soname=$(IPA_LIB) \ - -Wl,--no-undefined $(INTERNAL_CFLAGS) $(INTERNAL_LDFLAGS) \ - $(CXXFLAGS) \ - -o $(IPA_LIB) ${IPA_OBJS} $(LIBIBERTY_FOR_SHLIB) -ldl -pthread diff --git a/src/patch_gdb.sh b/src/patch_gdb.sh deleted file mode 100755 index 164dcc6..0000000 --- a/src/patch_gdb.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash - -# Include utils library -script_dir=$(dirname "$0") -. "$script_dir/utils.sh" - -function apply_patch() { - # Apply a patch to a directory. - # - # Parameters: - # $1: directory - # $2: path of patch - # - # Returns: - # 0: success - # 1: failure - - local dir="$1" - local patch="$(realpath "$2")" - - pushd "$dir" > /dev/null - if [[ $? -ne 0 ]]; then - return 1 - fi - - # Check if the patch was already applied - if ! patch -p1 --dry-run < "$patch" &>/dev/null; then - >&2 echo "Error: patch already applied" - popd > /dev/null - return 1 - fi - - patch -p1 < "$patch" - if [[ $? -ne 0 ]]; then - popd > /dev/null - return 1 - fi - - popd > /dev/null -} - -function main() { - if [[ $# -ne 2 ]]; then - >&2 echo "Usage: $0 " - exit 1 - fi - - fancy_title "Applying GDB patch" - apply_patch "$1" "$2" - if [[ $? -ne 0 ]]; then - >&2 echo "Error: failed to apply GDB patch" - exit 1 - fi - fancy_title "Finished applying GDB patch" -} - -main "$@"