]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - binutils/objcopy.c
Revert "2.41 Release sources"
[thirdparty/binutils-gdb.git] / binutils / objcopy.c
index 3569b890c7d74728c5277edc68d14ab12d1a631b..b2b7ab6ab7e0dca029d8725734eb50fb5801f5d4 100644 (file)
@@ -803,6 +803,7 @@ parse_flags (const char *s)
       PARSE_FLAG ("contents", SEC_HAS_CONTENTS);
       PARSE_FLAG ("merge", SEC_MERGE);
       PARSE_FLAG ("strings", SEC_STRINGS);
+      PARSE_FLAG ("large", SEC_ELF_LARGE);
 #undef PARSE_FLAG
       else
        {
@@ -812,8 +813,10 @@ parse_flags (const char *s)
          strncpy (copy, s, len);
          copy[len] = '\0';
          non_fatal (_("unrecognized section flag `%s'"), copy);
-         fatal (_("supported flags: %s"),
-                "alloc, load, noload, readonly, debug, code, data, rom, exclude, share, contents, merge, strings");
+         fatal (_ ("supported flags: %s"),
+                "alloc, load, noload, readonly, debug, code, data, rom, "
+                "exclude, contents, merge, strings, (COFF specific) share, "
+                "(ELF x86-64 specific) large");
        }
 
       s = snext;
@@ -2618,7 +2621,7 @@ merge_gnu_build_notes (bfd *          abfd,
 }
 
 static flagword
-check_new_section_flags (flagword flags, bfd * abfd, const char * secname)
+check_new_section_flags (flagword flags, bfd *abfd, const char * secname)
 {
   /* Only set the SEC_COFF_SHARED flag on COFF files.
      The same bit value is used by ELF targets to indicate
@@ -2631,6 +2634,19 @@ check_new_section_flags (flagword flags, bfd * abfd, const char * secname)
                 bfd_get_filename (abfd), secname);
       flags &= ~ SEC_COFF_SHARED;
     }
+
+  /* Report a fatal error if 'large' is used with a non-x86-64 ELF target.
+     Suppress the error for non-ELF targets to allow -O binary and formats that
+     use the bit value SEC_ELF_LARGE for other purposes.  */
+  if ((flags & SEC_ELF_LARGE) != 0
+      && bfd_get_flavour (abfd) == bfd_target_elf_flavour
+      && get_elf_backend_data (abfd)->elf_machine_code != EM_X86_64)
+    {
+      fatal (_ ("%s[%s]: 'large' flag is ELF x86-64 specific"),
+            bfd_get_filename (abfd), secname);
+      flags &= ~SEC_ELF_LARGE;
+    }
+
   return flags;
 }
 
@@ -3599,9 +3615,11 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
     } *list, *l;
   bfd **ptr = &obfd->archive_head;
   bfd *this_element;
-  char *dir;
+  char *dir = NULL;
   char *filename;
 
+  list = NULL;
+
   /* PR 24281: It is not clear what should happen when copying a thin archive.
      One part is straight forward - if the output archive is in a different
      directory from the input archive then any relative paths in the library
@@ -3620,7 +3638,7 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
       bfd_set_error (bfd_error_invalid_operation);
       bfd_nonfatal_message (NULL, ibfd, NULL,
                            _("sorry: copying thin archives is not currently supported"));
-      return;
+      goto cleanup_and_exit;
     }
 
   /* Make a temp directory to hold the contents.  */
@@ -3638,8 +3656,6 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
   if (deterministic)
     obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
 
-  list = NULL;
-
   this_element = bfd_openr_next_archived_file (ibfd, NULL);
 
   if (!bfd_set_format (obfd, bfd_get_format (ibfd)))
@@ -3781,44 +3797,46 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
     }
   *ptr = NULL;
 
+ cleanup_and_exit:
   filename = xstrdup (bfd_get_filename (obfd));
   if (!(status == 0 ? bfd_close : bfd_close_all_done) (obfd))
     {
+      if (!status)
+       bfd_nonfatal_message (filename, NULL, NULL, NULL);
       status = 1;
-      bfd_nonfatal_message (filename, NULL, NULL, NULL);
     }
   free (filename);
 
   filename = xstrdup (bfd_get_filename (ibfd));
   if (!bfd_close (ibfd))
     {
+      if (!status)
+       bfd_nonfatal_message (filename, NULL, NULL, NULL);
       status = 1;
-      bfd_nonfatal_message (filename, NULL, NULL, NULL);
     }
   free (filename);
 
- cleanup_and_exit:
   /* Delete all the files that we opened.  */
-  {
-    struct name_list * next;
-
-    for (l = list; l != NULL; l = next)
-      {
-       if (l->obfd == NULL)
-         rmdir (l->name);
-       else
-         {
-           bfd_close (l->obfd);
-           unlink (l->name);
-         }
-       free ((char *) l->name);
-       next = l->next;
-       free (l);
-      }
-  }
+  struct name_list *next;
+  for (l = list; l != NULL; l = next)
+    {
+      if (l->obfd == NULL)
+       rmdir (l->name);
+      else
+       {
+         bfd_close (l->obfd);
+         unlink (l->name);
+       }
+      free ((char *) l->name);
+      next = l->next;
+      free (l);
+    }
 
-  rmdir (dir);
-  free (dir);
+  if (dir)
+    {
+      rmdir (dir);
+      free (dir);
+    }
 }
 
 /* The top-level control.  */
@@ -3917,7 +3935,8 @@ copy_file (const char *input_filename, const char *output_filename, int ofd,
 
       if (obfd == NULL)
        {
-         close (ofd);
+         if (ofd >= 0)
+           close (ofd);
          bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
          bfd_close (ibfd);
          status = 1;
@@ -3950,7 +3969,8 @@ copy_file (const char *input_filename, const char *output_filename, int ofd,
 
       if (obfd == NULL)
        {
-         close (ofd);
+         if (ofd >= 0)
+           close (ofd);
          bfd_nonfatal_message (output_filename, NULL, NULL, NULL);
          bfd_close (ibfd);
          status = 1;
@@ -4141,13 +4161,25 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
       flags = p->flags | (flags & (SEC_HAS_CONTENTS | SEC_RELOC));
       flags = check_new_section_flags (flags, obfd, bfd_section_name (isection));
     }
-  else if (strip_symbols == STRIP_NONDEBUG
-          && (flags & (SEC_ALLOC | SEC_GROUP)) != 0
-          && !is_nondebug_keep_contents_section (ibfd, isection))
+  else
     {
-      flagword clr = SEC_HAS_CONTENTS | SEC_LOAD | SEC_GROUP;
-
-      if (bfd_get_flavour (obfd) == bfd_target_elf_flavour)
+      flagword clr = 0;
+
+      /* For --extract-symbols where section sizes are zeroed, clear
+        SEC_LOAD to indicate to coff_compute_section_file_positions that
+        section sizes should not be adjusted for ALIGN_SECTIONS_IN_FILE.
+        We don't want to clear SEC_HAS_CONTENTS as that will result
+        in symbols being classified as 'B' by nm.  */
+      if (extract_symbol)
+       clr = SEC_LOAD;
+      /* If only keeping debug sections then we'll be keeping section
+        sizes in headers but making the sections have no contents.  */
+      else if (strip_symbols == STRIP_NONDEBUG
+              && (flags & (SEC_ALLOC | SEC_GROUP)) != 0
+              && !is_nondebug_keep_contents_section (ibfd, isection))
+       clr = SEC_HAS_CONTENTS | SEC_LOAD | SEC_GROUP;
+
+      if (clr && bfd_get_flavour (obfd) == bfd_target_elf_flavour)
        {
          /* PR 29532: Copy group sections intact as otherwise we end up with
             empty groups.  This prevents separate debug info files from
@@ -4155,7 +4187,7 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
             originally contained groups.  */
          if (flags & SEC_GROUP)
            clr = SEC_LOAD;
-         else
+         if ((clr & SEC_HAS_CONTENTS) != 0)
            make_nobits = true;
 
          /* Twiddle the input section flags so that it seems to