Sophie

Sophie

distrib > Mageia > 3 > i586 > media > core-release-src > by-pkgid > 87e24c835797f6ddf75b9bb0dca2f1f3 > files > 108

gdb-7.5.1-7.mga3.src.rpm

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.91.20120801/gdb/Makefile.in
===================================================================
--- gdb-7.4.91.20120801.orig/gdb/Makefile.in	2012-08-01 18:44:51.000000000 +0200
+++ gdb-7.4.91.20120801/gdb/Makefile.in	2012-08-01 18:47:05.701820594 +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.91.20120801/gdb/config.in
===================================================================
--- gdb-7.4.91.20120801.orig/gdb/config.in	2012-08-01 18:45:21.000000000 +0200
+++ gdb-7.4.91.20120801/gdb/config.in	2012-08-01 18:47:05.701820594 +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.91.20120801/gdb/configure
===================================================================
--- gdb-7.4.91.20120801.orig/gdb/configure	2012-08-01 18:45:21.000000000 +0200
+++ gdb-7.4.91.20120801/gdb/configure	2012-08-01 18:47:05.703820583 +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,494 @@ 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_index_iter iter;
+			   lzma_index_iter_init (&iter, 0);
+			   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.91.20120801/gdb/configure.ac
===================================================================
--- gdb-7.4.91.20120801.orig/gdb/configure.ac	2012-08-01 18:45:21.000000000 +0200
+++ gdb-7.4.91.20120801/gdb/configure.ac	2012-08-01 18:47:05.704820577 +0200
@@ -2196,6 +2196,27 @@ 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_index_iter iter;
+			   lzma_index_iter_init (&iter, 0);
+			   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.91.20120801/gdb/elfread.c
===================================================================
--- gdb-7.4.91.20120801.orig/gdb/elfread.c	2012-08-01 18:44:51.000000000 +0200
+++ gdb-7.4.91.20120801/gdb/elfread.c	2012-08-01 18:57:59.528202398 +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 = gdb_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))
+    {
+      gdb_bfd_unref (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,8 @@ elf_symfile_read (struct objfile *objfil
   else if (!objfile_has_partial_symbols (objfile))
     {
       char *debugfile, *build_id_filename;
+      bfd *abfd = NULL;
+      struct cleanup *cleanup;
 
       debugfile = find_separate_debug_file_by_buildid (objfile,
 						       &build_id_filename);
@@ -2440,14 +2702,11 @@ elf_symfile_read (struct objfile *objfil
       if (debugfile == NULL)
 	debugfile = find_separate_debug_file_by_debuglink (objfile);
 
+      cleanup = make_cleanup (xfree, debugfile);
       if (debugfile)
 	{
-	  struct cleanup *cleanup = make_cleanup (xfree, debugfile);
-	  bfd *abfd = symfile_bfd_open (debugfile);
-
+	  abfd = symfile_bfd_open (debugfile);
 	  make_cleanup_bfd_unref (abfd);
-	  symbol_file_add_separate (abfd, symfile_flags, objfile);
-	  do_cleanups (cleanup);
 	}
       /* Check if any separate debug info has been extracted out.  */
       else if (bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink")
@@ -2455,6 +2714,17 @@ 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);
+	  make_cleanup_bfd_unref (abfd);
+	}
+
+      if (abfd != NULL)
+	symbol_file_add_separate (abfd, symfile_flags, objfile);
+
+      do_cleanups (cleanup);
     }
 
   if (symtab_create_debug)
Index: gdb-7.4.91.20120801/gdb/testsuite/gdb.dwarf2/dw2-gnu-debugdata.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gdb-7.4.91.20120801/gdb/testsuite/gdb.dwarf2/dw2-gnu-debugdata.c	2012-08-01 18:47:05.705820572 +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.91.20120801/gdb/testsuite/gdb.dwarf2/dw2-gnu-debugdata.exp
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gdb-7.4.91.20120801/gdb/testsuite/gdb.dwarf2/dw2-gnu-debugdata.exp	2012-08-01 18:47:05.705820572 +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"