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 ++#include "gdbcore.h" ++#ifdef HAVE_LIBLZMA ++# include ++#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 . */ ++ ++#include ++ ++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 . ++ ++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" { = {} 0x[0-9a-f]+ } "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 - 7.4.50.20120703-9.fc18 +- Implement MiniDebugInfo F-18 Feature consumer (Alexander Larsson, BZ 834068). + * Tue Jul 3 2012 Jan Kratochvil - 7.4.50.20120703-8.fc18 - Rebase to FSF GDB 7.4.50.20120703. - [archer-tromey-dwz-multifile-rebase] Merge new branch (Tom Tromey).