GNU Binutils with patches for OS216
修订版 | 586c3d6ffaca4bf3a6c7ec651f16fbd350a2185d (tree) |
---|---|
时间 | 2013-11-07 02:12:03 |
作者 | H.J. Lu <hjl.tools@gmai...> |
Commiter | H.J. Lu |
Add binutils-lto-mixed.patch
@@ -17,6 +17,7 @@ clean=$1 | ||
17 | 17 | |
18 | 18 | patches=" |
19 | 19 | binutils-sharable.patch |
20 | + binutils-lto-mixed.patch | |
20 | 21 | " |
21 | 22 | |
22 | 23 | for p in $patches |
@@ -0,0 +1,3326 @@ | ||
1 | +From 1e48c600efcce8f04ea8f090fe95e8259a47cfcd Mon Sep 17 00:00:00 2001 | |
2 | +From: "H.J. Lu" <hjl.tools@gmail.com> | |
3 | +Date: Mon, 4 Nov 2013 09:17:45 -0800 | |
4 | +Subject: [PATCH] Add lto and none-lto input support for ld -r | |
5 | + | |
6 | +This patch adds lto and none-lto input support for ld -r so that | |
7 | +LTO can be used with ld -r without Makefile changes. It is useful | |
8 | +for Linux kernel build with LTO. | |
9 | +--- | |
10 | + ChangeLog.lto-mixed | 310 +++++++++++ | |
11 | + bfd/bfd-in2.h | 22 + | |
12 | + bfd/bfd.c | 47 ++ | |
13 | + bfd/elf.c | 1 + | |
14 | + bfd/elflink.c | 17 + | |
15 | + bfd/format.c | 34 +- | |
16 | + bfd/opncls.c | 66 +++ | |
17 | + bfd/plugin.c | 162 +++++- | |
18 | + bfd/plugin.h | 2 + | |
19 | + bfd/section.c | 3 + | |
20 | + binutils/objcopy.c | 28 +- | |
21 | + binutils/readelf.c | 1 + | |
22 | + gas/testsuite/gas/elf/section9.d | 1 + | |
23 | + gas/testsuite/gas/elf/section9.s | 2 + | |
24 | + include/bfdlink.h | 6 + | |
25 | + include/elf/common.h | 1 + | |
26 | + ld/emultempl/aarch64elf.em | 6 +- | |
27 | + ld/emultempl/alphaelf.em | 2 +- | |
28 | + ld/emultempl/armelf.em | 6 +- | |
29 | + ld/emultempl/elf32.em | 39 +- | |
30 | + ld/emultempl/ppc64elf.em | 6 +- | |
31 | + ld/emultempl/spuelf.em | 6 +- | |
32 | + ld/ldfile.c | 2 + | |
33 | + ld/ldlang.c | 1027 ++++++++++++++++++++++++++++++++++++- | |
34 | + ld/ldlang.h | 45 +- | |
35 | + ld/ldlex.h | 1 + | |
36 | + ld/ldmain.c | 78 +-- | |
37 | + ld/ldmain.h | 2 + | |
38 | + ld/lexsup.c | 6 + | |
39 | + ld/plugin.c | 36 +- | |
40 | + ld/plugin.h | 3 + | |
41 | + ld/scripttempl/armbpabi.sc | 2 +- | |
42 | + ld/scripttempl/elf.sc | 2 +- | |
43 | + ld/scripttempl/elf32sh-symbian.sc | 2 +- | |
44 | + ld/scripttempl/elf64hppa.sc | 2 +- | |
45 | + ld/scripttempl/elfxtensa.sc | 2 +- | |
46 | + ld/scripttempl/mep.sc | 2 +- | |
47 | + ld/scripttempl/pe.sc | 1 + | |
48 | + ld/scripttempl/pep.sc | 1 + | |
49 | + ld/testsuite/ld-plugin/lto-10.out | 1 + | |
50 | + ld/testsuite/ld-plugin/lto-10a.c | 6 + | |
51 | + ld/testsuite/ld-plugin/lto-10b.c | 7 + | |
52 | + ld/testsuite/ld-plugin/lto-10r.d | 7 + | |
53 | + ld/testsuite/ld-plugin/lto-4.out | 2 + | |
54 | + ld/testsuite/ld-plugin/lto-4a.c | 7 + | |
55 | + ld/testsuite/ld-plugin/lto-4b.c | 9 + | |
56 | + ld/testsuite/ld-plugin/lto-4c.c | 6 + | |
57 | + ld/testsuite/ld-plugin/lto-4r-a.d | 7 + | |
58 | + ld/testsuite/ld-plugin/lto-4r-b.d | 7 + | |
59 | + ld/testsuite/ld-plugin/lto-4r-c.d | 7 + | |
60 | + ld/testsuite/ld-plugin/lto-4r-d.d | 7 + | |
61 | + ld/testsuite/ld-plugin/lto.exp | 59 +++ | |
62 | + ld/testsuite/ld-plugin/pr12365a.c | 25 + | |
63 | + ld/testsuite/ld-plugin/pr12365b.c | 47 ++ | |
64 | + ld/testsuite/ld-plugin/pr12365c.c | 79 +++ | |
65 | + ld/testsuite/ld-plugin/pr14918.c | 5 + | |
66 | + ld/testsuite/ld-plugin/pr14918.d | 4 + | |
67 | + 57 files changed, 2163 insertions(+), 111 deletions(-) | |
68 | + create mode 100644 ChangeLog.lto-mixed | |
69 | + create mode 100644 ld/testsuite/ld-plugin/lto-10.out | |
70 | + create mode 100644 ld/testsuite/ld-plugin/lto-10a.c | |
71 | + create mode 100644 ld/testsuite/ld-plugin/lto-10b.c | |
72 | + create mode 100644 ld/testsuite/ld-plugin/lto-10r.d | |
73 | + create mode 100644 ld/testsuite/ld-plugin/lto-4.out | |
74 | + create mode 100644 ld/testsuite/ld-plugin/lto-4a.c | |
75 | + create mode 100644 ld/testsuite/ld-plugin/lto-4b.c | |
76 | + create mode 100644 ld/testsuite/ld-plugin/lto-4c.c | |
77 | + create mode 100644 ld/testsuite/ld-plugin/lto-4r-a.d | |
78 | + create mode 100644 ld/testsuite/ld-plugin/lto-4r-b.d | |
79 | + create mode 100644 ld/testsuite/ld-plugin/lto-4r-c.d | |
80 | + create mode 100644 ld/testsuite/ld-plugin/lto-4r-d.d | |
81 | + create mode 100644 ld/testsuite/ld-plugin/pr12365a.c | |
82 | + create mode 100644 ld/testsuite/ld-plugin/pr12365b.c | |
83 | + create mode 100644 ld/testsuite/ld-plugin/pr12365c.c | |
84 | + create mode 100644 ld/testsuite/ld-plugin/pr14918.c | |
85 | + create mode 100644 ld/testsuite/ld-plugin/pr14918.d | |
86 | + | |
87 | +diff --git a/ChangeLog.lto-mixed b/ChangeLog.lto-mixed | |
88 | +new file mode 100644 | |
89 | +index 0000000..b14ef5d | |
90 | +--- /dev/null | |
91 | ++++ b/ChangeLog.lto-mixed | |
92 | +@@ -0,0 +1,310 @@ | |
93 | ++bfd/ | |
94 | ++ | |
95 | ++2013-02-15 H.J. Lu <hongjiu.lu@intel.com> | |
96 | ++ | |
97 | ++ * ldlang.c (lang_finish): Take a bfd_boolean argument to support | |
98 | ++ object-only output. | |
99 | ++ (cmdline_emit_object_only_section): Pass TRUE to lang_finish. | |
100 | ++ | |
101 | ++ * ldlang.h (lang_finish): Updated. | |
102 | ++ | |
103 | ++ * ldmain.c (main): Pass FALSE to lang_finish. | |
104 | ++ | |
105 | ++2012-10-25 H.J. Lu <hongjiu.lu@intel.com> | |
106 | ++ | |
107 | ++ PR ld/14747 | |
108 | ++ * elflink.c (_bfd_elf_fix_symbol_flags): Check symbol for linker | |
109 | ++ created section instead. | |
110 | ++ | |
111 | ++2012-10-25 H.J. Lu <hongjiu.lu@intel.com> | |
112 | ++ | |
113 | ++ PR ld/14747 | |
114 | ++ * elflink.c (_bfd_elf_fix_symbol_flags): Never mark | |
115 | ++ _GLOBAL_OFFSET_TABLE_, _PROCEDURE_LINKAGE_TABLE_ nor _DYNAMIC | |
116 | ++ undefined. | |
117 | ++ | |
118 | ++2012-06-28 H.J. Lu <hongjiu.lu@intel.com> | |
119 | ++ | |
120 | ++ PR ld/14272 | |
121 | ++ * elflink.c (_bfd_elf_fix_symbol_flags): Mark the plugin symbol | |
122 | ++ undefined if it is referenced from a non-IR file. | |
123 | ++ | |
124 | ++2012-06-04 H.J. Lu <hongjiu.lu@intel.com> | |
125 | ++ | |
126 | ++ * plugin.c (add_symbols): Set tdata.plugin_data before calling | |
127 | ++ bfd_plugin_get_symbols_in_object_only. | |
128 | ++ | |
129 | ++2011-10-16 H.J. Lu <hongjiu.lu@intel.com> | |
130 | ++ | |
131 | ++ * plugin.c (add_symbols): Call | |
132 | ++ bfd_plugin_get_symbols_in_object_only. | |
133 | ++ (bfd_plugin_get_symtab_upper_bound): Don't call | |
134 | ++ bfd_plugin_get_symbols_in_object_only. | |
135 | ++ | |
136 | ++2011-10-16 H.J. Lu <hongjiu.lu@intel.com> | |
137 | ++ | |
138 | ++ * plugin.c (bfd_plugin_get_symbols_in_object_only): Optimized. | |
139 | ++ | |
140 | ++2011-10-16 H.J. Lu <hongjiu.lu@intel.com> | |
141 | ++ | |
142 | ++ * plugin.c (bfd_plugin_get_symbols_in_object_only): Properly | |
143 | ++ remove the object only section file. | |
144 | ++ | |
145 | ++2011-10-15 H.J. Lu <hongjiu.lu@intel.com> | |
146 | ++ | |
147 | ++ PR ld/13298 | |
148 | ++ * opncls.c (bfd_extract_object_only_section): New. | |
149 | ++ | |
150 | ++ * plugin.c (add_symbols): Initialize object_only_syms and | |
151 | ++ object_only_nsyms. | |
152 | ++ (bfd_plugin_fake_text_section): New. | |
153 | ++ (bfd_plugin_fake_common_section): Likewise. | |
154 | ++ (bfd_plugin_get_symbols_in_object_only): Likewise. | |
155 | ++ (bfd_plugin_get_symtab_upper_bound): Call | |
156 | ++ bfd_plugin_get_symbols_in_object_only and add symbols from | |
157 | ++ object only section. | |
158 | ++ (bfd_plugin_canonicalize_symtab): Remove fake_section and | |
159 | ++ fake_common_section. Use bfd_plugin_fake_text_section and | |
160 | ++ bfd_plugin_fake_common_section. Set udata.p to NULL. Copy | |
161 | ++ symbols from object only section. | |
162 | ++ | |
163 | ++ * plugin.h (plugin_data_struct): Add object_only_nsyms and | |
164 | ++ object_only_syms. | |
165 | ++ | |
166 | ++ * bfd-in2.h: Regenerated. | |
167 | ++ | |
168 | ++2011-05-14 H.J. Lu <hongjiu.lu@intel.com> | |
169 | ++ | |
170 | ++ PR ld/12758 | |
171 | ++ * elflink.c (elf_link_add_archive_symbols): Don't load the IR | |
172 | ++ archive member twice. | |
173 | ++ | |
174 | ++2011-04-19 H.J. Lu <hongjiu.lu@intel.com> | |
175 | ++ | |
176 | ++ * bfd.c (bfd_lto_object_type): New. | |
177 | ++ (bfd): Add object_only_section and lto_type. | |
178 | ++ (bfd_group_signature): New. | |
179 | ++ | |
180 | ++ * elf.c (special_sections_g): Add .gnu_object_only. | |
181 | ++ | |
182 | ++ * format.c (bfd_set_lto_type): New. | |
183 | ++ (bfd_check_format_matches): Use it. | |
184 | ++ | |
185 | ++ * section.c (GNU_OBJECT_ONLY_SECTION_NAME): New. | |
186 | ++ | |
187 | ++ * bfd-in2.h: Regenerated. | |
188 | ++ | |
189 | ++binutils/ | |
190 | ++ | |
191 | ++2011-04-19 H.J. Lu <hongjiu.lu@intel.com> | |
192 | ++ | |
193 | ++ * objcopy.c (group_signature): Removed. | |
194 | ++ (is_strip_section): Replace group_signature with | |
195 | ++ bfd_group_signature. | |
196 | ++ (setup_section): Likewise. | |
197 | ++ | |
198 | ++ * readelf.c (get_section_type_name): Handle SHT_GNU_OBJECT_ONLY. | |
199 | ++ | |
200 | ++gas/testsuite/ | |
201 | ++ | |
202 | ++2011-04-19 H.J. Lu <hongjiu.lu@intel.com> | |
203 | ++ | |
204 | ++ * gas/elf/section9.s: Add the .gnu_object_only test. | |
205 | ++ * gas/elf/section9.d: Updated. | |
206 | ++ | |
207 | ++include/ | |
208 | ++ | |
209 | ++2011-04-19 H.J. Lu <hongjiu.lu@intel.com> | |
210 | ++ | |
211 | ++ * bfdlink.h (bfd_link_info): Add emit_gnu_object_only and | |
212 | ++ emitting_gnu_object_only. | |
213 | ++ | |
214 | ++include/elf/ | |
215 | ++ | |
216 | ++2011-04-19 H.J. Lu <hongjiu.lu@intel.com> | |
217 | ++ | |
218 | ++ * common.h (SHT_GNU_OBJECT_ONLY): New. | |
219 | ++ | |
220 | ++ld/ | |
221 | ++ | |
222 | ++2012-10-20 H.J. Lu <hongjiu.lu@intel.com> | |
223 | ++ | |
224 | ++ * ldlang.c (lang_process): Replace trace_file_tries with | |
225 | ++ verbose. | |
226 | ++ | |
227 | ++2012-08-14 H.J. Lu <hongjiu.lu@intel.com> | |
228 | ++ | |
229 | ++ * emultempl/aarch64elf.em (gld${EMULATION_NAME}_finish): Renamed | |
230 | ++ to ... | |
231 | ++ (aarch64_finish): This. Replace finish_default with | |
232 | ++ gld${EMULATION_NAME}_finish. | |
233 | ++ (LDEMUL_FINISH): Set to aarch64_finish. | |
234 | ++ | |
235 | ++2011-10-15 H.J. Lu <hongjiu.lu@intel.com> | |
236 | ++ | |
237 | ++ PR ld/13298 | |
238 | ++ * ldlang.c (cmdline_extract_object_only_section): Call | |
239 | ++ bfd_extract_object_only_section. | |
240 | ++ | |
241 | ++2011-05-17 H.J. Lu <hongjiu.lu@intel.com> | |
242 | ++ | |
243 | ++ * ldlang.c (cmdline_remove_object_only_files): Return if | |
244 | ++ ENABLE_PLUGINS is undefined or plugin_save_temps is true. | |
245 | ++ | |
246 | ++2011-05-15 H.J. Lu <hongjiu.lu@intel.com> | |
247 | ++ | |
248 | ++ * ldlex.h (option_values): Add OPTION_PLUGIN_SAVE_TEMPS. | |
249 | ++ * lexsup.c (ld_options): Add -plugin-save-temps. | |
250 | ++ (parse_args): Handle OPTION_PLUGIN_SAVE_TEMPS. | |
251 | ++ | |
252 | ++ * plugin.c (plugin_save_temps): New. | |
253 | ++ (plugin_call_cleanup): Don't call plugin cleanup_handler if | |
254 | ++ plugin_save_temps is true. | |
255 | ++ | |
256 | ++ * plugin.h (plugin_save_temps): New. | |
257 | ++ | |
258 | ++2011-05-14 H.J. Lu <hongjiu.lu@intel.com> | |
259 | ++ | |
260 | ++ PR ld/12760 | |
261 | ++ * ldmain.c (warning_callback): Don't warn plugin dummy. | |
262 | ++ | |
263 | ++2011-04-19 H.J. Lu <hongjiu.lu@intel.com> | |
264 | ++ | |
265 | ++ * emultempl/alphaelf.em (alpha_finish): Replace finish_default | |
266 | ++ with gld${EMULATION_NAME}_finish. | |
267 | ++ | |
268 | ++ * emultempl/armelf.em (gld${EMULATION_NAME}_finish): Renamed | |
269 | ++ to ... | |
270 | ++ (arm_finish): This. Replace finish_default with | |
271 | ++ gld${EMULATION_NAME}_finish. | |
272 | ++ (LDEMUL_FINISH): Set to arm_finish. | |
273 | ++ | |
274 | ++ * emultempl/elf32.em (gld${EMULATION_NAME}_finish): New. | |
275 | ++ (orphan_init_done): Likewise. | |
276 | ++ (ld_${EMULATION_NAME}_emulation): Use gld${EMULATION_NAME}_finish. | |
277 | ++ (gld${EMULATION_NAME}_place_orphan): Initialize hold. | |
278 | ++ | |
279 | ++ * emultempl/ppc64elf.em (gld${EMULATION_NAME}_finish): Renamed | |
280 | ++ to ... | |
281 | ++ (ppc_finish): This. Replace finish_default with | |
282 | ++ gld${EMULATION_NAME}_finish. | |
283 | ++ (LDEMUL_FINISH): Set to ppc_finish. | |
284 | ++ | |
285 | ++ * emultempl/spuelf.em (gld${EMULATION_NAME}_finish): Renamed | |
286 | ++ to ... | |
287 | ++ (spu_finish): This. Replace finish_default with | |
288 | ++ gld${EMULATION_NAME}_finish. | |
289 | ++ (LDEMUL_FINISH): Set to spu_finish. | |
290 | ++ | |
291 | ++ * ldfile.c (ldfile_try_open_bfd): Call | |
292 | ++ cmdline_check_object_only_section. | |
293 | ++ | |
294 | ++ * ldlang.c: Include "ldwrite.h" and elf-bfd.h. | |
295 | ++ * ldlang.c (cmdline_object_only_file_list): New. | |
296 | ++ (cmdline_object_only_archive_list): Likewise. | |
297 | ++ (cmdline_temp_object_only_list): Likewise. | |
298 | ++ (cmdline_lists_init): Likewise. | |
299 | ++ (cmdline_list_new): Likewise. | |
300 | ++ (cmdline_list_append): Likewise. | |
301 | ++ (print_cmdline_list): Likewise. | |
302 | ++ (cmdline_on_object_only_archive_list_p): Likewise. | |
303 | ++ (cmdline_object_only_list_append): Likewise. | |
304 | ++ (cmdline_get_object_only_input_files): Likewise. | |
305 | ++ (cmdline_arg): Likewise. | |
306 | ++ (setup_section): Likewise. | |
307 | ++ (copy_section): Likewise. | |
308 | ++ (cmdline_fopen_temp): Likewise. | |
309 | ++ (cmdline_add_object_only_section): Likewise. | |
310 | ++ (cmdline_emit_object_only_section): Likewise. | |
311 | ++ (cmdline_extract_object_only_section): Likewise. | |
312 | ++ (cmdline_check_object_only_section): Likewise. | |
313 | ++ (cmdline_remove_object_only_files): Likewise. | |
314 | ++ (lang_init): Take a bfd_boolean argument to supprt object-only | |
315 | ++ output. Call cmdline_lists_init. | |
316 | ++ (load_symbols): Call cmdline_on_object_only_archive_list_p | |
317 | ++ to check if an archive member should be loaded. | |
318 | ++ (lang_process): Handle object-only link. | |
319 | ++ | |
320 | ++ * ldlang.h (lang_init): Take a bfd_boolean argument. | |
321 | ++ (cmdline_enum_type): New. | |
322 | ++ (cmdline_header_type): Likewise. | |
323 | ++ (cmdline_file_type): Likewise. | |
324 | ++ (cmdline_bfd_type): Likewise. | |
325 | ++ (cmdline_union_type): Likewise. | |
326 | ++ (cmdline_list_type): Likewise. | |
327 | ++ (cmdline_emit_object_only_section): Likewise. | |
328 | ++ (cmdline_check_object_only_section): Likewise. | |
329 | ++ (cmdline_remove_object_only_files): Likewise. | |
330 | ++ | |
331 | ++ * ldmain.c (main): Call xatexit with | |
332 | ++ cmdline_remove_object_only_files. Pass FALSE to lang_init. | |
333 | ++ Use ld_parse_linker_script. Set link_info.output_bfd to NULL | |
334 | ++ after close. Call cmdline_emit_object_only_section if needed. | |
335 | ++ (add_archive_element): Call cmdline_check_object_only_section. | |
336 | ++ (ld_parse_linker_script): New. | |
337 | ++ | |
338 | ++ * ldmain.h (ld_parse_linker_script): New. | |
339 | ++ | |
340 | ++ * plugin.c (plugin_opt_plugin_arg): Ignore -pass-through=. | |
341 | ++ (plugin_maybe_claim): Call cmdline_check_object_only_section | |
342 | ++ on claimed IR files. | |
343 | ++ | |
344 | ++ * scripttempl/armbpabi.sc: Also discard .gnu_object_only | |
345 | ++ sections. | |
346 | ++ * scripttempl/elf.sc: Likewise. | |
347 | ++ * scripttempl/elf32sh-symbian.sc: Likewise. | |
348 | ++ * scripttempl/elf64hppa.sc: Likewise. | |
349 | ++ * scripttempl/elfxtensa.sc: Likewise. | |
350 | ++ * scripttempl/mep.sc: Likewise. | |
351 | ++ * scripttempl/pe.sc: Likewise. | |
352 | ++ * scripttempl/pep.sc: Likewise. | |
353 | ++ | |
354 | ++ld/testsuite/ | |
355 | ++ | |
356 | ++2012-12-05 H.J. Lu <hongjiu.lu@intel.com> | |
357 | ++ | |
358 | ++ PR ld/14918 | |
359 | ++ * ld-plugin/lto.exp (lto_link_elf_tests): Add PR ld/14918 test. | |
360 | ++ | |
361 | ++ * ld-plugin/pr14918.c: New file. | |
362 | ++ * ld-plugin/pr14918.d: Likewise. | |
363 | ++ | |
364 | ++2011-01-22 H.J. Lu <hongjiu.lu@intel.com> | |
365 | ++ | |
366 | ++ PR ld/12365 | |
367 | ++ * ld-plugin/pr12365a.c: New file. | |
368 | ++ * ld-plugin/pr12365b.c: Likewise. | |
369 | ++ * ld-plugin/pr12365c.c: Likewise. | |
370 | ++ | |
371 | ++ * ld-plugin/lto.exp (lto_link_tests): Prepare for the PR ld/12365 | |
372 | ++ test. | |
373 | ++ Run the PR ld/12365 test. | |
374 | ++ | |
375 | ++2011-01-22 H.J. Lu <hongjiu.lu@intel.com> | |
376 | ++ | |
377 | ++ PR ld/12430 | |
378 | ++ * ld-plugin/lto-10.out: New file. | |
379 | ++ * ld-plugin/lto-10a.c: Likewise. | |
380 | ++ * ld-plugin/lto-10b.c: Likewise. | |
381 | ++ * ld-plugin/lto-10r.d: Likewise. | |
382 | ++ | |
383 | ++ * ld-plugin/lto.exp (lto_link_tests): Prepare for "LTO 10". | |
384 | ++ (lto_run_tests): Add "LTO 10". | |
385 | ++ Run lto-10r and create tmpdir/lto-10.o. | |
386 | ++ | |
387 | ++2011-01-22 H.J. Lu <hongjiu.lu@intel.com> | |
388 | ++ | |
389 | ++ PR ld/12291 | |
390 | ++ * ld-plugin/lto-4.out: Likewise. | |
391 | ++ * ld-plugin/lto-4a.c: Likewise. | |
392 | ++ * ld-plugin/lto-4b.c: Likewise. | |
393 | ++ * ld-plugin/lto-4c.c: Likewise. | |
394 | ++ * ld-plugin/lto-4r-a.d: Likewise. | |
395 | ++ * ld-plugin/lto-4r-b.d: Likewise. | |
396 | ++ * ld-plugin/lto-4r-c.d: Likewise. | |
397 | ++ * ld-plugin/lto-4r-d.d: Likewise. | |
398 | ++ | |
399 | ++ * ld-plugin/lto.exp (lto_link_tests): Prepare for "LTO 4[acd]" | |
400 | ++ and "lto-4r-[abcd]" tests. | |
401 | ++ (lto_run_tests): Add "LTO 4[acd]" tests. | |
402 | ++ Build liblto-4.a. Run "lto-4r-[abcd]" tests. | |
403 | +diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h | |
404 | +index 644f89d..743f920 100644 | |
405 | +--- a/bfd/bfd-in2.h | |
406 | ++++ b/bfd/bfd-in2.h | |
407 | +@@ -1081,6 +1081,9 @@ struct bfd_section *bfd_create_gnu_debuglink_section | |
408 | + bfd_boolean bfd_fill_in_gnu_debuglink_section | |
409 | + (bfd *abfd, struct bfd_section *sect, const char *filename); | |
410 | + | |
411 | ++const char *bfd_extract_object_only_section | |
412 | ++ (bfd *abfd); | |
413 | ++ | |
414 | + /* Extracted from libbfd.c. */ | |
415 | + | |
416 | + /* Byte swapping macros for user section data. */ | |
417 | +@@ -1606,6 +1609,9 @@ extern asection _bfd_std_section[4]; | |
418 | + #define BFD_COM_SECTION_NAME "*COM*" | |
419 | + #define BFD_IND_SECTION_NAME "*IND*" | |
420 | + | |
421 | ++/* GNU object-only section name. */ | |
422 | ++#define GNU_OBJECT_ONLY_SECTION_NAME ".gnu_object_only" | |
423 | ++ | |
424 | + /* Pointer to the common section. */ | |
425 | + #define bfd_com_section_ptr (&_bfd_std_section[0]) | |
426 | + /* Pointer to the undefined section. */ | |
427 | +@@ -5968,6 +5974,14 @@ enum bfd_direction | |
428 | + both_direction = 3 | |
429 | + }; | |
430 | + | |
431 | ++enum bfd_lto_object_type | |
432 | ++ { | |
433 | ++ lto_non_object, | |
434 | ++ lto_non_ir_object, | |
435 | ++ lto_ir_object, | |
436 | ++ lto_mixed_object | |
437 | ++ }; | |
438 | ++ | |
439 | + struct bfd | |
440 | + { | |
441 | + /* A unique identifier of the BFD */ | |
442 | +@@ -6115,6 +6129,9 @@ struct bfd | |
443 | + /* The last section on the section list. */ | |
444 | + struct bfd_section *section_last; | |
445 | + | |
446 | ++ /* The object-only section on the section list. */ | |
447 | ++ struct bfd_section *object_only_section; | |
448 | ++ | |
449 | + /* The number of sections. */ | |
450 | + unsigned int section_count; | |
451 | + | |
452 | +@@ -6233,6 +6250,9 @@ struct bfd | |
453 | + /* Set if only required symbols should be added in the link hash table for | |
454 | + this object. Used by VMS linkers. */ | |
455 | + unsigned int selective_search : 1; | |
456 | ++ | |
457 | ++ /* LTO object type. */ | |
458 | ++ unsigned int lto_type : 2; | |
459 | + }; | |
460 | + | |
461 | + typedef enum bfd_error | |
462 | +@@ -6437,6 +6457,8 @@ void bfd_emul_set_commonpagesize (const char *, bfd_vma); | |
463 | + | |
464 | + char *bfd_demangle (bfd *, const char *, int); | |
465 | + | |
466 | ++asymbol *bfd_group_signature (asection *group, asymbol **isympp); | |
467 | ++ | |
468 | + /* Extracted from archive.c. */ | |
469 | + symindex bfd_get_next_mapent | |
470 | + (bfd *abfd, symindex previous, carsym **sym); | |
471 | +diff --git a/bfd/bfd.c b/bfd/bfd.c | |
472 | +index 8d0580c..2ef48a7 100644 | |
473 | +--- a/bfd/bfd.c | |
474 | ++++ b/bfd/bfd.c | |
475 | +@@ -44,6 +44,14 @@ CODE_FRAGMENT | |
476 | + . both_direction = 3 | |
477 | + . }; | |
478 | + . | |
479 | ++.enum bfd_lto_object_type | |
480 | ++. { | |
481 | ++. lto_non_object, | |
482 | ++. lto_non_ir_object, | |
483 | ++. lto_ir_object, | |
484 | ++. lto_mixed_object | |
485 | ++. }; | |
486 | ++. | |
487 | + .struct bfd | |
488 | + .{ | |
489 | + . {* A unique identifier of the BFD *} | |
490 | +@@ -191,6 +199,9 @@ CODE_FRAGMENT | |
491 | + . {* The last section on the section list. *} | |
492 | + . struct bfd_section *section_last; | |
493 | + . | |
494 | ++. {* The object-only section on the section list. *} | |
495 | ++. struct bfd_section *object_only_section; | |
496 | ++. | |
497 | + . {* The number of sections. *} | |
498 | + . unsigned int section_count; | |
499 | + . | |
500 | +@@ -309,6 +320,9 @@ CODE_FRAGMENT | |
501 | + . {* Set if only required symbols should be added in the link hash table for | |
502 | + . this object. Used by VMS linkers. *} | |
503 | + . unsigned int selective_search : 1; | |
504 | ++. | |
505 | ++. {* LTO object type. *} | |
506 | ++. unsigned int lto_type : 2; | |
507 | + .}; | |
508 | + . | |
509 | + */ | |
510 | +@@ -1915,3 +1929,36 @@ bfd_demangle (bfd *abfd, const char *name, int options) | |
511 | + | |
512 | + return res; | |
513 | + } | |
514 | ++ | |
515 | ++/* | |
516 | ++FUNCTION | |
517 | ++ bfd_group_signature | |
518 | ++ | |
519 | ++SYNOPSIS | |
520 | ++ asymbol *bfd_group_signature (asection *group, asymbol **isympp); | |
521 | ++ | |
522 | ++DESCRIPTION | |
523 | ++ Return a pointer to the symbol used as a signature for GROUP. | |
524 | ++*/ | |
525 | ++ | |
526 | ++asymbol * | |
527 | ++bfd_group_signature (asection *group, asymbol **isympp) | |
528 | ++{ | |
529 | ++ bfd *abfd = group->owner; | |
530 | ++ Elf_Internal_Shdr *ghdr; | |
531 | ++ | |
532 | ++ if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) | |
533 | ++ return NULL; | |
534 | ++ | |
535 | ++ ghdr = &elf_section_data (group)->this_hdr; | |
536 | ++ if (ghdr->sh_link < elf_numsections (abfd)) | |
537 | ++ { | |
538 | ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); | |
539 | ++ Elf_Internal_Shdr *symhdr = elf_elfsections (abfd) [ghdr->sh_link]; | |
540 | ++ | |
541 | ++ if (symhdr->sh_type == SHT_SYMTAB | |
542 | ++ && ghdr->sh_info < symhdr->sh_size / bed->s->sizeof_sym) | |
543 | ++ return isympp[ghdr->sh_info - 1]; | |
544 | ++ } | |
545 | ++ return NULL; | |
546 | ++} | |
547 | +diff --git a/bfd/elf.c b/bfd/elf.c | |
548 | +index 8df38ee..9a01711 100644 | |
549 | +--- a/bfd/elf.c | |
550 | ++++ b/bfd/elf.c | |
551 | +@@ -2096,6 +2096,7 @@ static const struct bfd_elf_special_section special_sections_g[] = | |
552 | + { STRING_COMMA_LEN (".gnu.linkonce.b"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, | |
553 | + { STRING_COMMA_LEN (".gnu.lto_"), -1, SHT_PROGBITS, SHF_EXCLUDE }, | |
554 | + { STRING_COMMA_LEN (".got"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, | |
555 | ++ { STRING_COMMA_LEN (".gnu_object_only"), 0, SHT_GNU_OBJECT_ONLY, SHF_EXCLUDE }, | |
556 | + { STRING_COMMA_LEN (".gnu.version"), 0, SHT_GNU_versym, 0 }, | |
557 | + { STRING_COMMA_LEN (".gnu.version_d"), 0, SHT_GNU_verdef, 0 }, | |
558 | + { STRING_COMMA_LEN (".gnu.version_r"), 0, SHT_GNU_verneed, 0 }, | |
559 | +diff --git a/bfd/elflink.c b/bfd/elflink.c | |
560 | +index 1e6abd9..e1803bd 100644 | |
561 | +--- a/bfd/elflink.c | |
562 | ++++ b/bfd/elflink.c | |
563 | +@@ -2437,6 +2437,20 @@ _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h, | |
564 | + } | |
565 | + else | |
566 | + { | |
567 | ++ /* If a plugin symbol is referenced from a non-IR file, mark | |
568 | ++ the symbol as undefined, except for symbol for linker | |
569 | ++ created section. */ | |
570 | ++ if (h->root.non_ir_ref | |
571 | ++ && (h->root.type == bfd_link_hash_defined | |
572 | ++ || h->root.type == bfd_link_hash_defweak) | |
573 | ++ && (h->root.u.def.section->flags & SEC_LINKER_CREATED) == 0 | |
574 | ++ && h->root.u.def.section->owner != NULL | |
575 | ++ && (h->root.u.def.section->owner->flags & BFD_PLUGIN) != 0) | |
576 | ++ { | |
577 | ++ h->root.type = bfd_link_hash_undefined; | |
578 | ++ h->root.u.undef.abfd = h->root.u.def.section->owner; | |
579 | ++ } | |
580 | ++ | |
581 | + /* Unfortunately, NON_ELF is only correct if the symbol | |
582 | + was first seen in a non-ELF file. Fortunately, if the symbol | |
583 | + was first seen in an ELF file, we're probably OK unless the | |
584 | +@@ -5061,6 +5075,9 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) | |
585 | + something wrong with the archive. */ | |
586 | + if (element->archive_pass != 0) | |
587 | + { | |
588 | ++ /* Don't load the IR archive member twice. */ | |
589 | ++ if (element->lto_type == lto_ir_object) | |
590 | ++ continue; | |
591 | + bfd_set_error (bfd_error_bad_value); | |
592 | + goto error_return; | |
593 | + } | |
594 | +diff --git a/bfd/format.c b/bfd/format.c | |
595 | +index b8f39ca..b0fb483 100644 | |
596 | +--- a/bfd/format.c | |
597 | ++++ b/bfd/format.c | |
598 | +@@ -180,6 +180,33 @@ bfd_preserve_finish (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_preserve *preserve) | |
599 | + preserve->marker = NULL; | |
600 | + } | |
601 | + | |
602 | ++/* Set lto_type in ABFD. */ | |
603 | ++ | |
604 | ++static void | |
605 | ++bfd_set_lto_type (bfd *abfd) | |
606 | ++{ | |
607 | ++ if (abfd->format == bfd_object | |
608 | ++ && abfd->lto_type == lto_non_object | |
609 | ++ && (abfd->flags & (DYNAMIC | EXEC_P)) == 0) | |
610 | ++ { | |
611 | ++ asection *sec; | |
612 | ++ enum bfd_lto_object_type type = lto_non_ir_object; | |
613 | ++ for (sec = abfd->sections; sec != NULL; sec = sec->next) | |
614 | ++ { | |
615 | ++ if (strcmp (sec->name, GNU_OBJECT_ONLY_SECTION_NAME) == 0) | |
616 | ++ { | |
617 | ++ type = lto_mixed_object; | |
618 | ++ abfd->object_only_section = sec; | |
619 | ++ break; | |
620 | ++ } | |
621 | ++ else if (type != lto_ir_object | |
622 | ++ && strncmp (sec->name, ".gnu.lto_", 9) == 0) | |
623 | ++ type = lto_ir_object; | |
624 | ++ } | |
625 | ++ abfd->lto_type = type; | |
626 | ++ } | |
627 | ++} | |
628 | ++ | |
629 | + /* | |
630 | + FUNCTION | |
631 | + bfd_check_format_matches | |
632 | +@@ -222,7 +249,10 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) | |
633 | + } | |
634 | + | |
635 | + if (abfd->format != bfd_unknown) | |
636 | +- return abfd->format == format; | |
637 | ++ { | |
638 | ++ bfd_set_lto_type (abfd); | |
639 | ++ return abfd->format == format; | |
640 | ++ } | |
641 | + | |
642 | + if (matching != NULL || *bfd_associated_vector != NULL) | |
643 | + { | |
644 | +@@ -450,6 +480,8 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) | |
645 | + if (matching_vector) | |
646 | + free (matching_vector); | |
647 | + | |
648 | ++ bfd_set_lto_type (abfd); | |
649 | ++ | |
650 | + /* File position has moved, BTW. */ | |
651 | + return TRUE; | |
652 | + } | |
653 | +diff --git a/bfd/opncls.c b/bfd/opncls.c | |
654 | +index 3f09420..911d7bf 100644 | |
655 | +--- a/bfd/opncls.c | |
656 | ++++ b/bfd/opncls.c | |
657 | +@@ -1659,3 +1659,69 @@ bfd_fill_in_gnu_debuglink_section (bfd *abfd, | |
658 | + | |
659 | + return TRUE; | |
660 | + } | |
661 | ++ | |
662 | ++/* | |
663 | ++FUNCTION | |
664 | ++ bfd_extract_object_only_section | |
665 | ++ | |
666 | ++SYNOPSIS | |
667 | ++ const char *bfd_extract_object_only_section | |
668 | ++ (bfd *abfd); | |
669 | ++ | |
670 | ++DESCRIPTION | |
671 | ++ | |
672 | ++ Takes a @var{ABFD} and extract the .gnu_object_only section into | |
673 | ++ a temporary file. | |
674 | ++ | |
675 | ++RETURNS | |
676 | ++ The name of the temporary file is returned if all is ok. | |
677 | ++ Otherwise <<NULL>> is returned and bfd_error is set. | |
678 | ++*/ | |
679 | ++ | |
680 | ++const char * | |
681 | ++bfd_extract_object_only_section (bfd *abfd) | |
682 | ++{ | |
683 | ++ asection *sec = abfd->object_only_section; | |
684 | ++ const char *name; | |
685 | ++ FILE *file; | |
686 | ++ bfd_byte *memhunk = NULL; | |
687 | ++ size_t off, size; | |
688 | ++ bfd_error_type err; | |
689 | ++ | |
690 | ++ /* Get a temporary object-only file. */ | |
691 | ++ name = make_temp_file (".obj-only.o"); | |
692 | ++ | |
693 | ++ /* Open the object-only file. */ | |
694 | ++ file = real_fopen (name, FOPEN_WB); | |
695 | ++ if (!bfd_get_full_section_contents (abfd, sec, &memhunk)) | |
696 | ++ { | |
697 | ++ err = bfd_get_error (); | |
698 | ++ | |
699 | ++loser: | |
700 | ++ free (memhunk); | |
701 | ++ fclose (file); | |
702 | ++ unlink (name); | |
703 | ++ bfd_set_error (err); | |
704 | ++ return NULL; | |
705 | ++ } | |
706 | ++ | |
707 | ++ off = 0; | |
708 | ++ size = sec->size; | |
709 | ++ while (off != size) | |
710 | ++ { | |
711 | ++ size_t written, nwrite = size - off; | |
712 | ++ | |
713 | ++ written = fwrite (memhunk + off, 1, nwrite, file); | |
714 | ++ if (written < nwrite && ferror (file)) | |
715 | ++ { | |
716 | ++ err = bfd_error_system_call; | |
717 | ++ goto loser; | |
718 | ++ } | |
719 | ++ | |
720 | ++ off += written; | |
721 | ++ } | |
722 | ++ | |
723 | ++ free (memhunk); | |
724 | ++ fclose (file); | |
725 | ++ return name; | |
726 | ++} | |
727 | +diff --git a/bfd/plugin.c b/bfd/plugin.c | |
728 | +index 3306607..9d169a4 100644 | |
729 | +--- a/bfd/plugin.c | |
730 | ++++ b/bfd/plugin.c | |
731 | +@@ -130,6 +130,139 @@ register_claim_file (ld_plugin_claim_file_handler handler) | |
732 | + return LDPS_OK; | |
733 | + } | |
734 | + | |
735 | ++static asection bfd_plugin_fake_text_section | |
736 | ++ = BFD_FAKE_SECTION (bfd_plugin_fake_text_section, 0, 0, ".text", 0); | |
737 | ++static asection bfd_plugin_fake_common_section | |
738 | ++ = BFD_FAKE_SECTION (bfd_plugin_fake_common_section, SEC_IS_COMMON, 0, | |
739 | ++ NULL, 0); | |
740 | ++ | |
741 | ++/* Get symbols from object only section. */ | |
742 | ++ | |
743 | ++static void | |
744 | ++bfd_plugin_get_symbols_in_object_only (bfd *abfd) | |
745 | ++{ | |
746 | ++ struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data; | |
747 | ++ const char *object_only_file; | |
748 | ++ bfd *nbfd; | |
749 | ++ long storage; | |
750 | ++ long object_only_nsyms, added_nsyms, i; | |
751 | ++ asymbol **object_only_syms, **added_syms; | |
752 | ++ | |
753 | ++ plugin_data->object_only_syms = NULL; | |
754 | ++ plugin_data->object_only_nsyms = 0; | |
755 | ++ | |
756 | ++ if (abfd->sections == NULL && abfd->my_archive == NULL) | |
757 | ++ { | |
758 | ++ nbfd = bfd_openr (abfd->filename, NULL); | |
759 | ++ if (nbfd == NULL || !bfd_check_format (nbfd, bfd_object)) | |
760 | ++ { | |
761 | ++ (*_bfd_error_handler) | |
762 | ++ (_("%s: failed to open to extract object only section: %s"), | |
763 | ++ abfd->filename, bfd_errmsg (bfd_get_error ())); | |
764 | ++ bfd_close (nbfd); | |
765 | ++ return; | |
766 | ++ } | |
767 | ++ } | |
768 | ++ else | |
769 | ++ { | |
770 | ++ if (!bfd_check_format (abfd, bfd_object)) | |
771 | ++ { | |
772 | ++ (*_bfd_error_handler) | |
773 | ++ (_("%B: invalid file to extract object only section: %s"), | |
774 | ++ abfd, bfd_errmsg (bfd_get_error ())); | |
775 | ++ return; | |
776 | ++ } | |
777 | ++ nbfd = abfd; | |
778 | ++ } | |
779 | ++ | |
780 | ++ if (nbfd->lto_type == lto_mixed_object | |
781 | ++ && (nbfd->flags & HAS_SYMS) != 0) | |
782 | ++ { | |
783 | ++ object_only_file = bfd_extract_object_only_section (nbfd); | |
784 | ++ if (object_only_file == NULL) | |
785 | ++ (*_bfd_error_handler) | |
786 | ++ (_("%B: failed to extract object only section: %s"), | |
787 | ++ abfd, bfd_errmsg (bfd_get_error ())); | |
788 | ++ } | |
789 | ++ else | |
790 | ++ object_only_file = NULL; | |
791 | ++ | |
792 | ++ /* Close the new bfd we just opened. */ | |
793 | ++ if (nbfd != abfd) | |
794 | ++ bfd_close (nbfd); | |
795 | ++ | |
796 | ++ /* Return if there is no object only section or there is no | |
797 | ++ symbol in object only section. */ | |
798 | ++ if (!object_only_file) | |
799 | ++ return; | |
800 | ++ | |
801 | ++ /* Open the file containing object only section. */ | |
802 | ++ nbfd = bfd_openr (object_only_file, NULL); | |
803 | ++ if (!bfd_check_format (nbfd, bfd_object)) | |
804 | ++ { | |
805 | ++ (*_bfd_error_handler) | |
806 | ++ (_("%B: failed to open object only section: %s"), | |
807 | ++ abfd, bfd_errmsg (bfd_get_error ())); | |
808 | ++ goto quit; | |
809 | ++ } | |
810 | ++ | |
811 | ++ storage = bfd_get_symtab_upper_bound (nbfd); | |
812 | ++ if (storage <= 0) | |
813 | ++ { | |
814 | ++ if (storage < 0) | |
815 | ++ (*_bfd_error_handler) | |
816 | ++ (_("%B: failed to get symbol table in object only section: %s"), | |
817 | ++ abfd, bfd_errmsg (bfd_get_error ())); | |
818 | ++ | |
819 | ++ goto quit; | |
820 | ++ } | |
821 | ++ | |
822 | ++ object_only_syms = (asymbol **) bfd_malloc (storage); | |
823 | ++ object_only_nsyms = bfd_canonicalize_symtab (nbfd, object_only_syms); | |
824 | ++ | |
825 | ++ /* FIXME: We waste some spaces if not all symbols are copied. */ | |
826 | ++ added_syms = (asymbol **) bfd_alloc (abfd, storage); | |
827 | ++ added_nsyms = 0; | |
828 | ++ | |
829 | ++ /* Copy only global symbols from object only section. */ | |
830 | ++ for (i = 0; i < object_only_nsyms; i++) | |
831 | ++ { | |
832 | ++ asection *sec = object_only_syms[i]->section; | |
833 | ++ flagword flags = object_only_syms[i]->flags; | |
834 | ++ asymbol *s; | |
835 | ++ | |
836 | ++ if (bfd_is_com_section (sec)) | |
837 | ++ sec = &bfd_plugin_fake_common_section; | |
838 | ++ else if (bfd_is_und_section (sec)) | |
839 | ++ ; | |
840 | ++ else if ((flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0) | |
841 | ++ sec = &bfd_plugin_fake_text_section; | |
842 | ++ else | |
843 | ++ continue; | |
844 | ++ | |
845 | ++ s = bfd_alloc (abfd, sizeof (asymbol)); | |
846 | ++ BFD_ASSERT (s); | |
847 | ++ added_syms[added_nsyms++] = s; | |
848 | ++ | |
849 | ++ s->section = sec; | |
850 | ++ s->the_bfd = abfd; | |
851 | ++ s->name = xstrdup (object_only_syms[i]->name); | |
852 | ++ s->value = 0; | |
853 | ++ s->flags = flags; | |
854 | ++ s->udata.p = NULL; | |
855 | ++ } | |
856 | ++ | |
857 | ++ plugin_data->object_only_syms = added_syms; | |
858 | ++ plugin_data->object_only_nsyms = added_nsyms; | |
859 | ++ | |
860 | ++ free (object_only_syms); | |
861 | ++ | |
862 | ++quit: | |
863 | ++ /* Close and remove the object only section file. */ | |
864 | ++ bfd_close (nbfd); | |
865 | ++ unlink (object_only_file); | |
866 | ++} | |
867 | ++ | |
868 | + static enum ld_plugin_status | |
869 | + add_symbols (void * handle, | |
870 | + int nsyms, | |
871 | +@@ -142,10 +275,13 @@ add_symbols (void * handle, | |
872 | + plugin_data->nsyms = nsyms; | |
873 | + plugin_data->syms = syms; | |
874 | + | |
875 | +- if (nsyms != 0) | |
876 | ++ abfd->tdata.plugin_data = plugin_data; | |
877 | ++ | |
878 | ++ bfd_plugin_get_symbols_in_object_only (abfd); | |
879 | ++ | |
880 | ++ if ((nsyms + plugin_data->object_only_nsyms) != 0) | |
881 | + abfd->flags |= HAS_SYMS; | |
882 | + | |
883 | +- abfd->tdata.plugin_data = plugin_data; | |
884 | + return LDPS_OK; | |
885 | + } | |
886 | + | |
887 | +@@ -389,7 +525,8 @@ static long | |
888 | + bfd_plugin_get_symtab_upper_bound (bfd *abfd) | |
889 | + { | |
890 | + struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data; | |
891 | +- long nsyms = plugin_data->nsyms; | |
892 | ++ /* Add symbols from object only section. */ | |
893 | ++ long nsyms = plugin_data->nsyms + plugin_data->object_only_nsyms; | |
894 | + | |
895 | + BFD_ASSERT (nsyms >= 0); | |
896 | + | |
897 | +@@ -423,12 +560,7 @@ bfd_plugin_canonicalize_symtab (bfd *abfd, | |
898 | + struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data; | |
899 | + long nsyms = plugin_data->nsyms; | |
900 | + const struct ld_plugin_symbol *syms = plugin_data->syms; | |
901 | +- static asection fake_section; | |
902 | +- static asection fake_common_section; | |
903 | +- int i; | |
904 | +- | |
905 | +- fake_section.name = ".text"; | |
906 | +- fake_common_section.flags = SEC_IS_COMMON; | |
907 | ++ int i, j; | |
908 | + | |
909 | + for (i = 0; i < nsyms; i++) | |
910 | + { | |
911 | +@@ -441,10 +573,11 @@ bfd_plugin_canonicalize_symtab (bfd *abfd, | |
912 | + s->name = syms[i].name; | |
913 | + s->value = 0; | |
914 | + s->flags = convert_flags (&syms[i]); | |
915 | ++ s->udata.p = NULL; | |
916 | + switch (syms[i].def) | |
917 | + { | |
918 | + case LDPK_COMMON: | |
919 | +- s->section = &fake_common_section; | |
920 | ++ s->section = &bfd_plugin_fake_common_section; | |
921 | + break; | |
922 | + case LDPK_UNDEF: | |
923 | + case LDPK_WEAKUNDEF: | |
924 | +@@ -452,15 +585,18 @@ bfd_plugin_canonicalize_symtab (bfd *abfd, | |
925 | + break; | |
926 | + case LDPK_DEF: | |
927 | + case LDPK_WEAKDEF: | |
928 | +- s->section = &fake_section; | |
929 | ++ s->section = &bfd_plugin_fake_text_section; | |
930 | + break; | |
931 | + default: | |
932 | + BFD_ASSERT (0); | |
933 | + } | |
934 | +- | |
935 | +- s->udata.p = (void *) &syms[i]; | |
936 | + } | |
937 | + | |
938 | ++ /* Copy symbols from object only section. */ | |
939 | ++ nsyms += plugin_data->object_only_nsyms; | |
940 | ++ for (j = 0; j < plugin_data->object_only_nsyms; j++, i++) | |
941 | ++ alocation[i] = plugin_data->object_only_syms[j]; | |
942 | ++ | |
943 | + return nsyms; | |
944 | + } | |
945 | + | |
946 | +diff --git a/bfd/plugin.h b/bfd/plugin.h | |
947 | +index 3091f97..2db087f 100644 | |
948 | +--- a/bfd/plugin.h | |
949 | ++++ b/bfd/plugin.h | |
950 | +@@ -30,6 +30,8 @@ typedef struct plugin_data_struct | |
951 | + { | |
952 | + int nsyms; | |
953 | + const struct ld_plugin_symbol *syms; | |
954 | ++ int object_only_nsyms; | |
955 | ++ asymbol **object_only_syms; | |
956 | + } | |
957 | + plugin_data_struct; | |
958 | + | |
959 | +diff --git a/bfd/section.c b/bfd/section.c | |
960 | +index fb19d8c..bff4c92 100644 | |
961 | +--- a/bfd/section.c | |
962 | ++++ b/bfd/section.c | |
963 | +@@ -552,6 +552,9 @@ CODE_FRAGMENT | |
964 | + .#define BFD_COM_SECTION_NAME "*COM*" | |
965 | + .#define BFD_IND_SECTION_NAME "*IND*" | |
966 | + . | |
967 | ++.{* GNU object-only section name. *} | |
968 | ++.#define GNU_OBJECT_ONLY_SECTION_NAME ".gnu_object_only" | |
969 | ++. | |
970 | + .{* Pointer to the common section. *} | |
971 | + .#define bfd_com_section_ptr (&_bfd_std_section[0]) | |
972 | + .{* Pointer to the undefined section. *} | |
973 | +diff --git a/binutils/objcopy.c b/binutils/objcopy.c | |
974 | +index 14f6b96..8d90346 100644 | |
975 | +--- a/binutils/objcopy.c | |
976 | ++++ b/binutils/objcopy.c | |
977 | +@@ -1003,30 +1003,6 @@ is_specified_symbol (const char *name, htab_t htab) | |
978 | + return htab_find (htab, name) != NULL; | |
979 | + } | |
980 | + | |
981 | +-/* Return a pointer to the symbol used as a signature for GROUP. */ | |
982 | +- | |
983 | +-static asymbol * | |
984 | +-group_signature (asection *group) | |
985 | +-{ | |
986 | +- bfd *abfd = group->owner; | |
987 | +- Elf_Internal_Shdr *ghdr; | |
988 | +- | |
989 | +- if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) | |
990 | +- return NULL; | |
991 | +- | |
992 | +- ghdr = &elf_section_data (group)->this_hdr; | |
993 | +- if (ghdr->sh_link < elf_numsections (abfd)) | |
994 | +- { | |
995 | +- const struct elf_backend_data *bed = get_elf_backend_data (abfd); | |
996 | +- Elf_Internal_Shdr *symhdr = elf_elfsections (abfd) [ghdr->sh_link]; | |
997 | +- | |
998 | +- if (symhdr->sh_type == SHT_SYMTAB | |
999 | +- && ghdr->sh_info < symhdr->sh_size / bed->s->sizeof_sym) | |
1000 | +- return isympp[ghdr->sh_info - 1]; | |
1001 | +- } | |
1002 | +- return NULL; | |
1003 | +-} | |
1004 | +- | |
1005 | + /* Return TRUE if the section is a DWO section. */ | |
1006 | + | |
1007 | + static bfd_boolean | |
1008 | +@@ -1108,7 +1084,7 @@ is_strip_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec) | |
1009 | + /* PR binutils/3181 | |
1010 | + If we are going to strip the group signature symbol, then | |
1011 | + strip the group section too. */ | |
1012 | +- gsym = group_signature (sec); | |
1013 | ++ gsym = bfd_group_signature (sec, isympp); | |
1014 | + if (gsym != NULL) | |
1015 | + gname = gsym->name; | |
1016 | + else | |
1017 | +@@ -2722,7 +2698,7 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg) | |
1018 | + | |
1019 | + if ((isection->flags & SEC_GROUP) != 0) | |
1020 | + { | |
1021 | +- asymbol *gsym = group_signature (isection); | |
1022 | ++ asymbol *gsym = bfd_group_signature (isection, isympp); | |
1023 | + | |
1024 | + if (gsym != NULL) | |
1025 | + { | |
1026 | +diff --git a/binutils/readelf.c b/binutils/readelf.c | |
1027 | +index 0389f14..4781574 100644 | |
1028 | +--- a/binutils/readelf.c | |
1029 | ++++ b/binutils/readelf.c | |
1030 | +@@ -3312,6 +3312,7 @@ get_section_type_name (unsigned int sh_type) | |
1031 | + case 0x7ffffffd: return "AUXILIARY"; | |
1032 | + case 0x7fffffff: return "FILTER"; | |
1033 | + case SHT_GNU_LIBLIST: return "GNU_LIBLIST"; | |
1034 | ++ case SHT_GNU_OBJECT_ONLY: return "GNU_OBJECT_ONLY"; | |
1035 | + | |
1036 | + default: | |
1037 | + if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC)) | |
1038 | +diff --git a/gas/testsuite/gas/elf/section9.d b/gas/testsuite/gas/elf/section9.d | |
1039 | +index 1acf63e..bb66fa5 100644 | |
1040 | +--- a/gas/testsuite/gas/elf/section9.d | |
1041 | ++++ b/gas/testsuite/gas/elf/section9.d | |
1042 | +@@ -4,4 +4,5 @@ | |
1043 | + #... | |
1044 | + [ ]*\[.*\][ ]+\.gnu\.lto_main[ ]+PROGBITS.*[ ]+E[ ]+.* | |
1045 | + [ ]*\[.*\][ ]+\.gnu\.lto_\.pureconst[ ]+PROGBITS.*[ ]+E[ ]+.* | |
1046 | ++[ ]*\[.*\][ ]+\.gnu_object_only[ ]+GNU_OBJECT_ONLY.*[ ]+E[ ]+.* | |
1047 | + #pass | |
1048 | +diff --git a/gas/testsuite/gas/elf/section9.s b/gas/testsuite/gas/elf/section9.s | |
1049 | +index 6b8b107..abcdea1 100644 | |
1050 | +--- a/gas/testsuite/gas/elf/section9.s | |
1051 | ++++ b/gas/testsuite/gas/elf/section9.s | |
1052 | +@@ -2,3 +2,5 @@ | |
1053 | + .byte 0,0,0,0 | |
1054 | + .section .gnu.lto_.pureconst,"",%progbits | |
1055 | + .byte 0,0,0,0 | |
1056 | ++ .section .gnu_object_only | |
1057 | ++ .byte 0,0,0,0 | |
1058 | +diff --git a/include/bfdlink.h b/include/bfdlink.h | |
1059 | +index 1ac0738..c590771 100644 | |
1060 | +--- a/include/bfdlink.h | |
1061 | ++++ b/include/bfdlink.h | |
1062 | +@@ -380,6 +380,12 @@ struct bfd_link_info | |
1063 | + /* TRUE if ok to have multiple definition. */ | |
1064 | + unsigned int allow_multiple_definition: 1; | |
1065 | + | |
1066 | ++ /* TRUE if .gnu_object_only section should be created. */ | |
1067 | ++ unsigned int emit_gnu_object_only: 1; | |
1068 | ++ | |
1069 | ++ /* TRUE if .gnu_object_only section is being created. */ | |
1070 | ++ unsigned int emitting_gnu_object_only: 1; | |
1071 | ++ | |
1072 | + /* TRUE if ok to have version with no definition. */ | |
1073 | + unsigned int allow_undefined_version: 1; | |
1074 | + | |
1075 | +diff --git a/include/elf/common.h b/include/elf/common.h | |
1076 | +index cd3bcdd..decd37f 100644 | |
1077 | +--- a/include/elf/common.h | |
1078 | ++++ b/include/elf/common.h | |
1079 | +@@ -475,6 +475,7 @@ | |
1080 | + #define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes */ | |
1081 | + #define SHT_GNU_HASH 0x6ffffff6 /* GNU style symbol hash table */ | |
1082 | + #define SHT_GNU_LIBLIST 0x6ffffff7 /* List of prelink dependencies */ | |
1083 | ++#define SHT_GNU_OBJECT_ONLY 0x6ffffff8 /* Object only */ | |
1084 | + | |
1085 | + /* The next three section types are defined by Solaris, and are named | |
1086 | + SHT_SUNW*. We use them in GNU code, so we also define SHT_GNU* | |
1087 | +diff --git a/ld/emultempl/aarch64elf.em b/ld/emultempl/aarch64elf.em | |
1088 | +index b3279bf..54b9460 100644 | |
1089 | +--- a/ld/emultempl/aarch64elf.em | |
1090 | ++++ b/ld/emultempl/aarch64elf.em | |
1091 | +@@ -264,7 +264,7 @@ gld${EMULATION_NAME}_after_allocation (void) | |
1092 | + } | |
1093 | + | |
1094 | + static void | |
1095 | +-gld${EMULATION_NAME}_finish (void) | |
1096 | ++aarch64_finish (void) | |
1097 | + { | |
1098 | + if (! link_info.relocatable) | |
1099 | + { | |
1100 | +@@ -276,7 +276,7 @@ gld${EMULATION_NAME}_finish (void) | |
1101 | + } | |
1102 | + } | |
1103 | + | |
1104 | +- finish_default (); | |
1105 | ++ gld${EMULATION_NAME}_finish (); | |
1106 | + } | |
1107 | + | |
1108 | + /* This is a convenient point to tell BFD about target specific flags. | |
1109 | +@@ -413,4 +413,4 @@ LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=aarch64_elf_create_output_section_statem | |
1110 | + LDEMUL_BEFORE_PARSE=gld"${EMULATION_NAME}"_before_parse | |
1111 | + | |
1112 | + # Call the extra arm-elf function | |
1113 | +-LDEMUL_FINISH=gld${EMULATION_NAME}_finish | |
1114 | ++LDEMUL_FINISH=aarch64_finish | |
1115 | +diff --git a/ld/emultempl/alphaelf.em b/ld/emultempl/alphaelf.em | |
1116 | +index 21064ad..ec0965a 100644 | |
1117 | +--- a/ld/emultempl/alphaelf.em | |
1118 | ++++ b/ld/emultempl/alphaelf.em | |
1119 | +@@ -100,7 +100,7 @@ alpha_finish (void) | |
1120 | + if (limit_32bit) | |
1121 | + elf_elfheader (link_info.output_bfd)->e_flags |= EF_ALPHA_32BIT; | |
1122 | + | |
1123 | +- finish_default (); | |
1124 | ++ gld${EMULATION_NAME}_finish (); | |
1125 | + } | |
1126 | + EOF | |
1127 | + | |
1128 | +diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em | |
1129 | +index eee6af1..dda213e 100644 | |
1130 | +--- a/ld/emultempl/armelf.em | |
1131 | ++++ b/ld/emultempl/armelf.em | |
1132 | +@@ -365,7 +365,7 @@ gld${EMULATION_NAME}_after_allocation (void) | |
1133 | + } | |
1134 | + | |
1135 | + static void | |
1136 | +-gld${EMULATION_NAME}_finish (void) | |
1137 | ++arm_finish (void) | |
1138 | + { | |
1139 | + struct bfd_link_hash_entry * h; | |
1140 | + | |
1141 | +@@ -388,7 +388,7 @@ gld${EMULATION_NAME}_finish (void) | |
1142 | + } | |
1143 | + } | |
1144 | + | |
1145 | +- finish_default (); | |
1146 | ++ gld${EMULATION_NAME}_finish (); | |
1147 | + | |
1148 | + if (thumb_entry_symbol) | |
1149 | + { | |
1150 | +@@ -689,4 +689,4 @@ LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=arm_elf_create_output_section_statements | |
1151 | + LDEMUL_BEFORE_PARSE=gld"${EMULATION_NAME}"_before_parse | |
1152 | + | |
1153 | + # Call the extra arm-elf function | |
1154 | +-LDEMUL_FINISH=gld${EMULATION_NAME}_finish | |
1155 | ++LDEMUL_FINISH=arm_finish | |
1156 | +diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em | |
1157 | +index 682f5e5..69fcc60 100644 | |
1158 | +--- a/ld/emultempl/elf32.em | |
1159 | ++++ b/ld/emultempl/elf32.em | |
1160 | +@@ -68,6 +68,7 @@ static void gld${EMULATION_NAME}_before_allocation (void); | |
1161 | + static void gld${EMULATION_NAME}_after_allocation (void); | |
1162 | + static lang_output_section_statement_type *gld${EMULATION_NAME}_place_orphan | |
1163 | + (asection *, const char *, int); | |
1164 | ++static void gld${EMULATION_NAME}_finish (void); | |
1165 | + EOF | |
1166 | + | |
1167 | + if [ "x${USE_LIBPATH}" = xyes ] ; then | |
1168 | +@@ -1761,6 +1762,8 @@ output_rel_find (asection *sec, int isdyn) | |
1169 | + return last; | |
1170 | + } | |
1171 | + | |
1172 | ++static int orphan_init_done = 0; | |
1173 | ++ | |
1174 | + /* Place an orphan section. We use this to put random SHF_ALLOC | |
1175 | + sections in the right segment. */ | |
1176 | + | |
1177 | +@@ -1769,7 +1772,7 @@ gld${EMULATION_NAME}_place_orphan (asection *s, | |
1178 | + const char *secname, | |
1179 | + int constraint) | |
1180 | + { | |
1181 | +- static struct orphan_save hold[] = | |
1182 | ++ static struct orphan_save orig_hold[] = | |
1183 | + { | |
1184 | + { ".text", | |
1185 | + SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE, | |
1186 | +@@ -1796,6 +1799,7 @@ gld${EMULATION_NAME}_place_orphan (asection *s, | |
1187 | + SEC_HAS_CONTENTS, | |
1188 | + 0, 0, 0, 0 }, | |
1189 | + }; | |
1190 | ++ static struct orphan_save hold[ARRAY_SIZE (orig_hold)]; | |
1191 | + enum orphan_save_index | |
1192 | + { | |
1193 | + orphan_text = 0, | |
1194 | +@@ -1807,7 +1811,6 @@ gld${EMULATION_NAME}_place_orphan (asection *s, | |
1195 | + orphan_sdata, | |
1196 | + orphan_nonalloc | |
1197 | + }; | |
1198 | +- static int orphan_init_done = 0; | |
1199 | + struct orphan_save *place; | |
1200 | + lang_output_section_statement_type *after; | |
1201 | + lang_output_section_statement_type *os; | |
1202 | +@@ -1884,15 +1887,22 @@ gld${EMULATION_NAME}_place_orphan (asection *s, | |
1203 | + | |
1204 | + if (!orphan_init_done) | |
1205 | + { | |
1206 | +- struct orphan_save *ho; | |
1207 | ++ struct orphan_save *ho, *horig; | |
1208 | + | |
1209 | + for (ho = hold; ho < hold + sizeof (hold) / sizeof (hold[0]); ++ho) | |
1210 | ++ for (ho = hold, horig = orig_hold; | |
1211 | ++ ho < hold + ARRAY_SIZE (hold); | |
1212 | ++ ++ho, ++horig) | |
1213 | ++ { | |
1214 | ++ *ho = *horig; | |
1215 | ++ if (ho->name != NULL) | |
1216 | + if (ho->name != NULL) | |
1217 | + { | |
1218 | + ho->os = lang_output_section_find (ho->name); | |
1219 | + if (ho->os != NULL && ho->os->flags == 0) | |
1220 | + ho->os->flags = ho->flags; | |
1221 | + } | |
1222 | ++ } | |
1223 | + orphan_init_done = 1; | |
1224 | + } | |
1225 | + | |
1226 | +@@ -1962,6 +1972,27 @@ gld${EMULATION_NAME}_place_orphan (asection *s, | |
1227 | + EOF | |
1228 | + fi | |
1229 | + | |
1230 | ++fragment <<EOF | |
1231 | ++ | |
1232 | ++/* Final emulation specific call. */ | |
1233 | ++ | |
1234 | ++static void | |
1235 | ++gld${EMULATION_NAME}_finish (void) | |
1236 | ++{ | |
1237 | ++EOF | |
1238 | ++if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then | |
1239 | ++fragment <<EOF | |
1240 | ++ /* Support the object-only output. */ | |
1241 | ++ if (link_info.emit_gnu_object_only) | |
1242 | ++ orphan_init_done = 0; | |
1243 | ++ | |
1244 | ++EOF | |
1245 | ++fi | |
1246 | ++fragment <<EOF | |
1247 | ++ finish_default (); | |
1248 | ++} | |
1249 | ++EOF | |
1250 | ++ | |
1251 | + if test x"$LDEMUL_AFTER_ALLOCATION" != xgld"$EMULATION_NAME"_after_allocation; then | |
1252 | + fragment <<EOF | |
1253 | + | |
1254 | +@@ -2512,7 +2543,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = | |
1255 | + ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script}, | |
1256 | + "${EMULATION_NAME}", | |
1257 | + "${OUTPUT_FORMAT}", | |
1258 | +- ${LDEMUL_FINISH-finish_default}, | |
1259 | ++ ${LDEMUL_FINISH-gld${EMULATION_NAME}_finish}, | |
1260 | + ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL}, | |
1261 | + ${LDEMUL_OPEN_DYNAMIC_ARCHIVE-gld${EMULATION_NAME}_open_dynamic_archive}, | |
1262 | + ${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan}, | |
1263 | +diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em | |
1264 | +index f2085d7..00398bb 100644 | |
1265 | +--- a/ld/emultempl/ppc64elf.em | |
1266 | ++++ b/ld/emultempl/ppc64elf.em | |
1267 | +@@ -532,7 +532,7 @@ gld${EMULATION_NAME}_after_allocation (void) | |
1268 | + /* Final emulation specific call. */ | |
1269 | + | |
1270 | + static void | |
1271 | +-gld${EMULATION_NAME}_finish (void) | |
1272 | ++ppc_finish (void) | |
1273 | + { | |
1274 | + /* e_entry on PowerPC64 points to the function descriptor for | |
1275 | + _start. If _start is missing, default to the first function | |
1276 | +@@ -564,7 +564,7 @@ gld${EMULATION_NAME}_finish (void) | |
1277 | + } | |
1278 | + | |
1279 | + ppc64_elf_restore_symbols (&link_info); | |
1280 | +- finish_default (); | |
1281 | ++ gld${EMULATION_NAME}_finish (); | |
1282 | + } | |
1283 | + | |
1284 | + | |
1285 | +@@ -866,6 +866,6 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}' | |
1286 | + # | |
1287 | + LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation | |
1288 | + LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation | |
1289 | +-LDEMUL_FINISH=gld${EMULATION_NAME}_finish | |
1290 | ++LDEMUL_FINISH=ppc_finish | |
1291 | + LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_create_output_section_statements | |
1292 | + LDEMUL_NEW_VERS_PATTERN=gld${EMULATION_NAME}_new_vers_pattern | |
1293 | +diff --git a/ld/emultempl/spuelf.em b/ld/emultempl/spuelf.em | |
1294 | +index e14fa26..1dbc88a 100644 | |
1295 | +--- a/ld/emultempl/spuelf.em | |
1296 | ++++ b/ld/emultempl/spuelf.em | |
1297 | +@@ -416,7 +416,7 @@ spu_elf_relink (void) | |
1298 | + /* Final emulation specific call. */ | |
1299 | + | |
1300 | + static void | |
1301 | +-gld${EMULATION_NAME}_finish (void) | |
1302 | ++spu_finish (void) | |
1303 | + { | |
1304 | + if (is_spu_target ()) | |
1305 | + { | |
1306 | +@@ -432,7 +432,7 @@ gld${EMULATION_NAME}_finish (void) | |
1307 | + einfo ("%P: --auto-overlay ignored with zero local store range\n"); | |
1308 | + } | |
1309 | + | |
1310 | +- finish_default (); | |
1311 | ++ gld${EMULATION_NAME}_finish (); | |
1312 | + } | |
1313 | + | |
1314 | + static char * | |
1315 | +@@ -832,5 +832,5 @@ PARSE_AND_LIST_ARGS_CASES=' | |
1316 | + | |
1317 | + LDEMUL_AFTER_OPEN=spu_after_open | |
1318 | + LDEMUL_BEFORE_ALLOCATION=spu_before_allocation | |
1319 | +-LDEMUL_FINISH=gld${EMULATION_NAME}_finish | |
1320 | ++LDEMUL_FINISH=spu_finish | |
1321 | + LDEMUL_CHOOSE_TARGET=gld${EMULATION_NAME}_choose_target | |
1322 | +diff --git a/ld/ldfile.c b/ld/ldfile.c | |
1323 | +index 16baef8..2efbc56 100644 | |
1324 | +--- a/ld/ldfile.c | |
1325 | ++++ b/ld/ldfile.c | |
1326 | +@@ -319,7 +319,9 @@ success: | |
1327 | + plugin_maybe_claim (&file, entry); | |
1328 | + } | |
1329 | + } | |
1330 | ++ else | |
1331 | + #endif /* ENABLE_PLUGINS */ | |
1332 | ++ cmdline_check_object_only_section (entry->the_bfd, FALSE); | |
1333 | + | |
1334 | + /* It opened OK, the format checked out, and the plugins have had | |
1335 | + their chance to claim it, so this is success. */ | |
1336 | +diff --git a/ld/ldlang.c b/ld/ldlang.c | |
1337 | +index ba7f493..5ffc954 100644 | |
1338 | +--- a/ld/ldlang.c | |
1339 | ++++ b/ld/ldlang.c | |
1340 | +@@ -36,6 +36,7 @@ | |
1341 | + #include "ldctor.h" | |
1342 | + #include "ldfile.h" | |
1343 | + #include "ldemul.h" | |
1344 | ++#include "ldwrite.h" | |
1345 | + #include "fnmatch.h" | |
1346 | + #include "demangle.h" | |
1347 | + #include "hashtab.h" | |
1348 | +@@ -44,6 +45,9 @@ | |
1349 | + #include "plugin.h" | |
1350 | + #endif /* ENABLE_PLUGINS */ | |
1351 | + | |
1352 | ++/* FIXME: Put it here to avoid NAME conflict from ldgram.h. */ | |
1353 | ++#include "elf-bfd.h" | |
1354 | ++ | |
1355 | + #ifndef offsetof | |
1356 | + #define offsetof(TYPE, MEMBER) ((size_t) & (((TYPE*) 0)->MEMBER)) | |
1357 | + #endif | |
1358 | +@@ -67,6 +71,9 @@ static struct bfd_hash_table lang_definedness_table; | |
1359 | + static lang_statement_list_type *stat_save[10]; | |
1360 | + static lang_statement_list_type **stat_save_ptr = &stat_save[0]; | |
1361 | + static struct unique_sections *unique_section_list; | |
1362 | ++static cmdline_list_type cmdline_object_only_file_list; | |
1363 | ++static cmdline_list_type cmdline_object_only_archive_list; | |
1364 | ++static cmdline_list_type cmdline_temp_object_only_list; | |
1365 | + | |
1366 | + /* Forward declarations. */ | |
1367 | + static void exp_init_os (etree_type *); | |
1368 | +@@ -87,6 +94,10 @@ static void lang_record_phdrs (void); | |
1369 | + static void lang_do_version_exports_section (void); | |
1370 | + static void lang_finalize_version_expr_head | |
1371 | + (struct bfd_elf_version_expr_head *); | |
1372 | ++static void cmdline_lists_init (void); | |
1373 | ++static void cmdline_get_object_only_input_files (void); | |
1374 | ++static void print_cmdline_list (cmdline_union_type *); | |
1375 | ++static bfd_boolean cmdline_on_object_only_archive_list_p (bfd *); | |
1376 | + | |
1377 | + /* Exported variables. */ | |
1378 | + const char *output_target; | |
1379 | +@@ -1202,14 +1213,17 @@ output_section_statement_table_free (void) | |
1380 | + /* Build enough state so that the parser can build its tree. */ | |
1381 | + | |
1382 | + void | |
1383 | +-lang_init (void) | |
1384 | ++lang_init (bfd_boolean object_only) | |
1385 | + { | |
1386 | +- obstack_begin (&stat_obstack, 1000); | |
1387 | ++ if (!object_only) | |
1388 | ++ obstack_begin (&stat_obstack, 1000); | |
1389 | + | |
1390 | + stat_ptr = &statement_list; | |
1391 | + | |
1392 | + output_section_statement_table_init (); | |
1393 | + | |
1394 | ++ cmdline_lists_init (); | |
1395 | ++ | |
1396 | + lang_list_init (stat_ptr); | |
1397 | + | |
1398 | + lang_list_init (&input_file_chain); | |
1399 | +@@ -1228,18 +1242,20 @@ lang_init (void) | |
1400 | + simpler to re-use working machinery than using a linked list in terms | |
1401 | + of code-complexity here in ld, besides the initialization which just | |
1402 | + looks like other code here. */ | |
1403 | +- if (!bfd_hash_table_init_n (&lang_definedness_table, | |
1404 | +- lang_definedness_newfunc, | |
1405 | +- sizeof (struct lang_definedness_hash_entry), | |
1406 | +- 3)) | |
1407 | ++ if (!object_only | |
1408 | ++ && !bfd_hash_table_init_n (&lang_definedness_table, | |
1409 | ++ lang_definedness_newfunc, | |
1410 | ++ sizeof (struct lang_definedness_hash_entry), | |
1411 | ++ 3)) | |
1412 | + einfo (_("%P%F: can not create hash table: %E\n")); | |
1413 | + } | |
1414 | + | |
1415 | + void | |
1416 | +-lang_finish (void) | |
1417 | ++lang_finish (bfd_boolean object_only) | |
1418 | + { | |
1419 | + bfd_link_hash_table_free (link_info.output_bfd, link_info.hash); | |
1420 | +- bfd_hash_table_free (&lang_definedness_table); | |
1421 | ++ if (!object_only) | |
1422 | ++ bfd_hash_table_free (&lang_definedness_table); | |
1423 | + output_section_statement_table_free (); | |
1424 | + } | |
1425 | + | |
1426 | +@@ -2769,6 +2785,12 @@ load_symbols (lang_input_statement_type *entry, | |
1427 | + loaded = FALSE; | |
1428 | + } | |
1429 | + | |
1430 | ++ if (link_info.emitting_gnu_object_only) | |
1431 | ++ { | |
1432 | ++ if (!cmdline_on_object_only_archive_list_p (member)) | |
1433 | ++ continue; | |
1434 | ++ } | |
1435 | ++ | |
1436 | + subsbfd = member; | |
1437 | + if (!(*link_info.callbacks | |
1438 | + ->add_archive_element) (&link_info, member, | |
1439 | +@@ -6661,7 +6683,38 @@ lang_process (void) | |
1440 | + open_input_bfds (statement_list.head, OPEN_BFD_RESCAN); | |
1441 | + } | |
1442 | + } | |
1443 | ++ else | |
1444 | + #endif /* ENABLE_PLUGINS */ | |
1445 | ++ if (link_info.relocatable) | |
1446 | ++ { | |
1447 | ++ /* Check if .gnu_object_only section should be created. */ | |
1448 | ++ bfd *p; | |
1449 | ++ int object_type; | |
1450 | ++ | |
1451 | ++ object_type = 0; | |
1452 | ++ for (p = link_info.input_bfds; p != (bfd *) NULL; p = p->link_next) | |
1453 | ++ { | |
1454 | ++ object_type |= 1 << p->lto_type; | |
1455 | ++ if ((object_type & (1 << lto_mixed_object)) != 0 | |
1456 | ++ || ((object_type | |
1457 | ++ & (1 << lto_non_ir_object | |
1458 | ++ | 1 << lto_ir_object)) | |
1459 | ++ == (1 << lto_non_ir_object | 1 << lto_ir_object))) | |
1460 | ++ { | |
1461 | ++ link_info.emit_gnu_object_only = TRUE; | |
1462 | ++ break; | |
1463 | ++ } | |
1464 | ++ } | |
1465 | ++ | |
1466 | ++ if (verbose | |
1467 | ++ && (cmdline_object_only_file_list.head | |
1468 | ++ || cmdline_object_only_archive_list.head)) | |
1469 | ++ { | |
1470 | ++ info_msg (_("Object-only input files:\n ")); | |
1471 | ++ print_cmdline_list (cmdline_object_only_file_list.head); | |
1472 | ++ print_cmdline_list (cmdline_object_only_archive_list.head); | |
1473 | ++ } | |
1474 | ++ } | |
1475 | + | |
1476 | + link_info.gc_sym_list = &entry_symbol; | |
1477 | + if (entry_symbol.name == NULL) | |
1478 | +@@ -8061,3 +8114,961 @@ lang_ld_feature (char *str) | |
1479 | + p = q; | |
1480 | + } | |
1481 | + } | |
1482 | ++ | |
1483 | ++static void | |
1484 | ++cmdline_lists_init (void) | |
1485 | ++{ | |
1486 | ++ cmdline_object_only_file_list.tail | |
1487 | ++ = &cmdline_object_only_file_list.head; | |
1488 | ++ cmdline_object_only_archive_list.tail | |
1489 | ++ = &cmdline_object_only_archive_list.head; | |
1490 | ++ cmdline_temp_object_only_list.tail | |
1491 | ++ = &cmdline_temp_object_only_list.head; | |
1492 | ++} | |
1493 | ++ | |
1494 | ++/* Allocate an item with TYPE and DATA. */ | |
1495 | ++ | |
1496 | ++static cmdline_union_type * | |
1497 | ++cmdline_list_new (cmdline_enum_type type, void *data) | |
1498 | ++{ | |
1499 | ++ cmdline_union_type *new_opt; | |
1500 | ++ | |
1501 | ++ new_opt = (cmdline_union_type *) stat_alloc (sizeof (*new_opt)); | |
1502 | ++ new_opt->header.type = type; | |
1503 | ++ switch (type) | |
1504 | ++ { | |
1505 | ++ default: | |
1506 | ++ break; | |
1507 | ++ case cmdline_is_file_enum: | |
1508 | ++ new_opt->file.filename = (const char *) data; | |
1509 | ++ break; | |
1510 | ++ case cmdline_is_bfd_enum: | |
1511 | ++ new_opt->abfd.abfd = (bfd *) data; | |
1512 | ++ break; | |
1513 | ++ } | |
1514 | ++ return new_opt; | |
1515 | ++} | |
1516 | ++ | |
1517 | ++/* Append an item with TYPE and DATA to LIST. */ | |
1518 | ++ | |
1519 | ++static void | |
1520 | ++cmdline_list_append (cmdline_list_type *list, cmdline_enum_type type, | |
1521 | ++ void *data) | |
1522 | ++{ | |
1523 | ++ cmdline_union_type *new_opt = cmdline_list_new (type, data); | |
1524 | ++ new_opt->header.next = NULL; | |
1525 | ++ *list->tail = new_opt; | |
1526 | ++ list->tail = &new_opt->header.next; | |
1527 | ++} | |
1528 | ++ | |
1529 | ++static void | |
1530 | ++print_cmdline_list (cmdline_union_type *c) | |
1531 | ++{ | |
1532 | ++ for (; c != NULL; c = c->header.next) | |
1533 | ++ switch (c->header.type) | |
1534 | ++ { | |
1535 | ++ default: | |
1536 | ++ abort (); | |
1537 | ++ case cmdline_is_file_enum: | |
1538 | ++ info_msg (" %s", c->file.filename); | |
1539 | ++ break; | |
1540 | ++ case cmdline_is_bfd_enum: | |
1541 | ++ info_msg (" [%B]", c->abfd.abfd); | |
1542 | ++ break; | |
1543 | ++ } | |
1544 | ++ | |
1545 | ++ info_msg ("\n"); | |
1546 | ++} | |
1547 | ++ | |
1548 | ++/* Return TRUE if ABFD is on cmdline_object_only_archive_list. */ | |
1549 | ++ | |
1550 | ++static bfd_boolean | |
1551 | ++cmdline_on_object_only_archive_list_p (bfd *abfd) | |
1552 | ++{ | |
1553 | ++ cmdline_union_type *c, *next; | |
1554 | ++ bfd *archive, *obfd, *oarchive; | |
1555 | ++ ufile_ptr origin = abfd->origin; | |
1556 | ++ | |
1557 | ++ archive = bfd_my_archive (abfd); | |
1558 | ++ for (c = cmdline_object_only_archive_list.head; c != NULL; c = next) | |
1559 | ++ { | |
1560 | ++ if (c->header.type != cmdline_is_bfd_enum) | |
1561 | ++ abort (); | |
1562 | ++ | |
1563 | ++ next = c->header.next; | |
1564 | ++ obfd = c->abfd.abfd; | |
1565 | ++ oarchive = bfd_my_archive (obfd); | |
1566 | ++ | |
1567 | ++ /* The list is grouped by archive file name and sorted by member | |
1568 | ++ origin. */ | |
1569 | ++ if (strcmp (archive->filename, oarchive->filename) != 0) | |
1570 | ++ continue; | |
1571 | ++ | |
1572 | ++ if (origin == obfd->origin) | |
1573 | ++ return TRUE; | |
1574 | ++ else if (origin < obfd->origin) | |
1575 | ++ return FALSE; | |
1576 | ++ } | |
1577 | ++ | |
1578 | ++ return FALSE; | |
1579 | ++} | |
1580 | ++ | |
1581 | ++/* Append an item with TYPE and DATA to cmdline_object_only_file_list | |
1582 | ++ or cmdline_object_only_archive_list if needed. */ | |
1583 | ++ | |
1584 | ++static void | |
1585 | ++cmdline_object_only_list_append (cmdline_enum_type type, void *data) | |
1586 | ++{ | |
1587 | ++ cmdline_union_type *c; | |
1588 | ++ cmdline_union_type *new_opt, *next, **prev; | |
1589 | ++ bfd *abfd, *archive; | |
1590 | ++ bfd *obfd, *oarchive; | |
1591 | ++ bfd *nbfd, *narchive; | |
1592 | ++ ufile_ptr origin, norigin; | |
1593 | ++ | |
1594 | ++ /* Put it on cmdline_object_only_file_list if it isn't an archive | |
1595 | ++ member. */ | |
1596 | ++ switch (type) | |
1597 | ++ { | |
1598 | ++ default: | |
1599 | ++ abort (); | |
1600 | ++ case cmdline_is_bfd_enum: | |
1601 | ++ abfd = (bfd *) data; | |
1602 | ++ archive = bfd_my_archive (abfd); | |
1603 | ++ if (archive) | |
1604 | ++ break; | |
1605 | ++ case cmdline_is_file_enum: | |
1606 | ++ cmdline_list_append (&cmdline_object_only_file_list, type, data); | |
1607 | ++ return; | |
1608 | ++ } | |
1609 | ++ | |
1610 | ++ /* Put archive member on cmdline_object_only_archive_list and sort | |
1611 | ++ the list by archive name and archive member origin. */ | |
1612 | ++ new_opt = (cmdline_union_type *) stat_alloc (sizeof (*new_opt)); | |
1613 | ++ new_opt->header.type = cmdline_is_bfd_enum; | |
1614 | ++ new_opt->header.next = NULL; | |
1615 | ++ new_opt->abfd.abfd = (bfd *) data; | |
1616 | ++ | |
1617 | ++ c = cmdline_object_only_archive_list.head; | |
1618 | ++ if (c == NULL) | |
1619 | ++ { | |
1620 | ++ cmdline_object_only_archive_list.head = new_opt; | |
1621 | ++ cmdline_object_only_archive_list.tail = &new_opt->header.next; | |
1622 | ++ return; | |
1623 | ++ } | |
1624 | ++ | |
1625 | ++ prev = NULL; | |
1626 | ++ origin = abfd->origin; | |
1627 | ++ for (; c != NULL; c = next) | |
1628 | ++ { | |
1629 | ++ if (c->header.type != cmdline_is_bfd_enum) | |
1630 | ++ abort (); | |
1631 | ++ | |
1632 | ++ next = c->header.next; | |
1633 | ++ | |
1634 | ++ obfd = c->abfd.abfd; | |
1635 | ++ oarchive = bfd_my_archive (obfd); | |
1636 | ++ | |
1637 | ++ if (strcmp (archive->filename, oarchive->filename) == 0) | |
1638 | ++ { | |
1639 | ++ bfd_boolean after; | |
1640 | ++ | |
1641 | ++ if (origin < obfd->origin) | |
1642 | ++ { | |
1643 | ++ /* Insert it before the current. */ | |
1644 | ++ new_opt->header.next = c; | |
1645 | ++ if (prev) | |
1646 | ++ *prev = new_opt; | |
1647 | ++ else | |
1648 | ++ cmdline_object_only_archive_list.head = new_opt; | |
1649 | ++ return; | |
1650 | ++ } | |
1651 | ++ | |
1652 | ++ after = TRUE; | |
1653 | ++ | |
1654 | ++ /* Check origin. */ | |
1655 | ++ while (next) | |
1656 | ++ { | |
1657 | ++ if (next->header.type != cmdline_is_bfd_enum) | |
1658 | ++ abort (); | |
1659 | ++ | |
1660 | ++ nbfd = next->abfd.abfd; | |
1661 | ++ norigin = nbfd->origin; | |
1662 | ++ if (origin > norigin) | |
1663 | ++ { | |
1664 | ++ /* Insert it after NEXT. */ | |
1665 | ++ break; | |
1666 | ++ } | |
1667 | ++ | |
1668 | ++ narchive = bfd_my_archive (nbfd); | |
1669 | ++ if (strcmp (archive->filename, narchive->filename) != 0) | |
1670 | ++ { | |
1671 | ++ /* Insert it befor NEXT. */ | |
1672 | ++ after = FALSE; | |
1673 | ++ break; | |
1674 | ++ } | |
1675 | ++ | |
1676 | ++ c = next; | |
1677 | ++ next = next->header.next; | |
1678 | ++ } | |
1679 | ++ | |
1680 | ++ if (after && next) | |
1681 | ++ { | |
1682 | ++ c = next; | |
1683 | ++ next = next->header.next; | |
1684 | ++ } | |
1685 | ++ | |
1686 | ++ if (*cmdline_object_only_archive_list.tail == c->header.next) | |
1687 | ++ cmdline_object_only_archive_list.tail | |
1688 | ++ = &new_opt->header.next; | |
1689 | ++ | |
1690 | ++ prev = &c->header.next; | |
1691 | ++ new_opt->header.next = next; | |
1692 | ++ *prev = new_opt; | |
1693 | ++ return; | |
1694 | ++ } | |
1695 | ++ | |
1696 | ++ prev = &c->header.next; | |
1697 | ++ } | |
1698 | ++ | |
1699 | ++ *cmdline_object_only_archive_list.tail = new_opt; | |
1700 | ++ cmdline_object_only_archive_list.tail = &new_opt->header.next; | |
1701 | ++} | |
1702 | ++ | |
1703 | ++/* Get object-only input files. */ | |
1704 | ++ | |
1705 | ++static void | |
1706 | ++cmdline_get_object_only_input_files (void) | |
1707 | ++{ | |
1708 | ++ cmdline_union_type *c, *next; | |
1709 | ++ bfd *abfd, *archive; | |
1710 | ++ bfd *nbfd, *narchive; | |
1711 | ++ | |
1712 | ++ /* Add files first. */ | |
1713 | ++ for (c = cmdline_object_only_file_list.head; | |
1714 | ++ c != NULL; c = c->header.next) | |
1715 | ++ switch (c->header.type) | |
1716 | ++ { | |
1717 | ++ default: | |
1718 | ++ abort (); | |
1719 | ++ case cmdline_is_file_enum: | |
1720 | ++ lang_add_input_file (c->file.filename, | |
1721 | ++ lang_input_file_is_file_enum, NULL); | |
1722 | ++ break; | |
1723 | ++ case cmdline_is_bfd_enum: | |
1724 | ++ abfd = c->abfd.abfd; | |
1725 | ++ if (bfd_my_archive (abfd)) | |
1726 | ++ abort (); | |
1727 | ++ lang_add_input_file (abfd->filename, | |
1728 | ++ lang_input_file_is_file_enum, NULL); | |
1729 | ++ break; | |
1730 | ++ } | |
1731 | ++ | |
1732 | ++ /* Add archive members next. */ | |
1733 | ++ for (c = cmdline_object_only_archive_list.head; c != NULL; c = next) | |
1734 | ++ { | |
1735 | ++ if (c->header.type != cmdline_is_bfd_enum) | |
1736 | ++ abort (); | |
1737 | ++ | |
1738 | ++ next = c->header.next; | |
1739 | ++ | |
1740 | ++ abfd = c->abfd.abfd; | |
1741 | ++ archive = bfd_my_archive (abfd); | |
1742 | ++ | |
1743 | ++ /* Add the first archive of the archive member group. */ | |
1744 | ++ lang_add_input_file (archive->filename, | |
1745 | ++ lang_input_file_is_file_enum, NULL); | |
1746 | ++ | |
1747 | ++ /* Skip the rest members in the archive member group. */ | |
1748 | ++ do | |
1749 | ++ { | |
1750 | ++ if (!next) | |
1751 | ++ break; | |
1752 | ++ | |
1753 | ++ if (next->header.type != cmdline_is_bfd_enum) | |
1754 | ++ abort (); | |
1755 | ++ | |
1756 | ++ next = next->header.next; | |
1757 | ++ if (!next) | |
1758 | ++ break; | |
1759 | ++ nbfd = next->abfd.abfd; | |
1760 | ++ narchive = bfd_my_archive (nbfd); | |
1761 | ++ } | |
1762 | ++ while (strcmp (archive->filename, narchive->filename) == 0); | |
1763 | ++ } | |
1764 | ++} | |
1765 | ++ | |
1766 | ++struct cmdline_arg | |
1767 | ++{ | |
1768 | ++ bfd *obfd; | |
1769 | ++ asymbol **isympp; | |
1770 | ++ int status; | |
1771 | ++}; | |
1772 | ++ | |
1773 | ++/* Create a section in OBFD with the same | |
1774 | ++ name and attributes as ISECTION in IBFD. */ | |
1775 | ++ | |
1776 | ++static void | |
1777 | ++setup_section (bfd *ibfd, sec_ptr isection, void *p) | |
1778 | ++{ | |
1779 | ++ struct cmdline_arg *arg = (struct cmdline_arg *) p; | |
1780 | ++ bfd *obfd = arg->obfd; | |
1781 | ++ asymbol **isympp = arg->isympp; | |
1782 | ++ const char *name = isection->name; | |
1783 | ++ sec_ptr osection; | |
1784 | ++ const char *err; | |
1785 | ++ | |
1786 | ++ /* Skip the object-only section. */ | |
1787 | ++ if (ibfd->object_only_section == isection) | |
1788 | ++ return; | |
1789 | ++ | |
1790 | ++ /* If we have already failed earlier on, do not keep on generating | |
1791 | ++ complaints now. */ | |
1792 | ++ if (arg->status) | |
1793 | ++ return; | |
1794 | ++ | |
1795 | ++ osection = bfd_make_section_anyway_with_flags (obfd, name, | |
1796 | ++ isection->flags); | |
1797 | ++ | |
1798 | ++ if (osection == NULL) | |
1799 | ++ { | |
1800 | ++ err = _("failed to create output section"); | |
1801 | ++ goto loser; | |
1802 | ++ } | |
1803 | ++ | |
1804 | ++ osection->size = isection->size; | |
1805 | ++ osection->vma = isection->vma; | |
1806 | ++ osection->lma = isection->lma; | |
1807 | ++ osection->alignment_power = isection->alignment_power; | |
1808 | ++ | |
1809 | ++ /* Copy merge entity size. */ | |
1810 | ++ osection->entsize = isection->entsize; | |
1811 | ++ | |
1812 | ++ /* This used to be mangle_section; we do here to avoid using | |
1813 | ++ bfd_get_section_by_name since some formats allow multiple | |
1814 | ++ sections with the same name. */ | |
1815 | ++ isection->output_section = osection; | |
1816 | ++ isection->output_offset = 0; | |
1817 | ++ | |
1818 | ++ if ((isection->flags & SEC_GROUP) != 0) | |
1819 | ++ { | |
1820 | ++ asymbol *gsym = bfd_group_signature (isection, isympp); | |
1821 | ++ | |
1822 | ++ if (gsym != NULL) | |
1823 | ++ { | |
1824 | ++ gsym->flags |= BSF_KEEP; | |
1825 | ++ if (ibfd->xvec->flavour == bfd_target_elf_flavour) | |
1826 | ++ elf_group_id (isection) = gsym; | |
1827 | ++ } | |
1828 | ++ } | |
1829 | ++ | |
1830 | ++ /* Allow the BFD backend to copy any private data it understands | |
1831 | ++ from the input section to the output section. */ | |
1832 | ++ if (!bfd_copy_private_section_data (ibfd, isection, obfd, osection)) | |
1833 | ++ { | |
1834 | ++ err = _("failed to copy private data"); | |
1835 | ++ goto loser; | |
1836 | ++ } | |
1837 | ++ | |
1838 | ++ /* All went well. */ | |
1839 | ++ return; | |
1840 | ++ | |
1841 | ++loser: | |
1842 | ++ arg->status = 1; | |
1843 | ++ einfo (_("%P%F: setup_section: %s: %s\n"), err, name); | |
1844 | ++} | |
1845 | ++ | |
1846 | ++/* Copy the data of input section ISECTION of IBFD | |
1847 | ++ to an output section with the same name in OBFD. | |
1848 | ++ If stripping then don't copy any relocation info. */ | |
1849 | ++ | |
1850 | ++static void | |
1851 | ++copy_section (bfd *ibfd, sec_ptr isection, void *p) | |
1852 | ++{ | |
1853 | ++ struct cmdline_arg *arg = (struct cmdline_arg *) p; | |
1854 | ++ bfd *obfd = arg->obfd; | |
1855 | ++ asymbol **isympp = arg->isympp; | |
1856 | ++ arelent **relpp; | |
1857 | ++ long relcount; | |
1858 | ++ sec_ptr osection; | |
1859 | ++ bfd_size_type size; | |
1860 | ++ long relsize; | |
1861 | ++ flagword flags; | |
1862 | ++ const char *err; | |
1863 | ++ | |
1864 | ++ /* Skip the object-only section. */ | |
1865 | ++ if (ibfd->object_only_section == isection) | |
1866 | ++ return; | |
1867 | ++ | |
1868 | ++ /* If we have already failed earlier on, do not keep on generating | |
1869 | ++ complaints now. */ | |
1870 | ++ if (arg->status) | |
1871 | ++ return; | |
1872 | ++ | |
1873 | ++ flags = bfd_get_section_flags (ibfd, isection); | |
1874 | ++ if ((flags & SEC_GROUP) != 0) | |
1875 | ++ return; | |
1876 | ++ | |
1877 | ++ osection = isection->output_section; | |
1878 | ++ size = bfd_get_section_size (isection); | |
1879 | ++ | |
1880 | ++ if (size == 0 || osection == 0) | |
1881 | ++ return; | |
1882 | ++ | |
1883 | ++ relsize = bfd_get_reloc_upper_bound (ibfd, isection); | |
1884 | ++ | |
1885 | ++ if (relsize < 0) | |
1886 | ++ { | |
1887 | ++ /* Do not complain if the target does not support relocations. */ | |
1888 | ++ if (relsize == -1 | |
1889 | ++ && bfd_get_error () == bfd_error_invalid_operation) | |
1890 | ++ relsize = 0; | |
1891 | ++ else | |
1892 | ++ { | |
1893 | ++ err = bfd_errmsg (bfd_get_error ()); | |
1894 | ++ goto loser; | |
1895 | ++ } | |
1896 | ++ } | |
1897 | ++ | |
1898 | ++ if (relsize == 0) | |
1899 | ++ bfd_set_reloc (obfd, osection, NULL, 0); | |
1900 | ++ else | |
1901 | ++ { | |
1902 | ++ relpp = (arelent **) xmalloc (relsize); | |
1903 | ++ relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp); | |
1904 | ++ if (relcount < 0) | |
1905 | ++ { | |
1906 | ++ err = _("relocation count is negative"); | |
1907 | ++ goto loser; | |
1908 | ++ } | |
1909 | ++ | |
1910 | ++ bfd_set_reloc (obfd, osection, | |
1911 | ++ relcount == 0 ? NULL : relpp, relcount); | |
1912 | ++ if (relcount == 0) | |
1913 | ++ free (relpp); | |
1914 | ++ } | |
1915 | ++ | |
1916 | ++ if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS) | |
1917 | ++ { | |
1918 | ++ bfd_byte *memhunk = NULL; | |
1919 | ++ | |
1920 | ++ if (!bfd_get_full_section_contents (ibfd, isection, &memhunk)) | |
1921 | ++ { | |
1922 | ++ err = bfd_errmsg (bfd_get_error ()); | |
1923 | ++ goto loser; | |
1924 | ++ } | |
1925 | ++ | |
1926 | ++ if (!bfd_set_section_contents (obfd, osection, memhunk, 0, size)) | |
1927 | ++ { | |
1928 | ++ err = bfd_errmsg (bfd_get_error ()); | |
1929 | ++ goto loser; | |
1930 | ++ } | |
1931 | ++ free (memhunk); | |
1932 | ++ } | |
1933 | ++ | |
1934 | ++ /* All went well. */ | |
1935 | ++ return; | |
1936 | ++ | |
1937 | ++loser: | |
1938 | ++ einfo (_("%P%F: copy_section: %s: %s\n"), err, isection->name); | |
1939 | ++} | |
1940 | ++/* Open the temporary bfd created in the same directory as PATH. */ | |
1941 | ++ | |
1942 | ++static bfd * | |
1943 | ++cmdline_fopen_temp (const char *path, const char *target, | |
1944 | ++ const char *mode) | |
1945 | ++{ | |
1946 | ++#define template "ldXXXXXX" | |
1947 | ++ const char *slash = strrchr (path, '/'); | |
1948 | ++ char *tmpname; | |
1949 | ++ size_t len; | |
1950 | ++ int fd; | |
1951 | ++ | |
1952 | ++#ifdef HAVE_DOS_BASED_FILE_SYSTEM | |
1953 | ++ { | |
1954 | ++ /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */ | |
1955 | ++ char *bslash = strrchr (path, '\\'); | |
1956 | ++ | |
1957 | ++ if (slash == NULL || (bslash != NULL && bslash > slash)) | |
1958 | ++ slash = bslash; | |
1959 | ++ if (slash == NULL && path[0] != '\0' && path[1] == ':') | |
1960 | ++ slash = path + 1; | |
1961 | ++ } | |
1962 | ++#endif | |
1963 | ++ | |
1964 | ++ if (slash != (char *) NULL) | |
1965 | ++ { | |
1966 | ++ len = slash - path; | |
1967 | ++ tmpname = (char *) xmalloc (len + sizeof (template) + 2); | |
1968 | ++ memcpy (tmpname, path, len); | |
1969 | ++ | |
1970 | ++#ifdef HAVE_DOS_BASED_FILE_SYSTEM | |
1971 | ++ /* If tmpname is "X:", appending a slash will make it a root | |
1972 | ++ directory on drive X, which is NOT the same as the current | |
1973 | ++ directory on drive X. */ | |
1974 | ++ if (len == 2 && tmpname[1] == ':') | |
1975 | ++ tmpname[len++] = '.'; | |
1976 | ++#endif | |
1977 | ++ tmpname[len++] = '/'; | |
1978 | ++ } | |
1979 | ++ else | |
1980 | ++ { | |
1981 | ++ tmpname = (char *) xmalloc (sizeof (template)); | |
1982 | ++ len = 0; | |
1983 | ++ } | |
1984 | ++ | |
1985 | ++ memcpy (tmpname + len, template, sizeof (template)); | |
1986 | ++#undef template | |
1987 | ++ | |
1988 | ++#ifdef HAVE_MKSTEMP | |
1989 | ++ fd = mkstemp (tmpname); | |
1990 | ++#else | |
1991 | ++ tmpname = mktemp (tmpname); | |
1992 | ++ if (tmpname == NULL) | |
1993 | ++ return NULL; | |
1994 | ++ fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600); | |
1995 | ++#endif | |
1996 | ++ if (fd == -1) | |
1997 | ++ return NULL; | |
1998 | ++ return bfd_fopen (tmpname, target, mode, fd); | |
1999 | ++} | |
2000 | ++ | |
2001 | ++/* Add the object-only section. */ | |
2002 | ++ | |
2003 | ++static void | |
2004 | ++cmdline_add_object_only_section (bfd_byte *contents, size_t size) | |
2005 | ++{ | |
2006 | ++ bfd_vma start; | |
2007 | ++ flagword flags; | |
2008 | ++ enum bfd_architecture iarch; | |
2009 | ++ unsigned int imach; | |
2010 | ++ long symcount; | |
2011 | ++ long symsize; | |
2012 | ++ asymbol **isympp = NULL; | |
2013 | ++ asymbol **osympp = NULL; | |
2014 | ++ bfd *obfd = NULL, *ibfd; | |
2015 | ++ const char *err; | |
2016 | ++ struct arg | |
2017 | ++ { | |
2018 | ++ bfd *obfd; | |
2019 | ++ asymbol **isympp; | |
2020 | ++ int status; | |
2021 | ++ } arg; | |
2022 | ++ char **matching; | |
2023 | ++ const char *ofilename = NULL; | |
2024 | ++ asection *sec; | |
2025 | ++ | |
2026 | ++ ibfd = bfd_openr (output_filename, output_target); | |
2027 | ++ if (!ibfd) | |
2028 | ++ { | |
2029 | ++ err = bfd_errmsg (bfd_get_error ()); | |
2030 | ++ goto loser; | |
2031 | ++ } | |
2032 | ++ | |
2033 | ++ if (!bfd_check_format_matches (ibfd, bfd_object, &matching)) | |
2034 | ++ { | |
2035 | ++ err = bfd_errmsg (bfd_get_error ()); | |
2036 | ++ goto loser; | |
2037 | ++ } | |
2038 | ++ | |
2039 | ++ obfd = cmdline_fopen_temp (output_filename, output_target, "w"); | |
2040 | ++ if (!obfd) | |
2041 | ++ { | |
2042 | ++ err = bfd_errmsg (bfd_get_error ()); | |
2043 | ++ goto loser; | |
2044 | ++ } | |
2045 | ++ ofilename = bfd_get_filename (obfd); | |
2046 | ++ | |
2047 | ++ if (!bfd_set_format (obfd, bfd_object)) | |
2048 | ++ { | |
2049 | ++ err = bfd_errmsg (bfd_get_error ()); | |
2050 | ++ goto loser; | |
2051 | ++ } | |
2052 | ++ | |
2053 | ++ /* Copy the start address, flags and architecture of input file to | |
2054 | ++ output file. */ | |
2055 | ++ flags = bfd_get_file_flags (ibfd); | |
2056 | ++ start = bfd_get_start_address (ibfd); | |
2057 | ++ iarch = bfd_get_arch (ibfd); | |
2058 | ++ imach = bfd_get_mach (ibfd); | |
2059 | ++ if (!bfd_set_start_address (obfd, start) | |
2060 | ++ || !bfd_set_file_flags (obfd, flags) | |
2061 | ++ || !bfd_set_arch_mach (obfd, iarch, imach)) | |
2062 | ++ { | |
2063 | ++ err = bfd_errmsg (bfd_get_error ()); | |
2064 | ++ goto loser; | |
2065 | ++ } | |
2066 | ++ | |
2067 | ++ symsize = bfd_get_symtab_upper_bound (ibfd); | |
2068 | ++ if (symsize < 0) | |
2069 | ++ { | |
2070 | ++ err = bfd_errmsg (bfd_get_error ()); | |
2071 | ++ goto loser; | |
2072 | ++ } | |
2073 | ++ | |
2074 | ++ isympp = (asymbol **) xmalloc (symsize); | |
2075 | ++ symcount = bfd_canonicalize_symtab (ibfd, isympp); | |
2076 | ++ if (symcount < 0) | |
2077 | ++ { | |
2078 | ++ err = bfd_errmsg (bfd_get_error ()); | |
2079 | ++ goto loser; | |
2080 | ++ } | |
2081 | ++ | |
2082 | ++ arg.obfd = obfd; | |
2083 | ++ arg.isympp = isympp; | |
2084 | ++ arg.status = 0; | |
2085 | ++ | |
2086 | ++ /* BFD mandates that all output sections be created and sizes set before | |
2087 | ++ any output is done. Thus, we traverse all sections multiple times. */ | |
2088 | ++ bfd_map_over_sections (ibfd, setup_section, &arg); | |
2089 | ++ | |
2090 | ++ if (arg.status) | |
2091 | ++ { | |
2092 | ++ err = _("error setting up sections"); | |
2093 | ++ goto loser; | |
2094 | ++ } | |
2095 | ++ | |
2096 | ++ /* Allow the BFD backend to copy any private data it understands | |
2097 | ++ from the input section to the output section. */ | |
2098 | ++ if (! bfd_copy_private_header_data (ibfd, obfd)) | |
2099 | ++ { | |
2100 | ++ err = _("error copying private header data"); | |
2101 | ++ goto loser; | |
2102 | ++ } | |
2103 | ++ | |
2104 | ++ /* Create the object-only section. */ | |
2105 | ++ sec = bfd_make_section_with_flags (obfd, | |
2106 | ++ GNU_OBJECT_ONLY_SECTION_NAME, | |
2107 | ++ (SEC_HAS_CONTENTS | |
2108 | ++ | SEC_READONLY | |
2109 | ++ | SEC_DATA | |
2110 | ++ | SEC_LINKER_CREATED)); | |
2111 | ++ if (sec == NULL) | |
2112 | ++ { | |
2113 | ++ err = _("can't create object-only section"); | |
2114 | ++ goto loser; | |
2115 | ++ } | |
2116 | ++ | |
2117 | ++ if (! bfd_set_section_size (obfd, sec, size)) | |
2118 | ++ { | |
2119 | ++ err = _("can't set object-only section size"); | |
2120 | ++ goto loser; | |
2121 | ++ } | |
2122 | ++ | |
2123 | ++ if (ibfd->object_only_section) | |
2124 | ++ { | |
2125 | ++ /* Filter out the object-only section symbol. */ | |
2126 | ++ long src_count = 0, dst_count = 0; | |
2127 | ++ asymbol **from, **to; | |
2128 | ++ | |
2129 | ++ osympp = (asymbol **) xmalloc (symcount * sizeof (asymbol *)); | |
2130 | ++ from = isympp; | |
2131 | ++ to = osympp; | |
2132 | ++ for (; src_count < symcount; src_count++) | |
2133 | ++ { | |
2134 | ++ asymbol *sym = from[src_count]; | |
2135 | ++ if (bfd_get_section (sym) != ibfd->object_only_section) | |
2136 | ++ to[dst_count++] = sym; | |
2137 | ++ } | |
2138 | ++ to[dst_count] = NULL; | |
2139 | ++ symcount = dst_count; | |
2140 | ++ bfd_set_symtab (obfd, osympp, symcount); | |
2141 | ++ } | |
2142 | ++ else | |
2143 | ++ bfd_set_symtab (obfd, isympp, symcount); | |
2144 | ++ | |
2145 | ++ /* This has to happen after the symbol table has been set. */ | |
2146 | ++ bfd_map_over_sections (ibfd, copy_section, &arg); | |
2147 | ++ | |
2148 | ++ if (arg.status) | |
2149 | ++ { | |
2150 | ++ err = _("error copying sections"); | |
2151 | ++ goto loser; | |
2152 | ++ } | |
2153 | ++ | |
2154 | ++ /* Copy the object-only section to the output. */ | |
2155 | ++ if (! bfd_set_section_contents (obfd, sec, contents, 0, size)) | |
2156 | ++ { | |
2157 | ++ err = _("error adding object-only section"); | |
2158 | ++ goto loser; | |
2159 | ++ } | |
2160 | ++ | |
2161 | ++ /* Allow the BFD backend to copy any private data it understands | |
2162 | ++ from the input BFD to the output BFD. This is done last to | |
2163 | ++ permit the routine to look at the filtered symbol table, which is | |
2164 | ++ important for the ECOFF code at least. */ | |
2165 | ++ if (! bfd_copy_private_bfd_data (ibfd, obfd)) | |
2166 | ++ { | |
2167 | ++ err = _("error copying private BFD data"); | |
2168 | ++ goto loser; | |
2169 | ++ } | |
2170 | ++ | |
2171 | ++ if (!bfd_close (obfd)) | |
2172 | ++ { | |
2173 | ++ unlink (ofilename); | |
2174 | ++ einfo (_("%P%F: failed to finish output with object-only section\n")); | |
2175 | ++ } | |
2176 | ++ | |
2177 | ++ /* Must be freed after bfd_close (). */ | |
2178 | ++ free (isympp); | |
2179 | ++ if (osympp) | |
2180 | ++ free (osympp); | |
2181 | ++ | |
2182 | ++ if (rename (ofilename, output_filename)) | |
2183 | ++ { | |
2184 | ++ unlink (ofilename); | |
2185 | ++ einfo (_("%P%F: failed to rename output with object-only section\n")); | |
2186 | ++ } | |
2187 | ++ | |
2188 | ++ return; | |
2189 | ++ | |
2190 | ++loser: | |
2191 | ++ if (isympp) | |
2192 | ++ free (isympp); | |
2193 | ++ if (osympp) | |
2194 | ++ free (osympp); | |
2195 | ++ if (obfd) | |
2196 | ++ bfd_close (obfd); | |
2197 | ++ if (ofilename) | |
2198 | ++ unlink (ofilename); | |
2199 | ++ einfo (_("%P%F: failed to add object-only section: %s\n"), err); | |
2200 | ++} | |
2201 | ++ | |
2202 | ++/* Emit the final output with object-only section. */ | |
2203 | ++ | |
2204 | ++void | |
2205 | ++cmdline_emit_object_only_section (void) | |
2206 | ++{ | |
2207 | ++ const char *saved_output_filename = output_filename; | |
2208 | ++ int fd; | |
2209 | ++ size_t size, off; | |
2210 | ++ bfd_byte *contents; | |
2211 | ++ struct stat st; | |
2212 | ++ | |
2213 | ++ /* Get a temporary object-only file. */ | |
2214 | ++ output_filename = make_temp_file (".obj-only.o"); | |
2215 | ++ | |
2216 | ++ had_output_filename = FALSE; | |
2217 | ++ link_info.input_bfds = NULL; | |
2218 | ++ link_info.input_bfds_tail = &link_info.input_bfds; | |
2219 | ++ | |
2220 | ++ lang_init (TRUE); | |
2221 | ++ | |
2222 | ++ ld_parse_linker_script (); | |
2223 | ++ | |
2224 | ++ /* Set up the object-only output. */ | |
2225 | ++ lang_final (); | |
2226 | ++ | |
2227 | ++ /* Open the object-only file for output. */ | |
2228 | ++ lang_for_each_statement (ldlang_open_output); | |
2229 | ++ | |
2230 | ++ ldemul_create_output_section_statements (); | |
2231 | ++ | |
2232 | ++ if (!bfd_section_already_linked_table_init ()) | |
2233 | ++ einfo (_("%P%F: Failed to create hash table\n")); | |
2234 | ++ | |
2235 | ++ /* Call cmdline_on_object_only_archive_list_p to check which member | |
2236 | ++ should be loaded. */ | |
2237 | ++ input_flags.whole_archive = TRUE; | |
2238 | ++ | |
2239 | ++ /* Set it to avoid adding more to cmdline lists. */ | |
2240 | ++ link_info.emitting_gnu_object_only = TRUE; | |
2241 | ++ | |
2242 | ++ /* Get object-only input files. */ | |
2243 | ++ cmdline_get_object_only_input_files (); | |
2244 | ++ | |
2245 | ++ /* Open object-only input files. */ | |
2246 | ++ open_input_bfds (statement_list.head, FALSE); | |
2247 | ++ | |
2248 | ++ ldemul_after_open (); | |
2249 | ++ | |
2250 | ++ bfd_section_already_linked_table_free (); | |
2251 | ++ | |
2252 | ++ /* Make sure that we're not mixing architectures. We call this | |
2253 | ++ after all the input files have been opened, but before we do any | |
2254 | ++ other processing, so that any operations merge_private_bfd_data | |
2255 | ++ does on the output file will be known during the rest of the | |
2256 | ++ link. */ | |
2257 | ++ lang_check (); | |
2258 | ++ | |
2259 | ++ /* Size up the common data. */ | |
2260 | ++ lang_common (); | |
2261 | ++ | |
2262 | ++ /* Update wild statements. */ | |
2263 | ++ update_wild_statements (statement_list.head); | |
2264 | ++ | |
2265 | ++ /* Run through the contours of the script and attach input sections | |
2266 | ++ to the correct output sections. */ | |
2267 | ++ map_input_to_output_sections (statement_list.head, NULL, NULL); | |
2268 | ++ | |
2269 | ++ /* Find any sections not attached explicitly and handle them. */ | |
2270 | ++ lang_place_orphans (); | |
2271 | ++ | |
2272 | ++ /* Do anything special before sizing sections. This is where ELF | |
2273 | ++ and other back-ends size dynamic sections. */ | |
2274 | ++ ldemul_before_allocation (); | |
2275 | ++ | |
2276 | ++ /* Size up the sections. */ | |
2277 | ++ lang_size_sections (NULL, ! RELAXATION_ENABLED); | |
2278 | ++ | |
2279 | ++ /* See if anything special should be done now we know how big | |
2280 | ++ everything is. This is where relaxation is done. */ | |
2281 | ++ ldemul_after_allocation (); | |
2282 | ++ | |
2283 | ++ ldemul_finish (); | |
2284 | ++ | |
2285 | ++ /* Make sure that the section addresses make sense. */ | |
2286 | ++ if (command_line.check_section_addresses) | |
2287 | ++ lang_check_section_addresses (); | |
2288 | ++ | |
2289 | ++ lang_end (); | |
2290 | ++ | |
2291 | ++ ldwrite (); | |
2292 | ++ | |
2293 | ++ lang_finish (TRUE); | |
2294 | ++ | |
2295 | ++ if (! bfd_close (link_info.output_bfd)) | |
2296 | ++ einfo (_("%P%F:%s: final close failed on object-only output: %E\n"), | |
2297 | ++ output_filename); | |
2298 | ++ | |
2299 | ++ /* Read in the object-only file. */ | |
2300 | ++ fd = open (output_filename, O_RDONLY | O_BINARY); | |
2301 | ++ if (fd < 0) | |
2302 | ++ { | |
2303 | ++ bfd_set_error (bfd_error_system_call); | |
2304 | ++ einfo (_("%P%F:%s: cannot open object-only output: %E"), | |
2305 | ++ output_filename); | |
2306 | ++ } | |
2307 | ++ | |
2308 | ++ /* Get the object-only file size. */ | |
2309 | ++ if (fstat (fd, &st) != 0) | |
2310 | ++ { | |
2311 | ++ bfd_set_error (bfd_error_system_call); | |
2312 | ++ einfo (_("%P%F:%s: cannot stat object-only output: %E"), | |
2313 | ++ output_filename); | |
2314 | ++ } | |
2315 | ++ | |
2316 | ++ size = st.st_size; | |
2317 | ++ off = 0; | |
2318 | ++ contents = (bfd_byte *) xmalloc (size); | |
2319 | ++ while (off != size) | |
2320 | ++ { | |
2321 | ++ ssize_t got; | |
2322 | ++ | |
2323 | ++ got = read (fd, contents + off, size - off); | |
2324 | ++ if (got < 0) | |
2325 | ++ { | |
2326 | ++ bfd_set_error (bfd_error_system_call); | |
2327 | ++ einfo (_("%P%F:%s: read failed on object-only output: %E"), | |
2328 | ++ output_filename); | |
2329 | ++ } | |
2330 | ++ | |
2331 | ++ off += got; | |
2332 | ++ } | |
2333 | ++ | |
2334 | ++ close (fd); | |
2335 | ++ | |
2336 | ++ /* Remove the temporary object-only file. */ | |
2337 | ++ unlink (output_filename); | |
2338 | ++ | |
2339 | ++ output_filename = saved_output_filename; | |
2340 | ++ | |
2341 | ++ cmdline_add_object_only_section (contents, size); | |
2342 | ++ | |
2343 | ++ free (contents); | |
2344 | ++} | |
2345 | ++ | |
2346 | ++/* Extract the object-only section. */ | |
2347 | ++ | |
2348 | ++static const char * | |
2349 | ++cmdline_extract_object_only_section (bfd *abfd) | |
2350 | ++{ | |
2351 | ++ const char *name = bfd_extract_object_only_section (abfd); | |
2352 | ++ | |
2353 | ++ if (name == NULL) | |
2354 | ++ einfo (_("%P%F: cannot extract object-only section from %B: %E"), | |
2355 | ++ abfd); | |
2356 | ++ | |
2357 | ++ /* It should be removed after it is done. */ | |
2358 | ++ cmdline_list_append (&cmdline_temp_object_only_list, | |
2359 | ++ cmdline_is_file_enum, (void *) name); | |
2360 | ++ | |
2361 | ++ return name; | |
2362 | ++} | |
2363 | ++ | |
2364 | ++/* Check and handle the object-only section. */ | |
2365 | ++ | |
2366 | ++void | |
2367 | ++cmdline_check_object_only_section (bfd *abfd, bfd_boolean lto) | |
2368 | ++{ | |
2369 | ++ const char *filename; | |
2370 | ++ | |
2371 | ++ if (link_info.emitting_gnu_object_only | |
2372 | ++ || abfd->format != bfd_object) | |
2373 | ++ return; | |
2374 | ++ | |
2375 | ++ if (lto) | |
2376 | ++ { | |
2377 | ++ /* For LTO link, we only need to extract object-only section | |
2378 | ++ from the mixed object, add it to input, and put it on LTO | |
2379 | ++ claimed output. */ | |
2380 | ++ switch (abfd->lto_type) | |
2381 | ++ { | |
2382 | ++ default: | |
2383 | ++ abort (); | |
2384 | ++ case lto_mixed_object: | |
2385 | ++ filename = cmdline_extract_object_only_section (abfd); | |
2386 | ++ lang_add_input_file (filename, | |
2387 | ++ lang_input_file_is_file_enum, NULL); | |
2388 | ++ break; | |
2389 | ++ case lto_non_ir_object: | |
2390 | ++ case lto_ir_object: | |
2391 | ++ break; | |
2392 | ++ } | |
2393 | ++ } | |
2394 | ++ else if (link_info.relocatable) | |
2395 | ++ { | |
2396 | ++ /* For non-LTO relocatable link, we need to append non-IR object | |
2397 | ++ file and the object file in object-only section to the object | |
2398 | ++ only list. */ | |
2399 | ++ switch (abfd->lto_type) | |
2400 | ++ { | |
2401 | ++ default: | |
2402 | ++ abort (); | |
2403 | ++ case lto_mixed_object: | |
2404 | ++ filename = cmdline_extract_object_only_section (abfd); | |
2405 | ++ cmdline_object_only_list_append (cmdline_is_file_enum, | |
2406 | ++ (void *) filename); | |
2407 | ++ break; | |
2408 | ++ case lto_non_ir_object: | |
2409 | ++ cmdline_object_only_list_append (cmdline_is_bfd_enum, abfd); | |
2410 | ++ break; | |
2411 | ++ case lto_ir_object: | |
2412 | ++ break; | |
2413 | ++ } | |
2414 | ++ } | |
2415 | ++} | |
2416 | ++ | |
2417 | ++/* Remove temporary object-only files. */ | |
2418 | ++ | |
2419 | ++void | |
2420 | ++cmdline_remove_object_only_files (void) | |
2421 | ++{ | |
2422 | ++ cmdline_union_type *c; | |
2423 | ++ | |
2424 | ++#ifdef ENABLE_PLUGINS | |
2425 | ++ if (plugin_save_temps) | |
2426 | ++ return; | |
2427 | ++#endif | |
2428 | ++ | |
2429 | ++ c = cmdline_temp_object_only_list.head; | |
2430 | ++ for (; c != NULL; c = c->header.next) | |
2431 | ++ switch (c->header.type) | |
2432 | ++ { | |
2433 | ++ default: | |
2434 | ++ abort (); | |
2435 | ++ case cmdline_is_file_enum: | |
2436 | ++ unlink (c->file.filename); | |
2437 | ++ break; | |
2438 | ++ } | |
2439 | ++} | |
2440 | +diff --git a/ld/ldlang.h b/ld/ldlang.h | |
2441 | +index 2dbec5a..1754457 100644 | |
2442 | +--- a/ld/ldlang.h | |
2443 | ++++ b/ld/ldlang.h | |
2444 | +@@ -488,9 +488,9 @@ extern lang_statement_list_type input_file_chain; | |
2445 | + extern int lang_statement_iteration; | |
2446 | + | |
2447 | + extern void lang_init | |
2448 | +- (void); | |
2449 | ++ (bfd_boolean); | |
2450 | + extern void lang_finish | |
2451 | +- (void); | |
2452 | ++ (bfd_boolean); | |
2453 | + extern lang_memory_region_type * lang_memory_region_lookup | |
2454 | + (const char * const, bfd_boolean); | |
2455 | + extern void lang_memory_region_alias | |
2456 | +@@ -660,4 +660,45 @@ ldlang_override_segment_assignment | |
2457 | + extern void | |
2458 | + lang_ld_feature (char *); | |
2459 | + | |
2460 | ++typedef enum | |
2461 | ++{ | |
2462 | ++ cmdline_is_file_enum, | |
2463 | ++ cmdline_is_bfd_enum | |
2464 | ++} cmdline_enum_type; | |
2465 | ++ | |
2466 | ++typedef struct cmdline_header_struct | |
2467 | ++{ | |
2468 | ++ union cmdline_union *next; | |
2469 | ++ cmdline_enum_type type; | |
2470 | ++} cmdline_header_type; | |
2471 | ++ | |
2472 | ++typedef struct cmdline_file_struct | |
2473 | ++{ | |
2474 | ++ cmdline_header_type header; | |
2475 | ++ const char *filename; | |
2476 | ++} cmdline_file_type; | |
2477 | ++ | |
2478 | ++typedef struct cmdline_bfd_struct | |
2479 | ++{ | |
2480 | ++ cmdline_header_type header; | |
2481 | ++ bfd *abfd; | |
2482 | ++} cmdline_bfd_type; | |
2483 | ++ | |
2484 | ++typedef union cmdline_union | |
2485 | ++{ | |
2486 | ++ cmdline_header_type header; | |
2487 | ++ cmdline_file_type file; | |
2488 | ++ cmdline_bfd_type abfd; | |
2489 | ++} cmdline_union_type; | |
2490 | ++ | |
2491 | ++typedef struct cmdline_list | |
2492 | ++{ | |
2493 | ++ cmdline_union_type *head; | |
2494 | ++ cmdline_union_type **tail; | |
2495 | ++} cmdline_list_type; | |
2496 | ++ | |
2497 | ++extern void cmdline_emit_object_only_section (void); | |
2498 | ++extern void cmdline_check_object_only_section (bfd *, bfd_boolean); | |
2499 | ++extern void cmdline_remove_object_only_files (void); | |
2500 | ++ | |
2501 | + #endif | |
2502 | +diff --git a/ld/ldlex.h b/ld/ldlex.h | |
2503 | +index 99f4282..023564f 100644 | |
2504 | +--- a/ld/ldlex.h | |
2505 | ++++ b/ld/ldlex.h | |
2506 | +@@ -134,6 +134,7 @@ enum option_values | |
2507 | + #ifdef ENABLE_PLUGINS | |
2508 | + OPTION_PLUGIN, | |
2509 | + OPTION_PLUGIN_OPT, | |
2510 | ++ OPTION_PLUGIN_SAVE_TEMPS, | |
2511 | + #endif /* ENABLE_PLUGINS */ | |
2512 | + OPTION_DEFAULT_SCRIPT, | |
2513 | + OPTION_PRINT_OUTPUT_FORMAT, | |
2514 | +diff --git a/ld/ldmain.c b/ld/ldmain.c | |
2515 | +index 019df71..8b93bdd 100644 | |
2516 | +--- a/ld/ldmain.c | |
2517 | ++++ b/ld/ldmain.c | |
2518 | +@@ -220,6 +220,9 @@ main (int argc, char **argv) | |
2519 | + | |
2520 | + xatexit (ld_cleanup); | |
2521 | + | |
2522 | ++ /* Remove temporary object-only files. */ | |
2523 | ++ xatexit (cmdline_remove_object_only_files); | |
2524 | ++ | |
2525 | + /* Set up the sysroot directory. */ | |
2526 | + ld_sysroot = get_sysroot (argc, argv); | |
2527 | + if (*ld_sysroot) | |
2528 | +@@ -296,7 +299,7 @@ main (int argc, char **argv) | |
2529 | + default_target = ldemul_choose_target (argc, argv); | |
2530 | + config.maxpagesize = bfd_emul_get_maxpagesize (default_target); | |
2531 | + config.commonpagesize = bfd_emul_get_commonpagesize (default_target); | |
2532 | +- lang_init (); | |
2533 | ++ lang_init (FALSE); | |
2534 | + ldemul_before_parse (); | |
2535 | + lang_has_input_file = FALSE; | |
2536 | + parse_args (argc, argv); | |
2537 | +@@ -311,34 +314,7 @@ main (int argc, char **argv) | |
2538 | + | |
2539 | + ldemul_set_symbols (); | |
2540 | + | |
2541 | +- /* If we have not already opened and parsed a linker script, | |
2542 | +- try the default script from command line first. */ | |
2543 | +- if (saved_script_handle == NULL | |
2544 | +- && command_line.default_script != NULL) | |
2545 | +- { | |
2546 | +- ldfile_open_command_file (command_line.default_script); | |
2547 | +- parser_input = input_script; | |
2548 | +- yyparse (); | |
2549 | +- } | |
2550 | +- | |
2551 | +- /* If we have not already opened and parsed a linker script | |
2552 | +- read the emulation's appropriate default script. */ | |
2553 | +- if (saved_script_handle == NULL) | |
2554 | +- { | |
2555 | +- int isfile; | |
2556 | +- char *s = ldemul_get_script (&isfile); | |
2557 | +- | |
2558 | +- if (isfile) | |
2559 | +- ldfile_open_default_command_file (s); | |
2560 | +- else | |
2561 | +- { | |
2562 | +- lex_string = s; | |
2563 | +- lex_redirect (s, _("built in linker script"), 1); | |
2564 | +- } | |
2565 | +- parser_input = input_script; | |
2566 | +- yyparse (); | |
2567 | +- lex_string = NULL; | |
2568 | +- } | |
2569 | ++ ld_parse_linker_script (); | |
2570 | + | |
2571 | + if (verbose) | |
2572 | + { | |
2573 | +@@ -426,7 +402,7 @@ main (int argc, char **argv) | |
2574 | + if (nocrossref_list != NULL) | |
2575 | + check_nocrossrefs (); | |
2576 | + | |
2577 | +- lang_finish (); | |
2578 | ++ lang_finish (FALSE); | |
2579 | + | |
2580 | + /* Even if we're producing relocatable output, some non-fatal errors should | |
2581 | + be reported in the exit status. (What non-fatal errors, if any, do we | |
2582 | +@@ -445,6 +421,8 @@ main (int argc, char **argv) | |
2583 | + if (! bfd_close (link_info.output_bfd)) | |
2584 | + einfo (_("%F%B: final close failed: %E\n"), link_info.output_bfd); | |
2585 | + | |
2586 | ++ link_info.output_bfd = NULL; | |
2587 | ++ | |
2588 | + /* If the --force-exe-suffix is enabled, and we're making an | |
2589 | + executable file and it doesn't end in .exe, copy it to one | |
2590 | + which does. */ | |
2591 | +@@ -491,6 +469,9 @@ main (int argc, char **argv) | |
2592 | + } | |
2593 | + } | |
2594 | + | |
2595 | ++ if (link_info.emit_gnu_object_only) | |
2596 | ++ cmdline_emit_object_only_section (); | |
2597 | ++ | |
2598 | + END_PROGRESS (program_name); | |
2599 | + | |
2600 | + if (config.stats) | |
2601 | +@@ -798,7 +779,9 @@ add_archive_element (struct bfd_link_info *info, | |
2602 | + } | |
2603 | + } | |
2604 | + } | |
2605 | ++ else | |
2606 | + #endif /* ENABLE_PLUGINS */ | |
2607 | ++ cmdline_check_object_only_section (input->the_bfd, FALSE); | |
2608 | + | |
2609 | + ldlang_add_file (input); | |
2610 | + | |
2611 | +@@ -1467,3 +1450,38 @@ notice (struct bfd_link_info *info, | |
2612 | + | |
2613 | + return TRUE; | |
2614 | + } | |
2615 | ++ | |
2616 | ++/* Parse the linker script. */ | |
2617 | ++ | |
2618 | ++void | |
2619 | ++ld_parse_linker_script () | |
2620 | ++{ | |
2621 | ++ /* If we have not already opened and parsed a linker script, | |
2622 | ++ try the default script from command line first. */ | |
2623 | ++ if (saved_script_handle == NULL | |
2624 | ++ && command_line.default_script != NULL) | |
2625 | ++ { | |
2626 | ++ ldfile_open_command_file (command_line.default_script); | |
2627 | ++ parser_input = input_script; | |
2628 | ++ yyparse (); | |
2629 | ++ } | |
2630 | ++ | |
2631 | ++ /* If we have not already opened and parsed a linker script | |
2632 | ++ read the emulation's appropriate default script. */ | |
2633 | ++ if (saved_script_handle == NULL) | |
2634 | ++ { | |
2635 | ++ int isfile; | |
2636 | ++ char *s = ldemul_get_script (&isfile); | |
2637 | ++ | |
2638 | ++ if (isfile) | |
2639 | ++ ldfile_open_default_command_file (s); | |
2640 | ++ else | |
2641 | ++ { | |
2642 | ++ lex_string = s; | |
2643 | ++ lex_redirect (s, _("built in linker script"), 1); | |
2644 | ++ } | |
2645 | ++ parser_input = input_script; | |
2646 | ++ yyparse (); | |
2647 | ++ lex_string = NULL; | |
2648 | ++ } | |
2649 | ++} | |
2650 | +diff --git a/ld/ldmain.h b/ld/ldmain.h | |
2651 | +index 90558a1..39ab014 100644 | |
2652 | +--- a/ld/ldmain.h | |
2653 | ++++ b/ld/ldmain.h | |
2654 | +@@ -59,4 +59,6 @@ extern void add_wrap (const char *); | |
2655 | + extern void add_ignoresym (struct bfd_link_info *, const char *); | |
2656 | + extern void add_keepsyms_file (const char *); | |
2657 | + | |
2658 | ++extern void ld_parse_linker_script (void); | |
2659 | ++ | |
2660 | + #endif | |
2661 | +diff --git a/ld/lexsup.c b/ld/lexsup.c | |
2662 | +index 2f71750..e6c4a7c 100644 | |
2663 | +--- a/ld/lexsup.c | |
2664 | ++++ b/ld/lexsup.c | |
2665 | +@@ -168,6 +168,9 @@ static const struct ld_option ld_options[] = | |
2666 | + '\0', N_("PLUGIN"), N_("Load named plugin"), ONE_DASH }, | |
2667 | + { {"plugin-opt", required_argument, NULL, OPTION_PLUGIN_OPT}, | |
2668 | + '\0', N_("ARG"), N_("Send arg to last-loaded plugin"), ONE_DASH }, | |
2669 | ++ { {"plugin-save-temps", no_argument, NULL, OPTION_PLUGIN_SAVE_TEMPS}, | |
2670 | ++ '\0', NULL, N_("Store plugin intermediate files permanently"), | |
2671 | ++ ONE_DASH }, | |
2672 | + { {"flto", optional_argument, NULL, OPTION_IGNORE}, | |
2673 | + '\0', NULL, N_("Ignored for GCC LTO option compatibility"), | |
2674 | + ONE_DASH }, | |
2675 | +@@ -967,6 +970,9 @@ parse_args (unsigned argc, char **argv) | |
2676 | + if (plugin_opt_plugin_arg (optarg)) | |
2677 | + einfo(_("%P%F: bad -plugin-opt option\n")); | |
2678 | + break; | |
2679 | ++ case OPTION_PLUGIN_SAVE_TEMPS: | |
2680 | ++ plugin_save_temps = TRUE; | |
2681 | ++ break; | |
2682 | + #endif /* ENABLE_PLUGINS */ | |
2683 | + case 'q': | |
2684 | + link_info.emitrelocations = TRUE; | |
2685 | +diff --git a/ld/plugin.c b/ld/plugin.c | |
2686 | +index 0d5339f..1037c88 100644 | |
2687 | +--- a/ld/plugin.c | |
2688 | ++++ b/ld/plugin.c | |
2689 | +@@ -39,6 +39,9 @@ | |
2690 | + /* Report plugin symbols. */ | |
2691 | + bfd_boolean report_plugin_symbols; | |
2692 | + | |
2693 | ++/* Store plugin intermediate files permanently. */ | |
2694 | ++bfd_boolean plugin_save_temps; | |
2695 | ++ | |
2696 | + /* The suffix to append to the name of the real (claimed) object file | |
2697 | + when generating a dummy BFD to hold the IR symbols sent from the | |
2698 | + plugin. For cosmetic use only; appears in maps, crefs etc. */ | |
2699 | +@@ -217,6 +220,17 @@ plugin_opt_plugin_arg (const char *arg) | |
2700 | + if (!last_plugin) | |
2701 | + return set_plugin_error (_("<no plugin>")); | |
2702 | + | |
2703 | ++ /* Ignore -pass-through= from GCC driver. */ | |
2704 | ++ if (*arg == '-') | |
2705 | ++ { | |
2706 | ++ const char *p; | |
2707 | ++ for (p = arg + 1; p; p++) | |
2708 | ++ if (*p != '-') | |
2709 | ++ break; | |
2710 | ++ if (strncmp (p, "pass-through=", 13) == 0) | |
2711 | ++ return 0; | |
2712 | ++ } | |
2713 | ++ | |
2714 | + newarg = xmalloc (sizeof *newarg); | |
2715 | + newarg->arg = arg; | |
2716 | + newarg->next = NULL; | |
2717 | +@@ -874,6 +888,9 @@ plugin_maybe_claim (struct ld_plugin_input_file *file, | |
2718 | + close (file->fd); | |
2719 | + if (claimed) | |
2720 | + { | |
2721 | ++ /* Check object only section. */ | |
2722 | ++ cmdline_check_object_only_section (entry->the_bfd, TRUE); | |
2723 | ++ | |
2724 | + /* Discard the real file's BFD and substitute the dummy one. */ | |
2725 | + | |
2726 | + /* BFD archive handling caches elements so we can't call | |
2727 | +@@ -927,14 +944,17 @@ plugin_call_cleanup (void) | |
2728 | + { | |
2729 | + if (curplug->cleanup_handler && !curplug->cleanup_done) | |
2730 | + { | |
2731 | +- enum ld_plugin_status rv; | |
2732 | +- curplug->cleanup_done = TRUE; | |
2733 | +- called_plugin = curplug; | |
2734 | +- rv = (*curplug->cleanup_handler) (); | |
2735 | +- called_plugin = NULL; | |
2736 | +- if (rv != LDPS_OK) | |
2737 | +- info_msg (_("%P: %s: error in plugin cleanup: %d (ignored)\n"), | |
2738 | +- curplug->name, rv); | |
2739 | ++ if (!plugin_save_temps) | |
2740 | ++ { | |
2741 | ++ enum ld_plugin_status rv; | |
2742 | ++ curplug->cleanup_done = TRUE; | |
2743 | ++ called_plugin = curplug; | |
2744 | ++ rv = (*curplug->cleanup_handler) (); | |
2745 | ++ called_plugin = NULL; | |
2746 | ++ if (rv != LDPS_OK) | |
2747 | ++ info_msg (_("%P: %s: error in plugin cleanup: %d (ignored)\n"), | |
2748 | ++ curplug->name, rv); | |
2749 | ++ } | |
2750 | + dlclose (curplug->dlhandle); | |
2751 | + } | |
2752 | + curplug = curplug->next; | |
2753 | +diff --git a/ld/plugin.h b/ld/plugin.h | |
2754 | +index a227575..d41aa53 100644 | |
2755 | +--- a/ld/plugin.h | |
2756 | ++++ b/ld/plugin.h | |
2757 | +@@ -24,6 +24,9 @@ | |
2758 | + /* Report plugin symbols. */ | |
2759 | + extern bfd_boolean report_plugin_symbols; | |
2760 | + | |
2761 | ++/* Store plugin intermediate files permanently. */ | |
2762 | ++extern bfd_boolean plugin_save_temps; | |
2763 | ++ | |
2764 | + /* Set at all symbols read time, to avoid recursively offering the plugin | |
2765 | + its own newly-added input files and libs to claim. */ | |
2766 | + extern bfd_boolean no_more_claiming; | |
2767 | +diff --git a/ld/scripttempl/armbpabi.sc b/ld/scripttempl/armbpabi.sc | |
2768 | +index a1bbc2b..d85aeba 100644 | |
2769 | +--- a/ld/scripttempl/armbpabi.sc | |
2770 | ++++ b/ld/scripttempl/armbpabi.sc | |
2771 | +@@ -30,7 +30,7 @@ INTERP=".interp 0 : { *(.interp) }" | |
2772 | + PLT=".plt ${RELOCATING-0} : { *(.plt) }" | |
2773 | + RODATA=".rodata ${RELOCATING-0} : { *(.rodata${RELOCATING+ .rodata.* .gnu.linkonce.r.*}) }" | |
2774 | + DATARELRO=".data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro .data.rel.ro.*) }" | |
2775 | +-DISCARDED="/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }" | |
2776 | ++DISCARDED="/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu_object_only) }" | |
2777 | + if test -z "${NO_SMALL_DATA}"; then | |
2778 | + SBSS=".sbss ${RELOCATING-0} : | |
2779 | + { | |
2780 | +diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc | |
2781 | +index e8126cb..f295c10 100644 | |
2782 | +--- a/ld/scripttempl/elf.sc | |
2783 | ++++ b/ld/scripttempl/elf.sc | |
2784 | +@@ -160,7 +160,7 @@ RELA_IPLT=".rela.iplt ${RELOCATING-0} : | |
2785 | + DYNAMIC=".dynamic ${RELOCATING-0} : { *(.dynamic) }" | |
2786 | + RODATA=".${RODATA_NAME} ${RELOCATING-0} : { *(.${RODATA_NAME}${RELOCATING+ .${RODATA_NAME}.* .gnu.linkonce.r.*}) }" | |
2787 | + DATARELRO=".data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }" | |
2788 | +-DISCARDED="/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }" | |
2789 | ++DISCARDED="/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu_object_only) }" | |
2790 | + if test -z "${NO_SMALL_DATA}"; then | |
2791 | + SBSS=".${SBSS_NAME} ${RELOCATING-0} : | |
2792 | + { | |
2793 | +diff --git a/ld/scripttempl/elf32sh-symbian.sc b/ld/scripttempl/elf32sh-symbian.sc | |
2794 | +index 680028f..9130376 100644 | |
2795 | +--- a/ld/scripttempl/elf32sh-symbian.sc | |
2796 | ++++ b/ld/scripttempl/elf32sh-symbian.sc | |
2797 | +@@ -83,7 +83,7 @@ fi | |
2798 | + PLT=".plt : { *(.plt) } :dynamic :dyn" | |
2799 | + DYNAMIC=".dynamic : { *(.dynamic) } :dynamic :dyn" | |
2800 | + RODATA=".rodata ALIGN(4) : { *(.rodata${RELOCATING+ .rodata.* .gnu.linkonce.r.*}) }" | |
2801 | +-DISCARDED="/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.directive) *(.gnu.lto_*) }" | |
2802 | ++DISCARDED="/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.directive) *(.gnu.lto_*) *(.gnu_object_only) }" | |
2803 | + test -z "$GOT" && GOT=".got ${RELOCATING-0} : { *(.got.plt) *(.got) } :dynamic :dyn" | |
2804 | + INIT_ARRAY=".init_array ${RELOCATING-0} : | |
2805 | + { | |
2806 | +diff --git a/ld/scripttempl/elf64hppa.sc b/ld/scripttempl/elf64hppa.sc | |
2807 | +index d529f8d..7676925 100644 | |
2808 | +--- a/ld/scripttempl/elf64hppa.sc | |
2809 | ++++ b/ld/scripttempl/elf64hppa.sc | |
2810 | +@@ -127,7 +127,7 @@ fi | |
2811 | + DYNAMIC=".dynamic ${RELOCATING-0} : { *(.dynamic) }" | |
2812 | + RODATA=".rodata ${RELOCATING-0} : { *(.rodata${RELOCATING+ .rodata.* .gnu.linkonce.r.*}) }" | |
2813 | + DATARELRO=".data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }" | |
2814 | +-DISCARDED="/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }" | |
2815 | ++DISCARDED="/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu_object_only) }" | |
2816 | + if test -z "${NO_SMALL_DATA}"; then | |
2817 | + SBSS=".sbss ${RELOCATING-0} : | |
2818 | + { | |
2819 | +diff --git a/ld/scripttempl/elfxtensa.sc b/ld/scripttempl/elfxtensa.sc | |
2820 | +index b51fe6a..a440d68 100644 | |
2821 | +--- a/ld/scripttempl/elfxtensa.sc | |
2822 | ++++ b/ld/scripttempl/elfxtensa.sc | |
2823 | +@@ -140,7 +140,7 @@ fi | |
2824 | + DYNAMIC=".dynamic ${RELOCATING-0} : { *(.dynamic) }" | |
2825 | + RODATA=".rodata ${RELOCATING-0} : { *(.rodata${RELOCATING+ .rodata.* .gnu.linkonce.r.*}) }" | |
2826 | + DATARELRO=".data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }" | |
2827 | +-DISCARDED="/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }" | |
2828 | ++DISCARDED="/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu_object_only) }" | |
2829 | + INIT_LIT=".init.literal 0 : { *(.init.literal) }" | |
2830 | + INIT=".init 0 : { *(.init) }" | |
2831 | + FINI_LIT=".fini.literal 0 : { *(.fini.literal) }" | |
2832 | +diff --git a/ld/scripttempl/mep.sc b/ld/scripttempl/mep.sc | |
2833 | +index cf85f76..562696b 100644 | |
2834 | +--- a/ld/scripttempl/mep.sc | |
2835 | ++++ b/ld/scripttempl/mep.sc | |
2836 | +@@ -114,7 +114,7 @@ fi | |
2837 | + DYNAMIC=".dynamic ${RELOCATING-0} : { *(.dynamic) }" | |
2838 | + RODATA=".rodata ${RELOCATING-0} : { *(.rodata${RELOCATING+ .rodata.* .gnu.linkonce.r.*}) }" | |
2839 | + DATARELRO=".data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro .data.rel.ro.*) }" | |
2840 | +-DISCARDED="/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }" | |
2841 | ++DISCARDED="/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu_object_only) }" | |
2842 | + if test -z "${NO_SMALL_DATA}"; then | |
2843 | + SBSS=".sbss ${RELOCATING-0} : | |
2844 | + { | |
2845 | +diff --git a/ld/scripttempl/pe.sc b/ld/scripttempl/pe.sc | |
2846 | +index 59ce042..3968076 100644 | |
2847 | +--- a/ld/scripttempl/pe.sc | |
2848 | ++++ b/ld/scripttempl/pe.sc | |
2849 | +@@ -151,6 +151,7 @@ SECTIONS | |
2850 | + *(.drectve) | |
2851 | + ${RELOCATING+ *(.note.GNU-stack)} | |
2852 | + ${RELOCATING+ *(.gnu.lto_*)} | |
2853 | ++ ${RELOCATING+ *(.gnu_object_only)} | |
2854 | + } | |
2855 | + | |
2856 | + .idata ${RELOCATING+BLOCK(__section_alignment__)} : | |
2857 | +diff --git a/ld/scripttempl/pep.sc b/ld/scripttempl/pep.sc | |
2858 | +index 884baaf..5040ade 100644 | |
2859 | +--- a/ld/scripttempl/pep.sc | |
2860 | ++++ b/ld/scripttempl/pep.sc | |
2861 | +@@ -156,6 +156,7 @@ SECTIONS | |
2862 | + *(.drectve) | |
2863 | + ${RELOCATING+ *(.note.GNU-stack)} | |
2864 | + ${RELOCATING+ *(.gnu.lto_*)} | |
2865 | ++ ${RELOCATING+ *(.gnu_object_only)} | |
2866 | + } | |
2867 | + | |
2868 | + .idata ${RELOCATING+BLOCK(__section_alignment__)} : | |
2869 | +diff --git a/ld/testsuite/ld-plugin/lto-10.out b/ld/testsuite/ld-plugin/lto-10.out | |
2870 | +new file mode 100644 | |
2871 | +index 0000000..ce01362 | |
2872 | +--- /dev/null | |
2873 | ++++ b/ld/testsuite/ld-plugin/lto-10.out | |
2874 | +@@ -0,0 +1 @@ | |
2875 | ++hello | |
2876 | +diff --git a/ld/testsuite/ld-plugin/lto-10a.c b/ld/testsuite/ld-plugin/lto-10a.c | |
2877 | +new file mode 100644 | |
2878 | +index 0000000..93d57b5 | |
2879 | +--- /dev/null | |
2880 | ++++ b/ld/testsuite/ld-plugin/lto-10a.c | |
2881 | +@@ -0,0 +1,6 @@ | |
2882 | ++extern int foo(void); | |
2883 | ++ | |
2884 | ++int main(void) | |
2885 | ++{ | |
2886 | ++ return foo(); | |
2887 | ++} | |
2888 | +diff --git a/ld/testsuite/ld-plugin/lto-10b.c b/ld/testsuite/ld-plugin/lto-10b.c | |
2889 | +new file mode 100644 | |
2890 | +index 0000000..507055b | |
2891 | +--- /dev/null | |
2892 | ++++ b/ld/testsuite/ld-plugin/lto-10b.c | |
2893 | +@@ -0,0 +1,7 @@ | |
2894 | ++#include <stdio.h> | |
2895 | ++ | |
2896 | ++int foo(void) | |
2897 | ++{ | |
2898 | ++ printf ("hello\n"); | |
2899 | ++ return 0; | |
2900 | ++} | |
2901 | +diff --git a/ld/testsuite/ld-plugin/lto-10r.d b/ld/testsuite/ld-plugin/lto-10r.d | |
2902 | +new file mode 100644 | |
2903 | +index 0000000..689e6ec | |
2904 | +--- /dev/null | |
2905 | ++++ b/ld/testsuite/ld-plugin/lto-10r.d | |
2906 | +@@ -0,0 +1,7 @@ | |
2907 | ++#ld: -r tmpdir/lto-10a.o tmpdir/lto-10b.o | |
2908 | ++#source: dummy.s | |
2909 | ++#nm: -p | |
2910 | ++ | |
2911 | ++#... | |
2912 | ++[0-9a-f]+ C __gnu_lto_v.* | |
2913 | ++#pass | |
2914 | +diff --git a/ld/testsuite/ld-plugin/lto-4.out b/ld/testsuite/ld-plugin/lto-4.out | |
2915 | +new file mode 100644 | |
2916 | +index 0000000..8d8cc92 | |
2917 | +--- /dev/null | |
2918 | ++++ b/ld/testsuite/ld-plugin/lto-4.out | |
2919 | +@@ -0,0 +1,2 @@ | |
2920 | ++hello bar | |
2921 | ++hello foo | |
2922 | +diff --git a/ld/testsuite/ld-plugin/lto-4a.c b/ld/testsuite/ld-plugin/lto-4a.c | |
2923 | +new file mode 100644 | |
2924 | +index 0000000..2d07cf5 | |
2925 | +--- /dev/null | |
2926 | ++++ b/ld/testsuite/ld-plugin/lto-4a.c | |
2927 | +@@ -0,0 +1,7 @@ | |
2928 | ++extern void foo(void); | |
2929 | ++ | |
2930 | ++int main(void) | |
2931 | ++{ | |
2932 | ++ foo(); | |
2933 | ++ return 0; | |
2934 | ++} | |
2935 | +diff --git a/ld/testsuite/ld-plugin/lto-4b.c b/ld/testsuite/ld-plugin/lto-4b.c | |
2936 | +new file mode 100644 | |
2937 | +index 0000000..bb4a68b | |
2938 | +--- /dev/null | |
2939 | ++++ b/ld/testsuite/ld-plugin/lto-4b.c | |
2940 | +@@ -0,0 +1,9 @@ | |
2941 | ++#include <stdio.h> | |
2942 | ++ | |
2943 | ++extern void bar (void); | |
2944 | ++ | |
2945 | ++void foo(void) | |
2946 | ++{ | |
2947 | ++ bar (); | |
2948 | ++ printf ("hello foo\n"); | |
2949 | ++} | |
2950 | +diff --git a/ld/testsuite/ld-plugin/lto-4c.c b/ld/testsuite/ld-plugin/lto-4c.c | |
2951 | +new file mode 100644 | |
2952 | +index 0000000..317e6fc | |
2953 | +--- /dev/null | |
2954 | ++++ b/ld/testsuite/ld-plugin/lto-4c.c | |
2955 | +@@ -0,0 +1,6 @@ | |
2956 | ++#include <stdio.h> | |
2957 | ++ | |
2958 | ++void bar (void) | |
2959 | ++{ | |
2960 | ++ printf ("hello bar\n"); | |
2961 | ++} | |
2962 | +diff --git a/ld/testsuite/ld-plugin/lto-4r-a.d b/ld/testsuite/ld-plugin/lto-4r-a.d | |
2963 | +new file mode 100644 | |
2964 | +index 0000000..c618cff | |
2965 | +--- /dev/null | |
2966 | ++++ b/ld/testsuite/ld-plugin/lto-4r-a.d | |
2967 | +@@ -0,0 +1,7 @@ | |
2968 | ++#ld: -r tmpdir/lto-4a.o tmpdir/lto-4b.o tmpdir/lto-4c.o | |
2969 | ++#source: dummy.s | |
2970 | ++#objdump: -h | |
2971 | ++ | |
2972 | ++#... | |
2973 | ++.* .gnu_object_only.* | |
2974 | ++#pass | |
2975 | +diff --git a/ld/testsuite/ld-plugin/lto-4r-b.d b/ld/testsuite/ld-plugin/lto-4r-b.d | |
2976 | +new file mode 100644 | |
2977 | +index 0000000..07d71cb | |
2978 | +--- /dev/null | |
2979 | ++++ b/ld/testsuite/ld-plugin/lto-4r-b.d | |
2980 | +@@ -0,0 +1,7 @@ | |
2981 | ++#ld: -r tmpdir/lto-4a.o tmpdir/lto-4b.o | |
2982 | ++#source: dummy.s | |
2983 | ++#objdump: -h | |
2984 | ++ | |
2985 | ++#... | |
2986 | ++.* .gnu_object_only.* | |
2987 | ++#pass | |
2988 | +diff --git a/ld/testsuite/ld-plugin/lto-4r-c.d b/ld/testsuite/ld-plugin/lto-4r-c.d | |
2989 | +new file mode 100644 | |
2990 | +index 0000000..ada50c0 | |
2991 | +--- /dev/null | |
2992 | ++++ b/ld/testsuite/ld-plugin/lto-4r-c.d | |
2993 | +@@ -0,0 +1,7 @@ | |
2994 | ++#ld: -r tmpdir/lto-4r-b.o tmpdir/lto-4c.o | |
2995 | ++#source: dummy.s | |
2996 | ++#objdump: -h | |
2997 | ++ | |
2998 | ++#... | |
2999 | ++.* .gnu_object_only.* | |
3000 | ++#pass | |
3001 | +diff --git a/ld/testsuite/ld-plugin/lto-4r-d.d b/ld/testsuite/ld-plugin/lto-4r-d.d | |
3002 | +new file mode 100644 | |
3003 | +index 0000000..d4c5852 | |
3004 | +--- /dev/null | |
3005 | ++++ b/ld/testsuite/ld-plugin/lto-4r-d.d | |
3006 | +@@ -0,0 +1,7 @@ | |
3007 | ++#ld: -r --whole-archive tmpdir/liblto-4.a | |
3008 | ++#source: dummy.s | |
3009 | ++#objdump: -h | |
3010 | ++ | |
3011 | ++#... | |
3012 | ++.* .gnu_object_only.* | |
3013 | ++#pass | |
3014 | +diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp | |
3015 | +index c5249f0..b91bce0 100644 | |
3016 | +--- a/ld/testsuite/ld-plugin/lto.exp | |
3017 | ++++ b/ld/testsuite/ld-plugin/lto.exp | |
3018 | +@@ -59,6 +59,15 @@ set lto_link_tests { | |
3019 | + {"Build liblto-3.a" | |
3020 | + "" "-flto" | |
3021 | + {lto-3b.c} {} "liblto-3.a"} | |
3022 | ++ {"Build libdummy.a 4a" | |
3023 | ++ "" "-flto" | |
3024 | ++ {lto-4a.c} {} "libdummy.a"} | |
3025 | ++ {"Build libdummy.a 4b" | |
3026 | ++ "" "-O2" | |
3027 | ++ {lto-4b.c} {} "libdummy.a"} | |
3028 | ++ {"Build libdummy.a 4c" | |
3029 | ++ "" "-O2" | |
3030 | ++ {lto-4c.c} {} "libdummy.a"} | |
3031 | + {"Build libdummy.a 5a" | |
3032 | + "" "-flto" | |
3033 | + {lto-5a.c} {} "libdummy.a"} | |
3034 | +@@ -68,9 +77,18 @@ set lto_link_tests { | |
3035 | + {"LTO 6" | |
3036 | + "-O2 -flto -fuse-linker-plugin" "" | |
3037 | + {lto-6.c} {} "lto-6.exe" "c"} | |
3038 | ++ {"Build libdummy.a PR ld/12365" | |
3039 | ++ "" "-flto -O2" | |
3040 | ++ {pr12365a.c pr12365b.c pr12365c.c} {} "libdummy.a"} | |
3041 | + {"Build libdummy.a 9" | |
3042 | + "" "-O2 -finline -flto" | |
3043 | + {lto-9.cc} {} "libdummy.a"} | |
3044 | ++ {"Build libdummy.a 10a" | |
3045 | ++ "" "-O2" | |
3046 | ++ {lto-10a.c} {} "libdummy.a"} | |
3047 | ++ {"Build libdummy.a 10b" | |
3048 | ++ "" "-O2 -flto" | |
3049 | ++ {lto-10b.c} {} "libdummy.a"} | |
3050 | + {"Build libdummy.a 11a" | |
3051 | + "" "-O -flto" | |
3052 | + {lto-11a.c} {} "libdummy.a"} | |
3053 | +@@ -206,6 +224,9 @@ set lto_link_elf_tests { | |
3054 | + {"Build libpr15146d.a" | |
3055 | + "" "-flto -O2" | |
3056 | + {pr15146d.c} {} "lib15146d.a"} | |
3057 | ++ {"PR ld/14918" | |
3058 | ++ "-flto" "-flto" | |
3059 | ++ {pr14918.c} {{"readelf" {-d --wide} "pr14918.d"}} "pr14918.exe" "c"} | |
3060 | + } | |
3061 | + | |
3062 | + # Check final symbols in executables. | |
3063 | +@@ -241,9 +262,21 @@ set lto_run_tests { | |
3064 | + {"LTO 3c" | |
3065 | + "-O2 -flto -fuse-linker-plugin tmpdir/lto-3a.o tmpdir/lto-3c.o -Wl,--whole-archive tmpdir/liblto-3.a -Wl,--no-whole-archive tmpdir/liblto-3.a" "" | |
3066 | + {dummy.c} "lto-3d.exe" "lto-3.out" "" "c"} | |
3067 | ++ {"LTO 4a" | |
3068 | ++ "-O2 -flto -fuse-linker-plugin tmpdir/lto-4r-a.o" "" | |
3069 | ++ {dummy.c} "lto-4a.exe" "lto-4.out" "" "c"} | |
3070 | ++ {"LTO 4c" | |
3071 | ++ "-O2 -flto -fuse-linker-plugin tmpdir/lto-4r-c.o" "" | |
3072 | ++ {dummy.c} "lto-4c.exe" "lto-4.out" "" "c"} | |
3073 | ++ {"LTO 4d" | |
3074 | ++ "-O2 -flto -fuse-linker-plugin tmpdir/lto-4r-d.o" "" | |
3075 | ++ {dummy.c} "lto-4d.exe" "lto-4.out" "" "c"} | |
3076 | + {"LTO 5" | |
3077 | + "-O2 -flto -fuse-linker-plugin tmpdir/lto-5.o" "" | |
3078 | + {dummy.c} "lto-5.exe" "lto-5.out" "" "c"} | |
3079 | ++ {"LTO 10" | |
3080 | ++ "-O2 -flto -fuse-linker-plugin tmpdir/lto-10.o" "" | |
3081 | ++ {dummy.c} "lto-10.exe" "lto-10.out" "" "c"} | |
3082 | + {"LTO 11" | |
3083 | + "-O -flto -fuse-linker-plugin tmpdir/liblto-11.a" "" | |
3084 | + {dummy.c} "lto-11.exe" "lto-11.out" "" "c"} | |
3085 | +@@ -312,6 +345,15 @@ if { [is_elf_format] | |
3086 | + } | |
3087 | + } | |
3088 | + | |
3089 | ++set testname "Build liblto-4.a" | |
3090 | ++remote_file host delete "tmpdir/liblto-4.a" | |
3091 | ++set catch_output [run_host_cmd "$ar" "rc tmpdir/liblto-4.a tmpdir/lto-4a.o tmpdir/lto-4b.o tmpdir/lto-4c.o"] | |
3092 | ++if {![string match "" $catch_output]} { | |
3093 | ++ unresolved $testname | |
3094 | ++ restore_notify | |
3095 | ++ return | |
3096 | ++} | |
3097 | ++ | |
3098 | + set testname "Build liblto-11.a" | |
3099 | + remote_file host delete "tmpdir/liblto-11.a" | |
3100 | + set catch_output [run_host_cmd "$ar" "rc tmpdir/liblto-11.a tmpdir/lto-11a.o tmpdir/lto-11b.o tmpdir/lto-11c.o"] | |
3101 | +@@ -323,6 +365,13 @@ if {![string match "" $catch_output]} { | |
3102 | + | |
3103 | + if { [at_least_gcc_version 4 7] } { | |
3104 | + # Check expected LTO linker errors. | |
3105 | ++ set testname "PR ld/12365" | |
3106 | ++ set exec_output [run_host_cmd "$CC" "$gcc_gas_flag $gcc_ld_flag -O2 -flto -fuse-linker-plugin tmpdir/pr12365a.o tmpdir/pr12365b.o tmpdir/pr12365c.o"] | |
3107 | ++ if { [ regexp "undefined reference to `my_bcopy'" $exec_output ] } { | |
3108 | ++ pass $testname | |
3109 | ++ } { | |
3110 | ++ fail $testname | |
3111 | ++ } | |
3112 | + set testname "PR ld/12942 (3)" | |
3113 | + set exec_output [run_host_cmd "$CXX" "$gcc_gas_flag $gcc_ld_flag -O2 -flto -fuse-linker-plugin tmpdir/pr12942b.o tmpdir/pr12942a.o"] | |
3114 | + if { [ regexp "undefined reference to `link_error\\(\\)'" $exec_output ] } { | |
3115 | +@@ -335,8 +384,18 @@ if { [at_least_gcc_version 4 7] } { | |
3116 | + # Run "ld -r" to generate inputs for complex LTO tests. | |
3117 | + run_dump_test "lto-3r" | |
3118 | + remote_exec host "mv" "tmpdir/dump tmpdir/lto-3.o" | |
3119 | ++run_dump_test "lto-4r-a" | |
3120 | ++remote_exec host "mv" "tmpdir/dump tmpdir/lto-4r-a.o" | |
3121 | ++run_dump_test "lto-4r-b" | |
3122 | ++remote_exec host "mv" "tmpdir/dump tmpdir/lto-4r-b.o" | |
3123 | ++run_dump_test "lto-4r-c" | |
3124 | ++remote_exec host "mv" "tmpdir/dump tmpdir/lto-4r-c.o" | |
3125 | ++run_dump_test "lto-4r-d" | |
3126 | ++remote_exec host "mv" "tmpdir/dump tmpdir/lto-4r-d.o" | |
3127 | + run_dump_test "lto-5r" | |
3128 | + remote_exec host "mv" "tmpdir/dump tmpdir/lto-5.o" | |
3129 | ++run_dump_test "lto-10r" | |
3130 | ++remote_exec host "mv" "tmpdir/dump tmpdir/lto-10.o" | |
3131 | + | |
3132 | + run_cc_link_tests $lto_link_symbol_tests | |
3133 | + | |
3134 | +diff --git a/ld/testsuite/ld-plugin/pr12365a.c b/ld/testsuite/ld-plugin/pr12365a.c | |
3135 | +new file mode 100644 | |
3136 | +index 0000000..a9bb6c6 | |
3137 | +--- /dev/null | |
3138 | ++++ b/ld/testsuite/ld-plugin/pr12365a.c | |
3139 | +@@ -0,0 +1,25 @@ | |
3140 | ++extern void abort(void); | |
3141 | ++extern void main_test (void); | |
3142 | ++extern void abort (void); | |
3143 | ++int inside_main; | |
3144 | ++ | |
3145 | ++int | |
3146 | ++main () | |
3147 | ++{ | |
3148 | ++ inside_main = 1; | |
3149 | ++ main_test (); | |
3150 | ++ inside_main = 0; | |
3151 | ++ return 0; | |
3152 | ++} | |
3153 | ++ | |
3154 | ++/* When optimizing, all the constant cases should have been | |
3155 | ++ constant folded, so no calls to link_error should remain. | |
3156 | ++ In any case, link_error should not be called. */ | |
3157 | ++ | |
3158 | ++#ifndef __OPTIMIZE__ | |
3159 | ++void | |
3160 | ++link_error (void) | |
3161 | ++{ | |
3162 | ++ abort (); | |
3163 | ++} | |
3164 | ++#endif | |
3165 | +diff --git a/ld/testsuite/ld-plugin/pr12365b.c b/ld/testsuite/ld-plugin/pr12365b.c | |
3166 | +new file mode 100644 | |
3167 | +index 0000000..3e86e06 | |
3168 | +--- /dev/null | |
3169 | ++++ b/ld/testsuite/ld-plugin/pr12365b.c | |
3170 | +@@ -0,0 +1,47 @@ | |
3171 | ++#define ASMNAME(cname) ASMNAME2 (__USER_LABEL_PREFIX__, cname) | |
3172 | ++#define ASMNAME2(prefix, cname) STRING (prefix) cname | |
3173 | ++#define STRING(x) #x | |
3174 | ++ | |
3175 | ++typedef __SIZE_TYPE__ size_t; | |
3176 | ++extern void abort (void); | |
3177 | ++extern void *memcpy (void *, const void *, size_t) | |
3178 | ++ __asm (ASMNAME ("my_memcpy")); | |
3179 | ++extern void bcopy (const void *, void *, size_t) | |
3180 | ++ __asm (ASMNAME ("my_bcopy")); | |
3181 | ++extern void *memset (void *, int, size_t) | |
3182 | ++ __asm (ASMNAME ("my_memset")); | |
3183 | ++extern void bzero (void *, size_t) | |
3184 | ++ __asm (ASMNAME ("my_bzero")); | |
3185 | ++extern int memcmp (const void *, const void *, size_t); | |
3186 | ++ | |
3187 | ++struct A { char c[32]; } a = { "foobar" }; | |
3188 | ++char x[64] = "foobar", y[64]; | |
3189 | ++int i = 39, j = 6, k = 4; | |
3190 | ++ | |
3191 | ++extern int inside_main; | |
3192 | ++ | |
3193 | ++void | |
3194 | ++main_test (void) | |
3195 | ++{ | |
3196 | ++ struct A b = a; | |
3197 | ++ struct A c = { { 'x' } }; | |
3198 | ++ | |
3199 | ++ inside_main = 1; | |
3200 | ++ | |
3201 | ++ if (memcmp (b.c, x, 32) || c.c[0] != 'x' || memcmp (c.c + 1, x + 32, 31)) | |
3202 | ++ abort (); | |
3203 | ++ if (__builtin_memcpy (y, x, i) != y || memcmp (x, y, 64)) | |
3204 | ++ abort (); | |
3205 | ++ if (memcpy (y + 6, x, j) != y + 6 | |
3206 | ++ || memcmp (x, y, 6) || memcmp (x, y + 6, 58)) | |
3207 | ++ abort (); | |
3208 | ++ if (__builtin_memset (y + 2, 'X', k) != y + 2 | |
3209 | ++ || memcmp (y, "foXXXXfoobar", 13)) | |
3210 | ++ abort (); | |
3211 | ++ bcopy (y + 1, y + 2, 6); | |
3212 | ++ if (memcmp (y, "fooXXXXfobar", 13)) | |
3213 | ++ abort (); | |
3214 | ++ __builtin_bzero (y + 4, 2); | |
3215 | ++ if (memcmp (y, "fooX\0\0Xfobar", 13)) | |
3216 | ++ abort (); | |
3217 | ++} | |
3218 | +diff --git a/ld/testsuite/ld-plugin/pr12365c.c b/ld/testsuite/ld-plugin/pr12365c.c | |
3219 | +new file mode 100644 | |
3220 | +index 0000000..2edd0ff | |
3221 | +--- /dev/null | |
3222 | ++++ b/ld/testsuite/ld-plugin/pr12365c.c | |
3223 | +@@ -0,0 +1,79 @@ | |
3224 | ++extern void abort (void); | |
3225 | ++extern int inside_main; | |
3226 | ++typedef __SIZE_TYPE__ size_t; | |
3227 | ++ | |
3228 | ++#define TEST_ABORT if (inside_main) abort() | |
3229 | ++ | |
3230 | ++void * | |
3231 | ++my_memcpy (void *d, const void *s, size_t n) | |
3232 | ++{ | |
3233 | ++ char *dst = (char *) d; | |
3234 | ++ const char *src = (const char *) s; | |
3235 | ++ while (n--) | |
3236 | ++ *dst++ = *src++; | |
3237 | ++ return (char *) d; | |
3238 | ++} | |
3239 | ++ | |
3240 | ++void | |
3241 | ++my_bcopy (const void *s, void *d, size_t n) | |
3242 | ++{ | |
3243 | ++ char *dst = (char *) d; | |
3244 | ++ const char *src = (const char *) s; | |
3245 | ++ if (src >= dst) | |
3246 | ++ while (n--) | |
3247 | ++ *dst++ = *src++; | |
3248 | ++ else | |
3249 | ++ { | |
3250 | ++ dst += n; | |
3251 | ++ src += n; | |
3252 | ++ while (n--) | |
3253 | ++ *--dst = *--src; | |
3254 | ++ } | |
3255 | ++} | |
3256 | ++ | |
3257 | ++void * | |
3258 | ++my_memset (void *d, int c, size_t n) | |
3259 | ++{ | |
3260 | ++ char *dst = (char *) d; | |
3261 | ++ while (n--) | |
3262 | ++ *dst++ = c; | |
3263 | ++ return (char *) d; | |
3264 | ++} | |
3265 | ++ | |
3266 | ++void | |
3267 | ++my_bzero (void *d, size_t n) | |
3268 | ++{ | |
3269 | ++ char *dst = (char *) d; | |
3270 | ++ while (n--) | |
3271 | ++ *dst++ = '\0'; | |
3272 | ++} | |
3273 | ++ | |
3274 | ++void * | |
3275 | ++memcpy (void *d, const void *s, size_t n) | |
3276 | ++{ | |
3277 | ++ void *result = my_memcpy (d, s, n); | |
3278 | ++ TEST_ABORT; | |
3279 | ++ return result; | |
3280 | ++} | |
3281 | ++ | |
3282 | ++void | |
3283 | ++bcopy (const void *s, void *d, size_t n) | |
3284 | ++{ | |
3285 | ++ my_bcopy (s, d, n); | |
3286 | ++ TEST_ABORT; | |
3287 | ++} | |
3288 | ++ | |
3289 | ++void * | |
3290 | ++memset (void *d, int c, size_t n) | |
3291 | ++{ | |
3292 | ++ void *result = my_memset (d, c, n); | |
3293 | ++ TEST_ABORT; | |
3294 | ++ return result; | |
3295 | ++} | |
3296 | ++ | |
3297 | ++void | |
3298 | ++bzero (void *d, size_t n) | |
3299 | ++{ | |
3300 | ++ my_bzero (d, n); | |
3301 | ++ TEST_ABORT; | |
3302 | ++} | |
3303 | +diff --git a/ld/testsuite/ld-plugin/pr14918.c b/ld/testsuite/ld-plugin/pr14918.c | |
3304 | +new file mode 100644 | |
3305 | +index 0000000..a9bce4a | |
3306 | +--- /dev/null | |
3307 | ++++ b/ld/testsuite/ld-plugin/pr14918.c | |
3308 | +@@ -0,0 +1,5 @@ | |
3309 | ++int | |
3310 | ++main () | |
3311 | ++{ | |
3312 | ++ return 0; | |
3313 | ++} | |
3314 | +diff --git a/ld/testsuite/ld-plugin/pr14918.d b/ld/testsuite/ld-plugin/pr14918.d | |
3315 | +new file mode 100644 | |
3316 | +index 0000000..0b14948 | |
3317 | +--- /dev/null | |
3318 | ++++ b/ld/testsuite/ld-plugin/pr14918.d | |
3319 | +@@ -0,0 +1,4 @@ | |
3320 | ++#failif | |
3321 | ++#... | |
3322 | ++ 0x0+1 \(NEEDED\) +Shared library: \[libgcc_s.so.[0-9]+\] | |
3323 | ++#... | |
3324 | +-- | |
3325 | +1.8.3.1 | |
3326 | + |