[gdb] Implement MiniDebugInfo F-18 Feature consumer (Alexander Larsson, BZ 834068).

Jan Kratochvil jankratochvil at fedoraproject.org
Thu Jul 5 21:18:29 UTC 2012


commit c501c4bdb1f4b298f507ad9a7f1c5bf0596089f8
Author: Jan Kratochvil <jan.kratochvil at redhat.com>
Date:   Thu Jul 5 23:18:24 2012 +0200

    Implement MiniDebugInfo F-18 Feature consumer (Alexander Larsson, BZ 834068).

 gdb-minidebuginfo.patch | 1040 +++++++++++++++++++++++++++++++++++++++++++++++
 gdb.spec                |   10 +-
 2 files changed, 1049 insertions(+), 1 deletions(-)
---
diff --git a/gdb-minidebuginfo.patch b/gdb-minidebuginfo.patch
new file mode 100644
index 0000000..d60a66b
--- /dev/null
+++ b/gdb-minidebuginfo.patch
@@ -0,0 +1,1040 @@
+http://fedoraproject.org/wiki/Features/MiniDebugInfo
+https://bugzilla.redhat.com/show_bug.cgi?id=834068
+
+Patch by Alexander Larsson.
+Review/modifications and testfile by Jan Kratochvil.
+
+Index: gdb-7.4.50.20120703/gdb/Makefile.in
+===================================================================
+--- gdb-7.4.50.20120703.orig/gdb/Makefile.in	2012-07-05 22:47:39.000000000 +0200
++++ gdb-7.4.50.20120703/gdb/Makefile.in	2012-07-05 22:47:45.475509372 +0200
+@@ -151,6 +151,9 @@ READLINE_CFLAGS = @READLINE_CFLAGS@
+ # Where is expat?  This will be empty if expat was not available.
+ LIBEXPAT = @LIBEXPAT@
+ 
++# Where is lzma?  This will be empty if lzma was not available.
++LIBLZMA = @LIBLZMA@
++
+ WARN_CFLAGS = @WARN_CFLAGS@
+ WERROR_CFLAGS = @WERROR_CFLAGS@
+ GDB_WARN_CFLAGS = $(WARN_CFLAGS)
+@@ -467,7 +470,7 @@ INTERNAL_LDFLAGS = $(CFLAGS) $(GLOBAL_CF
+ # LIBIBERTY appears twice on purpose.
+ CLIBS = $(SIM) $(READLINE) $(OPCODES) $(BFD) $(INTL) $(LIBIBERTY) $(LIBDECNUMBER) \
+ 	$(XM_CLIBS) $(NAT_CLIBS) $(GDBTKLIBS) @LIBS@ @PYTHON_LIBS@ \
+-	$(LIBEXPAT) \
++	$(LIBEXPAT) $(LIBLZMA) \
+ 	$(LIBIBERTY) $(WIN32LIBS) $(LIBGNU)
+ CDEPS = $(XM_CDEPS) $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE_DEPS) \
+ 	$(OPCODES) $(INTL_DEPS) $(LIBIBERTY) $(CONFIG_DEPS) $(LIBGNU)
+Index: gdb-7.4.50.20120703/gdb/config.in
+===================================================================
+--- gdb-7.4.50.20120703.orig/gdb/config.in	2012-07-05 22:47:40.000000000 +0200
++++ gdb-7.4.50.20120703/gdb/config.in	2012-07-05 22:47:45.476509371 +0200
+@@ -198,6 +198,9 @@
+ /* Define to 1 if you have the `libiconvlist' function. */
+ #undef HAVE_LIBICONVLIST
+ 
++/* Define if you have the lzma library. */
++#undef HAVE_LIBLZMA
++
+ /* Define to 1 if you have the `m' library (-lm). */
+ #undef HAVE_LIBM
+ 
+Index: gdb-7.4.50.20120703/gdb/configure
+===================================================================
+--- gdb-7.4.50.20120703.orig/gdb/configure	2012-07-05 22:47:40.000000000 +0200
++++ gdb-7.4.50.20120703/gdb/configure	2012-07-05 22:47:45.485509363 +0200
+@@ -641,6 +641,9 @@ TCL_VERSION
+ WIN32LDAPP
+ GUI_CFLAGS_X
+ LIBGUI
++LTLIBLZMA
++LIBLZMA
++HAVE_LIBLZMA
+ WIN32LIBS
+ SER_HARDWIRE
+ WERROR_CFLAGS
+@@ -813,6 +816,8 @@ with_system_gdbinit
+ enable_werror
+ enable_build_warnings
+ enable_gdb_build_warnings
++with_lzma
++with_liblzma_prefix
+ with_tcl
+ with_tk
+ with_x
+@@ -1532,6 +1537,9 @@ Optional Packages:
+   --with-sysroot[=DIR]    search for usr/lib et al within DIR
+   --with-system-gdbinit=PATH
+                           automatically load a system-wide gdbinit file
++  --with-lzma             support lzma compression (auto/yes/no)
++  --with-liblzma-prefix[=DIR]  search for liblzma in DIR/include and DIR/lib
++  --without-liblzma-prefix     don't search for liblzma in includedir and libdir
+   --with-tcl              directory containing tcl configuration (tclConfig.sh)
+   --with-tk               directory containing tk configuration (tkConfig.sh)
+   --with-x                use the X Window System
+@@ -13151,6 +13159,492 @@ LIBS=$OLD_LIBS
+ # Add any host-specific objects to GDB.
+ CONFIG_OBS="${CONFIG_OBS} ${gdb_host_obs}"
+ 
++# If building on ELF, look for lzma support for embedded compressed debug info.
++if test $gdb_cv_var_elf = yes; then
++
++# Check whether --with-lzma was given.
++if test "${with_lzma+set}" = set; then :
++  withval=$with_lzma;
++else
++  with_lzma=auto
++fi
++
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use lzma" >&5
++$as_echo_n "checking whether to use lzma... " >&6; }
++  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_lzma" >&5
++$as_echo "$with_lzma" >&6; }
++
++  if test "${with_lzma}" != no; then
++
++
++
++
++
++
++
++
++    use_additional=yes
++
++  acl_save_prefix="$prefix"
++  prefix="$acl_final_prefix"
++  acl_save_exec_prefix="$exec_prefix"
++  exec_prefix="$acl_final_exec_prefix"
++
++    eval additional_includedir=\"$includedir\"
++    eval additional_libdir=\"$libdir\"
++
++  exec_prefix="$acl_save_exec_prefix"
++  prefix="$acl_save_prefix"
++
++
++# Check whether --with-liblzma-prefix was given.
++if test "${with_liblzma_prefix+set}" = set; then :
++  withval=$with_liblzma_prefix;
++    if test "X$withval" = "Xno"; then
++      use_additional=no
++    else
++      if test "X$withval" = "X"; then
++
++  acl_save_prefix="$prefix"
++  prefix="$acl_final_prefix"
++  acl_save_exec_prefix="$exec_prefix"
++  exec_prefix="$acl_final_exec_prefix"
++
++          eval additional_includedir=\"$includedir\"
++          eval additional_libdir=\"$libdir\"
++
++  exec_prefix="$acl_save_exec_prefix"
++  prefix="$acl_save_prefix"
++
++      else
++        additional_includedir="$withval/include"
++        additional_libdir="$withval/lib"
++      fi
++    fi
++
++fi
++
++      LIBLZMA=
++  LTLIBLZMA=
++  INCLZMA=
++  rpathdirs=
++  ltrpathdirs=
++  names_already_handled=
++  names_next_round='lzma '
++  while test -n "$names_next_round"; do
++    names_this_round="$names_next_round"
++    names_next_round=
++    for name in $names_this_round; do
++      already_handled=
++      for n in $names_already_handled; do
++        if test "$n" = "$name"; then
++          already_handled=yes
++          break
++        fi
++      done
++      if test -z "$already_handled"; then
++        names_already_handled="$names_already_handled $name"
++                        uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
++        eval value=\"\$HAVE_LIB$uppername\"
++        if test -n "$value"; then
++          if test "$value" = yes; then
++            eval value=\"\$LIB$uppername\"
++            test -z "$value" || LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$value"
++            eval value=\"\$LTLIB$uppername\"
++            test -z "$value" || LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }$value"
++          else
++                                    :
++          fi
++        else
++                              found_dir=
++          found_la=
++          found_so=
++          found_a=
++          if test $use_additional = yes; then
++            if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then
++              found_dir="$additional_libdir"
++              found_so="$additional_libdir/lib$name.$shlibext"
++              if test -f "$additional_libdir/lib$name.la"; then
++                found_la="$additional_libdir/lib$name.la"
++              fi
++            else
++              if test -f "$additional_libdir/lib$name.$libext"; then
++                found_dir="$additional_libdir"
++                found_a="$additional_libdir/lib$name.$libext"
++                if test -f "$additional_libdir/lib$name.la"; then
++                  found_la="$additional_libdir/lib$name.la"
++                fi
++              fi
++            fi
++          fi
++          if test "X$found_dir" = "X"; then
++            for x in $LDFLAGS $LTLIBLZMA; do
++
++  acl_save_prefix="$prefix"
++  prefix="$acl_final_prefix"
++  acl_save_exec_prefix="$exec_prefix"
++  exec_prefix="$acl_final_exec_prefix"
++  eval x=\"$x\"
++  exec_prefix="$acl_save_exec_prefix"
++  prefix="$acl_save_prefix"
++
++              case "$x" in
++                -L*)
++                  dir=`echo "X$x" | sed -e 's/^X-L//'`
++                  if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then
++                    found_dir="$dir"
++                    found_so="$dir/lib$name.$shlibext"
++                    if test -f "$dir/lib$name.la"; then
++                      found_la="$dir/lib$name.la"
++                    fi
++                  else
++                    if test -f "$dir/lib$name.$libext"; then
++                      found_dir="$dir"
++                      found_a="$dir/lib$name.$libext"
++                      if test -f "$dir/lib$name.la"; then
++                        found_la="$dir/lib$name.la"
++                      fi
++                    fi
++                  fi
++                  ;;
++              esac
++              if test "X$found_dir" != "X"; then
++                break
++              fi
++            done
++          fi
++          if test "X$found_dir" != "X"; then
++                        LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }-L$found_dir -l$name"
++            if test "X$found_so" != "X"; then
++                                                        if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then
++                                LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$found_so"
++              else
++                                                                                haveit=
++                for x in $ltrpathdirs; do
++                  if test "X$x" = "X$found_dir"; then
++                    haveit=yes
++                    break
++                  fi
++                done
++                if test -z "$haveit"; then
++                  ltrpathdirs="$ltrpathdirs $found_dir"
++                fi
++                                if test "$hardcode_direct" = yes; then
++                                                      LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$found_so"
++                else
++                  if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then
++                                                            LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$found_so"
++                                                            haveit=
++                    for x in $rpathdirs; do
++                      if test "X$x" = "X$found_dir"; then
++                        haveit=yes
++                        break
++                      fi
++                    done
++                    if test -z "$haveit"; then
++                      rpathdirs="$rpathdirs $found_dir"
++                    fi
++                  else
++                                                                                haveit=
++                    for x in $LDFLAGS $LIBLZMA; do
++
++  acl_save_prefix="$prefix"
++  prefix="$acl_final_prefix"
++  acl_save_exec_prefix="$exec_prefix"
++  exec_prefix="$acl_final_exec_prefix"
++  eval x=\"$x\"
++  exec_prefix="$acl_save_exec_prefix"
++  prefix="$acl_save_prefix"
++
++                      if test "X$x" = "X-L$found_dir"; then
++                        haveit=yes
++                        break
++                      fi
++                    done
++                    if test -z "$haveit"; then
++                      LIBLZMA="${LIBLZMA}${LIBLZMA:+ }-L$found_dir"
++                    fi
++                    if test "$hardcode_minus_L" != no; then
++                                                                                        LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$found_so"
++                    else
++                                                                                                                                                                                LIBLZMA="${LIBLZMA}${LIBLZMA:+ }-l$name"
++                    fi
++                  fi
++                fi
++              fi
++            else
++              if test "X$found_a" != "X"; then
++                                LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$found_a"
++              else
++                                                LIBLZMA="${LIBLZMA}${LIBLZMA:+ }-L$found_dir -l$name"
++              fi
++            fi
++                        additional_includedir=
++            case "$found_dir" in
++              */lib | */lib/)
++                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'`
++                additional_includedir="$basedir/include"
++                ;;
++            esac
++            if test "X$additional_includedir" != "X"; then
++                                                                                                                if test "X$additional_includedir" != "X/usr/include"; then
++                haveit=
++                if test "X$additional_includedir" = "X/usr/local/include"; then
++                  if test -n "$GCC"; then
++                    case $host_os in
++                      linux*) haveit=yes;;
++                    esac
++                  fi
++                fi
++                if test -z "$haveit"; then
++                  for x in $CPPFLAGS $INCLZMA; do
++
++  acl_save_prefix="$prefix"
++  prefix="$acl_final_prefix"
++  acl_save_exec_prefix="$exec_prefix"
++  exec_prefix="$acl_final_exec_prefix"
++  eval x=\"$x\"
++  exec_prefix="$acl_save_exec_prefix"
++  prefix="$acl_save_prefix"
++
++                    if test "X$x" = "X-I$additional_includedir"; then
++                      haveit=yes
++                      break
++                    fi
++                  done
++                  if test -z "$haveit"; then
++                    if test -d "$additional_includedir"; then
++                                            INCLZMA="${INCLZMA}${INCLZMA:+ }-I$additional_includedir"
++                    fi
++                  fi
++                fi
++              fi
++            fi
++                        if test -n "$found_la"; then
++                                                        save_libdir="$libdir"
++              case "$found_la" in
++                */* | *\\*) . "$found_la" ;;
++                *) . "./$found_la" ;;
++              esac
++              libdir="$save_libdir"
++                            for dep in $dependency_libs; do
++                case "$dep" in
++                  -L*)
++                    additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
++                                                                                                                                                                if test "X$additional_libdir" != "X/usr/lib"; then
++                      haveit=
++                      if test "X$additional_libdir" = "X/usr/local/lib"; then
++                        if test -n "$GCC"; then
++                          case $host_os in
++                            linux*) haveit=yes;;
++                          esac
++                        fi
++                      fi
++                      if test -z "$haveit"; then
++                        haveit=
++                        for x in $LDFLAGS $LIBLZMA; do
++
++  acl_save_prefix="$prefix"
++  prefix="$acl_final_prefix"
++  acl_save_exec_prefix="$exec_prefix"
++  exec_prefix="$acl_final_exec_prefix"
++  eval x=\"$x\"
++  exec_prefix="$acl_save_exec_prefix"
++  prefix="$acl_save_prefix"
++
++                          if test "X$x" = "X-L$additional_libdir"; then
++                            haveit=yes
++                            break
++                          fi
++                        done
++                        if test -z "$haveit"; then
++                          if test -d "$additional_libdir"; then
++                                                        LIBLZMA="${LIBLZMA}${LIBLZMA:+ }-L$additional_libdir"
++                          fi
++                        fi
++                        haveit=
++                        for x in $LDFLAGS $LTLIBLZMA; do
++
++  acl_save_prefix="$prefix"
++  prefix="$acl_final_prefix"
++  acl_save_exec_prefix="$exec_prefix"
++  exec_prefix="$acl_final_exec_prefix"
++  eval x=\"$x\"
++  exec_prefix="$acl_save_exec_prefix"
++  prefix="$acl_save_prefix"
++
++                          if test "X$x" = "X-L$additional_libdir"; then
++                            haveit=yes
++                            break
++                          fi
++                        done
++                        if test -z "$haveit"; then
++                          if test -d "$additional_libdir"; then
++                                                        LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }-L$additional_libdir"
++                          fi
++                        fi
++                      fi
++                    fi
++                    ;;
++                  -R*)
++                    dir=`echo "X$dep" | sed -e 's/^X-R//'`
++                    if test "$enable_rpath" != no; then
++                                                                  haveit=
++                      for x in $rpathdirs; do
++                        if test "X$x" = "X$dir"; then
++                          haveit=yes
++                          break
++                        fi
++                      done
++                      if test -z "$haveit"; then
++                        rpathdirs="$rpathdirs $dir"
++                      fi
++                                                                  haveit=
++                      for x in $ltrpathdirs; do
++                        if test "X$x" = "X$dir"; then
++                          haveit=yes
++                          break
++                        fi
++                      done
++                      if test -z "$haveit"; then
++                        ltrpathdirs="$ltrpathdirs $dir"
++                      fi
++                    fi
++                    ;;
++                  -l*)
++                                        names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
++                    ;;
++                  *.la)
++                                                                                names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
++                    ;;
++                  *)
++                                        LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$dep"
++                    LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }$dep"
++                    ;;
++                esac
++              done
++            fi
++          else
++                                                            LIBLZMA="${LIBLZMA}${LIBLZMA:+ }-l$name"
++            LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }-l$name"
++          fi
++        fi
++      fi
++    done
++  done
++  if test "X$rpathdirs" != "X"; then
++    if test -n "$hardcode_libdir_separator"; then
++                        alldirs=
++      for found_dir in $rpathdirs; do
++        alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir"
++      done
++            acl_save_libdir="$libdir"
++      libdir="$alldirs"
++      eval flag=\"$hardcode_libdir_flag_spec\"
++      libdir="$acl_save_libdir"
++      LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$flag"
++    else
++            for found_dir in $rpathdirs; do
++        acl_save_libdir="$libdir"
++        libdir="$found_dir"
++        eval flag=\"$hardcode_libdir_flag_spec\"
++        libdir="$acl_save_libdir"
++        LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$flag"
++      done
++    fi
++  fi
++  if test "X$ltrpathdirs" != "X"; then
++            for found_dir in $ltrpathdirs; do
++      LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }-R$found_dir"
++    done
++  fi
++
++
++        ac_save_CPPFLAGS="$CPPFLAGS"
++
++  for element in $INCLZMA; do
++    haveit=
++    for x in $CPPFLAGS; do
++
++  acl_save_prefix="$prefix"
++  prefix="$acl_final_prefix"
++  acl_save_exec_prefix="$exec_prefix"
++  exec_prefix="$acl_final_exec_prefix"
++  eval x=\"$x\"
++  exec_prefix="$acl_save_exec_prefix"
++  prefix="$acl_save_prefix"
++
++      if test "X$x" = "X$element"; then
++        haveit=yes
++        break
++      fi
++    done
++    if test -z "$haveit"; then
++      CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element"
++    fi
++  done
++
++
++  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblzma" >&5
++$as_echo_n "checking for liblzma... " >&6; }
++if test "${ac_cv_liblzma+set}" = set; then :
++  $as_echo_n "(cached) " >&6
++else
++
++    ac_save_LIBS="$LIBS"
++    LIBS="$LIBS $LIBLZMA"
++    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h.  */
++#include "lzma.h"
++int
++main ()
++{
++lzma_mf_is_supported (LZMA_MF_HC3);
++  ;
++  return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++  ac_cv_liblzma=yes
++else
++  ac_cv_liblzma=no
++fi
++rm -f core conftest.err conftest.$ac_objext \
++    conftest$ac_exeext conftest.$ac_ext
++    LIBS="$ac_save_LIBS"
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_liblzma" >&5
++$as_echo "$ac_cv_liblzma" >&6; }
++  if test "$ac_cv_liblzma" = yes; then
++    HAVE_LIBLZMA=yes
++
++$as_echo "#define HAVE_LIBLZMA 1" >>confdefs.h
++
++    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with liblzma" >&5
++$as_echo_n "checking how to link with liblzma... " >&6; }
++    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBLZMA" >&5
++$as_echo "$LIBLZMA" >&6; }
++  else
++    HAVE_LIBLZMA=no
++            CPPFLAGS="$ac_save_CPPFLAGS"
++    LIBLZMA=
++    LTLIBLZMA=
++  fi
++
++
++
++
++
++
++    if test "$HAVE_LIBLZMA" != yes; then
++      if test "$with_lzma" = yes; then
++        as_fn_error "missing liblzma for --with-lzma" "$LINENO" 5
++      fi
++    fi
++  fi
++fi
++
+ LIBGUI="../libgui/src/libgui.a"
+ GUI_CFLAGS_X="-I${srcdir}/../libgui/src"
+ 
+Index: gdb-7.4.50.20120703/gdb/configure.ac
+===================================================================
+--- gdb-7.4.50.20120703.orig/gdb/configure.ac	2012-07-05 22:47:40.000000000 +0200
++++ gdb-7.4.50.20120703/gdb/configure.ac	2012-07-05 22:47:45.487509361 +0200
+@@ -2196,6 +2196,25 @@ LIBS=$OLD_LIBS
+ # Add any host-specific objects to GDB.
+ CONFIG_OBS="${CONFIG_OBS} ${gdb_host_obs}"
+ 
++# If building on ELF, look for lzma support for embedded compressed debug info.
++if test $gdb_cv_var_elf = yes; then
++  AC_ARG_WITH(lzma,
++    AS_HELP_STRING([--with-lzma], [support lzma compression (auto/yes/no)]),
++    [], [with_lzma=auto])
++  AC_MSG_CHECKING([whether to use lzma])
++  AC_MSG_RESULT([$with_lzma])
++
++  if test "${with_lzma}" != no; then
++    AC_LIB_HAVE_LINKFLAGS([lzma], [], [#include "lzma.h"],
++			  [lzma_mf_is_supported (LZMA_MF_HC3);])
++    if test "$HAVE_LIBLZMA" != yes; then
++      if test "$with_lzma" = yes; then
++        AC_MSG_ERROR([missing liblzma for --with-lzma])
++      fi
++    fi
++  fi
++fi
++
+ LIBGUI="../libgui/src/libgui.a"
+ GUI_CFLAGS_X="-I${srcdir}/../libgui/src"
+ AC_SUBST(LIBGUI)
+Index: gdb-7.4.50.20120703/gdb/elfread.c
+===================================================================
+--- gdb-7.4.50.20120703.orig/gdb/elfread.c	2012-07-05 22:47:39.000000000 +0200
++++ gdb-7.4.50.20120703/gdb/elfread.c	2012-07-05 22:49:13.200427038 +0200
+@@ -51,6 +51,10 @@
+ #include "observer.h"
+ #include "elf/external.h"
+ #include <sys/stat.h>
++#include "gdbcore.h"
++#ifdef HAVE_LIBLZMA
++# include <lzma.h>
++#endif
+ 
+ extern void _initialize_elfread (void);
+ 
+@@ -2210,6 +2214,262 @@ find_separate_debug_file_by_buildid (str
+   return NULL;
+ }
+ 
++#ifdef HAVE_LIBLZMA
++
++/* Custom lzma_allocator.alloc so they use the gdb ones.  */
++
++static void *
++alloc_lzma (void *opaque, size_t nmemb, size_t size)
++{
++  return xmalloc (nmemb * size);
++}
++
++/* Custom lzma_allocator.free so they use the gdb ones.  */
++
++static void
++free_lzma (void *opaque, void *ptr)
++{
++  xfree (ptr);
++}
++
++/* It cannot be const due to the lzma library function prototypes.  */
++
++static lzma_allocator gdb_lzma_allocator = { alloc_lzma, free_lzma, NULL};
++
++/* Custom bfd_openr_iovec implementation to read compressed data from a
++   section. This keeps only the last decompressed block in memory to
++   allow larger data without using to much memory.  */
++
++struct lzma_stream
++{
++  /* Section of input BFD we are decoding data from.  */
++  asection *section;
++
++  /* lzma library decompression state.  */
++  lzma_index *index;
++
++  /* Currently decoded block.  */
++  bfd_size_type data_start;
++  bfd_size_type data_end;
++  gdb_byte *data;
++};
++
++/* bfd_openr_iovec OPEN_P implementation for
++   find_separate_debug_file_in_section.  OPEN_CLOSURE is 'asection *' of the
++   section to decompress.
++
++   Return 'struct lzma_stream *' must be freed by caller by xfree, together
++   with its INDEX lzma data.  */
++
++static void *
++lzma_open (struct bfd *nbfd, void *open_closure)
++{
++  asection *section = open_closure;
++  bfd_size_type size, offset;
++  lzma_stream_flags options;
++  gdb_byte footer[LZMA_STREAM_HEADER_SIZE];
++  gdb_byte *indexdata;
++  lzma_index *index;
++  int ret;
++  uint64_t memlimit = UINT64_MAX;
++  struct lzma_stream *lstream;
++  size_t pos;
++
++  size = bfd_get_section_size (section);
++  offset = section->filepos + size - LZMA_STREAM_HEADER_SIZE;
++  if (size < LZMA_STREAM_HEADER_SIZE
++      || bfd_seek (section->owner, offset, SEEK_SET) != 0
++      || bfd_bread (footer, LZMA_STREAM_HEADER_SIZE, section->owner)
++         != LZMA_STREAM_HEADER_SIZE
++      || lzma_stream_footer_decode (&options, footer) != LZMA_OK
++      || offset < options.backward_size)
++    {
++      bfd_set_error (bfd_error_wrong_format);
++      return NULL;
++    }
++
++  offset -= options.backward_size;
++  indexdata = xmalloc (options.backward_size);
++  index = NULL;
++  pos = 0;
++  if (bfd_seek (section->owner, offset, SEEK_SET) != 0
++      || bfd_bread (indexdata, options.backward_size, section->owner)
++         != options.backward_size
++      || lzma_index_buffer_decode (&index, &memlimit, &gdb_lzma_allocator,
++				   indexdata, &pos, options.backward_size)
++         != LZMA_OK
++      || lzma_index_size (index) != options.backward_size)
++    {
++      xfree (indexdata);
++      bfd_set_error (bfd_error_wrong_format);
++      return NULL;
++    }
++  xfree (indexdata);
++
++  lstream = xzalloc (sizeof (struct lzma_stream));
++  lstream->section = section;
++  lstream->index = index;
++
++  return lstream;
++}
++
++/* bfd_openr_iovec PREAD_P implementation for
++   find_separate_debug_file_in_section.  Passed STREAM
++   is 'struct lzma_stream *'.  */
++
++static file_ptr
++lzma_pread (struct bfd *nbfd, void *stream, void *buf, file_ptr nbytes,
++	    file_ptr offset)
++{
++  struct lzma_stream *lstream = stream;
++  bfd_size_type chunk_size;
++  lzma_index_iter iter;
++  gdb_byte *compressed, *uncompressed;
++  file_ptr block_offset;
++  lzma_filter filters[LZMA_FILTERS_MAX + 1];
++  lzma_block block;
++  size_t compressed_pos, uncompressed_pos;
++  file_ptr res;
++
++  res = 0;
++  while (nbytes > 0)
++    {
++      if (lstream->data == NULL
++	  || lstream->data_start > offset || offset >= lstream->data_end)
++	{
++	  asection *section = lstream->section;
++
++	  lzma_index_iter_init (&iter, lstream->index);
++	  if (lzma_index_iter_locate (&iter, offset))
++	    break;
++
++	  compressed = xmalloc (iter.block.total_size);
++	  block_offset = section->filepos + iter.block.compressed_file_offset;
++	  if (bfd_seek (section->owner, block_offset, SEEK_SET) != 0
++	      || bfd_bread (compressed, iter.block.total_size, section->owner)
++		 != iter.block.total_size)
++	    {
++	      xfree (compressed);
++	      break;
++	    }
++
++	  uncompressed = xmalloc (iter.block.uncompressed_size);
++
++	  memset (&block, 0, sizeof (block));
++	  block.filters = filters;
++	  block.header_size = lzma_block_header_size_decode (compressed[0]);
++	  if (lzma_block_header_decode (&block, &gdb_lzma_allocator, compressed)
++	      != LZMA_OK)
++	    {
++	      xfree (compressed);
++	      xfree (uncompressed);
++	      break;
++	    }
++
++	  compressed_pos = block.header_size;
++	  uncompressed_pos = 0;
++	  if (lzma_block_buffer_decode (&block, &gdb_lzma_allocator,
++					compressed, &compressed_pos,
++					iter.block.total_size,
++					uncompressed, &uncompressed_pos,
++					iter.block.uncompressed_size)
++	      != LZMA_OK)
++	    {
++	      xfree (compressed);
++	      xfree (uncompressed);
++	      break;
++	    }
++
++	  xfree (compressed);
++
++	  xfree (lstream->data);
++	  lstream->data = uncompressed;
++	  lstream->data_start = iter.block.uncompressed_file_offset;
++	  lstream->data_end = (iter.block.uncompressed_file_offset
++			       + iter.block.uncompressed_size);
++	}
++
++      chunk_size = min (nbytes, lstream->data_end - offset);
++      memcpy (buf, lstream->data + offset - lstream->data_start, chunk_size);
++      buf = (gdb_byte *) buf + chunk_size;
++      offset += chunk_size;
++      nbytes -= chunk_size;
++      res += chunk_size;
++    }
++
++  return res;
++}
++
++/* bfd_openr_iovec CLOSE_P implementation for
++   find_separate_debug_file_in_section.  Passed STREAM
++   is 'struct lzma_stream *'.  */
++
++static int
++lzma_close (struct bfd *nbfd,
++	    void *stream)
++{
++  struct lzma_stream *lstream = stream;
++
++  lzma_index_end (lstream->index, &gdb_lzma_allocator);
++  xfree (lstream->data);
++  xfree (lstream);
++  return 0;
++}
++
++/* bfd_openr_iovec STAT_P implementation for
++   find_separate_debug_file_in_section.  Passed STREAM
++   is 'struct lzma_stream *'.  */
++
++static int
++lzma_stat (struct bfd *abfd,
++	   void *stream,
++	   struct stat *sb)
++{
++  struct lzma_stream *lstream = stream;
++
++  sb->st_size = lzma_index_uncompressed_size (lstream->index);
++  return 0;
++}
++
++/* This looks for a xz compressed separate debug info object file embedded
++   in a section called .gnu_debugdata. If we find one we create a iovec
++   based bfd that decompresses the object data on demand.  */
++
++static bfd *
++find_separate_debug_file_in_section (struct objfile *objfile)
++{
++  asection *section;
++  bfd *abfd;
++
++  section = bfd_get_section_by_name (objfile->obfd, ".gnu_debugdata");
++  if (section == NULL)
++    return NULL;
++
++  /* objfile->NAME lifetime is longer than the ABFD's lifetime.  */
++  abfd = bfd_openr_iovec (objfile->name, gnutarget, lzma_open, section,
++			  lzma_pread, lzma_close, lzma_stat);
++  if (abfd == NULL)
++    return NULL;
++
++  if (!bfd_check_format (abfd, bfd_object))
++    {
++      bfd_close (abfd);
++      return NULL;
++    }
++
++  return abfd;
++}
++
++#else /* !HAVE_LIBLZMA */
++
++static bfd *
++find_separate_debug_file_in_section (struct objfile *objfile)
++{
++  return NULL;
++}
++
++#endif /* !HAVE_LIBLZMA */
++
+ /* Scan and build partial symbols for a symbol file.
+    We have been initialized by a call to elf_symfile_init, which
+    currently does nothing.
+@@ -2433,6 +2693,7 @@ elf_symfile_read (struct objfile *objfil
+   else if (!objfile_has_partial_symbols (objfile))
+     {
+       char *debugfile, *build_id_filename;
++      bfd *abfd = NULL;
+ 
+       debugfile = find_separate_debug_file_by_buildid (objfile,
+ 						       &build_id_filename);
+@@ -2442,9 +2703,7 @@ elf_symfile_read (struct objfile *objfil
+ 
+       if (debugfile)
+ 	{
+-	  bfd *abfd = symfile_bfd_open (debugfile);
+-
+-	  symbol_file_add_separate (abfd, symfile_flags, objfile);
++	  abfd = symfile_bfd_open (debugfile);
+ 	  xfree (debugfile);
+ 	}
+       /* Check if any separate debug info has been extracted out.  */
+@@ -2453,6 +2712,12 @@ elf_symfile_read (struct objfile *objfil
+ 	debug_print_missing (objfile->name, build_id_filename);
+ 
+       xfree (build_id_filename);
++
++      if (abfd == NULL)
++	abfd = find_separate_debug_file_in_section (objfile);
++
++      if (abfd != NULL)
++	symbol_file_add_separate (abfd, symfile_flags, objfile);
+     }
+ 
+   if (symtab_create_debug)
+Index: gdb-7.4.50.20120703/gdb/testsuite/gdb.dwarf2/dw2-gnu-debugdata.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ gdb-7.4.50.20120703/gdb/testsuite/gdb.dwarf2/dw2-gnu-debugdata.c	2012-07-05 22:47:45.488509360 +0200
+@@ -0,0 +1,30 @@
++/* This testcase is part of GDB, the GNU debugger.
++
++   Copyright 2012 Free Software Foundation, Inc.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
++
++#include <signal.h>
++
++static int
++debugdata_function (void)
++{
++  return raise (SIGSEGV) + 1;
++}
++
++int
++main (void)
++{
++  return debugdata_function () + 1;
++}
+Index: gdb-7.4.50.20120703/gdb/testsuite/gdb.dwarf2/dw2-gnu-debugdata.exp
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ gdb-7.4.50.20120703/gdb/testsuite/gdb.dwarf2/dw2-gnu-debugdata.exp	2012-07-05 22:50:36.622348900 +0200
+@@ -0,0 +1,91 @@
++# Copyright 2012 Free Software Foundation, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program.  If not, see <http://www.gnu.org/licenses/>.
++
++standard_testfile
++
++load_lib dwarf.exp
++if ![dwarf2_support] {
++    return 0
++}
++
++if [build_executable ${testfile}.exp $testfile] {
++    return -1
++}
++
++proc run { test cmdline } {
++    verbose "cmdline is $cmdline"
++    set result [catch "exec $cmdline" output]
++    verbose "result is $result"
++    verbose "output is $output"
++    if {$result == 0} {
++	pass $test
++	return 0
++    } else {
++	fail $test
++	return -1
++    }
++}
++
++set strip_program [transform strip]
++set nm_program [transform nm]
++
++# Extract the dynamic symbols from the main binary, there is no need to also have these
++# in the normal symbol table
++file delete -- ${binfile}.dynsyms
++if [run "nm -D" "[transform nm] -D ${binfile} --format=posix --defined-only | awk \\{print\\ \\\$1\\} | sort > ${binfile}.dynsyms"] {
++    return -1
++}
++
++# Extract all the text (i.e. function) symbols from the debuginfo
++file delete -- ${binfile}.funcsyms
++if [run "nm" "[transform nm] ${binfile} --format=posix --defined-only | awk \\{if(\\\$2==\"T\"||\\\$2==\"t\")print\\ \\\$1\\} | sort > ${binfile}.funcsyms"] {
++    return -1
++}
++
++# Keep all the function symbols not already in the dynamic symbol table
++file delete -- ${binfile}.keep_symbols
++if [run "comm" "comm -13 ${binfile}.dynsyms ${binfile}.funcsyms > ${binfile}.keep_symbols"] {
++    return -1
++}
++
++# Copy the full debuginfo, keeping only a minumal set of symbols and removing some unnecessary sections
++file delete -- ${binfile}.mini_debuginfo
++if [run "objcopy 1" "[transform objcopy] -S --remove-section .gdb_index --remove-section .comment --keep-symbols=${binfile}.keep_symbols ${binfile} ${binfile}.mini_debuginfo"] {
++    return -1
++}
++
++# GDB specific - we do not have split executable in advance.
++file delete -- ${binfile}.strip
++if [run "strip" "[transform strip] --strip-all -o ${binfile}.strip ${binfile}"] {
++    return -1
++}
++
++# Inject the compressed data into the .gnu_debugdata section of the original binary
++file delete -- ${binfile}.mini_debuginfo.xz
++if [run "xz" "xz ${binfile}.mini_debuginfo"] {
++    return -1
++}
++file delete -- ${binfile}.test
++if [run "objcopy 2" "[transform objcopy] --add-section .gnu_debugdata=${binfile}.mini_debuginfo.xz ${binfile}.strip ${binfile}.test"] {
++    return -1
++}
++
++clean_restart "$testfile.strip"
++
++gdb_test "p debugdata_function" {No symbol table is loaded\.  Use the "file" command\.} "no symtab"
++
++clean_restart "$testfile.test"
++
++gdb_test "p debugdata_function" { = {<text variable, no debug info>} 0x[0-9a-f]+ <debugdata_function>} "have symtab"
diff --git a/gdb.spec b/gdb.spec
index 133ba22..ec877c1 100644
--- a/gdb.spec
+++ b/gdb.spec
@@ -35,7 +35,7 @@ Version: 7.4.50.%{snap}
 
 # The release always contains a leading reserved number, start it at 1.
 # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
-Release: 8%{?dist}
+Release: 9%{?dist}
 
 License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and BSD and Public Domain
 Group: Development/Debuggers
@@ -569,6 +569,10 @@ Patch703: gdb-rhbz-818343-set-solib-absolute-prefix-testcase.patch
 #=push
 Patch715: gdb-errno-func-datatype-revert.patch
 
+# Implement MiniDebugInfo F-18 Feature consumer (Alexander Larsson, BZ 834068).
+#=fedora
+Patch716: gdb-minidebuginfo.patch
+
 %if 0%{!?rhel:1} || 0%{?rhel} > 6
 # RL_STATE_FEDORA_GDB would not be found for:
 # Patch642: gdb-readline62-ask-more-rh.patch
@@ -858,6 +862,7 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c
 %patch695 -p1
 %patch698 -p1
 %patch703 -p1
+%patch716 -p1
 
 %patch393 -p1
 %if 0%{!?el5:1} || 0%{?scl:1}
@@ -1347,6 +1352,9 @@ fi
 %endif # 0%{!?el5:1} || "%{_target_cpu}" == "noarch"
 
 %changelog
+* Thu Jul  5 2012 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.4.50.20120703-9.fc18
+- Implement MiniDebugInfo F-18 Feature consumer (Alexander Larsson, BZ 834068).
+
 * Tue Jul  3 2012 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.4.50.20120703-8.fc18
 - Rebase to FSF GDB 7.4.50.20120703.
 - [archer-tromey-dwz-multifile-rebase] Merge new branch (Tom Tromey).


More information about the scm-commits mailing list