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]

[PATCHx2] Extend objcopy with long section name handling.


    Hello team,

  The attached two patches resolve some fallout from my recent revamp of long
section names handling in COFF and PE.

  To recap: COFF section headers only have eight bytes for the section name,
in object files you can represent longer names by placing an index into the
string table in the section name, in PE long section names are allowed in
object files but should be truncated in executable images, binutils used to
always generate them anyway which was non-standard, it turns out that this is
a problem for some native tools but we require it for GDB, so I made it a
run-time decision whether to use long section names, defaulted according to
the rules in the spec.

  Anyway, the previous patch made BFD choose to generate strictly-compliant
files by default, but provided an interface for the client of libbfd to choose
at runtime whether long section names should be emitted or not if it wants to
override the default.  ld allows the decision to be based on an explicit
command-line option (and also enables it automatically if it sees debug info
present), but objcopy has no control at the moment, so any executable image
processed by objcopy will be emitted in the default strictly-compliant mode,
with truncated versions of any long section names.  This mangles the debug
info badly, or at any rate prevents GDB and friends from being able to process
it.  (The truncated section names containing debug info are in fact almost
unique, and GDB could quite easily be taught to recognize them, but for now
the simplest solution is to continue relying on the slightly non-standard
behaviour that has worked so well for us in the past).

  The attached patches address this by 1) providing support in BFD to find out
if long section names are used in an input BFD, and 2) providing a
command-line option for objcopy that tells it how to deal with long section names.

1)  At the moment, the bfd backend long section names flag is only relevant
for output BFDs, controlling whether long section names are emitted or not.
In input BFDs it will simply retain the default value for the image or object
format throughout processing, neither signifying nor controlling anything.
This patch changes that: it give the flag a meaningful semantic for read BFDs,
in that it is still initialised to the format default (true for relocatable
objects, false for executable images), but if long section names are
encountered on reading the BFD, the flag is set.  This will have no effect on
any current usage, as it's only relevant to output BFDs at the moment, but it
makes available the information about the BFDs so that ...

2)  ... objcopy can now handle long section names in one of three ways: it can
either explicitly enable or disable them in the output object, or it can be
told to preserve long section names only if they are present.

  Tested on i686-pc-cygwin natively, with no regressions, and it fixes a bug
that otherwise leads to corruption of the newly-built cygwin dll during the
separate debug info processing.

  Also testing cross from i686-pc-linux-gnu to {a29k-unknown-coff,
alpha-freebsd, alpha-linuxecoff, alpha-unknown-linux,
alpha-unknown-linuxecoff, arm-epoc-pe, arm-unknown-coff, arm-unknown-linux,
arm-vxworks, arm-wince-pe, h8300-unknown-rtems, h8500-unknown-rtems,
hppa-unknown-linux, hppa64-unknown-linux, i370-unknown-linux, i386-coff,
i386-msdos, i386-pc-netbsdpe, i386-pc-pe, i586-linux, i586-pc-interix,
i586-pc-msdosdjgpp, i586-unknown-beospe, i586-unknown-coff, i686-pc-cygwin,
i686-pc-linux-gnu, i686-pc-mingw32, i960-intel-nindy, i960-unknown-coff,
ia64-unknown-linux, m68k-coff, m68k-unknown-coff, m68k-unknown-linux,
m68k-unknown-netbsd, m88k-unknown-coff, mcore-unknown-pe, mips-dec-bsd,
mips-unknown-ecoff, mips-unknown-linux, mips-unknown-pe, ns32k-unknown-netbsd,
or32-unknown-coff, powerpc-unknown-aix5, powerpc-unknown-linux,
powerpc64-unknown-linux, powerpcle-unknown-pe, ppc-eabi, s390-unknown-linux,
s390x-unknown-linux, sh-coff, sh-unknown-linux, sh-unknown-pe,
sh-unknown-rtems, sparc-unknown-coff, sparc-unknown-linux,
sparc64-unknown-linux, thumb-epoc-pe, tic30-unknown-coff, tic54x-unknown-coff,
tic80-unknown-coff, vax-unknown-netbsd, vax-unknown-vms, vms-vax,
w65-unknown-coff, x86_64-pc-freebsd, x86_64-pc-linux-gnu, x86_64-pc-mingw32,
x86_64-unknown-linux, z8k-coff, z8k-unknown-coff}; assuming no regressions, ok
for head?

bfd/ChangeLog

	* coffgen.c (make_a_section_from_file):  Set the backend long
	section names enable if long section names found on input.
	* coffcode.h:  Extend long section names documentation to match.

binutils/ChangeLog

	* objcopy.c (enum long_section_name_handling):  New enum type.
	(enum command_line_switch):  Add OPTION_LONG_SECTION_NAMES.
	(copy_options[]):  Add entry for --long-section-names option.
	(copy_usage):  Document it.
	(set_long_section_mode):  New subroutine.
	(copy_file):  Call it.
	(copy_main):  Accept OPTION_LONG_SECTION_NAMES and parse arg.
	* doc/binutils.texi:  Update objcopy documentation with details
	of new option.


    cheers,
      DaveK

Index: bfd/coffcode.h
===================================================================
RCS file: /cvs/src/src/bfd/coffcode.h,v
retrieving revision 1.150
diff -p -u -r1.150 coffcode.h
--- bfd/coffcode.h	19 Mar 2009 11:02:09 -0000	1.150
+++ bfd/coffcode.h	13 Apr 2009 18:30:36 -0000
@@ -153,6 +153,14 @@ SUBSUBSECTION
 	points to a function that allows the value of the flag to be altered
 	at runtime, on formats that support long section names at all; on
 	other formats it points to a stub that returns an error indication.
+	
+	With input BFDs, the flag is set according to whether any long section
+	names are detected while reading the section headers.  For a completely
+	new BFD, the flag is set to the default for the target format.  This
+	information can be used by a client of the BFD library when deciding
+	what output format to generate, and means that a BFD that is opened
+	for read and subsequently converted to a writeable BFD and modified
+	in-place will retain whatever format it had on input.
 
 	If @code{COFF_LONG_SECTION_NAMES} is simply defined (blank), or is
 	defined to the value "1", then long section names are enabled by
Index: bfd/coffgen.c
===================================================================
RCS file: /cvs/src/src/bfd/coffgen.c,v
retrieving revision 1.70
diff -p -u -r1.70 coffgen.c
--- bfd/coffgen.c	14 Mar 2009 09:34:27 -0000	1.70
+++ bfd/coffgen.c	13 Apr 2009 18:30:37 -0000
@@ -73,6 +73,11 @@ make_a_section_from_file (bfd *abfd,
       char *p;
       const char *strings;
 
+      /* Flag that this BFD uses long names, even though the format might
+         expect them to be off by default.  This won't directly affect the
+         format of any output BFD created from this one, but the information
+         can be used to decide what to do.  */
+      bfd_coff_set_long_section_names (abfd, TRUE);
       memcpy (buf, hdr->s_name + 1, SCNNMLEN - 1);
       buf[SCNNMLEN - 1] = '\0';
       strindex = strtol (buf, &p, 10);


Index: binutils/objcopy.c
===================================================================
RCS file: /cvs/src/src/binutils/objcopy.c,v
retrieving revision 1.127
diff -p -r1.127 objcopy.c
*** binutils/objcopy.c	13 Mar 2009 13:39:57 -0000	1.127
--- binutils/objcopy.c	13 Apr 2009 18:31:09 -0000
***************
*** 32,37 ****
--- 32,39 ----
  #include "elf-bfd.h"
  #include <sys/stat.h>
  #include "libbfd.h"
+ #include "coff/internal.h"
+ #include "libcoff.h"
  
  struct is_specified_symbol_predicate_data
  {
*************** static bfd_boolean extract_symbol = FALS
*** 216,221 ****
--- 218,235 ----
     of <reverse_bytes> bytes within each output section.  */
  static int reverse_bytes = 0;
  
+ /* For Coff objects, we may want to allow or disallow long section names,
+    or preserve them where found in the inputs.  Debug info relies on them.  */
+ enum long_section_name_handling
+   {
+     DISABLE,
+     ENABLE,
+     KEEP
+   };
+ 
+ /* The default long section handling mode is to preserve them.
+    This is also the only behaviour for 'strip'.  */
+ static enum long_section_name_handling long_section_names = KEEP;
  
  /* 150 isn't special; it's just an arbitrary non-ASCII char value.  */
  enum command_line_switch
*************** enum command_line_switch
*** 247,252 ****
--- 261,267 ----
      OPTION_KEEP_SYMBOLS,
      OPTION_LOCALIZE_HIDDEN,
      OPTION_LOCALIZE_SYMBOLS,
+     OPTION_LONG_SECTION_NAMES,
      OPTION_GLOBALIZE_SYMBOL,
      OPTION_GLOBALIZE_SYMBOLS,
      OPTION_KEEPGLOBAL_SYMBOLS,
*************** static struct option copy_options[] =
*** 340,345 ****
--- 355,361 ----
    {"localize-hidden", no_argument, 0, OPTION_LOCALIZE_HIDDEN},
    {"localize-symbol", required_argument, 0, 'L'},
    {"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS},
+   {"long-section-names", required_argument, 0, OPTION_LONG_SECTION_NAMES},
    {"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
    {"no-change-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
    {"only-keep-debug", no_argument, 0, OPTION_ONLY_KEEP_DEBUG},
*************** copy_usage (FILE *stream, int exit_statu
*** 470,475 ****
--- 486,493 ----
                                     Set section <name>'s properties to <flags>\n\
       --add-section <name>=<file>   Add section <name> found in <file> to output\n\
       --rename-section <old>=<new>[,<flags>] Rename section <old> to <new>\n\
+      --long-section-names {enable|disable|keep}\n\
+                                    Handle long section names in Coff objects.\n\
       --change-leading-char         Force output format's leading character style\n\
       --remove-leading-char         Remove leading character from global symbols\n\
       --reverse-bytes=<num>         Reverse <num> bytes at a time, in output sections with content\n\
*************** copy_unknown_element:
*** 2025,2030 ****
--- 2043,2060 ----
    rmdir (dir);
  }
  
+ static void
+ set_long_section_mode (bfd *output_bfd, bfd *input_bfd, enum long_section_name_handling style)
+ {
+   /* This is only relevant to Coff targets.  */
+   if (bfd_get_flavour (output_bfd) == bfd_target_coff_flavour)
+     {
+       if (style == KEEP)
+ 	style = bfd_coff_long_section_names (input_bfd) ? ENABLE : DISABLE;
+       bfd_coff_set_long_section_names (output_bfd, style != DISABLE);
+     }
+ }
+ 
  /* The top-level control.  */
  
  static void
*************** copy_file (const char *input_filename, c
*** 2073,2078 ****
--- 2103,2110 ----
  	  status = 1;
  	  return;
  	}
+       /* This is a no-op on non-Coff targets.  */
+       set_long_section_mode (obfd, ibfd, long_section_names);
  
        copy_archive (ibfd, obfd, output_target, force_output_target);
      }
*************** copy_file (const char *input_filename, c
*** 2093,2098 ****
--- 2125,2132 ----
   	  status = 1;
   	  return;
   	}
+       /* This is a no-op on non-Coff targets.  */
+       set_long_section_mode (obfd, ibfd, long_section_names);
  
        if (! copy_object (ibfd, obfd))
  	status = 1;
*************** copy_main (int argc, char *argv[])
*** 3353,3358 ****
--- 3387,3403 ----
  	  add_specific_symbols (optarg, localize_specific_htab);
  	  break;
  
+ 	case OPTION_LONG_SECTION_NAMES:
+ 	  if (!strcmp ("enable", optarg))
+ 	    long_section_names = ENABLE;
+ 	  else if (!strcmp ("disable", optarg))
+ 	    long_section_names = DISABLE;
+ 	  else if (!strcmp ("keep", optarg))
+ 	    long_section_names = KEEP;
+ 	  else
+ 	    fatal (_("unknown long section names option '%s'"), optarg);
+ 	  break;
+ 
  	case OPTION_GLOBALIZE_SYMBOLS:
  	  add_specific_symbols (optarg, globalize_specific_htab);
  	  break;
Index: binutils/doc/binutils.texi
===================================================================
RCS file: /cvs/src/src/binutils/doc/binutils.texi,v
retrieving revision 1.142
diff -p -r1.142 binutils.texi
*** binutils/doc/binutils.texi	1 Apr 2009 14:57:11 -0000	1.142
--- binutils/doc/binutils.texi	13 Apr 2009 18:31:10 -0000
*************** objcopy [@option{-F} @var{bfdname}|@opti
*** 1001,1006 ****
--- 1001,1007 ----
          [@option{--set-section-flags} @var{section}=@var{flags}]
          [@option{--add-section} @var{sectionname}=@var{filename}]
          [@option{--rename-section} @var{oldname}=@var{newname}[,@var{flags}]]
+         [@option{--long-section-names} @{enable,disable,keep@}]
          [@option{--change-leading-char}] [@option{--remove-leading-char}]
          [@option{--reverse-bytes=}@var{num}]
          [@option{--srec-len=}@var{ival}] [@option{--srec-forceS3}]
*************** data you could use the following command
*** 1338,1343 ****
--- 1339,1356 ----
     <input_binary_file> <output_object_file>
  @end smallexample
  
+ @item --long-section-names @{enable,disable,keep@}
+ Controls the handling of long section names when processing @code{COFF}
+ and @code{PE-COFF} object formats.  The default behaviour, @samp{keep},
+ is to preserve long section names if any are present in the input file.
+ The @samp{enable} and @samp{disable} options forcibly enable or disable
+ the use of long section names in the output object; when @samp{disable}
+ is in effect, any long section names in the input object will be truncated.
+ The @samp{enable} option will only emit long section names if any are
+ present in the inputs; this is mostly the same as @samp{keep}, but it
+ is left undefined whether the @samp{enable} option might force the 
+ creation of an empty string table in the output file.
+ 
  @item --change-leading-char
  Some object file formats use special characters at the start of
  symbols.  The most common such character is underscore, which compilers



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