This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH/BUGFIX] GDB needs long PE section names enabled.


    Dear all, I messed up, sorry.

  Graydon here was sharp enough to spot something I overlooked[*] in my patch
to regularize the behaviour of BFD and ld w.r.t. PE/COFF long section names:
when using DW-2 debug info, GDB needs to be able to look it up via the long
section names.  Thus although it's technically wrong to use long section names
in PE executable images, it's vital for debuggability on GNU platforms.

  The abbreviated debug info section names are almost but not *quite* unique
in their leading parts, and I considered writing some code to mung the section
names down to short unique names instead of simply truncating them, but then
we'd be doing something non-standard anyway.  So I decided that the second
simplest fix (the first simplest being just to unconditionally re-enable long
section names in executables and leave it to the people who really want
technical compliance to override with a command-line option) would be that, if
we haven't been given an explicit command-line option, and any debug sections
are present, we re-enable long section names in the output.  That's what the
attached patch does.

  Tested that this patch works on i686-pc-cygwin both by looking at the
section names with objdump and by debugging a linked exe with gdb and
observing whether or not it reported debug info present - see attached.  Now
running crossbuilds and regtests from i686-pc-linux-gnu to {arm-epoc-pe,
arm-wince-pe, i386-pc-netbsdpe, i386-pc-pe, i586-pc-interix,
i586-unknown-beospe, i686-pc-cygwin, i686-pc-mingw32, mcore-unknown-pe,
powerpcle-unknown-pe, sh-unknown-pe, thumb-epoc-pe, x86_64-pc-freebsd,
x86_64-pc-linux-gnu, x86_64-pc-mingw32}.

  If testing passes, OK for trunk?

    cheers,
      DaveK
-- 
[*] - Cygwin's old compiler still defaults to .stabs, and the new ones that
use dw2 debug by default are still in unstable status, so I wasn't using them
when I tested the original patch, and didn't see any problem in GDB.
<<<<<<<<<<<<<<<<<<<<<<<< with unpatched ld >>>>>>>>>>>>>>>>>>>>>>>>

/usr/build/obj-binutils2 $ ld -Bdynamic --dll-search-prefix=cyg -o hw.dw2 /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../crt0.o -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../.. hw.o -lgcc -lcygwin -luser32 -lkernel32 -ladvapi32 -lshell32 -lgcc -v
GNU ld (GNU Binutils) 2.19.51.20090301
@_______. .
(       /"\
 ||--||(___)
 '"  '"'---'
/usr/build/obj-binutils2 $ objdump -h hw.dw2

hw.dw2:     file format pei-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         000003a0  00401000  00401000  00000400  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000010  00402000  00402000  00000800  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000040  00403000  00403000  00000000  2**2
                  ALLOC
  3 .idata        00000188  00404000  00404000  00000a00  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  4 .debug_a      00000020  00405000  00405000  00000c00  2**0
                  CONTENTS, READONLY, DEBUGGING
  5 .debug_p      00000028  00406000  00406000  00000e00  2**0
                  CONTENTS, READONLY, DEBUGGING
  6 .debug_i      00000193  00407000  00407000  00001000  2**0
                  CONTENTS, READONLY, DEBUGGING
  7 .debug_a      00000081  00408000  00408000  00001200  2**0
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_l      00000048  00409000  00409000  00001400  2**0
                  CONTENTS, READONLY, DEBUGGING
  9 .debug_f      00000044  0040a000  0040a000  00001600  2**2
                  CONTENTS, READONLY, DEBUGGING
 10 .debug_s      0000000d  0040b000  0040b000  00001800  2**0
                  CONTENTS, READONLY, DEBUGGING
@_______. .
(       /"\
 ||--||(___)
 '"  '"'---'
/usr/build/obj-binutils2 $ gdb hw.dw2
GNU gdb (GDB) 6.8.50.20090301-cvs
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-cygwin".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
(no debugging symbols found)
(gdb) list main
No symbol table is loaded.  Use the "file" command.
(gdb) b test_fun
Breakpoint 1 at 0x401056
(gdb) r
Starting program: /usr/build/obj-binutils2/hw.dw2
[New Thread 1936.0x288]
[New Thread 1936.0x7d8]

Breakpoint 1, 0x00401056 in test_fun ()
(gdb) list
1       /* assert.cc: Handle the assert macro for WIN32.
2
3          Copyright 1997, 1998, 2000, 2001 Red Hat, Inc.
4
5       This file is part of Cygwin.
6
7       This software is a copyrighted work licensed under the terms of the
8       Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
9       details. */
10
(gdb) n
Single stepping until exit from function test_fun,
which has no line number information.
Hello world!
0x00401093 in main ()
(gdb) n
Single stepping until exit from function main,
which has no line number information.

Program exited with code 015.
(gdb) q
@_______. .
(       /"\
 ||--||(___)
 '"  '"'---'
/usr/build/obj-binutils2 $
<<<<<<<<<<<<<<<<<<<<<<<<< with patched ld >>>>>>>>>>>>>>>>>>>>>>>>>

/usr/build/obj-binutils2 $ ./ld/.libs/ld-new -Bdynamic --dll-search-prefix=cyg -o hw.dw2 /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../crt0.o -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../.. hw.o -lgcc -lcygwin -luser32 -lkernel32 -ladvapi32 -lshell32 -lgcc -v
GNU ld (GNU Binutils) 2.19.51.20090301
pe_use_coff_long_section_names -1 link_info.strip 0
fname '/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../crt0.o'
fname '/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../crt0.o' secname '.text' found
0
fname '/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../crt0.o' secname '.data' found
0
fname '/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../crt0.o' secname '.bss' found 0

fname 'hw.o'
fname 'hw.o' secname '.text' found 0
fname 'hw.o' secname '.data' found 0
fname 'hw.o' secname '.bss' found 0
fname 'hw.o' secname '.debug_abbrev' found 1
fname 'hw.o' secname '.debug_info' found 1
fname 'hw.o' secname '.debug_line' found 1
fname 'hw.o' secname '.rdata' found 1
fname 'hw.o' secname '.debug_frame' found 1
fname 'hw.o' secname '.debug_pubnames' found 1
fname 'hw.o' secname '.debug_aranges' found 1
fname 'hw.o' secname '.debug_str' found 1
@_______. .
(       /"\
 ||--||(___)
 '"  '"'---'
/usr/build/obj-binutils2 $ gdb hw.dw2
GNU gdb (GDB) 6.8.50.20090301-cvs
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-cygwin".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
(gdb) list main
5       {
6         return printf ("Hello world!\n");
7       }
8
9       int main (int argc, const char **argv)
10      {
11        return test_fun ();
12      }
(gdb) b test_fun
Breakpoint 1 at 0x401056: file hw.c, line 6.
(gdb) r
Starting program: /usr/build/obj-binutils2/hw.dw2
[New Thread 2192.0x5dc]
[New Thread 2192.0x8d4]

Breakpoint 1, test_fun () at hw.c:6
6         return printf ("Hello world!\n");
(gdb) n
Hello world!
7       }
(gdb) n
main (argc=1, argv=0x612380) at hw.c:12
12      }
(gdb) n

Program exited with code 015.
(gdb) q
@_______. .
(       /"\
 ||--||(___)
 '"  '"'---'
/usr/build/obj-binutils2 $

Index: ld/NEWS
===================================================================
RCS file: /cvs/src/src/ld/NEWS,v
retrieving revision 1.97
diff -p -u -r1.97 NEWS
--- ld/NEWS	18 Feb 2009 18:23:07 -0000	1.97
+++ ld/NEWS	3 Mar 2009 02:02:22 -0000
@@ -3,7 +3,9 @@
 * PE targets no longer make use of the long section names PE extension to
   the COFF format when generating executable images, by default.  The old
   (slightly non-conformant) behaviour can still be invoked by using the
-  new '--enable-long-section-names' command-line option.
+  new '--enable-long-section-names' command-line option.  It is also enabled
+  automatically in the presence of un-stripped debug information, as GDB
+  needs to be able to find the debug info sections by their full names.
 
 * --as-needed now links in a dynamic library if it satisfies undefined
   symbols in regular objects, or in other dynamic libraries.  In the
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.233
diff -p -u -r1.233 ld.texinfo
--- ld/ld.texinfo	24 Feb 2009 22:43:09 -0000	1.233
+++ ld/ld.texinfo	3 Mar 2009 02:02:24 -0000
@@ -2124,7 +2124,13 @@ allow their use in executable images as 
 disallow it in object files, by using these two options.  Executable images
 generated with these long section names are slightly non-standard, carrying
 as they do a string table, and may generate confusing output when examined
-with non-GNU PE-aware tools, such as file viewers and dumpers.
+with non-GNU PE-aware tools, such as file viewers and dumpers.  However, 
+GDB relies on the use of PE long section names to find Dwarf-2 debug 
+information sections in an executable image at runtime, and so if neither
+option is specified on the command-line, @command{ld} will enable long
+section names, overriding the default and technically correct behaviour,
+when it finds the presence of debug information while linking an executable
+image and not stripping symbols.
 [This option is valid for all PE targeted ports of the linker]
 
 @kindex --enable-stdcall-fixup
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.145
diff -p -u -r1.145 pe.em
--- ld/emultempl/pe.em	27 Feb 2009 19:01:56 -0000	1.145
+++ ld/emultempl/pe.em	3 Mar 2009 02:02:24 -0000
@@ -1043,6 +1043,13 @@ pr_sym (struct bfd_hash_entry *h, void *
 }
 #endif /* DLL_SUPPORT */
 
+static void 
+debug_section_p (bfd *abfd ATTRIBUTE_UNUSED, asection *sect, void *obj)
+{
+  int *found = (int *) obj;
+  if (strncmp (".debug_", sect->name, sizeof (".debug_") - 1) == 0)
+    *found = 1;
+}
 
 static void
 gld_${EMULATION_NAME}_after_open (void)
@@ -1076,6 +1083,29 @@ gld_${EMULATION_NAME}_after_open (void)
   pe_data (link_info.output_bfd)->pe_opthdr = pe;
   pe_data (link_info.output_bfd)->dll = init[DLLOFF].value;
   pe_data (link_info.output_bfd)->real_flags |= real_flags;
+
+  /* At this point we must decide whether to use long section names
+     in the output or not.  If the user hasn't explicitly specified
+     on the command line, we leave it to the default for the format
+     (object files yes, image files no), except if there is debug
+     information present; GDB relies on the long section names to
+     find it, so enable it in that case.  */
+  if (pe_use_coff_long_section_names < 0 && link_info.strip == strip_none)
+    {
+      /* Iterate over all sections of all input BFDs, checking
+         for any that begin 'debug_' and are long names.  */
+      LANG_FOR_EACH_INPUT_STATEMENT (is)
+	{
+	  int found_debug = 0;
+	  bfd_map_over_sections (is->the_bfd, debug_section_p, &found_debug);
+	  if (found_debug)
+	    {
+	      pe_use_coff_long_section_names = 1;
+	      break;
+	    }
+	}
+    }
+
   pe_output_file_set_long_section_names (link_info.output_bfd);
 
 #ifdef DLL_SUPPORT
Index: ld/emultempl/pep.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pep.em,v
retrieving revision 1.22
diff -p -u -r1.22 pep.em
--- ld/emultempl/pep.em	18 Feb 2009 18:23:07 -0000	1.22
+++ ld/emultempl/pep.em	3 Mar 2009 02:02:25 -0000
@@ -1020,6 +1020,13 @@ pr_sym (struct bfd_hash_entry *h, void *
 }
 #endif /* DLL_SUPPORT */
 
+static void 
+debug_section_p (bfd *abfd ATTRIBUTE_UNUSED, asection *sect, void *obj)
+{
+  int *found = (int *) obj;
+  if (strncmp (".debug_", sect->name, sizeof (".debug_") - 1) == 0)
+    *found = 1;
+}
 
 static void
 gld_${EMULATION_NAME}_after_open (void)
@@ -1053,6 +1060,29 @@ gld_${EMULATION_NAME}_after_open (void)
   pe_data (link_info.output_bfd)->pe_opthdr = pep;
   pe_data (link_info.output_bfd)->dll = init[DLLOFF].value;
   pe_data (link_info.output_bfd)->real_flags |= real_flags;
+
+  /* At this point we must decide whether to use long section names
+     in the output or not.  If the user hasn't explicitly specified
+     on the command line, we leave it to the default for the format
+     (object files yes, image files no), except if there is debug
+     information present; GDB relies on the long section names to
+     find it, so enable it in that case.  */
+  if (pep_use_coff_long_section_names < 0 && link_info.strip == strip_none)
+    {
+      /* Iterate over all sections of all input BFDs, checking
+         for any that begin 'debug_' and are long names.  */
+      LANG_FOR_EACH_INPUT_STATEMENT (is)
+	{
+	  int found_debug = 0;
+	  bfd_map_over_sections (is->the_bfd, debug_section_p, &found_debug);
+	  if (found_debug)
+	    {
+	      pep_use_coff_long_section_names = 1;
+	      break;
+	    }
+	}
+    }
+
   pep_output_file_set_long_section_names (link_info.output_bfd);
 
 #ifdef DLL_SUPPORT


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]