Define SKIP_ZEROES as 32 for tic4x target in order to ensure proper
[deliverable/binutils-gdb.git] / binutils / objcopy.c
index bc32c02ba96894e00da1adc179be46345ee326cd..978e9c11604be431e6d93d1a8e6e3e67433e67ae 100644 (file)
@@ -1,6 +1,6 @@
 /* objcopy.c -- copy object file from input to output, optionally massaging it.
    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001
+   2001, 2002
    Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
@@ -32,7 +32,7 @@
 /* A list of symbols to explicitly strip out, or to keep.  A linked
    list is good enough for a small number from the command line, but
    this will slow things down a lot if many symbols are being
-   deleted. */
+   deleted.  */
 
 struct symlist
 {
@@ -97,7 +97,7 @@ static asymbol **osympp = NULL;       /* Output symbols that survive stripping */
 static int copy_byte = -1;
 static int interleave = 4;
 
-static boolean verbose;                /* Print file and target names. */
+static boolean verbose;                /* Print file and target names.  */
 static boolean preserve_dates; /* Preserve input file timestamp.  */
 static int status = 0;         /* Exit status.  */
 
@@ -110,7 +110,7 @@ enum strip_action
     STRIP_ALL                  /* strip all symbols */
   };
 
-/* Which symbols to remove. */
+/* Which symbols to remove.  */
 static enum strip_action strip_symbols;
 
 enum locals_action
@@ -339,7 +339,7 @@ extern char *program_name;
 
 /* This flag distinguishes between strip and objcopy:
    1 means this is 'strip'; 0 means this is 'objcopy'.
-   -1 means if we should use argv[0] to decide. */
+   -1 means if we should use argv[0] to decide.  */
 extern int is_strip;
 
 /* The maximum length of an S record.  This variable is declared in srec.c
@@ -440,7 +440,7 @@ strip_usage (stream, exit_status)
   -p --preserve-dates              Copy modified/access timestamps to the output\n\
   -R --remove-section=<name>       Remove section <name> from the output\n\
   -s --strip-all                   Remove all symbol and relocation information\n\
-  -g -S --strip-debug              Remove all debugging symbols\n\
+  -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\
   -K --keep-symbol=<name>          Only copy symbol <name>\n\
@@ -564,7 +564,7 @@ add_specific_symbol (name, list)
   *list = tmp_list;
 }
 
-/* Add symbols listed in `filename' to strip_specific_list. */
+/* Add symbols listed in `filename' to strip_specific_list.  */
 
 #define IS_WHITESPACE(c)      ((c) == ' ' || (c) == '\t')
 #define IS_LINE_TERMINATOR(c) ((c) == '\n' || (c) == '\r' || (c) == '\0')
@@ -579,7 +579,7 @@ add_specific_symbols (filename, list)
   char * line;
   char * buffer;
   unsigned int line_count;
-  
+
   if (stat (filename, & st) < 0)
     fatal (_("cannot stat: %s: %s"), filename, strerror (errno));
   if (st.st_size == 0)
@@ -598,7 +598,7 @@ add_specific_symbols (filename, list)
   buffer [st.st_size + 1] = '\0';
 
   line_count = 1;
-  
+
   for (line = buffer; * line != '\0'; line ++)
     {
       char * eol;
@@ -617,7 +617,7 @@ add_specific_symbols (filename, list)
                ++ eol;
              finished = true;
              break;
-             
+
            case '\r':
              * eol = '\0';
              /* Cope with \r\n.  */
@@ -625,18 +625,18 @@ add_specific_symbols (filename, list)
                ++ eol;
              finished = true;
              break;
-             
+
            case 0:
              finished = true;
              break;
-             
+
            case '#':
              /* Line comment, Terminate the line here, in case a
                 name is present and then allow the rest of the
                 loop to find the real end of the line.  */
              * eol = '\0';
              break;
-             
+
            default:
              break;
            }
@@ -653,8 +653,8 @@ add_specific_symbols (filename, list)
       for (name_end = name;
           (! IS_WHITESPACE (* name_end))
           && (! IS_LINE_TERMINATOR (* name_end));
-           name_end ++)
-        ;
+          name_end ++)
+       ;
 
       if (! IS_LINE_TERMINATOR (* name_end))
        {
@@ -667,7 +667,7 @@ add_specific_symbols (filename, list)
            non_fatal (_("Ignoring rubbish found on line %d of %s"),
                       line_count, filename);
        }
-  
+
       * name_end = '\0';
 
       if (name_end > name)
@@ -797,7 +797,7 @@ filter_symbols (abfd, obfd, osyms, isyms, symcount)
                   && ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
                       & BSF_KEEP) != 0))
        keep = 1;
-      else if (relocatable                     /* Relocatable file. */
+      else if (relocatable                     /* Relocatable file.  */
               && (flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
        keep = 1;
       else if (bfd_decode_symclass (sym) == 'I')
@@ -960,8 +960,8 @@ copy_object (ibfd, obfd)
     start = bfd_get_start_address (ibfd);
   start += change_start;
 
-  /* Neither the start address nor the flags 
-     need to be set for a core file. */
+  /* Neither the start address nor the flags
+     need to be set for a core file.  */
   if (bfd_get_format (obfd) != bfd_core)
     {
       if (!bfd_set_start_address (obfd, start)
@@ -973,7 +973,9 @@ copy_object (ibfd, obfd)
 
   /* Copy architecture of input file to output file.  */
   if (!bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
-                         bfd_get_mach (ibfd)))
+                         bfd_get_mach (ibfd))
+      && (ibfd->target_defaulted
+         || bfd_get_arch (ibfd) != bfd_get_arch (obfd)))
     non_fatal (_("Warning: Output file cannot represent architecture %s"),
               bfd_printable_arch_mach (bfd_get_arch (ibfd),
                                        bfd_get_mach (ibfd)));
@@ -1088,8 +1090,8 @@ copy_object (ibfd, obfd)
                                              size + (gap_stop - gap_start)))
                    {
                      non_fatal (_("Can't fill gap after %s: %s"),
-                              bfd_get_section_name (obfd, osections[i]),
-                              bfd_errmsg (bfd_get_error ()));
+                                bfd_get_section_name (obfd, osections[i]),
+                                bfd_errmsg (bfd_get_error ()));
                      status = 1;
                      break;
                    }
@@ -1113,8 +1115,8 @@ copy_object (ibfd, obfd)
                                          pad_to - lma))
                {
                  non_fatal (_("Can't add padding to %s: %s"),
-                          bfd_get_section_name (obfd, osections[c - 1]),
-                          bfd_errmsg (bfd_get_error ()));
+                            bfd_get_section_name (obfd, osections[c - 1]),
+                            bfd_errmsg (bfd_get_error ()));
                  status = 1;
                }
              else
@@ -1268,6 +1270,13 @@ copy_object (ibfd, obfd)
     }
 }
 
+#undef MKDIR
+#if defined (_WIN32) && !defined (__CYGWIN32__)
+#define MKDIR(DIR, MODE) mkdir (DIR)
+#else
+#define MKDIR(DIR, MODE) mkdir (DIR, MODE)
+#endif
+
 /* Read each archive element in turn from IBFD, copy the
    contents to temp file, and keep the temp file handle.  */
 
@@ -1280,7 +1289,7 @@ copy_archive (ibfd, obfd, output_target)
   struct name_list
     {
       struct name_list *next;
-      char *name;
+      const char *name;
       bfd *obfd;
     } *list, *l;
   bfd **ptr = &obfd->archive_head;
@@ -1288,11 +1297,7 @@ copy_archive (ibfd, obfd, output_target)
   char *dir = make_tempname (bfd_get_filename (obfd));
 
   /* Make a temp directory to hold the contents.  */
-#if defined (_WIN32) && !defined (__CYGWIN32__)
-  if (mkdir (dir) != 0)
-#else
-  if (mkdir (dir, 0700) != 0)
-#endif
+  if (MKDIR (dir, 0700) != 0)
     {
       fatal (_("cannot mkdir %s for archive copying (error: %s)"),
             dir, strerror (errno));
@@ -1308,14 +1313,35 @@ copy_archive (ibfd, obfd, output_target)
 
   while (!status && this_element != (bfd *) NULL)
     {
-      /* Create an output file for this member.  */
-      char *output_name = concat (dir, "/", bfd_get_filename (this_element),
-                                 (char *) NULL);
-      bfd *output_bfd = bfd_openw (output_name, output_target);
+      char *output_name;
+      bfd *output_bfd;
       bfd *last_element;
       struct stat buf;
       int stat_status = 0;
 
+      /* Create an output file for this member.  */
+      output_name = concat (dir, "/",
+                           bfd_get_filename (this_element), (char *) 0);
+
+      /* If the file already exists, make another temp dir.  */
+      if (stat (output_name, &buf) >= 0)
+       {
+         output_name = make_tempname (output_name);
+         if (MKDIR (output_name, 0700) != 0)
+           {
+             fatal (_("cannot mkdir %s for archive copying (error: %s)"),
+                    output_name, strerror (errno));
+           }
+         l = (struct name_list *) xmalloc (sizeof (struct name_list));
+         l->name = output_name;
+         l->next = list;
+         l->obfd = NULL;
+         list = l;
+         output_name = concat (output_name, "/",
+                               bfd_get_filename (this_element), (char *) 0);
+       }
+
+      output_bfd = bfd_openw (output_name, output_target);
       if (preserve_dates)
        {
          stat_status = bfd_stat_arch_elt (this_element, &buf);
@@ -1339,7 +1365,7 @@ copy_archive (ibfd, obfd, output_target)
       if (!bfd_close (output_bfd))
        {
          bfd_nonfatal (bfd_get_filename (output_bfd));
-         /* Error in new object file. Don't change archive. */
+         /* Error in new object file. Don't change archive.  */
          status = 1;
        }
 
@@ -1371,8 +1397,13 @@ copy_archive (ibfd, obfd, output_target)
   /* Delete all the files that we opened.  */
   for (l = list; l != NULL; l = l->next)
     {
-      bfd_close (l->obfd);
-      unlink (l->name);
+      if (l->obfd == NULL)
+       rmdir (l->name);
+      else
+       {
+         bfd_close (l->obfd);
+         unlink (l->name);
+       }
     }
   rmdir (dir);
 }
@@ -1387,7 +1418,8 @@ copy_file (input_filename, output_filename, input_target, output_target)
      const char *output_target;
 {
   bfd *ibfd;
-  char **matching;
+  char **obj_matching;
+  char **core_matching;
 
   /* To allow us to do "strip *" without dying on the first
      non-object file, failures are nonfatal.  */
@@ -1410,11 +1442,10 @@ copy_file (input_filename, output_filename, input_target, output_target)
 
       copy_archive (ibfd, obfd, output_target);
     }
-  else if (bfd_check_format_matches (ibfd, bfd_object, &matching)
-          || bfd_check_format_matches (ibfd, bfd_core, &matching))
+  else if (bfd_check_format_matches (ibfd, bfd_object, &obj_matching))
     {
       bfd *obfd;
-
+    do_copy:
       /* bfd_get_target does not return the correct value until
          bfd_check_format succeeds.  */
       if (output_target == NULL)
@@ -1434,12 +1465,33 @@ copy_file (input_filename, output_filename, input_target, output_target)
     }
   else
     {
+      bfd_error_type obj_error = bfd_get_error ();
+      bfd_error_type core_error;
+      
+      if (bfd_check_format_matches (ibfd, bfd_core, &core_matching))
+       {
+         /* This probably can't happen..  */
+         if (obj_error == bfd_error_file_ambiguously_recognized)
+           free (obj_matching);
+         goto do_copy;
+       }
+
+      core_error = bfd_get_error ();
+      /* Report the object error in preference to the core error.  */
+      if (obj_error != core_error)
+       bfd_set_error (obj_error);
+
       bfd_nonfatal (input_filename);
 
-      if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
+      if (obj_error == bfd_error_file_ambiguously_recognized)
+       {
+         list_matching_formats (obj_matching);
+         free (obj_matching);
+       }
+      if (core_error == bfd_error_file_ambiguously_recognized)
        {
-         list_matching_formats (matching);
-         free (matching);
+         list_matching_formats (core_matching);
+         free (core_matching);
        }
 
       status = 1;
@@ -1464,7 +1516,7 @@ add_section_rename (old_name, new_name, flags)
        if (strcmp (rename->new_name, new_name) == 0
            && rename->flags == flags)
          return;
-       
+
        fatal (_("Multiple renames of section %s"), old_name);
       }
 
@@ -1474,7 +1526,7 @@ add_section_rename (old_name, new_name, flags)
   rename->new_name = new_name;
   rename->flags    = flags;
   rename->next     = section_rename_list;
-  
+
   section_rename_list = rename;
 }
 
@@ -1524,7 +1576,7 @@ setup_section (ibfd, isection, obfdarg)
   flagword flags;
   const char *err;
   const char * name;
-  
+
   if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
       && (strip_symbols == STRIP_DEBUG
          || strip_symbols == STRIP_UNNEEDED
@@ -1544,7 +1596,7 @@ setup_section (ibfd, isection, obfdarg)
 
   /* Get the, possibly new, name of the output section.  */
   name = find_section_rename (ibfd, isection, & flags);
-  
+
   osection = bfd_make_section_anyway (obfd, name);
 
   if (osection == NULL)
@@ -1655,13 +1707,15 @@ copy_section (ibfd, isection, obfdarg)
   sec_ptr osection;
   bfd_size_type size;
   long relsize;
+  flagword flags;
 
   /* If we have already failed earlier on,
      do not keep on generating complaints now.  */
   if (status != 0)
     return;
 
-  if ((bfd_get_section_flags (ibfd, isection) & SEC_DEBUGGING) != 0
+  flags = bfd_get_section_flags (ibfd, isection);
+  if ((flags & SEC_DEBUGGING) != 0
       && (strip_symbols == STRIP_DEBUG
          || strip_symbols == STRIP_UNNEEDED
          || strip_symbols == STRIP_ALL
@@ -1669,6 +1723,9 @@ copy_section (ibfd, isection, obfdarg)
          || 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)
@@ -1682,7 +1739,7 @@ copy_section (ibfd, isection, obfdarg)
   if (size == 0 || osection == 0)
     return;
 
-  /* Core files do not need to be relocated. */
+  /* Core files do not need to be relocated.  */
   if (bfd_get_format (obfd) == bfd_core)
     relsize = 0;
   else
@@ -1703,7 +1760,7 @@ copy_section (ibfd, isection, obfdarg)
       if (strip_symbols == STRIP_ALL)
        {
          /* Remove relocations which are not in
-            keep_strip_specific_list. */
+            keep_strip_specific_list.  */
          arelent **temp_relpp;
          long temp_relcount = 0;
          long i;
@@ -1726,7 +1783,7 @@ copy_section (ibfd, isection, obfdarg)
   isection->_cooked_size = isection->_raw_size;
   isection->reloc_done = true;
 
-  if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS 
+  if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS
       && bfd_get_section_flags (obfd, osection) & SEC_HAS_CONTENTS)
     {
       PTR memhunk = (PTR) xmalloc ((unsigned) size);
@@ -2095,9 +2152,9 @@ copy_main (argc, argv)
            fatal (_("byte number must be non-negative"));
          break;
 
-        case 'B':
-          binary_architecture = optarg;
-          break;
+       case 'B':
+         binary_architecture = optarg;
+         break;
 
        case 'i':
          interleave = atoi (optarg);
@@ -2463,13 +2520,13 @@ copy_main (argc, argv)
          set_start_set = true;
          break;
 
-        case OPTION_SREC_LEN:
-          Chunk = parse_vma (optarg, "--srec-len");
-          break;
+       case OPTION_SREC_LEN:
+         Chunk = parse_vma (optarg, "--srec-len");
+         break;
 
-        case OPTION_SREC_FORCES3:
+       case OPTION_SREC_FORCES3:
          S3Forced = true;
-          break;
+         break;
 
        case OPTION_STRIP_SYMBOLS:
          add_specific_symbols (optarg, &strip_specific_list);
@@ -2532,16 +2589,16 @@ copy_main (argc, argv)
   if (binary_architecture != (char *) NULL)
     {
       if (input_target && strcmp (input_target, "binary") == 0)
-        {
-          const bfd_arch_info_type * temp_arch_info;
+       {
+         const bfd_arch_info_type * temp_arch_info;
 
          temp_arch_info = bfd_scan_arch (binary_architecture);
 
-          if (temp_arch_info != NULL)
-            bfd_external_binary_architecture = temp_arch_info->arch;
-          else
-            fatal (_("architecture %s unknown"), binary_architecture);
-        }
+         if (temp_arch_info != NULL)
+           bfd_external_binary_architecture = temp_arch_info->arch;
+         else
+           fatal (_("architecture %s unknown"), binary_architecture);
+       }
       else
        {
          non_fatal (_("Warning: input target 'binary' required for binary architecture parameter."));
This page took 0.029479 seconds and 4 git commands to generate.