PowerPC: Don't generate unused section symbols
[binutils-gdb.git] / bfd / coffcode.h
index cd495dbe6185f933e87ce63e0feb9677fcae98ba..2fd699ff1b82818950d858a3dce2697b42f6d4a0 100644 (file)
@@ -1,5 +1,5 @@
 /* Support for the generic parts of most COFF variants, for BFD.
-   Copyright (C) 1990-2020 Free Software Foundation, Inc.
+   Copyright (C) 1990-2021 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -364,6 +364,10 @@ CODE_FRAGMENT
 #define GNU_LINKONCE_WT ".gnu.linkonce.wt."
 #define DOT_RELOC      ".reloc"
 
+#if defined(COFF_WITH_PE) || defined(COFF_GO32_EXE) || defined(COFF_GO32)
+# define COFF_WITH_EXTENDED_RELOC_COUNTER
+#endif
+
 #if defined (COFF_LONG_SECTION_NAMES)
 /* Needed to expand the inputs to BLANKOR1TOODD.  */
 #define COFFLONGSECTIONCATHELPER(x,y)    x ## y
@@ -441,14 +445,6 @@ static void * coff_mkobject_hook
 static flagword handle_COMDAT
   (bfd *, flagword, void *, const char *, asection *);
 #endif
-#ifdef COFF_IMAGE_WITH_PE
-static bfd_boolean coff_read_word
-  (bfd *, unsigned int *);
-static unsigned int coff_compute_checksum
-  (bfd *);
-static bfd_boolean coff_apply_checksum
-  (bfd *);
-#endif
 #ifdef TICOFF
 static bfd_boolean ticoff0_bad_format_hook
   (bfd *, void * );
@@ -717,7 +713,7 @@ sec_to_styp_flags (const char *sec_name, flagword sec_flags)
 #ifndef COFF_WITH_PE
 
 static bfd_boolean
-styp_to_sec_flags (bfd *abfd ATTRIBUTE_UNUSED,
+styp_to_sec_flags (bfd *abfd,
                   void * hdr,
                   const char *name,
                   asection *section ATTRIBUTE_UNUSED,
@@ -850,6 +846,11 @@ styp_to_sec_flags (bfd *abfd ATTRIBUTE_UNUSED,
     sec_flags = (SEC_LOAD | SEC_ALLOC);
 #endif /* STYP_SDATA */
 
+  if ((bfd_applicable_section_flags (abfd) & SEC_SMALL_DATA) != 0
+      && (CONST_STRNEQ (name, ".sbss")
+         || CONST_STRNEQ (name, ".sdata")))
+    sec_flags |= SEC_SMALL_DATA;
+
 #if defined (COFF_LONG_SECTION_NAMES) && defined (COFF_SUPPORT_GNU_LINKONCE)
   /* As a GNU extension, if the name begins with .gnu.linkonce, we
      only link a single copy of the section.  This is used to support
@@ -1312,6 +1313,11 @@ styp_to_sec_flags (bfd *abfd,
        }
     }
 
+  if ((bfd_applicable_section_flags (abfd) & SEC_SMALL_DATA) != 0
+      && (CONST_STRNEQ (name, ".sbss")
+         || CONST_STRNEQ (name, ".sdata")))
+    sec_flags |= SEC_SMALL_DATA;
+
 #if defined (COFF_LONG_SECTION_NAMES) && defined (COFF_SUPPORT_GNU_LINKONCE)
   /* As a GNU extension, if the name begins with .gnu.linkonce, we
      only link a single copy of the section.  This is used to support
@@ -1954,6 +1960,39 @@ coff_set_alignment_hook (bfd *abfd, asection *section, void * scnhdr)
 }
 
 #else /* ! RS6000COFF_C */
+#if defined (COFF_GO32_EXE) || defined (COFF_GO32)
+
+static void
+coff_set_alignment_hook (bfd * abfd, asection * section, void * scnhdr)
+{
+  struct internal_scnhdr *hdr = (struct internal_scnhdr *) scnhdr;
+
+  /* Check for extended relocs.  */
+  if (hdr->s_flags & IMAGE_SCN_LNK_NRELOC_OVFL)
+    {
+      struct external_reloc dst;
+      struct internal_reloc n;
+      const file_ptr oldpos = bfd_tell (abfd);
+      const bfd_size_type relsz = bfd_coff_relsz (abfd);
+
+      if (bfd_seek (abfd, (file_ptr) hdr->s_relptr, 0) != 0)
+       return;
+      if (bfd_bread (& dst, relsz, abfd) != relsz)
+       return;
+
+      coff_swap_reloc_in (abfd, &dst, &n);
+      if (bfd_seek (abfd, oldpos, 0) != 0)
+       return;
+      section->reloc_count = hdr->s_nreloc = n.r_vaddr - 1;
+      section->rel_filepos += relsz;
+    }
+  else if (hdr->s_nreloc == 0xffff)
+    _bfd_error_handler
+      (_("%pB: warning: claims to have 0xffff relocs, without overflow"),
+       abfd);
+}
+
+#else /* ! COFF_GO32_EXE && ! COFF_GO32 */
 
 static void
 coff_set_alignment_hook (bfd *abfd ATTRIBUTE_UNUSED,
@@ -1962,6 +2001,7 @@ coff_set_alignment_hook (bfd *abfd ATTRIBUTE_UNUSED,
 {
 }
 
+#endif /* ! COFF_GO32_EXE && ! COFF_GO32 */
 #endif /* ! RS6000COFF_C */
 #endif /* ! COFF_WITH_PE */
 #endif /* ! COFF_ALIGN_IN_SECTION_HEADER */
@@ -2066,15 +2106,6 @@ coff_mkobject_hook (bfd * abfd,
     abfd->flags |= HAS_DEBUG;
 #endif
 
-  if ((internal_f->f_flags & F_GO32STUB) != 0)
-    {
-      coff->go32stub = (char *) bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE);
-      if (coff->go32stub == NULL)
-       return NULL;
-    }
-  if (coff->go32stub != NULL)
-    memcpy (coff->go32stub, internal_f->go32stub, GO32_STUBSIZE);
-
   return coff;
 }
 #endif
@@ -2097,11 +2128,6 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr)
   machine = 0;
   switch (internal_f->f_magic)
     {
-#ifdef PPCMAGIC
-    case PPCMAGIC:
-      arch = bfd_arch_powerpc;
-      break;
-#endif
 #ifdef I386MAGIC
     case I386MAGIC:
     case I386PTXMAGIC:
@@ -2520,8 +2546,8 @@ coff_write_relocs (bfd * abfd, int first_undef)
       if (bfd_seek (abfd, s->rel_filepos, SEEK_SET) != 0)
        return FALSE;
 
-#ifdef COFF_WITH_PE
-      if (obj_pe (abfd) && s->reloc_count >= 0xffff)
+#ifdef COFF_WITH_EXTENDED_RELOC_COUNTER
+      if ((obj_pe (abfd) || obj_go32 (abfd)) && s->reloc_count >= 0xffff)
        {
          /* Encode real count here as first reloc.  */
          struct internal_reloc n;
@@ -2627,8 +2653,7 @@ coff_write_relocs (bfd * abfd, int first_undef)
        }
 
 #ifdef TARG_AUX
-      if (p != NULL)
-       free (p);
+      free (p);
 #endif
     }
 
@@ -2752,12 +2777,6 @@ coff_set_flags (bfd * abfd,
       return TRUE;
 #endif
 
-#ifdef PPCMAGIC
-    case bfd_arch_powerpc:
-      *magicp = PPCMAGIC;
-      return TRUE;
-#endif
-
 #if defined(I386MAGIC) || defined(AMD64MAGIC)
     case bfd_arch_i386:
 #if defined(I386MAGIC)
@@ -2810,9 +2829,7 @@ coff_set_flags (bfd * abfd,
 
 #ifdef RS6000COFF_C
     case bfd_arch_rs6000:
-#ifndef PPCMAGIC
     case bfd_arch_powerpc:
-#endif
       BFD_ASSERT (bfd_get_flavour (abfd) == bfd_target_xcoff_flavour);
       *magicp = bfd_xcoff_magic_number (abfd);
       return TRUE;
@@ -3249,11 +3266,8 @@ coff_compute_section_file_positions (bfd * abfd)
 
 #ifdef COFF_IMAGE_WITH_PE
 
-static unsigned int pelength;
-static unsigned int peheader;
-
 static bfd_boolean
-coff_read_word (bfd *abfd, unsigned int *value)
+coff_read_word (bfd *abfd, unsigned int *value, unsigned int *pelength)
 {
   unsigned char b[2];
   int status;
@@ -3270,13 +3284,13 @@ coff_read_word (bfd *abfd, unsigned int *value)
   else
     *value = (unsigned int) (b[0] + (b[1] << 8));
 
-  pelength += (unsigned int) status;
+  *pelength += status;
 
   return TRUE;
 }
 
 static unsigned int
-coff_compute_checksum (bfd *abfd)
+coff_compute_checksum (bfd *abfd, unsigned int *pelength)
 {
   bfd_boolean more_data;
   file_ptr filepos;
@@ -3284,7 +3298,7 @@ coff_compute_checksum (bfd *abfd)
   unsigned int total;
 
   total = 0;
-  pelength = 0;
+  *pelength = 0;
   filepos = (file_ptr) 0;
 
   do
@@ -3292,7 +3306,7 @@ coff_compute_checksum (bfd *abfd)
       if (bfd_seek (abfd, filepos, SEEK_SET) != 0)
        return 0;
 
-      more_data = coff_read_word (abfd, &value);
+      more_data = coff_read_word (abfd, &value, pelength);
       total += value;
       total = 0xffff & (total + (total >> 0x10));
       filepos += 2;
@@ -3307,11 +3321,13 @@ coff_apply_checksum (bfd *abfd)
 {
   unsigned int computed;
   unsigned int checksum = 0;
+  unsigned int peheader;
+  unsigned int pelength;
 
   if (bfd_seek (abfd, 0x3c, SEEK_SET) != 0)
     return FALSE;
 
-  if (!coff_read_word (abfd, &peheader))
+  if (!coff_read_word (abfd, &peheader, &pelength))
     return FALSE;
 
   if (bfd_seek (abfd, peheader + 0x58, SEEK_SET) != 0)
@@ -3323,7 +3339,7 @@ coff_apply_checksum (bfd *abfd)
   if (bfd_seek (abfd, peheader, SEEK_SET) != 0)
     return FALSE;
 
-  computed = coff_compute_checksum (abfd);
+  computed = coff_compute_checksum (abfd, &pelength);
 
   checksum = computed + pelength;
 
@@ -3381,9 +3397,9 @@ coff_write_object_contents (bfd * abfd)
   for (current = abfd->sections; current != NULL; current =
        current->next)
     {
-#ifdef COFF_WITH_PE
+#ifdef COFF_WITH_EXTENDED_RELOC_COUNTER
       /* We store the actual reloc count in the first reloc's addr.  */
-      if (obj_pe (abfd) && current->reloc_count >= 0xffff)
+      if ((obj_pe (abfd) || obj_go32 (abfd)) && current->reloc_count >= 0xffff)
        reloc_count ++;
 #endif
       reloc_count += current->reloc_count;
@@ -3411,9 +3427,9 @@ coff_write_object_contents (bfd * abfd)
        {
          current->rel_filepos = reloc_base;
          reloc_base += current->reloc_count * bfd_coff_relsz (abfd);
-#ifdef COFF_WITH_PE
+#ifdef COFF_WITH_EXTENDED_RELOC_COUNTER
          /* Extra reloc to hold real count.  */
-         if (obj_pe (abfd) && current->reloc_count >= 0xffff)
+         if ((obj_pe (abfd) || obj_go32 (abfd)) && current->reloc_count >= 0xffff)
            reloc_base += bfd_coff_relsz (abfd);
 #endif
        }
@@ -3614,7 +3630,7 @@ coff_write_object_contents (bfd * abfd)
          SCNHDR buff;
          bfd_size_type amt = bfd_coff_scnhsz (abfd);
 
-         if (coff_swap_scnhdr_out (abfd, &section, &buff) == 0
+         if (bfd_coff_swap_scnhdr_out (abfd, &section, &buff) == 0
              || bfd_bwrite (& buff, amt, abfd) != amt)
            return FALSE;
        }
@@ -3740,7 +3756,7 @@ coff_write_object_contents (bfd * abfd)
          scnhdr.s_nlnno = current->target_index;
          scnhdr.s_flags = STYP_OVRFLO;
          amt = bfd_coff_scnhsz (abfd);
-         if (coff_swap_scnhdr_out (abfd, &scnhdr, &buff) == 0
+         if (bfd_coff_swap_scnhdr_out (abfd, &scnhdr, &buff) == 0
              || bfd_bwrite (& buff, amt, abfd) != amt)
            return FALSE;
        }
@@ -3748,6 +3764,22 @@ coff_write_object_contents (bfd * abfd)
 #endif
 #endif
 
+#if defined (COFF_GO32_EXE) || defined (COFF_GO32)
+  /* Pad section headers.  */
+  if ((abfd->flags & EXEC_P) && abfd->sections != NULL)
+    {
+      file_ptr cur_ptr = scn_base
+                        + abfd->section_count * bfd_coff_scnhsz (abfd);
+      long fill_size = (abfd->sections->filepos - cur_ptr);
+      bfd_byte *b = bfd_zmalloc (fill_size);
+      if (b)
+       {
+         bfd_bwrite ((PTR)b, fill_size, abfd);
+         free (b);
+       }
+    }
+#endif
+
   /* OK, now set up the filehdr...  */
 
   /* Don't include the internal abs section in the section count */
@@ -3836,11 +3868,6 @@ coff_write_object_contents (bfd * abfd)
     internal_a.magic = ZMAGIC;
 #endif
 
-#if defined(PPC_PE)
-#define __A_MAGIC_SET__
-    internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
-#endif
-
 #if defined MCORE_PE
 #define __A_MAGIC_SET__
     internal_a.magic = IMAGE_NT_OPTIONAL_HDR_MAGIC;
@@ -3922,24 +3949,6 @@ coff_write_object_contents (bfd * abfd)
        return FALSE;
     }
 #endif
-#ifdef COFF_IMAGE_WITH_PE
-#ifdef PPC_PE
-  else if ((abfd->flags & EXEC_P) != 0)
-    {
-      bfd_byte b;
-
-      /* PowerPC PE appears to require that all executable files be
-        rounded up to the page size.  */
-      b = 0;
-      if (bfd_seek (abfd,
-                   (file_ptr) BFD_ALIGN (sym_base, COFF_PAGE_SIZE) - 1,
-                   SEEK_SET) != 0
-         || bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
-       return FALSE;
-    }
-#endif
-#endif
-
   /* If bfd_get_symcount (abfd) != 0, then we are not using the COFF
      backend linker, and obj_raw_syment_count is not valid until after
      coff_write_symbols is called.  */
@@ -4850,6 +4859,12 @@ coff_classify_symbol (bfd *abfd,
     case C_THUMBEXT:
     case C_THUMBEXTFUNC:
 #endif
+#ifdef RS6000COFF_C
+    case C_HIDEXT:
+#if ! defined _AIX52 && ! defined AIX_WEAK_SUPPORT
+    case C_AIX_WEAKEXT:
+#endif
+#endif
 #ifdef C_SYSTEM
     case C_SYSTEM:
 #endif
@@ -4863,6 +4878,10 @@ coff_classify_symbol (bfd *abfd,
          else
            return COFF_SYMBOL_COMMON;
        }
+#ifdef RS6000COFF_C
+      if (syment->n_sclass == C_HIDEXT)
+       return COFF_SYMBOL_LOCAL;
+#endif
       return COFF_SYMBOL_GLOBAL;
 
     default:
@@ -5801,6 +5820,7 @@ const bfd_target VAR =                                                    \
   '/',                         /* AR_pad_char.  */                     \
   15,                          /* AR_max_namelen.  */                  \
   0,                           /* match priority.  */                  \
+  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */ \
                                                                        \
   /* Data conversion functions.  */                                    \
   bfd_getb64, bfd_getb_signed_64, bfd_putb64,                          \
@@ -5862,6 +5882,7 @@ const bfd_target VAR =                                                    \
   '/',                         /* AR_pad_char.  */                     \
   15,                          /* AR_max_namelen.  */                  \
   0,                           /* match priority.  */                  \
+  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */ \
                                                                        \
   /* Data conversion functions.  */                                    \
   bfd_getb64, bfd_getb_signed_64, bfd_putb64,                          \
@@ -5923,6 +5944,7 @@ const bfd_target VAR =                                                    \
   '/',                         /* AR_pad_char.  */                     \
   15,                          /* AR_max_namelen.  */                  \
   0,                           /* match priority.  */                  \
+  TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */ \
                                                                        \
   /* Data conversion functions.  */                                    \
   bfd_getl64, bfd_getl_signed_64, bfd_putl64,                          \