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