Set correct values for NM, SIZE etc...
[deliverable/binutils-gdb.git] / binutils / objcopy.c
index f2dd5a4e6d8f36b93590316af3f453205460d894..12ca0372e2dd605665c32c96ccec2461cac2e513 100644 (file)
@@ -1,5 +1,5 @@
 /* objcopy.c -- copy object file from input to output, optionally massaging it.
-   Copyright (C) 1991 Free Software Foundation, Inc.
+   Copyright (C) 1991, 92, 93, 94 Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
 
 #include "bucomm.h"
 #include <getopt.h>
 
-static void setup_sections ();
-static void copy_sections ();
-static void mangle_sections ();
+static void setup_section ();
+static void copy_section ();
+static void mangle_section ();
 
 #define nonfatal(s) {bfd_nonfatal(s); status = 1; return;}
 
 static asymbol **isympp = NULL;        /* Input symbols */
 static asymbol **osympp = NULL;        /* Output symbols that survive stripping */
+
+/* If `copy_byte' >= 0, copy only that byte of every `interleave' bytes.  */
+static int copy_byte = -1;
+static int interleave = 4;
+
 static boolean verbose;                /* Print file and target names. */
-static int status = 0;
+static int status = 0;         /* Exit status.  */
 
 enum strip_action
   {
@@ -58,20 +63,19 @@ static enum locals_action discard_locals;
 
 static struct option strip_options[] =
 {
-  {"strip-all", no_argument, 0, 's'},
-  {"strip-debug", no_argument, 0, 'S'},
   {"discard-all", no_argument, 0, 'x'},
   {"discard-locals", no_argument, 0, 'X'},
+  {"format", required_argument, 0, 'F'}, /* Obsolete */
   {"help", no_argument, 0, 'h'},
-  {"input-target", required_argument, 0, 'I'},
   {"input-format", required_argument, 0, 'I'}, /* Obsolete */
-  {"output-target", required_argument, 0, 'O'},
+  {"input-target", required_argument, 0, 'I'},
   {"output-format", required_argument, 0, 'O'},        /* Obsolete */
+  {"output-target", required_argument, 0, 'O'},
+  {"strip-all", no_argument, 0, 's'},
+  {"strip-debug", no_argument, 0, 'S'},
   {"target", required_argument, 0, 'F'},
-  {"format", required_argument, 0, 'F'}, /* Obsolete */
-
-  {"version", no_argument, 0, 'V'},
   {"verbose", no_argument, 0, 'v'},
+  {"version", no_argument, 0, 'V'},
   {0, no_argument, 0, 0}
 };
 
@@ -79,20 +83,21 @@ static struct option strip_options[] =
 
 static struct option copy_options[] =
 {
-  {"strip-all", no_argument, 0, 'S'},
-  {"strip-debug", no_argument, 0, 'g'},
+  {"byte", required_argument, 0, 'b'},
   {"discard-all", no_argument, 0, 'x'},
   {"discard-locals", no_argument, 0, 'X'},
+  {"format", required_argument, 0, 'F'}, /* Obsolete */
   {"help", no_argument, 0, 'h'},
-  {"input-target", required_argument, 0, 'I'},
   {"input-format", required_argument, 0, 'I'}, /* Obsolete */
-  {"output-target", required_argument, 0, 'O'},
+  {"input-target", required_argument, 0, 'I'},
+  {"interleave", required_argument, 0, 'i'},
   {"output-format", required_argument, 0, 'O'},        /* Obsolete */
+  {"output-target", required_argument, 0, 'O'},
+  {"strip-all", no_argument, 0, 'S'},
+  {"strip-debug", no_argument, 0, 'g'},
   {"target", required_argument, 0, 'F'},
-  {"format", required_argument, 0, 'F'}, /* Obsolete */
-
-  {"version", no_argument, 0, 'V'},
   {"verbose", no_argument, 0, 'v'},
+  {"version", no_argument, 0, 'V'},
   {0, no_argument, 0, 0}
 };
 
@@ -112,10 +117,12 @@ copy_usage (stream, status)
      int status;
 {
   fprintf (stream, "\
-Usage: %s [-vVSgxX] [-I bfdname] [-O bfdname] [-F bfdname]\n\
+Usage: %s [-vVSgxX] [-I bfdname] [-O bfdname] [-F bfdname] [-b byte]\n\
+       [-i interleave] [--interleave=interleave] [--byte=byte]\n\
        [--input-target=bfdname] [--output-target=bfdname] [--target=bfdname]\n\
        [--strip-all] [--strip-debug] [--discard-all] [--discard-locals]\n\
-       [--verbose] [--version] [--help] in-file [out-file]\n", program_name);
+       [--verbose] [--version] [--help] in-file [out-file]\n",
+          program_name);
   exit (status);
 }
 
@@ -200,6 +207,21 @@ filter_symbols (abfd, osyms, isyms, symcount)
   return dst_count;
 }
 
+/* Keep only every `copy_byte'th byte in MEMHUNK, which is *SIZE bytes long.
+   Adjust *SIZE.  */
+
+void
+filter_bytes (memhunk, size)
+     char *memhunk;
+     bfd_size_type *size;
+{
+  char *from = memhunk + copy_byte, *to = memhunk, *end = memhunk + *size;
+
+  for (; from < end; from += interleave)
+    *to++ = *from;
+  *size /= interleave;
+}
+
 /* Copy object file IBFD onto OBFD.  */
 
 static void
@@ -266,9 +288,9 @@ copy_object (ibfd, obfd)
 
   /* bfd mandates that all output sections be created and sizes set before
      any output is done.  Thus, we traverse all sections multiple times.  */
-  bfd_map_over_sections (ibfd, setup_sections, (void *) obfd);
-  bfd_map_over_sections (ibfd, copy_sections, (void *) obfd);
-  bfd_map_over_sections (ibfd, mangle_sections, (void *) obfd);
+  bfd_map_over_sections (ibfd, setup_section, (void *) obfd);
+  bfd_map_over_sections (ibfd, copy_section, (void *) obfd);
+  bfd_map_over_sections (ibfd, mangle_section, (void *) obfd);
 }
 
 static char *
@@ -368,6 +390,7 @@ copy_file (input_filename, output_filename, input_target, output_target)
      char *output_target;
 {
   bfd *ibfd;
+  char **matching;
 
   /* To allow us to do "strip *" without dying on the first
      non-object file, failures are nonfatal.  */
@@ -378,7 +401,16 @@ copy_file (input_filename, output_filename, input_target, output_target)
       nonfatal (input_filename);
     }
 
-  if (bfd_check_format (ibfd, bfd_object))
+  if (bfd_check_format (ibfd, bfd_archive))
+    {
+      bfd *obfd = bfd_openw (output_filename, output_target);
+      if (obfd == NULL)
+       {
+         nonfatal (output_filename);
+       }
+      copy_archive (ibfd, obfd, output_target);
+    }
+  else if (bfd_check_format_matches (ibfd, bfd_object, &matching))
     {
       bfd *obfd = bfd_openw (output_filename, output_target);
       if (obfd == NULL)
@@ -398,20 +430,15 @@ copy_file (input_filename, output_filename, input_target, output_target)
          nonfatal (input_filename);
        }
     }
-  else if (bfd_check_format (ibfd, bfd_archive))
+  else
     {
-      bfd *obfd = bfd_openw (output_filename, output_target);
-      if (obfd == NULL)
+      bfd_nonfatal (input_filename);
+      if (bfd_error == file_ambiguously_recognized)
        {
-         nonfatal (output_filename);
+         list_matching_formats (matching);
+         free (matching);
        }
-      copy_archive (ibfd, obfd, output_target);
-    }
-  else
-    {
-      /* Get the right error message.  */
-      bfd_check_format (ibfd, bfd_object);
-      nonfatal (input_filename);
+      status = 1;
     }
 }
 
@@ -419,7 +446,7 @@ copy_file (input_filename, output_filename, input_target, output_target)
    as ISECTION in IBFD.  */
 
 static void
-setup_sections (ibfd, isection, obfd)
+setup_section (ibfd, isection, obfd)
      bfd *ibfd;
      sec_ptr isection;
      bfd *obfd;
@@ -493,7 +520,7 @@ loser:
    If stripping then don't copy any relocation info.  */
 
 static void
-copy_sections (ibfd, isection, obfd)
+copy_section (ibfd, isection, obfd)
      bfd *ibfd;
      sec_ptr isection;
      bfd *obfd;
@@ -544,6 +571,9 @@ copy_sections (ibfd, isection, obfd)
          nonfatal (bfd_get_filename (ibfd));
        }
 
+      if (copy_byte >= 0)
+       filter_bytes (memhunk, &size);
+
       if (!bfd_set_section_contents (obfd, osection, memhunk, (file_ptr) 0,
                                     size))
        {
@@ -559,7 +589,7 @@ copy_sections (ibfd, isection, obfd)
    their new location in the output file, through some complex sums.  */
 
 static void
-mangle_sections (ibfd, p, obfd)
+mangle_section (ibfd, p, obfd)
      bfd *ibfd;
      asection *p;
      bfd *obfd;
@@ -666,6 +696,7 @@ strip_main (argc, argv)
        {
        case 'I':
          input_target = optarg;
+         break;
        case 'O':
          output_target = optarg;
          break;
@@ -747,20 +778,38 @@ copy_main (argc, argv)
   boolean show_version = false;
   int c;
 
-  while ((c = getopt_long (argc, argv, "I:s:O:d:F:b:SgxXVv",
+  while ((c = getopt_long (argc, argv, "b:i:I:s:O:d:F:SgxXVv",
                           copy_options, (int *) 0)) != EOF)
     {
       switch (c)
        {
+       case 'b':
+         copy_byte = atoi(optarg);
+         if (copy_byte < 0)
+           {
+             fprintf (stderr, "%s: byte number must be non-negative\n",
+                      program_name);
+             exit (1);
+           }
+         break;
+       case 'i':
+         interleave = atoi(optarg);
+         if (interleave < 1)
+           {
+             fprintf(stderr, "%s: interleave must be positive\n",
+                     program_name);
+             exit (1);
+           }
+         break;
        case 'I':
        case 's':               /* "source" - 'I' is preferred */
          input_target = optarg;
+         break;
        case 'O':
        case 'd':               /* "destination" - 'O' is preferred */
          output_target = optarg;
          break;
        case 'F':
-       case 'b':               /* "both" - 'F' is preferred */
          input_target = output_target = optarg;
          break;
        case 'S':
@@ -796,6 +845,13 @@ copy_main (argc, argv)
       exit (0);
     }
 
+  if (copy_byte >= interleave)
+    {
+      fprintf (stderr, "%s: byte number must be less than interleave\n",
+              program_name);
+      exit (1);
+    }
+
   if (optind == argc || optind + 2 < argc)
     copy_usage (stderr, 1);
 
@@ -836,6 +892,7 @@ main (argc, argv)
      char *argv[];
 {
   program_name = argv[0];
+  xmalloc_set_program_name (program_name);
   strip_symbols = strip_undef;
   discard_locals = locals_undef;
 
This page took 0.027308 seconds and 4 git commands to generate.