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