arc: Remove EF_ARC_CPU_GENERIC constant.
[deliverable/binutils-gdb.git] / bfd / elf32-arc.c
1 /* ARC-specific support for 32-bit ELF
2 Copyright (C) 1994-2016 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 #include "sysdep.h"
23 #include "bfd.h"
24 #include "libbfd.h"
25 #include "elf-bfd.h"
26 #include "elf/arc.h"
27 #include "libiberty.h"
28 #include "opcode/arc-func.h"
29 #include "arc-plt.h"
30
31 #ifdef DEBUG
32 # define PR_DEBUG(fmt, args...) fprintf (stderr, fmt, ##args)
33 #else
34 # define PR_DEBUG(fmt, args...)
35 #endif
36
37 /* #define ARC_ENABLE_DEBUG 1 */
38 #ifndef ARC_ENABLE_DEBUG
39 #define ARC_DEBUG(...)
40 #else
41 static char *
42 name_for_global_symbol (struct elf_link_hash_entry *h)
43 {
44 static char *local_str = "(local)";
45 if (h == NULL)
46 return local_str;
47 else
48 return h->root.root.string;
49 }
50 #define ARC_DEBUG(args...) fprintf (stderr, ##args)
51 #endif
52
53
54 #define ADD_RELA(BFD, SECTION, OFFSET, SYM_IDX, TYPE, ADDEND) \
55 { \
56 struct elf_link_hash_table *_htab = elf_hash_table (info); \
57 Elf_Internal_Rela _rel; \
58 bfd_byte * _loc; \
59 \
60 _loc = _htab->srel##SECTION->contents \
61 + ((_htab->srel##SECTION->reloc_count) \
62 * sizeof (Elf32_External_Rela)); \
63 _htab->srel##SECTION->reloc_count++; \
64 _rel.r_addend = ADDEND; \
65 _rel.r_offset = (_htab->s##SECTION)->output_section->vma \
66 + (_htab->s##SECTION)->output_offset + OFFSET; \
67 _rel.r_info = ELF32_R_INFO (SYM_IDX, TYPE); \
68 bfd_elf32_swap_reloca_out (BFD, &_rel, _loc); \
69 }
70
71 struct arc_local_data
72 {
73 bfd_vma sdata_begin_symbol_vma;
74 asection * sdata_output_section;
75 bfd_vma got_symbol_vma;
76 };
77
78 struct arc_local_data global_arc_data =
79 {
80 .sdata_begin_symbol_vma = 0,
81 .sdata_output_section = NULL,
82 .got_symbol_vma = 0,
83 };
84
85 struct dynamic_sections
86 {
87 bfd_boolean initialized;
88 asection * sgot;
89 asection * srelgot;
90 asection * sgotplt;
91 asection * srelgotplt;
92 asection * sdyn;
93 asection * splt;
94 asection * srelplt;
95 };
96
97 enum dyn_section_types
98 {
99 got = 0,
100 relgot,
101 gotplt,
102 dyn,
103 plt,
104 relplt,
105 DYN_SECTION_TYPES_END
106 };
107
108 const char * dyn_section_names[DYN_SECTION_TYPES_END] =
109 {
110 ".got",
111 ".rela.got",
112 ".got.plt",
113 ".dynamic",
114 ".plt",
115 ".rela.plt"
116 };
117
118 enum tls_type_e
119 {
120 GOT_UNKNOWN = 0,
121 GOT_NORMAL,
122 GOT_TLS_GD,
123 GOT_TLS_IE,
124 GOT_TLS_LE
125 };
126
127 enum tls_got_entries
128 {
129 NONE = 0,
130 MOD,
131 OFF,
132 MOD_AND_OFF
133 };
134
135 struct got_entry
136 {
137 struct got_entry *next;
138 enum tls_type_e type;
139 bfd_vma offset;
140 bfd_boolean processed;
141 bfd_boolean created_dyn_relocation;
142 enum tls_got_entries existing_entries;
143 };
144
145 static void
146 new_got_entry_to_list (struct got_entry **list,
147 enum tls_type_e type,
148 bfd_vma offset,
149 enum tls_got_entries existing_entries)
150 {
151 /* Find list end. Avoid having multiple entries of the same
152 type. */
153 struct got_entry **p = list;
154 while (*p != NULL)
155 {
156 if ((*p)->type == type)
157 return;
158 p = &((*p)->next);
159 }
160
161 struct got_entry *entry =
162 (struct got_entry *) malloc (sizeof(struct got_entry));
163
164 entry->type = type;
165 entry->offset = offset;
166 entry->next = NULL;
167 entry->processed = FALSE;
168 entry->created_dyn_relocation = FALSE;
169 entry->existing_entries = existing_entries;
170
171 /* Add the entry to the end of the list. */
172 *p = entry;
173 }
174
175 static bfd_boolean
176 symbol_has_entry_of_type (struct got_entry *list, enum tls_type_e type)
177 {
178 while (list != NULL)
179 {
180 if (list->type == type)
181 return TRUE;
182 list = list->next;
183 }
184
185 return FALSE;
186 }
187
188 /* The default symbols representing the init and fini dyn values.
189 TODO: Check what is the relation of those strings with arclinux.em
190 and DT_INIT. */
191 #define INIT_SYM_STRING "_init"
192 #define FINI_SYM_STRING "_fini"
193
194 char * init_str = INIT_SYM_STRING;
195 char * fini_str = FINI_SYM_STRING;
196
197 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
198 case VALUE: \
199 return "R_" #TYPE; \
200 break;
201
202 static ATTRIBUTE_UNUSED const char *
203 reloc_type_to_name (unsigned int type)
204 {
205 switch (type)
206 {
207 #include "elf/arc-reloc.def"
208
209 default:
210 return "UNKNOWN";
211 break;
212 }
213 }
214 #undef ARC_RELOC_HOWTO
215
216 /* Try to minimize the amount of space occupied by relocation tables
217 on the ROM (not that the ROM won't be swamped by other ELF overhead). */
218
219 #define USE_REL 1
220
221 static ATTRIBUTE_UNUSED bfd_boolean
222 is_reloc_PC_relative (reloc_howto_type *howto)
223 {
224 return (strstr (howto->name, "PC") != NULL) ? TRUE : FALSE;
225 }
226
227 static bfd_boolean
228 is_reloc_SDA_relative (reloc_howto_type *howto)
229 {
230 return (strstr (howto->name, "SDA") != NULL) ? TRUE : FALSE;
231 }
232
233 static bfd_boolean
234 is_reloc_for_GOT (reloc_howto_type * howto)
235 {
236 if (strstr (howto->name, "TLS") != NULL)
237 return FALSE;
238 return (strstr (howto->name, "GOT") != NULL) ? TRUE : FALSE;
239 }
240
241 static bfd_boolean
242 is_reloc_for_PLT (reloc_howto_type * howto)
243 {
244 return (strstr (howto->name, "PLT") != NULL) ? TRUE : FALSE;
245 }
246
247 static bfd_boolean
248 is_reloc_for_TLS (reloc_howto_type *howto)
249 {
250 return (strstr (howto->name, "TLS") != NULL) ? TRUE : FALSE;
251 }
252
253 #define arc_bfd_get_8(A,B,C) bfd_get_8(A,B)
254 #define arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
255 #define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
256 #define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C)
257 #define arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
258 #define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)
259
260
261 static bfd_reloc_status_type
262 arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
263 arelent *reloc_entry,
264 asymbol *symbol_in,
265 void *data ATTRIBUTE_UNUSED,
266 asection *input_section,
267 bfd *output_bfd,
268 char ** error_message ATTRIBUTE_UNUSED)
269 {
270 if (output_bfd != NULL)
271 {
272 reloc_entry->address += input_section->output_offset;
273
274 /* In case of relocateable link and if the reloc is against a
275 section symbol, the addend needs to be adjusted according to
276 where the section symbol winds up in the output section. */
277 if ((symbol_in->flags & BSF_SECTION_SYM) && symbol_in->section)
278 reloc_entry->addend += symbol_in->section->output_offset;
279
280 return bfd_reloc_ok;
281 }
282
283 return bfd_reloc_continue;
284 }
285
286
287 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
288 TYPE = VALUE,
289 enum howto_list
290 {
291 #include "elf/arc-reloc.def"
292 HOWTO_LIST_LAST
293 };
294 #undef ARC_RELOC_HOWTO
295
296 #define ARC_RELOC_HOWTO(TYPE, VALUE, RSIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
297 [TYPE] = HOWTO (R_##TYPE, 0, RSIZE, BITSIZE, FALSE, 0, complain_overflow_##OVERFLOW, arc_elf_reloc, "R_" #TYPE, FALSE, 0, 0, FALSE),
298
299 static struct reloc_howto_struct elf_arc_howto_table[] =
300 {
301 #include "elf/arc-reloc.def"
302 /* Example of what is generated by the preprocessor. Currently kept as an
303 example.
304 HOWTO (R_ARC_NONE, // Type.
305 0, // Rightshift.
306 2, // Size (0 = byte, 1 = short, 2 = long).
307 32, // Bitsize.
308 FALSE, // PC_relative.
309 0, // Bitpos.
310 complain_overflow_bitfield, // Complain_on_overflow.
311 bfd_elf_generic_reloc, // Special_function.
312 "R_ARC_NONE", // Name.
313 TRUE, // Partial_inplace.
314 0, // Src_mask.
315 0, // Dst_mask.
316 FALSE), // PCrel_offset.
317 */
318 };
319 #undef ARC_RELOC_HOWTO
320
321 static void arc_elf_howto_init (void)
322 {
323 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
324 elf_arc_howto_table[TYPE].pc_relative = \
325 (strstr (#FORMULA, " P ") != NULL || strstr (#FORMULA, " PDATA ") != NULL); \
326 elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0); \
327 /* Only 32 bit data relocations should be marked as ME. */ \
328 if (strstr (#FORMULA, " ME ") != NULL) \
329 { \
330 BFD_ASSERT (SIZE == 2); \
331 }
332
333 #include "elf/arc-reloc.def"
334
335 }
336 #undef ARC_RELOC_HOWTO
337
338
339 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
340 [TYPE] = VALUE,
341 const int howto_table_lookup[] =
342 {
343 #include "elf/arc-reloc.def"
344 };
345 #undef ARC_RELOC_HOWTO
346
347 static reloc_howto_type *
348 arc_elf_howto (unsigned int r_type)
349 {
350 if (elf_arc_howto_table[R_ARC_32].dst_mask == 0)
351 arc_elf_howto_init ();
352 return &elf_arc_howto_table[r_type];
353 }
354
355 /* Map BFD reloc types to ARC ELF reloc types. */
356
357 struct arc_reloc_map
358 {
359 bfd_reloc_code_real_type bfd_reloc_val;
360 unsigned char elf_reloc_val;
361 };
362
363 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
364 { BFD_RELOC_##TYPE, R_##TYPE },
365 static const struct arc_reloc_map arc_reloc_map[] =
366 {
367 #include "elf/arc-reloc.def"
368
369 {BFD_RELOC_NONE, R_ARC_NONE},
370 {BFD_RELOC_8, R_ARC_8},
371 {BFD_RELOC_16, R_ARC_16},
372 {BFD_RELOC_24, R_ARC_24},
373 {BFD_RELOC_32, R_ARC_32},
374 };
375 #undef ARC_RELOC_HOWTO
376
377 static reloc_howto_type *
378 arc_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
379 bfd_reloc_code_real_type code)
380 {
381 unsigned int i;
382
383 for (i = ARRAY_SIZE (arc_reloc_map); i--;)
384 {
385 if (arc_reloc_map[i].bfd_reloc_val == code)
386 return arc_elf_howto (arc_reloc_map[i].elf_reloc_val);
387 }
388
389 return NULL;
390 }
391
392 /* Function to set the ELF flag bits. */
393 static bfd_boolean
394 arc_elf_set_private_flags (bfd *abfd, flagword flags)
395 {
396 elf_elfheader (abfd)->e_flags = flags;
397 elf_flags_init (abfd) = TRUE;
398 return TRUE;
399 }
400
401 /* Print private flags. */
402 static bfd_boolean
403 arc_elf_print_private_bfd_data (bfd *abfd, void * ptr)
404 {
405 FILE *file = (FILE *) ptr;
406 flagword flags;
407
408 BFD_ASSERT (abfd != NULL && ptr != NULL);
409
410 /* Print normal ELF private data. */
411 _bfd_elf_print_private_bfd_data (abfd, ptr);
412
413 flags = elf_elfheader (abfd)->e_flags;
414 fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
415
416 switch (flags & EF_ARC_MACH_MSK)
417 {
418 case EF_ARC_CPU_ARCV2HS : fprintf (file, " -mcpu=ARCv2HS"); break;
419 case EF_ARC_CPU_ARCV2EM : fprintf (file, " -mcpu=ARCv2EM"); break;
420 case E_ARC_MACH_ARC600 : fprintf (file, " -mcpu=ARC600"); break;
421 case E_ARC_MACH_ARC601 : fprintf (file, " -mcpu=ARC601"); break;
422 case E_ARC_MACH_ARC700 : fprintf (file, " -mcpu=ARC700"); break;
423 default:
424 fprintf (file, "-mcpu=unknown");
425 break;
426 }
427
428 switch (flags & EF_ARC_OSABI_MSK)
429 {
430 case E_ARC_OSABI_ORIG : fprintf (file, " (ABI:legacy)"); break;
431 case E_ARC_OSABI_V2 : fprintf (file, " (ABI:v2)"); break;
432 case E_ARC_OSABI_V3 : fprintf (file, " (ABI:v3)"); break;
433 default:
434 fprintf (file, "(ABI:unknown)");
435 break;
436 }
437
438 fputc ('\n', file);
439 return TRUE;
440 }
441
442 /* Copy backend specific data from one object module to another. */
443
444 static bfd_boolean
445 arc_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
446 {
447 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
448 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
449 return TRUE;
450
451 BFD_ASSERT (!elf_flags_init (obfd)
452 || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
453
454 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
455 elf_flags_init (obfd) = TRUE;
456
457 /* Copy object attributes. */
458 _bfd_elf_copy_obj_attributes (ibfd, obfd);
459
460 return _bfd_elf_copy_private_bfd_data (ibfd, obfd);
461 }
462
463 static reloc_howto_type *
464 bfd_elf32_bfd_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED,
465 const char *r_name)
466 {
467 unsigned int i;
468
469 for (i = 0; i < ARRAY_SIZE (elf_arc_howto_table); i++)
470 if (elf_arc_howto_table[i].name != NULL
471 && strcasecmp (elf_arc_howto_table[i].name, r_name) == 0)
472 return arc_elf_howto (i);
473
474 return NULL;
475 }
476
477 /* Set the howto pointer for an ARC ELF reloc. */
478
479 static void
480 arc_info_to_howto_rel (bfd * abfd ATTRIBUTE_UNUSED,
481 arelent * cache_ptr,
482 Elf_Internal_Rela * dst)
483 {
484 unsigned int r_type;
485
486 r_type = ELF32_R_TYPE (dst->r_info);
487 BFD_ASSERT (r_type < (unsigned int) R_ARC_max);
488 cache_ptr->howto = arc_elf_howto (r_type);
489 }
490
491 /* Merge backend specific data from an object file to the output
492 object file when linking. */
493
494 static bfd_boolean
495 arc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
496 {
497 unsigned short mach_ibfd;
498 static unsigned short mach_obfd = EM_NONE;
499 flagword out_flags;
500 flagword in_flags;
501 asection *sec;
502
503 /* Check if we have the same endianess. */
504 if (! _bfd_generic_verify_endian_match (ibfd, obfd))
505 {
506 _bfd_error_handler (_("ERROR: Endian Match failed. Attempting to link "
507 "%B with binary %s of opposite endian-ness"),
508 ibfd, bfd_get_filename (obfd));
509 return FALSE;
510 }
511
512 /* Collect ELF flags. */
513 in_flags = elf_elfheader (ibfd)->e_flags & EF_ARC_MACH_MSK;
514 out_flags = elf_elfheader (obfd)->e_flags & EF_ARC_MACH_MSK;
515
516 if (!elf_flags_init (obfd)) /* First call, no flags set. */
517 {
518 elf_flags_init (obfd) = TRUE;
519 out_flags = in_flags;
520 }
521
522 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
523 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
524 return TRUE;
525
526 /* Check to see if the input BFD actually contains any sections. Do
527 not short-circuit dynamic objects; their section list may be
528 emptied by elf_link_add_object_symbols. */
529 if (!(ibfd->flags & DYNAMIC))
530 {
531 bfd_boolean null_input_bfd = TRUE;
532 bfd_boolean only_data_sections = TRUE;
533
534 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
535 {
536 if ((bfd_get_section_flags (ibfd, sec)
537 & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
538 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
539 only_data_sections = FALSE;
540
541 null_input_bfd = FALSE;
542 }
543
544 if (null_input_bfd || only_data_sections)
545 return TRUE;
546 }
547
548 /* Complain about various flag/architecture mismatches. */
549 mach_ibfd = elf_elfheader (ibfd)->e_machine;
550 if (mach_obfd == EM_NONE)
551 {
552 mach_obfd = mach_ibfd;
553 }
554 else
555 {
556 if (mach_ibfd != mach_obfd)
557 {
558 _bfd_error_handler (_("ERROR: Attempting to link %B "
559 "with a binary %s of different architecture"),
560 ibfd, bfd_get_filename (obfd));
561 return FALSE;
562 }
563 else if (in_flags != out_flags)
564 {
565 /* Warn if different flags. */
566 (*_bfd_error_handler)
567 (_("%s: uses different e_flags (0x%lx) fields than "
568 "previous modules (0x%lx)"),
569 bfd_get_filename (ibfd), (long)in_flags, (long)out_flags);
570 if (in_flags && out_flags)
571 return FALSE;
572 /* MWDT doesnt set the eflags hence make sure we choose the
573 eflags set by gcc. */
574 in_flags = in_flags > out_flags ? in_flags : out_flags;
575 }
576 }
577
578 /* Update the flags. */
579 elf_elfheader (obfd)->e_flags = in_flags;
580
581 if (bfd_get_mach (obfd) < bfd_get_mach (ibfd))
582 {
583 return bfd_set_arch_mach (obfd, bfd_arch_arc, bfd_get_mach (ibfd));
584 }
585
586 return TRUE;
587 }
588
589 /* Set the right machine number for an ARC ELF file. */
590 static bfd_boolean
591 arc_elf_object_p (bfd * abfd)
592 {
593 /* Make sure this is initialised, or you'll have the potential of passing
594 garbage---or misleading values---into the call to
595 bfd_default_set_arch_mach (). */
596 int mach = bfd_mach_arc_arc700;
597 unsigned long arch = elf_elfheader (abfd)->e_flags & EF_ARC_MACH_MSK;
598 unsigned e_machine = elf_elfheader (abfd)->e_machine;
599
600 if (e_machine == EM_ARC_COMPACT || e_machine == EM_ARC_COMPACT2)
601 {
602 switch (arch)
603 {
604 case E_ARC_MACH_ARC600:
605 mach = bfd_mach_arc_arc600;
606 break;
607 case E_ARC_MACH_ARC601:
608 mach = bfd_mach_arc_arc601;
609 break;
610 case E_ARC_MACH_ARC700:
611 mach = bfd_mach_arc_arc700;
612 break;
613 case EF_ARC_CPU_ARCV2HS:
614 case EF_ARC_CPU_ARCV2EM:
615 mach = bfd_mach_arc_arcv2;
616 break;
617 default:
618 mach = (e_machine == EM_ARC_COMPACT) ?
619 bfd_mach_arc_arc700 : bfd_mach_arc_arcv2;
620 break;
621 }
622 }
623 else
624 {
625 if (e_machine == EM_ARC)
626 {
627 (*_bfd_error_handler)
628 (_("Error: The ARC4 architecture is no longer supported.\n"));
629 return FALSE;
630 }
631 else
632 {
633 (*_bfd_error_handler)
634 (_("Warning: unset or old architecture flags. \n"
635 " Use default machine.\n"));
636 }
637 }
638
639 return bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach);
640 }
641
642 /* The final processing done just before writing out an ARC ELF object file.
643 This gets the ARC architecture right based on the machine number. */
644
645 static void
646 arc_elf_final_write_processing (bfd * abfd,
647 bfd_boolean linker ATTRIBUTE_UNUSED)
648 {
649 unsigned long emf;
650
651 switch (bfd_get_mach (abfd))
652 {
653 case bfd_mach_arc_arc600:
654 emf = EM_ARC_COMPACT;
655 break;
656 case bfd_mach_arc_arc601:
657 emf = EM_ARC_COMPACT;
658 break;
659 case bfd_mach_arc_arc700:
660 emf = EM_ARC_COMPACT;
661 break;
662 case bfd_mach_arc_arcv2:
663 emf = EM_ARC_COMPACT2;
664 break;
665 default:
666 abort ();
667 }
668
669 elf_elfheader (abfd)->e_machine = emf;
670
671 /* Record whatever is the current syscall ABI version. */
672 elf_elfheader (abfd)->e_flags |= E_ARC_OSABI_CURRENT;
673 }
674
675 #define BFD_DEBUG_PIC(...)
676
677 struct arc_relocation_data
678 {
679 bfd_vma reloc_offset;
680 bfd_vma reloc_addend;
681 bfd_vma got_offset_value;
682
683 bfd_vma sym_value;
684 asection * sym_section;
685
686 reloc_howto_type *howto;
687
688 asection * input_section;
689
690 bfd_vma sdata_begin_symbol_vma;
691 bfd_boolean sdata_begin_symbol_vma_set;
692 bfd_vma got_symbol_vma;
693
694 bfd_boolean should_relocate;
695 };
696
697 static void
698 debug_arc_reloc (struct arc_relocation_data reloc_data)
699 {
700 PR_DEBUG ("Reloc type=%s, should_relocate = %s\n",
701 reloc_data.howto->name,
702 reloc_data.should_relocate ? "true" : "false");
703 PR_DEBUG (" offset = 0x%x, addend = 0x%x\n",
704 (unsigned int) reloc_data.reloc_offset,
705 (unsigned int) reloc_data.reloc_addend);
706 PR_DEBUG (" Symbol:\n");
707 PR_DEBUG (" value = 0x%08x\n",
708 (unsigned int) reloc_data.sym_value);
709 if (reloc_data.sym_section != NULL)
710 {
711 PR_DEBUG ("IN IF\n");
712 PR_DEBUG (
713 " section name = %s, output_offset 0x%08x",
714 reloc_data.sym_section->name,
715 (unsigned int) reloc_data.sym_section->output_offset);
716 if (reloc_data.sym_section->output_section != NULL)
717 {
718 PR_DEBUG (
719 ", output_section->vma = 0x%08x",
720 ((unsigned int) reloc_data.sym_section->output_section->vma));
721 }
722
723 PR_DEBUG ( "\n");
724 }
725 else
726 {
727 PR_DEBUG ( " symbol section is NULL\n");
728 }
729
730 PR_DEBUG ( " Input_section:\n");
731 if (reloc_data.input_section != NULL)
732 {
733 PR_DEBUG (
734 " section name = %s, output_offset 0x%08x, output_section->vma = 0x%08x\n",
735 reloc_data.input_section->name,
736 (unsigned int) reloc_data.input_section->output_offset,
737 (unsigned int) reloc_data.input_section->output_section->vma);
738 PR_DEBUG ( " changed_address = 0x%08x\n",
739 (unsigned int) (reloc_data.input_section->output_section->vma +
740 reloc_data.input_section->output_offset +
741 reloc_data.reloc_offset));
742 }
743 else
744 {
745 PR_DEBUG ( " input section is NULL\n");
746 }
747 }
748
749 static bfd_vma
750 middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
751 {
752 if (do_it)
753 {
754 insn =
755 ((insn & 0xffff0000) >> 16) |
756 ((insn & 0xffff) << 16);
757 }
758 return insn;
759 }
760
761 #define ME(reloc) (reloc)
762
763 #define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") != NULL) \
764 && (!bfd_big_endian (BFD)))
765
766 #define S (reloc_data.sym_value \
767 + (reloc_data.sym_section->output_section != NULL ? \
768 (reloc_data.sym_section->output_offset \
769 + reloc_data.sym_section->output_section->vma) : 0) \
770 )
771 #define L (reloc_data.sym_value \
772 + (reloc_data.sym_section->output_section != NULL ? \
773 (reloc_data.sym_section->output_offset \
774 + reloc_data.sym_section->output_section->vma) : 0) \
775 )
776 #define A (reloc_data.reloc_addend)
777 #define B (0)
778 #define G (reloc_data.got_offset_value)
779 #define GOT (reloc_data.got_symbol_vma)
780 #define GOT_BEGIN (htab->sgot->output_section->vma)
781
782 #define MES (0)
783 /* P: relative offset to PCL The offset should be to the
784 current location aligned to 32 bits. */
785 #define P ( \
786 ( \
787 (reloc_data.input_section->output_section != NULL ? \
788 reloc_data.input_section->output_section->vma : 0) \
789 + reloc_data.input_section->output_offset \
790 + (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0)) \
791 ) & ~0x3)
792 #define PDATA ( \
793 (reloc_data.input_section->output_section->vma \
794 + reloc_data.input_section->output_offset \
795 + (reloc_data.reloc_offset) \
796 ))
797 #define SECTSTAR (reloc_data.input_section->output_offset)
798 #define SECTSTART (reloc_data.input_section->output_offset)
799 #define _SDA_BASE_ (reloc_data.sdata_begin_symbol_vma)
800 #define TLS_REL ((elf_hash_table (info))->tls_sec->output_section->vma)
801 #define _SDA_BASE_ (reloc_data.sdata_begin_symbol_vma)
802 #define TLS_TBSS (8)
803 #define TCB_SIZE (8)
804
805 #define none (0)
806
807 #define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA) \
808 {\
809 asection *sym_section = reloc_data.sym_section; \
810 asection *input_section = reloc_data.input_section; \
811 ARC_DEBUG ("FORMULA = " #FORMULA "\n"); \
812 ARC_DEBUG ("S = 0x%x\n", S); \
813 ARC_DEBUG ("A = 0x%x\n", A); \
814 ARC_DEBUG ("L = 0x%x\n", L); \
815 if (sym_section->output_section != NULL) \
816 { \
817 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
818 sym_section->output_section->vma + sym_section->output_offset); \
819 } \
820 else \
821 { \
822 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
823 } \
824 if (input_section->output_section != NULL) \
825 { \
826 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
827 input_section->output_section->vma + input_section->output_offset); \
828 } \
829 else \
830 { \
831 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
832 } \
833 ARC_DEBUG ("PCL = 0x%x\n", P); \
834 ARC_DEBUG ("P = 0x%x\n", P); \
835 ARC_DEBUG ("G = 0x%x\n", G); \
836 ARC_DEBUG ("SDA_OFFSET = 0x%x\n", _SDA_BASE_); \
837 ARC_DEBUG ("SDA_SET = %d\n", reloc_data.sdata_begin_symbol_vma_set); \
838 ARC_DEBUG ("GOT_OFFSET = 0x%x\n", GOT); \
839 ARC_DEBUG ("relocation = 0x%08x\n", relocation); \
840 ARC_DEBUG ("before = 0x%08x\n", (unsigned int) insn); \
841 ARC_DEBUG ("data = 0x%08x (%u) (%d)\n", (unsigned int) relocation, (unsigned int) relocation, (int) relocation); \
842 }
843
844 #define PRINT_DEBUG_RELOC_INFO_AFTER \
845 { \
846 ARC_DEBUG ("after = 0x%08x\n", (unsigned int) insn); \
847 }
848
849 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
850 case R_##TYPE: \
851 { \
852 bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
853 relocation = FORMULA ; \
854 PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA) \
855 insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
856 insn = RELOC_FUNCTION (insn, relocation); \
857 insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
858 PRINT_DEBUG_RELOC_INFO_AFTER \
859 } \
860 break;
861
862 static bfd_reloc_status_type
863 arc_do_relocation (bfd_byte * contents,
864 struct arc_relocation_data reloc_data,
865 struct bfd_link_info *info)
866 {
867 bfd_vma relocation = 0;
868 bfd_vma insn;
869 bfd_vma orig_insn ATTRIBUTE_UNUSED;
870 bfd * abfd = reloc_data.input_section->owner;
871 struct elf_link_hash_table *htab ATTRIBUTE_UNUSED = elf_hash_table (info);
872
873 if (reloc_data.should_relocate == FALSE)
874 return bfd_reloc_ok;
875
876 switch (reloc_data.howto->size)
877 {
878 case 2:
879 insn = arc_bfd_get_32 (abfd,
880 contents + reloc_data.reloc_offset,
881 reloc_data.input_section);
882 break;
883 case 1:
884 insn = arc_bfd_get_16 (abfd,
885 contents + reloc_data.reloc_offset,
886 reloc_data.input_section);
887 break;
888 case 0:
889 insn = arc_bfd_get_8 (abfd,
890 contents + reloc_data.reloc_offset,
891 reloc_data.input_section);
892 break;
893 default:
894 insn = 0;
895 BFD_ASSERT (0);
896 break;
897 }
898
899 orig_insn = insn;
900
901 switch (reloc_data.howto->type)
902 {
903 #include "elf/arc-reloc.def"
904
905 default:
906 BFD_ASSERT (0);
907 break;
908 }
909
910 /* Check for relocation overflow. */
911 if (reloc_data.howto->complain_on_overflow != complain_overflow_dont)
912 {
913 bfd_reloc_status_type flag;
914 flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
915 reloc_data.howto->bitsize,
916 reloc_data.howto->rightshift,
917 bfd_arch_bits_per_address (abfd),
918 relocation);
919
920 #undef DEBUG_ARC_RELOC
921 #define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
922 if (flag != bfd_reloc_ok)
923 {
924 PR_DEBUG ( "Relocation overflows !!!!\n");
925
926 DEBUG_ARC_RELOC (reloc_data);
927
928 PR_DEBUG (
929 "Relocation value = signed -> %d, unsigned -> %u"
930 ", hex -> (0x%08x)\n",
931 (int) relocation,
932 (unsigned int) relocation,
933 (unsigned int) relocation);
934 return flag;
935 }
936 }
937 #undef DEBUG_ARC_RELOC
938 #define DEBUG_ARC_RELOC(A)
939
940 switch (reloc_data.howto->size)
941 {
942 case 2:
943 arc_bfd_put_32 (abfd, insn,
944 contents + reloc_data.reloc_offset,
945 reloc_data.input_section);
946 break;
947 case 1:
948 arc_bfd_put_16 (abfd, insn,
949 contents + reloc_data.reloc_offset,
950 reloc_data.input_section);
951 break;
952 case 0:
953 arc_bfd_put_8 (abfd, insn,
954 contents + reloc_data.reloc_offset,
955 reloc_data.input_section);
956 break;
957 default:
958 ARC_DEBUG ("size = %d\n", reloc_data.howto->size);
959 BFD_ASSERT (0);
960 break;
961 }
962
963 return bfd_reloc_ok;
964 }
965 #undef S
966 #undef A
967 #undef B
968 #undef G
969 #undef GOT
970 #undef L
971 #undef MES
972 #undef P
973 #undef SECTSTAR
974 #undef SECTSTART
975 #undef _SDA_BASE_
976 #undef none
977
978 #undef ARC_RELOC_HOWTO
979
980 static struct got_entry **
981 arc_get_local_got_ents (bfd * abfd)
982 {
983 static struct got_entry **local_got_ents = NULL;
984
985 if (local_got_ents == NULL)
986 {
987 size_t size;
988 Elf_Internal_Shdr *symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
989
990 size = symtab_hdr->sh_info * sizeof (bfd_vma);
991 local_got_ents = (struct got_entry **)
992 bfd_alloc (abfd, sizeof(struct got_entry *) * size);
993 if (local_got_ents == NULL)
994 return FALSE;
995
996 memset (local_got_ents, 0, sizeof(struct got_entry *) * size);
997 elf_local_got_ents (abfd) = local_got_ents;
998 }
999
1000 return local_got_ents;
1001 }
1002
1003 /* Relocate an arc ELF section.
1004 Function : elf_arc_relocate_section
1005 Brief : Relocate an arc section, by handling all the relocations
1006 appearing in that section.
1007 Args : output_bfd : The bfd being written to.
1008 info : Link information.
1009 input_bfd : The input bfd.
1010 input_section : The section being relocated.
1011 contents : contents of the section being relocated.
1012 relocs : List of relocations in the section.
1013 local_syms : is a pointer to the swapped in local symbols.
1014 local_section : is an array giving the section in the input file
1015 corresponding to the st_shndx field of each
1016 local symbol. */
1017 static bfd_boolean
1018 elf_arc_relocate_section (bfd * output_bfd,
1019 struct bfd_link_info * info,
1020 bfd * input_bfd,
1021 asection * input_section,
1022 bfd_byte * contents,
1023 Elf_Internal_Rela * relocs,
1024 Elf_Internal_Sym * local_syms,
1025 asection ** local_sections)
1026 {
1027 Elf_Internal_Shdr * symtab_hdr;
1028 struct elf_link_hash_entry ** sym_hashes;
1029 struct got_entry ** local_got_ents;
1030 Elf_Internal_Rela * rel;
1031 Elf_Internal_Rela * relend;
1032 struct elf_link_hash_table *htab = elf_hash_table (info);
1033
1034 symtab_hdr = &((elf_tdata (input_bfd))->symtab_hdr);
1035 sym_hashes = elf_sym_hashes (input_bfd);
1036
1037 rel = relocs;
1038 relend = relocs + input_section->reloc_count;
1039 for (; rel < relend; rel++)
1040 {
1041 enum elf_arc_reloc_type r_type;
1042 reloc_howto_type * howto;
1043 unsigned long r_symndx;
1044 struct elf_link_hash_entry * h;
1045 Elf_Internal_Sym * sym;
1046 asection * sec;
1047 struct elf_link_hash_entry *h2;
1048
1049 struct arc_relocation_data reloc_data =
1050 {
1051 .reloc_offset = 0,
1052 .reloc_addend = 0,
1053 .got_offset_value = 0,
1054 .sym_value = 0,
1055 .sym_section = NULL,
1056 .howto = NULL,
1057 .input_section = NULL,
1058 .sdata_begin_symbol_vma = 0,
1059 .sdata_begin_symbol_vma_set = FALSE,
1060 .got_symbol_vma = 0,
1061 .should_relocate = FALSE
1062 };
1063
1064 r_type = ELF32_R_TYPE (rel->r_info);
1065
1066 if (r_type >= (int) R_ARC_max)
1067 {
1068 bfd_set_error (bfd_error_bad_value);
1069 return FALSE;
1070 }
1071 howto = &elf_arc_howto_table[r_type];
1072
1073 r_symndx = ELF32_R_SYM (rel->r_info);
1074
1075 /* If we are generating another .o file and the symbol in not
1076 local, skip this relocation. */
1077 if (bfd_link_relocatable (info))
1078 {
1079 /* This is a relocateable link. We don't have to change
1080 anything, unless the reloc is against a section symbol,
1081 in which case we have to adjust according to where the
1082 section symbol winds up in the output section. */
1083
1084 /* Checks if this is a local symbol and thus the reloc
1085 might (will??) be against a section symbol. */
1086 if (r_symndx < symtab_hdr->sh_info)
1087 {
1088 sym = local_syms + r_symndx;
1089 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1090 {
1091 sec = local_sections[r_symndx];
1092
1093 /* for RELA relocs.Just adjust the addend
1094 value in the relocation entry. */
1095 rel->r_addend += sec->output_offset + sym->st_value;
1096
1097 BFD_DEBUG_PIC (
1098 PR_DEBUG ("local symbols reloc "
1099 "(section=%d %s) seen in %s\n",
1100 r_symndx,
1101 local_sections[r_symndx]->name,
1102 __PRETTY_FUNCTION__)
1103 );
1104 }
1105 }
1106
1107 continue;
1108 }
1109
1110 h2 = elf_link_hash_lookup (elf_hash_table (info), "__SDATA_BEGIN__",
1111 FALSE, FALSE, TRUE);
1112
1113 if (reloc_data.sdata_begin_symbol_vma_set == FALSE
1114 && h2 != NULL && h2->root.type != bfd_link_hash_undefined
1115 && h2->root.u.def.section->output_section != NULL)
1116 /* TODO: Verify this condition. */
1117 {
1118 reloc_data.sdata_begin_symbol_vma =
1119 (h2->root.u.def.value +
1120 h2->root.u.def.section->output_section->vma);
1121 reloc_data.sdata_begin_symbol_vma_set = TRUE;
1122 }
1123
1124 reloc_data.input_section = input_section;
1125 reloc_data.howto = howto;
1126 reloc_data.reloc_offset = rel->r_offset;
1127 reloc_data.reloc_addend = rel->r_addend;
1128
1129 /* This is a final link. */
1130 h = NULL;
1131 sym = NULL;
1132 sec = NULL;
1133
1134 if (r_symndx < symtab_hdr->sh_info) /* A local symbol. */
1135 {
1136 local_got_ents = arc_get_local_got_ents (output_bfd);
1137 struct got_entry *entry = local_got_ents[r_symndx];
1138
1139 sym = local_syms + r_symndx;
1140 sec = local_sections[r_symndx];
1141
1142 reloc_data.sym_value = sym->st_value;
1143 reloc_data.sym_section = sec;
1144
1145 /* Mergeable section handling. */
1146 if ((sec->flags & SEC_MERGE)
1147 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1148 {
1149 asection *msec;
1150 msec = sec;
1151 rel->r_addend = _bfd_elf_rel_local_sym (output_bfd, sym,
1152 &msec, rel->r_addend);
1153 rel->r_addend -= (sec->output_section->vma
1154 + sec->output_offset
1155 + sym->st_value);
1156 rel->r_addend += msec->output_section->vma + msec->output_offset;
1157
1158 reloc_data.reloc_addend = rel->r_addend;
1159 }
1160
1161 if ((is_reloc_for_GOT (howto)
1162 || is_reloc_for_TLS (howto)) && entry != NULL)
1163 {
1164 if (is_reloc_for_TLS (howto))
1165 while (entry->type == GOT_NORMAL && entry->next != NULL)
1166 entry = entry->next;
1167
1168 if (is_reloc_for_GOT (howto))
1169 while (entry->type != GOT_NORMAL && entry->next != NULL)
1170 entry = entry->next;
1171
1172 if (entry->type == GOT_TLS_GD && entry->processed == FALSE)
1173 {
1174 bfd_vma sym_vma = sym->st_value
1175 + sec->output_section->vma
1176 + sec->output_offset;
1177
1178 /* Create dynamic relocation for local sym. */
1179 ADD_RELA (output_bfd, got, entry->offset, 0,
1180 R_ARC_TLS_DTPMOD, 0);
1181 ADD_RELA (output_bfd, got, entry->offset+4, 0,
1182 R_ARC_TLS_DTPOFF, 0);
1183
1184 bfd_vma sec_vma = sec->output_section->vma
1185 + sec->output_offset;
1186 bfd_put_32 (output_bfd, sym_vma - sec_vma,
1187 htab->sgot->contents + entry->offset + 4);
1188
1189 ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_GD value "
1190 "= 0x%x @ 0x%x, for symbol %s\n",
1191 sym_vma - sec_vma,
1192 htab->sgot->contents + entry->offset + 4,
1193 "(local)");
1194
1195 entry->processed = TRUE;
1196 }
1197 if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
1198 {
1199 bfd_vma sym_vma = sym->st_value
1200 + sec->output_section->vma
1201 + sec->output_offset;
1202 bfd_vma sec_vma = htab->tls_sec->output_section->vma;
1203 bfd_put_32 (output_bfd, sym_vma - sec_vma,
1204 htab->sgot->contents + entry->offset);
1205 /* TODO: Check if this type of relocs is the cause
1206 for all the ARC_NONE dynamic relocs. */
1207
1208 ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_IE value = "
1209 "0x%x @ 0x%x, for symbol %s\n",
1210 sym_vma - sec_vma,
1211 htab->sgot->contents + entry->offset,
1212 "(local)");
1213
1214 entry->processed = TRUE;
1215 }
1216 if (entry->type == GOT_NORMAL && entry->processed == FALSE)
1217 {
1218 bfd_vma sec_vma = reloc_data.sym_section->output_section->vma
1219 + reloc_data.sym_section->output_offset;
1220
1221 bfd_put_32 (output_bfd, reloc_data.sym_value + sec_vma,
1222 htab->sgot->contents + entry->offset);
1223
1224 ARC_DEBUG ("arc_info: PATCHED: 0x%08x @ 0x%08x for "
1225 "sym %s in got offset 0x%x\n",
1226 reloc_data.sym_value + sec_vma,
1227 htab->sgot->output_section->vma
1228 + htab->sgot->output_offset + entry->offset,
1229 "(local)",
1230 entry->offset);
1231 entry->processed = TRUE;
1232 }
1233
1234 reloc_data.got_offset_value = entry->offset;
1235 ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
1236 "vma = 0x%x for symbol %s\n",
1237 entry->type, entry->offset,
1238 htab->sgot->output_section->vma
1239 + htab->sgot->output_offset + entry->offset,
1240 "(local)");
1241 }
1242
1243 BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1244 if (htab->sgot != NULL)
1245 reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1246 + htab->sgot->output_offset;
1247
1248 reloc_data.should_relocate = TRUE;
1249 }
1250 else /* Global symbol. */
1251 {
1252 /* Get the symbol's entry in the symtab. */
1253 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1254
1255 while (h->root.type == bfd_link_hash_indirect
1256 || h->root.type == bfd_link_hash_warning)
1257 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1258
1259 BFD_ASSERT ((h->dynindx == -1) >= (h->forced_local != 0));
1260 /* If we have encountered a definition for this symbol. */
1261 if (h->root.type == bfd_link_hash_defined
1262 || h->root.type == bfd_link_hash_defweak)
1263 {
1264 reloc_data.sym_value = h->root.u.def.value;
1265 reloc_data.sym_section = h->root.u.def.section;
1266
1267 reloc_data.should_relocate = TRUE;
1268
1269 if (is_reloc_for_GOT (howto) && !bfd_link_pic (info))
1270 {
1271 /* TODO: Change it to use arc_do_relocation with
1272 ARC_32 reloc. Try to use ADD_RELA macro. */
1273 bfd_vma relocation =
1274 reloc_data.sym_value + reloc_data.reloc_addend
1275 + (reloc_data.sym_section->output_section != NULL ?
1276 (reloc_data.sym_section->output_offset
1277 + reloc_data.sym_section->output_section->vma)
1278 : 0);
1279
1280 BFD_ASSERT (h->got.glist);
1281 bfd_vma got_offset = h->got.glist->offset;
1282 bfd_put_32 (output_bfd, relocation,
1283 htab->sgot->contents + got_offset);
1284 }
1285 if (is_reloc_for_PLT (howto) && h->plt.offset != (bfd_vma) -1)
1286 {
1287 /* TODO: This is repeated up here. */
1288 reloc_data.sym_value = h->plt.offset;
1289 reloc_data.sym_section = htab->splt;
1290 }
1291 }
1292 else if (h->root.type == bfd_link_hash_undefweak)
1293 {
1294 /* Is weak symbol and has no definition. */
1295 if (is_reloc_for_GOT (howto))
1296 {
1297 reloc_data.sym_value = h->root.u.def.value;
1298 reloc_data.sym_section = htab->sgot;
1299 reloc_data.should_relocate = TRUE;
1300 }
1301 else if (is_reloc_for_PLT (howto)
1302 && h->plt.offset != (bfd_vma) -1)
1303 {
1304 /* TODO: This is repeated up here. */
1305 reloc_data.sym_value = h->plt.offset;
1306 reloc_data.sym_section = htab->splt;
1307 reloc_data.should_relocate = TRUE;
1308 }
1309 else
1310 continue;
1311 }
1312 else
1313 {
1314 if (is_reloc_for_GOT (howto))
1315 {
1316 reloc_data.sym_value = h->root.u.def.value;
1317 reloc_data.sym_section = htab->sgot;
1318
1319 reloc_data.should_relocate = TRUE;
1320 }
1321 else if (is_reloc_for_PLT (howto))
1322 {
1323 /* Fail if it is linking for PIE and the symbol is
1324 undefined. */
1325 if (bfd_link_executable (info)
1326 && !(*info->callbacks->undefined_symbol)
1327 (info, h->root.root.string, input_bfd, input_section,
1328 rel->r_offset, TRUE))
1329 {
1330 return FALSE;
1331 }
1332 reloc_data.sym_value = h->plt.offset;
1333 reloc_data.sym_section = htab->splt;
1334
1335 reloc_data.should_relocate = TRUE;
1336 }
1337 else if (!bfd_link_pic (info)
1338 && !(*info->callbacks->undefined_symbol)
1339 (info, h->root.root.string, input_bfd, input_section,
1340 rel->r_offset, TRUE))
1341 {
1342 return FALSE;
1343 }
1344 }
1345
1346 if (h->got.glist != NULL)
1347 {
1348 struct got_entry *entry = h->got.glist;
1349
1350 if (is_reloc_for_GOT (howto) || is_reloc_for_TLS (howto))
1351 {
1352 if (! elf_hash_table (info)->dynamic_sections_created
1353 || (bfd_link_pic (info)
1354 && SYMBOL_REFERENCES_LOCAL (info, h)))
1355 {
1356 reloc_data.sym_value = h->root.u.def.value;
1357 reloc_data.sym_section = h->root.u.def.section;
1358
1359 if (is_reloc_for_TLS (howto))
1360 while (entry->type == GOT_NORMAL && entry->next != NULL)
1361 entry = entry->next;
1362
1363 if (entry->processed == FALSE
1364 && (entry->type == GOT_TLS_GD
1365 || entry->type == GOT_TLS_IE))
1366 {
1367 bfd_vma sym_value = h->root.u.def.value
1368 + h->root.u.def.section->output_section->vma
1369 + h->root.u.def.section->output_offset;
1370
1371 bfd_vma sec_vma =
1372 elf_hash_table (info)->tls_sec->output_section->vma;
1373
1374 bfd_put_32 (output_bfd,
1375 sym_value - sec_vma,
1376 htab->sgot->contents + entry->offset
1377 + (entry->existing_entries == MOD_AND_OFF ? 4 : 0));
1378
1379 ARC_DEBUG ("arc_info: FIXED -> %s value = 0x%x "
1380 "@ 0x%x, for symbol %s\n",
1381 (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
1382 "GOT_TLS_IE"),
1383 sym_value - sec_vma,
1384 htab->sgot->contents + entry->offset
1385 + (entry->existing_entries == MOD_AND_OFF ? 4 : 0),
1386 h->root.root.string);
1387
1388 entry->processed = TRUE;
1389 }
1390
1391 if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
1392 {
1393 bfd_vma sec_vma = htab->tls_sec->output_section->vma;
1394 bfd_put_32 (output_bfd,
1395 reloc_data.sym_value - sec_vma,
1396 htab->sgot->contents + entry->offset);
1397 }
1398
1399 if (entry->type == GOT_NORMAL && entry->processed == FALSE)
1400 {
1401 bfd_vma sec_vma =
1402 reloc_data.sym_section->output_section->vma
1403 + reloc_data.sym_section->output_offset;
1404
1405 if (h->root.type != bfd_link_hash_undefweak)
1406 {
1407 bfd_put_32 (output_bfd,
1408 reloc_data.sym_value + sec_vma,
1409 htab->sgot->contents + entry->offset);
1410
1411 ARC_DEBUG ("arc_info: PATCHED: 0x%08x "
1412 "@ 0x%08x for sym %s in got offset 0x%x\n",
1413 reloc_data.sym_value + sec_vma,
1414 htab->sgot->output_section->vma
1415 + htab->sgot->output_offset + entry->offset,
1416 h->root.root.string,
1417 entry->offset);
1418 }
1419 else
1420 {
1421 ARC_DEBUG ("arc_info: PATCHED: NOT_PATCHED "
1422 "@ 0x%08x for sym %s in got offset 0x%x "
1423 "(is undefweak)\n",
1424 htab->sgot->output_section->vma
1425 + htab->sgot->output_offset + entry->offset,
1426 h->root.root.string,
1427 entry->offset);
1428 }
1429
1430 entry->processed = TRUE;
1431 }
1432 }
1433 }
1434
1435 reloc_data.got_offset_value = entry->offset;
1436
1437 ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
1438 "vma = 0x%x for symbol %s\n",
1439 entry->type, entry->offset,
1440 htab->sgot->output_section->vma
1441 + htab->sgot->output_offset + entry->offset,
1442 h->root.root.string);
1443 }
1444
1445 BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1446 if (htab->sgot != NULL)
1447 reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1448 + htab->sgot->output_offset;
1449 }
1450
1451 switch (r_type)
1452 {
1453 case R_ARC_32:
1454 case R_ARC_32_ME:
1455 case R_ARC_PC32:
1456 case R_ARC_32_PCREL:
1457 if (bfd_link_pic (info) && !bfd_link_pie (info)
1458 && ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1459 || (h != NULL
1460 && h->dynindx != -1
1461 && (!info->symbolic || !h->def_regular))))
1462 {
1463 Elf_Internal_Rela outrel;
1464 bfd_byte *loc;
1465 bfd_boolean skip = FALSE;
1466 bfd_boolean relocate = FALSE;
1467 asection *sreloc = _bfd_elf_get_dynamic_reloc_section
1468 (input_bfd, input_section,
1469 /*RELA*/ TRUE);
1470
1471 BFD_ASSERT (sreloc != NULL);
1472
1473 outrel.r_offset = _bfd_elf_section_offset (output_bfd,
1474 info,
1475 input_section,
1476 rel->r_offset);
1477 if (outrel.r_offset == (bfd_vma) -1)
1478 skip = TRUE;
1479
1480 outrel.r_addend = rel->r_addend;
1481 outrel.r_offset += (input_section->output_section->vma
1482 + input_section->output_offset);
1483
1484 if (skip)
1485 {
1486 memset (&outrel, 0, sizeof outrel);
1487 relocate = FALSE;
1488 }
1489 else if (r_type == R_ARC_PC32
1490 || r_type == R_ARC_32_PCREL)
1491 {
1492 BFD_ASSERT (h != NULL && h->dynindx != -1);
1493 if ((input_section->flags & SEC_ALLOC) != 0)
1494 relocate = FALSE;
1495 else
1496 relocate = TRUE;
1497 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1498 }
1499 else
1500 {
1501 /* Handle local symbols, they either do not have a
1502 global hash table entry (h == NULL), or are
1503 forced local due to a version script
1504 (h->forced_local), or the third condition is
1505 legacy, it appears to say something like, for
1506 links where we are pre-binding the symbols, or
1507 there's not an entry for this symbol in the
1508 dynamic symbol table, and it's a regular symbol
1509 not defined in a shared object, then treat the
1510 symbol as local, resolve it now. */
1511 if (h == NULL
1512 || ((info->symbolic || h->dynindx == -1)
1513 && h->def_regular)
1514 || h->forced_local)
1515 {
1516 relocate = TRUE;
1517 /* outrel.r_addend = 0; */
1518 outrel.r_info = ELF32_R_INFO (0, R_ARC_RELATIVE);
1519 }
1520 else
1521 {
1522 BFD_ASSERT (h->dynindx != -1);
1523
1524 /* This type of dynamic relocation cannot be created
1525 for code sections. */
1526 BFD_ASSERT ((input_section->flags & SEC_CODE) == 0);
1527
1528 if ((input_section->flags & SEC_ALLOC) != 0)
1529 relocate = FALSE;
1530 else
1531 relocate = TRUE;
1532 outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_32);
1533 }
1534 }
1535
1536 BFD_ASSERT (sreloc->contents != 0);
1537
1538 loc = sreloc->contents;
1539 loc += sreloc->reloc_count * sizeof (Elf32_External_Rela);
1540 sreloc->reloc_count += 1;
1541
1542 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1543
1544 if (relocate == FALSE)
1545 continue;
1546 }
1547 break;
1548 default:
1549 break;
1550 }
1551
1552 if (is_reloc_SDA_relative (howto)
1553 && (reloc_data.sdata_begin_symbol_vma_set == FALSE))
1554 {
1555 (*_bfd_error_handler)
1556 ("Error: Linker symbol __SDATA_BEGIN__ not found");
1557 bfd_set_error (bfd_error_bad_value);
1558 return FALSE;
1559 }
1560
1561 DEBUG_ARC_RELOC (reloc_data);
1562
1563 if (arc_do_relocation (contents, reloc_data, info) != bfd_reloc_ok)
1564 return FALSE;
1565 }
1566
1567 return TRUE;
1568 }
1569
1570 static struct dynamic_sections
1571 arc_create_dynamic_sections (bfd * abfd, struct bfd_link_info *info)
1572 {
1573 struct elf_link_hash_table *htab;
1574 bfd *dynobj;
1575 struct dynamic_sections ds =
1576 {
1577 .initialized = FALSE,
1578 .sgot = NULL,
1579 .srelgot = NULL,
1580 .sgotplt = NULL,
1581 .srelgotplt = NULL,
1582 .sdyn = NULL,
1583 .splt = NULL,
1584 .srelplt = NULL
1585 };
1586
1587 htab = elf_hash_table (info);
1588 BFD_ASSERT (htab);
1589
1590 /* Create dynamic sections for relocatable executables so that we
1591 can copy relocations. */
1592 if (! htab->dynamic_sections_created && bfd_link_pic (info))
1593 {
1594 if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
1595 BFD_ASSERT (0);
1596 }
1597
1598 dynobj = (elf_hash_table (info))->dynobj;
1599
1600 if (dynobj)
1601 {
1602 ds.sgot = htab->sgot;
1603 ds.srelgot = htab->srelgot;
1604
1605 ds.sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
1606 ds.srelgotplt = ds.srelplt;
1607
1608 ds.splt = bfd_get_section_by_name (dynobj, ".plt");
1609 ds.srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
1610 }
1611
1612 if (htab->dynamic_sections_created)
1613 {
1614 ds.sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
1615 }
1616
1617 ds.initialized = TRUE;
1618
1619 return ds;
1620 }
1621
1622 #define ADD_SYMBOL_REF_SEC_AND_RELOC(SECNAME, COND_FOR_RELOC, H) \
1623 htab->s##SECNAME->size; \
1624 { \
1625 if (COND_FOR_RELOC) \
1626 { \
1627 htab->srel##SECNAME->size += sizeof (Elf32_External_Rela); \
1628 ARC_DEBUG ("arc_info: Added reloc space in " \
1629 #SECNAME " section at " __FILE__ \
1630 ":%d for symbol\n", \
1631 __LINE__, name_for_global_symbol (H)); \
1632 } \
1633 if (H) \
1634 if (h->dynindx == -1 && !h->forced_local) \
1635 if (! bfd_elf_link_record_dynamic_symbol (info, H)) \
1636 return FALSE; \
1637 htab->s##SECNAME->size += 4; \
1638 }
1639
1640 static bfd_boolean
1641 elf_arc_check_relocs (bfd * abfd,
1642 struct bfd_link_info * info,
1643 asection * sec,
1644 const Elf_Internal_Rela * relocs)
1645 {
1646 Elf_Internal_Shdr * symtab_hdr;
1647 struct elf_link_hash_entry ** sym_hashes;
1648 struct got_entry ** local_got_ents;
1649 const Elf_Internal_Rela * rel;
1650 const Elf_Internal_Rela * rel_end;
1651 bfd * dynobj;
1652 asection * sreloc = NULL;
1653 struct elf_link_hash_table * htab = elf_hash_table (info);
1654
1655 if (bfd_link_relocatable (info))
1656 return TRUE;
1657
1658 dynobj = (elf_hash_table (info))->dynobj;
1659 symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1660 sym_hashes = elf_sym_hashes (abfd);
1661 local_got_ents = arc_get_local_got_ents (abfd);
1662
1663 rel_end = relocs + sec->reloc_count;
1664 for (rel = relocs; rel < rel_end; rel++)
1665 {
1666 enum elf_arc_reloc_type r_type;
1667 reloc_howto_type *howto;
1668 unsigned long r_symndx;
1669 struct elf_link_hash_entry *h;
1670
1671 r_type = ELF32_R_TYPE (rel->r_info);
1672
1673 if (r_type >= (int) R_ARC_max)
1674 {
1675 bfd_set_error (bfd_error_bad_value);
1676 return FALSE;
1677 }
1678 howto = &elf_arc_howto_table[r_type];
1679
1680 if (dynobj == NULL
1681 && (is_reloc_for_GOT (howto) == TRUE
1682 || is_reloc_for_TLS (howto) == TRUE))
1683 {
1684 dynobj = elf_hash_table (info)->dynobj = abfd;
1685 if (! _bfd_elf_create_got_section (abfd, info))
1686 return FALSE;
1687 }
1688
1689 /* Load symbol information. */
1690 r_symndx = ELF32_R_SYM (rel->r_info);
1691 if (r_symndx < symtab_hdr->sh_info) /* Is a local symbol. */
1692 h = NULL;
1693 else /* Global one. */
1694 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1695
1696 switch (r_type)
1697 {
1698 case R_ARC_32:
1699 case R_ARC_32_ME:
1700 /* During shared library creation, these relocs should not
1701 appear in a shared library (as memory will be read only
1702 and the dynamic linker can not resolve these. However
1703 the error should not occur for e.g. debugging or
1704 non-readonly sections. */
1705 if (bfd_link_dll (info) && !bfd_link_pie (info)
1706 && (sec->flags & SEC_ALLOC) != 0
1707 && (sec->flags & SEC_READONLY) != 0)
1708 {
1709 const char *name;
1710 if (h)
1711 name = h->root.root.string;
1712 else
1713 /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); */
1714 name = "UNKNOWN";
1715 (*_bfd_error_handler)
1716 (_("\
1717 %B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
1718 abfd,
1719 arc_elf_howto (r_type)->name,
1720 name);
1721 bfd_set_error (bfd_error_bad_value);
1722 return FALSE;
1723 }
1724
1725 /* In some cases we are not setting the 'non_got_ref'
1726 flag, even though the relocations don't require a GOT
1727 access. We should extend the testing in this area to
1728 ensure that no significant cases are being missed. */
1729 if (h)
1730 h->non_got_ref = 1;
1731 /* FALLTHROUGH */
1732 case R_ARC_PC32:
1733 case R_ARC_32_PCREL:
1734 if (bfd_link_pic (info) && !bfd_link_pie (info)
1735 && ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1736 || (h != NULL
1737 && h->dynindx != -1
1738 && (!info->symbolic || !h->def_regular))))
1739 {
1740 if (sreloc == NULL)
1741 {
1742 sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
1743 2, abfd,
1744 /*rela*/
1745 TRUE);
1746
1747 if (sreloc == NULL)
1748 return FALSE;
1749 }
1750 sreloc->size += sizeof (Elf32_External_Rela);
1751
1752 }
1753 default:
1754 break;
1755 }
1756
1757 if (is_reloc_for_PLT (howto) == TRUE)
1758 {
1759 if (h == NULL)
1760 continue;
1761 else
1762 h->needs_plt = 1;
1763 }
1764
1765 if (is_reloc_for_GOT (howto) == TRUE)
1766 {
1767 if (h == NULL)
1768 {
1769 /* Local symbol. */
1770 if (local_got_ents[r_symndx] == NULL)
1771 {
1772 bfd_vma offset =
1773 ADD_SYMBOL_REF_SEC_AND_RELOC (got,
1774 bfd_link_pic (info),
1775 NULL);
1776 new_got_entry_to_list (&(local_got_ents[r_symndx]),
1777 GOT_NORMAL, offset, NONE);
1778 }
1779 }
1780 else
1781 {
1782 /* Global symbol. */
1783 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1784 if (h->got.glist == NULL)
1785 {
1786 bfd_vma offset =
1787 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1788 new_got_entry_to_list (&h->got.glist,
1789 GOT_NORMAL, offset, NONE);
1790 }
1791 }
1792 }
1793
1794 if (is_reloc_for_TLS (howto) == TRUE)
1795 {
1796 enum tls_type_e type = GOT_UNKNOWN;
1797
1798 switch (r_type)
1799 {
1800 case R_ARC_TLS_GD_GOT:
1801 type = GOT_TLS_GD;
1802 break;
1803 case R_ARC_TLS_IE_GOT:
1804 type = GOT_TLS_IE;
1805 break;
1806 default:
1807 break;
1808 }
1809
1810 struct got_entry **list = NULL;
1811 if (h != NULL)
1812 list = &(h->got.glist);
1813 else
1814 list = &(local_got_ents[r_symndx]);
1815
1816 if (type != GOT_UNKNOWN && !symbol_has_entry_of_type (*list, type))
1817 {
1818 enum tls_got_entries entries = NONE;
1819 bfd_vma offset =
1820 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1821
1822 if (type == GOT_TLS_GD)
1823 {
1824 bfd_vma ATTRIBUTE_UNUSED notneeded =
1825 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1826 entries = MOD_AND_OFF;
1827 }
1828
1829 if (entries == NONE)
1830 entries = OFF;
1831
1832 new_got_entry_to_list (list, type, offset, entries);
1833 }
1834 }
1835 }
1836
1837 return TRUE;
1838 }
1839
1840 #define ELF_DYNAMIC_INTERPRETER "/sbin/ld-uClibc.so"
1841
1842 static struct plt_version_t *
1843 arc_get_plt_version (struct bfd_link_info *info)
1844 {
1845 int i;
1846
1847 for (i = 0; i < 1; i++)
1848 {
1849 ARC_DEBUG ("%d: size1 = %d, size2 = %d\n", i,
1850 plt_versions[i].entry_size,
1851 plt_versions[i].elem_size);
1852 }
1853
1854 if (bfd_get_mach (info->output_bfd) == bfd_mach_arc_arcv2)
1855 {
1856 if (bfd_link_pic (info))
1857 return &(plt_versions[ELF_ARCV2_PIC]);
1858 else
1859 return &(plt_versions[ELF_ARCV2_ABS]);
1860 }
1861 else
1862 {
1863 if (bfd_link_pic (info))
1864 return &(plt_versions[ELF_ARC_PIC]);
1865 else
1866 return &(plt_versions[ELF_ARC_ABS]);
1867 }
1868 }
1869
1870 static bfd_vma
1871 add_symbol_to_plt (struct bfd_link_info *info)
1872 {
1873 struct elf_link_hash_table *htab = elf_hash_table (info);
1874 bfd_vma ret;
1875
1876 struct plt_version_t *plt_data = arc_get_plt_version (info);
1877
1878 /* If this is the first .plt entry, make room for the special first
1879 entry. */
1880 if (htab->splt->size == 0)
1881 htab->splt->size += plt_data->entry_size;
1882
1883 ret = htab->splt->size;
1884
1885 htab->splt->size += plt_data->elem_size;
1886 ARC_DEBUG ("PLT_SIZE = %d\n", htab->splt->size);
1887
1888 htab->sgotplt->size += 4;
1889 htab->srelplt->size += sizeof (Elf32_External_Rela);
1890
1891 return ret;
1892 }
1893
1894 #define PLT_DO_RELOCS_FOR_ENTRY(ABFD, DS, RELOCS) \
1895 plt_do_relocs_for_symbol (ABFD, DS, RELOCS, 0, 0)
1896
1897 static void
1898 plt_do_relocs_for_symbol (bfd *abfd,
1899 struct elf_link_hash_table *htab,
1900 const struct plt_reloc *reloc,
1901 bfd_vma plt_offset,
1902 bfd_vma symbol_got_offset)
1903 {
1904 while (SYM_ONLY (reloc->symbol) != LAST_RELOC)
1905 {
1906 bfd_vma relocation = 0;
1907
1908 switch (SYM_ONLY (reloc->symbol))
1909 {
1910 case SGOT:
1911 relocation =
1912 htab->sgotplt->output_section->vma +
1913 htab->sgotplt->output_offset + symbol_got_offset;
1914 break;
1915 }
1916 relocation += reloc->addend;
1917
1918 if (IS_RELATIVE (reloc->symbol))
1919 {
1920 bfd_vma reloc_offset = reloc->offset;
1921 reloc_offset -= (IS_INSN_32 (reloc->symbol)) ? 4 : 0;
1922 reloc_offset -= (IS_INSN_24 (reloc->symbol)) ? 2 : 0;
1923
1924 relocation -= htab->splt->output_section->vma
1925 + htab->splt->output_offset
1926 + plt_offset + reloc_offset;
1927 }
1928
1929 /* TODO: being ME is not a property of the relocation but of the
1930 section of which is applying the relocation. */
1931 if (IS_MIDDLE_ENDIAN (reloc->symbol) || bfd_big_endian (abfd))
1932 {
1933 relocation =
1934 ((relocation & 0xffff0000) >> 16) |
1935 ((relocation & 0xffff) << 16);
1936 }
1937
1938 switch (reloc->size)
1939 {
1940 case 32:
1941 bfd_put_32 (htab->splt->output_section->owner,
1942 relocation,
1943 htab->splt->contents + plt_offset + reloc->offset);
1944 break;
1945 }
1946
1947 reloc = &(reloc[1]); /* Jump to next relocation. */
1948 }
1949 }
1950
1951 static void
1952 relocate_plt_for_symbol (bfd *output_bfd,
1953 struct bfd_link_info *info,
1954 struct elf_link_hash_entry *h)
1955 {
1956 struct plt_version_t *plt_data = arc_get_plt_version (info);
1957 struct elf_link_hash_table *htab = elf_hash_table (info);
1958
1959 bfd_vma plt_index = (h->plt.offset - plt_data->entry_size)
1960 / plt_data->elem_size;
1961 bfd_vma got_offset = (plt_index + 3) * 4;
1962
1963 ARC_DEBUG ("arc_info: PLT_OFFSET = 0x%x, PLT_ENTRY_VMA = 0x%x, \
1964 GOT_ENTRY_OFFSET = 0x%x, GOT_ENTRY_VMA = 0x%x, for symbol %s\n",
1965 h->plt.offset,
1966 htab->splt->output_section->vma
1967 + htab->splt->output_offset
1968 + h->plt.offset,
1969 got_offset,
1970 htab->sgotplt->output_section->vma
1971 + htab->sgotplt->output_offset
1972 + got_offset,
1973 h->root.root.string);
1974
1975 memcpy (htab->splt->contents + h->plt.offset,
1976 plt_data->elem,
1977 plt_data->elem_size);
1978 plt_do_relocs_for_symbol (output_bfd, htab,
1979 plt_data->elem_relocs,
1980 h->plt.offset,
1981 got_offset);
1982
1983 /* Fill in the entry in the global offset table. */
1984 bfd_put_32 (output_bfd,
1985 (bfd_vma) (htab->splt->output_section->vma
1986 + htab->splt->output_offset),
1987 htab->sgotplt->contents + got_offset);
1988
1989 /* TODO: Fill in the entry in the .rela.plt section. */
1990 {
1991 Elf_Internal_Rela rel;
1992 bfd_byte *loc;
1993
1994 rel.r_offset = (htab->sgotplt->output_section->vma
1995 + htab->sgotplt->output_offset
1996 + got_offset);
1997 rel.r_addend = 0;
1998 rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_JMP_SLOT);
1999
2000 loc = htab->srelplt->contents;
2001 loc += plt_index * sizeof (Elf32_External_Rela); /* relA */
2002 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2003 }
2004 }
2005
2006 static void
2007 relocate_plt_for_entry (bfd *abfd,
2008 struct bfd_link_info *info)
2009 {
2010 struct plt_version_t *plt_data = arc_get_plt_version (info);
2011 struct elf_link_hash_table *htab = elf_hash_table (info);
2012
2013 memcpy (htab->splt->contents, plt_data->entry,
2014 plt_data->entry_size);
2015 PLT_DO_RELOCS_FOR_ENTRY (abfd, htab, plt_data->entry_relocs);
2016 }
2017
2018 /* Desc : Adjust a symbol defined by a dynamic object and referenced
2019 by a regular object. The current definition is in some section of
2020 the dynamic object, but we're not including those sections. We
2021 have to change the definition to something the rest of the link can
2022 understand. */
2023
2024 static bfd_boolean
2025 elf_arc_adjust_dynamic_symbol (struct bfd_link_info *info,
2026 struct elf_link_hash_entry *h)
2027 {
2028 asection *s;
2029 unsigned int power_of_two;
2030 bfd *dynobj = (elf_hash_table (info))->dynobj;
2031 struct elf_link_hash_table *htab = elf_hash_table (info);
2032
2033 if (h->type == STT_FUNC
2034 || h->type == STT_GNU_IFUNC
2035 || h->needs_plt == 1)
2036 {
2037 if (!bfd_link_pic (info) && !h->def_dynamic && !h->ref_dynamic)
2038 {
2039 /* This case can occur if we saw a PLT32 reloc in an input
2040 file, but the symbol was never referred to by a dynamic
2041 object. In such a case, we don't actually need to build
2042 a procedure linkage table, and we can just do a PC32
2043 reloc instead. */
2044 BFD_ASSERT (h->needs_plt);
2045 return TRUE;
2046 }
2047
2048 /* Make sure this symbol is output as a dynamic symbol. */
2049 if (h->dynindx == -1 && !h->forced_local
2050 && !bfd_elf_link_record_dynamic_symbol (info, h))
2051 return FALSE;
2052
2053 if (bfd_link_pic (info)
2054 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
2055 {
2056 bfd_vma loc = add_symbol_to_plt (info);
2057
2058 if (!bfd_link_pic (info) && !h->def_regular)
2059 {
2060 h->root.u.def.section = htab->splt;
2061 h->root.u.def.value = loc;
2062 }
2063 h->plt.offset = loc;
2064 }
2065 else
2066 {
2067 h->plt.offset = (bfd_vma) -1;
2068 h->needs_plt = 0;
2069 }
2070 return TRUE;
2071 }
2072
2073 /* If this is a weak symbol, and there is a real definition, the
2074 processor independent code will have arranged for us to see the
2075 real definition first, and we can just use the same value. */
2076 if (h->u.weakdef != NULL)
2077 {
2078 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2079 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2080 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2081 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2082 return TRUE;
2083 }
2084
2085 /* If there are no non-GOT references, we do not need a copy
2086 relocation. */
2087 if (!h->non_got_ref)
2088 return TRUE;
2089
2090 /* This is a reference to a symbol defined by a dynamic object which
2091 is not a function. */
2092
2093 /* If we are creating a shared library, we must presume that the
2094 only references to the symbol are via the global offset table.
2095 For such cases we need not do anything here; the relocations will
2096 be handled correctly by relocate_section. */
2097 if (bfd_link_pic (info))
2098 return TRUE;
2099
2100 /* We must allocate the symbol in our .dynbss section, which will
2101 become part of the .bss section of the executable. There will be
2102 an entry for this symbol in the .dynsym section. The dynamic
2103 object will contain position independent code, so all references
2104 from the dynamic object to this symbol will go through the global
2105 offset table. The dynamic linker will use the .dynsym entry to
2106 determine the address it must put in the global offset table, so
2107 both the dynamic object and the regular object will refer to the
2108 same memory location for the variable. */
2109
2110 s = bfd_get_section_by_name (dynobj, ".dynbss");
2111 BFD_ASSERT (s != NULL);
2112
2113 /* We must generate a R_ARC_COPY reloc to tell the dynamic linker to
2114 copy the initial value out of the dynamic object and into the
2115 runtime process image. We need to remember the offset into the
2116 .rela.bss section we are going to use. */
2117 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2118 {
2119 asection *srel;
2120
2121 srel = bfd_get_section_by_name (dynobj, ".rela.bss");
2122 BFD_ASSERT (srel != NULL);
2123 srel->size += sizeof (Elf32_External_Rela);
2124 h->needs_copy = 1;
2125 }
2126
2127 /* We need to figure out the alignment required for this symbol. I
2128 have no idea how ELF linkers handle this. */
2129 power_of_two = bfd_log2 (h->size);
2130 if (power_of_two > 3)
2131 power_of_two = 3;
2132
2133 /* Apply the required alignment. */
2134 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
2135 if (power_of_two > bfd_get_section_alignment (dynobj, s))
2136 {
2137 if (! bfd_set_section_alignment (dynobj, s, power_of_two))
2138 return FALSE;
2139 }
2140
2141 /* Define the symbol as being at this point in the section. */
2142 h->root.u.def.section = s;
2143 h->root.u.def.value = s->size;
2144
2145 /* Increment the section size to make room for the symbol. */
2146 s->size += h->size;
2147
2148 return TRUE;
2149 }
2150
2151 /* Function : elf_arc_finish_dynamic_symbol
2152 Brief : Finish up dynamic symbol handling. We set the
2153 contents of various dynamic sections here.
2154 Args : output_bfd :
2155 info :
2156 h :
2157 sym :
2158 Returns : True/False as the return status. */
2159
2160 static bfd_boolean
2161 elf_arc_finish_dynamic_symbol (bfd * output_bfd,
2162 struct bfd_link_info *info,
2163 struct elf_link_hash_entry *h,
2164 Elf_Internal_Sym * sym)
2165 {
2166 if (h->plt.offset != (bfd_vma) -1)
2167 {
2168 relocate_plt_for_symbol (output_bfd, info, h);
2169
2170 if (!h->def_regular)
2171 {
2172 /* Mark the symbol as undefined, rather than as defined in
2173 the .plt section. Leave the value alone. */
2174 sym->st_shndx = SHN_UNDEF;
2175 }
2176 }
2177
2178 if (h->got.glist != NULL)
2179 {
2180 struct got_entry *list = h->got.glist;
2181
2182 /* Traverse the list of got entries for this symbol. */
2183 while (list)
2184 {
2185 bfd_vma got_offset = h->got.glist->offset;
2186
2187 if (list->type == GOT_NORMAL
2188 && list->created_dyn_relocation == FALSE)
2189 {
2190 if (bfd_link_pic (info)
2191 && (info->symbolic || h->dynindx == -1)
2192 && h->def_regular)
2193 {
2194 ADD_RELA (output_bfd, got, got_offset, 0, R_ARC_RELATIVE, 0);
2195 }
2196 else
2197 {
2198 ADD_RELA (output_bfd, got, got_offset, h->dynindx,
2199 R_ARC_GLOB_DAT, 0);
2200 }
2201 list->created_dyn_relocation = TRUE;
2202 }
2203 else if (list->existing_entries != NONE)
2204 {
2205 struct elf_link_hash_table *htab = elf_hash_table (info);
2206 enum tls_got_entries e = list->existing_entries;
2207
2208 BFD_ASSERT (list->type != GOT_TLS_GD
2209 || list->existing_entries == MOD_AND_OFF);
2210
2211 bfd_vma dynindx = h->dynindx == -1 ? 0 : h->dynindx;
2212 if (e == MOD_AND_OFF || e == MOD)
2213 {
2214 ADD_RELA (output_bfd, got, got_offset, dynindx,
2215 R_ARC_TLS_DTPMOD, 0);
2216 ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2217 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2218 list->type,
2219 got_offset,
2220 htab->sgot->output_section->vma
2221 + htab->sgot->output_offset + got_offset,
2222 dynindx, 0);
2223 }
2224 if (e == MOD_AND_OFF || e == OFF)
2225 {
2226 bfd_vma addend = 0;
2227 if (list->type == GOT_TLS_IE)
2228 addend = bfd_get_32 (output_bfd,
2229 htab->sgot->contents + got_offset);
2230
2231 ADD_RELA (output_bfd, got,
2232 got_offset + (e == MOD_AND_OFF ? 4 : 0),
2233 dynindx,
2234 (list->type == GOT_TLS_IE ?
2235 R_ARC_TLS_TPOFF : R_ARC_TLS_DTPOFF),
2236 addend);
2237
2238 ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2239 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2240 list->type,
2241 got_offset,
2242 htab->sgot->output_section->vma
2243 + htab->sgot->output_offset + got_offset,
2244 dynindx, addend);
2245 }
2246 }
2247
2248 list = list->next;
2249 }
2250
2251 h->got.glist = NULL;
2252 }
2253
2254 if (h->needs_copy)
2255 {
2256 bfd_vma rel_offset = (h->root.u.def.value
2257 + h->root.u.def.section->output_section->vma
2258 + h->root.u.def.section->output_offset);
2259
2260 asection *srelbss =
2261 bfd_get_section_by_name (h->root.u.def.section->owner,
2262 ".rela.bss");
2263
2264 bfd_byte * loc = srelbss->contents
2265 + (srelbss->reloc_count * sizeof (Elf32_External_Rela));
2266 srelbss->reloc_count++;
2267
2268 Elf_Internal_Rela rel;
2269 rel.r_addend = 0;
2270 rel.r_offset = rel_offset;
2271 rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_COPY);
2272
2273 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2274 }
2275
2276 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
2277 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2278 || strcmp (h->root.root.string, "__DYNAMIC") == 0
2279 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
2280 sym->st_shndx = SHN_ABS;
2281
2282 return TRUE;
2283 }
2284
2285 #define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION, ASSERT) \
2286 case TAG: \
2287 if (SYMBOL != NULL) \
2288 { \
2289 h = elf_link_hash_lookup (elf_hash_table (info), \
2290 SYMBOL, FALSE, FALSE, TRUE); \
2291 } \
2292 else if (SECTION != NULL) \
2293 { \
2294 s = bfd_get_section_by_name (output_bfd, SECTION); \
2295 BFD_ASSERT (s != NULL || !ASSERT); \
2296 do_it = TRUE; \
2297 } \
2298 break;
2299
2300 /* Function : elf_arc_finish_dynamic_sections
2301 Brief : Finish up the dynamic sections handling.
2302 Args : output_bfd :
2303 info :
2304 h :
2305 sym :
2306 Returns : True/False as the return status. */
2307
2308 static bfd_boolean
2309 elf_arc_finish_dynamic_sections (bfd * output_bfd,
2310 struct bfd_link_info *info)
2311 {
2312 struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
2313 struct elf_link_hash_table *htab = elf_hash_table (info);
2314 bfd *dynobj = (elf_hash_table (info))->dynobj;
2315
2316 if (ds.sdyn)
2317 {
2318 Elf32_External_Dyn *dyncon, *dynconend;
2319
2320 dyncon = (Elf32_External_Dyn *) ds.sdyn->contents;
2321 dynconend =
2322 (Elf32_External_Dyn *) (ds.sdyn->contents + ds.sdyn->size);
2323 for (; dyncon < dynconend; dyncon++)
2324 {
2325 Elf_Internal_Dyn internal_dyn;
2326 bfd_boolean do_it = FALSE;
2327
2328 struct elf_link_hash_entry *h = NULL;
2329 asection *s = NULL;
2330
2331 bfd_elf32_swap_dyn_in (dynobj, dyncon, &internal_dyn);
2332
2333 switch (internal_dyn.d_tag)
2334 {
2335 GET_SYMBOL_OR_SECTION (DT_INIT, "_init", NULL, TRUE)
2336 GET_SYMBOL_OR_SECTION (DT_FINI, "_fini", NULL, TRUE)
2337 GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt", TRUE)
2338 GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt", TRUE)
2339 GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt", TRUE)
2340 GET_SYMBOL_OR_SECTION (DT_RELASZ, NULL, ".rela.plt", FALSE)
2341 GET_SYMBOL_OR_SECTION (DT_VERSYM, NULL, ".gnu.version", TRUE)
2342 GET_SYMBOL_OR_SECTION (DT_VERDEF, NULL, ".gnu.version_d", TRUE)
2343 GET_SYMBOL_OR_SECTION (DT_VERNEED, NULL, ".gnu.version_r", TRUE)
2344 default:
2345 break;
2346 }
2347
2348 /* In case the dynamic symbols should be updated with a symbol. */
2349 if (h != NULL
2350 && (h->root.type == bfd_link_hash_defined
2351 || h->root.type == bfd_link_hash_defweak))
2352 {
2353 asection *asec_ptr;
2354
2355 internal_dyn.d_un.d_val = h->root.u.def.value;
2356 asec_ptr = h->root.u.def.section;
2357 if (asec_ptr->output_section != NULL)
2358 {
2359 internal_dyn.d_un.d_val +=
2360 (asec_ptr->output_section->vma +
2361 asec_ptr->output_offset);
2362 }
2363 else
2364 {
2365 /* The symbol is imported from another shared
2366 library and does not apply to this one. */
2367 internal_dyn.d_un.d_val = 0;
2368 }
2369 do_it = TRUE;
2370 }
2371 else if (s != NULL) /* With a section information. */
2372 {
2373 switch (internal_dyn.d_tag)
2374 {
2375 case DT_PLTGOT:
2376 case DT_JMPREL:
2377 case DT_VERSYM:
2378 case DT_VERDEF:
2379 case DT_VERNEED:
2380 internal_dyn.d_un.d_ptr = s->vma;
2381 do_it = TRUE;
2382 break;
2383
2384 case DT_PLTRELSZ:
2385 internal_dyn.d_un.d_val = s->size;
2386 do_it = TRUE;
2387 break;
2388
2389 case DT_RELASZ:
2390 if (s != NULL)
2391 internal_dyn.d_un.d_val -= s->size;
2392 do_it = TRUE;
2393 break;
2394
2395 default:
2396 break;
2397 }
2398 }
2399
2400 if (do_it == TRUE)
2401 bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon);
2402 }
2403
2404 if (htab->splt->size > 0)
2405 {
2406 relocate_plt_for_entry (output_bfd, info);
2407 }
2408
2409 /* TODO: Validate this. */
2410 elf_section_data (htab->srelplt->output_section)->this_hdr.sh_entsize
2411 = 0xc;
2412 }
2413
2414 /* Fill in the first three entries in the global offset table. */
2415 if (htab->sgot)
2416 {
2417 if (htab->sgot->size > 0 || htab->sgotplt->size > 0)
2418 {
2419 if (ds.sdyn == NULL)
2420 bfd_put_32 (output_bfd, (bfd_vma) 0,
2421 htab->sgotplt->contents);
2422 else
2423 bfd_put_32 (output_bfd,
2424 ds.sdyn->output_section->vma + ds.sdyn->output_offset,
2425 htab->sgotplt->contents);
2426 bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 4);
2427 bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 8);
2428 }
2429 }
2430
2431 return TRUE;
2432 }
2433
2434 #define ADD_DYNAMIC_SYMBOL(NAME, TAG) \
2435 h = elf_link_hash_lookup (elf_hash_table (info), \
2436 NAME, FALSE, FALSE, FALSE); \
2437 if ((h != NULL && (h->ref_regular || h->def_regular))) \
2438 if (! _bfd_elf_add_dynamic_entry (info, TAG, 0)) \
2439 return FALSE;
2440
2441 /* Set the sizes of the dynamic sections. */
2442 static bfd_boolean
2443 elf_arc_size_dynamic_sections (bfd * output_bfd,
2444 struct bfd_link_info *info)
2445 {
2446 bfd * dynobj;
2447 asection * s;
2448 bfd_boolean relocs_exist = FALSE;
2449 bfd_boolean reltext_exist = FALSE;
2450 struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
2451 struct elf_link_hash_table *htab = elf_hash_table (info);
2452
2453 dynobj = (elf_hash_table (info))->dynobj;
2454 BFD_ASSERT (dynobj != NULL);
2455
2456 if ((elf_hash_table (info))->dynamic_sections_created)
2457 {
2458 struct elf_link_hash_entry *h;
2459
2460 /* Set the contents of the .interp section to the
2461 interpreter. */
2462 if (!bfd_link_pic (info))
2463 {
2464 s = bfd_get_section_by_name (dynobj, ".interp");
2465 BFD_ASSERT (s != NULL);
2466 s->size = sizeof (ELF_DYNAMIC_INTERPRETER);
2467 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2468 }
2469
2470 /* Add some entries to the .dynamic section. We fill in some of
2471 the values later, in elf_bfd_final_link, but we must add the
2472 entries now so that we know the final size of the .dynamic
2473 section. Checking if the .init section is present. We also
2474 create DT_INIT and DT_FINI entries if the init_str has been
2475 changed by the user. */
2476 ADD_DYNAMIC_SYMBOL ("init", DT_INIT);
2477 ADD_DYNAMIC_SYMBOL ("fini", DT_FINI);
2478 }
2479 else
2480 {
2481 /* We may have created entries in the .rela.got section.
2482 However, if we are not creating the dynamic sections, we will
2483 not actually use these entries. Reset the size of .rela.got,
2484 which will cause it to get stripped from the output file
2485 below. */
2486 if (htab->srelgot != NULL)
2487 htab->srelgot->size = 0;
2488 }
2489
2490 if (htab->splt != NULL && htab->splt->size == 0)
2491 htab->splt->flags |= SEC_EXCLUDE;
2492 for (s = dynobj->sections; s != NULL; s = s->next)
2493 {
2494 if ((s->flags & SEC_LINKER_CREATED) == 0)
2495 continue;
2496
2497 if (strncmp (s->name, ".rela", 5) == 0)
2498 {
2499 if (s->size == 0)
2500 {
2501 s->flags |= SEC_EXCLUDE;
2502 }
2503 else
2504 {
2505 if (strcmp (s->name, ".rela.plt") != 0)
2506 {
2507 const char *outname =
2508 bfd_get_section_name (output_bfd,
2509 htab->srelplt->output_section);
2510
2511 asection *target = bfd_get_section_by_name (output_bfd,
2512 outname + 4);
2513
2514 relocs_exist = TRUE;
2515 if (target != NULL && target->size != 0
2516 && (target->flags & SEC_READONLY) != 0
2517 && (target->flags & SEC_ALLOC) != 0)
2518 reltext_exist = TRUE;
2519 }
2520 }
2521
2522 /* We use the reloc_count field as a counter if we need to
2523 copy relocs into the output file. */
2524 s->reloc_count = 0;
2525 }
2526
2527 if (strcmp (s->name, ".dynamic") == 0)
2528 continue;
2529
2530 if (s->size != 0)
2531 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2532
2533 if (s->contents == NULL && s->size != 0)
2534 return FALSE;
2535 }
2536
2537 if (ds.sdyn)
2538 {
2539 /* TODO: Check if this is needed. */
2540 if (!bfd_link_pic (info))
2541 if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
2542 return FALSE;
2543
2544 if (htab->splt && (htab->splt->flags & SEC_EXCLUDE) == 0)
2545 if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
2546 || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2547 || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2548 || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0)
2549 )
2550 return FALSE;
2551
2552 if (relocs_exist == TRUE)
2553 if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
2554 || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
2555 || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
2556 sizeof (Elf32_External_Rela))
2557 )
2558 return FALSE;
2559
2560 if (reltext_exist == TRUE)
2561 if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
2562 return FALSE;
2563 }
2564
2565 return TRUE;
2566 }
2567
2568 const struct elf_size_info arc_elf32_size_info =
2569 {
2570 sizeof (Elf32_External_Ehdr),
2571 sizeof (Elf32_External_Phdr),
2572 sizeof (Elf32_External_Shdr),
2573 sizeof (Elf32_External_Rel),
2574 sizeof (Elf32_External_Rela),
2575 sizeof (Elf32_External_Sym),
2576 sizeof (Elf32_External_Dyn),
2577 sizeof (Elf_External_Note),
2578 4,
2579 1,
2580 32, 2,
2581 ELFCLASS32, EV_CURRENT,
2582 bfd_elf32_write_out_phdrs,
2583 bfd_elf32_write_shdrs_and_ehdr,
2584 bfd_elf32_checksum_contents,
2585 bfd_elf32_write_relocs,
2586 bfd_elf32_swap_symbol_in,
2587 bfd_elf32_swap_symbol_out,
2588 bfd_elf32_slurp_reloc_table,
2589 bfd_elf32_slurp_symbol_table,
2590 bfd_elf32_swap_dyn_in,
2591 bfd_elf32_swap_dyn_out,
2592 bfd_elf32_swap_reloc_in,
2593 bfd_elf32_swap_reloc_out,
2594 bfd_elf32_swap_reloca_in,
2595 bfd_elf32_swap_reloca_out
2596 };
2597
2598 #define elf_backend_size_info arc_elf32_size_info
2599
2600 static struct bfd_link_hash_table *
2601 arc_elf_link_hash_table_create (bfd *abfd)
2602 {
2603 struct elf_link_hash_table *htab;
2604
2605 htab = bfd_zmalloc (sizeof (*htab));
2606 if (htab == NULL)
2607 return NULL;
2608
2609 if (!_bfd_elf_link_hash_table_init (htab, abfd,
2610 _bfd_elf_link_hash_newfunc,
2611 sizeof (struct elf_link_hash_entry),
2612 GENERIC_ELF_DATA))
2613 {
2614 free (htab);
2615 return NULL;
2616 }
2617
2618 htab->init_got_refcount.refcount = 0;
2619 htab->init_got_refcount.glist = NULL;
2620 htab->init_got_offset.offset = 0;
2621 htab->init_got_offset.glist = NULL;
2622 return (struct bfd_link_hash_table *) htab;
2623 }
2624
2625 /* Hook called by the linker routine which adds symbols from an object
2626 file. */
2627
2628 static bfd_boolean
2629 elf_arc_add_symbol_hook (bfd * abfd,
2630 struct bfd_link_info * info,
2631 Elf_Internal_Sym * sym,
2632 const char ** namep ATTRIBUTE_UNUSED,
2633 flagword * flagsp ATTRIBUTE_UNUSED,
2634 asection ** secp ATTRIBUTE_UNUSED,
2635 bfd_vma * valp ATTRIBUTE_UNUSED)
2636 {
2637 if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
2638 || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
2639 && (abfd->flags & DYNAMIC) == 0
2640 && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
2641 elf_tdata (info->output_bfd)->has_gnu_symbols = elf_gnu_symbol_any;
2642
2643 return TRUE;
2644 }
2645
2646 #define TARGET_LITTLE_SYM arc_elf32_le_vec
2647 #define TARGET_LITTLE_NAME "elf32-littlearc"
2648 #define TARGET_BIG_SYM arc_elf32_be_vec
2649 #define TARGET_BIG_NAME "elf32-bigarc"
2650 #define ELF_ARCH bfd_arch_arc
2651 #define ELF_MACHINE_CODE EM_ARC_COMPACT
2652 #define ELF_MACHINE_ALT1 EM_ARC_COMPACT2
2653 #define ELF_MAXPAGESIZE 0x2000
2654
2655 #define bfd_elf32_bfd_link_hash_table_create arc_elf_link_hash_table_create
2656
2657 #define bfd_elf32_bfd_merge_private_bfd_data arc_elf_merge_private_bfd_data
2658 #define bfd_elf32_bfd_reloc_type_lookup arc_elf32_bfd_reloc_type_lookup
2659 #define bfd_elf32_bfd_set_private_flags arc_elf_set_private_flags
2660 #define bfd_elf32_bfd_print_private_bfd_data arc_elf_print_private_bfd_data
2661 #define bfd_elf32_bfd_copy_private_bfd_data arc_elf_copy_private_bfd_data
2662
2663 #define elf_info_to_howto_rel arc_info_to_howto_rel
2664 #define elf_backend_object_p arc_elf_object_p
2665 #define elf_backend_final_write_processing arc_elf_final_write_processing
2666
2667 #define elf_backend_relocate_section elf_arc_relocate_section
2668 #define elf_backend_check_relocs elf_arc_check_relocs
2669 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
2670
2671 #define elf_backend_adjust_dynamic_symbol elf_arc_adjust_dynamic_symbol
2672 #define elf_backend_finish_dynamic_symbol elf_arc_finish_dynamic_symbol
2673
2674 #define elf_backend_finish_dynamic_sections elf_arc_finish_dynamic_sections
2675 #define elf_backend_size_dynamic_sections elf_arc_size_dynamic_sections
2676 #define elf_backend_add_symbol_hook elf_arc_add_symbol_hook
2677
2678 #define elf_backend_can_gc_sections 1
2679 #define elf_backend_want_got_plt 1
2680 #define elf_backend_plt_readonly 1
2681 #define elf_backend_rela_plts_and_copies_p 1
2682 #define elf_backend_want_plt_sym 0
2683 #define elf_backend_got_header_size 12
2684
2685 #define elf_backend_may_use_rel_p 0
2686 #define elf_backend_may_use_rela_p 1
2687 #define elf_backend_default_use_rela_p 1
2688
2689 #include "elf32-target.h"
This page took 0.088006 seconds and 4 git commands to generate.