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