1 # DP: Fix PR ld/12730, taken from the trunk
3 2011-05-07 H.J. Lu <hongjiu.lu@intel.com>
6 * elf.c (_bfd_elf_section_offset): Check SEC_ELF_REVERSE_COPY.
8 * elflink.c (elf_link_input_bfd): Reverse copy .ctors/.dtors
11 * section.c (SEC_ELF_REVERSE_COPY): New.
12 * bfd-in2.h: Regenerated.
14 2011-05-07 H.J. Lu <hongjiu.lu@intel.com>
17 * ld-elf/elf.exp (array_tests): Add "pr12730".
18 (array_tests_pie): New.
19 (array_tests_static): Add -static for "static init array mixed".
20 Add "static pr12730". Run array_tests_pie for Linux.
22 * ld-elf/init-mixed.c (ctor1007): Renamed to ...
25 (ctors1007): Remove ctor1007. Add ctor1007b and ctor1007a.
26 (dtor1007): Renamed to ...
29 (dtors1007): Remove dtor1007. Add dtor1007b and dtor1007a.
30 (ctor65535): Renamed to ...
33 (ctors65535): Remove ctor65535. Add ctor65535b and ctor65535a.
34 (dtor65535): Renamed to ...
37 (dtors65535): Remove dtor65535. Add dtor65535b and dtor65535a.
39 * ld-elf/pr12730.cc: New.
40 * ld-elf/pr12730.out: Likewise.
42 diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
43 index aa12c8a..5076ccf 100644
46 @@ -1320,6 +1320,11 @@ typedef struct bfd_section
48 #define SEC_COFF_SHARED_LIBRARY 0x4000000
50 + /* This input section should be copied to output in reverse order
51 + as an array of pointers. This is for ELF linker internal use
53 +#define SEC_ELF_REVERSE_COPY 0x4000000
55 /* This section contains data which may be shared with other
56 executables or shared objects. This is for COFF only. */
57 #define SEC_COFF_SHARED 0x8000000
58 diff --git a/bfd/elf.c b/bfd/elf.c
59 index b5a1952..6fccf42 100644
62 @@ -9379,6 +9379,12 @@ _bfd_elf_section_offset (bfd *abfd,
63 case ELF_INFO_TYPE_EH_FRAME:
64 return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset);
66 + if ((sec->flags & SEC_ELF_REVERSE_COPY) != 0)
68 + const struct elf_backend_data *bed = get_elf_backend_data (abfd);
69 + bfd_size_type address_size = bed->s->arch_size / 8;
70 + offset = sec->size - offset - address_size;
75 diff --git a/bfd/elflink.c b/bfd/elflink.c
76 index 082355d..e4f728d 100644
79 @@ -9120,6 +9120,9 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
81 const struct elf_backend_data *bed;
82 struct elf_link_hash_entry **sym_hashes;
83 + bfd_size_type address_size;
84 + bfd_vma r_type_mask;
87 output_bfd = finfo->output_bfd;
88 bed = get_elf_backend_data (output_bfd);
89 @@ -9290,6 +9293,19 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
93 + if (bed->s->arch_size == 32)
101 + r_type_mask = 0xffffffff;
106 /* Relocate the contents of each section. */
107 sym_hashes = elf_sym_hashes (input_bfd);
108 for (o = input_bfd->sections; o != NULL; o = o->next)
109 @@ -9394,8 +9410,6 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
111 Elf_Internal_Rela *internal_relocs;
112 Elf_Internal_Rela *rel, *relend;
113 - bfd_vma r_type_mask;
115 int action_discarded;
118 @@ -9407,15 +9421,27 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
119 && o->reloc_count > 0)
122 - if (bed->s->arch_size == 32)
123 + /* We need to reverse-copy input .ctors/.dtors sections if
124 + they are placed in .init_array/.finit_array for output. */
125 + if (o->size > address_size
126 + && ((strncmp (o->name, ".ctors", 6) == 0
127 + && strcmp (o->output_section->name,
128 + ".init_array") == 0)
129 + || (strncmp (o->name, ".dtors", 6) == 0
130 + && strcmp (o->output_section->name,
131 + ".fini_array") == 0))
132 + && (o->name[6] == 0 || o->name[6] == '.'))
134 - r_type_mask = 0xff;
139 - r_type_mask = 0xffffffff;
141 + if (o->size != o->reloc_count * address_size)
143 + (*_bfd_error_handler)
144 + (_("error: %B: size of section %A is not "
145 + "multiple of address size"),
147 + bfd_set_error (bfd_error_on_input);
150 + o->flags |= SEC_ELF_REVERSE_COPY;
153 action_discarded = -1;
154 @@ -9876,12 +9902,34 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
157 /* FIXME: octets_per_byte. */
158 - if (! (o->flags & SEC_EXCLUDE)
159 - && ! bfd_set_section_contents (output_bfd, o->output_section,
161 - (file_ptr) o->output_offset,
164 + if (! (o->flags & SEC_EXCLUDE))
166 + file_ptr offset = (file_ptr) o->output_offset;
167 + bfd_size_type todo = o->size;
168 + if ((o->flags & SEC_ELF_REVERSE_COPY))
170 + /* Reverse-copy input section to output. */
173 + todo -= address_size;
174 + if (! bfd_set_section_contents (output_bfd,
182 + offset += address_size;
186 + else if (! bfd_set_section_contents (output_bfd,
195 diff --git a/bfd/section.c b/bfd/section.c
196 index 65ac5e6..3cd7e65 100644
199 @@ -327,6 +327,11 @@ CODE_FRAGMENT
201 .#define SEC_COFF_SHARED_LIBRARY 0x4000000
203 +. {* This input section should be copied to output in reverse order
204 +. as an array of pointers. This is for ELF linker internal use
206 +.#define SEC_ELF_REVERSE_COPY 0x4000000
208 . {* This section contains data which may be shared with other
209 . executables or shared objects. This is for COFF only. *}
210 .#define SEC_COFF_SHARED 0x8000000
211 diff --git a/ld/testsuite/ld-elf/elf.exp b/ld/testsuite/ld-elf/elf.exp
212 index 73a417c..6808d8a 100644
213 --- a/ld/testsuite/ld-elf/elf.exp
214 +++ b/ld/testsuite/ld-elf/elf.exp
215 @@ -81,17 +81,32 @@ set array_tests {
216 {"init array" "" "" {init.c} "init" "init.out"}
217 {"fini array" "" "" {fini.c} "fini" "fini.out"}
218 {"init array mixed" "" "" {init-mixed.c} "init-mixed" "init-mixed.out" "-I."}
219 + {"pr12730" "" "" {pr12730.cc} "pr12730" "pr12730.out" "" "c++"}
221 +set array_tests_pie {
222 + {"PIE preinit array" "-pie" "" {preinit.c} "preinit" "preinit.out" "-fPIE" }
223 + {"PIE init array" "-pie" "" {init.c} "init" "init.out" "-fPIE"}
224 + {"PIE fini array" "-pie" "" {fini.c} "fini" "fini.out" "-fPIE"}
225 + {"PIE init array mixed" "-pie" "" {init-mixed.c} "init-mixed" "init-mixed.out" "-I. -fPIE"}
226 + {"PIE pr12730" "-pie" "" {pr12730.cc} "pr12730" "pr12730.out" "-fPIE" "c++"}
228 set array_tests_static {
229 {"static preinit array" "-static" "" {preinit.c} "preinit" "preinit.out"}
230 {"static init array" "-static" "" {init.c} "init" "init.out"}
231 {"static fini array" "-static" "" {fini.c} "fini" "fini.out"}
232 - {"static init array mixed" "" "" {init-mixed.c} "init-mixed" "init-mixed.out" "-I."}
233 + {"static init array mixed" "-static" "" {init-mixed.c} "init-mixed" "init-mixed.out" "-I."}
234 + {"static pr12730" "-static" "" {pr12730.cc} "pr12730" "pr12730.out" "" "c++"}
237 # NetBSD ELF systems do not currently support the .*_array sections.
238 set xfails [list "*-*-netbsdelf*"]
239 run_ld_link_exec_tests $xfails $array_tests
241 +# Run PIE tests only on Linux.
242 +if { [istarget "*-*-linux*"] } {
243 + run_ld_link_exec_tests $xfails $array_tests_pie
246 # Be cautious to not XFAIL for *-*-linux-gnu*, *-*-kfreebsd-gnu*, etc.
247 switch -regexp $target_triplet {
248 ^\[^-\]*-\[^-\]*-gnu.*$ {
249 diff --git a/ld/testsuite/ld-elf/init-mixed.c b/ld/testsuite/ld-elf/init-mixed.c
250 index 1d0c727..770a4b5 100644
251 --- a/ld/testsuite/ld-elf/init-mixed.c
252 +++ b/ld/testsuite/ld-elf/init-mixed.c
253 @@ -27,25 +27,39 @@ void (*const fini_array1005[]) ()
271 void (*const ctors1007[]) ()
272 __attribute__ ((section (".ctors.64528"), aligned (sizeof (void *))))
274 + = { ctor1007b, ctor1007a };
291 void (*const dtors1007[]) ()
292 __attribute__ ((section (".dtors.64528"), aligned (sizeof (void *))))
294 + = { dtor1007b, dtor1007a };
298 @@ -69,17 +83,31 @@ void (*const fini_array65530[]) ()
312 + if (count != 65535)
316 void (*const ctors65535[]) ()
317 __attribute__ ((section (".ctors"), aligned (sizeof (void *))))
319 + = { ctor65535b, ctor65535a };
323 + if (count != 65536)
333 @@ -87,7 +115,7 @@ dtor65535 ()
335 void (*const dtors65535[]) ()
336 __attribute__ ((section (".dtors"), aligned (sizeof (void *))))
338 + = { dtor65535b, dtor65535a };
342 diff --git a/ld/testsuite/ld-elf/pr12730.cc b/ld/testsuite/ld-elf/pr12730.cc
344 index 0000000..69f57f9
346 +++ b/ld/testsuite/ld-elf/pr12730.cc
360 + { std::cout << "Hello, world!" << std::endl; }
367 + T* _M_allocate_single_object ()
373 +static void __attribute__ (( constructor )) PWLIB_StaticLoader() {
374 + Foo<Hello> allocator;
375 + Hello* salut = allocator._M_allocate_single_object ();
386 diff --git a/ld/testsuite/ld-elf/pr12730.out b/ld/testsuite/ld-elf/pr12730.out
388 index 0000000..af5626b
390 +++ b/ld/testsuite/ld-elf/pr12730.out