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