]> git.ipfire.org Git - people/amarx/ipfire-3.x.git/blob - binutils/patches/binutils-HEAD-change-ld-notice-interface.patch
binutils: Update to 2.24
[people/amarx/ipfire-3.x.git] / binutils / patches / binutils-HEAD-change-ld-notice-interface.patch
1 From 4613510308cea27713e8c7424b2afee9b99f6226 Mon Sep 17 00:00:00 2001
2 From: Alan Modra <amodra@gmail.com>
3 Date: Tue, 12 Aug 2014 10:43:33 +0930
4 Subject: [PATCH] Change ld "notice" interface for better handling of
5 indirect symbols
6
7 The main aim of this change was to have non_ir_ref set correctly on
8 new indirect symbols. I could have added a "copy" param to the "notice"
9 function, so that indirect symbols could be created in plugin_notice,
10 but it seemed cleaner to create indirect syms earlier and pass them
11 rather than "string" to "notice".
12
13 include/
14 * bfdlink.h (struct bfd_link_callbacks <notice>): Remove "string"
15 param, add "inh".
16 bfd/
17 * coff-aux.c (coff_m68k_aux_link_add_one_symbol): Only call "notice"
18 here when not calling the generic add_symbol function. Formatting.
19 Correct handling of indirect symbols. Update notice call.
20 * elflink.c (_bfd_elf_notice_as_needed): Update notice call.
21 * linker.c (_bfd_generic_link_add_one_symbol): Create indirect
22 symbols early. Update notice call. Add comments regarding weak
23 symbols vs. indirect.
24 ld/
25 * ldmain.c (notice): Update args.
26 * plugin.c (plugin_notice): Likewise. Follow warning sym link.
27 Handle new indirect symbol.
28 ---
29 bfd/coff-aux.c | 62 ++++++++++++++++++++++-------------------
30 bfd/elflink.c | 2 +-
31 bfd/linker.c | 82 +++++++++++++++++++++++++++++--------------------------
32 include/bfdlink.h | 13 ++++-----
33 ld/ldmain.c | 6 ++--
34 ld/plugin.c | 33 ++++++++++++----------
35 9 files changed, 128 insertions(+), 91 deletions(-)
36
37 diff --git a/bfd/coff-aux.c b/bfd/coff-aux.c
38 index e79c77a..d95b98b 100644
39 --- a/bfd/coff-aux.c
40 +++ b/bfd/coff-aux.c
41 @@ -73,20 +73,17 @@ coff_m68k_aux_link_add_one_symbol (struct bfd_link_info *info,
42 bfd_boolean collect,
43 struct bfd_link_hash_entry **hashp)
44 {
45 - struct bfd_link_hash_entry *h;
46 + struct bfd_link_hash_entry *h, *inh, *t;
47
48 - if ((flags & (BSF_WARNING | BSF_CONSTRUCTOR | BSF_WEAK)) == 0 &&
49 - !bfd_is_und_section (section) &&
50 - !bfd_is_com_section (section))
51 + if ((flags & (BSF_WARNING | BSF_CONSTRUCTOR | BSF_WEAK)) == 0
52 + && !bfd_is_und_section (section)
53 + && !bfd_is_com_section (section))
54 {
55 /* The new symbol is a definition or an indirect definition */
56
57 /* This bit copied from linker.c */
58 if (hashp != NULL && *hashp != NULL)
59 - {
60 - h = *hashp;
61 - BFD_ASSERT (strcmp (h->root.string, name) == 0);
62 - }
63 + h = *hashp;
64 else
65 {
66 h = bfd_link_hash_lookup (info->hash, name, TRUE, copy, FALSE);
67 @@ -98,37 +95,46 @@ coff_m68k_aux_link_add_one_symbol (struct bfd_link_info *info,
68 }
69 }
70
71 - if (info->notice_hash != (struct bfd_hash_table *) NULL
72 - && (bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE)
73 - != (struct bfd_hash_entry *) NULL))
74 - {
75 - if (! (*info->callbacks->notice) (info, h, abfd, section, value,
76 - flags, string))
77 - return FALSE;
78 - }
79 -
80 if (hashp != (struct bfd_link_hash_entry **) NULL)
81 *hashp = h;
82 /* end duplication from linker.c */
83
84 - if (h->type == bfd_link_hash_defined
85 - || h->type == bfd_link_hash_indirect)
86 + t = h;
87 + inh = NULL;
88 + if (h->type == bfd_link_hash_indirect)
89 {
90 - asection *msec;
91 + inh = h->u.i.link;
92 + t = inh;
93 + }
94
95 - if (h->type == bfd_link_hash_defined)
96 - msec = h->u.def.section;
97 - else
98 - msec = bfd_ind_section_ptr;
99 + if (t->type == bfd_link_hash_defined)
100 + {
101 + asection *msec = t->u.def.section;
102 + bfd_boolean special = FALSE;
103
104 if (bfd_is_abs_section (msec) && !bfd_is_abs_section (section))
105 {
106 - h->u.def.section = section;
107 - h->u.def.value = value;
108 - return TRUE;
109 + t->u.def.section = section;
110 + t->u.def.value = value;
111 + special = TRUE;
112 }
113 else if (bfd_is_abs_section (section) && !bfd_is_abs_section (msec))
114 - return TRUE;
115 + special = TRUE;
116 +
117 + if (special)
118 + {
119 + if (info->notice_all
120 + || (info->notice_hash != NULL
121 + && bfd_hash_lookup (info->notice_hash, name,
122 + FALSE, FALSE) != NULL))
123 + {
124 + if (!(*info->callbacks->notice) (info, h, inh,
125 + abfd, section, value, flags))
126 + return FALSE;
127 + }
128 +
129 + return TRUE;
130 + }
131 }
132 }
133
134 diff --git a/bfd/elflink.c b/bfd/elflink.c
135 index 69a87a6..de0a734 100644
136 --- a/bfd/elflink.c
137 +++ b/bfd/elflink.c
138 @@ -3299,7 +3299,7 @@ _bfd_elf_notice_as_needed (bfd *ibfd,
139 struct bfd_link_info *info,
140 enum notice_asneeded_action act)
141 {
142 - return (*info->callbacks->notice) (info, NULL, ibfd, NULL, act, 0, NULL);
143 + return (*info->callbacks->notice) (info, NULL, NULL, ibfd, NULL, act, 0);
144 }
145
146 /* Add symbols from an ELF object file to the linker hash table. */
147 diff --git a/bfd/linker.c b/bfd/linker.c
148 index 1a5ecef..abdf5b0 100644
149 --- a/bfd/linker.c
150 +++ b/bfd/linker.c
151 @@ -1442,13 +1442,23 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
152 {
153 enum link_row row;
154 struct bfd_link_hash_entry *h;
155 + struct bfd_link_hash_entry *inh = NULL;
156 bfd_boolean cycle;
157
158 BFD_ASSERT (section != NULL);
159
160 if (bfd_is_ind_section (section)
161 || (flags & BSF_INDIRECT) != 0)
162 - row = INDR_ROW;
163 + {
164 + row = INDR_ROW;
165 + /* Create the indirect symbol here. This is for the benefit of
166 + the plugin "notice" function.
167 + STRING is the name of the symbol we want to indirect to. */
168 + inh = bfd_wrapped_link_hash_lookup (abfd, info, string, TRUE,
169 + copy, FALSE);
170 + if (inh == NULL)
171 + return FALSE;
172 + }
173 else if ((flags & BSF_WARNING) != 0)
174 row = WARN_ROW;
175 else if ((flags & BSF_CONSTRUCTOR) != 0)
176 @@ -1493,8 +1503,8 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
177 || (info->notice_hash != NULL
178 && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL))
179 {
180 - if (! (*info->callbacks->notice) (info, h,
181 - abfd, section, value, flags, string))
182 + if (! (*info->callbacks->notice) (info, h, inh,
183 + abfd, section, value, flags))
184 return FALSE;
185 }
186
187 @@ -1728,44 +1738,40 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
188 return FALSE;
189 /* Fall through. */
190 case IND:
191 - /* Create an indirect symbol. */
192 - {
193 - struct bfd_link_hash_entry *inh;
194 -
195 - /* STRING is the name of the symbol we want to indirect
196 - to. */
197 - inh = bfd_wrapped_link_hash_lookup (abfd, info, string, TRUE,
198 - copy, FALSE);
199 - if (inh == NULL)
200 + if (inh->type == bfd_link_hash_indirect
201 + && inh->u.i.link == h)
202 + {
203 + (*_bfd_error_handler)
204 + (_("%B: indirect symbol `%s' to `%s' is a loop"),
205 + abfd, name, string);
206 + bfd_set_error (bfd_error_invalid_operation);
207 return FALSE;
208 - if (inh->type == bfd_link_hash_indirect
209 - && inh->u.i.link == h)
210 - {
211 - (*_bfd_error_handler)
212 - (_("%B: indirect symbol `%s' to `%s' is a loop"),
213 - abfd, name, string);
214 - bfd_set_error (bfd_error_invalid_operation);
215 - return FALSE;
216 - }
217 - if (inh->type == bfd_link_hash_new)
218 - {
219 - inh->type = bfd_link_hash_undefined;
220 - inh->u.undef.abfd = abfd;
221 - bfd_link_add_undef (info->hash, inh);
222 - }
223 + }
224 + if (inh->type == bfd_link_hash_new)
225 + {
226 + inh->type = bfd_link_hash_undefined;
227 + inh->u.undef.abfd = abfd;
228 + bfd_link_add_undef (info->hash, inh);
229 + }
230
231 - /* If the indirect symbol has been referenced, we need to
232 - push the reference down to the symbol we are
233 - referencing. */
234 - if (h->type != bfd_link_hash_new)
235 - {
236 - row = UNDEF_ROW;
237 - cycle = TRUE;
238 - }
239 + /* If the indirect symbol has been referenced, we need to
240 + push the reference down to the symbol we are referencing. */
241 + if (h->type != bfd_link_hash_new)
242 + {
243 + /* ??? If inh->type == bfd_link_hash_undefweak this
244 + converts inh to bfd_link_hash_undefined. */
245 + row = UNDEF_ROW;
246 + cycle = TRUE;
247 + }
248
249 - h->type = bfd_link_hash_indirect;
250 - h->u.i.link = inh;
251 - }
252 + h->type = bfd_link_hash_indirect;
253 + h->u.i.link = inh;
254 + /* Not setting h = h->u.i.link here means that when cycle is
255 + set above we'll always go to REFC, and then cycle again
256 + to the indirected symbol. This means that any successful
257 + change of an existing symbol to indirect counts as a
258 + reference. ??? That may not be correct when the existing
259 + symbol was defweak. */
260 break;
261
262 case SET:
263 diff --git a/include/bfdlink.h b/include/bfdlink.h
264 index 58dba2a..125683d 100644
265 --- a/include/bfdlink.h
266 +++ b/include/bfdlink.h
267 @@ -640,15 +640,14 @@ struct bfd_link_callbacks
268 (struct bfd_link_info *, const char *name,
269 bfd *abfd, asection *section, bfd_vma address);
270 /* A function which is called when a symbol in notice_hash is
271 - defined or referenced. H is the symbol. ABFD, SECTION and
272 - ADDRESS are the (new) value of the symbol. If SECTION is
273 - bfd_und_section, this is a reference. FLAGS are the symbol
274 - BSF_* flags. STRING is the name of the symbol to indirect to if
275 - the sym is indirect, or the warning string if a warning sym. */
276 + defined or referenced. H is the symbol, INH the indirect symbol
277 + if applicable. ABFD, SECTION and ADDRESS are the (new) value of
278 + the symbol. If SECTION is bfd_und_section, this is a reference.
279 + FLAGS are the symbol BSF_* flags. */
280 bfd_boolean (*notice)
281 (struct bfd_link_info *, struct bfd_link_hash_entry *h,
282 - bfd *abfd, asection *section, bfd_vma address, flagword flags,
283 - const char *string);
284 + struct bfd_link_hash_entry *inh,
285 + bfd *abfd, asection *section, bfd_vma address, flagword flags);
286 /* Error or warning link info message. */
287 void (*einfo)
288 (const char *fmt, ...);
289 diff --git a/ld/ldmain.c b/ld/ldmain.c
290 index ea25afe..77235d5 100644
291 --- a/ld/ldmain.c
292 +++ b/ld/ldmain.c
293 @@ -137,7 +137,7 @@ static bfd_boolean unattached_reloc
294 (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma);
295 static bfd_boolean notice
296 (struct bfd_link_info *, struct bfd_link_hash_entry *,
297 - bfd *, asection *, bfd_vma, flagword, const char *);
298 + struct bfd_link_hash_entry *, bfd *, asection *, bfd_vma, flagword);
299
300 static struct bfd_link_callbacks link_callbacks =
301 {
302 @@ -1461,11 +1461,11 @@ unattached_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED,
303 static bfd_boolean
304 notice (struct bfd_link_info *info,
305 struct bfd_link_hash_entry *h,
306 + struct bfd_link_hash_entry *inh ATTRIBUTE_UNUSED,
307 bfd *abfd,
308 asection *section,
309 bfd_vma value,
310 - flagword flags ATTRIBUTE_UNUSED,
311 - const char *string ATTRIBUTE_UNUSED)
312 + flagword flags ATTRIBUTE_UNUSED)
313 {
314 const char *name;
315
316 diff --git a/ld/plugin.c b/ld/plugin.c
317 index 8d6ae05..8cca7d0 100644
318 --- a/ld/plugin.c
319 +++ b/ld/plugin.c
320 @@ -127,8 +127,9 @@ static const size_t tv_header_size = ARRAY_SIZE (tv_header_tags);
321
322 /* Forward references. */
323 static bfd_boolean plugin_notice (struct bfd_link_info *,
324 - struct bfd_link_hash_entry *, bfd *,
325 - asection *, bfd_vma, flagword, const char *);
326 + struct bfd_link_hash_entry *,
327 + struct bfd_link_hash_entry *,
328 + bfd *, asection *, bfd_vma, flagword);
329
330 #if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
331
332 @@ -962,16 +963,21 @@ plugin_call_cleanup (void)
333 static bfd_boolean
334 plugin_notice (struct bfd_link_info *info,
335 struct bfd_link_hash_entry *h,
336 + struct bfd_link_hash_entry *inh,
337 bfd *abfd,
338 asection *section,
339 bfd_vma value,
340 - flagword flags,
341 - const char *string)
342 + flagword flags)
343 {
344 + struct bfd_link_hash_entry *orig_h = h;
345 +
346 if (h != NULL)
347 {
348 bfd *sym_bfd;
349
350 + if (h->type == bfd_link_hash_warning)
351 + h = h->u.i.link;
352 +
353 /* Nothing to do here if this def/ref is from an IR dummy BFD. */
354 if (is_ir_dummy_bfd (abfd))
355 ;
356 @@ -981,16 +987,15 @@ plugin_notice (struct bfd_link_info *info,
357 else if (bfd_is_ind_section (section)
358 || (flags & BSF_INDIRECT) != 0)
359 {
360 + /* ??? Some of this is questionable. See comments in
361 + _bfd_generic_link_add_one_symbol for case IND. */
362 if (h->type != bfd_link_hash_new)
363 {
364 - struct bfd_link_hash_entry *inh;
365 -
366 h->non_ir_ref = TRUE;
367 - inh = bfd_wrapped_link_hash_lookup (abfd, info, string, FALSE,
368 - FALSE, FALSE);
369 - if (inh != NULL)
370 - inh->non_ir_ref = TRUE;
371 + inh->non_ir_ref = TRUE;
372 }
373 + else if (inh->type == bfd_link_hash_new)
374 + inh->non_ir_ref = TRUE;
375 }
376
377 /* Nothing to do here for warning symbols. */
378 @@ -1031,13 +1036,13 @@ plugin_notice (struct bfd_link_info *info,
379 }
380
381 /* Continue with cref/nocrossref/trace-sym processing. */
382 - if (h == NULL
383 + if (orig_h == NULL
384 || orig_notice_all
385 || (info->notice_hash != NULL
386 - && bfd_hash_lookup (info->notice_hash, h->root.string,
387 + && bfd_hash_lookup (info->notice_hash, orig_h->root.string,
388 FALSE, FALSE) != NULL))
389 - return (*orig_callbacks->notice) (info, h,
390 - abfd, section, value, flags, string);
391 + return (*orig_callbacks->notice) (info, orig_h, inh,
392 + abfd, section, value, flags);
393 return TRUE;
394 }
395
396 --
397 1.9.3
398