dynrelro section for read-only dynamic symbols copied into executable
authorAlan Modra <amodra@gmail.com>
Sun, 25 Dec 2016 14:00:45 +0000 (00:30 +1030)
committerAlan Modra <amodra@gmail.com>
Mon, 26 Dec 2016 03:17:51 +0000 (13:47 +1030)
Variables defined in shared libraries are copied into an executable's
.bss section when code in the executable is non-PIC and thus would
require dynamic text relocations to access the variable directly in
the shared library.  Recent x86 toolchains also copy variables into
the executable to gain a small speed improvement.

The problem is that if the variable was originally read-only, the copy
in .bss is writable, potentially opening a security hole.  This patch
cures that problem by putting the copy in a section that becomes
read-only after ld.so relocation, provided -z relro is in force.

The patch also fixes a microblaze linker segfault on attempting to
use dynamic bss variables.

bfd/
PR ld/20995
* elf-bfd.h (struct elf_link_hash_table): Add sdynrelro and
sreldynrelro.
(struct elf_backend_data): Add want_dynrelro.
* elfxx-target.h (elf_backend_want_dynrelro): Define.
(elfNN_bed): Update initializer.
* elflink.c (_bfd_elf_create_dynamic_sections): Create
sdynrelro and sreldynrelro sections.
* elf32-arm.c (elf32_arm_adjust_dynamic_symbol): Place variables
copied into the executable from read-only sections into sdynrelro.
(elf32_arm_size_dynamic_sections): Handle sdynrelro.
(elf32_arm_finish_dynamic_symbol): Select sreldynrelro for
dynamic relocs in sdynrelro.
(elf_backend_want_dynrelro): Define.
* elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol)
(elf32_hppa_size_dynamic_sections, elf32_hppa_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf32-i386.c (elf_i386_adjust_dynamic_symbol)
(elf_i386_size_dynamic_sections, elf_i386_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf32-metag.c (elf_metag_adjust_dynamic_symbol)
(elf_metag_size_dynamic_sections, elf_metag_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf32-microblaze.c (microblaze_elf_adjust_dynamic_symbol)
(microblaze_elf_size_dynamic_sections)
(microblaze_elf_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf32-nios2.c (nios2_elf32_finish_dynamic_symbol)
(nios2_elf32_adjust_dynamic_symbol)
(nios2_elf32_size_dynamic_sections)
(elf_backend_want_dynrelro): As above.
* elf32-or1k.c (or1k_elf_finish_dynamic_symbol)
(or1k_elf_adjust_dynamic_symbol, or1k_elf_size_dynamic_sections)
(elf_backend_want_dynrelro): As above.
* elf32-ppc.c (ppc_elf_adjust_dynamic_symbol)
(ppc_elf_size_dynamic_sections, ppc_elf_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf32-s390.c (elf_s390_adjust_dynamic_symbol)
(elf_s390_size_dynamic_sections, elf_s390_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf32-tic6x.c (elf32_tic6x_adjust_dynamic_symbol)
(elf32_tic6x_size_dynamic_sections)
(elf32_tic6x_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf32-tilepro.c (tilepro_elf_adjust_dynamic_symbol)
(tilepro_elf_size_dynamic_sections)
(tilepro_elf_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol)
(ppc64_elf_size_dynamic_sections, ppc64_elf_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf64-s390.c (elf_s390_adjust_dynamic_symbol)
(elf_s390_size_dynamic_sections, elf_s390_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol)
(elf_x86_64_size_dynamic_sections)
(elf_x86_64_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elfnn-aarch64.c (elfNN_aarch64_adjust_dynamic_symbol)
(elfNN_aarch64_size_dynamic_sections)
(elfNN_aarch64_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elfnn-riscv.c (riscv_elf_adjust_dynamic_symbol)
(riscv_elf_size_dynamic_sections, riscv_elf_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elfxx-mips.c (_bfd_mips_elf_adjust_dynamic_symbol)
(_bfd_mips_elf_size_dynamic_sections)
(_bfd_mips_vxworks_finish_dynamic_symbol): As above.
* elfxx-sparc.c (_bfd_sparc_elf_adjust_dynamic_symbol)
(_bfd_sparc_elf_size_dynamic_sections)
(_bfd_sparc_elf_finish_dynamic_symbol): As above.
* elfxx-tilegx.c (tilegx_elf_adjust_dynamic_symbol)
(tilegx_elf_size_dynamic_sections)
(tilegx_elf_finish_dynamic_symbol): As above.
* elf32-mips.c (elf_backend_want_dynrelro): Define.
* elf64-mips.c (elf_backend_want_dynrelro): Define.
* elf32-sparc.c (elf_backend_want_dynrelro): Define.
* elf64-sparc.c (elf_backend_want_dynrelro): Define.
* elf32-tilegx.c (elf_backend_want_dynrelro): Define.
* elf64-tilegx.c (elf_backend_want_dynrelro): Define.
* elf32-microblaze.c (microblaze_elf_adjust_dynamic_symbol): Tidy.
(microblaze_elf_size_dynamic_sections): Handle sdynbss.
* elf32-nios2.c (nios2_elf32_size_dynamic_sections): Make use
of linker shortcuts to dynamic sections rather than comparing
names.  Correctly set "got" flag.
ld/
PR ld/20995
* testsuite/ld-arm/farcall-mixed-app-v5.d: Update to suit changed
stub hash table traversal caused by section id increment.  Accept
the previous output too.
* testsuite/ld-arm/farcall-mixed-app.d: Likewise.
* testsuite/ld-arm/farcall-mixed-lib-v4t.d: Likewise.
* testsuite/ld-arm/farcall-mixed-lib.d: Likewise.
* testsuite/ld-elf/pr20995a.s, * testsuite/ld-elf/pr20995b.s,
* testsuite/ld-elf/pr20995.r: New test.
* testsuite/ld-elf/elf.exp: Run it.

38 files changed:
bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf32-arm.c
bfd/elf32-hppa.c
bfd/elf32-i386.c
bfd/elf32-metag.c
bfd/elf32-microblaze.c
bfd/elf32-mips.c
bfd/elf32-nios2.c
bfd/elf32-or1k.c
bfd/elf32-ppc.c
bfd/elf32-s390.c
bfd/elf32-sparc.c
bfd/elf32-tic6x.c
bfd/elf32-tilegx.c
bfd/elf32-tilepro.c
bfd/elf64-mips.c
bfd/elf64-ppc.c
bfd/elf64-s390.c
bfd/elf64-sparc.c
bfd/elf64-tilegx.c
bfd/elf64-x86-64.c
bfd/elflink.c
bfd/elfnn-aarch64.c
bfd/elfnn-riscv.c
bfd/elfxx-mips.c
bfd/elfxx-sparc.c
bfd/elfxx-target.h
bfd/elfxx-tilegx.c
ld/ChangeLog
ld/testsuite/ld-arm/farcall-mixed-app-v5.d
ld/testsuite/ld-arm/farcall-mixed-app.d
ld/testsuite/ld-arm/farcall-mixed-lib-v4t.d
ld/testsuite/ld-arm/farcall-mixed-lib.d
ld/testsuite/ld-elf/elf.exp
ld/testsuite/ld-elf/pr20995.r [new file with mode: 0644]
ld/testsuite/ld-elf/pr20995a.s [new file with mode: 0644]
ld/testsuite/ld-elf/pr20995b.s [new file with mode: 0644]

index d1ecdea3f9dea5c90576af9f8c2d2cade92756a9..4d7bd7763c53ad60eb3d42ce404a15560af965dd 100644 (file)
@@ -1,3 +1,91 @@
+2016-12-26  Alan Modra  <amodra@gmail.com>
+
+       PR ld/20995
+       * elf-bfd.h (struct elf_link_hash_table): Add sdynrelro and
+       sreldynrelro.
+       (struct elf_backend_data): Add want_dynrelro.
+       * elfxx-target.h (elf_backend_want_dynrelro): Define.
+       (elfNN_bed): Update initializer.
+       * elflink.c (_bfd_elf_create_dynamic_sections): Create
+       sdynrelro and sreldynrelro sections.
+       * elf32-arm.c (elf32_arm_adjust_dynamic_symbol): Place variables
+       copied into the executable from read-only sections into sdynrelro.
+       (elf32_arm_size_dynamic_sections): Handle sdynrelro.
+       (elf32_arm_finish_dynamic_symbol): Select sreldynrelro for
+       dynamic relocs in sdynrelro.
+       (elf_backend_want_dynrelro): Define.
+       * elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol)
+       (elf32_hppa_size_dynamic_sections, elf32_hppa_finish_dynamic_symbol)
+       (elf_backend_want_dynrelro): As above.
+       * elf32-i386.c (elf_i386_adjust_dynamic_symbol)
+       (elf_i386_size_dynamic_sections, elf_i386_finish_dynamic_symbol)
+       (elf_backend_want_dynrelro): As above.
+       * elf32-metag.c (elf_metag_adjust_dynamic_symbol)
+       (elf_metag_size_dynamic_sections, elf_metag_finish_dynamic_symbol)
+       (elf_backend_want_dynrelro): As above.
+       * elf32-microblaze.c (microblaze_elf_adjust_dynamic_symbol)
+       (microblaze_elf_size_dynamic_sections)
+       (microblaze_elf_finish_dynamic_symbol)
+       (elf_backend_want_dynrelro): As above.
+       * elf32-nios2.c (nios2_elf32_finish_dynamic_symbol)
+       (nios2_elf32_adjust_dynamic_symbol)
+       (nios2_elf32_size_dynamic_sections)
+       (elf_backend_want_dynrelro): As above.
+       * elf32-or1k.c (or1k_elf_finish_dynamic_symbol)
+       (or1k_elf_adjust_dynamic_symbol, or1k_elf_size_dynamic_sections)
+       (elf_backend_want_dynrelro): As above.
+       * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol)
+       (ppc_elf_size_dynamic_sections, ppc_elf_finish_dynamic_symbol)
+       (elf_backend_want_dynrelro): As above.
+       * elf32-s390.c (elf_s390_adjust_dynamic_symbol)
+       (elf_s390_size_dynamic_sections, elf_s390_finish_dynamic_symbol)
+       (elf_backend_want_dynrelro): As above.
+       * elf32-tic6x.c (elf32_tic6x_adjust_dynamic_symbol)
+       (elf32_tic6x_size_dynamic_sections)
+       (elf32_tic6x_finish_dynamic_symbol)
+       (elf_backend_want_dynrelro): As above.
+       * elf32-tilepro.c (tilepro_elf_adjust_dynamic_symbol)
+       (tilepro_elf_size_dynamic_sections)
+       (tilepro_elf_finish_dynamic_symbol)
+       (elf_backend_want_dynrelro): As above.
+       * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol)
+       (ppc64_elf_size_dynamic_sections, ppc64_elf_finish_dynamic_symbol)
+       (elf_backend_want_dynrelro): As above.
+       * elf64-s390.c (elf_s390_adjust_dynamic_symbol)
+       (elf_s390_size_dynamic_sections, elf_s390_finish_dynamic_symbol)
+       (elf_backend_want_dynrelro): As above.
+       * elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol)
+       (elf_x86_64_size_dynamic_sections)
+       (elf_x86_64_finish_dynamic_symbol)
+       (elf_backend_want_dynrelro): As above.
+       * elfnn-aarch64.c (elfNN_aarch64_adjust_dynamic_symbol)
+       (elfNN_aarch64_size_dynamic_sections)
+       (elfNN_aarch64_finish_dynamic_symbol)
+       (elf_backend_want_dynrelro): As above.
+       * elfnn-riscv.c (riscv_elf_adjust_dynamic_symbol)
+       (riscv_elf_size_dynamic_sections, riscv_elf_finish_dynamic_symbol)
+       (elf_backend_want_dynrelro): As above.
+       * elfxx-mips.c (_bfd_mips_elf_adjust_dynamic_symbol)
+       (_bfd_mips_elf_size_dynamic_sections)
+       (_bfd_mips_vxworks_finish_dynamic_symbol): As above.
+       * elfxx-sparc.c (_bfd_sparc_elf_adjust_dynamic_symbol)
+       (_bfd_sparc_elf_size_dynamic_sections)
+       (_bfd_sparc_elf_finish_dynamic_symbol): As above.
+       * elfxx-tilegx.c (tilegx_elf_adjust_dynamic_symbol)
+       (tilegx_elf_size_dynamic_sections)
+       (tilegx_elf_finish_dynamic_symbol): As above.
+       * elf32-mips.c (elf_backend_want_dynrelro): Define.
+       * elf64-mips.c (elf_backend_want_dynrelro): Define.
+       * elf32-sparc.c (elf_backend_want_dynrelro): Define.
+       * elf64-sparc.c (elf_backend_want_dynrelro): Define.
+       * elf32-tilegx.c (elf_backend_want_dynrelro): Define.
+       * elf64-tilegx.c (elf_backend_want_dynrelro): Define.
+       * elf32-microblaze.c (microblaze_elf_adjust_dynamic_symbol): Tidy.
+       (microblaze_elf_size_dynamic_sections): Handle sdynbss.
+       * elf32-nios2.c (nios2_elf32_size_dynamic_sections): Make use
+       of linker shortcuts to dynamic sections rather than comparing
+       names.  Correctly set "got" flag.
+
 2016-12-26  Alan Modra  <amodra@gmail.com>
 
        * elf-bfd.h (struct elf_link_hash_table): Add sdynbss and srelbss.
index 4093434e646776e25dc45cef03c63fe2a5acb823..1c634d8dd196f84252a991e2c3786e8d74c9322c 100644 (file)
@@ -597,6 +597,8 @@ struct elf_link_hash_table
   asection *srelplt;
   asection *sdynbss;
   asection *srelbss;
+  asection *sdynrelro;
+  asection *sreldynrelro;
   asection *igotplt;
   asection *iplt;
   asection *irelplt;
@@ -1451,6 +1453,7 @@ struct elf_backend_data
   unsigned can_refcount : 1;
   unsigned want_got_sym : 1;
   unsigned want_dynbss : 1;
+  unsigned want_dynrelro : 1;
 
   /* Targets which do not support physical addressing often require
      that the p_paddr field in the section header to be set to zero.
index 47611361d68f852146b4aed57a37c058fe8fb167..384063e5c1ea52ee2a662611f35b53ddd81f4f15 100644 (file)
@@ -15264,7 +15264,7 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
                                 struct elf_link_hash_entry * h)
 {
   bfd * dynobj;
-  asection * s;
+  asection *s, *srel;
   struct elf32_arm_link_hash_entry * eh;
   struct elf32_arm_link_hash_table *globals;
 
@@ -15363,20 +15363,24 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
      determine the address it must put in the global offset table, so
      both the dynamic object and the regular object will refer to the
      same memory location for the variable.  */
-  s = globals->root.sdynbss;
-  BFD_ASSERT (s != NULL);
-
   /* If allowed, we must generate a R_ARM_COPY reloc to tell the dynamic
      linker to copy the initial value out of the dynamic object and into
      the runtime process image.  We need to remember the offset into the
      .rel(a).bss section we are going to use.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = globals->root.sdynrelro;
+      srel = globals->root.sreldynrelro;
+    }
+  else
+    {
+      s = globals->root.sdynbss;
+      srel = globals->root.srelbss;
+    }
   if (info->nocopyreloc == 0
       && (h->root.u.def.section->flags & SEC_ALLOC) != 0
       && h->size != 0)
     {
-      asection *srel;
-
-      srel = bfd_get_linker_section (dynobj, RELOC_SECTION (globals, ".bss"));
       elf32_arm_allocate_dynrelocs (info, srel, 1);
       h->needs_copy = 1;
     }
@@ -16091,7 +16095,8 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
               && s != htab->root.sgotplt
               && s != htab->root.iplt
               && s != htab->root.igotplt
-              && s != htab->root.sdynbss)
+              && s != htab->root.sdynbss
+              && s != htab->root.sdynrelro)
        {
          /* It's not one of our sections, so don't allocate space.  */
          continue;
@@ -16301,14 +16306,15 @@ elf32_arm_finish_dynamic_symbol (bfd * output_bfd,
                  && (h->root.type == bfd_link_hash_defined
                      || h->root.type == bfd_link_hash_defweak));
 
-      s = htab->root.srelbss;
-      BFD_ASSERT (s != NULL);
-
       rel.r_addend = 0;
       rel.r_offset = (h->root.u.def.value
                      + h->root.u.def.section->output_section->vma
                      + h->root.u.def.section->output_offset);
       rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_COPY);
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->root.sreldynrelro;
+      else
+       s = htab->root.srelbss;
       elf32_arm_add_dynreloc (output_bfd, info, s, &rel);
     }
 
@@ -19389,6 +19395,7 @@ elf32_arm_backend_symbol_processing (bfd *abfd, asymbol *sym)
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_got_plt       1
 #define elf_backend_want_plt_sym       0
+#define elf_backend_want_dynrelro      1
 #define elf_backend_may_use_rel_p      1
 #define elf_backend_may_use_rela_p     0
 #define elf_backend_default_use_rela_p 0
index 3ce4b928f50c64508faeaa79b21f4b99e5c1b37a..cbe42cfde9f0e7d82b3337b40e0a552a11a42eb6 100644 (file)
@@ -1793,7 +1793,7 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
                                  struct elf_link_hash_entry *eh)
 {
   struct elf32_hppa_link_hash_table *htab;
-  asection *sec;
+  asection *sec, *srel;
 
   /* If this is a function, put it in the procedure linkage table.  We
      will fill in the contents of the procedure linkage table later.  */
@@ -1899,14 +1899,22 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* We must generate a COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  */
+  if ((eh->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      sec = htab->etab.sdynrelro;
+      srel = htab->etab.sreldynrelro;
+    }
+  else
+    {
+      sec = htab->etab.sdynbss;
+      srel = htab->etab.srelbss;
+    }
   if ((eh->root.u.def.section->flags & SEC_ALLOC) != 0 && eh->size != 0)
     {
-      htab->etab.srelbss->size += sizeof (Elf32_External_Rela);
+      srel->size += sizeof (Elf32_External_Rela);
       eh->needs_copy = 1;
     }
 
-  sec = htab->etab.sdynbss;
-
   return _bfd_elf_adjust_dynamic_copy (info, eh, sec);
 }
 
@@ -2374,7 +2382,8 @@ elf32_hppa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
            }
        }
       else if (sec == htab->etab.sgot
-              || sec == htab->etab.sdynbss)
+              || sec == htab->etab.sdynbss
+              || sec == htab->etab.sdynrelro)
        ;
       else if (CONST_STRNEQ (bfd_get_section_name (dynobj, sec), ".rela"))
        {
@@ -4427,13 +4436,15 @@ elf32_hppa_finish_dynamic_symbol (bfd *output_bfd,
                 || eh->root.type == bfd_link_hash_defweak)))
        abort ();
 
-      sec = htab->etab.srelbss;
-
       rela.r_offset = (eh->root.u.def.value
                      + eh->root.u.def.section->output_offset
                      + eh->root.u.def.section->output_section->vma);
       rela.r_addend = 0;
       rela.r_info = ELF32_R_INFO (eh->dynindx, R_PARISC_COPY);
+      if ((eh->root.u.def.section->flags & SEC_READONLY) != 0)
+       sec = htab->etab.sreldynrelro;
+      else
+       sec = htab->etab.srelbss;
       loc = sec->contents + sec->reloc_count++ * sizeof (Elf32_External_Rela);
       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
     }
@@ -4641,6 +4652,7 @@ elf32_hppa_elf_get_symbol_type (Elf_Internal_Sym *elf_sym, int type)
 #define elf_backend_plt_readonly            0
 #define elf_backend_want_plt_sym            0
 #define elf_backend_got_header_size         8
+#define elf_backend_want_dynrelro           1
 #define elf_backend_rela_normal                     1
 #define elf_backend_dtrel_excludes_plt      1
 
index eb287a81ba615343daf805ee1c7f19d2e6491edb..8f4477d00efba9453c193e4ae7a190cf6508b024 100644 (file)
@@ -2424,7 +2424,7 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
                                struct elf_link_hash_entry *h)
 {
   struct elf_i386_link_hash_table *htab;
-  asection *s;
+  asection *s, *srel;
   struct elf_i386_link_hash_entry *eh;
   struct elf_dyn_relocs *p;
 
@@ -2584,14 +2584,22 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* We must generate a R_386_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->elf.sdynrelro;
+      srel = htab->elf.sreldynrelro;
+    }
+  else
+    {
+      s = htab->elf.sdynbss;
+      srel = htab->elf.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
-      htab->elf.srelbss->size += sizeof (Elf32_External_Rel);
+      srel->size += sizeof (Elf32_External_Rel);
       h->needs_copy = 1;
     }
 
-  s = htab->elf.sdynbss;
-
   return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
@@ -3405,7 +3413,8 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
               || s == htab->elf.igotplt
               || s == htab->plt_got
               || s == htab->plt_eh_frame
-              || s == htab->elf.sdynbss)
+              || s == htab->elf.sdynbss
+              || s == htab->elf.sdynrelro)
        {
          /* Strip these too.  */
        }
@@ -5564,20 +5573,26 @@ do_glob_dat:
   if (h->needs_copy)
     {
       Elf_Internal_Rela rel;
+      asection *s;
 
       /* This symbol needs a copy reloc.  Set it up.  */
 
       if (h->dynindx == -1
          || (h->root.type != bfd_link_hash_defined
              && h->root.type != bfd_link_hash_defweak)
-         || htab->elf.srelbss == NULL)
+         || htab->elf.srelbss == NULL
+         || htab->elf.sreldynrelro == NULL)
        abort ();
 
       rel.r_offset = (h->root.u.def.value
                      + h->root.u.def.section->output_section->vma
                      + h->root.u.def.section->output_offset);
       rel.r_info = ELF32_R_INFO (h->dynindx, R_386_COPY);
-      elf_append_rel (output_bfd, htab->elf.srelbss, &rel);
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->elf.sreldynrelro;
+      else
+       s = htab->elf.srelbss;
+      elf_append_rel (output_bfd, s, &rel);
     }
 
   return TRUE;
@@ -6028,6 +6043,7 @@ elf_i386_hash_symbol (struct elf_link_hash_entry *h)
 #define elf_backend_dtrel_excludes_plt 1
 #define elf_backend_extern_protected_data 1
 #define elf_backend_caches_rawsize     1
+#define elf_backend_want_dynrelro      1
 
 /* Support RELA for objdump of prelink objects.  */
 #define elf_info_to_howto                    elf_i386_info_to_howto_rel
index 4ec2266d30b151ec0db8ee563cd11b6596e7bde0..f4b1e12064a80a03ce85d6dc7a622f77f234f8b0 100644 (file)
@@ -2470,7 +2470,7 @@ elf_metag_adjust_dynamic_symbol (struct bfd_link_info *info,
   struct elf_metag_link_hash_table *htab;
   struct elf_metag_link_hash_entry *hh;
   struct elf_metag_dyn_reloc_entry *hdh_p;
-  asection *s;
+  asection *s, *srel;
 
   /* If this is a function, put it in the procedure linkage table.  We
      will fill in the contents of the procedure linkage table later,
@@ -2564,14 +2564,22 @@ elf_metag_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* We must generate a COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  */
+  if ((eh->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->etab.sdynrelro;
+      srel = htab->etab.sreldynrelro;
+    }
+  else
+    {
+      s = htab->etab.sdynbss;
+      srel = htab->etab.srelbss;
+    }
   if ((eh->root.u.def.section->flags & SEC_ALLOC) != 0 && eh->size != 0)
     {
-      htab->etab.srelbss->size += sizeof (Elf32_External_Rela);
+      srel->size += sizeof (Elf32_External_Rela);
       eh->needs_copy = 1;
     }
 
-  s = htab->etab.sdynbss;
-
   return _bfd_elf_adjust_dynamic_copy (info, eh, s);
 }
 
@@ -2933,7 +2941,8 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
       if (s == htab->etab.splt
          || s == htab->etab.sgot
          || s == htab->etab.sgotplt
-         || s == htab->etab.sdynbss)
+         || s == htab->etab.sdynbss
+         || s == htab->etab.sdynrelro)
        {
          /* Strip this section if we don't need it; see the
             comment below.  */
@@ -3215,13 +3224,15 @@ elf_metag_finish_dynamic_symbol (bfd *output_bfd,
                 || eh->root.type == bfd_link_hash_defweak)))
        abort ();
 
-      s = htab->etab.srelbss;
-
       rel.r_offset = (eh->root.u.def.value
                      + eh->root.u.def.section->output_offset
                      + eh->root.u.def.section->output_section->vma);
       rel.r_addend = 0;
       rel.r_info = ELF32_R_INFO (eh->dynindx, R_METAG_COPY);
+      if ((eh->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->etab.sreldynrelro;
+      else
+       s = htab->etab.srelbss;
       loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
       bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
     }
@@ -4286,6 +4297,7 @@ elf_metag_plt_sym_val (bfd_vma i, const asection *plt,
 #define elf_backend_want_plt_sym               0
 #define elf_backend_plt_readonly               1
 #define elf_backend_dtrel_excludes_plt         1
+#define elf_backend_want_dynrelro              1
 
 #define bfd_elf32_bfd_reloc_type_lookup        metag_reloc_type_lookup
 #define bfd_elf32_bfd_reloc_name_lookup        metag_reloc_name_lookup
index 33c6026e853c689ff357563e28b3353876ae62db..31527d5a45576efc7d426761679ad582006f7edb 100644 (file)
@@ -2557,9 +2557,8 @@ microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   struct elf32_mb_link_hash_table *htab;
   struct elf32_mb_link_hash_entry * eh;
   struct elf32_mb_dyn_relocs *p;
-  asection *sdynbss, *s;
+  asection *s, *srel;
   unsigned int power_of_two;
-  bfd *dynobj;
 
   htab = elf32_mb_hash_table (info);
   if (htab == NULL)
@@ -2658,11 +2657,19 @@ microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
      to copy the initial value out of the dynamic object and into the
      runtime process image.  */
-  dynobj = elf_hash_table (info)->dynobj;
-  BFD_ASSERT (dynobj != NULL);
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->elf.sdynrelro;
+      srel = htab->elf.sreldynrelro;
+    }
+  else
+    {
+      s = htab->elf.sdynbss;
+      srel = htab->elf.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
     {
-      htab->elf.srelbss->size += sizeof (Elf32_External_Rela);
+      srel->size += sizeof (Elf32_External_Rela);
       h->needs_copy = 1;
     }
 
@@ -2672,21 +2679,20 @@ microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   if (power_of_two > 3)
     power_of_two = 3;
 
-  sdynbss = htab->elf.sdynbss;
   /* Apply the required alignment.  */
-  sdynbss->size = BFD_ALIGN (sdynbss->size, (bfd_size_type) (1 << power_of_two));
-  if (power_of_two > bfd_get_section_alignment (dynobj, sdynbss))
+  s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
+  if (power_of_two > s->alignment_power)
     {
-      if (! bfd_set_section_alignment (dynobj, sdynbss, power_of_two))
+      if (!bfd_set_section_alignment (s->owner, s, power_of_two))
        return FALSE;
     }
 
   /* Define the symbol as being at this point in the section.  */
-  h->root.u.def.section = sdynbss;
-  h->root.u.def.value = sdynbss->size;
+  h->root.u.def.section = s;
+  h->root.u.def.value = s->size;
 
   /* Increment the section size to make room for the symbol.  */
-  sdynbss->size += h->size;
+  s->size += h->size;
   return TRUE;
 }
 
@@ -3050,7 +3056,9 @@ microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
         }
       else if (s != htab->elf.splt
               && s != htab->elf.sgot
-              && s != htab->elf.sgotplt)
+              && s != htab->elf.sgotplt
+              && s != htab->elf.sdynbss
+              && s != htab->elf.sdynrelro)
         {
           /* It's not one of our sections, so don't allocate space.  */
           continue;
@@ -3256,14 +3264,15 @@ microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
 
       BFD_ASSERT (h->dynindx != -1);
 
-      s = bfd_get_linker_section (htab->elf.dynobj, ".rela.bss");
-      BFD_ASSERT (s != NULL);
-
       rela.r_offset = (h->root.u.def.value
                        + h->root.u.def.section->output_section->vma
                        + h->root.u.def.section->output_offset);
       rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_COPY);
       rela.r_addend = 0;
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->elf.sreldynrelro;
+      else
+       s = htab->elf.srelbss;
       loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
     }
@@ -3439,6 +3448,7 @@ microblaze_elf_add_symbol_hook (bfd *abfd,
 #define elf_backend_want_got_plt               1
 #define elf_backend_plt_readonly               1
 #define elf_backend_got_header_size            12
+#define elf_backend_want_dynrelro              1
 #define elf_backend_rela_normal                1
 #define elf_backend_dtrel_excludes_plt         1
 
index d398810ce6342b92895c5cd1a1a8202ccd277af7..f7649eb5e87c75fe636f877d4fa3354ec5dd6abd 100644 (file)
@@ -2482,6 +2482,7 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
 #define elf_backend_ecoff_debug_swap   &mips_elf32_ecoff_debug_swap
 
 #define elf_backend_got_header_size    (4 * MIPS_RESERVED_GOTNO)
+#define elf_backend_want_dynrelro      1
 #define elf_backend_may_use_rel_p      1
 #define elf_backend_may_use_rela_p     0
 #define elf_backend_default_use_rela_p 0
index a4ce99c7cd399f1e42b8861115dde6d6e4500000..541eb6f3489611f0b9d2ff45c8bc0addf871012a 100644 (file)
@@ -5275,14 +5275,16 @@ nios2_elf32_finish_dynamic_symbol (bfd *output_bfd,
                  && (h->root.type == bfd_link_hash_defined
                      || h->root.type == bfd_link_hash_defweak));
 
-      s = htab->root.srelbss;
-      BFD_ASSERT (s != NULL);
-
       rela.r_offset = (h->root.u.def.value
                       + h->root.u.def.section->output_section->vma
                       + h->root.u.def.section->output_offset);
       rela.r_info = ELF32_R_INFO (h->dynindx, R_NIOS2_COPY);
       rela.r_addend = 0;
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->root.sreldynrelro;
+      else
+       s = htab->root.srelbss;
+      BFD_ASSERT (s != NULL);
       loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
     }
@@ -5441,7 +5443,7 @@ nios2_elf32_adjust_dynamic_symbol (struct bfd_link_info *info,
 {
   struct elf32_nios2_link_hash_table *htab;
   bfd *dynobj;
-  asection *s;
+  asection *s, *srel;
   unsigned align2;
 
   htab = elf32_nios2_hash_table (info);
@@ -5523,19 +5525,22 @@ nios2_elf32_adjust_dynamic_symbol (struct bfd_link_info *info,
      determine the address it must put in the global offset table, so
      both the dynamic object and the regular object will refer to the
      same memory location for the variable.  */
-  s = htab->root.sdynbss;
-  BFD_ASSERT (s != NULL);
-
   /* We must generate a R_NIOS2_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
      .rela.bss section we are going to use.  */
-  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
     {
-      asection *srel;
-
+      s = htab->root.sdynrelro;
+      srel = htab->root.sreldynrelro;
+    }
+  else
+    {
+      s = htab->root.sdynbss;
       srel = htab->root.srelbss;
-      BFD_ASSERT (srel != NULL);
+    }
+  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+    {
       srel->size += sizeof (Elf32_External_Rela);
       h->needs_copy = 1;
     }
@@ -5975,7 +5980,7 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
         of the dynobj section names depend upon the input files.  */
       name = bfd_get_section_name (dynobj, s);
 
-      if (strcmp (name, ".plt") == 0)
+      if (s == htab->root.splt)
        {
          /* Remember whether there is a PLT.  */
          plt = s->size != 0;
@@ -5998,9 +6003,14 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
              s->reloc_count = 0;
            }
        }
-      else if (CONST_STRNEQ (name, ".got"))
-       got = s->size != 0;
-      else if (strcmp (name, ".dynbss") != 0)
+      else if (s == htab->root.sgot
+              || s == htab->root.sgotplt)
+       {
+         if (s->size != 0)
+           got = TRUE;
+       }
+      else if (s != htab->root.sdynbss
+              && s != htab->root.sdynrelro)
        /* It's not one of our sections, so don't allocate space.  */
        continue;
 
@@ -6249,6 +6259,7 @@ const struct bfd_elf_special_section elf32_nios2_special_sections[] =
 #define elf_backend_can_refcount       1
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_got_plt       1
+#define elf_backend_want_dynrelro      1
 #define elf_backend_rela_normal                1
 #define elf_backend_dtrel_excludes_plt 1
 
index c75a2ce125277b93b3dab14db84f15977dcb7bd0..7fc6b816a542e07acb3c6b1013c3bc8078afd0d7 100644 (file)
@@ -1944,17 +1944,16 @@ or1k_elf_finish_dynamic_symbol (bfd *output_bfd,
                   && (h->root.type == bfd_link_hash_defined
                       || h->root.type == bfd_link_hash_defweak));
 
-      s = bfd_get_section_by_name (h->root.u.def.section->owner,
-                                   ".rela.bss");
-      BFD_ASSERT (s != NULL);
-
       rela.r_offset = (h->root.u.def.value
                        + h->root.u.def.section->output_section->vma
                        + h->root.u.def.section->output_offset);
       rela.r_info = ELF32_R_INFO (h->dynindx, R_OR1K_COPY);
       rela.r_addend = 0;
-      loc = s->contents;
-      loc += s->reloc_count * sizeof (Elf32_External_Rela);
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->root.sreldynrelro;
+      else
+       s = htab->root.srelbss;
+      loc = s->contents + s->reloc_count * sizeof (Elf32_External_Rela);
       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
       ++s->reloc_count;
     }
@@ -1995,7 +1994,7 @@ or1k_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   struct elf_or1k_link_hash_entry *eh;
   struct elf_or1k_dyn_relocs *p;
   bfd *dynobj;
-  asection *s;
+  asection *s, *srel;
 
   dynobj = elf_hash_table (info)->dynobj;
 
@@ -2098,19 +2097,22 @@ or1k_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   if (htab == NULL)
     return FALSE;
 
-  s = htab->root.sdynbss;
-  BFD_ASSERT (s != NULL);
-
   /* We must generate a R_OR1K_COPY reloc to tell the dynamic linker
      to copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
      .rela.bss section we are going to use.  */
-  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
     {
-      asection *srel;
-
+      s = htab->root.sdynrelro;
+      srel = htab->root.sreldynrelro;
+    }
+  else
+    {
+      s = htab->root.sdynbss;
       srel = htab->root.srelbss;
-      BFD_ASSERT (srel != NULL);
+    }
+  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
+    {
       srel->size += sizeof (Elf32_External_Rela);
       h->needs_copy = 1;
     }
@@ -2472,7 +2474,8 @@ or1k_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
       if (s == htab->root.splt
           || s == htab->root.sgot
           || s == htab->root.sgotplt
-          || s == htab->root.sdynbss)
+         || s == htab->root.sdynbss
+         || s == htab->root.sdynrelro)
         {
           /* Strip this section if we don't need it; see the
              comment below.  */
@@ -2742,6 +2745,7 @@ elf32_or1k_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 #define elf_backend_want_plt_sym                0
 #define elf_backend_got_header_size             12
 #define elf_backend_dtrel_excludes_plt         1
+#define elf_backend_want_dynrelro              1
 
 #define bfd_elf32_bfd_link_hash_table_create    or1k_elf_link_hash_table_create
 #define elf_backend_copy_indirect_symbol        or1k_elf_copy_indirect_symbol
index 7f541d16b0601addaa7ccee5ef6906f07cc4d626..e65ff615a44d7454d33d1f8d7a840eb58405bf1e 100644 (file)
@@ -5806,6 +5806,8 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   if (ppc_elf_hash_entry (h)->has_sda_refs)
     s = htab->dynsbss;
+  else if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    s = htab->elf.sdynrelro;
   else
     s = htab->elf.sdynbss;
   BFD_ASSERT (s != NULL);
@@ -5820,6 +5822,8 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
 
       if (ppc_elf_hash_entry (h)->has_sda_refs)
        srel = htab->relsbss;
+      else if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       srel = htab->elf.sreldynrelro;
       else
        srel = htab->elf.srelbss;
       BFD_ASSERT (srel != NULL);
@@ -6636,6 +6640,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd,
               || s == htab->elf.sgotplt
               || s == htab->sbss
               || s == htab->elf.sdynbss
+              || s == htab->elf.sdynrelro
               || s == htab->dynsbss)
        {
          /* Strip these too.  */
@@ -10356,6 +10361,8 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
 
       if (ppc_elf_hash_entry (h)->has_sda_refs)
        s = htab->relsbss;
+      else if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->elf.sreldynrelro;
       else
        s = htab->elf.srelbss;
       BFD_ASSERT (s != NULL);
@@ -10893,6 +10900,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
 #endif
 
 #define elf_backend_plt_not_loaded     1
+#define elf_backend_want_dynrelro      1
 #define elf_backend_can_gc_sections    1
 #define elf_backend_can_refcount       1
 #define elf_backend_rela_normal                1
index 79c40509381ffa102ba414e8d809b51f9e239550..b52144aaaa1566f68d37951755f4e9419b18babc 100644 (file)
@@ -1607,7 +1607,7 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
                                struct elf_link_hash_entry *h)
 {
   struct elf_s390_link_hash_table *htab;
-  asection *s;
+  asection *s, *srel;
 
   /* STT_GNU_IFUNC symbol must go through PLT. */
   if (s390_is_ifunc_symbol_p (h))
@@ -1757,14 +1757,22 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* We must generate a R_390_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->elf.sdynrelro;
+      srel = htab->elf.sreldynrelro;
+    }
+  else
+    {
+      s = htab->elf.sdynbss;
+      srel = htab->elf.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
-      htab->elf.srelbss->size += sizeof (Elf32_External_Rela);
+      srel->size += sizeof (Elf32_External_Rela);
       h->needs_copy = 1;
     }
 
-  s = htab->elf.sdynbss;
-
   return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
@@ -2157,6 +2165,7 @@ elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
          || s == htab->elf.sgot
          || s == htab->elf.sgotplt
          || s == htab->elf.sdynbss
+         || s == htab->elf.sdynrelro
          || s == htab->elf.iplt
          || s == htab->elf.igotplt
          || s == htab->irelifunc)
@@ -3800,6 +3809,7 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
   if (h->needs_copy)
     {
       Elf_Internal_Rela rela;
+      asection *s;
       bfd_byte *loc;
 
       /* This symbols needs a copy reloc.  Set it up.  */
@@ -3807,7 +3817,8 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
       if (h->dynindx == -1
          || (h->root.type != bfd_link_hash_defined
              && h->root.type != bfd_link_hash_defweak)
-         || htab->elf.srelbss == NULL)
+         || htab->elf.srelbss == NULL
+         || htab->elf.sreldynrelro == NULL)
        abort ();
 
       rela.r_offset = (h->root.u.def.value
@@ -3815,8 +3826,11 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
                       + h->root.u.def.section->output_offset);
       rela.r_info = ELF32_R_INFO (h->dynindx, R_390_COPY);
       rela.r_addend = 0;
-      loc = htab->elf.srelbss->contents;
-      loc += htab->elf.srelbss->reloc_count++ * sizeof (Elf32_External_Rela);
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->elf.sreldynrelro;
+      else
+       s = htab->elf.srelbss;
+      loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
     }
 
@@ -4154,6 +4168,7 @@ elf32_s390_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_plt_sym       0
 #define elf_backend_got_header_size    12
+#define elf_backend_want_dynrelro      1
 #define elf_backend_rela_normal                1
 
 #define elf_info_to_howto                    elf_s390_info_to_howto
index 528cba29eac65339407dd04bd9e3f0e4e7158f3c..86109451f316af25f67c93f5aacf353454fd764b 100644 (file)
@@ -245,6 +245,7 @@ elf32_sparc_add_symbol_hook (bfd * abfd,
 #define elf_backend_plt_readonly 0
 #define elf_backend_want_plt_sym 1
 #define elf_backend_got_header_size 4
+#define elf_backend_want_dynrelro 1
 #define elf_backend_rela_normal 1
 
 #define elf_backend_add_symbol_hook            elf32_sparc_add_symbol_hook
index c2b22ee89a8e7e9a99d293c9436979e92856eae2..1ccbf9c7f0f5cb9416a88baaacc62c068cd8ce38 100644 (file)
@@ -1860,13 +1860,15 @@ elf32_tic6x_finish_dynamic_symbol (bfd * output_bfd,
   if (h->needs_copy)
     {
       Elf_Internal_Rela rel;
+      asection *s;
 
       /* This symbol needs a copy reloc.  Set it up.  */
 
       if (h->dynindx == -1
          || (h->root.type != bfd_link_hash_defined
              && h->root.type != bfd_link_hash_defweak)
-         || htab->elf.srelbss == NULL)
+         || htab->elf.srelbss == NULL
+         || htab->elf.sreldynrelro == NULL)
        abort ();
 
       rel.r_offset = (h->root.u.def.value
@@ -1874,8 +1876,12 @@ elf32_tic6x_finish_dynamic_symbol (bfd * output_bfd,
                      + h->root.u.def.section->output_offset);
       rel.r_info = ELF32_R_INFO (h->dynindx, R_C6000_COPY);
       rel.r_addend = 0;
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->elf.sreldynrelro;
+      else
+       s = htab->elf.srelbss;
 
-      elf32_tic6x_install_rela (output_bfd, htab->elf.srelbss, &rel);
+      elf32_tic6x_install_rela (output_bfd, s, &rel);
     }
 
   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
@@ -2061,7 +2067,7 @@ elf32_tic6x_adjust_dynamic_symbol (struct bfd_link_info *info,
 {
   struct elf32_tic6x_link_hash_table *htab;
   bfd *dynobj;
-  asection *s;
+  asection *s, *srel;
 
   dynobj = elf_hash_table (info)->dynobj;
 
@@ -2146,14 +2152,22 @@ elf32_tic6x_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* We must generate a R_C6000_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->elf.sdynrelro;
+      srel = htab->elf.sreldynrelro;
+    }
+  else
+    {
+      s = htab->elf.sdynbss;
+      srel = htab->elf.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
-      htab->elf.srelbss->size += sizeof (Elf32_External_Rela);
+      srel->size += sizeof (Elf32_External_Rela);
       h->needs_copy = 1;
     }
 
-  s = htab->elf.sdynbss;
-
   return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
@@ -3376,7 +3390,8 @@ elf32_tic6x_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
       else if (s == htab->elf.splt
               || s == htab->elf.sgot
               || s == htab->elf.sgotplt
-              || s == htab->elf.sdynbss)
+              || s == htab->elf.sdynbss
+              || s == htab->elf.sdynrelro)
        {
          /* Strip this section if we don't need it; see the
             comment below.  */
@@ -4369,6 +4384,7 @@ elf32_tic6x_write_section (bfd *output_bfd,
 #define elf_backend_can_refcount       1
 #define elf_backend_want_got_plt       1
 #define elf_backend_want_dynbss                1
+#define elf_backend_want_dynrelro      1
 #define elf_backend_plt_readonly       1
 #define elf_backend_rela_normal                1
 #define elf_backend_got_header_size     8
index bf1ad6bb105247729b9f2ca43efe0c0ad561eaac..1b4aa8ff6ff94a9532f4159fa28bb1300c5f2c18 100644 (file)
@@ -128,6 +128,7 @@ tilegx_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 #define elf_backend_plt_alignment 6
 #define elf_backend_want_plt_sym 1
 #define elf_backend_got_header_size 4
+#define elf_backend_want_dynrelro 1
 #define elf_backend_rela_normal 1
 #define elf_backend_default_execstack 0
 
index 18aabb030ec1877ae0891cf245468b359046b58c..f95cd2780fd7c50e1bcaecfdb08d811b1a214ce0 100644 (file)
@@ -2062,7 +2062,7 @@ tilepro_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   struct tilepro_elf_link_hash_table *htab;
   struct tilepro_elf_link_hash_entry * eh;
   struct tilepro_elf_dyn_relocs *p;
-  asection *s;
+  asection *s, *srel;
 
   htab = tilepro_elf_hash_table (info);
   BFD_ASSERT (htab != NULL);
@@ -2164,13 +2164,23 @@ tilepro_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
      to copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
      .rel.bss section we are going to use.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->elf.sdynrelro;
+      srel = htab->elf.sreldynrelro;
+    }
+  else
+    {
+      s = htab->elf.sdynbss;
+      srel = htab->elf.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
-      htab->elf.srelbss->size += TILEPRO_ELF_RELA_BYTES;
+      srel->size += TILEPRO_ELF_RELA_BYTES;
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (info, h, htab->elf.sdynbss);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
@@ -2565,7 +2575,8 @@ tilepro_elf_size_dynamic_sections (bfd *output_bfd,
       if (s == htab->elf.splt
          || s == htab->elf.sgot
          || s == htab->elf.sgotplt
-         || s == htab->elf.sdynbss)
+         || s == htab->elf.sdynbss
+         || s == htab->elf.sdynrelro)
        {
          /* Strip this section if we don't need it; see the
             comment below.  */
@@ -3797,14 +3808,15 @@ tilepro_elf_finish_dynamic_symbol (bfd *output_bfd,
       /* This symbols needs a copy reloc.  Set it up.  */
       BFD_ASSERT (h->dynindx != -1);
 
-      s = htab->elf.srelbss;
-      BFD_ASSERT (s != NULL);
-
       rela.r_offset = (h->root.u.def.value
                       + h->root.u.def.section->output_section->vma
                       + h->root.u.def.section->output_offset);
       rela.r_info = ELF32_R_INFO (h->dynindx, R_TILEPRO_COPY);
       rela.r_addend = 0;
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->elf.sreldynrelro;
+      else
+       s = htab->elf.srelbss;
       tilepro_elf_append_rela_32 (output_bfd, s, &rela);
     }
 
@@ -4045,6 +4057,7 @@ tilepro_additional_program_headers (bfd *abfd,
 #define elf_backend_plt_alignment 6
 #define elf_backend_want_plt_sym 1
 #define elf_backend_got_header_size GOT_ENTRY_SIZE
+#define elf_backend_want_dynrelro 1
 #define elf_backend_rela_normal 1
 #define elf_backend_default_execstack 0
 
index 8cd0a73e764e9ea3aeed6d40aa648de7c5dbd866..1a39522423db1e36d0bee6f6576564eefc9010e0 100644 (file)
@@ -4467,6 +4467,7 @@ const struct elf_size_info mips_elf64_size_info =
 #define elf_backend_grok_psinfo                elf64_mips_grok_psinfo
 
 #define elf_backend_got_header_size    (8 * MIPS_RESERVED_GOTNO)
+#define elf_backend_want_dynrelro      1
 
 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
    work better/work only in RELA, so we default to this.  */
index c421426508be31cfcdc0b870ff0f9d94193ee0d7..9520777f1e0403d90a48b6f6c0a2b69f6421f96a 100644 (file)
@@ -72,6 +72,7 @@ static bfd_vma opd_entry_value
 #define elf_backend_plt_alignment 3
 #define elf_backend_plt_not_loaded 1
 #define elf_backend_got_header_size 8
+#define elf_backend_want_dynrelro 1
 #define elf_backend_can_gc_sections 1
 #define elf_backend_can_refcount 1
 #define elf_backend_rela_normal 1
@@ -7235,7 +7236,7 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
                                 struct elf_link_hash_entry *h)
 {
   struct ppc_link_hash_table *htab;
-  asection *s;
+  asection *s, *srel;
 
   htab = ppc_hash_table (info);
   if (htab == NULL)
@@ -7365,14 +7366,22 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
      to copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
      .rela.bss section we are going to use.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->elf.sdynrelro;
+      srel = htab->elf.sreldynrelro;
+    }
+  else
+    {
+      s = htab->elf.sdynbss;
+      srel = htab->elf.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
-      htab->elf.srelbss->size += sizeof (Elf64_External_Rela);
+      srel->size += sizeof (Elf64_External_Rela);
       h->needs_copy = 1;
     }
 
-  s = htab->elf.sdynbss;
-
   return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
@@ -10174,7 +10183,8 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
               || s == htab->elf.splt
               || s == htab->elf.iplt
               || s == htab->glink
-              || s == htab->elf.sdynbss)
+              || s == htab->elf.sdynbss
+              || s == htab->elf.sdynrelro)
        {
          /* Strip this section if we don't need it; see the
             comment below.  */
@@ -10227,7 +10237,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd,
         but this way if it does we get a R_PPC64_NONE reloc in .rela
         sections instead of garbage.
         We also rely on the section contents being zero when writing
-        the GOT.  */
+        the GOT and .dynrelro.  */
       s->contents = bfd_zalloc (dynobj, s->size);
       if (s->contents == NULL)
        return FALSE;
@@ -15421,11 +15431,13 @@ ppc64_elf_finish_dynamic_symbol (bfd *output_bfd,
   if (h->needs_copy)
     {
       /* This symbol needs a copy reloc.  Set it up.  */
+      asection *srel;
 
       if (h->dynindx == -1
          || (h->root.type != bfd_link_hash_defined
              && h->root.type != bfd_link_hash_defweak)
-         || htab->elf.srelbss == NULL)
+         || htab->elf.srelbss == NULL
+         || htab->elf.sreldynrelro == NULL)
        abort ();
 
       rela.r_offset = (h->root.u.def.value
@@ -15433,8 +15445,12 @@ ppc64_elf_finish_dynamic_symbol (bfd *output_bfd,
                       + h->root.u.def.section->output_offset);
       rela.r_info = ELF64_R_INFO (h->dynindx, R_PPC64_COPY);
       rela.r_addend = 0;
-      loc = htab->elf.srelbss->contents;
-      loc += htab->elf.srelbss->reloc_count++ * sizeof (Elf64_External_Rela);
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       srel = htab->elf.sreldynrelro;
+      else
+       srel = htab->elf.srelbss;
+      loc = srel->contents;
+      loc += srel->reloc_count++ * sizeof (Elf64_External_Rela);
       bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
     }
 
index ab2bbaa9331e01cfe49bfe59132c8b496a2825d8..64a74c5dfcdd87bed5636d29d379d5b92425ff45 100644 (file)
@@ -1541,7 +1541,7 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
                                struct elf_link_hash_entry *h)
 {
   struct elf_s390_link_hash_table *htab;
-  asection *s;
+  asection *s, *srel;
 
   /* STT_GNU_IFUNC symbol must go through PLT. */
   if (s390_is_ifunc_symbol_p (h))
@@ -1693,14 +1693,22 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* We must generate a R_390_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->elf.sdynrelro;
+      srel = htab->elf.sreldynrelro;
+    }
+  else
+    {
+      s = htab->elf.sdynbss;
+      srel = htab->elf.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
-      htab->elf.srelbss->size += sizeof (Elf64_External_Rela);
+      srel->size += sizeof (Elf64_External_Rela);
       h->needs_copy = 1;
     }
 
-  s = htab->elf.sdynbss;
-
   return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
@@ -2099,6 +2107,7 @@ elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
          || s == htab->elf.sgot
          || s == htab->elf.sgotplt
          || s == htab->elf.sdynbss
+         || s == htab->elf.sdynrelro
          || s == htab->elf.iplt
          || s == htab->elf.igotplt
          || s == htab->irelifunc)
@@ -3585,6 +3594,7 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
   if (h->needs_copy)
     {
       Elf_Internal_Rela rela;
+      asection *s;
       bfd_byte *loc;
 
       /* This symbols needs a copy reloc.  Set it up.  */
@@ -3600,8 +3610,11 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
                       + h->root.u.def.section->output_offset);
       rela.r_info = ELF64_R_INFO (h->dynindx, R_390_COPY);
       rela.r_addend = 0;
-      loc = htab->elf.srelbss->contents;
-      loc += htab->elf.srelbss->reloc_count++ * sizeof (Elf64_External_Rela);
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->elf.sreldynrelro;
+      else
+       s = htab->elf.srelbss;
+      loc = s->contents + s->reloc_count++ * sizeof (Elf64_External_Rela);
       bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
     }
 
@@ -3979,6 +3992,7 @@ const struct elf_size_info s390_elf64_size_info =
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_plt_sym       0
 #define elf_backend_got_header_size    24
+#define elf_backend_want_dynrelro      1
 #define elf_backend_rela_normal                1
 
 #define elf_info_to_howto              elf_s390_info_to_howto
index 65fb5e4e74c61dbeeda8b3f500fb41ce5bf536c5..eecccd16c48ebd45799f9305840003ca0b77249d 100644 (file)
@@ -920,6 +920,7 @@ const struct elf_size_info elf64_sparc_size_info =
 #define elf_backend_plt_readonly 0
 #define elf_backend_want_plt_sym 1
 #define elf_backend_got_header_size 8
+#define elf_backend_want_dynrelro 1
 #define elf_backend_rela_normal 1
 
 /* Section 5.2.4 of the ABI specifies a 256-byte boundary for the table.  */
index c281474a691cb3bbac5206d1aa511d8cdc28e158..f3f9076dd56579f83b2136f65868306585fafdcd 100644 (file)
@@ -129,6 +129,7 @@ tilegx_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 #define elf_backend_plt_alignment 6
 #define elf_backend_want_plt_sym 1
 #define elf_backend_got_header_size 8
+#define elf_backend_want_dynrelro 1
 #define elf_backend_rela_normal 1
 #define elf_backend_default_execstack 0
 
index d5a36bcc74962079caac6a3f515729ee2dd90ced..5b3dd8a09a1a5816622e29a2d16c1408d05246d8 100644 (file)
@@ -2828,7 +2828,7 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
                                  struct elf_link_hash_entry *h)
 {
   struct elf_x86_64_link_hash_table *htab;
-  asection *s;
+  asection *s, *srel;
   struct elf_x86_64_link_hash_entry *eh;
   struct elf_dyn_relocs *p;
 
@@ -2986,16 +2986,24 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* We must generate a R_X86_64_COPY reloc to tell the dynamic linker
      to copy the initial value out of the dynamic object and into the
      runtime process image.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->elf.sdynrelro;
+      srel = htab->elf.sreldynrelro;
+    }
+  else
+    {
+      s = htab->elf.sdynbss;
+      srel = htab->elf.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
       const struct elf_backend_data *bed;
       bed = get_elf_backend_data (info->output_bfd);
-      htab->elf.srelbss->size += bed->s->sizeof_rela;
+      srel->size += bed->s->sizeof_rela;
       h->needs_copy = 1;
     }
 
-  s = htab->elf.sdynbss;
-
   return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
@@ -3811,7 +3819,8 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
          || s == htab->plt_bnd
          || s == htab->plt_got
          || s == htab->plt_eh_frame
-         || s == htab->elf.sdynbss)
+         || s == htab->elf.sdynbss
+         || s == htab->elf.sdynrelro)
        {
          /* Strip this section if we don't need it; see the
             comment below.  */
@@ -6024,13 +6033,15 @@ do_glob_dat:
   if (h->needs_copy)
     {
       Elf_Internal_Rela rela;
+      asection *s;
 
       /* This symbol needs a copy reloc.  Set it up.  */
 
       if (h->dynindx == -1
          || (h->root.type != bfd_link_hash_defined
              && h->root.type != bfd_link_hash_defweak)
-         || htab->elf.srelbss == NULL)
+         || htab->elf.srelbss == NULL
+         || htab->elf.sreldynrelro == NULL)
        abort ();
 
       rela.r_offset = (h->root.u.def.value
@@ -6038,7 +6049,11 @@ do_glob_dat:
                       + h->root.u.def.section->output_offset);
       rela.r_info = htab->r_info (h->dynindx, R_X86_64_COPY);
       rela.r_addend = 0;
-      elf_append_rela (output_bfd, htab->elf.srelbss, &rela);
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->elf.sreldynrelro;
+      else
+       s = htab->elf.srelbss;
+      elf_append_rela (output_bfd, s, &rela);
     }
 
   return TRUE;
@@ -6719,6 +6734,7 @@ static const struct bfd_elf_special_section
 #define elf_backend_extern_protected_data   1
 #define elf_backend_caches_rawsize         1
 #define elf_backend_dtrel_excludes_plt     1
+#define elf_backend_want_dynrelro          1
 
 #define elf_info_to_howto                  elf_x86_64_info_to_howto
 
index 9728e29feaf82745358bd4ab4a59fae56d3268a8..d8d40f1441bafbeb3e39d845fe981f8993ea0436 100644 (file)
@@ -429,6 +429,19 @@ _bfd_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
        return FALSE;
       htab->sdynbss = s;
 
+      if (bed->want_dynrelro)
+       {
+         /* Similarly, but for symbols that were originally in read-only
+            sections.  */
+         s = bfd_make_section_anyway_with_flags (abfd, ".data.rel.ro",
+                                                 (SEC_ALLOC | SEC_READONLY
+                                                  | SEC_HAS_CONTENTS
+                                                  | SEC_LINKER_CREATED));
+         if (s == NULL)
+           return FALSE;
+         htab->sdynrelro = s;
+       }
+
       /* The .rel[a].bss section holds copy relocs.  This section is not
         normally needed.  We need to create it here, though, so that the
         linker will map it to an output section.  We can't just create it
@@ -450,6 +463,19 @@ _bfd_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
              || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
            return FALSE;
          htab->srelbss = s;
+
+         if (bed->want_dynrelro)
+           {
+             s = (bfd_make_section_anyway_with_flags
+                  (abfd, (bed->rela_plts_and_copies_p
+                          ? ".rela.data.rel.ro" : ".rel.data.rel.ro"),
+                   flags | SEC_READONLY));
+             if (s == NULL
+                 || ! bfd_set_section_alignment (abfd, s,
+                                                 bed->s->log_file_align))
+               return FALSE;
+             htab->sreldynrelro = s;
+           }
        }
     }
 
index 8a5559685e77a069fe15a90fe636dec866183e31..0103b01ee91114bae798b76e82c7dd3d375c31bd 100644 (file)
@@ -6833,7 +6833,7 @@ elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info *info,
                                     struct elf_link_hash_entry *h)
 {
   struct elf_aarch64_link_hash_table *htab;
-  asection *s;
+  asection *s, *srel;
 
   /* If this is a function, put it in the procedure linkage table.  We
      will fill in the contents of the procedure linkage table later,
@@ -6910,14 +6910,22 @@ elfNN_aarch64_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* We must generate a R_AARCH64_COPY reloc to tell the dynamic linker
      to copy the initial value out of the dynamic object and into the
      runtime process image.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->root.sdynrelro;
+      srel = htab->root.sreldynrelro;
+    }
+  else
+    {
+      s = htab->root.sdynbss;
+      srel = htab->root.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
-      htab->root.srelbss->size += RELOC_SIZE (htab);
+      srel->size += RELOC_SIZE (htab);
       h->needs_copy = 1;
     }
 
-  s = htab->root.sdynbss;
-
   return _bfd_elf_adjust_dynamic_copy (info, h, s);
 
 }
@@ -8517,7 +8525,8 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
          || s == htab->root.sgotplt
          || s == htab->root.iplt
          || s == htab->root.igotplt
-         || s == htab->root.sdynbss)
+         || s == htab->root.sdynbss
+         || s == htab->root.sdynrelro)
        {
          /* Strip this section if we don't need it; see the
             comment below.  */
@@ -8921,6 +8930,7 @@ do_glob_dat:
   if (h->needs_copy)
     {
       Elf_Internal_Rela rela;
+      asection *s;
       bfd_byte *loc;
 
       /* This symbol needs a copy reloc.  Set it up.  */
@@ -8936,8 +8946,11 @@ do_glob_dat:
                       + h->root.u.def.section->output_offset);
       rela.r_info = ELFNN_R_INFO (h->dynindx, AARCH64_R (COPY));
       rela.r_addend = 0;
-      loc = htab->root.srelbss->contents;
-      loc += htab->root.srelbss->reloc_count++ * RELOC_SIZE (htab);
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->root.sreldynrelro;
+      else
+       s = htab->root.srelbss;
+      loc = s->contents + s->reloc_count++ * RELOC_SIZE (htab);
       bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
     }
 
@@ -9390,6 +9403,7 @@ const struct elf_size_info elfNN_aarch64_size_info =
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_got_plt       1
 #define elf_backend_want_plt_sym       0
+#define elf_backend_want_dynrelro      1
 #define elf_backend_may_use_rel_p      0
 #define elf_backend_may_use_rela_p     1
 #define elf_backend_default_use_rela_p 1
index db4b7821df1620953de0509b33aeae89b0a7bfc4..69907bd241f103b7efbb1d2ea6e238032e2fe1fd 100644 (file)
@@ -862,7 +862,7 @@ riscv_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   struct riscv_elf_link_hash_entry * eh;
   struct riscv_elf_dyn_relocs *p;
   bfd *dynobj;
-  asection *s;
+  asection *s, *srel;
 
   htab = riscv_elf_hash_table (info);
   BFD_ASSERT (htab != NULL);
@@ -965,16 +965,26 @@ riscv_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
      to copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
      .rel.bss section we are going to use.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->elf.sdynrelro;
+      srel = htab->elf.sreldynrelro;
+    }
+  else
+    {
+      s = htab->elf.sdynbss;
+      srel = htab->elf.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
-      htab->elf.srelbss->size += sizeof (ElfNN_External_Rela);
+      srel->size += sizeof (ElfNN_External_Rela);
       h->needs_copy = 1;
     }
 
   if (eh->tls_type & ~GOT_NORMAL)
     return _bfd_elf_adjust_dynamic_copy (info, h, htab->sdyntdata);
 
-  return _bfd_elf_adjust_dynamic_copy (info, h, htab->elf.sdynbss);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
@@ -1328,7 +1338,8 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
       if (s == htab->elf.splt
          || s == htab->elf.sgot
          || s == htab->elf.sgotplt
-         || s == htab->elf.sdynbss)
+         || s == htab->elf.sdynbss
+         || s == htab->elf.sdynrelro)
        {
          /* Strip this section if we don't need it; see the
             comment below.  */
@@ -2389,6 +2400,7 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
   if (h->needs_copy)
     {
       Elf_Internal_Rela rela;
+      asection *s;
 
       /* This symbols needs a copy reloc.  Set it up.  */
       BFD_ASSERT (h->dynindx != -1);
@@ -2396,7 +2408,11 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
       rela.r_offset = sec_addr (h->root.u.def.section) + h->root.u.def.value;
       rela.r_info = ELFNN_R_INFO (h->dynindx, R_RISCV_COPY);
       rela.r_addend = 0;
-      riscv_elf_append_rela (output_bfd, htab->elf.srelbss, &rela);
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->elf.sreldynrelro;
+      else
+       s = htab->elf.srelbss;
+      riscv_elf_append_rela (output_bfd, s, &rela);
     }
 
   /* Mark some specially defined symbols as absolute.  */
@@ -3213,6 +3229,7 @@ riscv_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 #define elf_backend_plt_alignment      4
 #define elf_backend_want_plt_sym       1
 #define elf_backend_got_header_size    (ARCH_SIZE / 8)
+#define elf_backend_want_dynrelro      1
 #define elf_backend_rela_normal                1
 #define elf_backend_default_execstack  0
 
index 086d537e7957449ad370d1155933cc52f97ccf4a..7c7cd3898a891364650c658c79f7b3df5ca35d19 100644 (file)
@@ -9129,6 +9129,7 @@ _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   bfd *dynobj;
   struct mips_elf_link_hash_entry *hmips;
   struct mips_elf_link_hash_table *htab;
+  asection *s, *srel;
 
   htab = mips_elf_hash_table (info);
   BFD_ASSERT (htab != NULL);
@@ -9371,10 +9372,20 @@ _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
      both the dynamic object and the regular object will refer to the
      same memory location for the variable.  */
 
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->root.sdynrelro;
+      srel = htab->root.sreldynrelro;
+    }
+  else
+    {
+      s = htab->root.sdynbss;
+      srel = htab->root.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
     {
       if (htab->is_vxworks)
-       htab->root.srelbss->size += sizeof (Elf32_External_Rela);
+       srel->size += sizeof (Elf32_External_Rela);
       else
        mips_elf_allocate_dynamic_relocations (dynobj, info, 1);
       h->needs_copy = 1;
@@ -9384,7 +9395,7 @@ _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
      dynamic will now refer to the local copy instead.  */
   hmips->possibly_dynamic_relocs = 0;
 
-  return _bfd_elf_adjust_dynamic_copy (info, h, htab->root.sdynbss);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 \f
 /* This function is called after all the input files have been read,
@@ -9906,7 +9917,8 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
               && s != htab->root.sgot
               && s != htab->root.sgotplt
               && s != htab->sstubs
-              && s != htab->root.sdynbss)
+              && s != htab->root.sdynbss
+              && s != htab->root.sdynrelro)
        {
          /* It's not one of our sections, so don't allocate space.  */
          continue;
@@ -11296,6 +11308,8 @@ _bfd_mips_vxworks_finish_dynamic_symbol (bfd *output_bfd,
   if (h->needs_copy)
     {
       Elf_Internal_Rela rel;
+      asection *srel;
+      bfd_byte *loc;
 
       BFD_ASSERT (h->dynindx != -1);
 
@@ -11304,11 +11318,13 @@ _bfd_mips_vxworks_finish_dynamic_symbol (bfd *output_bfd,
                      + h->root.u.def.value);
       rel.r_info = ELF32_R_INFO (h->dynindx, R_MIPS_COPY);
       rel.r_addend = 0;
-      bfd_elf32_swap_reloca_out (output_bfd, &rel,
-                                htab->root.srelbss->contents
-                                + (htab->root.srelbss->reloc_count
-                                   * sizeof (Elf32_External_Rela)));
-      ++htab->root.srelbss->reloc_count;
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       srel = htab->root.sreldynrelro;
+      else
+       srel = htab->root.srelbss;
+      loc = srel->contents + srel->reloc_count * sizeof (Elf32_External_Rela);
+      bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
+      ++srel->reloc_count;
     }
 
   /* If this is a mips16/microMIPS symbol, force the value to be even.  */
index 050993ce1b3fd0d5ef3f0b6183fb4e063a948fb2..d7b26885ecafd2934e13dc3423665983cceea967 100644 (file)
@@ -2086,7 +2086,7 @@ _bfd_sparc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   struct _bfd_sparc_elf_link_hash_table *htab;
   struct _bfd_sparc_elf_link_hash_entry * eh;
   struct _bfd_sparc_elf_dyn_relocs *p;
-  asection *s;
+  asection *s, *srel;
 
   htab = _bfd_sparc_elf_hash_table (info);
   BFD_ASSERT (htab != NULL);
@@ -2199,14 +2199,22 @@ _bfd_sparc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
      to copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
      .rel.bss section we are going to use.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->elf.sdynrelro;
+      srel = htab->elf.sreldynrelro;
+    }
+  else
+    {
+      s = htab->elf.sdynbss;
+      srel = htab->elf.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
-      htab->elf.srelbss->size += SPARC_ELF_RELA_BYTES (htab);
+      srel->size += SPARC_ELF_RELA_BYTES (htab);
       h->needs_copy = 1;
     }
 
-  s = htab->elf.sdynbss;
-
   return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
@@ -2686,6 +2694,7 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd,
       if (s == htab->elf.splt
          || s == htab->elf.sgot
          || s == htab->elf.sdynbss
+         || s == htab->elf.sdynrelro
          || s == htab->elf.iplt
          || s == htab->elf.sgotplt)
        {
@@ -4527,15 +4536,15 @@ _bfd_sparc_elf_finish_dynamic_symbol (bfd *output_bfd,
       /* This symbols needs a copy reloc.  Set it up.  */
       BFD_ASSERT (h->dynindx != -1);
 
-      s = bfd_get_linker_section (h->root.u.def.section->owner,
-                                 ".rela.bss");
-      BFD_ASSERT (s != NULL);
-
       rela.r_offset = (h->root.u.def.value
                       + h->root.u.def.section->output_section->vma
                       + h->root.u.def.section->output_offset);
       rela.r_info = SPARC_ELF_R_INFO (htab, NULL, h->dynindx, R_SPARC_COPY);
       rela.r_addend = 0;
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->elf.sreldynrelro;
+      else
+       s = htab->elf.srelbss;
       sparc_elf_append_rela (output_bfd, s, &rela);
     }
 
index aff862148596775424e76b7d576106d36e4407f3..7f081283f9ccb507a990392d0cdac07e12df7121 100644 (file)
 #ifndef elf_backend_want_dynbss
 #define elf_backend_want_dynbss 1
 #endif
+#ifndef elf_backend_want_dynrelro
+#define elf_backend_want_dynrelro 0
+#endif
 #ifndef elf_backend_want_p_paddr_set_to_zero
 #define elf_backend_want_p_paddr_set_to_zero 0
 #endif
@@ -855,6 +858,7 @@ static struct elf_backend_data elfNN_bed =
   elf_backend_can_refcount,
   elf_backend_want_got_sym,
   elf_backend_want_dynbss,
+  elf_backend_want_dynrelro,
   elf_backend_want_p_paddr_set_to_zero,
   elf_backend_default_execstack,
   elf_backend_caches_rawsize,
index 92b9de8aedf24cd1fa32c202ad23c12ed643575c..ce4fb07f2b77d19c0cfce504c456eae8b6824d76 100644 (file)
@@ -2327,7 +2327,7 @@ tilegx_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   struct tilegx_elf_link_hash_entry * eh;
   struct tilegx_elf_dyn_relocs *p;
   bfd *dynobj;
-  asection *s;
+  asection *s, *srel;
 
   htab = tilegx_elf_hash_table (info);
   BFD_ASSERT (htab != NULL);
@@ -2431,13 +2431,23 @@ tilegx_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
      to copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
      .rel.bss section we are going to use.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->elf.sdynrelro;
+      srel = htab->elf.sreldynrelro;
+    }
+  else
+    {
+      s = htab->elf.sdynbss;
+      srel = htab->elf.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
-      htab->elf.srelbss->size += TILEGX_ELF_RELA_BYTES (htab);
+      srel->size += TILEGX_ELF_RELA_BYTES (htab);
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (info, h, htab->elf.sdynbss);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
@@ -2826,7 +2836,8 @@ tilegx_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
       if (s == htab->elf.splt
          || s == htab->elf.sgot
          || s == htab->elf.sgotplt
-         || s == htab->elf.sdynbss)
+         || s == htab->elf.sdynbss
+         || s == htab->elf.sdynrelro)
        {
          /* Strip this section if we don't need it; see the
             comment below.  */
@@ -4187,7 +4198,10 @@ tilegx_elf_finish_dynamic_symbol (bfd *output_bfd,
       /* This symbols needs a copy reloc.  Set it up.  */
       BFD_ASSERT (h->dynindx != -1);
 
-      s = htab->elf.srelbss;
+      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+       s = htab->elf.sreldynrelro;
+      else
+       s = htab->elf.srelbss;
       BFD_ASSERT (s != NULL);
 
       rela.r_offset = (h->root.u.def.value
index a9f157ead297d0c3c939a7cb4f2a9a67abbc5630..1b8f59aa600f2a5311a4ce3f08502e4f68faa2a5 100644 (file)
@@ -1,3 +1,16 @@
+2016-12-26  Alan Modra  <amodra@gmail.com>
+
+       PR ld/20995
+       * testsuite/ld-arm/farcall-mixed-app-v5.d: Update to suit changed
+       stub hash table traversal caused by section id increment.  Accept
+       the previous output too.
+       * testsuite/ld-arm/farcall-mixed-app.d: Likewise.
+       * testsuite/ld-arm/farcall-mixed-lib-v4t.d: Likewise.
+       * testsuite/ld-arm/farcall-mixed-lib.d: Likewise.
+       * testsuite/ld-elf/pr20995a.s, * testsuite/ld-elf/pr20995b.s,
+       * testsuite/ld-elf/pr20995.r: New test.
+       * testsuite/ld-elf/elf.exp: Run it.
+
 2016-12-26  Alan Modra  <amodra@gmail.com>
 
        * scripttempl/elf.sc: Don't use $BSS_NAME in .dynbss.
index b570badb4bc4a5f439f1c0cfaba42d5cbf16891d..af4419874a57c4395fb18edfef89ff4f70823a89 100644 (file)
@@ -50,8 +50,8 @@ Disassembly of section .far_arm:
 .* <app_func>:
  .*:   e1a0c00d        mov     ip, sp
  .*:   e92dd800        push    {fp, ip, lr, pc}
- .*:   eb0000..        bl      .* <__lib_func1_veneer>
- .*:   eb0000..        bl      .* <__lib_func2_veneer>
+ .*:   eb00000(6|8)    bl      .* <__lib_func1_veneer>
+ .*:   eb00000(7|5)    bl      .* <__lib_func2_veneer>
  .*:   e89d6800        ldm     sp, {fp, sp, lr}
  .*:   e12fff1e        bx      lr
  .*:   e1a00000        nop                     ; \(mov r0, r0\)
@@ -61,12 +61,12 @@ Disassembly of section .far_arm:
  .*:   e12fff1e        bx      lr
 #...
 
-.* <__lib_func1_veneer>:
- .*:   e51ff004        ldr     pc, \[pc, #-4\] ; .* <__lib_func1_veneer\+0x4>
- .*:   000081e8        .word   0x000081e8
-.* <__lib_func2_veneer>:
- .*:   e51ff004        ldr     pc, \[pc, #-4\] ; .* <__lib_func2_veneer\+0x4>
- .*:   000081dc        .word   0x000081dc
+.* <__lib_func(1|2)_veneer>:
+ .*:   e51ff004        ldr     pc, \[pc, #-4\] ; .* <__lib_func(1|2)_veneer\+0x4>
+ .*:   000081(e8|dc)   .word   0x000081(e8|dc)
+.* <__lib_func(2|1)_veneer>:
+ .*:   e51ff004        ldr     pc, \[pc, #-4\] ; .* <__lib_func(2|1)_veneer\+0x4>
+ .*:   000081(dc|e8)   .word   0x000081(dc|e8)
 
 Disassembly of section .far_thumb:
 
index 9fa97dcf11731e6cb094f813e23262fe69162cbc..f3be54f13427c033033d550f6502991d09c39fd8 100644 (file)
@@ -52,8 +52,8 @@ Disassembly of section .far_arm:
 .* <app_func>:
  .*:   e1a0c00d        mov     ip, sp
  .*:   e92dd800        push    {fp, ip, lr, pc}
- .*:   eb000006        bl      .* <__lib_func1_veneer>
- .*:   eb000007        bl      .* <__lib_func2_veneer>
+ .*:   eb00000(6|8)    bl      .* <__lib_func1_veneer>
+ .*:   eb00000(7|5)    bl      .* <__lib_func2_veneer>
  .*:   e89d6800        ldm     sp, {fp, sp, lr}
  .*:   e12fff1e        bx      lr
  .*:   e1a00000        nop                     ; \(mov r0, r0\)
@@ -63,12 +63,12 @@ Disassembly of section .far_arm:
  .*:   e12fff1e        bx      lr
 #...
 
-.* <__lib_func1_veneer>:
- .*:   e51ff004        ldr     pc, \[pc, #-4\] ; .* <__lib_func1_veneer\+0x4>
- .*:   000081ec        .word   0x000081ec
-.* <__lib_func2_veneer>:
- .*:   e51ff004        ldr     pc, \[pc, #-4\] ; .* <__lib_func2_veneer\+0x4>
- .*:   000081e0        .word   0x000081e0
+.* <__lib_func(1|2)_veneer>:
+ .*:   e51ff004        ldr     pc, \[pc, #-4\] ; .* <__lib_func(1|2)_veneer\+0x4>
+ .*:   000081e(c|0)    .word   0x000081e(c|0)
+.* <__lib_func(2|1)_veneer>:
+ .*:   e51ff004        ldr     pc, \[pc, #-4\] ; .* <__lib_func(2|1)_veneer\+0x4>
+ .*:   000081e(0|c)    .word   0x000081e(0|c)
 
 Disassembly of section .far_thumb:
 
index fa52ad119a3f5679b222c9dcbb594314d1490b3b..83b15a0f99adf5a42f2f7d125138b14ca157e458 100644 (file)
@@ -87,24 +87,24 @@ Disassembly of section .text:
        ...
 
 .* <__real_lib_func3>:
- .*:   f000 f80e       bl      2000390 <__app_func_from_thumb>
- .*:   f000 f804       bl      2000380 <__app_func_weak_from_thumb>
+ .*:   f000 f80(e|6)   bl      .* <__app_func_from_thumb>
+ .*:   f000 f80(4|c)   bl      .* <__app_func_weak_from_thumb>
  .*:   4770            bx      lr
 #...
 
-.* <__app_func_weak_from_thumb>:
+.* <__app_func(_weak)?_from_thumb>:
  .*:   4778            bx      pc
  .*:   46c0            nop                     ; \(mov r8, r8\)
- .*:   e59fc000        ldr     ip, \[pc\]      ; 200038c <__app_func_weak_from_thumb\+0xc>
+ .*:   e59fc000        ldr     ip, \[pc\]      ; 200038c <__app_func(_weak)?_from_thumb\+0xc>
  .*:   e08cf00f        add     pc, ip, pc
- .*:   fdffff28        .word   0xfdffff28
+ .*:   fdffff(2|1)8    .word   0xfdffff(2|1)8
 
-.* <__app_func_from_thumb>:
+.* <__app_func(_weak)?_from_thumb>:
  .*:   4778            bx      pc
  .*:   46c0            nop                     ; \(mov r8, r8\)
- .*:   e59fc000        ldr     ip, \[pc\]      ; 200039c <__app_func_from_thumb\+0xc>
+ .*:   e59fc000        ldr     ip, \[pc\]      ; 200039c <__app_func(_weak)?_from_thumb\+0xc>
  .*:   e08cf00f        add     pc, ip, pc
- .*:   fdffff08        .word   0xfdffff08
+ .*:   fdffff(0|1)8    .word   0xfdffff(0|1)8
 
 .* <lib_func3>:
  .*:   e59fc004        ldr     ip, \[pc, #4\]  ; 20003ac <lib_func3\+0xc>
index ad7352b119acaeb9b49d9ecc5fe319a789db3b4a..d256477bb90cc53a0710216fbcbd8c848cddbdfe 100644 (file)
@@ -72,18 +72,18 @@ Disassembly of section .text:
        ...
 
 .* <lib_func3>:
- .*:   f000 e80c       blx     200037c <__app_func_from_thumb>
- .*:   f000 e804       blx     2000370 <__app_func_weak_from_thumb>
+ .*:   f000 e80(c|6)   blx     .* <__app_func_from_thumb>
+ .*:   f000 e80(4|a)   blx     .* <__app_func_weak_from_thumb>
  .*:   4770            bx      lr
 #...
 
-.* <__app_func_weak_from_thumb>:
- .*:   e59fc000        ldr     ip, \[pc\]      ; 2000378 <__app_func_weak_from_thumb\+0x8>
+.* <__app_func(_weak)?_from_thumb>:
+ .*:   e59fc000        ldr     ip, \[pc\]      ; 2000378 <__app_func(_weak)?_from_thumb\+0x8>
  .*:   e08ff00c        add     pc, pc, ip
- .*:   fdffff34        .word   0xfdffff34
+ .*:   fdffff(34|28)   .word   0xfdffff(34|28)
 
-.* <__app_func_from_thumb>:
- .*:   e59fc000        ldr     ip, \[pc\]      ; 2000384 <__app_func_from_thumb\+0x8>
+.* <__app_func(_weak)?_from_thumb>:
+ .*:   e59fc000        ldr     ip, \[pc\]      ; 2000384 <__app_func(_weak)?_from_thumb\+0x8>
  .*:   e08ff00c        add     pc, pc, ip
- .*:   fdffff1c        .word   0xfdffff1c
+ .*:   fdffff(1c|28)   .word   0xfdffff(1c|28)
        ...
index f93ad467b5467353ce8f9a2d47833bb2b414fdf1..9b1fbeb9a83227fc1254761b64740cd02f764a27 100644 (file)
@@ -127,6 +127,20 @@ if { [check_shared_lib_support] } then {
            {symbolic-func.s} {{readelf {-r --wide} symbolic-func.r}}
            "symbolic-func.so"}
     }
+    # xfail on tic6x due to non-PIC/non-PID warnings
+    setup_xfail "tic6x-*-*"
+    run_ld_link_tests {
+       {"Build pr20995.so"
+           "-shared" "" ""
+           {pr20995b.s} {} "pr20995.so"}
+    }
+    # These targets don't copy dynamic variables into .bss.
+    setup_xfail "alpha-*-*" "bfin-*-*" "ia64-*-*" "xtensa-*-*"
+    run_ld_link_tests {
+       {"pr20995"
+           "" "tmpdir/pr20995.so" ""
+           {pr20995a.s} {{readelf {-S --wide} pr20995.r}} "pr20995"}
+    }
 }
 
 set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
diff --git a/ld/testsuite/ld-elf/pr20995.r b/ld/testsuite/ld-elf/pr20995.r
new file mode 100644 (file)
index 0000000..7336de6
--- /dev/null
@@ -0,0 +1,5 @@
+#...
+.* \.data\.rel\.ro +PROGBITS +[^ ]+ [^ ]+ [^ ]*[1-9a-f]0* .*
+#...
+.* \.bss +NOBITS +[^ ]+ [^ ]+ [^ ]*[1-9a-f]0* .*
+#...
diff --git a/ld/testsuite/ld-elf/pr20995a.s b/ld/testsuite/ld-elf/pr20995a.s
new file mode 100644 (file)
index 0000000..8da589c
--- /dev/null
@@ -0,0 +1,11 @@
+       .text
+       .global start
+start:
+       .global _start
+_start:
+       .global __start
+__start:
+       .global main
+main:
+       .dc.a rw
+       .dc.a ro
diff --git a/ld/testsuite/ld-elf/pr20995b.s b/ld/testsuite/ld-elf/pr20995b.s
new file mode 100644 (file)
index 0000000..7ff76ee
--- /dev/null
@@ -0,0 +1,13 @@
+       .data
+       .type rw,%object
+       .globl rw
+rw:
+       .dc.a 0
+       .size rw, . - rw
+
+       .text
+       .type ro,%object
+       .globl ro
+ro:
+       .dc.a 0
+       .size ro, . - ro