Here is one implementation of ELF sharable section proposal:

http://groups-beta.google.com/group/generic-abi/browse_thread/thread/bca08f6560f61b0d

Several people have expressed interests. I post it here for comments.
I used OS specific values. If we get consensus, I can change those
values to generic range.


H.J.
bfd/

2007-01-04  H.J. Lu  <[EMAIL PROTECTED]>

        * elf-bfd.h (_bfd_elf_sharable_com_section): New.
        (_bfd_elf_add_sharable_symbol): Likewise.
        (_bfd_elf_sharable_section_from_bfd_section): Likewise.
        (_bfd_elf_sharable_symbol_processing): Likewise.
        (_bfd_elf_sharable_common_definition): Likewise.
        (_bfd_elf_sharable_common_section_index): Likewise.
        (_bfd_elf_sharable_common_section): Likewise.
        (_bfd_elf_sharable_merge_symbol): Likewise.

        * elf.c (special_sections_g): Add ".gnu.linkonce.shrb" and
        ".gnu.linkonce.shrd".
        (special_sections_s): Add ".sharable_bss" and ".sharable_data".
        (get_program_header_size): Handle PT_GNU_SHR segment.
        (_bfd_elf_map_sections_to_segments): Likewise.
        (assign_file_positions_for_load_sections): Likewise.

        * elf32-i386.c (elf_i386_link_hash_table): Add sdynsharablebss
        and srelsharablebss fields.
        (elf_i386_link_hash_table_create): Initialize sdynsharablebss
        and srelsharablebss.
        (elf_i386_create_dynamic_sections): Handle sdynsharablebss and
        srelsharablebss.
        (elf_i386_adjust_dynamic_symbol): Likewise.
        (elf_i386_size_dynamic_sections): Likewise.
        (elf_i386_finish_dynamic_symbol): Likewise.
        (elf_backend_add_symbol_hook): Defined.
        (elf_backend_section_from_bfd_section): Likewise.
        (elf_backend_symbol_processing): Likewise.
        (elf_backend_common_section_index): Likewise.
        (elf_backend_common_section): Likewise.
        (elf_backend_common_definition): Likewise.
        (elf_backend_merge_symbol): Likewise.

        * elf64-x86-64.c (elf64_x86_64_link_hash_table): Add
        sdynsharablebss and srelsharablebss fields.
        (elf64_x86_64_link_hash_table_create): Initialize sdynsharablebss
        and srelsharablebss.
        (elf64_x86_64_create_dynamic_sections): Handle sdynsharablebss
        and srelsharablebss.
        (elf64_x86_64_adjust_dynamic_symbol): Likewise.
        (elf64_x86_64_size_dynamic_sections): Likewise.
        (elf64_x86_64_finish_dynamic_symbol): Likewise.
        (elf64_x86_64_add_symbol_hook): Handle sharable symbols.
        (elf64_x86_64_elf_section_from_bfd_section): Likewise.
        (elf64_x86_64_symbol_processing): Likewise.
        (elf64_x86_64_merge_symbol): Likewise.
        (elf64_x86_64_common_definition): Handle sharable sections.
        (elf64_x86_64_common_section_index): Likewise.
        (elf64_x86_64_common_section): Likewise.

        * elflink.c (_bfd_elf_create_dynamic_sections): Handle
        .dynsharablebss section.
        (_bfd_elf_sharable_com_section): New.
        (get_sharable_common_section): Likewise.
        (_bfd_elf_add_sharable_symbol): Likewise.
        (_bfd_elf_sharable_section_from_bfd_section): Likewise.
        (_bfd_elf_sharable_symbol_processing): Likewise.
        (_bfd_elf_sharable_common_definition): Likewise.
        (_bfd_elf_sharable_common_section_index): Likewise.
        (_bfd_elf_sharable_common_section): Likewise.
        (_bfd_elf_sharable_merge_symbol): Likewise.

        * elfxx-ia64.c (elfNN_ia64_add_symbol_hook): Handle sharable
        symbols.
        (elf_backend_add_symbol_hook): Defined.
        (elf_backend_section_from_bfd_section): Likewise.
        (elf_backend_symbol_processing): Likewise.
        (elf_backend_common_section_index): Likewise.
        (elf_backend_common_section): Likewise.
        (elf_backend_common_definition): Likewise.
        (elf_backend_merge_symbol): Likewise.

binutils/

2007-01-04  H.J. Lu  <[EMAIL PROTECTED]>

        * readelf.c (dump_relocations): Handle sharable sections.
        (get_segment_type): Handle sharable segment.
        (get_symbol_index_type): Handle sharable sections.

gas/

2007-01-04  H.J. Lu  <[EMAIL PROTECTED]>

        * config/obj-elf.c (obj_elf_sharable_common): New.
        (elf_pseudo_table): Add "sharable_common".
        (obj_elf_change_section): Handle sharable sections.

include/elf/

2007-01-04  H.J. Lu  <[EMAIL PROTECTED]>

        * common.h (PT_GNU_SHR): New.
        (SHF_GNU_SHARABLE): Likewise.
        (SHN_GNU_SHARABLE_COMMON): Likewise.

ld/

2007-01-04  H.J. Lu  <[EMAIL PROTECTED]>

        * emulparams/elf64_ia64.sh (SHARABLE_SECTIONS): Set to yes.
        * emulparams/elf_i386.sh (SHARABLE_SECTIONS): Likewise.
        * emulparams/elf_x86_64.sh (SHARABLE_SECTIONS): Likewise.

        * emultempl/elf32.em: Include "elf-bfd.h".
        (gld${EMULATION_NAME}_place_orphan): Don't allow orphaned
        sharable sections.

        * scripttempl/elf.sc: Support sharable sections.

--- binutils/bfd/elf-bfd.h.shr  2007-01-04 12:24:45.000000000 -0800
+++ binutils/bfd/elf-bfd.h      2007-01-04 12:24:45.000000000 -0800
@@ -1828,6 +1828,28 @@ extern bfd_boolean bfd_elf_link_add_symb
   (bfd *, struct bfd_link_info *);
 extern bfd_boolean _bfd_elf_add_dynamic_entry
   (struct bfd_link_info *, bfd_vma, bfd_vma);
+extern asection _bfd_elf_sharable_com_section;
+extern bfd_boolean _bfd_elf_add_sharable_symbol
+  (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
+   flagword *, asection **, bfd_vma *);
+extern bfd_boolean _bfd_elf_sharable_section_from_bfd_section
+  (bfd *, asection *, int *);
+extern void _bfd_elf_sharable_symbol_processing
+  (bfd *, asymbol *);
+extern bfd_boolean _bfd_elf_sharable_common_definition
+  (Elf_Internal_Sym *);
+extern unsigned int _bfd_elf_sharable_common_section_index
+  (asection *);
+extern asection *_bfd_elf_sharable_common_section
+  (asection *);
+extern bfd_boolean _bfd_elf_sharable_merge_symbol
+  (struct bfd_link_info *, struct elf_link_hash_entry **,
+   struct elf_link_hash_entry *, Elf_Internal_Sym *, asection **,
+   bfd_vma *, unsigned int *, bfd_boolean *, bfd_boolean *,
+   bfd_boolean *, bfd_boolean *, bfd_boolean *, bfd_boolean *,
+   bfd_boolean *, bfd_boolean *, bfd *, asection **,
+   bfd_boolean *, bfd_boolean *, bfd_boolean *, bfd_boolean *,
+   bfd *, asection **);
 
 extern bfd_boolean bfd_elf_link_record_dynamic_symbol
   (struct bfd_link_info *, struct elf_link_hash_entry *);
--- binutils/bfd/elf.c.shr      2007-01-04 12:24:45.000000000 -0800
+++ binutils/bfd/elf.c  2007-01-04 12:24:45.000000000 -0800
@@ -2329,6 +2329,8 @@ static const struct bfd_elf_special_sect
   { STRING_COMMA_LEN (".gnu.liblist"),     0, SHT_GNU_LIBLIST, SHF_ALLOC },
   { STRING_COMMA_LEN (".gnu.conflict"),    0, SHT_RELA,        SHF_ALLOC },
   { STRING_COMMA_LEN (".gnu.hash"),        0, SHT_GNU_HASH,    SHF_ALLOC },
+  { STRING_COMMA_LEN (".gnu.linkonce.shrb"), -2, SHT_NOBITS, SHF_ALLOC + 
SHF_WRITE + SHF_GNU_SHARABLE},
+  { STRING_COMMA_LEN (".gnu.linkonce.shrd"), -2, SHT_PROGBITS, SHF_ALLOC + 
SHF_WRITE + SHF_GNU_SHARABLE},
   { NULL,                        0,        0, 0,               0 }
 };
 
@@ -2383,6 +2385,8 @@ static const struct bfd_elf_special_sect
   /* See struct bfd_elf_special_section declaration for the semantics of
      this special case where .prefix_length != strlen (.prefix).  */
   { ".stabstr",                        5,  3, SHT_STRTAB, 0 },
+  { STRING_COMMA_LEN (".sharable_bss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE 
+ SHF_GNU_SHARABLE},
+  { STRING_COMMA_LEN (".sharable_data"), -2, SHT_PROGBITS, SHF_ALLOC + 
SHF_WRITE + SHF_GNU_SHARABLE},
   { NULL,                       0,  0, 0,          0 }
 };
 
@@ -3671,6 +3675,32 @@ get_program_header_size (bfd *abfd, stru
        }
     }
 
+  /* Check to see if we need a PT_GNU_SHR segment for sharable data
+     sections.  */
+  for (s = abfd->sections; s != NULL; s = s->next)
+    {
+      if ((elf_section_flags (s) & SHF_GNU_SHARABLE) != 0
+         && elf_section_type (s) == SHT_PROGBITS)
+       {
+         /* We need a PT_GNU_SHR segment.  */
+         ++segs;
+         break;
+       }
+    }
+
+  /* Check to see if we need a PT_GNU_SHR segment for sharable bss
+     sections.  */
+  for (s = abfd->sections; s != NULL; s = s->next)
+    {
+      if ((elf_section_flags (s) & SHF_GNU_SHARABLE) != 0
+         && elf_section_type (s) == SHT_NOBITS)
+       {
+         /* We need a PT_GNU_SHR segment.  */
+         ++segs;
+         break;
+       }
+    }
+
   /* Let the backend count up any program headers it might need.  */
   bed = get_elf_backend_data (abfd);
   if (bed->elf_backend_additional_program_headers)
@@ -3811,6 +3841,8 @@ _bfd_elf_map_sections_to_segments (bfd *
       bfd_boolean phdr_in_segment = TRUE;
       bfd_boolean writable;
       int tls_count = 0;
+      int sharable_data_count = 0, sharable_bss_count = 0;
+      asection *first_sharable_data = NULL, *first_sharable_bss = NULL;
       asection *first_tls = NULL;
       asection *dynsec, *eh_frame_hdr;
       bfd_size_type amt;
@@ -4056,6 +4088,22 @@ _bfd_elf_map_sections_to_segments (bfd *
                first_tls = s;
              tls_count++;
            }
+         if (elf_section_flags (s) & SHF_GNU_SHARABLE)
+           {
+             if (elf_section_type (s) == SHT_PROGBITS)
+               {
+                 if (! sharable_data_count)
+                   first_sharable_data = s;
+                 sharable_data_count++;
+               }
+             else
+               {
+                 BFD_ASSERT (elf_section_type (s) == SHT_NOBITS);
+                 if (! sharable_bss_count)
+                   first_sharable_bss = s;
+                 sharable_bss_count++;
+               }
+           }
        }
 
       /* If there are any SHF_TLS output sections, add PT_TLS segment.  */
@@ -4085,6 +4133,60 @@ _bfd_elf_map_sections_to_segments (bfd *
          pm = &m->next;
        }
 
+      /* If there are any output SHF_GNU_SHARABLE data sections, add a
+        PT_GNU_SHR segment.  */
+      if (sharable_data_count > 0)
+       {
+         int i;
+
+         amt = sizeof (struct elf_segment_map);
+         amt += (sharable_data_count - 1) * sizeof (asection *);
+         m = bfd_zalloc (abfd, amt);
+         if (m == NULL)
+           goto error_return;
+         m->next = NULL;
+         m->p_type = PT_GNU_SHR;
+         m->count = sharable_data_count;
+         /* Mandated PF_R.  */
+         m->p_flags = PF_R;
+         m->p_flags_valid = 1;
+         for (i = 0; i < sharable_data_count; ++i)
+           {
+             m->sections[i] = first_sharable_data;
+             first_sharable_data = first_sharable_data->next;
+           }
+
+         *pm = m;
+          pm = &m->next;
+       }
+
+      /* If there are any output SHF_GNU_SHARABLE bss sections, add a
+        PT_GNU_SHR segment.  */
+      if (sharable_bss_count > 0)
+       {
+         int i;
+
+         amt = sizeof (struct elf_segment_map);
+         amt += (sharable_bss_count - 1) * sizeof (asection *);
+         m = bfd_zalloc (abfd, amt);
+         if (m == NULL)
+           goto error_return;
+         m->next = NULL;
+         m->p_type = PT_GNU_SHR;
+         m->count = sharable_bss_count;
+         /* Mandated PF_R.  */
+         m->p_flags = PF_R;
+         m->p_flags_valid = 1;
+         for (i = 0; i < sharable_bss_count; ++i)
+           {
+             m->sections[i] = first_sharable_bss;
+             first_sharable_bss = first_sharable_bss->next;
+           }
+
+         *pm = m;
+          pm = &m->next;
+       }
+
       /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME
         segment.  */
       eh_frame_hdr = elf_tdata (abfd)->eh_frame_hdr;
@@ -4505,6 +4607,7 @@ assign_file_positions_for_load_sections 
          align = (bfd_size_type) 1 << bfd_get_section_alignment (abfd, sec);
 
          if (p->p_type == PT_LOAD
+             || p->p_type == PT_GNU_SHR
              || p->p_type == PT_TLS)
            {
              bfd_signed_vma adjust;
--- binutils/bfd/elf32-i386.c.shr       2007-01-04 12:24:45.000000000 -0800
+++ binutils/bfd/elf32-i386.c   2007-01-04 12:24:45.000000000 -0800
@@ -646,6 +646,8 @@ struct elf_i386_link_hash_table
   asection *srelplt;
   asection *sdynbss;
   asection *srelbss;
+  asection *sdynsharablebss;
+  asection *srelsharablebss;
 
   /* The (unloaded but important) .rel.plt.unloaded section on VxWorks.  */
   asection *srelplt2;
@@ -738,6 +740,8 @@ elf_i386_link_hash_table_create (bfd *ab
   ret->srelplt = NULL;
   ret->sdynbss = NULL;
   ret->srelbss = NULL;
+  ret->sdynsharablebss = NULL;
+  ret->srelsharablebss = NULL;
   ret->tls_ldm_got.refcount = 0;
   ret->next_tls_desc_index = 0;
   ret->sgotplt_jump_table_size = 0;
@@ -798,10 +802,19 @@ elf_i386_create_dynamic_sections (bfd *d
   htab->srelplt = bfd_get_section_by_name (dynobj, ".rel.plt");
   htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
   if (!info->shared)
-    htab->srelbss = bfd_get_section_by_name (dynobj, ".rel.bss");
+    {
+      htab->srelbss = bfd_get_section_by_name (dynobj, ".rel.bss");
+      htab->sdynsharablebss
+       = bfd_get_section_by_name (dynobj, ".dynsharablebss");
+      htab->srelsharablebss
+       = bfd_get_section_by_name (dynobj, ".rel.sharable_bss");
+    }
 
   if (!htab->splt || !htab->srelplt || !htab->sdynbss
-      || (!info->shared && !htab->srelbss))
+      || (!info->shared
+         && (!htab->srelbss
+             || !htab->sdynsharablebss
+             || !htab->srelsharablebss)))
     abort ();
 
   if (htab->is_vxworks
@@ -1516,12 +1529,20 @@ elf_i386_adjust_dynamic_symbol (struct b
      both the dynamic object and the regular object will refer to the
      same memory location for the variable.  */
 
+  s = htab->sdynbss;
+
   /* 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_ALLOC) != 0)
     {
-      htab->srelbss->size += sizeof (Elf32_External_Rel);
+      if (elf_section_flags (h->root.u.def.section) & SHF_GNU_SHARABLE)
+       {
+         htab->srelsharablebss->size += sizeof (Elf32_External_Rel);
+         s = htab->sdynsharablebss;
+       }
+      else
+       htab->srelbss->size += sizeof (Elf32_External_Rel);
       h->needs_copy = 1;
     }
 
@@ -1532,7 +1553,6 @@ elf_i386_adjust_dynamic_symbol (struct b
     power_of_two = 3;
 
   /* Apply the required alignment.  */
-  s = htab->sdynbss;
   s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
   if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
     {
@@ -2000,7 +2020,8 @@ elf_i386_size_dynamic_sections (bfd *out
       if (s == htab->splt
          || s == htab->sgot
          || s == htab->sgotplt
-         || s == htab->sdynbss)
+         || s == htab->sdynbss
+         || s == htab->sdynsharablebss)
        {
          /* Strip this section if we don't need it; see the
             comment below.  */
@@ -3571,21 +3592,27 @@ elf_i386_finish_dynamic_symbol (bfd *out
     {
       Elf_Internal_Rela rel;
       bfd_byte *loc;
+      asection *s;
+
+      if (h->root.u.def.section == htab->sdynsharablebss)
+       s = htab->srelsharablebss;
+      else
+       s = htab->srelbss;
 
       /* 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->srelbss == NULL)
+         || s == 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);
-      loc = htab->srelbss->contents;
-      loc += htab->srelbss->reloc_count++ * sizeof (Elf32_External_Rel);
+      loc = s->contents;
+      loc += s->reloc_count++ * sizeof (Elf32_External_Rel);
       bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
     }
 
@@ -3872,6 +3899,21 @@ elf_i386_hash_symbol (struct elf_link_ha
 #define elf_backend_plt_sym_val                      elf_i386_plt_sym_val
 #define elf_backend_hash_symbol                      elf_i386_hash_symbol
 
+#define elf_backend_add_symbol_hook \
+  _bfd_elf_add_sharable_symbol
+#define elf_backend_section_from_bfd_section \
+  _bfd_elf_sharable_section_from_bfd_section
+#define elf_backend_symbol_processing \
+  _bfd_elf_sharable_symbol_processing
+#define elf_backend_common_section_index \
+  _bfd_elf_sharable_common_section_index
+#define elf_backend_common_section \
+  _bfd_elf_sharable_common_section
+#define elf_backend_common_definition \
+  _bfd_elf_sharable_common_definition
+#define elf_backend_merge_symbol \
+  _bfd_elf_sharable_merge_symbol
+
 #include "elf32-target.h"
 
 /* FreeBSD support.  */
--- binutils/bfd/elf64-x86-64.c.shr     2007-01-04 12:24:45.000000000 -0800
+++ binutils/bfd/elf64-x86-64.c 2007-01-04 12:24:45.000000000 -0800
@@ -452,6 +452,8 @@ struct elf64_x86_64_link_hash_table
   asection *srelplt;
   asection *sdynbss;
   asection *srelbss;
+  asection *sdynsharablebss;
+  asection *srelsharablebss;
 
   /* The offset into splt of the PLT entry for the TLS descriptor
      resolver.  Special values are 0, if not necessary (or not found
@@ -539,6 +541,8 @@ elf64_x86_64_link_hash_table_create (bfd
   ret->srelplt = NULL;
   ret->sdynbss = NULL;
   ret->srelbss = NULL;
+  ret->sdynsharablebss = NULL;
+  ret->srelsharablebss = NULL;
   ret->sym_sec.abfd = NULL;
   ret->tlsdesc_plt = 0;
   ret->tlsdesc_got = 0;
@@ -597,10 +601,19 @@ elf64_x86_64_create_dynamic_sections (bf
   htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
   htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
   if (!info->shared)
-    htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss");
+    {
+      htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss");
+      htab->sdynsharablebss
+       = bfd_get_section_by_name (dynobj, ".dynsharablebss");
+      htab->srelsharablebss
+       = bfd_get_section_by_name (dynobj, ".rela.sharable_bss");
+    }
 
   if (!htab->splt || !htab->srelplt || !htab->sdynbss
-      || (!info->shared && !htab->srelbss))
+      || (!info->shared
+         && (!htab->srelbss
+             || !htab->sdynsharablebss
+             || !htab->srelsharablebss)))
     abort ();
 
   return TRUE;
@@ -1379,12 +1392,20 @@ elf64_x86_64_adjust_dynamic_symbol (stru
 
   htab = elf64_x86_64_hash_table (info);
 
+  s = htab->sdynbss;
+
   /* 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_ALLOC) != 0)
     {
-      htab->srelbss->size += sizeof (Elf64_External_Rela);
+      if (elf_section_flags (h->root.u.def.section) & SHF_GNU_SHARABLE)
+       {
+         htab->srelsharablebss->size += sizeof (Elf64_External_Rela);
+         s = htab->sdynsharablebss;
+       }
+      else
+       htab->srelbss->size += sizeof (Elf64_External_Rela);
       h->needs_copy = 1;
     }
 
@@ -1398,7 +1419,6 @@ elf64_x86_64_adjust_dynamic_symbol (stru
     power_of_two = 4;
 
   /* Apply the required alignment.  */
-  s = htab->sdynbss;
   s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
   if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
     {
@@ -1860,7 +1880,8 @@ elf64_x86_64_size_dynamic_sections (bfd 
       if (s == htab->splt
          || s == htab->sgot
          || s == htab->sgotplt
-         || s == htab->sdynbss)
+         || s == htab->sdynbss
+         || s == htab->sdynsharablebss)
        {
          /* Strip this section if we don't need it; see the
             comment below.  */
@@ -3196,13 +3217,19 @@ elf64_x86_64_finish_dynamic_symbol (bfd 
     {
       Elf_Internal_Rela rela;
       bfd_byte *loc;
+      asection *s;
+
+      if (h->root.u.def.section == htab->sdynsharablebss)
+       s = htab->srelsharablebss;
+      else
+       s = htab->srelbss;
 
       /* 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->srelbss == NULL)
+         || s == NULL)
        abort ();
 
       rela.r_offset = (h->root.u.def.value
@@ -3210,8 +3237,8 @@ elf64_x86_64_finish_dynamic_symbol (bfd 
                       + h->root.u.def.section->output_offset);
       rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_COPY);
       rela.r_addend = 0;
-      loc = htab->srelbss->contents;
-      loc += htab->srelbss->reloc_count++ * sizeof (Elf64_External_Rela);
+      loc = s->contents;
+      loc += s->reloc_count++ * sizeof (Elf64_External_Rela);
       bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
     }
 
@@ -3475,9 +3502,12 @@ elf64_x86_64_add_symbol_hook (bfd *abfd,
        }
       *secp = lcomm;
       *valp = sym->st_size;
+      return TRUE;
       break;
     }
-  return TRUE;
+
+  return _bfd_elf_add_sharable_symbol (abfd, info, sym, namep, flagsp,
+                                      secp, valp);
 }
 
 
@@ -3493,7 +3523,7 @@ elf64_x86_64_elf_section_from_bfd_sectio
       *index = SHN_X86_64_LCOMMON;
       return TRUE;
     }
-  return FALSE;
+  return _bfd_elf_sharable_section_from_bfd_section (abfd, sec, index);
 }
 
 /* Process a symbol.  */
@@ -3511,22 +3541,26 @@ elf64_x86_64_symbol_processing (bfd *abf
       asym->value = elfsym->internal_elf_sym.st_size;
       /* Common symbol doesn't set BSF_GLOBAL.  */
       asym->flags &= ~BSF_GLOBAL;
+      return;
       break;
     }
+  
+  _bfd_elf_sharable_symbol_processing (abfd, asym);
 }
 
 static bfd_boolean
 elf64_x86_64_common_definition (Elf_Internal_Sym *sym)
 {
   return (sym->st_shndx == SHN_COMMON
-         || sym->st_shndx == SHN_X86_64_LCOMMON);
+         || sym->st_shndx == SHN_X86_64_LCOMMON
+         || _bfd_elf_sharable_common_definition (sym));
 }
 
 static unsigned int
 elf64_x86_64_common_section_index (asection *sec)
 {
   if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
-    return SHN_COMMON;
+    return _bfd_elf_sharable_common_section_index (sec);
   else
     return SHN_X86_64_LCOMMON;
 }
@@ -3535,7 +3569,7 @@ static asection *
 elf64_x86_64_common_section (asection *sec)
 {
   if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
-    return bfd_com_section_ptr;
+    return _bfd_elf_sharable_common_section (sec);
   else
     return &_bfd_elf_large_com_section;
 }
@@ -3572,7 +3606,8 @@ elf64_x86_64_merge_symbol (struct bfd_li
       && h->root.type == bfd_link_hash_common
       && !*newdyn
       && bfd_is_com_section (*sec)
-      && *oldsec != *sec)
+      && *oldsec != *sec
+      && _bfd_elf_sharable_common_section_index (*oldsec) == SHN_COMMON)
     {
       if (sym->st_shndx == SHN_COMMON
          && (elf_section_flags (*oldsec) & SHF_X86_64_LARGE) != 0)
@@ -3580,13 +3615,26 @@ elf64_x86_64_merge_symbol (struct bfd_li
          h->root.u.c.p->section
            = bfd_make_section_old_way (oldbfd, "COMMON");
          h->root.u.c.p->section->flags = SEC_ALLOC;
+         return TRUE;
        }
       else if (sym->st_shndx == SHN_X86_64_LCOMMON
               && (elf_section_flags (*oldsec) & SHF_X86_64_LARGE) == 0)
-       *psec = *sec = bfd_com_section_ptr; 
+       {
+         *psec = *sec = bfd_com_section_ptr; 
+         return TRUE;
+       }
     }
 
-  return TRUE;
+  return _bfd_elf_sharable_merge_symbol (info, sym_hash, h, sym,
+                                        psec, pvalue, pold_alignment,
+                                        skip, override,
+                                        type_change_ok, size_change_ok,
+                                        newdyn, newdef,
+                                        newdyncommon, newweak,
+                                        abfd, sec,
+                                        olddyn, olddef,
+                                        olddyncommon, oldweak,
+                                        oldbfd, oldsec);
 }
 
 static int
--- binutils/bfd/elflink.c.shr  2007-01-04 12:24:45.000000000 -0800
+++ binutils/bfd/elflink.c      2007-01-04 12:24:45.000000000 -0800
@@ -352,6 +352,22 @@ _bfd_elf_create_dynamic_sections (bfd *a
          if (s == NULL
              || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
            return FALSE;
+
+         s = bfd_make_section (abfd, ".dynsharablebss");
+         if (s == NULL
+             || ! bfd_set_section_flags (abfd, s,
+                                         (SEC_ALLOC
+                                          | SEC_LINKER_CREATED)))
+           return FALSE;
+
+         s = bfd_make_section (abfd,
+                               (bed->default_use_rela_p
+                                ? ".rela.sharable_bss"
+                                : ".rel.sharable_bss"));
+         if (s == NULL
+             || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
+             || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
+           return FALSE;
        }
     }
 
@@ -10581,3 +10597,219 @@ _bfd_elf_common_section (asection *sec A
 {
   return bfd_com_section_ptr;
 }
+
+asection _bfd_elf_sharable_com_section
+  = BFD_FAKE_SECTION (_bfd_elf_sharable_com_section, SEC_IS_COMMON,
+                     NULL, "SHARABLE_COMMON", 0);
+ 
+static asection *
+get_sharable_common_section (bfd *abfd)
+{
+  asection *scomm = bfd_get_section_by_name (abfd, "SHARABLE_COMMON");
+
+  if (scomm == NULL)
+    {
+      scomm = bfd_make_section_with_flags (abfd,
+                                          "SHARABLE_COMMON",
+                                          (SEC_ALLOC
+                                           | SEC_IS_COMMON
+                                           | SEC_LINKER_CREATED));
+      if (scomm == NULL)
+       return scomm;
+      elf_section_flags (scomm) |= SHF_GNU_SHARABLE;
+    }
+
+  return scomm;
+}
+
+bfd_boolean
+_bfd_elf_add_sharable_symbol (bfd *abfd ATTRIBUTE_UNUSED,
+                             struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                             Elf_Internal_Sym *sym,
+                             const char **namep ATTRIBUTE_UNUSED,
+                             flagword *flagsp ATTRIBUTE_UNUSED,
+                             asection **secp,
+                             bfd_vma *valp)
+{
+  asection *scomm;
+
+  switch (sym->st_shndx)
+    {
+    case SHN_GNU_SHARABLE_COMMON:
+      scomm = get_sharable_common_section (abfd);
+      if (scomm == NULL)
+       return FALSE;
+      *secp = scomm;
+      *valp = sym->st_size;
+      break;
+    }
+  return TRUE;
+}
+
+bfd_boolean
+_bfd_elf_sharable_section_from_bfd_section
+  (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, int *index)
+{
+  if (sec == &_bfd_elf_sharable_com_section)
+    {
+      *index = SHN_GNU_SHARABLE_COMMON;
+      return TRUE;
+    }
+  return FALSE;
+}
+
+void
+_bfd_elf_sharable_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
+                                    asymbol *asym)
+{
+  elf_symbol_type *elfsym = (elf_symbol_type *) asym;
+
+  switch (elfsym->internal_elf_sym.st_shndx)
+    {
+    case SHN_GNU_SHARABLE_COMMON:
+      asym->section = &_bfd_elf_sharable_com_section;
+      asym->value = elfsym->internal_elf_sym.st_size;
+      asym->flags &= ~BSF_GLOBAL;
+      break;
+    }
+}
+
+bfd_boolean
+_bfd_elf_sharable_common_definition (Elf_Internal_Sym *sym)
+{
+  return (sym->st_shndx == SHN_COMMON
+         || sym->st_shndx == SHN_GNU_SHARABLE_COMMON);
+}
+
+unsigned int
+_bfd_elf_sharable_common_section_index (asection *sec)
+{
+  if ((elf_section_flags (sec) & SHF_GNU_SHARABLE) == 0)
+    return SHN_COMMON;
+  else
+    return SHN_GNU_SHARABLE_COMMON;
+}
+
+asection *
+_bfd_elf_sharable_common_section (asection *sec)
+{
+  if ((elf_section_flags (sec) & SHF_GNU_SHARABLE) == 0)
+    return bfd_com_section_ptr;
+  else
+    return &_bfd_elf_sharable_com_section;
+}
+
+bfd_boolean
+_bfd_elf_sharable_merge_symbol
+  (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+   struct elf_link_hash_entry **sym_hash ATTRIBUTE_UNUSED,
+   struct elf_link_hash_entry *h,
+   Elf_Internal_Sym *sym ATTRIBUTE_UNUSED,
+   asection **psec,
+   bfd_vma *pvalue ATTRIBUTE_UNUSED,
+   unsigned int *pold_alignment ATTRIBUTE_UNUSED,
+   bfd_boolean *skip ATTRIBUTE_UNUSED,
+   bfd_boolean *override ATTRIBUTE_UNUSED,
+   bfd_boolean *type_change_ok ATTRIBUTE_UNUSED,
+   bfd_boolean *size_change_ok ATTRIBUTE_UNUSED,
+   bfd_boolean *newdef ATTRIBUTE_UNUSED,
+   bfd_boolean *newdyn,
+   bfd_boolean *newdyncommon ATTRIBUTE_UNUSED,
+   bfd_boolean *newweak ATTRIBUTE_UNUSED,
+   bfd *abfd,
+   asection **sec,
+   bfd_boolean *olddef ATTRIBUTE_UNUSED,
+   bfd_boolean *olddyn,
+   bfd_boolean *olddyncommon ATTRIBUTE_UNUSED,
+   bfd_boolean *oldweak ATTRIBUTE_UNUSED,
+   bfd *oldbfd,
+   asection **oldsec)
+{
+  /* Check sharable symbol.  If one is undefined, it is OK.  */
+  if (*oldsec && !bfd_is_und_section (*sec))
+    {
+      bfd_boolean sharable, oldsharable;
+     
+      sharable = (elf_section_data (*sec)
+                 && (elf_section_flags (*sec) & SHF_GNU_SHARABLE));
+      oldsharable = (elf_section_data (*oldsec)
+                    && (elf_section_flags (*oldsec)
+                        & SHF_GNU_SHARABLE));
+
+      if (sharable != oldsharable)
+       {
+         bfd *nsbfd, *sbfd;
+         asection *nssec, *ssec;
+         bfd_boolean nsdyn, sdyn, nsdef, sdef;
+
+         if (oldsharable)
+           {
+             sbfd = oldbfd;
+             nsbfd = abfd;
+             ssec = *oldsec;
+             nssec = *sec;
+             sdyn = *olddyn;
+             nsdyn = *newdyn;
+             sdef = *olddef;
+             nsdef = *newdef;
+           }
+         else
+           {
+             sbfd = abfd;
+             nsbfd = oldbfd;
+             ssec = *sec;
+             nssec = *oldsec;
+             sdyn = *newdyn;
+             nsdyn = *olddyn;
+             sdef = *newdef;
+             nsdef = *olddef;
+           }
+
+         if (sdef && !sdyn)
+           {
+             /* If the sharable definition comes from a relocatable
+                file, it will override the non-sharable one in DSO. */
+             return TRUE;
+           }
+         else if (!nsdef
+                  && !nsdyn
+                  && (h->root.type == bfd_link_hash_common
+                      || bfd_is_com_section (nssec)))
+           {
+             asection *scomm;
+
+             /* When the non-sharable common symbol in a relocatable
+                file, we can turn it into sharable.  If the sharable
+                symbol isn't common, the non-sharable common symbol
+                will be overidden.  We only need to handle the
+                sharable common symbol and the non-sharable common
+                symbol.  We just turn the non-sharable common symbol
+                into the sharable one. */
+             if (sym->st_shndx == SHN_GNU_SHARABLE_COMMON)
+               {
+                 scomm = get_sharable_common_section (oldbfd);
+                 if (scomm == NULL)
+                   return FALSE;
+                 h->root.u.c.p->section = scomm;
+               }
+             else
+               {
+                 scomm = get_sharable_common_section (abfd);
+                 if (scomm == NULL)
+                   return FALSE;
+                 *psec = *sec = scomm;
+               }
+
+             return TRUE;
+           }
+
+         (*_bfd_error_handler)
+           (_("%s: sharable symbol in %B section %A mismatches non-shrable 
symbol in %B section %A"),
+            sbfd, ssec, nsbfd, nssec, h->root.root.string);
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
+    }
+
+  return TRUE;
+}
--- binutils/bfd/elfxx-ia64.c.shr       2007-01-04 12:24:45.000000000 -0800
+++ binutils/bfd/elfxx-ia64.c   2007-01-04 12:24:45.000000000 -0800
@@ -1620,7 +1620,8 @@ elfNN_ia64_add_symbol_hook (abfd, info, 
       *valp = sym->st_size;
     }
 
-  return TRUE;
+  return _bfd_elf_add_sharable_symbol (abfd, info, sym, namep, flagsp,
+                                      secp, valp);
 }
 
 /* Return the number of additional phdrs we will need.  */
@@ -5802,6 +5803,19 @@ elfNN_hpux_backend_symbol_processing (bf
 #define elf_backend_rela_normal                1
 #define elf_backend_special_sections   elfNN_ia64_special_sections
 
+#define elf_backend_section_from_bfd_section \
+  _bfd_elf_sharable_section_from_bfd_section
+#define elf_backend_symbol_processing \
+  _bfd_elf_sharable_symbol_processing
+#define elf_backend_common_section_index \
+  _bfd_elf_sharable_common_section_index
+#define elf_backend_common_section \
+  _bfd_elf_sharable_common_section
+#define elf_backend_common_definition \
+  _bfd_elf_sharable_common_definition
+#define elf_backend_merge_symbol \
+  _bfd_elf_sharable_merge_symbol
+
 /* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
    SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
    We don't want to flood users with so many error messages. We turn
--- binutils/binutils/readelf.c.shr     2006-12-27 07:30:41.000000000 -0800
+++ binutils/binutils/readelf.c 2007-01-04 12:24:45.000000000 -0800
@@ -1238,6 +1238,8 @@ dump_relocations (FILE *file,
                        sec_name = "ABS";
                      else if (psym->st_shndx == SHN_COMMON)
                        sec_name = "COMMON";
+                     else if (psym->st_shndx == SHN_GNU_SHARABLE_COMMON)
+                       sec_name = "GNU_SHARABLE_COMMON";
                      else if (elf_header.e_machine == EM_MIPS
                               && psym->st_shndx == SHN_MIPS_SCOMMON)
                        sec_name = "SCOMMON";
@@ -2436,6 +2438,7 @@ get_segment_type (unsigned long p_type)
     case PT_SHLIB:     return "SHLIB";
     case PT_PHDR:      return "PHDR";
     case PT_TLS:       return "TLS";
+    case PT_GNU_SHR:   return "GNU_SHR";
 
     case PT_GNU_EH_FRAME:
                        return "GNU_EH_FRAME";
@@ -6935,6 +6938,8 @@ get_symbol_index_type (unsigned int type
     case SHN_UNDEF:    return "UND";
     case SHN_ABS:      return "ABS";
     case SHN_COMMON:   return "COM";
+    case SHN_GNU_SHARABLE_COMMON:
+                       return "GNU_SHARABLE_COM";
     default:
       if (type == SHN_IA_64_ANSI_COMMON
          && elf_header.e_machine == EM_IA_64
--- binutils/gas/config/obj-elf.c.shr   2006-12-05 11:27:59.000000000 -0800
+++ binutils/gas/config/obj-elf.c       2007-01-04 12:24:45.000000000 -0800
@@ -68,6 +68,7 @@ static void obj_elf_symver (int);
 static void obj_elf_subsection (int);
 static void obj_elf_popsection (int);
 static void obj_elf_tls_common (int);
+static void obj_elf_sharable_common (int);
 static void obj_elf_lcomm (int);
 static void obj_elf_struct (int);
 
@@ -125,6 +126,8 @@ static const pseudo_typeS elf_pseudo_tab
 
   {"tls_common", obj_elf_tls_common, 0},
 
+  {"sharable_common", obj_elf_sharable_common, 0},
+
   /* End sentinel.  */
   {NULL, NULL, 0},
 };
@@ -369,6 +372,39 @@ obj_elf_tls_common (int ignore ATTRIBUTE
 }
 
 static void
+obj_elf_sharable_common (int ignore ATTRIBUTE_UNUSED)
+{
+  static segT sharable_bss_section;
+  asection *saved_com_section_ptr = elf_com_section_ptr;
+  asection *saved_bss_section = bss_section;
+
+  if (sharable_bss_section == NULL)
+    {
+      flagword applicable;
+      segT seg = now_seg;
+      subsegT subseg = now_subseg;
+
+      /* The .sharable_bss section is for local .sharable_common
+        symbols.  */
+      sharable_bss_section = subseg_new (".sharable_bss", 0);
+      applicable = bfd_applicable_section_flags (stdoutput);
+      bfd_set_section_flags (stdoutput, sharable_bss_section,
+                            applicable & SEC_ALLOC);
+      seg_info (sharable_bss_section)->bss = 1;
+
+      subseg_set (seg, subseg);
+    }
+
+  elf_com_section_ptr = &_bfd_elf_sharable_com_section;
+  bss_section = sharable_bss_section;
+
+  s_comm_internal (0, elf_common_parse);
+
+  elf_com_section_ptr = saved_com_section_ptr;
+  bss_section = saved_bss_section;
+}
+
+static void
 obj_elf_lcomm (int ignore ATTRIBUTE_UNUSED)
 {
   symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
@@ -582,11 +618,17 @@ obj_elf_change_section (const char *name
 
                 .section .lbss,"aw",@progbits
 
+                "@progbits" is incorrect.  Also for sharable bss
+                sections, gcc, as of 2005-07-06, will emit
+
+                .section .sharable_bss,"aw",@progbits
+
                 "@progbits" is incorrect.  */
 #ifdef TC_I386
              && (bed->s->arch_size != 64
                  || !(ssect->attr & SHF_X86_64_LARGE))
 #endif
+             && !(ssect->attr & SHF_GNU_SHARABLE)
              && ssect->type != SHT_INIT_ARRAY
              && ssect->type != SHT_FINI_ARRAY
              && ssect->type != SHT_PREINIT_ARRAY)
--- binutils/include/elf/common.h.shr   2006-10-24 23:49:18.000000000 -0700
+++ binutils/include/elf/common.h       2007-01-04 12:25:50.000000000 -0800
@@ -306,6 +306,7 @@
 #define PT_SUNW_EH_FRAME PT_GNU_EH_FRAME      /* Solaris uses the same value */
 #define PT_GNU_STACK   (PT_LOOS + 0x474e551) /* Stack flags */
 #define PT_GNU_RELRO   (PT_LOOS + 0x474e552) /* Read-only after relocation */
+#define PT_GNU_SHR     (PT_LOOS + 0x474e554) /* Sharable segment */
 
 /* Program segment permissions, in program header p_flags field.  */
 
@@ -377,6 +378,8 @@
 #define SHF_MASKOS     0x0FF00000      /* New value, Oct 4, 1999 Draft */
 #define SHF_MASKPROC   0xF0000000      /* Processor-specific semantics */
 
+#define SHF_GNU_SHARABLE 0x01000000    /* sharable section */
+
 /* Values of note segment descriptor types for core files.  */
 
 #define NT_PRSTATUS    1               /* Contains copy of prstatus struct */
@@ -495,6 +498,9 @@
 #define SHN_HIRESERVE  0xFFFF          /* End range of reserved indices */
 #define SHN_BAD                ((unsigned) -1) /* Used internally by bfd */
 
+/* Associated symbol is in common sharable */
+#define SHN_GNU_SHARABLE_COMMON (SHN_LOOS + 10)
+
 /* The following constants control how a symbol may be accessed once it has
    become part of an executable or shared library.  */
 
--- binutils/ld/emulparams/elf64_ia64.sh.shr    2006-05-30 09:45:32.000000000 
-0700
+++ binutils/ld/emulparams/elf64_ia64.sh        2007-01-04 12:24:45.000000000 
-0800
@@ -37,3 +37,4 @@ OTHER_READONLY_SECTIONS="${OTHER_READONL
 # .dtors.  They have to be next to .sbss/.sbss2/.sdata/.sdata2.
 SMALL_DATA_CTOR=" "
 SMALL_DATA_DTOR=" "
+SHARABLE_SECTIONS=yes
--- binutils/ld/emulparams/elf_i386.sh.shr      2006-05-30 09:45:32.000000000 
-0700
+++ binutils/ld/emulparams/elf_i386.sh  2007-01-04 12:24:45.000000000 -0800
@@ -12,3 +12,4 @@ GENERATE_SHLIB_SCRIPT=yes
 GENERATE_PIE_SCRIPT=yes
 NO_SMALL_DATA=yes
 SEPARATE_GOTPLT=12
+SHARABLE_SECTIONS=yes
--- binutils/ld/emulparams/elf_x86_64.sh.shr    2006-10-18 09:24:01.000000000 
-0700
+++ binutils/ld/emulparams/elf_x86_64.sh        2007-01-04 12:24:45.000000000 
-0800
@@ -14,6 +14,7 @@ GENERATE_PIE_SCRIPT=yes
 NO_SMALL_DATA=yes
 LARGE_SECTIONS=yes
 SEPARATE_GOTPLT=24
+SHARABLE_SECTIONS=yes
 
 if [ "x${host}" = "x${target}" ]; then
   case " $EMULATION_LIBPATH " in
--- binutils/ld/emultempl/elf32.em.shr  2006-12-05 11:28:02.000000000 -0800
+++ binutils/ld/emultempl/elf32.em      2007-01-04 12:24:45.000000000 -0800
@@ -55,6 +55,8 @@ Foundation, Inc., 51 Franklin Street - F
 #include "elf/common.h"
 #include "elf-bfd.h"
 
+#include "elf-bfd.h"
+
 /* Declare functions used by various EXTRA_EM_FILEs.  */
 static void gld${EMULATION_NAME}_before_parse (void);
 static void gld${EMULATION_NAME}_after_open (void);
@@ -1456,6 +1458,12 @@ gld${EMULATION_NAME}_place_orphan (asect
 
   secname = bfd_get_section_name (s->owner, s);
 
+  /* Orphaned sharable sections won't have correct page
+     requirements.  */
+  if (elf_section_flags (s) & SHF_GNU_SHARABLE)
+    einfo ("%F%P: unable to place orphaned sharable section %A (%B)\n",
+          s, s->owner);
+
   if (! link_info.relocatable
       && link_info.combreloc
       && (s->flags & SEC_ALLOC))
--- binutils/ld/scripttempl/elf.sc.shr  2006-10-25 17:31:59.000000000 -0700
+++ binutils/ld/scripttempl/elf.sc      2007-01-04 12:24:45.000000000 -0800
@@ -236,6 +236,40 @@ STACK="  .stack        ${RELOCATING-0}${
     ${RELOCATING+_stack = .;}
     *(.stack)
   }"
+test "${SHARABLE_SECTIONS}" = "yes" && OTHER_READWRITE_SECTIONS="
+  ${OTHER_READWRITE_SECTIONS}
+  /* Sharable data sections.  */
+  .sharable_data ${RELOCATING-0} : ${RELOCATING+ALIGN(${MAXPAGESIZE})}
+  {
+    ${RELOCATING+PROVIDE_HIDDEN (__sharable_data_start = .);}
+    *(.sharable_data${RELOCATING+ .sharable_data.* .gnu.linkonce.shrd.*})
+    /* Align here to ensure that the sharable data section ends at the
+       page boundary.  */
+    ${RELOCATING+. = ALIGN(. != 0 ? ${MAXPAGESIZE} : 1);}
+    ${RELOCATING+PROVIDE_HIDDEN (__sharable_data_end = .);}
+  }
+"
+test "${SHARABLE_SECTIONS}" = "yes" && OTHER_BSS_SECTIONS="
+  ${OTHER_BSS_SECTIONS}
+  /* Sharable bss sections  */
+  .sharable_bss ${RELOCATING-0} : ${RELOCATING+ALIGN(${MAXPAGESIZE})}
+  {
+    ${RELOCATING+PROVIDE_HIDDEN (__sharable_bss_start = .);}
+    *(.dynsharablebss)
+    *(.sharable_bss${RELOCATING+ .sharable_bss.* .gnu.linkonce.shrb.*}) 
+    *(SHARABLE_COMMON)
+    /* Align here to ensure that the sharable bss section ends at the
+       page boundary.  */
+    ${RELOCATING+. = ALIGN(. != 0 ? ${MAXPAGESIZE} : 1);}
+    ${RELOCATING+PROVIDE_HIDDEN (__sharable_bss_end = .);}
+  }
+"
+test "${SHARABLE_SECTIONS}" = "yes" && REL_SHARABLE="
+  .rel.sharable_data   ${RELOCATING-0} : { *(.rel.sharable_data${RELOCATING+ 
.rel.sharable_data.* .rel.gnu.linkonce.shrd.*}) }
+  .rela.sharable_data  ${RELOCATING-0} : { *(.rela.sharable_data${RELOCATING+ 
.rela.sharable_data.* .rela.gnu.linkonce.shrd.*}) }
+  .rel.sharable_bss    ${RELOCATING-0} : { *(.rel.sharable_bss${RELOCATING+ 
.rel.sharable_bss.* .rel.gnu.linkonce.shrb.*}) }
+  .rela.sharable_bss   ${RELOCATING-0} : { *(.rela.sharable_bss${RELOCATING+ 
.rela.sharable_bss.* .rela.gnu.linkonce.shrb.*}) }
+"
 
 # if this is for an embedded system, don't add SIZEOF_HEADERS.
 if [ -z "$EMBEDDED" ]; then
@@ -305,6 +339,7 @@ eval $COMBRELOCCAT <<EOF
   .rel.got      ${RELOCATING-0} : { *(.rel.got) }
   .rela.got     ${RELOCATING-0} : { *(.rela.got) }
   ${OTHER_GOT_RELOC_SECTIONS}
+  ${REL_SHARABLE}
   ${REL_SDATA}
   ${REL_SBSS}
   ${REL_SDATA2}

Reply via email to