This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB 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]

RFC: strip --strip-nondebug


Hi Guys,

  I am seeking comments and criticisms on the attached patch.  It adds
  a new switch to strip:

    --strip-nondebug

  This can be used to create an output file which only contains the
  debug information from an executable.  This would allow stripped
  binaries to be shipped with separate debug info files, and provided
  that the debugger supported it, they could still be debugged.

  The patch is incomplete - it needs a ChangeLog entry as well as
  modifications to NEWS and binutils.texi to document the new
  functionality, but I will write all of these once/if the patch is
  in acceptable state.

Cheers
        Nick

Index: binutils/objcopy.c
===================================================================
RCS file: /cvs/src/src/binutils/objcopy.c,v
retrieving revision 1.48
diff -c -3 -p -r1.48 objcopy.c
*** binutils/objcopy.c	2 Jun 2003 14:45:12 -0000	1.48
--- binutils/objcopy.c	5 Jun 2003 15:50:15 -0000
*************** enum strip_action
*** 130,136 ****
      STRIP_NONE,			/* don't strip */
      STRIP_DEBUG,		/* strip all debugger symbols */
      STRIP_UNNEEDED,		/* strip unnecessary symbols */
!     STRIP_ALL			/* strip all symbols */
    };
  
  /* Which symbols to remove.  */
--- 130,137 ----
      STRIP_NONE,			/* don't strip */
      STRIP_DEBUG,		/* strip all debugger symbols */
      STRIP_UNNEEDED,		/* strip unnecessary symbols */
!     STRIP_ALL,			/* strip all symbols */
!     STRIP_NONDEBUG		/* Strip everything but debug info.  */
    };
  
  /* Which symbols to remove.  */
*************** static char *prefix_alloc_sections_strin
*** 277,282 ****
--- 278,284 ----
  #define OPTION_PREFIX_SECTIONS (OPTION_PREFIX_SYMBOLS + 1)
  #define OPTION_PREFIX_ALLOC_SECTIONS (OPTION_PREFIX_SECTIONS + 1)
  #define OPTION_FORMATS_INFO (OPTION_PREFIX_ALLOC_SECTIONS + 1)
+ #define OPTION_STRIP_NONDEBUG (OPTION_FORMATS_INFO + 1)
  
  /* Options to handle if running as "strip".  */
  
*************** static struct option strip_options[] =
*** 297,302 ****
--- 299,305 ----
    {"remove-section", required_argument, 0, 'R'},
    {"strip-all", no_argument, 0, 's'},
    {"strip-debug", no_argument, 0, 'S'},
+   {"strip-nondebug", no_argument, 0, OPTION_STRIP_NONDEBUG},
    {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
    {"strip-symbol", required_argument, 0, 'N'},
    {"target", required_argument, 0, 'F'},
*************** strip_usage (stream, exit_status)
*** 490,495 ****
--- 493,499 ----
    -g -S -d --strip-debug           Remove all debugging symbols\n\
       --strip-unneeded              Remove all symbols not needed by relocations\n\
    -N --strip-symbol=<name>         Do not copy symbol <name>\n\
+      --strip-nondebug              Remove all but the debug info\n\
    -K --keep-symbol=<name>          Only copy symbol <name>\n\
    -x --discard-all                 Remove all non-global symbols\n\
    -X --discard-locals              Remove any compiler-generated symbols\n\
*************** is_strip_section (abfd, sec)
*** 752,776 ****
       bfd *abfd ATTRIBUTE_UNUSED;
       asection *sec;
  {
!   struct section_list *p;
  
!   if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0
!       && (strip_symbols == STRIP_DEBUG
  	  || strip_symbols == STRIP_UNNEEDED
  	  || strip_symbols == STRIP_ALL
  	  || discard_locals == LOCALS_ALL
! 	  || convert_debugging))
!     return TRUE;
  
!   if (! sections_removed && ! sections_copied)
!     return FALSE;
  
!   p = find_section_list (bfd_get_section_name (abfd, sec), FALSE);
!   if (sections_removed && p != NULL && p->remove)
!     return TRUE;
!   if (sections_copied && (p == NULL || ! p->copy))
!     return TRUE;
!   return FALSE;
  }
  
  /* Choose which symbol entries to copy; put the result in OSYMS.
--- 756,787 ----
       bfd *abfd ATTRIBUTE_UNUSED;
       asection *sec;
  {
!   if (sections_removed || sections_copied)
!     {
!       struct section_list *p;
! 
!       p = find_section_list (bfd_get_section_name (abfd, sec), FALSE);
! 
!       if (sections_removed && p != NULL && p->remove)
! 	return TRUE;
!       if (sections_copied && (p == NULL || ! p->copy))
! 	return TRUE;
!     }
  
!   if ((bfd_get_section_flags (abfd, sec) & SEC_DEBUGGING) != 0)
!     {
!       if (strip_symbols == STRIP_DEBUG
  	  || strip_symbols == STRIP_UNNEEDED
  	  || strip_symbols == STRIP_ALL
  	  || discard_locals == LOCALS_ALL
! 	  || convert_debugging)
! 	return TRUE;
  
!       if (strip_symbols == STRIP_NONDEBUG)
! 	return FALSE;
!     }
  
!   return strip_symbols == STRIP_NONDEBUG ? TRUE : FALSE;
  }
  
  /* Choose which symbol entries to copy; put the result in OSYMS.
*************** filter_symbols (abfd, obfd, osyms, isyms
*** 882,890 ****
  	       || bfd_is_com_section (bfd_get_section (sym)))
  	keep = strip_symbols != STRIP_UNNEEDED;
        else if ((flags & BSF_DEBUGGING) != 0)	/* Debugging symbol.  */
! 	keep = (strip_symbols != STRIP_DEBUG
! 		&& strip_symbols != STRIP_UNNEEDED
! 		&& ! convert_debugging);
        else if (bfd_get_section (sym)->comdat)
  	/* COMDAT sections store special information in local
  	   symbols, so we cannot risk stripping any of them.  */
--- 893,903 ----
  	       || bfd_is_com_section (bfd_get_section (sym)))
  	keep = strip_symbols != STRIP_UNNEEDED;
        else if ((flags & BSF_DEBUGGING) != 0)	/* Debugging symbol.  */
! 	{
! 	  keep = (strip_symbols != STRIP_DEBUG
! 		  && strip_symbols != STRIP_UNNEEDED
! 		  && ! convert_debugging);
! 	}
        else if (bfd_get_section (sym)->comdat)
  	/* COMDAT sections store special information in local
  	   symbols, so we cannot risk stripping any of them.  */
*************** copy_object (ibfd, obfd)
*** 1329,1334 ****
--- 1342,1348 ----
    if (strip_symbols == STRIP_DEBUG
        || strip_symbols == STRIP_ALL
        || strip_symbols == STRIP_UNNEEDED
+       || strip_symbols == STRIP_NONDEBUG
        || discard_locals != LOCALS_UNDEF
        || strip_specific_list != NULL
        || keep_specific_list != NULL
*************** copy_object (ibfd, obfd)
*** 1434,1440 ****
       from the input BFD to the output BFD.  This is done last to
       permit the routine to look at the filtered symbol table, which is
       important for the ECOFF code at least.  */
!   if (! bfd_copy_private_bfd_data (ibfd, obfd))
      {
        non_fatal (_("%s: error copying private BFD data: %s"),
  		 bfd_get_filename (obfd),
--- 1448,1459 ----
       from the input BFD to the output BFD.  This is done last to
       permit the routine to look at the filtered symbol table, which is
       important for the ECOFF code at least.  */
!   if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
!       && strip_symbols == STRIP_NONDEBUG)
!     /* Do not copy the private data when creating an ELF
!        format debug info file.  We do not want the program headers.  */
!     ;
!   else if (! bfd_copy_private_bfd_data (ibfd, obfd))
      {
        non_fatal (_("%s: error copying private BFD data: %s"),
  		 bfd_get_filename (obfd),
*************** copy_object (ibfd, obfd)
*** 1442,1448 ****
        status = 1;
        return;
      }
! 
    /* Switch to the alternate machine code.  We have to do this at the
       very end, because we only initialize the header when we create
       the first section.  */
--- 1461,1467 ----
        status = 1;
        return;
      }
!   
    /* Switch to the alternate machine code.  We have to do this at the
       very end, because we only initialize the header when we create
       the first section.  */
*************** setup_section (ibfd, isection, obfdarg)
*** 1761,1783 ****
    const char * name;
    char *prefix = NULL;
  
!   if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
!       && (strip_symbols == STRIP_DEBUG
! 	  || strip_symbols == STRIP_UNNEEDED
! 	  || strip_symbols == STRIP_ALL
! 	  || discard_locals == LOCALS_ALL
! 	  || convert_debugging))
      return;
  
    p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
    if (p != NULL)
      p->used = TRUE;
  
-   if (sections_removed && p != NULL && p->remove)
-     return;
-   if (sections_copied && (p == NULL || ! p->copy))
-     return;
- 
    /* Get the, possibly new, name of the output section.  */
    name = find_section_rename (ibfd, isection, & flags);
  
--- 1780,1792 ----
    const char * name;
    char *prefix = NULL;
  
!   if (is_strip_section (ibfd, isection))
      return;
  
    p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
    if (p != NULL)
      p->used = TRUE;
  
    /* Get the, possibly new, name of the output section.  */
    name = find_section_rename (ibfd, isection, & flags);
  
*************** setup_section (ibfd, isection, obfdarg)
*** 1872,1878 ****
  
    /* Allow the BFD backend to copy any private data it understands
       from the input section to the output section.  */
!   if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
      {
        err = _("private data");
        goto loser;
--- 1881,1892 ----
  
    /* Allow the BFD backend to copy any private data it understands
       from the input section to the output section.  */
!   if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
!       && strip_symbols == STRIP_NONDEBUG)
!     /* Do not copy the private data when creating an ELF
!        format debug info file.  We do not want the program headers.  */
!     ;
!   else if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection))
      {
        err = _("private data");
        goto loser;
*************** copy_section (ibfd, isection, obfdarg)
*** 1913,1943 ****
    if (status != 0)
      return;
  
!   flags = bfd_get_section_flags (ibfd, isection);
!   if ((flags & SEC_DEBUGGING) != 0
!       && (strip_symbols == STRIP_DEBUG
! 	  || strip_symbols == STRIP_UNNEEDED
! 	  || strip_symbols == STRIP_ALL
! 	  || discard_locals == LOCALS_ALL
! 	  || convert_debugging))
      return;
  
    if ((flags & SEC_GROUP) != 0)
      return;
  
-   p = find_section_list (bfd_section_name (ibfd, isection), FALSE);
- 
-   if (sections_removed && p != NULL && p->remove)
-     return;
-   if (sections_copied && (p == NULL || ! p->copy))
-     return;
- 
    osection = isection->output_section;
    size = bfd_get_section_size_before_reloc (isection);
  
    if (size == 0 || osection == 0)
      return;
  
    /* Core files do not need to be relocated.  */
    if (bfd_get_format (obfd) == bfd_core)
      relsize = 0;
--- 1927,1947 ----
    if (status != 0)
      return;
  
!   if (is_strip_section (ibfd, isection))
      return;
  
+   flags = bfd_get_section_flags (ibfd, isection);
    if ((flags & SEC_GROUP) != 0)
      return;
  
    osection = isection->output_section;
    size = bfd_get_section_size_before_reloc (isection);
  
    if (size == 0 || osection == 0)
      return;
  
+   p = find_section_list (bfd_get_section_name (ibfd, isection), FALSE);
+ 
    /* Core files do not need to be relocated.  */
    if (bfd_get_format (obfd) == bfd_core)
      relsize = 0;
*************** strip_main (argc, argv)
*** 2265,2270 ****
--- 2269,2277 ----
  	case OPTION_FORMATS_INFO:
  	  formats_info = TRUE;
  	  break;
+ 	case OPTION_STRIP_NONDEBUG:
+ 	  strip_symbols = STRIP_NONDEBUG;
+ 	  break;
  	case 0:
  	  /* We've been given a long option.  */
  	  break;


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