SHF_GNU_MBIND requires ELFOSABI_GNU
authorAlan Modra <amodra@gmail.com>
Tue, 23 Jul 2019 08:24:42 +0000 (17:54 +0930)
committerAlan Modra <amodra@gmail.com>
Tue, 23 Jul 2019 08:52:02 +0000 (18:22 +0930)
When SHF_GNU_MBIND was added in the SHF_LOOS to SHF_HIOS range, it
should have required ELFOSABI_GNU since these flags are already in use
by other OSes.  HPUX SHF_HP_TLS in fact has the same value.  That
means no place in binutils should test SHF_GNU_MBIND without first
checking OSABI, and SHF_GNU_MBIND should not be set without also
setting OSABI.  At least, that's the ideal, but the patch accepts
SHF_GNU_MBIND on ELFOSABI_NONE object files since gas didn't always
set OSABI.  However, to reinforce the fact that SHF_GNU_MBIND isn't
proper without a non-zero OSABI, readelf will display the flag as
LOOS+0 if OSABI isn't set.

The clash with SHF_HP_TLS means that hppa64-linux either has that flag
on .tbss sections or supports GNU_MBIND, not both.  (hppa64-linux
users, if there are any, may have noticed that GNU ld since 2017
mysteriously aligned their .tbss sections to a 4k boundary.  That was
one consequence of SHF_HP_TLS being blindly interpreted as
SHF_GNU_MBIND.)  Since it seems that binutils, gdb, gcc, glibc, and
the linux kernel don't care about SHF_HP_TLS I took that flag out of
.tbss for hppa64-linux.

bfd/
* elf-bfd.h (enum elf_gnu_osabi): Add elf_gnu_osabi_mbind.
* elf.c (_bfd_elf_make_section_from_shdr): Set elf_gnu_osabi_mbind.
(get_program_header_size): Formatting.  Only test SH_GNU_MBIND
when elf_gnu_osabi_mbind is set.
(_bfd_elf_map_sections_to_segments): Likewise.
(_bfd_elf_init_private_section_data): Likewise.
(_bfd_elf_final_write_processing): Update comment.
* elf64-hppa.c (elf64_hppa_special_sections): Move .tbss entry.
(elf_backend_special_sections): Define without .tbss for linux.
binutils/
* readelf.c (get_parisc_segment_type): Split off hpux entries..
(get_ia64_segment_type): ..and these..
(get_hpux_segment_type): ..to here.
(get_segment_type): Condition GNU_MBIND on osabi.  Use
get_hpux_segment_type.
(get_symbol_binding): Do not print UNIQUE for ELFOSABI_NONE.
(get_symbol_type): Do not print IFUNC for ELFOSABI_NONE.
gas/
* config/obj-elf.c (obj_elf_change_section): Don't emit a fatal
error for non-SHF_ALLOC SHF_GNU_MBIND here.
(obj_elf_parse_section_letters): Return SHF_GNU_MBIND in new
gnu_attr param.
(obj_elf_section): Adjust obj_elf_parse_section_letters call.
Formatting.  Set SHF_GNU_MBIND and elf_osabi from gnu_attr.
Emit normal error for non-SHF_ALLOC SHF_GNU_MBIND and wrong osabi.
(obj_elf_type): Set elf_osabi for ifunc.
* testsuite/gas/elf/section12a.d: xfail msp430 and hpux.
* testsuite/gas/elf/section12b.d: Likewise.
* testsuite/gas/elf/section13.d: Likewise.
* testsuite/gas/elf/section13.l: Adjust expected error.
ld/
* emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Condition
SHF_GNU_MBIND on osabi.  Set output elf_gnu_osabi_mbind.

14 files changed:
bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf.c
bfd/elf64-hppa.c
binutils/ChangeLog
binutils/readelf.c
gas/ChangeLog
gas/config/obj-elf.c
gas/testsuite/gas/elf/section12a.d
gas/testsuite/gas/elf/section12b.d
gas/testsuite/gas/elf/section13.d
gas/testsuite/gas/elf/section13.l
ld/ChangeLog
ld/emultempl/elf32.em

index 3a19099b6f7d9d2a49fa517dad54929d83968d1d..0b6dff692f84d8470daf344c004947b16a711187 100644 (file)
@@ -1,3 +1,15 @@
+2019-07-23  Alan Modra  <amodra@gmail.com>
+
+       * elf-bfd.h (enum elf_gnu_osabi): Add elf_gnu_osabi_mbind.
+       * elf.c (_bfd_elf_make_section_from_shdr): Set elf_gnu_osabi_mbind.
+       (get_program_header_size): Formatting.  Only test SH_GNU_MBIND
+       when elf_gnu_osabi_mbind is set.
+       (_bfd_elf_map_sections_to_segments): Likewise.
+       (_bfd_elf_init_private_section_data): Likewise.
+       (_bfd_elf_final_write_processing): Update comment.
+       * elf64-hppa.c (elf64_hppa_special_sections): Move .tbss entry.
+       (elf_backend_special_sections): Define without .tbss for linux.
+
 2019-07-23  Alan Modra  <amodra@gmail.com>
 
        * elf-bfd.h (enum elf_gnu_osabi): Rename from elf_gnu_symbols.
index 134496ed271f19b11135bc678f031b327d7df93c..01beac6757d6c44a4923837f955c6a065991f175 100644 (file)
@@ -1809,11 +1809,12 @@ struct output_elf_obj_tdata
   bfd_boolean flags_init;
 };
 
-/* Indicate if the bfd contains symbols that have the STT_GNU_IFUNC
-   symbol type or STB_GNU_UNIQUE binding.  Used to set the osabi
-   field in the ELF header structure.  */
+/* Indicate if the bfd contains SHF_GNU_MBIND sections or symbols that
+   have the STT_GNU_IFUNC symbol type or STB_GNU_UNIQUE binding.  Used
+   to set the osabi field in the ELF header structure.  */
 enum elf_gnu_osabi
 {
+  elf_gnu_osabi_mbind = 1 << 0,
   elf_gnu_osabi_ifunc = 1 << 1,
   elf_gnu_osabi_unique = 1 << 2,
 };
index 55bb0916ee77ae17ceee51be17c8720a797e2225..1c77a7917ab77eeb31429bb342def802e98290f1 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1067,6 +1067,19 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
   if ((hdr->sh_flags & SHF_EXCLUDE) != 0)
     flags |= SEC_EXCLUDE;
 
+  switch (elf_elfheader (abfd)->e_ident[EI_OSABI])
+    {
+      /* FIXME: We should not recognize SHF_GNU_MBIND for ELFOSABI_NONE,
+        but binutils as of 2019-07-23 did not set the EI_OSABI header
+        byte.  */
+    case ELFOSABI_NONE:
+    case ELFOSABI_GNU:
+    case ELFOSABI_FREEBSD:
+      if ((hdr->sh_flags & SHF_GNU_MBIND) != 0)
+       elf_tdata (abfd)->has_gnu_osabi |= elf_gnu_osabi_mbind;
+      break;
+    }
+
   if ((flags & SEC_ALLOC) == 0)
     {
       /* The debugging sections appear to be recognized only by name,
@@ -4425,31 +4438,32 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info)
 
   bed = get_elf_backend_data (abfd);
 
- if ((abfd->flags & D_PAGED) != 0)
-   {
-     /* Add a PT_GNU_MBIND segment for each mbind section.  */
-     unsigned int page_align_power = bfd_log2 (bed->commonpagesize);
-     for (s = abfd->sections; s != NULL; s = s->next)
-       if (elf_section_flags (s) & SHF_GNU_MBIND)
-        {
-          if (elf_section_data (s)->this_hdr.sh_info
-              > PT_GNU_MBIND_NUM)
-            {
-              _bfd_error_handler
-                /* xgettext:c-format */
-                (_("%pB: GNU_MBIN section `%pA' has invalid sh_info field: %d"),
-                    abfd, s, elf_section_data (s)->this_hdr.sh_info);
-              continue;
-            }
-          /* Align mbind section to page size.  */
-          if (s->alignment_power < page_align_power)
-            s->alignment_power = page_align_power;
-          segs ++;
-        }
-   }
-
- /* Let the backend count up any program headers it might need.  */
- if (bed->elf_backend_additional_program_headers)
+  if ((abfd->flags & D_PAGED) != 0
+      && (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0)
+    {
+      /* Add a PT_GNU_MBIND segment for each mbind section.  */
+      unsigned int page_align_power = bfd_log2 (bed->commonpagesize);
+      for (s = abfd->sections; s != NULL; s = s->next)
+       if (elf_section_flags (s) & SHF_GNU_MBIND)
+         {
+           if (elf_section_data (s)->this_hdr.sh_info > PT_GNU_MBIND_NUM)
+             {
+               _bfd_error_handler
+                 /* xgettext:c-format */
+                 (_("%pB: GNU_MBIND section `%pA' has invalid "
+                    "sh_info field: %d"),
+                  abfd, s, elf_section_data (s)->this_hdr.sh_info);
+               continue;
+             }
+           /* Align mbind section to page size.  */
+           if (s->alignment_power < page_align_power)
+             s->alignment_power = page_align_power;
+           segs ++;
+         }
+    }
+
+  /* Let the backend count up any program headers it might need.  */
+  if (bed->elf_backend_additional_program_headers)
     {
       int a;
 
@@ -5045,11 +5059,12 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
          pm = &m->next;
        }
 
-      if (first_mbind && (abfd->flags & D_PAGED) != 0)
+      if (first_mbind
+         && (abfd->flags & D_PAGED) != 0
+         && (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0)
        for (s = first_mbind; s != NULL; s = s->next)
          if ((elf_section_flags (s) & SHF_GNU_MBIND) != 0
-             && (elf_section_data (s)->this_hdr.sh_info
-                 <= PT_GNU_MBIND_NUM))
+             && elf_section_data (s)->this_hdr.sh_info <= PT_GNU_MBIND_NUM)
            {
              /* Mandated PF_R.  */
              unsigned long p_flags = PF_R;
@@ -7665,7 +7680,8 @@ _bfd_elf_init_private_section_data (bfd *ibfd,
                               & (SHF_MASKOS | SHF_MASKPROC));
 
   /* Copy sh_info from input for mbind section.  */
-  if (elf_section_flags (isec) & SHF_GNU_MBIND)
+  if ((elf_tdata (ibfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0
+      && elf_section_flags (isec) & SHF_GNU_MBIND)
     elf_section_data (osec)->this_hdr.sh_info
       = elf_section_data (isec)->this_hdr.sh_info;
 
@@ -12118,9 +12134,9 @@ _bfd_elf_final_write_processing (bfd *abfd,
   if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE)
     i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
 
-  /* To make things simpler for the loader on Linux systems we set the
-     osabi field to ELFOSABI_GNU if the binary contains symbols of
-     the STT_GNU_IFUNC type or STB_GNU_UNIQUE binding.  */
+  /* Set the osabi field to ELFOSABI_GNU if the binary contains
+     SHF_GNU_MBIND sections or symbols of STT_GNU_IFUNC type or
+     STB_GNU_UNIQUE binding.  */
   if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE
       && elf_tdata (abfd)->has_gnu_osabi)
     i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_GNU;
index 9f6a51334f4d1070360f67a4e17b505ed09f4869..77811580c679b535aea388ea8f10fb9be78937c7 100644 (file)
@@ -3954,13 +3954,13 @@ elf64_hppa_relocate_section (bfd *output_bfd,
 
 static const struct bfd_elf_special_section elf64_hppa_special_sections[] =
 {
+  { STRING_COMMA_LEN (".tbss"),         0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_HP_TLS },
   { STRING_COMMA_LEN (".fini"),         0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
   { STRING_COMMA_LEN (".init"),         0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
   { STRING_COMMA_LEN (".plt"),  0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
   { STRING_COMMA_LEN (".dlt"),  0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
   { STRING_COMMA_LEN (".sdata"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
   { STRING_COMMA_LEN (".sbss"),         0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
-  { STRING_COMMA_LEN (".tbss"),         0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_HP_TLS },
   { NULL,                   0,  0, 0,            0 }
 };
 
@@ -4088,5 +4088,7 @@ const struct elf_size_info hppa64_elf_size_info =
 #define ELF_OSABI                      ELFOSABI_GNU
 #undef elf64_bed
 #define elf64_bed                      elf64_hppa_linux_bed
+#undef elf_backend_special_sections
+#define elf_backend_special_sections   (elf64_hppa_special_sections + 1)
 
 #include "elf64-target.h"
index 7bbb9d373d3c384ca3eda4c361505777a4dfcb16..e329c40f305f42a59bfa58aaef16f6fb2617debd 100644 (file)
@@ -1,3 +1,13 @@
+2019-07-23  Alan Modra  <amodra@gmail.com>
+
+       * readelf.c (get_parisc_segment_type): Split off hpux entries..
+       (get_ia64_segment_type): ..and these..
+       (get_hpux_segment_type): ..to here.
+       (get_segment_type): Condition GNU_MBIND on osabi.  Use
+       get_hpux_segment_type.
+       (get_symbol_binding): Do not print UNIQUE for ELFOSABI_NONE.
+       (get_symbol_type): Do not print IFUNC for ELFOSABI_NONE.
+
 2019-07-23  Alan Modra  <amodra@gmail.com>
 
        * testsuite/binutils-all/objcopy.exp (elf64): Correct object
index 5e8fe824b3e4f395015c867ffc21fb80308a81f1..1ba4bcb57936f8edda37810f7f10c4df6d41c004 100644 (file)
@@ -3879,22 +3879,6 @@ get_parisc_segment_type (unsigned long type)
 {
   switch (type)
     {
-    case PT_HP_TLS:            return "HP_TLS";
-    case PT_HP_CORE_NONE:      return "HP_CORE_NONE";
-    case PT_HP_CORE_VERSION:   return "HP_CORE_VERSION";
-    case PT_HP_CORE_KERNEL:    return "HP_CORE_KERNEL";
-    case PT_HP_CORE_COMM:      return "HP_CORE_COMM";
-    case PT_HP_CORE_PROC:      return "HP_CORE_PROC";
-    case PT_HP_CORE_LOADABLE:  return "HP_CORE_LOADABLE";
-    case PT_HP_CORE_STACK:     return "HP_CORE_STACK";
-    case PT_HP_CORE_SHM:       return "HP_CORE_SHM";
-    case PT_HP_CORE_MMF:       return "HP_CORE_MMF";
-    case PT_HP_PARALLEL:       return "HP_PARALLEL";
-    case PT_HP_FASTBIND:       return "HP_FASTBIND";
-    case PT_HP_OPT_ANNOT:      return "HP_OPT_ANNOT";
-    case PT_HP_HSL_ANNOT:      return "HP_HSL_ANNOT";
-    case PT_HP_STACK:          return "HP_STACK";
-    case PT_HP_CORE_UTSNAME:   return "HP_CORE_UTSNAME";
     case PT_PARISC_ARCHEXT:    return "PARISC_ARCHEXT";
     case PT_PARISC_UNWIND:     return "PARISC_UNWIND";
     case PT_PARISC_WEAKORDER:  return "PARISC_WEAKORDER";
@@ -3909,10 +3893,6 @@ get_ia64_segment_type (unsigned long type)
     {
     case PT_IA_64_ARCHEXT:     return "IA_64_ARCHEXT";
     case PT_IA_64_UNWIND:      return "IA_64_UNWIND";
-    case PT_HP_TLS:            return "HP_TLS";
-    case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
-    case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
-    case PT_IA_64_HP_STACK:    return "HP_STACK";
     default:                    return NULL;
     }
 }
@@ -3927,6 +3907,44 @@ get_tic6x_segment_type (unsigned long type)
     }
 }
 
+static const char *
+get_hpux_segment_type (unsigned long type, unsigned e_machine)
+{
+  if (e_machine == EM_PARISC)
+    switch (type)
+      {
+      case PT_HP_TLS:          return "HP_TLS";
+      case PT_HP_CORE_NONE:    return "HP_CORE_NONE";
+      case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
+      case PT_HP_CORE_KERNEL:  return "HP_CORE_KERNEL";
+      case PT_HP_CORE_COMM:    return "HP_CORE_COMM";
+      case PT_HP_CORE_PROC:    return "HP_CORE_PROC";
+      case PT_HP_CORE_LOADABLE:        return "HP_CORE_LOADABLE";
+      case PT_HP_CORE_STACK:   return "HP_CORE_STACK";
+      case PT_HP_CORE_SHM:     return "HP_CORE_SHM";
+      case PT_HP_CORE_MMF:     return "HP_CORE_MMF";
+      case PT_HP_PARALLEL:     return "HP_PARALLEL";
+      case PT_HP_FASTBIND:     return "HP_FASTBIND";
+      case PT_HP_OPT_ANNOT:    return "HP_OPT_ANNOT";
+      case PT_HP_HSL_ANNOT:    return "HP_HSL_ANNOT";
+      case PT_HP_STACK:                return "HP_STACK";
+      case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
+      default:                 return NULL;
+      }
+
+  if (e_machine == EM_IA_64)
+    switch (type)
+      {
+      case PT_HP_TLS:           return "HP_TLS";
+      case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
+      case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
+      case PT_IA_64_HP_STACK:   return "HP_STACK";
+      default:                  return NULL;
+      }
+
+  return NULL;
+}
+
 static const char *
 get_solaris_segment_type (unsigned long type)
 {
@@ -3965,12 +3983,7 @@ get_segment_type (Filedata * filedata, unsigned long p_type)
     case PT_GNU_PROPERTY: return "GNU_PROPERTY";
 
     default:
-      if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
-       {
-         sprintf (buff, "GNU_MBIND+%#lx",
-                  p_type - PT_GNU_MBIND_LO);
-       }
-      else if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
+      if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
        {
          const char * result;
 
@@ -4011,24 +4024,28 @@ get_segment_type (Filedata * filedata, unsigned long p_type)
        }
       else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
        {
-         const char * result;
+         const char * result = NULL;
 
-         switch (filedata->file_header.e_machine)
+         switch (filedata->file_header.e_ident[EI_OSABI])
            {
-           case EM_PARISC:
-             result = get_parisc_segment_type (p_type);
+           case ELFOSABI_GNU:
+           case ELFOSABI_FREEBSD:
+             if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
+               {
+                 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
+                 result = buff;
+               }
              break;
-           case EM_IA_64:
-             result = get_ia64_segment_type (p_type);
+           case ELFOSABI_HPUX:
+             result = get_hpux_segment_type (p_type,
+                                             filedata->file_header.e_machine);
+             break;
+           case ELFOSABI_SOLARIS:
+             result = get_solaris_segment_type (p_type);
              break;
            default:
-             if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
-               result = get_solaris_segment_type (p_type);
-             else
-               result = NULL;
              break;
            }
-
          if (result != NULL)
            return result;
 
@@ -11052,9 +11069,7 @@ get_symbol_binding (Filedata * filedata, unsigned int binding)
       else if (binding >= STB_LOOS && binding <= STB_HIOS)
        {
          if (binding == STB_GNU_UNIQUE
-             && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
-                 /* GNU is still using the default value 0.  */
-                 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
+             && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
            return "UNIQUE";
          snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
        }
@@ -11106,9 +11121,7 @@ get_symbol_type (Filedata * filedata, unsigned int type)
 
          if (type == STT_GNU_IFUNC
              && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
-                 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
-                 /* GNU is still using the default value 0.  */
-                 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
+                 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
            return "IFUNC";
 
          snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
index 47938f7b8cdc54f34bb7b34d66a1c560750768b4..19ca4644061c2d1fe1612a33ccf4299d9339d247 100644 (file)
@@ -1,3 +1,18 @@
+2019-07-23  Alan Modra  <amodra@gmail.com>
+
+       * config/obj-elf.c (obj_elf_change_section): Don't emit a fatal
+       error for non-SHF_ALLOC SHF_GNU_MBIND here.
+       (obj_elf_parse_section_letters): Return SHF_GNU_MBIND in new
+       gnu_attr param.
+       (obj_elf_section): Adjust obj_elf_parse_section_letters call.
+       Formatting.  Set SHF_GNU_MBIND and elf_osabi from gnu_attr.
+       Emit normal error for non-SHF_ALLOC SHF_GNU_MBIND and wrong osabi.
+       (obj_elf_type): Set elf_osabi for ifunc.
+       * testsuite/gas/elf/section12a.d: xfail msp430 and hpux.
+       * testsuite/gas/elf/section12b.d: Likewise.
+       * testsuite/gas/elf/section13.d: Likewise.
+       * testsuite/gas/elf/section13.l: Adjust expected error.
+
 2019-07-23  Alan Modra  <amodra@gmail.com>
 
        * testsuite/gas/elf/section12a.d: Don't skip for rx.
index af35feeec2f259db45e128a16cedc9db8494edff..fd2c943771fdb8bce67ef9e63bcc09596acea43d 100644 (file)
@@ -706,9 +706,6 @@ obj_elf_change_section (const char *name,
        attr |= ssect->attr;
     }
 
-  if ((attr & (SHF_ALLOC | SHF_GNU_MBIND)) == SHF_GNU_MBIND)
-    as_fatal (_("SHF_ALLOC isn't set for GNU_MBIND section: %s"), name);
-
   /* Convert ELF type and flags to BFD flags.  */
   flags = (SEC_RELOC
           | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
@@ -785,7 +782,8 @@ obj_elf_change_section (const char *name,
 }
 
 static bfd_vma
-obj_elf_parse_section_letters (char *str, size_t len, bfd_boolean *is_clone)
+obj_elf_parse_section_letters (char *str, size_t len,
+                              bfd_boolean *is_clone, bfd_vma *gnu_attr)
 {
   bfd_vma attr = 0;
   *is_clone = FALSE;
@@ -819,7 +817,7 @@ obj_elf_parse_section_letters (char *str, size_t len, bfd_boolean *is_clone)
          attr |= SHF_TLS;
          break;
        case 'd':
-         attr |= SHF_GNU_MBIND;
+         *gnu_attr |= SHF_GNU_MBIND;
          break;
        case '?':
          *is_clone = TRUE;
@@ -1011,6 +1009,7 @@ obj_elf_section (int push)
   char *beg;
   int type, dummy;
   bfd_vma attr;
+  bfd_vma gnu_attr;
   int entsize;
   int linkonce;
   subsegT new_subsection = -1;
@@ -1041,6 +1040,7 @@ obj_elf_section (int push)
     return;
   type = SHT_NULL;
   attr = 0;
+  gnu_attr = 0;
   group_name = NULL;
   entsize = 0;
   linkonce = 0;
@@ -1077,7 +1077,8 @@ obj_elf_section (int push)
              ignore_rest_of_line ();
              return;
            }
-         attr |= obj_elf_parse_section_letters (beg, strlen (beg), &is_clone);
+         attr |= obj_elf_parse_section_letters (beg, strlen (beg),
+                                                &is_clone, &gnu_attr);
 
          SKIP_WHITESPACE ();
          if (*input_line_pointer == ',')
@@ -1103,14 +1104,14 @@ obj_elf_section (int push)
                  ++input_line_pointer;
 
                  if (ISDIGIT (* input_line_pointer))
-                   {
-                     type = strtoul (input_line_pointer, & input_line_pointer, 0);
-                   }
+                   type = strtoul (input_line_pointer, &input_line_pointer, 0);
                  else
                    {
                      c = get_symbol_name (& beg);
                      (void) restore_line_pointer (c);
-                     type = obj_elf_section_type (beg, input_line_pointer - beg, TRUE);
+                     type = obj_elf_section_type (beg,
+                                                  input_line_pointer - beg,
+                                                  TRUE);
                    }
                }
              else
@@ -1177,7 +1178,7 @@ obj_elf_section (int push)
                }
            }
 
-         if ((attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
+         if ((gnu_attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
            {
              ++input_line_pointer;
              SKIP_WHITESPACE ();
@@ -1211,7 +1212,8 @@ obj_elf_section (int push)
              c = get_symbol_name (& beg);
              (void) restore_line_pointer (c);
 
-             attr |= obj_elf_section_word (beg, input_line_pointer - beg, & type);
+             attr |= obj_elf_section_word (beg, input_line_pointer - beg,
+                                           &type);
 
              SKIP_WHITESPACE ();
            }
@@ -1226,6 +1228,23 @@ done:
   obj_elf_change_section (name, type, info, attr, entsize, group_name,
                          linkonce, push);
 
+  if ((gnu_attr & SHF_GNU_MBIND) != 0)
+    {
+      struct elf_backend_data *bed;
+
+      if ((attr & SHF_ALLOC) == 0)
+       as_bad (_("SHF_ALLOC isn't set for GNU_MBIND section: %s"), name);
+
+      bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput);
+      if (bed->elf_osabi == ELFOSABI_NONE)
+       bed->elf_osabi = ELFOSABI_GNU;
+      else if (bed->elf_osabi != ELFOSABI_GNU
+              && bed->elf_osabi != ELFOSABI_FREEBSD)
+       as_bad (_("GNU_MBIND section is supported only by GNU "
+                 "and FreeBSD targets"));
+    }
+  elf_section_flags (now_seg) |= gnu_attr;
+
   if (push && new_subsection != -1)
     subseg_set (now_seg, new_subsection);
 }
@@ -2032,15 +2051,15 @@ obj_elf_type (int ignore ATTRIBUTE_UNUSED)
           || strcmp (type_name, "10") == 0
           || strcmp (type_name, "STT_GNU_IFUNC") == 0)
     {
-      const struct elf_backend_data *bed;
-
-      bed = get_elf_backend_data (stdoutput);
-      if (!(bed->elf_osabi == ELFOSABI_GNU
-           || bed->elf_osabi == ELFOSABI_FREEBSD
-           /* GNU is still using the default value 0.  */
-           || bed->elf_osabi == ELFOSABI_NONE))
-       as_bad (_("symbol type \"%s\" is supported only by GNU and FreeBSD targets"),
-               type_name);
+      struct elf_backend_data *bed;
+
+      bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput);
+      if (bed->elf_osabi == ELFOSABI_NONE)
+       bed->elf_osabi = ELFOSABI_GNU;
+      else if (bed->elf_osabi != ELFOSABI_GNU
+              && bed->elf_osabi != ELFOSABI_FREEBSD)
+       as_bad (_("symbol type \"%s\" is supported only by GNU "
+                 "and FreeBSD targets"), type_name);
       type = BSF_FUNCTION | BSF_GNU_INDIRECT_FUNCTION;
     }
   else if (strcmp (type_name, "gnu_unique_object") == 0)
@@ -2048,14 +2067,12 @@ obj_elf_type (int ignore ATTRIBUTE_UNUSED)
       struct elf_backend_data *bed;
 
       bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput);
-      if (!(bed->elf_osabi == ELFOSABI_GNU
-           /* GNU is still using the default value 0.  */
-           || bed->elf_osabi == ELFOSABI_NONE))
+      if (bed->elf_osabi == ELFOSABI_NONE)
+       bed->elf_osabi = ELFOSABI_GNU;
+      else if (bed->elf_osabi != ELFOSABI_GNU)
        as_bad (_("symbol type \"%s\" is supported only by GNU targets"),
                type_name);
       type = BSF_OBJECT | BSF_GNU_UNIQUE;
-      /* PR 10549: Always set OSABI field to GNU for objects containing unique symbols.  */
-      bed->elf_osabi = ELFOSABI_GNU;
     }
 #ifdef md_elf_symbol_type
   else if ((type = md_elf_symbol_type (type_name, sym, elfsym)) != -1)
index 3e04171dd3132b8ec4245c952b6ba67266f25661..2b6aa3e8f02186e80a218760be17ee7447eccf7d 100644 (file)
@@ -2,6 +2,8 @@
 #as: --no-pad-sections
 #readelf: -Sg --wide
 #name: mbind sections
+# msp430 and hpux do not support SHF_GNU_MBIND
+#xfail: msp430-*-* *-*-hpux*
 
 #...
   \[[ 0-9]+\] \.mbind\.data[   ]+PROGBITS[     ]+0+0 0+[0-9a-f]+ 0+1 00 WAD  0   0  1
index 717bc1a7a917e21940b4b39cdf230b1816dd6635..fcbb6974f8b6cf1afeaa04da20e28261b40ffa13 100644 (file)
@@ -2,8 +2,9 @@
 #as: --no-pad-sections
 #objdump: -s
 #name: mbind section contents
-# The RX port annoyingly reorders the sections so that they do not match the sequence expected below.
-#skip: rx-*-*
+# RX annoyingly reorders the sections so that they do not match the sequence
+# expected below.  msp430 and hpux do not support SHF_GNU_MBIND
+#xfail: rx-*-* msp430-*-* *-*-hpux*
 
 #...
 Contents of section .mbind.data:
index 940ccec295414fba4b3eec1e55339c20eff66843..9f4fe36f6ee5207b52adfa3d0259bd0d31220dda 100644 (file)
@@ -1,2 +1,3 @@
 #name: mbind sections without SHF_ALLOC
 #error_output: section13.l
+#xfail: msp430-*-* *-*-hpux*
index c56b5aebb16643e16e488301c65b2af901847618..3ddf54a7ea21bea9cbfa33401fdbc626b46e8772 100644 (file)
@@ -1,2 +1,2 @@
 [^:]*: Assembler messages:
-[^:]*:1: Fatal error: SHF_ALLOC isn't set for GNU_MBIND section: .mbind.data
+[^:]*:1: Error: SHF_ALLOC isn't set for GNU_MBIND section: .mbind.data
index fd13791f325ef58646b72b0e20fa6047889cc458..7d7b6643137bb0f763e5ebb23da3a62c6799755b 100644 (file)
@@ -1,3 +1,8 @@
+2019-07-23  Alan Modra  <amodra@gmail.com>
+
+       * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Condition
+       SHF_GNU_MBIND on osabi.  Set output elf_gnu_osabi_mbind.
+
 2019-07-23  Alan Modra  <amodra@gmail.com>
 
        * testsuite/ld-elf/size-1.d,
index f3c6e3adeee5d78b6c0a8b764eed299be1424fc4..5cdd1bd667b07598fb4f5fd2489f716dc5c97d24 100644 (file)
@@ -2131,6 +2131,7 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
       && elfinput
       && elfoutput
       && (s->flags & SEC_ALLOC) != 0
+      && (elf_tdata (s->owner)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0
       && (elf_section_flags (s) & SHF_GNU_MBIND) != 0)
     {
       /* Find the output mbind section with the same type, attributes
@@ -2168,6 +2169,7 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
        secname = ".mbind.rodata";
       else
        secname = ".mbind.text";
+      elf_tdata (link_info.output_bfd)->has_gnu_osabi |= elf_gnu_osabi_mbind;
     }
 
   /* Look through the script to see where to place this section.  The
This page took 0.041172 seconds and 4 git commands to generate.