/src/binutils-gdb/bfd/arc-got.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* ARC-specific support for 32-bit ELF |
2 | | Copyright (C) 1994-2025 Free Software Foundation, Inc. |
3 | | Contributed by Cupertino Miranda (cmiranda@synopsys.com). |
4 | | |
5 | | This file is part of BFD, the Binary File Descriptor library. |
6 | | |
7 | | This program is free software; you can redistribute it and/or modify |
8 | | it under the terms of the GNU General Public License as published by |
9 | | the Free Software Foundation; either version 3 of the License, or |
10 | | (at your option) any later version. |
11 | | |
12 | | This program is distributed in the hope that it will be useful, |
13 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | GNU General Public License for more details. |
16 | | |
17 | | You should have received a copy of the GNU General Public License |
18 | | along with this program; if not, write to the Free Software |
19 | | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
20 | | MA 02110-1301, USA. */ |
21 | | |
22 | | #ifndef ARC_GOT_H |
23 | | #define ARC_GOT_H |
24 | | |
25 | | #define TCB_SIZE (8) |
26 | | |
27 | | #define align_power(addr, align) \ |
28 | | (((addr) + ((bfd_vma) 1 << (align)) - 1) & (-((bfd_vma) 1 << (align)))) |
29 | | |
30 | | enum tls_type_e |
31 | | { |
32 | | GOT_UNKNOWN = 0, |
33 | | GOT_NORMAL, |
34 | | GOT_TLS_GD, |
35 | | GOT_TLS_IE, |
36 | | GOT_TLS_LE |
37 | | }; |
38 | | |
39 | | enum tls_got_entries |
40 | | { |
41 | | TLS_GOT_NONE = 0, |
42 | | TLS_GOT_MOD, |
43 | | TLS_GOT_OFF, |
44 | | TLS_GOT_MOD_AND_OFF |
45 | | }; |
46 | | |
47 | | struct got_entry |
48 | | { |
49 | | struct got_entry *next; |
50 | | enum tls_type_e type; |
51 | | bfd_vma offset; |
52 | | bool processed; |
53 | | bool created_dyn_relocation; |
54 | | enum tls_got_entries existing_entries; |
55 | | }; |
56 | | |
57 | | /* Return the local got list, if not defined, create an empty one. */ |
58 | | |
59 | | static struct got_entry ** |
60 | | arc_get_local_got_ents (bfd * abfd) |
61 | 0 | { |
62 | 0 | if (elf_local_got_ents (abfd) == NULL) |
63 | 0 | { |
64 | 0 | bfd_size_type amt = (elf_tdata (abfd)->symtab_hdr.sh_info |
65 | 0 | * sizeof (*elf_local_got_ents (abfd))); |
66 | 0 | elf_local_got_ents (abfd) = bfd_zmalloc (amt); |
67 | 0 | if (elf_local_got_ents (abfd) == NULL) |
68 | 0 | { |
69 | 0 | _bfd_error_handler (_("%pB: cannot allocate memory for local " |
70 | 0 | "GOT entries"), abfd); |
71 | 0 | bfd_set_error (bfd_error_bad_value); |
72 | 0 | return NULL; |
73 | 0 | } |
74 | 0 | } |
75 | | |
76 | 0 | return elf_local_got_ents (abfd); |
77 | 0 | } |
78 | | |
79 | | static struct got_entry * |
80 | | got_entry_for_type (struct got_entry **list, |
81 | | enum tls_type_e type) |
82 | 0 | { |
83 | 0 | struct got_entry **p = list; |
84 | |
|
85 | 0 | while (*p != NULL) |
86 | 0 | { |
87 | 0 | if ((*p)->type == type) |
88 | 0 | return *p; |
89 | 0 | p = &((*p)->next); |
90 | 0 | } |
91 | 0 | return NULL; |
92 | 0 | } |
93 | | |
94 | | static void |
95 | | new_got_entry_to_list (struct got_entry **list, |
96 | | enum tls_type_e type, |
97 | | bfd_vma offset, |
98 | | enum tls_got_entries existing_entries) |
99 | 0 | { |
100 | | /* Find list end. Avoid having multiple entries of the same |
101 | | type. */ |
102 | 0 | struct got_entry **p = list; |
103 | 0 | struct got_entry *entry; |
104 | |
|
105 | 0 | while (*p != NULL) |
106 | 0 | { |
107 | 0 | if ((*p)->type == type) |
108 | 0 | return; |
109 | 0 | p = &((*p)->next); |
110 | 0 | } |
111 | | |
112 | 0 | entry = (struct got_entry *) xmalloc (sizeof (struct got_entry)); |
113 | |
|
114 | 0 | entry->type = type; |
115 | 0 | entry->offset = offset; |
116 | 0 | entry->next = NULL; |
117 | 0 | entry->processed = false; |
118 | 0 | entry->created_dyn_relocation = false; |
119 | 0 | entry->existing_entries = existing_entries; |
120 | |
|
121 | 0 | ARC_DEBUG ("New GOT got entry added to list: " |
122 | 0 | "type: %d, offset: %ld, existing_entries: %d\n", |
123 | 0 | type, (long) offset, existing_entries); |
124 | | |
125 | | /* Add the entry to the end of the list. */ |
126 | 0 | *p = entry; |
127 | 0 | } |
128 | | |
129 | | static enum tls_type_e |
130 | | tls_type_for_reloc (reloc_howto_type *howto) |
131 | 0 | { |
132 | 0 | enum tls_type_e ret = GOT_UNKNOWN; |
133 | |
|
134 | 0 | if (is_reloc_for_GOT (howto)) |
135 | 0 | return GOT_NORMAL; |
136 | | |
137 | 0 | switch (howto->type) |
138 | 0 | { |
139 | 0 | case R_ARC_TLS_GD_GOT: |
140 | 0 | ret = GOT_TLS_GD; |
141 | 0 | break; |
142 | 0 | case R_ARC_TLS_IE_GOT: |
143 | 0 | ret = GOT_TLS_IE; |
144 | 0 | break; |
145 | 0 | case R_ARC_TLS_LE_32: |
146 | 0 | ret = GOT_TLS_LE; |
147 | 0 | break; |
148 | 0 | default: |
149 | 0 | ret = GOT_UNKNOWN; |
150 | 0 | break; |
151 | 0 | } |
152 | | |
153 | 0 | return ret; |
154 | 0 | }; |
155 | | |
156 | | static struct got_entry ** |
157 | | get_got_entry_list_for_symbol (bfd *abfd, |
158 | | unsigned long r_symndx, |
159 | | struct elf_link_hash_entry *h) |
160 | 0 | { |
161 | 0 | struct elf_arc_link_hash_entry *h1 = |
162 | 0 | ((struct elf_arc_link_hash_entry *) h); |
163 | 0 | if (h1 != NULL) |
164 | 0 | { |
165 | 0 | return &h1->got_ents; |
166 | 0 | } |
167 | 0 | else |
168 | 0 | { |
169 | 0 | return arc_get_local_got_ents (abfd) + r_symndx; |
170 | 0 | } |
171 | 0 | } |
172 | | |
173 | | |
174 | | static enum tls_type_e |
175 | | arc_got_entry_type_for_reloc (reloc_howto_type *howto) |
176 | 0 | { |
177 | 0 | enum tls_type_e type = GOT_UNKNOWN; |
178 | |
|
179 | 0 | if (is_reloc_for_GOT (howto)) |
180 | 0 | return GOT_NORMAL; |
181 | | |
182 | 0 | if (is_reloc_for_TLS (howto)) |
183 | 0 | { |
184 | 0 | switch (howto->type) |
185 | 0 | { |
186 | 0 | case R_ARC_TLS_GD_GOT: |
187 | 0 | type = GOT_TLS_GD; |
188 | 0 | break; |
189 | 0 | case R_ARC_TLS_IE_GOT: |
190 | 0 | type = GOT_TLS_IE; |
191 | 0 | break; |
192 | 0 | default: |
193 | 0 | break; |
194 | 0 | } |
195 | 0 | } |
196 | 0 | return type; |
197 | 0 | } |
198 | | |
199 | | #define ADD_SYMBOL_REF_SEC_AND_RELOC(SECNAME, COND_FOR_RELOC, H) \ |
200 | 0 | htab->s##SECNAME->size; \ |
201 | 0 | { \ |
202 | 0 | if (COND_FOR_RELOC) \ |
203 | 0 | { \ |
204 | 0 | htab->srel##SECNAME->size += sizeof (Elf32_External_Rela); \ |
205 | 0 | ARC_DEBUG ("arc_info: Added reloc space in " \ |
206 | 0 | #SECNAME " section at " __FILE__ \ |
207 | 0 | ":%d for symbol %s\n", \ |
208 | 0 | __LINE__, name_for_global_symbol (H)); \ |
209 | 0 | } \ |
210 | 0 | if (H) \ |
211 | 0 | if (H->dynindx == -1 && !H->forced_local) \ |
212 | 0 | if (! bfd_elf_link_record_dynamic_symbol (info, H)) \ |
213 | 0 | return false; \ |
214 | 0 | htab->s##SECNAME->size += 4; \ |
215 | 0 | } \ |
216 | | |
217 | | static bool |
218 | | arc_fill_got_info_for_reloc (enum tls_type_e type, |
219 | | struct got_entry **list, |
220 | | struct bfd_link_info * info, |
221 | | struct elf_link_hash_entry *h) |
222 | 0 | { |
223 | 0 | struct elf_link_hash_table *htab = elf_hash_table (info); |
224 | |
|
225 | 0 | if (got_entry_for_type (list, type) != NULL) |
226 | 0 | return true; |
227 | | |
228 | 0 | switch (type) |
229 | 0 | { |
230 | 0 | case GOT_NORMAL: |
231 | 0 | { |
232 | 0 | bfd_vma offset |
233 | 0 | = ADD_SYMBOL_REF_SEC_AND_RELOC (got, bfd_link_pic (info) |
234 | 0 | || h != NULL, h); |
235 | 0 | new_got_entry_to_list (list, type, offset, TLS_GOT_NONE); |
236 | 0 | } |
237 | 0 | break; |
238 | | |
239 | | |
240 | 0 | case GOT_TLS_GD: |
241 | 0 | { |
242 | 0 | bfd_vma offset |
243 | 0 | = ADD_SYMBOL_REF_SEC_AND_RELOC (got, true, h); |
244 | 0 | bfd_vma ATTRIBUTE_UNUSED notneeded |
245 | 0 | = ADD_SYMBOL_REF_SEC_AND_RELOC (got, true, h); |
246 | 0 | new_got_entry_to_list (list, type, offset, TLS_GOT_MOD_AND_OFF); |
247 | 0 | } |
248 | 0 | break; |
249 | 0 | case GOT_TLS_IE: |
250 | 0 | case GOT_TLS_LE: |
251 | 0 | { |
252 | 0 | bfd_vma offset |
253 | 0 | = ADD_SYMBOL_REF_SEC_AND_RELOC (got, true, h); |
254 | 0 | new_got_entry_to_list (list, type, offset, TLS_GOT_OFF); |
255 | 0 | } |
256 | 0 | break; |
257 | | |
258 | 0 | default: |
259 | 0 | return false; |
260 | 0 | break; |
261 | 0 | } |
262 | 0 | return true; |
263 | 0 | } |
264 | | |
265 | | struct arc_static_sym_data { |
266 | | bfd_vma sym_value; |
267 | | const char *symbol_name; |
268 | | }; |
269 | | |
270 | | static struct arc_static_sym_data |
271 | | get_static_sym_data (unsigned long r_symndx, |
272 | | Elf_Internal_Sym *local_syms, |
273 | | asection **local_sections, |
274 | | struct elf_link_hash_entry *h, |
275 | | struct arc_relocation_data *reloc_data) |
276 | 0 | { |
277 | 0 | static const char local_name[] = "(local)"; |
278 | 0 | struct arc_static_sym_data ret = { 0, NULL }; |
279 | |
|
280 | 0 | if (h != NULL) |
281 | 0 | { |
282 | 0 | BFD_ASSERT (h->root.type != bfd_link_hash_undefweak |
283 | 0 | && h->root.type != bfd_link_hash_undefined); |
284 | | /* TODO: This should not be here. */ |
285 | 0 | reloc_data->sym_value = h->root.u.def.value; |
286 | 0 | reloc_data->sym_section = h->root.u.def.section; |
287 | |
|
288 | 0 | ret.sym_value = h->root.u.def.value |
289 | 0 | + h->root.u.def.section->output_section->vma |
290 | 0 | + h->root.u.def.section->output_offset; |
291 | |
|
292 | 0 | ret.symbol_name = h->root.root.string; |
293 | 0 | } |
294 | 0 | else |
295 | 0 | { |
296 | 0 | Elf_Internal_Sym *sym = local_syms + r_symndx; |
297 | 0 | asection *sec = local_sections[r_symndx]; |
298 | |
|
299 | 0 | ret.sym_value = sym->st_value |
300 | 0 | + sec->output_section->vma |
301 | 0 | + sec->output_offset; |
302 | |
|
303 | 0 | ret.symbol_name = local_name; |
304 | 0 | } |
305 | 0 | return ret; |
306 | 0 | } |
307 | | |
308 | | static bfd_vma |
309 | | relocate_fix_got_relocs_for_got_info (struct got_entry ** list_p, |
310 | | enum tls_type_e type, |
311 | | struct bfd_link_info * info, |
312 | | bfd * output_bfd, |
313 | | unsigned long r_symndx, |
314 | | Elf_Internal_Sym * local_syms, |
315 | | asection ** local_sections, |
316 | | struct elf_link_hash_entry * h, |
317 | | struct arc_relocation_data * reloc_data) |
318 | 0 | { |
319 | 0 | struct elf_link_hash_table *htab = elf_hash_table (info); |
320 | 0 | struct got_entry *entry = NULL; |
321 | |
|
322 | 0 | if (list_p == NULL || type == GOT_UNKNOWN || type == GOT_TLS_LE) |
323 | 0 | return 0; |
324 | | |
325 | 0 | entry = got_entry_for_type (list_p, type); |
326 | 0 | BFD_ASSERT (entry); |
327 | |
|
328 | 0 | if (h == NULL |
329 | 0 | || h->forced_local == true |
330 | 0 | || (! elf_hash_table (info)->dynamic_sections_created |
331 | 0 | || (bfd_link_pic (info) |
332 | 0 | && SYMBOL_REFERENCES_LOCAL (info, h)))) |
333 | 0 | { |
334 | 0 | const char ATTRIBUTE_UNUSED *symbol_name; |
335 | 0 | asection *tls_sec = elf_hash_table (info)->tls_sec; |
336 | |
|
337 | 0 | if (entry && !entry->processed) |
338 | 0 | { |
339 | 0 | switch (entry->type) |
340 | 0 | { |
341 | 0 | case GOT_TLS_GD: |
342 | 0 | { |
343 | 0 | BFD_ASSERT (tls_sec && tls_sec->output_section); |
344 | 0 | bfd_vma sec_vma = tls_sec->output_section->vma; |
345 | |
|
346 | 0 | if (h == NULL || h->forced_local |
347 | 0 | || !elf_hash_table (info)->dynamic_sections_created) |
348 | 0 | { |
349 | 0 | struct arc_static_sym_data tmp = |
350 | 0 | get_static_sym_data (r_symndx, local_syms, local_sections, |
351 | 0 | h, reloc_data); |
352 | |
|
353 | 0 | bfd_put_32 (output_bfd, |
354 | 0 | tmp.sym_value - sec_vma |
355 | 0 | + (elf_hash_table (info)->dynamic_sections_created |
356 | 0 | ? 0 |
357 | 0 | : (align_power (0, |
358 | 0 | tls_sec->alignment_power))), |
359 | 0 | htab->sgot->contents + entry->offset |
360 | 0 | + (entry->existing_entries == TLS_GOT_MOD_AND_OFF |
361 | 0 | ? 4 : 0)); |
362 | |
|
363 | 0 | ARC_DEBUG ("arc_info: FIXED -> %s value = %#lx " |
364 | 0 | "@ %lx, for symbol %s\n", |
365 | 0 | (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" : |
366 | 0 | "GOT_TLS_IE"), |
367 | 0 | (long) (sym_value - sec_vma), |
368 | 0 | (long) (htab->sgot->output_section->vma |
369 | 0 | + htab->sgot->output_offset |
370 | 0 | + entry->offset |
371 | 0 | + (entry->existing_entries == TLS_GOT_MOD_AND_OFF |
372 | 0 | ? 4 : 0)), |
373 | 0 | tmp.symbol_name); |
374 | 0 | } |
375 | 0 | } |
376 | 0 | break; |
377 | | |
378 | 0 | case GOT_TLS_IE: |
379 | 0 | { |
380 | 0 | BFD_ASSERT (tls_sec && tls_sec->output_section); |
381 | 0 | bfd_vma ATTRIBUTE_UNUSED sec_vma |
382 | 0 | = tls_sec->output_section->vma; |
383 | |
|
384 | 0 | struct arc_static_sym_data tmp = |
385 | 0 | get_static_sym_data (r_symndx, local_syms, local_sections, |
386 | 0 | h, reloc_data); |
387 | |
|
388 | 0 | bfd_put_32 (output_bfd, |
389 | 0 | tmp.sym_value - sec_vma |
390 | 0 | + (elf_hash_table (info)->dynamic_sections_created |
391 | 0 | ? 0 |
392 | 0 | : (align_power (TCB_SIZE, |
393 | 0 | tls_sec->alignment_power))), |
394 | 0 | htab->sgot->contents + entry->offset |
395 | 0 | + (entry->existing_entries == TLS_GOT_MOD_AND_OFF |
396 | 0 | ? 4 : 0)); |
397 | |
|
398 | 0 | ARC_DEBUG ("arc_info: FIXED -> %s value = %#lx " |
399 | 0 | "@ %p, for symbol %s\n", |
400 | 0 | (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" : |
401 | 0 | "GOT_TLS_IE"), |
402 | 0 | (long) (sym_value - sec_vma), |
403 | 0 | (long) (htab->sgot->output_section->vma |
404 | 0 | + htab->sgot->output_offset |
405 | 0 | + entry->offset |
406 | 0 | + (entry->existing_entries == TLS_GOT_MOD_AND_OFF |
407 | 0 | ? 4 : 0)), |
408 | 0 | tmp.symbol_name); |
409 | 0 | } |
410 | 0 | break; |
411 | | |
412 | 0 | case GOT_NORMAL: |
413 | 0 | { |
414 | 0 | bfd_vma sec_vma |
415 | 0 | = reloc_data->sym_section->output_section->vma |
416 | 0 | + reloc_data->sym_section->output_offset; |
417 | |
|
418 | 0 | if (h != NULL |
419 | 0 | && h->root.type == bfd_link_hash_undefweak) |
420 | 0 | ARC_DEBUG ("arc_info: PATCHED: NOT_PATCHED " |
421 | 0 | "@ %#08lx for sym %s in got offset %#lx " |
422 | 0 | "(is undefweak)\n", |
423 | 0 | (long) (htab->sgot->output_section->vma |
424 | 0 | + htab->sgot->output_offset |
425 | 0 | + entry->offset), |
426 | 0 | symbol_name, |
427 | 0 | (long) entry->offset); |
428 | 0 | else |
429 | 0 | { |
430 | 0 | bfd_put_32 (output_bfd, |
431 | 0 | reloc_data->sym_value + sec_vma, |
432 | 0 | htab->sgot->contents + entry->offset); |
433 | 0 | ARC_DEBUG ("arc_info: PATCHED: %#08lx " |
434 | 0 | "@ %#08lx for sym %s in got offset %#lx\n", |
435 | 0 | (long) (reloc_data->sym_value + sec_vma), |
436 | 0 | (long) (htab->sgot->output_section->vma |
437 | 0 | + htab->sgot->output_offset |
438 | 0 | + entry->offset), |
439 | 0 | symbol_name, |
440 | 0 | (long) entry->offset); |
441 | 0 | } |
442 | 0 | } |
443 | 0 | break; |
444 | 0 | default: |
445 | 0 | BFD_ASSERT (0); |
446 | 0 | break; |
447 | 0 | } |
448 | 0 | entry->processed = true; |
449 | 0 | } |
450 | 0 | } |
451 | | |
452 | 0 | return entry->offset; |
453 | 0 | } |
454 | | |
455 | | static void |
456 | | create_got_dynrelocs_for_single_entry (struct got_entry *list, |
457 | | bfd *output_bfd, |
458 | | struct bfd_link_info * info, |
459 | | struct elf_link_hash_entry *h) |
460 | 0 | { |
461 | 0 | if (list == NULL) |
462 | 0 | return; |
463 | | |
464 | 0 | bfd_vma got_offset = list->offset; |
465 | |
|
466 | 0 | if (list->type == GOT_NORMAL |
467 | 0 | && !list->created_dyn_relocation) |
468 | 0 | { |
469 | 0 | if (bfd_link_pic (info) |
470 | 0 | && h != NULL |
471 | 0 | && (info->symbolic || h->dynindx == -1) |
472 | 0 | && h->def_regular) |
473 | 0 | { |
474 | 0 | ADD_RELA (output_bfd, got, got_offset, 0, R_ARC_RELATIVE, 0); |
475 | 0 | } |
476 | | /* Do not fully understand the side effects of this condition. |
477 | | The relocation space might still being reserved. Perhaps |
478 | | I should clear its value. */ |
479 | 0 | else if (h != NULL && h->dynindx != -1) |
480 | 0 | { |
481 | 0 | ADD_RELA (output_bfd, got, got_offset, h->dynindx, R_ARC_GLOB_DAT, 0); |
482 | 0 | } |
483 | 0 | list->created_dyn_relocation = true; |
484 | 0 | } |
485 | 0 | else if (list->existing_entries != TLS_GOT_NONE |
486 | 0 | && !list->created_dyn_relocation) |
487 | 0 | { |
488 | | /* TODO TLS: This is not called for local symbols. |
489 | | In order to correctly implement TLS, this should also |
490 | | be called for all local symbols with tls got entries. |
491 | | Should be moved to relocate_section in order to make it |
492 | | work for local symbols. */ |
493 | 0 | struct elf_link_hash_table *htab = elf_hash_table (info); |
494 | 0 | enum tls_got_entries e = list->existing_entries; |
495 | |
|
496 | 0 | BFD_ASSERT (list->type != GOT_TLS_GD |
497 | 0 | || list->existing_entries == TLS_GOT_MOD_AND_OFF); |
498 | |
|
499 | 0 | bfd_vma dynindx = (h == NULL || h->dynindx == -1) ? 0 : h->dynindx; |
500 | |
|
501 | 0 | if (e == TLS_GOT_MOD_AND_OFF || e == TLS_GOT_MOD) |
502 | 0 | { |
503 | 0 | ADD_RELA (output_bfd, got, got_offset, dynindx, |
504 | 0 | R_ARC_TLS_DTPMOD, 0); |
505 | 0 | ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \ |
506 | 0 | GOT_OFFSET = %#lx, GOT_VMA = %#lx, INDEX = %ld, ADDEND = 0x0\n", |
507 | 0 | list->type, |
508 | 0 | (long) got_offset, |
509 | 0 | (long) (htab->sgot->output_section->vma |
510 | 0 | + htab->sgot->output_offset + got_offset), |
511 | 0 | (long) dynindx); |
512 | 0 | } |
513 | |
|
514 | 0 | if (e == TLS_GOT_MOD_AND_OFF || e == TLS_GOT_OFF) |
515 | 0 | { |
516 | 0 | bfd_vma addend = 0; |
517 | 0 | if (list->type == GOT_TLS_IE) |
518 | 0 | { |
519 | 0 | addend = bfd_get_32 (output_bfd, |
520 | 0 | htab->sgot->contents + got_offset); |
521 | 0 | } |
522 | |
|
523 | 0 | ADD_RELA (output_bfd, got, |
524 | 0 | got_offset + (e == TLS_GOT_MOD_AND_OFF ? 4 : 0), |
525 | 0 | dynindx, |
526 | 0 | (list->type == GOT_TLS_IE ? R_ARC_TLS_TPOFF |
527 | 0 | : R_ARC_TLS_DTPOFF), |
528 | 0 | addend); |
529 | |
|
530 | 0 | ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \ |
531 | 0 | GOT_OFFSET = %#lx, GOT_VMA = %#lx, INDEX = %ld, ADDEND = %#lx\n", |
532 | 0 | list->type, |
533 | 0 | (long) got_offset, |
534 | 0 | (long) (htab->sgot->output_section->vma |
535 | 0 | + htab->sgot->output_offset + got_offset), |
536 | 0 | (long) dynindx, (long) addend); |
537 | 0 | } |
538 | 0 | list->created_dyn_relocation = true; |
539 | 0 | } |
540 | 0 | } |
541 | | |
542 | | static void |
543 | | create_got_dynrelocs_for_got_info (struct got_entry **list_p, |
544 | | bfd *output_bfd, |
545 | | struct bfd_link_info * info, |
546 | | struct elf_link_hash_entry *h) |
547 | 0 | { |
548 | 0 | if (list_p == NULL) |
549 | 0 | return; |
550 | | |
551 | 0 | struct got_entry *list = *list_p; |
552 | | /* Traverse the list of got entries for this symbol. */ |
553 | 0 | while (list) |
554 | 0 | { |
555 | 0 | create_got_dynrelocs_for_single_entry (list, output_bfd, info, h); |
556 | 0 | list = list->next; |
557 | 0 | } |
558 | 0 | } |
559 | | |
560 | | #undef ADD_SYMBOL_REF_SEC_AND_RELOC |
561 | | |
562 | | #endif /* ARC_GOT_H */ |