• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Revisionbd20f1ced5c064bd633e3d8c8b9a73b5c71e1c7f (tree)
Time2013-11-07 02:09:32
AuthorH.J. Lu <hjl.tools@gmai...>
CommiterH.J. Lu

Log Message

Add binutils-sharable.patch

Change Summary

Incremental Difference

--- /dev/null
+++ b/patches/README
@@ -0,0 +1,32 @@
1+#! /bin/sh
2+
3+# If you don't use rpm, you can use this file to apply additional Linux
4+# patches. At the top level of the binutils source tree, do
5+#
6+# /bin/sh patches/README
7+#
8+# You may have to do
9+#
10+# cd bfd
11+# make headers
12+#
13+# if the build fails.
14+
15+dir=`dirname $0`
16+clean=$1
17+
18+patches="
19+ binutils-sharable.patch
20+"
21+
22+for p in $patches
23+do
24+ if [ ! -n "$clean" ]
25+ then
26+ suffix=$(echo $p | sed -e "s/.*-\([^-]\+\).patch/\1/")
27+ backup="-b --suffix .$suffix"
28+ fi
29+ patch -E -p1 $backup < $dir/$p || exit 1
30+done
31+find -name "*.orig" | xargs rm -fv
32+find -name "*.gmo" | xargs rm -fv
--- /dev/null
+++ b/patches/binutils-sharable.patch
@@ -0,0 +1,1285 @@
1+From d982080fe4d81ee0a863a0258b317377260a3a8f Mon Sep 17 00:00:00 2001
2+From: "H.J. Lu" <hjl.tools@gmail.com>
3+Date: Mon, 4 Nov 2013 09:44:13 -0800
4+Subject: [PATCH] Add PT_GNU_SHR/SHF_GNU_SHARABLE/SHN_GNU_SHARABLE_COMMON
5+ support to gas/ld
6+
7+PT_GNU_SHR/SHF_GNU_SHARABLE/SHN_GNU_SHARABLE_COMMON are used to group
8+data into a PT_GNU_SHR to improve performance on NUMA system.
9+---
10+ ChangeLog.sharable | 140 ++++++++++++++++++++++++++
11+ bfd/elf-bfd.h | 21 +++-
12+ bfd/elf.c | 103 +++++++++++++++++++
13+ bfd/elf32-i386.c | 55 ++++++++--
14+ bfd/elf64-x86-64.c | 73 +++++++++++---
15+ bfd/elflink.c | 228 +++++++++++++++++++++++++++++++++++++++++-
16+ bfd/elfnn-ia64.c | 16 ++-
17+ binutils/readelf.c | 5 +
18+ gas/config/obj-elf.c | 42 ++++++++
19+ include/bfdlink.h | 3 +
20+ include/elf/common.h | 6 ++
21+ ld/emulparams/elf32_x86_64.sh | 1 +
22+ ld/emulparams/elf64_ia64.sh | 1 +
23+ ld/emulparams/elf_i386.sh | 1 +
24+ ld/emulparams/elf_x86_64.sh | 1 +
25+ ld/emultempl/elf32.em | 7 ++
26+ ld/ldmain.c | 1 +
27+ ld/scripttempl/elf.sc | 35 +++++++
28+ 18 files changed, 712 insertions(+), 27 deletions(-)
29+ create mode 100644 ChangeLog.sharable
30+
31+diff --git a/ChangeLog.sharable b/ChangeLog.sharable
32+new file mode 100644
33+index 0000000..3ccf957
34+--- /dev/null
35++++ b/ChangeLog.sharable
36+@@ -0,0 +1,140 @@
37++bfd/
38++
39++2013-04-05 H.J. Lu <hongjiu.lu@intel.com>
40++
41++ * elf-bfd.h (struct elf_backend_data <merge_symbol>): Add abfd,
42++ newdyn and olddyn. Remove const from oldsec.
43++ (_bfd_elf_sharable_merge_symbol): Updated.
44++ * elf64-x86-64.c (elf_x86_64_merge_symbol): Likewise.
45++ * elflink.c (_bfd_elf_merge_symbol): Update bed->merge_symbol
46++ call.
47++
48++2009-12-12 H.J. Lu <hongjiu.lu@intel.com>
49++
50++ * elf.c: Fix shadowed variable warnings.
51++ * elf64-x86-64.c: Likewise.
52++ * elflink.c: Likewise.
53++
54++2007-01-23 H.J. Lu <hongjiu.lu@intel.com>
55++
56++ * elf-bfd.h (_bfd_elf_sharable_com_section): New.
57++ (_bfd_elf_add_sharable_symbol): Likewise.
58++ (_bfd_elf_sharable_section_from_bfd_section): Likewise.
59++ (_bfd_elf_sharable_symbol_processing): Likewise.
60++ (_bfd_elf_sharable_common_definition): Likewise.
61++ (_bfd_elf_sharable_common_section_index): Likewise.
62++ (_bfd_elf_sharable_common_section): Likewise.
63++ (_bfd_elf_sharable_merge_symbol): Likewise.
64++
65++ * elf.c (special_sections_g): Add ".gnu.linkonce.shrb" and
66++ ".gnu.linkonce.shrd".
67++ (special_sections_s): Add ".sharable_bss" and ".sharable_data".
68++ (get_program_header_size): Handle PT_GNU_SHR segment.
69++ (_bfd_elf_map_sections_to_segments): Likewise.
70++ (assign_file_positions_for_load_sections): Likewise.
71++
72++ * elf32-i386.c (elf_i386_link_hash_table): Add sdynsharablebss
73++ and srelsharablebss fields.
74++ (elf_i386_link_hash_table_create): Initialize sdynsharablebss
75++ and srelsharablebss.
76++ (elf_i386_create_dynamic_sections): Handle sdynsharablebss and
77++ srelsharablebss.
78++ (elf_i386_adjust_dynamic_symbol): Likewise.
79++ (elf_i386_size_dynamic_sections): Likewise.
80++ (elf_i386_finish_dynamic_symbol): Likewise.
81++ (elf_backend_add_symbol_hook): Defined.
82++ (elf_backend_section_from_bfd_section): Likewise.
83++ (elf_backend_symbol_processing): Likewise.
84++ (elf_backend_common_section_index): Likewise.
85++ (elf_backend_common_section): Likewise.
86++ (elf_backend_common_definition): Likewise.
87++ (elf_backend_merge_symbol): Likewise.
88++
89++ * elf64-x86-64.c (elf64_x86_64_link_hash_table): Add
90++ sdynsharablebss and srelsharablebss fields.
91++ (elf64_x86_64_link_hash_table_create): Initialize sdynsharablebss
92++ and srelsharablebss.
93++ (elf64_x86_64_create_dynamic_sections): Handle sdynsharablebss
94++ and srelsharablebss.
95++ (elf64_x86_64_adjust_dynamic_symbol): Likewise.
96++ (elf64_x86_64_size_dynamic_sections): Likewise.
97++ (elf64_x86_64_finish_dynamic_symbol): Likewise.
98++ (elf64_x86_64_add_symbol_hook): Handle sharable symbols.
99++ (elf64_x86_64_elf_section_from_bfd_section): Likewise.
100++ (elf64_x86_64_symbol_processing): Likewise.
101++ (elf64_x86_64_merge_symbol): Likewise.
102++ (elf64_x86_64_common_definition): Handle sharable sections.
103++ (elf64_x86_64_common_section_index): Likewise.
104++ (elf64_x86_64_common_section): Likewise.
105++
106++ * elflink.c (_bfd_elf_create_dynamic_sections): Handle
107++ .dynsharablebss section.
108++ (_bfd_elf_sharable_com_section): New.
109++ (get_sharable_common_section): Likewise.
110++ (_bfd_elf_add_sharable_symbol): Likewise.
111++ (_bfd_elf_sharable_section_from_bfd_section): Likewise.
112++ (_bfd_elf_sharable_symbol_processing): Likewise.
113++ (_bfd_elf_sharable_common_definition): Likewise.
114++ (_bfd_elf_sharable_common_section_index): Likewise.
115++ (_bfd_elf_sharable_common_section): Likewise.
116++ (_bfd_elf_sharable_merge_symbol): Likewise.
117++
118++ * elfnn-ia64.c (elfNN_ia64_add_symbol_hook): Handle sharable
119++ symbols.
120++ (elf_backend_add_symbol_hook): Defined.
121++ (elf_backend_section_from_bfd_section): Likewise.
122++ (elf_backend_symbol_processing): Likewise.
123++ (elf_backend_common_section_index): Likewise.
124++ (elf_backend_common_section): Likewise.
125++ (elf_backend_common_definition): Likewise.
126++ (elf_backend_merge_symbol): Likewise.
127++
128++binutils/
129++
130++2007-01-04 H.J. Lu <hongjiu.lu@intel.com>
131++
132++ * readelf.c (dump_relocations): Handle sharable sections.
133++ (get_segment_type): Handle sharable segment.
134++ (get_symbol_index_type): Handle sharable sections.
135++
136++gas/
137++
138++2007-01-04 H.J. Lu <hongjiu.lu@intel.com>
139++
140++ * config/obj-elf.c (obj_elf_sharable_common): New.
141++ (elf_pseudo_table): Add "sharable_common".
142++ (obj_elf_change_section): Handle sharable sections.
143++
144++include/
145++
146++2007-01-23 H.J. Lu <hongjiu.lu@intel.com>
147++
148++ * bfdlink.h (bfd_link_info): Add sharable_sections.
149++
150++include/elf/
151++
152++2007-01-04 H.J. Lu <hongjiu.lu@intel.com>
153++
154++ * common.h (PT_GNU_SHR): New.
155++ (SHF_GNU_SHARABLE): Likewise.
156++ (SHN_GNU_SHARABLE_COMMON): Likewise.
157++
158++ld/
159++
160++2011-01-08 H.J. Lu <hongjiu.lu@intel.com>
161++
162++ * emulparams/elf32_x86_64.sh (SHARABLE_SECTIONS): Set to yes.
163++
164++2007-01-04 H.J. Lu <hongjiu.lu@intel.com>
165++
166++ * emulparams/elf64_ia64.sh (SHARABLE_SECTIONS): Set to yes.
167++ * emulparams/elf_i386.sh (SHARABLE_SECTIONS): Likewise.
168++ * emulparams/elf_x86_64.sh (SHARABLE_SECTIONS): Likewise.
169++
170++ * emultempl/elf32.em (gld${EMULATION_NAME}_before_parse): Set
171++ link_info.sharable_sections based on $SHARABLE_SECTIONS.
172++ (gld${EMULATION_NAME}_place_orphan): Don't allow orphaned
173++ sharable sections.
174++
175++ * ldmain.c (main): Initialize link_info.sharable_sections.
176++ * scripttempl/elf.sc: Support sharable sections.
177+diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
178+index add80b3..525d4b9 100644
179+--- a/bfd/elf-bfd.h
180++++ b/bfd/elf-bfd.h
181+@@ -1210,8 +1210,9 @@ struct elf_backend_data
182+ /* Return TRUE if we can merge 2 definitions. */
183+ bfd_boolean (*merge_symbol) (struct elf_link_hash_entry *,
184+ const Elf_Internal_Sym *, asection **,
185++ bfd_boolean, bfd_boolean, bfd *,
186+ bfd_boolean, bfd_boolean,
187+- bfd *, const asection *);
188++ bfd *, asection *);
189+
190+ /* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */
191+ bfd_boolean (*elf_hash_symbol) (struct elf_link_hash_entry *);
192+@@ -2148,6 +2149,24 @@ extern bfd_boolean bfd_elf_link_add_symbols
193+ (bfd *, struct bfd_link_info *);
194+ extern bfd_boolean _bfd_elf_add_dynamic_entry
195+ (struct bfd_link_info *, bfd_vma, bfd_vma);
196++extern asection _bfd_elf_sharable_com_section;
197++extern bfd_boolean _bfd_elf_add_sharable_symbol
198++ (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
199++ flagword *, asection **, bfd_vma *);
200++extern bfd_boolean _bfd_elf_sharable_section_from_bfd_section
201++ (bfd *, asection *, int *);
202++extern void _bfd_elf_sharable_symbol_processing
203++ (bfd *, asymbol *);
204++extern bfd_boolean _bfd_elf_sharable_common_definition
205++ (Elf_Internal_Sym *);
206++extern unsigned int _bfd_elf_sharable_common_section_index
207++ (asection *);
208++extern asection *_bfd_elf_sharable_common_section
209++ (asection *);
210++extern bfd_boolean _bfd_elf_sharable_merge_symbol
211++ (struct elf_link_hash_entry *, const Elf_Internal_Sym *,
212++ asection **, bfd_boolean, bfd_boolean, bfd *,
213++ bfd_boolean, bfd_boolean, bfd *, asection *);
214+
215+ extern bfd_boolean bfd_elf_link_record_dynamic_symbol
216+ (struct bfd_link_info *, struct elf_link_hash_entry *);
217+diff --git a/bfd/elf.c b/bfd/elf.c
218+index 8df38ee..88c182e 100644
219+--- a/bfd/elf.c
220++++ b/bfd/elf.c
221+@@ -2102,6 +2102,8 @@ static const struct bfd_elf_special_section special_sections_g[] =
222+ { STRING_COMMA_LEN (".gnu.liblist"), 0, SHT_GNU_LIBLIST, SHF_ALLOC },
223+ { STRING_COMMA_LEN (".gnu.conflict"), 0, SHT_RELA, SHF_ALLOC },
224+ { STRING_COMMA_LEN (".gnu.hash"), 0, SHT_GNU_HASH, SHF_ALLOC },
225++ { STRING_COMMA_LEN (".gnu.linkonce.shrb"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_GNU_SHARABLE},
226++ { STRING_COMMA_LEN (".gnu.linkonce.shrd"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_GNU_SHARABLE},
227+ { NULL, 0, 0, 0, 0 }
228+ };
229+
230+@@ -2156,6 +2158,8 @@ static const struct bfd_elf_special_section special_sections_s[] =
231+ /* See struct bfd_elf_special_section declaration for the semantics of
232+ this special case where .prefix_length != strlen (.prefix). */
233+ { ".stabstr", 5, 3, SHT_STRTAB, 0 },
234++ { STRING_COMMA_LEN (".sharable_bss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_GNU_SHARABLE},
235++ { STRING_COMMA_LEN (".sharable_data"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_GNU_SHARABLE},
236+ { NULL, 0, 0, 0, 0 }
237+ };
238+
239+@@ -3615,6 +3619,32 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info)
240+ }
241+ }
242+
243++ /* Check to see if we need a PT_GNU_SHR segment for sharable data
244++ sections. */
245++ for (s = abfd->sections; s != NULL; s = s->next)
246++ {
247++ if ((elf_section_flags (s) & SHF_GNU_SHARABLE) != 0
248++ && elf_section_type (s) == SHT_PROGBITS)
249++ {
250++ /* We need a PT_GNU_SHR segment. */
251++ ++segs;
252++ break;
253++ }
254++ }
255++
256++ /* Check to see if we need a PT_GNU_SHR segment for sharable bss
257++ sections. */
258++ for (s = abfd->sections; s != NULL; s = s->next)
259++ {
260++ if ((elf_section_flags (s) & SHF_GNU_SHARABLE) != 0
261++ && elf_section_type (s) == SHT_NOBITS)
262++ {
263++ /* We need a PT_GNU_SHR segment. */
264++ ++segs;
265++ break;
266++ }
267++ }
268++
269+ /* Let the backend count up any program headers it might need. */
270+ bed = get_elf_backend_data (abfd);
271+ if (bed->elf_backend_additional_program_headers)
272+@@ -3785,6 +3815,8 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
273+ bfd_boolean phdr_in_segment = TRUE;
274+ bfd_boolean writable;
275+ int tls_count = 0;
276++ int sharable_data_count = 0, sharable_bss_count = 0;
277++ asection *first_sharable_data = NULL, *first_sharable_bss = NULL;
278+ asection *first_tls = NULL;
279+ asection *dynsec, *eh_frame_hdr;
280+ bfd_size_type amt;
281+@@ -4093,6 +4125,22 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
282+ first_tls = s;
283+ tls_count++;
284+ }
285++ if (elf_section_flags (s) & SHF_GNU_SHARABLE)
286++ {
287++ if (elf_section_type (s) == SHT_PROGBITS)
288++ {
289++ if (! sharable_data_count)
290++ first_sharable_data = s;
291++ sharable_data_count++;
292++ }
293++ else
294++ {
295++ BFD_ASSERT (elf_section_type (s) == SHT_NOBITS);
296++ if (! sharable_bss_count)
297++ first_sharable_bss = s;
298++ sharable_bss_count++;
299++ }
300++ }
301+ }
302+
303+ /* If there are any SHF_TLS output sections, add PT_TLS segment. */
304+@@ -4120,6 +4168,60 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
305+ pm = &m->next;
306+ }
307+
308++ /* If there are any output SHF_GNU_SHARABLE data sections, add a
309++ PT_GNU_SHR segment. */
310++ if (sharable_data_count > 0)
311++ {
312++ int j;
313++
314++ amt = sizeof (struct elf_segment_map);
315++ amt += (sharable_data_count - 1) * sizeof (asection *);
316++ m = bfd_zalloc (abfd, amt);
317++ if (m == NULL)
318++ goto error_return;
319++ m->next = NULL;
320++ m->p_type = PT_GNU_SHR;
321++ m->count = sharable_data_count;
322++ /* Mandated PF_R. */
323++ m->p_flags = PF_R;
324++ m->p_flags_valid = 1;
325++ for (j = 0; j < sharable_data_count; ++j)
326++ {
327++ m->sections[j] = first_sharable_data;
328++ first_sharable_data = first_sharable_data->next;
329++ }
330++
331++ *pm = m;
332++ pm = &m->next;
333++ }
334++
335++ /* If there are any output SHF_GNU_SHARABLE bss sections, add a
336++ PT_GNU_SHR segment. */
337++ if (sharable_bss_count > 0)
338++ {
339++ int j;
340++
341++ amt = sizeof (struct elf_segment_map);
342++ amt += (sharable_bss_count - 1) * sizeof (asection *);
343++ m = bfd_zalloc (abfd, amt);
344++ if (m == NULL)
345++ goto error_return;
346++ m->next = NULL;
347++ m->p_type = PT_GNU_SHR;
348++ m->count = sharable_bss_count;
349++ /* Mandated PF_R. */
350++ m->p_flags = PF_R;
351++ m->p_flags_valid = 1;
352++ for (j = 0; j < sharable_bss_count; ++j)
353++ {
354++ m->sections[j] = first_sharable_bss;
355++ first_sharable_bss = first_sharable_bss->next;
356++ }
357++
358++ *pm = m;
359++ pm = &m->next;
360++ }
361++
362+ /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME
363+ segment. */
364+ eh_frame_hdr = elf_eh_frame_hdr (abfd);
365+@@ -4661,6 +4763,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
366+ align = (bfd_size_type) 1 << bfd_get_section_alignment (abfd, sec);
367+
368+ if ((p->p_type == PT_LOAD
369++ || p->p_type == PT_GNU_SHR
370+ || p->p_type == PT_TLS)
371+ && (this_hdr->sh_type != SHT_NOBITS
372+ || ((this_hdr->sh_flags & SHF_ALLOC) != 0
373+diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
374+index 560e05c..bd5a1d2 100644
375+--- a/bfd/elf32-i386.c
376++++ b/bfd/elf32-i386.c
377+@@ -819,6 +819,9 @@ struct elf_i386_link_hash_table
378+
379+ /* The index of the next unused R_386_IRELATIVE slot in .rel.plt. */
380+ bfd_vma next_irelative_index;
381++
382++ asection *sdynsharablebss;
383++ asection *srelsharablebss;
384+ };
385+
386+ /* Get the i386 ELF linker hash table from a link_info structure. */
387+@@ -997,10 +1000,19 @@ elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
388+
389+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
390+ if (!info->shared)
391+- htab->srelbss = bfd_get_linker_section (dynobj, ".rel.bss");
392++ {
393++ htab->srelbss = bfd_get_linker_section (dynobj, ".rel.bss");
394++ htab->sdynsharablebss
395++ = bfd_get_linker_section (dynobj, ".dynsharablebss");
396++ htab->srelsharablebss
397++ = bfd_get_linker_section (dynobj, ".rel.sharable_bss");
398++ }
399+
400+ if (!htab->sdynbss
401+- || (!info->shared && !htab->srelbss))
402++ || (!info->shared
403++ && (!htab->srelbss
404++ || !htab->sdynsharablebss
405++ || !htab->srelsharablebss)))
406+ abort ();
407+
408+ if (get_elf_i386_backend_data (dynobj)->is_vxworks
409+@@ -2154,17 +2166,23 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
410+ both the dynamic object and the regular object will refer to the
411+ same memory location for the variable. */
412+
413++ s = htab->sdynbss;
414++
415+ /* We must generate a R_386_COPY reloc to tell the dynamic linker to
416+ copy the initial value out of the dynamic object and into the
417+ runtime process image. */
418+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
419+ {
420+- htab->srelbss->size += sizeof (Elf32_External_Rel);
421++ if (elf_section_flags (h->root.u.def.section) & SHF_GNU_SHARABLE)
422++ {
423++ htab->srelsharablebss->size += sizeof (Elf32_External_Rel);
424++ s = htab->sdynsharablebss;
425++ }
426++ else
427++ htab->srelbss->size += sizeof (Elf32_External_Rel);
428+ h->needs_copy = 1;
429+ }
430+
431+- s = htab->sdynbss;
432+-
433+ return _bfd_elf_adjust_dynamic_copy (h, s);
434+ }
435+
436+@@ -2886,6 +2904,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
437+ || s == htab->elf.iplt
438+ || s == htab->elf.igotplt
439+ || s == htab->plt_eh_frame
440++ || s == htab->sdynsharablebss
441+ || s == htab->sdynbss)
442+ {
443+ /* Strip these too. */
444+@@ -4682,20 +4701,26 @@ do_glob_dat:
445+ if (h->needs_copy)
446+ {
447+ Elf_Internal_Rela rel;
448++ asection *s;
449++
450++ if (h->root.u.def.section == htab->sdynsharablebss)
451++ s = htab->srelsharablebss;
452++ else
453++ s = htab->srelbss;
454+
455+ /* This symbol needs a copy reloc. Set it up. */
456+
457+ if (h->dynindx == -1
458+ || (h->root.type != bfd_link_hash_defined
459+ && h->root.type != bfd_link_hash_defweak)
460+- || htab->srelbss == NULL)
461++ || s == NULL)
462+ abort ();
463+
464+ rel.r_offset = (h->root.u.def.value
465+ + h->root.u.def.section->output_section->vma
466+ + h->root.u.def.section->output_offset);
467+ rel.r_info = ELF32_R_INFO (h->dynindx, R_386_COPY);
468+- elf_append_rel (output_bfd, htab->srelbss, &rel);
469++ elf_append_rel (output_bfd, s, &rel);
470+ }
471+
472+ return TRUE;
473+@@ -5016,7 +5041,8 @@ elf_i386_add_symbol_hook (bfd * abfd,
474+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE))
475+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
476+
477+- return TRUE;
478++ return _bfd_elf_add_sharable_symbol (abfd, info, sym, namep, flagsp,
479++ secp, valp);
480+ }
481+
482+ #define TARGET_LITTLE_SYM bfd_elf32_i386_vec
483+@@ -5070,6 +5096,19 @@ elf_i386_add_symbol_hook (bfd * abfd,
484+ #undef elf_backend_post_process_headers
485+ #define elf_backend_post_process_headers _bfd_elf_set_osabi
486+
487++#define elf_backend_section_from_bfd_section \
488++ _bfd_elf_sharable_section_from_bfd_section
489++#define elf_backend_symbol_processing \
490++ _bfd_elf_sharable_symbol_processing
491++#define elf_backend_common_section_index \
492++ _bfd_elf_sharable_common_section_index
493++#define elf_backend_common_section \
494++ _bfd_elf_sharable_common_section
495++#define elf_backend_common_definition \
496++ _bfd_elf_sharable_common_definition
497++#define elf_backend_merge_symbol \
498++ _bfd_elf_sharable_merge_symbol
499++
500+ #include "elf32-target.h"
501+
502+ /* FreeBSD support. */
503+diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
504+index f748641..bc5b578 100644
505+--- a/bfd/elf64-x86-64.c
506++++ b/bfd/elf64-x86-64.c
507+@@ -771,6 +771,9 @@ struct elf_x86_64_link_hash_table
508+ bfd_vma next_jump_slot_index;
509+ /* The index of the next R_X86_64_IRELATIVE entry in .rela.plt. */
510+ bfd_vma next_irelative_index;
511++
512++ asection *sdynsharablebss;
513++ asection *srelsharablebss;
514+ };
515+
516+ /* Get the x86-64 ELF linker hash table from a link_info structure. */
517+@@ -968,10 +971,19 @@ elf_x86_64_create_dynamic_sections (bfd *dynobj,
518+
519+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
520+ if (!info->shared)
521+- htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
522++ {
523++ htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
524++ htab->sdynsharablebss
525++ = bfd_get_linker_section (dynobj, ".dynsharablebss");
526++ htab->srelsharablebss
527++ = bfd_get_linker_section (dynobj, ".rela.sharable_bss");
528++ }
529+
530+ if (!htab->sdynbss
531+- || (!info->shared && !htab->srelbss))
532++ || (!info->shared
533++ && (!htab->srelbss
534++ || !htab->sdynsharablebss
535++ || !htab->srelsharablebss)))
536+ abort ();
537+
538+ if (!info->no_ld_generated_unwind_info
539+@@ -2248,6 +2260,8 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
540+ if (htab == NULL)
541+ return FALSE;
542+
543++ s = htab->sdynbss;
544++
545+ /* We must generate a R_X86_64_COPY reloc to tell the dynamic linker
546+ to copy the initial value out of the dynamic object and into the
547+ runtime process image. */
548+@@ -2255,12 +2269,16 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
549+ {
550+ const struct elf_backend_data *bed;
551+ bed = get_elf_backend_data (info->output_bfd);
552+- htab->srelbss->size += bed->s->sizeof_rela;
553++ if (elf_section_flags (h->root.u.def.section) & SHF_GNU_SHARABLE)
554++ {
555++ htab->srelsharablebss->size += bed->s->sizeof_rela;
556++ s = htab->sdynsharablebss;
557++ }
558++ else
559++ htab->srelbss->size += bed->s->sizeof_rela;
560+ h->needs_copy = 1;
561+ }
562+
563+- s = htab->sdynbss;
564+-
565+ return _bfd_elf_adjust_dynamic_copy (h, s);
566+ }
567+
568+@@ -2960,6 +2978,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
569+ || s == htab->elf.iplt
570+ || s == htab->elf.igotplt
571+ || s == htab->plt_eh_frame
572++ || s == htab->sdynsharablebss
573+ || s == htab->sdynbss)
574+ {
575+ /* Strip this section if we don't need it; see the
576+@@ -4720,13 +4739,19 @@ do_glob_dat:
577+ if (h->needs_copy)
578+ {
579+ Elf_Internal_Rela rela;
580++ asection *s;
581++
582++ if (h->root.u.def.section == htab->sdynsharablebss)
583++ s = htab->srelsharablebss;
584++ else
585++ s = htab->srelbss;
586+
587+ /* This symbol needs a copy reloc. Set it up. */
588+
589+ if (h->dynindx == -1
590+ || (h->root.type != bfd_link_hash_defined
591+ && h->root.type != bfd_link_hash_defweak)
592+- || htab->srelbss == NULL)
593++ || s == NULL)
594+ abort ();
595+
596+ rela.r_offset = (h->root.u.def.value
597+@@ -4734,7 +4759,7 @@ do_glob_dat:
598+ + h->root.u.def.section->output_offset);
599+ rela.r_info = htab->r_info (h->dynindx, R_X86_64_COPY);
600+ rela.r_addend = 0;
601+- elf_append_rela (output_bfd, htab->srelbss, &rela);
602++ elf_append_rela (output_bfd, s, &rela);
603+ }
604+
605+ return TRUE;
606+@@ -5069,7 +5094,8 @@ elf_x86_64_add_symbol_hook (bfd *abfd,
607+ || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE))
608+ elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
609+
610+- return TRUE;
611++ return _bfd_elf_add_sharable_symbol (abfd, info, sym, namep, flagsp,
612++ secp, valp);
613+ }
614+
615+
616+@@ -5085,7 +5111,8 @@ elf_x86_64_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
617+ *index_return = SHN_X86_64_LCOMMON;
618+ return TRUE;
619+ }
620+- return FALSE;
621++ return _bfd_elf_sharable_section_from_bfd_section (abfd, sec,
622++ index_return);
623+ }
624+
625+ /* Process a symbol. */
626+@@ -5103,22 +5130,26 @@ elf_x86_64_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
627+ asym->value = elfsym->internal_elf_sym.st_size;
628+ /* Common symbol doesn't set BSF_GLOBAL. */
629+ asym->flags &= ~BSF_GLOBAL;
630++ return;
631+ break;
632+ }
633++
634++ _bfd_elf_sharable_symbol_processing (abfd, asym);
635+ }
636+
637+ static bfd_boolean
638+ elf_x86_64_common_definition (Elf_Internal_Sym *sym)
639+ {
640+ return (sym->st_shndx == SHN_COMMON
641+- || sym->st_shndx == SHN_X86_64_LCOMMON);
642++ || sym->st_shndx == SHN_X86_64_LCOMMON
643++ || _bfd_elf_sharable_common_definition (sym));
644+ }
645+
646+ static unsigned int
647+ elf_x86_64_common_section_index (asection *sec)
648+ {
649+ if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
650+- return SHN_COMMON;
651++ return _bfd_elf_sharable_common_section_index (sec);
652+ else
653+ return SHN_X86_64_LCOMMON;
654+ }
655+@@ -5127,7 +5158,7 @@ static asection *
656+ elf_x86_64_common_section (asection *sec)
657+ {
658+ if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
659+- return bfd_com_section_ptr;
660++ return _bfd_elf_sharable_common_section (sec);
661+ else
662+ return &_bfd_elf_large_com_section;
663+ }
664+@@ -5137,9 +5168,12 @@ elf_x86_64_merge_symbol (struct elf_link_hash_entry *h,
665+ const Elf_Internal_Sym *sym,
666+ asection **psec,
667+ bfd_boolean newdef,
668++ bfd_boolean newdyn,
669++ bfd *abfd,
670+ bfd_boolean olddef,
671++ bfd_boolean olddyn,
672+ bfd *oldbfd,
673+- const asection *oldsec)
674++ asection *oldsec)
675+ {
676+ /* A normal common symbol and a large common symbol result in a
677+ normal common symbol. We turn the large common symbol into a
678+@@ -5148,7 +5182,8 @@ elf_x86_64_merge_symbol (struct elf_link_hash_entry *h,
679+ && h->root.type == bfd_link_hash_common
680+ && !newdef
681+ && bfd_is_com_section (*psec)
682+- && oldsec != *psec)
683++ && oldsec != *psec
684++ && _bfd_elf_sharable_common_section_index (oldsec) == SHN_COMMON)
685+ {
686+ if (sym->st_shndx == SHN_COMMON
687+ && (elf_section_flags (oldsec) & SHF_X86_64_LARGE) != 0)
688+@@ -5156,13 +5191,19 @@ elf_x86_64_merge_symbol (struct elf_link_hash_entry *h,
689+ h->root.u.c.p->section
690+ = bfd_make_section_old_way (oldbfd, "COMMON");
691+ h->root.u.c.p->section->flags = SEC_ALLOC;
692++ return TRUE;
693+ }
694+ else if (sym->st_shndx == SHN_X86_64_LCOMMON
695+ && (elf_section_flags (oldsec) & SHF_X86_64_LARGE) == 0)
696+- *psec = bfd_com_section_ptr;
697++ {
698++ *psec = bfd_com_section_ptr;
699++ return TRUE;
700++ }
701+ }
702+
703+- return TRUE;
704++ return _bfd_elf_sharable_merge_symbol (h, sym, psec, newdef, newdyn,
705++ abfd, olddef, olddyn, oldbfd,
706++ oldsec);
707+ }
708+
709+ static int
710+diff --git a/bfd/elflink.c b/bfd/elflink.c
711+index 1e6abd9..e187d91 100644
712+--- a/bfd/elflink.c
713++++ b/bfd/elflink.c
714+@@ -385,6 +385,27 @@ _bfd_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
715+ if (s == NULL
716+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
717+ return FALSE;
718++
719++ if (info->sharable_sections)
720++ {
721++ s = bfd_make_section (abfd, ".dynsharablebss");
722++ if (s == NULL
723++ || ! bfd_set_section_flags (abfd, s,
724++ (SEC_ALLOC
725++ | SEC_LINKER_CREATED)))
726++ return FALSE;
727++
728++ s = bfd_make_section (abfd,
729++ (bed->default_use_rela_p
730++ ? ".rela.sharable_bss"
731++ : ".rel.sharable_bss"));
732++ if (s == NULL
733++ || ! bfd_set_section_flags (abfd, s,
734++ flags | SEC_READONLY)
735++ || ! bfd_set_section_alignment (abfd, s,
736++ bed->s->log_file_align))
737++ return FALSE;
738++ }
739+ }
740+ }
741+
742+@@ -1347,7 +1368,8 @@ _bfd_elf_merge_symbol (bfd *abfd,
743+ backend to check if we can merge them. */
744+ if (bed->merge_symbol != NULL)
745+ {
746+- if (!bed->merge_symbol (h, sym, psec, newdef, olddef, oldbfd, oldsec))
747++ if (!bed->merge_symbol (h, sym, psec, newdef, newdyn, abfd,
748++ olddef, olddyn, oldbfd, oldsec))
749+ return FALSE;
750+ sec = *psec;
751+ }
752+@@ -13047,3 +13069,207 @@ elf_append_rel (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
753+ BFD_ASSERT (loc + bed->s->sizeof_rel <= s->contents + s->size);
754+ bed->s->swap_reloc_out (abfd, rel, loc);
755+ }
756++
757++asection _bfd_elf_sharable_com_section
758++ = BFD_FAKE_SECTION (_bfd_elf_sharable_com_section, SEC_IS_COMMON,
759++ NULL, "SHARABLE_COMMON", 0);
760++
761++static asection *
762++get_sharable_common_section (bfd *abfd)
763++{
764++ asection *scomm = bfd_get_section_by_name (abfd, "SHARABLE_COMMON");
765++
766++ if (scomm == NULL)
767++ {
768++ scomm = bfd_make_section_with_flags (abfd,
769++ "SHARABLE_COMMON",
770++ (SEC_ALLOC
771++ | SEC_IS_COMMON
772++ | SEC_LINKER_CREATED));
773++ if (scomm == NULL)
774++ return scomm;
775++ elf_section_flags (scomm) |= SHF_GNU_SHARABLE;
776++ }
777++
778++ return scomm;
779++}
780++
781++bfd_boolean
782++_bfd_elf_add_sharable_symbol (bfd *abfd ATTRIBUTE_UNUSED,
783++ struct bfd_link_info *info ATTRIBUTE_UNUSED,
784++ Elf_Internal_Sym *sym,
785++ const char **namep ATTRIBUTE_UNUSED,
786++ flagword *flagsp ATTRIBUTE_UNUSED,
787++ asection **secp,
788++ bfd_vma *valp)
789++{
790++ asection *scomm;
791++
792++ switch (sym->st_shndx)
793++ {
794++ case SHN_GNU_SHARABLE_COMMON:
795++ scomm = get_sharable_common_section (abfd);
796++ if (scomm == NULL)
797++ return FALSE;
798++ *secp = scomm;
799++ *valp = sym->st_size;
800++ break;
801++ }
802++ return TRUE;
803++}
804++
805++bfd_boolean
806++_bfd_elf_sharable_section_from_bfd_section
807++ (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, int *index_return)
808++{
809++ if (sec == &_bfd_elf_sharable_com_section)
810++ {
811++ *index_return = SHN_GNU_SHARABLE_COMMON;
812++ return TRUE;
813++ }
814++ return FALSE;
815++}
816++
817++void
818++_bfd_elf_sharable_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
819++ asymbol *asym)
820++{
821++ elf_symbol_type *elfsym = (elf_symbol_type *) asym;
822++
823++ switch (elfsym->internal_elf_sym.st_shndx)
824++ {
825++ case SHN_GNU_SHARABLE_COMMON:
826++ asym->section = &_bfd_elf_sharable_com_section;
827++ asym->value = elfsym->internal_elf_sym.st_size;
828++ asym->flags &= ~BSF_GLOBAL;
829++ break;
830++ }
831++}
832++
833++bfd_boolean
834++_bfd_elf_sharable_common_definition (Elf_Internal_Sym *sym)
835++{
836++ return (sym->st_shndx == SHN_COMMON
837++ || sym->st_shndx == SHN_GNU_SHARABLE_COMMON);
838++}
839++
840++unsigned int
841++_bfd_elf_sharable_common_section_index (asection *sec)
842++{
843++ if ((elf_section_flags (sec) & SHF_GNU_SHARABLE) == 0)
844++ return SHN_COMMON;
845++ else
846++ return SHN_GNU_SHARABLE_COMMON;
847++}
848++
849++asection *
850++_bfd_elf_sharable_common_section (asection *sec)
851++{
852++ if ((elf_section_flags (sec) & SHF_GNU_SHARABLE) == 0)
853++ return bfd_com_section_ptr;
854++ else
855++ return &_bfd_elf_sharable_com_section;
856++}
857++
858++bfd_boolean
859++_bfd_elf_sharable_merge_symbol (struct elf_link_hash_entry *h,
860++ const Elf_Internal_Sym *sym,
861++ asection **psec,
862++ bfd_boolean newdef,
863++ bfd_boolean newdyn,
864++ bfd *abfd,
865++ bfd_boolean olddef,
866++ bfd_boolean olddyn,
867++ bfd *oldbfd,
868++ asection *oldsec)
869++{
870++ asection *sec = *psec;
871++
872++ /* Check sharable symbol. If one is undefined, it is OK. */
873++ if (oldsec && !bfd_is_und_section (sec))
874++ {
875++ bfd_boolean sharable, oldsharable;
876++
877++ sharable = (elf_section_data (sec)
878++ && (elf_section_flags (sec) & SHF_GNU_SHARABLE));
879++ oldsharable = (elf_section_data (oldsec)
880++ && (elf_section_flags (oldsec)
881++ & SHF_GNU_SHARABLE));
882++
883++ if (sharable != oldsharable)
884++ {
885++ bfd *nsbfd, *sbfd;
886++ asection *nssec, *ssec;
887++ bfd_boolean nsdyn, sdyn, nsdef, sdef;
888++
889++ if (oldsharable)
890++ {
891++ sbfd = oldbfd;
892++ nsbfd = abfd;
893++ ssec = oldsec;
894++ nssec = sec;
895++ sdyn = olddyn;
896++ nsdyn = newdyn;
897++ sdef = olddef;
898++ nsdef = newdef;
899++ }
900++ else
901++ {
902++ sbfd = abfd;
903++ nsbfd = oldbfd;
904++ ssec = sec;
905++ nssec = oldsec;
906++ sdyn = newdyn;
907++ nsdyn = olddyn;
908++ sdef = newdef;
909++ nsdef = olddef;
910++ }
911++
912++ if (sdef && !sdyn)
913++ {
914++ /* If the sharable definition comes from a relocatable
915++ file, it will override the non-sharable one in DSO. */
916++ return TRUE;
917++ }
918++ else if (!nsdef
919++ && !nsdyn
920++ && (h->root.type == bfd_link_hash_common
921++ || bfd_is_com_section (nssec)))
922++ {
923++ asection *scomm;
924++
925++ /* When the non-sharable common symbol in a relocatable
926++ file, we can turn it into sharable. If the sharable
927++ symbol isn't common, the non-sharable common symbol
928++ will be overidden. We only need to handle the
929++ sharable common symbol and the non-sharable common
930++ symbol. We just turn the non-sharable common symbol
931++ into the sharable one. */
932++ if (sym->st_shndx == SHN_GNU_SHARABLE_COMMON)
933++ {
934++ scomm = get_sharable_common_section (oldbfd);
935++ if (scomm == NULL)
936++ return FALSE;
937++ h->root.u.c.p->section = scomm;
938++ }
939++ else
940++ {
941++ scomm = get_sharable_common_section (abfd);
942++ if (scomm == NULL)
943++ return FALSE;
944++ *psec = scomm;
945++ }
946++
947++ return TRUE;
948++ }
949++
950++ (*_bfd_error_handler)
951++ (_("%s: sharable symbol in %B section %A mismatches non-shrable symbol in %B section %A"),
952++ sbfd, ssec, nsbfd, nssec, h->root.root.string);
953++ bfd_set_error (bfd_error_bad_value);
954++ return FALSE;
955++ }
956++ }
957++
958++ return TRUE;
959++}
960+diff --git a/bfd/elfnn-ia64.c b/bfd/elfnn-ia64.c
961+index 117b4c8..33c7ee4 100644
962+--- a/bfd/elfnn-ia64.c
963++++ b/bfd/elfnn-ia64.c
964+@@ -1055,7 +1055,8 @@ elfNN_ia64_add_symbol_hook (bfd *abfd,
965+ *valp = sym->st_size;
966+ }
967+
968+- return TRUE;
969++ return _bfd_elf_add_sharable_symbol (abfd, info, sym, namep, flagsp,
970++ secp, valp);
971+ }
972+
973+ /* Return the number of additional phdrs we will need. */
974+@@ -5069,6 +5070,19 @@ elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
975+ #define elf_backend_special_sections elfNN_ia64_special_sections
976+ #define elf_backend_default_execstack 0
977+
978++#define elf_backend_section_from_bfd_section \
979++ _bfd_elf_sharable_section_from_bfd_section
980++#define elf_backend_symbol_processing \
981++ _bfd_elf_sharable_symbol_processing
982++#define elf_backend_common_section_index \
983++ _bfd_elf_sharable_common_section_index
984++#define elf_backend_common_section \
985++ _bfd_elf_sharable_common_section
986++#define elf_backend_common_definition \
987++ _bfd_elf_sharable_common_definition
988++#define elf_backend_merge_symbol \
989++ _bfd_elf_sharable_merge_symbol
990++
991+ /* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
992+ SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
993+ We don't want to flood users with so many error messages. We turn
994+diff --git a/binutils/readelf.c b/binutils/readelf.c
995+index 0389f14..cdc18ba 100644
996+--- a/binutils/readelf.c
997++++ b/binutils/readelf.c
998+@@ -1406,6 +1406,8 @@ dump_relocations (FILE * file,
999+ sec_name = "ABS";
1000+ else if (psym->st_shndx == SHN_COMMON)
1001+ sec_name = "COMMON";
1002++ else if (psym->st_shndx == SHN_GNU_SHARABLE_COMMON)
1003++ sec_name = "GNU_SHARABLE_COMMON";
1004+ else if ((elf_header.e_machine == EM_MIPS
1005+ && psym->st_shndx == SHN_MIPS_SCOMMON)
1006+ || (elf_header.e_machine == EM_TI_C6000
1007+@@ -3035,6 +3037,7 @@ get_segment_type (unsigned long p_type)
1008+ case PT_SHLIB: return "SHLIB";
1009+ case PT_PHDR: return "PHDR";
1010+ case PT_TLS: return "TLS";
1011++ case PT_GNU_SHR: return "GNU_SHR";
1012+
1013+ case PT_GNU_EH_FRAME:
1014+ return "GNU_EH_FRAME";
1015+@@ -9264,6 +9267,8 @@ get_symbol_index_type (unsigned int type)
1016+ case SHN_UNDEF: return "UND";
1017+ case SHN_ABS: return "ABS";
1018+ case SHN_COMMON: return "COM";
1019++ case SHN_GNU_SHARABLE_COMMON:
1020++ return "GNU_SHARABLE_COM";
1021+ default:
1022+ if (type == SHN_IA_64_ANSI_COMMON
1023+ && elf_header.e_machine == EM_IA_64
1024+diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
1025+index 3377261..286df1f 100644
1026+--- a/gas/config/obj-elf.c
1027++++ b/gas/config/obj-elf.c
1028+@@ -78,6 +78,7 @@ static void obj_elf_subsection (int);
1029+ static void obj_elf_popsection (int);
1030+ static void obj_elf_gnu_attribute (int);
1031+ static void obj_elf_tls_common (int);
1032++static void obj_elf_sharable_common (int);
1033+ static void obj_elf_lcomm (int);
1034+ static void obj_elf_struct (int);
1035+
1036+@@ -138,6 +139,8 @@ static const pseudo_typeS elf_pseudo_table[] =
1037+
1038+ {"tls_common", obj_elf_tls_common, 0},
1039+
1040++ {"sharable_common", obj_elf_sharable_common, 0},
1041++
1042+ /* End sentinel. */
1043+ {NULL, NULL, 0},
1044+ };
1045+@@ -393,6 +396,39 @@ obj_elf_tls_common (int ignore ATTRIBUTE_UNUSED)
1046+ }
1047+
1048+ static void
1049++obj_elf_sharable_common (int ignore ATTRIBUTE_UNUSED)
1050++{
1051++ static segT sharable_bss_section;
1052++ asection *saved_com_section_ptr = elf_com_section_ptr;
1053++ asection *saved_bss_section = bss_section;
1054++
1055++ if (sharable_bss_section == NULL)
1056++ {
1057++ flagword applicable;
1058++ segT seg = now_seg;
1059++ subsegT subseg = now_subseg;
1060++
1061++ /* The .sharable_bss section is for local .sharable_common
1062++ symbols. */
1063++ sharable_bss_section = subseg_new (".sharable_bss", 0);
1064++ applicable = bfd_applicable_section_flags (stdoutput);
1065++ bfd_set_section_flags (stdoutput, sharable_bss_section,
1066++ applicable & SEC_ALLOC);
1067++ seg_info (sharable_bss_section)->bss = 1;
1068++
1069++ subseg_set (seg, subseg);
1070++ }
1071++
1072++ elf_com_section_ptr = &_bfd_elf_sharable_com_section;
1073++ bss_section = sharable_bss_section;
1074++
1075++ s_comm_internal (0, elf_common_parse);
1076++
1077++ elf_com_section_ptr = saved_com_section_ptr;
1078++ bss_section = saved_bss_section;
1079++}
1080++
1081++static void
1082+ obj_elf_lcomm (int ignore ATTRIBUTE_UNUSED)
1083+ {
1084+ symbolS *symbolP = s_comm_internal (0, s_lcomm_internal);
1085+@@ -611,11 +647,17 @@ obj_elf_change_section (const char *name,
1086+
1087+ .section .lbss,"aw",@progbits
1088+
1089++ "@progbits" is incorrect. Also for sharable bss
1090++ sections, gcc, as of 2005-07-06, will emit
1091++
1092++ .section .sharable_bss,"aw",@progbits
1093++
1094+ "@progbits" is incorrect. */
1095+ #ifdef TC_I386
1096+ && (bed->s->arch_size != 64
1097+ || !(ssect->attr & SHF_X86_64_LARGE))
1098+ #endif
1099++ && !(ssect->attr & SHF_GNU_SHARABLE)
1100+ && ssect->type != SHT_INIT_ARRAY
1101+ && ssect->type != SHT_FINI_ARRAY
1102+ && ssect->type != SHT_PREINIT_ARRAY)
1103+diff --git a/include/bfdlink.h b/include/bfdlink.h
1104+index 1ac0738..8f6f2dc 100644
1105+--- a/include/bfdlink.h
1106++++ b/include/bfdlink.h
1107+@@ -387,6 +387,9 @@ struct bfd_link_info
1108+ --dynamic-list command line options. */
1109+ unsigned int dynamic: 1;
1110+
1111++ /* TRUE if sharables sections may be created. */
1112++ unsigned int sharable_sections: 1;
1113++
1114+ /* TRUE if PT_GNU_STACK segment should be created with PF_R|PF_W|PF_X
1115+ flags. */
1116+ unsigned int execstack: 1;
1117+diff --git a/include/elf/common.h b/include/elf/common.h
1118+index cd3bcdd..4f5e4b6 100644
1119+--- a/include/elf/common.h
1120++++ b/include/elf/common.h
1121+@@ -437,6 +437,7 @@
1122+ #define PT_SUNW_EH_FRAME PT_GNU_EH_FRAME /* Solaris uses the same value */
1123+ #define PT_GNU_STACK (PT_LOOS + 0x474e551) /* Stack flags */
1124+ #define PT_GNU_RELRO (PT_LOOS + 0x474e552) /* Read-only after relocation */
1125++#define PT_GNU_SHR (PT_LOOS + 0x474e554) /* Sharable segment */
1126+
1127+ /* Program segment permissions, in program header p_flags field. */
1128+
1129+@@ -519,6 +520,8 @@
1130+ are not to be further
1131+ relocated. */
1132+
1133++#define SHF_GNU_SHARABLE 0x01000000 /* sharable section */
1134++
1135+ /* Values of note segment descriptor types for core files. */
1136+
1137+ #define NT_PRSTATUS 1 /* Contains copy of prstatus struct */
1138+@@ -688,6 +691,9 @@
1139+ #define STT_LOPROC 13 /* Processor-specific semantics */
1140+ #define STT_HIPROC 15 /* Processor-specific semantics */
1141+
1142++/* Associated symbol is in common sharable */
1143++#define SHN_GNU_SHARABLE_COMMON (SHN_LOOS + 10)
1144++
1145+ /* The following constants control how a symbol may be accessed once it has
1146+ become part of an executable or shared library. */
1147+
1148+diff --git a/ld/emulparams/elf32_x86_64.sh b/ld/emulparams/elf32_x86_64.sh
1149+index d34297b..9fb8982 100644
1150+--- a/ld/emulparams/elf32_x86_64.sh
1151++++ b/ld/emulparams/elf32_x86_64.sh
1152+@@ -16,6 +16,7 @@ LARGE_SECTIONS=yes
1153+ LARGE_BSS_AFTER_BSS=
1154+ SEPARATE_GOTPLT="SIZEOF (.got.plt) >= 24 ? 24 : 0"
1155+ IREL_IN_PLT=
1156++SHARABLE_SECTIONS=yes
1157+
1158+ if [ "x${host}" = "x${target}" ]; then
1159+ case " $EMULATION_LIBPATH " in
1160+diff --git a/ld/emulparams/elf64_ia64.sh b/ld/emulparams/elf64_ia64.sh
1161+index 7e5e54d..d8cf531 100644
1162+--- a/ld/emulparams/elf64_ia64.sh
1163++++ b/ld/emulparams/elf64_ia64.sh
1164+@@ -37,3 +37,4 @@ OTHER_READONLY_SECTIONS="${OTHER_READONLY_SECTIONS}
1165+ # .dtors. They have to be next to .sbss/.sbss2/.sdata/.sdata2.
1166+ SMALL_DATA_CTOR=" "
1167+ SMALL_DATA_DTOR=" "
1168++SHARABLE_SECTIONS=yes
1169+diff --git a/ld/emulparams/elf_i386.sh b/ld/emulparams/elf_i386.sh
1170+index add700f..dc2d6ef 100644
1171+--- a/ld/emulparams/elf_i386.sh
1172++++ b/ld/emulparams/elf_i386.sh
1173+@@ -13,6 +13,7 @@ GENERATE_PIE_SCRIPT=yes
1174+ NO_SMALL_DATA=yes
1175+ SEPARATE_GOTPLT="SIZEOF (.got.plt) >= 12 ? 12 : 0"
1176+ IREL_IN_PLT=
1177++SHARABLE_SECTIONS=yes
1178+
1179+ # Linux modify the default library search path to first include
1180+ # a 32-bit specific directory.
1181+diff --git a/ld/emulparams/elf_x86_64.sh b/ld/emulparams/elf_x86_64.sh
1182+index 4842257..e9cd479 100644
1183+--- a/ld/emulparams/elf_x86_64.sh
1184++++ b/ld/emulparams/elf_x86_64.sh
1185+@@ -16,6 +16,7 @@ LARGE_SECTIONS=yes
1186+ LARGE_BSS_AFTER_BSS=
1187+ SEPARATE_GOTPLT="SIZEOF (.got.plt) >= 24 ? 24 : 0"
1188+ IREL_IN_PLT=
1189++SHARABLE_SECTIONS=yes
1190+
1191+ if [ "x${host}" = "x${target}" ]; then
1192+ case " $EMULATION_LIBPATH " in
1193+diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
1194+index 682f5e5..510ca2f 100644
1195+--- a/ld/emultempl/elf32.em
1196++++ b/ld/emultempl/elf32.em
1197+@@ -105,6 +105,7 @@ gld${EMULATION_NAME}_before_parse (void)
1198+ input_flags.dynamic = ${DYNAMIC_LINK-TRUE};
1199+ config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`;
1200+ config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`;
1201++ link_info.sharable_sections = `if test "$SHARABLE_SECTIONS" = "yes" ; then echo TRUE ; else echo FALSE ; fi`;
1202+ }
1203+
1204+ EOF
1205+@@ -1816,6 +1817,12 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
1206+ int iself = s->owner->xvec->flavour == bfd_target_elf_flavour;
1207+ unsigned int sh_type = iself ? elf_section_type (s) : SHT_NULL;
1208+
1209++ /* Orphaned sharable sections won't have correct page
1210++ requirements. */
1211++ if (elf_section_flags (s) & SHF_GNU_SHARABLE)
1212++ einfo ("%F%P: unable to place orphaned sharable section %A (%B)\n",
1213++ s, s->owner);
1214++
1215+ if (! link_info.relocatable
1216+ && link_info.combreloc
1217+ && (s->flags & SEC_ALLOC))
1218+diff --git a/ld/ldmain.c b/ld/ldmain.c
1219+index 019df71..8a5f01f 100644
1220+--- a/ld/ldmain.c
1221++++ b/ld/ldmain.c
1222+@@ -289,6 +289,7 @@ main (int argc, char **argv)
1223+ link_info.pei386_auto_import = -1;
1224+ link_info.spare_dynamic_tags = 5;
1225+ link_info.path_separator = ':';
1226++ link_info.sharable_sections = FALSE;
1227+
1228+ ldfile_add_arch ("");
1229+ emulation = get_emulation (argc, argv);
1230+diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc
1231+index e8126cb..922a906 100644
1232+--- a/ld/scripttempl/elf.sc
1233++++ b/ld/scripttempl/elf.sc
1234+@@ -298,6 +298,40 @@ STACK=" .stack ${RELOCATING-0}${RELOCATING+${STACK_ADDR}} :
1235+ ${RELOCATING+${USER_LABEL_PREFIX}_stack = .;}
1236+ *(.stack)
1237+ }"
1238++test "${SHARABLE_SECTIONS}" = "yes" && OTHER_READWRITE_SECTIONS="
1239++ ${OTHER_READWRITE_SECTIONS}
1240++ /* Sharable data sections. */
1241++ .sharable_data ${RELOCATING-0} : ${RELOCATING+ALIGN(${MAXPAGESIZE})}
1242++ {
1243++ ${RELOCATING+PROVIDE_HIDDEN (__sharable_data_start = .);}
1244++ *(.sharable_data${RELOCATING+ .sharable_data.* .gnu.linkonce.shrd.*})
1245++ /* Align here to ensure that the sharable data section ends at the
1246++ page boundary. */
1247++ ${RELOCATING+. = ALIGN(. != 0 ? ${MAXPAGESIZE} : 1);}
1248++ ${RELOCATING+PROVIDE_HIDDEN (__sharable_data_end = .);}
1249++ }
1250++"
1251++test "${SHARABLE_SECTIONS}" = "yes" && OTHER_BSS_SECTIONS="
1252++ ${OTHER_BSS_SECTIONS}
1253++ /* Sharable bss sections */
1254++ .sharable_bss ${RELOCATING-0} : ${RELOCATING+ALIGN(${MAXPAGESIZE})}
1255++ {
1256++ ${RELOCATING+PROVIDE_HIDDEN (__sharable_bss_start = .);}
1257++ *(.dynsharablebss)
1258++ *(.sharable_bss${RELOCATING+ .sharable_bss.* .gnu.linkonce.shrb.*})
1259++ *(SHARABLE_COMMON)
1260++ /* Align here to ensure that the sharable bss section ends at the
1261++ page boundary. */
1262++ ${RELOCATING+. = ALIGN(. != 0 ? ${MAXPAGESIZE} : 1);}
1263++ ${RELOCATING+PROVIDE_HIDDEN (__sharable_bss_end = .);}
1264++ }
1265++"
1266++test "${SHARABLE_SECTIONS}" = "yes" && REL_SHARABLE="
1267++ .rel.sharable_data ${RELOCATING-0} : { *(.rel.sharable_data${RELOCATING+ .rel.sharable_data.* .rel.gnu.linkonce.shrd.*}) }
1268++ .rela.sharable_data ${RELOCATING-0} : { *(.rela.sharable_data${RELOCATING+ .rela.sharable_data.* .rela.gnu.linkonce.shrd.*}) }
1269++ .rel.sharable_bss ${RELOCATING-0} : { *(.rel.sharable_bss${RELOCATING+ .rel.sharable_bss.* .rel.gnu.linkonce.shrb.*}) }
1270++ .rela.sharable_bss ${RELOCATING-0} : { *(.rela.sharable_bss${RELOCATING+ .rela.sharable_bss.* .rela.gnu.linkonce.shrb.*}) }
1271++"
1272+
1273+ TEXT_START_ADDR="SEGMENT_START(\"text-segment\", ${TEXT_START_ADDR})"
1274+ SHLIB_TEXT_START_ADDR="SEGMENT_START(\"text-segment\", ${SHLIB_TEXT_START_ADDR:-0})"
1275+@@ -392,6 +426,7 @@ eval $COMBRELOCCAT <<EOF
1276+ .rel.got ${RELOCATING-0} : { *(.rel.got) }
1277+ .rela.got ${RELOCATING-0} : { *(.rela.got) }
1278+ ${OTHER_GOT_RELOC_SECTIONS}
1279++ ${REL_SHARABLE}
1280+ ${REL_SDATA}
1281+ ${REL_SBSS}
1282+ ${REL_SDATA2}
1283+--
1284+1.8.3.1
1285+