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).
5 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
27 #include "libiberty.h"
28 #include "opcode/arc-func.h"
32 # define PR_DEBUG(fmt, args...) fprintf (stderr, fmt, ##args)
34 # define PR_DEBUG(fmt, args...)
37 /* #define ARC_ENABLE_DEBUG 1 */
38 #ifndef ARC_ENABLE_DEBUG
39 #define ARC_DEBUG(...)
42 name_for_global_symbol (struct elf_link_hash_entry *h)
44 static char *local_str = "(local)";
48 return h->root.root.string;
50 #define ARC_DEBUG(args...) fprintf (stderr, ##args)
54 #define ADD_RELA(BFD, SECTION, OFFSET, SYM_IDX, TYPE, ADDEND) \
56 struct elf_link_hash_table *_htab = elf_hash_table (info); \
57 Elf_Internal_Rela _rel; \
60 _loc = _htab->srel##SECTION->contents \
61 + ((_htab->srel##SECTION->reloc_count) \
62 * sizeof (Elf32_External_Rela)); \
63 _htab->srel##SECTION->reloc_count++; \
64 _rel.r_addend = ADDEND; \
65 _rel.r_offset = (_htab->s##SECTION)->output_section->vma \
66 + (_htab->s##SECTION)->output_offset + OFFSET; \
67 BFD_ASSERT ((long) SYM_IDX != -1); \
68 _rel.r_info = ELF32_R_INFO (SYM_IDX, TYPE); \
69 bfd_elf32_swap_reloca_out (BFD, &_rel, _loc); \
74 bfd_vma sdata_begin_symbol_vma;
75 asection * sdata_output_section;
76 bfd_vma got_symbol_vma;
79 struct arc_local_data global_arc_data =
81 .sdata_begin_symbol_vma = 0,
82 .sdata_output_section = NULL,
86 struct dynamic_sections
88 bfd_boolean initialized;
92 asection * srelgotplt;
98 enum dyn_section_types
106 DYN_SECTION_TYPES_END
109 const char * dyn_section_names[DYN_SECTION_TYPES_END] =
138 struct got_entry *next;
139 enum tls_type_e type;
141 bfd_boolean processed;
142 bfd_boolean created_dyn_relocation;
143 enum tls_got_entries existing_entries;
147 new_got_entry_to_list (struct got_entry **list,
148 enum tls_type_e type,
150 enum tls_got_entries existing_entries)
152 /* Find list end. Avoid having multiple entries of the same
154 struct got_entry **p = list;
157 if ((*p)->type == type)
162 struct got_entry *entry =
163 (struct got_entry *) malloc (sizeof(struct got_entry));
166 entry->offset = offset;
168 entry->processed = FALSE;
169 entry->created_dyn_relocation = FALSE;
170 entry->existing_entries = existing_entries;
172 /* Add the entry to the end of the list. */
177 symbol_has_entry_of_type (struct got_entry *list, enum tls_type_e type)
181 if (list->type == type)
189 /* The default symbols representing the init and fini dyn values.
190 TODO: Check what is the relation of those strings with arclinux.em
192 #define INIT_SYM_STRING "_init"
193 #define FINI_SYM_STRING "_fini"
195 char * init_str = INIT_SYM_STRING;
196 char * fini_str = FINI_SYM_STRING;
198 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
203 static ATTRIBUTE_UNUSED const char *
204 reloc_type_to_name (unsigned int type)
208 #include "elf/arc-reloc.def"
215 #undef ARC_RELOC_HOWTO
217 /* Try to minimize the amount of space occupied by relocation tables
218 on the ROM (not that the ROM won't be swamped by other ELF overhead). */
222 static ATTRIBUTE_UNUSED bfd_boolean
223 is_reloc_PC_relative (reloc_howto_type *howto)
225 return (strstr (howto->name, "PC") != NULL) ? TRUE : FALSE;
229 is_reloc_SDA_relative (reloc_howto_type *howto)
231 return (strstr (howto->name, "SDA") != NULL) ? TRUE : FALSE;
235 is_reloc_for_GOT (reloc_howto_type * howto)
237 if (strstr (howto->name, "TLS") != NULL)
239 return (strstr (howto->name, "GOT") != NULL) ? TRUE : FALSE;
243 is_reloc_for_PLT (reloc_howto_type * howto)
245 return (strstr (howto->name, "PLT") != NULL) ? TRUE : FALSE;
249 is_reloc_for_TLS (reloc_howto_type *howto)
251 return (strstr (howto->name, "TLS") != NULL) ? TRUE : FALSE;
254 #define arc_bfd_get_8(A,B,C) bfd_get_8(A,B)
255 #define arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
256 #define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
257 #define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C)
258 #define arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
259 #define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)
262 static bfd_reloc_status_type
263 arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
264 arelent *reloc_entry,
266 void *data ATTRIBUTE_UNUSED,
267 asection *input_section,
269 char ** error_message ATTRIBUTE_UNUSED)
271 if (output_bfd != NULL)
273 reloc_entry->address += input_section->output_offset;
275 /* In case of relocateable link and if the reloc is against a
276 section symbol, the addend needs to be adjusted according to
277 where the section symbol winds up in the output section. */
278 if ((symbol_in->flags & BSF_SECTION_SYM) && symbol_in->section)
279 reloc_entry->addend += symbol_in->section->output_offset;
284 return bfd_reloc_continue;
288 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
292 #include "elf/arc-reloc.def"
295 #undef ARC_RELOC_HOWTO
297 #define ARC_RELOC_HOWTO(TYPE, VALUE, RSIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
298 [TYPE] = HOWTO (R_##TYPE, 0, RSIZE, BITSIZE, FALSE, 0, complain_overflow_##OVERFLOW, arc_elf_reloc, "R_" #TYPE, FALSE, 0, 0, FALSE),
300 static struct reloc_howto_struct elf_arc_howto_table[] =
302 #include "elf/arc-reloc.def"
303 /* Example of what is generated by the preprocessor. Currently kept as an
305 HOWTO (R_ARC_NONE, // Type.
307 2, // Size (0 = byte, 1 = short, 2 = long).
309 FALSE, // PC_relative.
311 complain_overflow_bitfield, // Complain_on_overflow.
312 bfd_elf_generic_reloc, // Special_function.
313 "R_ARC_NONE", // Name.
314 TRUE, // Partial_inplace.
317 FALSE), // PCrel_offset.
320 #undef ARC_RELOC_HOWTO
322 static void arc_elf_howto_init (void)
324 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
325 elf_arc_howto_table[TYPE].pc_relative = \
326 (strstr (#FORMULA, " P ") != NULL || strstr (#FORMULA, " PDATA ") != NULL); \
327 elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0); \
328 /* Only 32 bit data relocations should be marked as ME. */ \
329 if (strstr (#FORMULA, " ME ") != NULL) \
331 BFD_ASSERT (SIZE == 2); \
334 #include "elf/arc-reloc.def"
337 #undef ARC_RELOC_HOWTO
340 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
342 const int howto_table_lookup[] =
344 #include "elf/arc-reloc.def"
346 #undef ARC_RELOC_HOWTO
348 static reloc_howto_type *
349 arc_elf_howto (unsigned int r_type)
351 if (elf_arc_howto_table[R_ARC_32].dst_mask == 0)
352 arc_elf_howto_init ();
353 return &elf_arc_howto_table[r_type];
356 /* Map BFD reloc types to ARC ELF reloc types. */
360 bfd_reloc_code_real_type bfd_reloc_val;
361 unsigned char elf_reloc_val;
364 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
365 { BFD_RELOC_##TYPE, R_##TYPE },
366 static const struct arc_reloc_map arc_reloc_map[] =
368 #include "elf/arc-reloc.def"
370 {BFD_RELOC_NONE, R_ARC_NONE},
371 {BFD_RELOC_8, R_ARC_8},
372 {BFD_RELOC_16, R_ARC_16},
373 {BFD_RELOC_24, R_ARC_24},
374 {BFD_RELOC_32, R_ARC_32},
376 #undef ARC_RELOC_HOWTO
378 typedef ATTRIBUTE_UNUSED bfd_vma (*replace_func) (unsigned, int ATTRIBUTE_UNUSED);
380 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
382 func = (void *) RELOC_FUNCTION; \
385 get_replace_function (bfd *abfd, unsigned int r_type)
391 #include "elf/arc-reloc.def"
394 if (func == replace_bits24 && bfd_big_endian (abfd))
395 return (replace_func) replace_bits24_be;
397 return (replace_func) func;
399 #undef ARC_RELOC_HOWTO
401 static reloc_howto_type *
402 arc_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
403 bfd_reloc_code_real_type code)
407 for (i = ARRAY_SIZE (arc_reloc_map); i--;)
409 if (arc_reloc_map[i].bfd_reloc_val == code)
410 return arc_elf_howto (arc_reloc_map[i].elf_reloc_val);
416 /* Function to set the ELF flag bits. */
418 arc_elf_set_private_flags (bfd *abfd, flagword flags)
420 elf_elfheader (abfd)->e_flags = flags;
421 elf_flags_init (abfd) = TRUE;
425 /* Print private flags. */
427 arc_elf_print_private_bfd_data (bfd *abfd, void * ptr)
429 FILE *file = (FILE *) ptr;
432 BFD_ASSERT (abfd != NULL && ptr != NULL);
434 /* Print normal ELF private data. */
435 _bfd_elf_print_private_bfd_data (abfd, ptr);
437 flags = elf_elfheader (abfd)->e_flags;
438 fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
440 switch (flags & EF_ARC_MACH_MSK)
442 case EF_ARC_CPU_ARCV2HS : fprintf (file, " -mcpu=ARCv2HS"); break;
443 case EF_ARC_CPU_ARCV2EM : fprintf (file, " -mcpu=ARCv2EM"); break;
444 case E_ARC_MACH_ARC600 : fprintf (file, " -mcpu=ARC600"); break;
445 case E_ARC_MACH_ARC601 : fprintf (file, " -mcpu=ARC601"); break;
446 case E_ARC_MACH_ARC700 : fprintf (file, " -mcpu=ARC700"); break;
448 fprintf (file, "-mcpu=unknown");
452 switch (flags & EF_ARC_OSABI_MSK)
454 case E_ARC_OSABI_ORIG : fprintf (file, " (ABI:legacy)"); break;
455 case E_ARC_OSABI_V2 : fprintf (file, " (ABI:v2)"); break;
456 case E_ARC_OSABI_V3 : fprintf (file, " (ABI:v3)"); break;
458 fprintf (file, "(ABI:unknown)");
466 /* Copy backend specific data from one object module to another. */
469 arc_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
471 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
472 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
475 BFD_ASSERT (!elf_flags_init (obfd)
476 || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
478 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
479 elf_flags_init (obfd) = TRUE;
481 /* Copy object attributes. */
482 _bfd_elf_copy_obj_attributes (ibfd, obfd);
484 return _bfd_elf_copy_private_bfd_data (ibfd, obfd);
487 static reloc_howto_type *
488 bfd_elf32_bfd_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED,
493 for (i = 0; i < ARRAY_SIZE (elf_arc_howto_table); i++)
494 if (elf_arc_howto_table[i].name != NULL
495 && strcasecmp (elf_arc_howto_table[i].name, r_name) == 0)
496 return arc_elf_howto (i);
501 /* Set the howto pointer for an ARC ELF reloc. */
504 arc_info_to_howto_rel (bfd * abfd ATTRIBUTE_UNUSED,
506 Elf_Internal_Rela * dst)
510 r_type = ELF32_R_TYPE (dst->r_info);
511 BFD_ASSERT (r_type < (unsigned int) R_ARC_max);
512 cache_ptr->howto = arc_elf_howto (r_type);
515 /* Merge backend specific data from an object file to the output
516 object file when linking. */
519 arc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
521 unsigned short mach_ibfd;
522 static unsigned short mach_obfd = EM_NONE;
527 /* Check if we have the same endianess. */
528 if (! _bfd_generic_verify_endian_match (ibfd, obfd))
530 _bfd_error_handler (_("ERROR: Endian Match failed. Attempting to link "
531 "%B with binary %s of opposite endian-ness"),
532 ibfd, bfd_get_filename (obfd));
536 /* Collect ELF flags. */
537 in_flags = elf_elfheader (ibfd)->e_flags & EF_ARC_MACH_MSK;
538 out_flags = elf_elfheader (obfd)->e_flags & EF_ARC_MACH_MSK;
540 if (!elf_flags_init (obfd)) /* First call, no flags set. */
542 elf_flags_init (obfd) = TRUE;
543 out_flags = in_flags;
546 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
547 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
550 /* Check to see if the input BFD actually contains any sections. Do
551 not short-circuit dynamic objects; their section list may be
552 emptied by elf_link_add_object_symbols. */
553 if (!(ibfd->flags & DYNAMIC))
555 bfd_boolean null_input_bfd = TRUE;
556 bfd_boolean only_data_sections = TRUE;
558 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
560 if ((bfd_get_section_flags (ibfd, sec)
561 & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
562 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
563 only_data_sections = FALSE;
565 null_input_bfd = FALSE;
568 if (null_input_bfd || only_data_sections)
572 /* Complain about various flag/architecture mismatches. */
573 mach_ibfd = elf_elfheader (ibfd)->e_machine;
574 if (mach_obfd == EM_NONE)
576 mach_obfd = mach_ibfd;
580 if (mach_ibfd != mach_obfd)
582 _bfd_error_handler (_("ERROR: Attempting to link %B "
583 "with a binary %s of different architecture"),
584 ibfd, bfd_get_filename (obfd));
587 else if (in_flags != out_flags)
589 /* Warn if different flags. */
590 (*_bfd_error_handler)
591 (_("%s: uses different e_flags (0x%lx) fields than "
592 "previous modules (0x%lx)"),
593 bfd_get_filename (ibfd), (long)in_flags, (long)out_flags);
594 if (in_flags && out_flags)
596 /* MWDT doesnt set the eflags hence make sure we choose the
597 eflags set by gcc. */
598 in_flags = in_flags > out_flags ? in_flags : out_flags;
602 /* Update the flags. */
603 elf_elfheader (obfd)->e_flags = in_flags;
605 if (bfd_get_mach (obfd) < bfd_get_mach (ibfd))
607 return bfd_set_arch_mach (obfd, bfd_arch_arc, bfd_get_mach (ibfd));
613 /* Set the right machine number for an ARC ELF file. */
615 arc_elf_object_p (bfd * abfd)
617 /* Make sure this is initialised, or you'll have the potential of passing
618 garbage---or misleading values---into the call to
619 bfd_default_set_arch_mach (). */
620 int mach = bfd_mach_arc_arc700;
621 unsigned long arch = elf_elfheader (abfd)->e_flags & EF_ARC_MACH_MSK;
622 unsigned e_machine = elf_elfheader (abfd)->e_machine;
624 if (e_machine == EM_ARC_COMPACT || e_machine == EM_ARC_COMPACT2)
628 case E_ARC_MACH_ARC600:
629 mach = bfd_mach_arc_arc600;
631 case E_ARC_MACH_ARC601:
632 mach = bfd_mach_arc_arc601;
634 case E_ARC_MACH_ARC700:
635 mach = bfd_mach_arc_arc700;
637 case E_ARC_MACH_NPS400:
638 mach = bfd_mach_arc_nps400;
640 case EF_ARC_CPU_ARCV2HS:
641 case EF_ARC_CPU_ARCV2EM:
642 mach = bfd_mach_arc_arcv2;
645 mach = (e_machine == EM_ARC_COMPACT) ?
646 bfd_mach_arc_arc700 : bfd_mach_arc_arcv2;
652 if (e_machine == EM_ARC)
654 (*_bfd_error_handler)
655 (_("Error: The ARC4 architecture is no longer supported.\n"));
660 (*_bfd_error_handler)
661 (_("Warning: unset or old architecture flags. \n"
662 " Use default machine.\n"));
666 return bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach);
669 /* The final processing done just before writing out an ARC ELF object file.
670 This gets the ARC architecture right based on the machine number. */
673 arc_elf_final_write_processing (bfd * abfd,
674 bfd_boolean linker ATTRIBUTE_UNUSED)
678 switch (bfd_get_mach (abfd))
680 case bfd_mach_arc_arc600:
681 emf = EM_ARC_COMPACT;
683 case bfd_mach_arc_arc601:
684 emf = EM_ARC_COMPACT;
686 case bfd_mach_arc_arc700:
687 emf = EM_ARC_COMPACT;
689 case bfd_mach_arc_nps400:
690 emf = EM_ARC_COMPACT;
692 case bfd_mach_arc_arcv2:
693 emf = EM_ARC_COMPACT2;
699 elf_elfheader (abfd)->e_machine = emf;
701 /* Record whatever is the current syscall ABI version. */
702 elf_elfheader (abfd)->e_flags |= E_ARC_OSABI_CURRENT;
705 #define BFD_DEBUG_PIC(...)
707 struct arc_relocation_data
709 bfd_signed_vma reloc_offset;
710 bfd_signed_vma reloc_addend;
711 bfd_signed_vma got_offset_value;
713 bfd_signed_vma sym_value;
714 asection * sym_section;
716 reloc_howto_type *howto;
718 asection * input_section;
720 bfd_signed_vma sdata_begin_symbol_vma;
721 bfd_boolean sdata_begin_symbol_vma_set;
722 bfd_signed_vma got_symbol_vma;
724 bfd_boolean should_relocate;
728 debug_arc_reloc (struct arc_relocation_data reloc_data)
730 PR_DEBUG ("Reloc type=%s, should_relocate = %s\n",
731 reloc_data.howto->name,
732 reloc_data.should_relocate ? "true" : "false");
733 PR_DEBUG (" offset = 0x%x, addend = 0x%x\n",
734 (unsigned int) reloc_data.reloc_offset,
735 (unsigned int) reloc_data.reloc_addend);
736 PR_DEBUG (" Symbol:\n");
737 PR_DEBUG (" value = 0x%08x\n",
738 (unsigned int) reloc_data.sym_value);
739 if (reloc_data.sym_section != NULL)
741 PR_DEBUG ("IN IF\n");
743 " section name = %s, output_offset 0x%08x",
744 reloc_data.sym_section->name,
745 (unsigned int) reloc_data.sym_section->output_offset);
746 if (reloc_data.sym_section->output_section != NULL)
749 ", output_section->vma = 0x%08x",
750 ((unsigned int) reloc_data.sym_section->output_section->vma));
757 PR_DEBUG ( " symbol section is NULL\n");
760 PR_DEBUG ( " Input_section:\n");
761 if (reloc_data.input_section != NULL)
764 " section name = %s, output_offset 0x%08x, output_section->vma = 0x%08x\n",
765 reloc_data.input_section->name,
766 (unsigned int) reloc_data.input_section->output_offset,
767 (unsigned int) reloc_data.input_section->output_section->vma);
768 PR_DEBUG ( " changed_address = 0x%08x\n",
769 (unsigned int) (reloc_data.input_section->output_section->vma +
770 reloc_data.input_section->output_offset +
771 reloc_data.reloc_offset));
775 PR_DEBUG ( " input section is NULL\n");
780 middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
785 ((insn & 0xffff0000) >> 16) |
786 ((insn & 0xffff) << 16);
791 #define ME(reloc) (reloc)
793 #define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") != NULL) \
794 && (!bfd_big_endian (BFD)))
796 #define S ((bfd_signed_vma) (reloc_data.sym_value \
797 + (reloc_data.sym_section->output_section != NULL ? \
798 (reloc_data.sym_section->output_offset \
799 + reloc_data.sym_section->output_section->vma) : 0)))
800 #define L ((bfd_signed_vma) (reloc_data.sym_value \
801 + (reloc_data.sym_section->output_section != NULL ? \
802 (reloc_data.sym_section->output_offset \
803 + reloc_data.sym_section->output_section->vma) : 0)))
804 #define A (reloc_data.reloc_addend)
806 #define G (reloc_data.got_offset_value)
807 #define GOT (reloc_data.got_symbol_vma)
808 #define GOT_BEGIN (htab->sgot->output_section->vma)
811 /* P: relative offset to PCL The offset should be to the
812 current location aligned to 32 bits. */
813 #define P ((bfd_signed_vma) ( \
815 (reloc_data.input_section->output_section != NULL ? \
816 reloc_data.input_section->output_section->vma : 0) \
817 + reloc_data.input_section->output_offset \
818 + (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0))) \
820 #define PDATA ((bfd_signed_vma) ( \
821 (reloc_data.input_section->output_section->vma \
822 + reloc_data.input_section->output_offset \
823 + (reloc_data.reloc_offset))))
824 #define SECTSTART (bfd_signed_vma) (reloc_data.input_section->output_offset)
825 #define _SDA_BASE_ (bfd_signed_vma) (reloc_data.sdata_begin_symbol_vma)
826 #define TLS_REL (bfd_signed_vma) \
827 ((elf_hash_table (info))->tls_sec->output_section->vma)
833 #define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA, TYPE) \
835 asection *sym_section = reloc_data.sym_section; \
836 asection *input_section = reloc_data.input_section; \
837 ARC_DEBUG ("RELOC_TYPE = " TYPE "\n"); \
838 ARC_DEBUG ("FORMULA = " FORMULA "\n"); \
839 ARC_DEBUG ("S = 0x%x\n", S); \
840 ARC_DEBUG ("A = 0x%x\n", A); \
841 ARC_DEBUG ("L = 0x%x\n", L); \
842 if (sym_section->output_section != NULL) \
844 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
845 sym_section->output_section->vma + sym_section->output_offset); \
849 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
851 if (input_section->output_section != NULL) \
853 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
854 input_section->output_section->vma + input_section->output_offset); \
858 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
860 ARC_DEBUG ("PCL = 0x%x\n", P); \
861 ARC_DEBUG ("P = 0x%x\n", P); \
862 ARC_DEBUG ("G = 0x%x\n", G); \
863 ARC_DEBUG ("SDA_OFFSET = 0x%x\n", _SDA_BASE_); \
864 ARC_DEBUG ("SDA_SET = %d\n", reloc_data.sdata_begin_symbol_vma_set); \
865 ARC_DEBUG ("GOT_OFFSET = 0x%x\n", GOT); \
866 ARC_DEBUG ("relocation = 0x%08x\n", relocation); \
867 ARC_DEBUG ("before = 0x%08x\n", (unsigned int) insn); \
868 ARC_DEBUG ("data = 0x%08x (%u) (%d)\n", (unsigned int) relocation, (unsigned int) relocation, (int) relocation); \
871 #define PRINT_DEBUG_RELOC_INFO_AFTER \
873 ARC_DEBUG ("after = 0x%08x\n", (unsigned int) insn); \
876 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
879 bfd_signed_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
880 relocation = FORMULA ; \
881 PRINT_DEBUG_RELOC_INFO_BEFORE (#FORMULA, #TYPE); \
882 insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
883 insn = (* get_replace_function (abfd, TYPE)) (insn, relocation); \
884 insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
885 PRINT_DEBUG_RELOC_INFO_AFTER \
889 static bfd_reloc_status_type
890 arc_do_relocation (bfd_byte * contents,
891 struct arc_relocation_data reloc_data,
892 struct bfd_link_info *info)
894 bfd_signed_vma relocation = 0;
896 bfd_vma orig_insn ATTRIBUTE_UNUSED;
897 bfd * abfd = reloc_data.input_section->owner;
898 struct elf_link_hash_table *htab ATTRIBUTE_UNUSED = elf_hash_table (info);
900 if (reloc_data.should_relocate == FALSE)
903 switch (reloc_data.howto->size)
906 insn = arc_bfd_get_32 (abfd,
907 contents + reloc_data.reloc_offset,
908 reloc_data.input_section);
911 insn = arc_bfd_get_16 (abfd,
912 contents + reloc_data.reloc_offset,
913 reloc_data.input_section);
916 insn = arc_bfd_get_8 (abfd,
917 contents + reloc_data.reloc_offset,
918 reloc_data.input_section);
928 switch (reloc_data.howto->type)
930 #include "elf/arc-reloc.def"
937 /* Check for relocation overflow. */
938 if (reloc_data.howto->complain_on_overflow != complain_overflow_dont)
940 bfd_reloc_status_type flag;
941 flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
942 reloc_data.howto->bitsize,
943 reloc_data.howto->rightshift,
944 bfd_arch_bits_per_address (abfd),
947 #undef DEBUG_ARC_RELOC
948 #define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
949 if (flag != bfd_reloc_ok)
951 PR_DEBUG ( "Relocation overflows !!!!\n");
953 DEBUG_ARC_RELOC (reloc_data);
956 "Relocation value = signed -> %d, unsigned -> %u"
957 ", hex -> (0x%08x)\n",
959 (unsigned int) relocation,
960 (unsigned int) relocation);
964 #undef DEBUG_ARC_RELOC
965 #define DEBUG_ARC_RELOC(A)
967 switch (reloc_data.howto->size)
970 arc_bfd_put_32 (abfd, insn,
971 contents + reloc_data.reloc_offset,
972 reloc_data.input_section);
975 arc_bfd_put_16 (abfd, insn,
976 contents + reloc_data.reloc_offset,
977 reloc_data.input_section);
980 arc_bfd_put_8 (abfd, insn,
981 contents + reloc_data.reloc_offset,
982 reloc_data.input_section);
985 ARC_DEBUG ("size = %d\n", reloc_data.howto->size);
1005 #undef ARC_RELOC_HOWTO
1007 static struct got_entry **
1008 arc_get_local_got_ents (bfd * abfd)
1010 static struct got_entry **local_got_ents = NULL;
1012 if (local_got_ents == NULL)
1015 Elf_Internal_Shdr *symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1017 size = symtab_hdr->sh_info * sizeof (bfd_vma);
1018 local_got_ents = (struct got_entry **)
1019 bfd_alloc (abfd, sizeof(struct got_entry *) * size);
1020 if (local_got_ents == NULL)
1023 memset (local_got_ents, 0, sizeof(struct got_entry *) * size);
1024 elf_local_got_ents (abfd) = local_got_ents;
1027 return local_got_ents;
1030 /* Relocate an arc ELF section.
1031 Function : elf_arc_relocate_section
1032 Brief : Relocate an arc section, by handling all the relocations
1033 appearing in that section.
1034 Args : output_bfd : The bfd being written to.
1035 info : Link information.
1036 input_bfd : The input bfd.
1037 input_section : The section being relocated.
1038 contents : contents of the section being relocated.
1039 relocs : List of relocations in the section.
1040 local_syms : is a pointer to the swapped in local symbols.
1041 local_section : is an array giving the section in the input file
1042 corresponding to the st_shndx field of each
1045 elf_arc_relocate_section (bfd * output_bfd,
1046 struct bfd_link_info * info,
1048 asection * input_section,
1049 bfd_byte * contents,
1050 Elf_Internal_Rela * relocs,
1051 Elf_Internal_Sym * local_syms,
1052 asection ** local_sections)
1054 Elf_Internal_Shdr * symtab_hdr;
1055 struct elf_link_hash_entry ** sym_hashes;
1056 struct got_entry ** local_got_ents;
1057 Elf_Internal_Rela * rel;
1058 Elf_Internal_Rela * relend;
1059 struct elf_link_hash_table *htab = elf_hash_table (info);
1061 symtab_hdr = &((elf_tdata (input_bfd))->symtab_hdr);
1062 sym_hashes = elf_sym_hashes (input_bfd);
1065 relend = relocs + input_section->reloc_count;
1066 for (; rel < relend; rel++)
1068 enum elf_arc_reloc_type r_type;
1069 reloc_howto_type * howto;
1070 unsigned long r_symndx;
1071 struct elf_link_hash_entry * h;
1072 Elf_Internal_Sym * sym;
1074 struct elf_link_hash_entry *h2;
1076 struct arc_relocation_data reloc_data =
1080 .got_offset_value = 0,
1082 .sym_section = NULL,
1084 .input_section = NULL,
1085 .sdata_begin_symbol_vma = 0,
1086 .sdata_begin_symbol_vma_set = FALSE,
1087 .got_symbol_vma = 0,
1088 .should_relocate = FALSE
1091 r_type = ELF32_R_TYPE (rel->r_info);
1093 if (r_type >= (int) R_ARC_max)
1095 bfd_set_error (bfd_error_bad_value);
1098 howto = &elf_arc_howto_table[r_type];
1100 r_symndx = ELF32_R_SYM (rel->r_info);
1102 /* If we are generating another .o file and the symbol in not
1103 local, skip this relocation. */
1104 if (bfd_link_relocatable (info))
1106 /* This is a relocateable link. We don't have to change
1107 anything, unless the reloc is against a section symbol,
1108 in which case we have to adjust according to where the
1109 section symbol winds up in the output section. */
1111 /* Checks if this is a local symbol and thus the reloc
1112 might (will??) be against a section symbol. */
1113 if (r_symndx < symtab_hdr->sh_info)
1115 sym = local_syms + r_symndx;
1116 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1118 sec = local_sections[r_symndx];
1120 /* for RELA relocs.Just adjust the addend
1121 value in the relocation entry. */
1122 rel->r_addend += sec->output_offset + sym->st_value;
1125 PR_DEBUG ("local symbols reloc "
1126 "(section=%d %s) seen in %s\n",
1128 local_sections[r_symndx]->name,
1129 __PRETTY_FUNCTION__)
1137 h2 = elf_link_hash_lookup (elf_hash_table (info), "__SDATA_BEGIN__",
1138 FALSE, FALSE, TRUE);
1140 if (reloc_data.sdata_begin_symbol_vma_set == FALSE
1141 && h2 != NULL && h2->root.type != bfd_link_hash_undefined
1142 && h2->root.u.def.section->output_section != NULL)
1143 /* TODO: Verify this condition. */
1145 reloc_data.sdata_begin_symbol_vma =
1146 (h2->root.u.def.value +
1147 h2->root.u.def.section->output_section->vma);
1148 reloc_data.sdata_begin_symbol_vma_set = TRUE;
1151 reloc_data.input_section = input_section;
1152 reloc_data.howto = howto;
1153 reloc_data.reloc_offset = rel->r_offset;
1154 reloc_data.reloc_addend = rel->r_addend;
1156 /* This is a final link. */
1161 if (r_symndx < symtab_hdr->sh_info) /* A local symbol. */
1163 local_got_ents = arc_get_local_got_ents (output_bfd);
1164 struct got_entry *entry = local_got_ents[r_symndx];
1166 sym = local_syms + r_symndx;
1167 sec = local_sections[r_symndx];
1169 reloc_data.sym_value = sym->st_value;
1170 reloc_data.sym_section = sec;
1172 /* Mergeable section handling. */
1173 if ((sec->flags & SEC_MERGE)
1174 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1178 rel->r_addend = _bfd_elf_rel_local_sym (output_bfd, sym,
1179 &msec, rel->r_addend);
1180 rel->r_addend -= (sec->output_section->vma
1181 + sec->output_offset
1183 rel->r_addend += msec->output_section->vma + msec->output_offset;
1185 reloc_data.reloc_addend = rel->r_addend;
1188 if ((is_reloc_for_GOT (howto)
1189 || is_reloc_for_TLS (howto)) && entry != NULL)
1191 if (is_reloc_for_TLS (howto))
1192 while (entry->type == GOT_NORMAL && entry->next != NULL)
1193 entry = entry->next;
1195 if (is_reloc_for_GOT (howto))
1196 while (entry->type != GOT_NORMAL && entry->next != NULL)
1197 entry = entry->next;
1199 if (entry->type == GOT_TLS_GD && entry->processed == FALSE)
1201 bfd_vma sym_vma = sym->st_value
1202 + sec->output_section->vma
1203 + sec->output_offset;
1205 /* Create dynamic relocation for local sym. */
1206 ADD_RELA (output_bfd, got, entry->offset, 0,
1207 R_ARC_TLS_DTPMOD, 0);
1208 ADD_RELA (output_bfd, got, entry->offset+4, 0,
1209 R_ARC_TLS_DTPOFF, 0);
1211 bfd_vma sec_vma = sec->output_section->vma
1212 + sec->output_offset;
1213 bfd_put_32 (output_bfd, sym_vma - sec_vma,
1214 htab->sgot->contents + entry->offset + 4);
1216 ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_GD value "
1217 "= 0x%x @ 0x%x, for symbol %s\n",
1219 htab->sgot->contents + entry->offset + 4,
1222 entry->processed = TRUE;
1224 if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
1226 bfd_vma sym_vma = sym->st_value
1227 + sec->output_section->vma
1228 + sec->output_offset;
1229 bfd_vma sec_vma = htab->tls_sec->output_section->vma;
1230 bfd_put_32 (output_bfd, sym_vma - sec_vma,
1231 htab->sgot->contents + entry->offset);
1232 /* TODO: Check if this type of relocs is the cause
1233 for all the ARC_NONE dynamic relocs. */
1235 ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_IE value = "
1236 "0x%x @ 0x%x, for symbol %s\n",
1238 htab->sgot->contents + entry->offset,
1241 entry->processed = TRUE;
1243 if (entry->type == GOT_NORMAL && entry->processed == FALSE)
1245 bfd_vma sec_vma = reloc_data.sym_section->output_section->vma
1246 + reloc_data.sym_section->output_offset;
1248 bfd_put_32 (output_bfd, reloc_data.sym_value + sec_vma,
1249 htab->sgot->contents + entry->offset);
1251 ARC_DEBUG ("arc_info: PATCHED: 0x%08x @ 0x%08x for "
1252 "sym %s in got offset 0x%x\n",
1253 reloc_data.sym_value + sec_vma,
1254 htab->sgot->output_section->vma
1255 + htab->sgot->output_offset + entry->offset,
1258 entry->processed = TRUE;
1261 reloc_data.got_offset_value = entry->offset;
1262 ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
1263 "vma = 0x%x for symbol %s\n",
1264 entry->type, entry->offset,
1265 htab->sgot->output_section->vma
1266 + htab->sgot->output_offset + entry->offset,
1270 BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1271 if (htab->sgot != NULL)
1272 reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1273 + htab->sgot->output_offset;
1275 reloc_data.should_relocate = TRUE;
1277 else /* Global symbol. */
1279 /* Get the symbol's entry in the symtab. */
1280 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1282 while (h->root.type == bfd_link_hash_indirect
1283 || h->root.type == bfd_link_hash_warning)
1284 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1286 BFD_ASSERT ((h->dynindx == -1) >= (h->forced_local != 0));
1287 /* If we have encountered a definition for this symbol. */
1288 if (h->root.type == bfd_link_hash_defined
1289 || h->root.type == bfd_link_hash_defweak)
1291 reloc_data.sym_value = h->root.u.def.value;
1292 reloc_data.sym_section = h->root.u.def.section;
1294 reloc_data.should_relocate = TRUE;
1296 if (is_reloc_for_GOT (howto) && !bfd_link_pic (info))
1298 /* TODO: Change it to use arc_do_relocation with
1299 ARC_32 reloc. Try to use ADD_RELA macro. */
1300 bfd_vma relocation =
1301 reloc_data.sym_value + reloc_data.reloc_addend
1302 + (reloc_data.sym_section->output_section != NULL ?
1303 (reloc_data.sym_section->output_offset
1304 + reloc_data.sym_section->output_section->vma)
1307 BFD_ASSERT (h->got.glist);
1308 bfd_vma got_offset = h->got.glist->offset;
1309 bfd_put_32 (output_bfd, relocation,
1310 htab->sgot->contents + got_offset);
1312 if (is_reloc_for_PLT (howto) && h->plt.offset != (bfd_vma) -1)
1314 /* TODO: This is repeated up here. */
1315 reloc_data.sym_value = h->plt.offset;
1316 reloc_data.sym_section = htab->splt;
1319 else if (h->root.type == bfd_link_hash_undefweak)
1321 /* Is weak symbol and has no definition. */
1322 if (is_reloc_for_GOT (howto))
1324 reloc_data.sym_value = h->root.u.def.value;
1325 reloc_data.sym_section = htab->sgot;
1326 reloc_data.should_relocate = TRUE;
1328 else if (is_reloc_for_PLT (howto)
1329 && h->plt.offset != (bfd_vma) -1)
1331 /* TODO: This is repeated up here. */
1332 reloc_data.sym_value = h->plt.offset;
1333 reloc_data.sym_section = htab->splt;
1334 reloc_data.should_relocate = TRUE;
1341 if (is_reloc_for_GOT (howto))
1343 reloc_data.sym_value = h->root.u.def.value;
1344 reloc_data.sym_section = htab->sgot;
1346 reloc_data.should_relocate = TRUE;
1348 else if (is_reloc_for_PLT (howto))
1350 /* Fail if it is linking for PIE and the symbol is
1352 if (bfd_link_executable (info)
1353 && !(*info->callbacks->undefined_symbol)
1354 (info, h->root.root.string, input_bfd, input_section,
1355 rel->r_offset, TRUE))
1359 reloc_data.sym_value = h->plt.offset;
1360 reloc_data.sym_section = htab->splt;
1362 reloc_data.should_relocate = TRUE;
1364 else if (!bfd_link_pic (info)
1365 && !(*info->callbacks->undefined_symbol)
1366 (info, h->root.root.string, input_bfd, input_section,
1367 rel->r_offset, TRUE))
1373 if (h->got.glist != NULL)
1375 struct got_entry *entry = h->got.glist;
1377 if (is_reloc_for_GOT (howto) || is_reloc_for_TLS (howto))
1379 if (! elf_hash_table (info)->dynamic_sections_created
1380 || (bfd_link_pic (info)
1381 && SYMBOL_REFERENCES_LOCAL (info, h)))
1383 reloc_data.sym_value = h->root.u.def.value;
1384 reloc_data.sym_section = h->root.u.def.section;
1386 if (is_reloc_for_TLS (howto))
1387 while (entry->type == GOT_NORMAL && entry->next != NULL)
1388 entry = entry->next;
1390 if (entry->processed == FALSE
1391 && (entry->type == GOT_TLS_GD
1392 || entry->type == GOT_TLS_IE))
1394 bfd_vma sym_value = h->root.u.def.value
1395 + h->root.u.def.section->output_section->vma
1396 + h->root.u.def.section->output_offset;
1399 elf_hash_table (info)->tls_sec->output_section->vma;
1401 bfd_put_32 (output_bfd,
1402 sym_value - sec_vma,
1403 htab->sgot->contents + entry->offset
1404 + (entry->existing_entries == TLS_GOT_MOD_AND_OFF ? 4 : 0));
1406 ARC_DEBUG ("arc_info: FIXED -> %s value = 0x%x "
1407 "@ 0x%x, for symbol %s\n",
1408 (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
1410 sym_value - sec_vma,
1411 htab->sgot->contents + entry->offset
1412 + (entry->existing_entries == TLS_GOT_MOD_AND_OFF ? 4 : 0),
1413 h->root.root.string);
1415 entry->processed = TRUE;
1418 if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
1420 bfd_vma sec_vma = htab->tls_sec->output_section->vma;
1421 bfd_put_32 (output_bfd,
1422 reloc_data.sym_value - sec_vma,
1423 htab->sgot->contents + entry->offset);
1426 if (entry->type == GOT_NORMAL && entry->processed == FALSE)
1429 reloc_data.sym_section->output_section->vma
1430 + reloc_data.sym_section->output_offset;
1432 if (h->root.type != bfd_link_hash_undefweak)
1434 bfd_put_32 (output_bfd,
1435 reloc_data.sym_value + sec_vma,
1436 htab->sgot->contents + entry->offset);
1438 ARC_DEBUG ("arc_info: PATCHED: 0x%08x "
1439 "@ 0x%08x for sym %s in got offset 0x%x\n",
1440 reloc_data.sym_value + sec_vma,
1441 htab->sgot->output_section->vma
1442 + htab->sgot->output_offset + entry->offset,
1443 h->root.root.string,
1448 ARC_DEBUG ("arc_info: PATCHED: NOT_PATCHED "
1449 "@ 0x%08x for sym %s in got offset 0x%x "
1451 htab->sgot->output_section->vma
1452 + htab->sgot->output_offset + entry->offset,
1453 h->root.root.string,
1457 entry->processed = TRUE;
1462 reloc_data.got_offset_value = entry->offset;
1464 ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
1465 "vma = 0x%x for symbol %s\n",
1466 entry->type, entry->offset,
1467 htab->sgot->output_section->vma
1468 + htab->sgot->output_offset + entry->offset,
1469 h->root.root.string);
1472 BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1473 if (htab->sgot != NULL)
1474 reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1475 + htab->sgot->output_offset;
1483 case R_ARC_32_PCREL:
1484 if (bfd_link_pic (info) && !bfd_link_pie (info)
1485 && ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1488 && (!info->symbolic || !h->def_regular))))
1490 Elf_Internal_Rela outrel;
1492 bfd_boolean skip = FALSE;
1493 bfd_boolean relocate = FALSE;
1494 asection *sreloc = _bfd_elf_get_dynamic_reloc_section
1495 (input_bfd, input_section,
1498 BFD_ASSERT (sreloc != NULL);
1500 outrel.r_offset = _bfd_elf_section_offset (output_bfd,
1504 if (outrel.r_offset == (bfd_vma) -1)
1507 outrel.r_addend = rel->r_addend;
1508 outrel.r_offset += (input_section->output_section->vma
1509 + input_section->output_offset);
1513 memset (&outrel, 0, sizeof outrel);
1516 else if (r_type == R_ARC_PC32
1517 || r_type == R_ARC_32_PCREL)
1519 BFD_ASSERT (h != NULL);
1520 if ((input_section->flags & SEC_ALLOC) != 0)
1525 BFD_ASSERT (h->dynindx != -1);
1526 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1530 /* Handle local symbols, they either do not have a
1531 global hash table entry (h == NULL), or are
1532 forced local due to a version script
1533 (h->forced_local), or the third condition is
1534 legacy, it appears to say something like, for
1535 links where we are pre-binding the symbols, or
1536 there's not an entry for this symbol in the
1537 dynamic symbol table, and it's a regular symbol
1538 not defined in a shared object, then treat the
1539 symbol as local, resolve it now. */
1541 || ((info->symbolic || h->dynindx == -1)
1546 /* outrel.r_addend = 0; */
1547 outrel.r_info = ELF32_R_INFO (0, R_ARC_RELATIVE);
1551 BFD_ASSERT (h->dynindx != -1);
1553 /* This type of dynamic relocation cannot be created
1554 for code sections. */
1555 BFD_ASSERT ((input_section->flags & SEC_CODE) == 0);
1557 if ((input_section->flags & SEC_ALLOC) != 0)
1562 BFD_ASSERT (h->dynindx != -1);
1563 outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_32);
1567 BFD_ASSERT (sreloc->contents != 0);
1569 loc = sreloc->contents;
1570 loc += sreloc->reloc_count * sizeof (Elf32_External_Rela);
1571 sreloc->reloc_count += 1;
1573 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1575 if (relocate == FALSE)
1583 if (is_reloc_SDA_relative (howto)
1584 && (reloc_data.sdata_begin_symbol_vma_set == FALSE))
1586 (*_bfd_error_handler)
1587 ("Error: Linker symbol __SDATA_BEGIN__ not found");
1588 bfd_set_error (bfd_error_bad_value);
1592 DEBUG_ARC_RELOC (reloc_data);
1594 if (arc_do_relocation (contents, reloc_data, info) != bfd_reloc_ok)
1601 static struct dynamic_sections
1602 arc_create_dynamic_sections (bfd * abfd, struct bfd_link_info *info)
1604 struct elf_link_hash_table *htab;
1606 struct dynamic_sections ds =
1608 .initialized = FALSE,
1618 htab = elf_hash_table (info);
1621 /* Create dynamic sections for relocatable executables so that we
1622 can copy relocations. */
1623 if (! htab->dynamic_sections_created && bfd_link_pic (info))
1625 if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
1629 dynobj = (elf_hash_table (info))->dynobj;
1633 ds.sgot = htab->sgot;
1634 ds.srelgot = htab->srelgot;
1636 ds.sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
1637 ds.srelgotplt = ds.srelplt;
1639 ds.splt = bfd_get_section_by_name (dynobj, ".plt");
1640 ds.srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
1643 if (htab->dynamic_sections_created)
1645 ds.sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
1648 ds.initialized = TRUE;
1653 #define ADD_SYMBOL_REF_SEC_AND_RELOC(SECNAME, COND_FOR_RELOC, H) \
1654 htab->s##SECNAME->size; \
1656 if (COND_FOR_RELOC) \
1658 htab->srel##SECNAME->size += sizeof (Elf32_External_Rela); \
1659 ARC_DEBUG ("arc_info: Added reloc space in " \
1660 #SECNAME " section at " __FILE__ \
1661 ":%d for symbol\n", \
1662 __LINE__, name_for_global_symbol (H)); \
1665 if (h->dynindx == -1 && !h->forced_local) \
1666 if (! bfd_elf_link_record_dynamic_symbol (info, H)) \
1668 htab->s##SECNAME->size += 4; \
1672 elf_arc_check_relocs (bfd * abfd,
1673 struct bfd_link_info * info,
1675 const Elf_Internal_Rela * relocs)
1677 Elf_Internal_Shdr * symtab_hdr;
1678 struct elf_link_hash_entry ** sym_hashes;
1679 struct got_entry ** local_got_ents;
1680 const Elf_Internal_Rela * rel;
1681 const Elf_Internal_Rela * rel_end;
1683 asection * sreloc = NULL;
1684 struct elf_link_hash_table * htab = elf_hash_table (info);
1686 if (bfd_link_relocatable (info))
1689 dynobj = (elf_hash_table (info))->dynobj;
1690 symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1691 sym_hashes = elf_sym_hashes (abfd);
1692 local_got_ents = arc_get_local_got_ents (abfd);
1694 rel_end = relocs + sec->reloc_count;
1695 for (rel = relocs; rel < rel_end; rel++)
1697 enum elf_arc_reloc_type r_type;
1698 reloc_howto_type *howto;
1699 unsigned long r_symndx;
1700 struct elf_link_hash_entry *h;
1702 r_type = ELF32_R_TYPE (rel->r_info);
1704 if (r_type >= (int) R_ARC_max)
1706 bfd_set_error (bfd_error_bad_value);
1709 howto = &elf_arc_howto_table[r_type];
1712 && (is_reloc_for_GOT (howto) == TRUE
1713 || is_reloc_for_TLS (howto) == TRUE))
1715 dynobj = elf_hash_table (info)->dynobj = abfd;
1716 if (! _bfd_elf_create_got_section (abfd, info))
1720 /* Load symbol information. */
1721 r_symndx = ELF32_R_SYM (rel->r_info);
1722 if (r_symndx < symtab_hdr->sh_info) /* Is a local symbol. */
1724 else /* Global one. */
1725 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1731 /* During shared library creation, these relocs should not
1732 appear in a shared library (as memory will be read only
1733 and the dynamic linker can not resolve these. However
1734 the error should not occur for e.g. debugging or
1735 non-readonly sections. */
1736 if (bfd_link_dll (info) && !bfd_link_pie (info)
1737 && (sec->flags & SEC_ALLOC) != 0
1738 && (sec->flags & SEC_READONLY) == 0
1739 && (sec->flags & SEC_CODE) != 0)
1743 name = h->root.root.string;
1745 /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); */
1747 (*_bfd_error_handler)
1749 %B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
1751 arc_elf_howto (r_type)->name,
1753 bfd_set_error (bfd_error_bad_value);
1757 /* In some cases we are not setting the 'non_got_ref'
1758 flag, even though the relocations don't require a GOT
1759 access. We should extend the testing in this area to
1760 ensure that no significant cases are being missed. */
1765 case R_ARC_32_PCREL:
1766 if (bfd_link_pic (info) && !bfd_link_pie (info)
1767 && ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1770 && (!info->symbolic || !h->def_regular))))
1774 sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
1782 sreloc->size += sizeof (Elf32_External_Rela);
1789 if (is_reloc_for_PLT (howto) == TRUE)
1797 if (is_reloc_for_GOT (howto) == TRUE)
1802 if (local_got_ents[r_symndx] == NULL)
1805 ADD_SYMBOL_REF_SEC_AND_RELOC (got,
1806 bfd_link_pic (info),
1808 new_got_entry_to_list (&(local_got_ents[r_symndx]),
1809 GOT_NORMAL, offset, TLS_GOT_NONE);
1814 /* Global symbol. */
1815 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1816 if (h->got.glist == NULL)
1819 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1820 new_got_entry_to_list (&h->got.glist,
1821 GOT_NORMAL, offset, TLS_GOT_NONE);
1826 if (is_reloc_for_TLS (howto) == TRUE)
1828 enum tls_type_e type = GOT_UNKNOWN;
1832 case R_ARC_TLS_GD_GOT:
1835 case R_ARC_TLS_IE_GOT:
1842 struct got_entry **list = NULL;
1844 list = &(h->got.glist);
1846 list = &(local_got_ents[r_symndx]);
1848 if (type != GOT_UNKNOWN && !symbol_has_entry_of_type (*list, type))
1850 enum tls_got_entries entries = TLS_GOT_NONE;
1852 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1854 if (type == GOT_TLS_GD)
1856 bfd_vma ATTRIBUTE_UNUSED notneeded =
1857 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1858 entries = TLS_GOT_MOD_AND_OFF;
1861 if (entries == TLS_GOT_NONE)
1862 entries = TLS_GOT_OFF;
1864 new_got_entry_to_list (list, type, offset, entries);
1872 #define ELF_DYNAMIC_INTERPRETER "/sbin/ld-uClibc.so"
1874 static struct plt_version_t *
1875 arc_get_plt_version (struct bfd_link_info *info)
1879 for (i = 0; i < 1; i++)
1881 ARC_DEBUG ("%d: size1 = %d, size2 = %d\n", i,
1882 plt_versions[i].entry_size,
1883 plt_versions[i].elem_size);
1886 if (bfd_get_mach (info->output_bfd) == bfd_mach_arc_arcv2)
1888 if (bfd_link_pic (info))
1889 return &(plt_versions[ELF_ARCV2_PIC]);
1891 return &(plt_versions[ELF_ARCV2_ABS]);
1895 if (bfd_link_pic (info))
1896 return &(plt_versions[ELF_ARC_PIC]);
1898 return &(plt_versions[ELF_ARC_ABS]);
1903 add_symbol_to_plt (struct bfd_link_info *info)
1905 struct elf_link_hash_table *htab = elf_hash_table (info);
1908 struct plt_version_t *plt_data = arc_get_plt_version (info);
1910 /* If this is the first .plt entry, make room for the special first
1912 if (htab->splt->size == 0)
1913 htab->splt->size += plt_data->entry_size;
1915 ret = htab->splt->size;
1917 htab->splt->size += plt_data->elem_size;
1918 ARC_DEBUG ("PLT_SIZE = %d\n", htab->splt->size);
1920 htab->sgotplt->size += 4;
1921 htab->srelplt->size += sizeof (Elf32_External_Rela);
1926 #define PLT_DO_RELOCS_FOR_ENTRY(ABFD, DS, RELOCS) \
1927 plt_do_relocs_for_symbol (ABFD, DS, RELOCS, 0, 0)
1930 plt_do_relocs_for_symbol (bfd *abfd,
1931 struct elf_link_hash_table *htab,
1932 const struct plt_reloc *reloc,
1934 bfd_vma symbol_got_offset)
1936 while (SYM_ONLY (reloc->symbol) != LAST_RELOC)
1938 bfd_vma relocation = 0;
1940 switch (SYM_ONLY (reloc->symbol))
1944 htab->sgotplt->output_section->vma +
1945 htab->sgotplt->output_offset + symbol_got_offset;
1948 relocation += reloc->addend;
1950 if (IS_RELATIVE (reloc->symbol))
1952 bfd_vma reloc_offset = reloc->offset;
1953 reloc_offset -= (IS_INSN_32 (reloc->symbol)) ? 4 : 0;
1954 reloc_offset -= (IS_INSN_24 (reloc->symbol)) ? 2 : 0;
1956 relocation -= htab->splt->output_section->vma
1957 + htab->splt->output_offset
1958 + plt_offset + reloc_offset;
1961 /* TODO: being ME is not a property of the relocation but of the
1962 section of which is applying the relocation. */
1963 if (IS_MIDDLE_ENDIAN (reloc->symbol) && !bfd_big_endian (abfd))
1966 ((relocation & 0xffff0000) >> 16) |
1967 ((relocation & 0xffff) << 16);
1970 switch (reloc->size)
1973 bfd_put_32 (htab->splt->output_section->owner,
1975 htab->splt->contents + plt_offset + reloc->offset);
1979 reloc = &(reloc[1]); /* Jump to next relocation. */
1984 relocate_plt_for_symbol (bfd *output_bfd,
1985 struct bfd_link_info *info,
1986 struct elf_link_hash_entry *h)
1988 struct plt_version_t *plt_data = arc_get_plt_version (info);
1989 struct elf_link_hash_table *htab = elf_hash_table (info);
1991 bfd_vma plt_index = (h->plt.offset - plt_data->entry_size)
1992 / plt_data->elem_size;
1993 bfd_vma got_offset = (plt_index + 3) * 4;
1995 ARC_DEBUG ("arc_info: PLT_OFFSET = 0x%x, PLT_ENTRY_VMA = 0x%x, \
1996 GOT_ENTRY_OFFSET = 0x%x, GOT_ENTRY_VMA = 0x%x, for symbol %s\n",
1998 htab->splt->output_section->vma
1999 + htab->splt->output_offset
2002 htab->sgotplt->output_section->vma
2003 + htab->sgotplt->output_offset
2005 h->root.root.string);
2010 uint16_t *ptr = (uint16_t *) plt_data->elem;
2011 for (i = 0; i < plt_data->elem_size/2; i++)
2013 uint16_t data = ptr[i];
2014 bfd_put_16 (output_bfd,
2016 htab->splt->contents + h->plt.offset + (i*2));
2020 plt_do_relocs_for_symbol (output_bfd, htab,
2021 plt_data->elem_relocs,
2025 /* Fill in the entry in the global offset table. */
2026 bfd_put_32 (output_bfd,
2027 (bfd_vma) (htab->splt->output_section->vma
2028 + htab->splt->output_offset),
2029 htab->sgotplt->contents + got_offset);
2031 /* TODO: Fill in the entry in the .rela.plt section. */
2033 Elf_Internal_Rela rel;
2036 rel.r_offset = (htab->sgotplt->output_section->vma
2037 + htab->sgotplt->output_offset
2041 BFD_ASSERT (h->dynindx != -1);
2042 rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_JMP_SLOT);
2044 loc = htab->srelplt->contents;
2045 loc += plt_index * sizeof (Elf32_External_Rela); /* relA */
2046 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2051 relocate_plt_for_entry (bfd *abfd,
2052 struct bfd_link_info *info)
2054 struct plt_version_t *plt_data = arc_get_plt_version (info);
2055 struct elf_link_hash_table *htab = elf_hash_table (info);
2059 uint16_t *ptr = (uint16_t *) plt_data->entry;
2060 for (i = 0; i < plt_data->entry_size/2; i++)
2062 uint16_t data = ptr[i];
2065 htab->splt->contents + (i*2));
2068 PLT_DO_RELOCS_FOR_ENTRY (abfd, htab, plt_data->entry_relocs);
2071 /* Desc : Adjust a symbol defined by a dynamic object and referenced
2072 by a regular object. The current definition is in some section of
2073 the dynamic object, but we're not including those sections. We
2074 have to change the definition to something the rest of the link can
2078 elf_arc_adjust_dynamic_symbol (struct bfd_link_info *info,
2079 struct elf_link_hash_entry *h)
2082 unsigned int power_of_two;
2083 bfd *dynobj = (elf_hash_table (info))->dynobj;
2084 struct elf_link_hash_table *htab = elf_hash_table (info);
2086 if (h->type == STT_FUNC
2087 || h->type == STT_GNU_IFUNC
2088 || h->needs_plt == 1)
2090 if (!bfd_link_pic (info) && !h->def_dynamic && !h->ref_dynamic)
2092 /* This case can occur if we saw a PLT32 reloc in an input
2093 file, but the symbol was never referred to by a dynamic
2094 object. In such a case, we don't actually need to build
2095 a procedure linkage table, and we can just do a PC32
2097 BFD_ASSERT (h->needs_plt);
2101 /* Make sure this symbol is output as a dynamic symbol. */
2102 if (h->dynindx == -1 && !h->forced_local
2103 && !bfd_elf_link_record_dynamic_symbol (info, h))
2106 if (bfd_link_pic (info)
2107 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
2109 bfd_vma loc = add_symbol_to_plt (info);
2111 if (!bfd_link_pic (info) && !h->def_regular)
2113 h->root.u.def.section = htab->splt;
2114 h->root.u.def.value = loc;
2116 h->plt.offset = loc;
2120 h->plt.offset = (bfd_vma) -1;
2126 /* If this is a weak symbol, and there is a real definition, the
2127 processor independent code will have arranged for us to see the
2128 real definition first, and we can just use the same value. */
2129 if (h->u.weakdef != NULL)
2131 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2132 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2133 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2134 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2138 /* If there are no non-GOT references, we do not need a copy
2140 if (!h->non_got_ref)
2143 /* This is a reference to a symbol defined by a dynamic object which
2144 is not a function. */
2146 /* If we are creating a shared library, we must presume that the
2147 only references to the symbol are via the global offset table.
2148 For such cases we need not do anything here; the relocations will
2149 be handled correctly by relocate_section. */
2150 if (bfd_link_pic (info))
2153 /* We must allocate the symbol in our .dynbss section, which will
2154 become part of the .bss section of the executable. There will be
2155 an entry for this symbol in the .dynsym section. The dynamic
2156 object will contain position independent code, so all references
2157 from the dynamic object to this symbol will go through the global
2158 offset table. The dynamic linker will use the .dynsym entry to
2159 determine the address it must put in the global offset table, so
2160 both the dynamic object and the regular object will refer to the
2161 same memory location for the variable. */
2163 s = bfd_get_section_by_name (dynobj, ".dynbss");
2164 BFD_ASSERT (s != NULL);
2166 /* We must generate a R_ARC_COPY reloc to tell the dynamic linker to
2167 copy the initial value out of the dynamic object and into the
2168 runtime process image. We need to remember the offset into the
2169 .rela.bss section we are going to use. */
2170 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2174 srel = bfd_get_section_by_name (dynobj, ".rela.bss");
2175 BFD_ASSERT (srel != NULL);
2176 srel->size += sizeof (Elf32_External_Rela);
2180 /* We need to figure out the alignment required for this symbol. I
2181 have no idea how ELF linkers handle this. */
2182 power_of_two = bfd_log2 (h->size);
2183 if (power_of_two > 3)
2186 /* Apply the required alignment. */
2187 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
2188 if (power_of_two > bfd_get_section_alignment (dynobj, s))
2190 if (! bfd_set_section_alignment (dynobj, s, power_of_two))
2194 /* Define the symbol as being at this point in the section. */
2195 h->root.u.def.section = s;
2196 h->root.u.def.value = s->size;
2198 /* Increment the section size to make room for the symbol. */
2204 /* Function : elf_arc_finish_dynamic_symbol
2205 Brief : Finish up dynamic symbol handling. We set the
2206 contents of various dynamic sections here.
2211 Returns : True/False as the return status. */
2214 elf_arc_finish_dynamic_symbol (bfd * output_bfd,
2215 struct bfd_link_info *info,
2216 struct elf_link_hash_entry *h,
2217 Elf_Internal_Sym * sym)
2219 if (h->plt.offset != (bfd_vma) -1)
2221 relocate_plt_for_symbol (output_bfd, info, h);
2223 if (!h->def_regular)
2225 /* Mark the symbol as undefined, rather than as defined in
2226 the .plt section. Leave the value alone. */
2227 sym->st_shndx = SHN_UNDEF;
2231 if (h->got.glist != NULL)
2233 struct got_entry *list = h->got.glist;
2235 /* Traverse the list of got entries for this symbol. */
2238 bfd_vma got_offset = h->got.glist->offset;
2240 if (list->type == GOT_NORMAL
2241 && list->created_dyn_relocation == FALSE)
2243 if (bfd_link_pic (info)
2244 && (info->symbolic || h->dynindx == -1)
2247 ADD_RELA (output_bfd, got, got_offset, 0, R_ARC_RELATIVE, 0);
2249 /* Do not fully understand the side effects of this condition.
2250 The relocation space might still being reserved. Perhaps
2251 I should clear its value. */
2252 else if (h->dynindx != -1)
2254 ADD_RELA (output_bfd, got, got_offset, h->dynindx,
2257 list->created_dyn_relocation = TRUE;
2259 else if (list->existing_entries != TLS_GOT_NONE)
2261 struct elf_link_hash_table *htab = elf_hash_table (info);
2262 enum tls_got_entries e = list->existing_entries;
2264 BFD_ASSERT (list->type != GOT_TLS_GD
2265 || list->existing_entries == TLS_GOT_MOD_AND_OFF);
2267 bfd_vma dynindx = h->dynindx == -1 ? 0 : h->dynindx;
2268 if (e == TLS_GOT_MOD_AND_OFF || e == TLS_GOT_MOD)
2270 ADD_RELA (output_bfd, got, got_offset, dynindx,
2271 R_ARC_TLS_DTPMOD, 0);
2272 ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2273 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2276 htab->sgot->output_section->vma
2277 + htab->sgot->output_offset + got_offset,
2280 if (e == TLS_GOT_MOD_AND_OFF || e == TLS_GOT_OFF)
2283 if (list->type == GOT_TLS_IE)
2284 addend = bfd_get_32 (output_bfd,
2285 htab->sgot->contents + got_offset);
2287 ADD_RELA (output_bfd, got,
2288 got_offset + (e == TLS_GOT_MOD_AND_OFF ? 4 : 0),
2290 (list->type == GOT_TLS_IE ?
2291 R_ARC_TLS_TPOFF : R_ARC_TLS_DTPOFF),
2294 ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2295 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2298 htab->sgot->output_section->vma
2299 + htab->sgot->output_offset + got_offset,
2307 h->got.glist = NULL;
2312 bfd_vma rel_offset = (h->root.u.def.value
2313 + h->root.u.def.section->output_section->vma
2314 + h->root.u.def.section->output_offset);
2317 bfd_get_section_by_name (h->root.u.def.section->owner,
2320 bfd_byte * loc = srelbss->contents
2321 + (srelbss->reloc_count * sizeof (Elf32_External_Rela));
2322 srelbss->reloc_count++;
2324 Elf_Internal_Rela rel;
2326 rel.r_offset = rel_offset;
2328 BFD_ASSERT (h->dynindx != -1);
2329 rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_COPY);
2331 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2334 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
2335 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2336 || strcmp (h->root.root.string, "__DYNAMIC") == 0
2337 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
2338 sym->st_shndx = SHN_ABS;
2343 #define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION, ASSERT) \
2345 if (SYMBOL != NULL) \
2347 h = elf_link_hash_lookup (elf_hash_table (info), \
2348 SYMBOL, FALSE, FALSE, TRUE); \
2350 else if (SECTION != NULL) \
2352 s = bfd_get_section_by_name (output_bfd, SECTION); \
2353 BFD_ASSERT (s != NULL || !ASSERT); \
2358 /* Function : elf_arc_finish_dynamic_sections
2359 Brief : Finish up the dynamic sections handling.
2364 Returns : True/False as the return status. */
2367 elf_arc_finish_dynamic_sections (bfd * output_bfd,
2368 struct bfd_link_info *info)
2370 struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
2371 struct elf_link_hash_table *htab = elf_hash_table (info);
2372 bfd *dynobj = (elf_hash_table (info))->dynobj;
2376 Elf32_External_Dyn *dyncon, *dynconend;
2378 dyncon = (Elf32_External_Dyn *) ds.sdyn->contents;
2380 (Elf32_External_Dyn *) (ds.sdyn->contents + ds.sdyn->size);
2381 for (; dyncon < dynconend; dyncon++)
2383 Elf_Internal_Dyn internal_dyn;
2384 bfd_boolean do_it = FALSE;
2386 struct elf_link_hash_entry *h = NULL;
2389 bfd_elf32_swap_dyn_in (dynobj, dyncon, &internal_dyn);
2391 switch (internal_dyn.d_tag)
2393 GET_SYMBOL_OR_SECTION (DT_INIT, "_init", NULL, TRUE)
2394 GET_SYMBOL_OR_SECTION (DT_FINI, "_fini", NULL, TRUE)
2395 GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt", TRUE)
2396 GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt", TRUE)
2397 GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt", TRUE)
2398 GET_SYMBOL_OR_SECTION (DT_RELASZ, NULL, ".rela.plt", FALSE)
2399 GET_SYMBOL_OR_SECTION (DT_VERSYM, NULL, ".gnu.version", TRUE)
2400 GET_SYMBOL_OR_SECTION (DT_VERDEF, NULL, ".gnu.version_d", TRUE)
2401 GET_SYMBOL_OR_SECTION (DT_VERNEED, NULL, ".gnu.version_r", TRUE)
2406 /* In case the dynamic symbols should be updated with a symbol. */
2408 && (h->root.type == bfd_link_hash_defined
2409 || h->root.type == bfd_link_hash_defweak))
2413 internal_dyn.d_un.d_val = h->root.u.def.value;
2414 asec_ptr = h->root.u.def.section;
2415 if (asec_ptr->output_section != NULL)
2417 internal_dyn.d_un.d_val +=
2418 (asec_ptr->output_section->vma +
2419 asec_ptr->output_offset);
2423 /* The symbol is imported from another shared
2424 library and does not apply to this one. */
2425 internal_dyn.d_un.d_val = 0;
2429 else if (s != NULL) /* With a section information. */
2431 switch (internal_dyn.d_tag)
2438 internal_dyn.d_un.d_ptr = s->vma;
2443 internal_dyn.d_un.d_val = s->size;
2449 internal_dyn.d_un.d_val -= s->size;
2459 bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon);
2462 if (htab->splt->size > 0)
2464 relocate_plt_for_entry (output_bfd, info);
2467 /* TODO: Validate this. */
2468 elf_section_data (htab->srelplt->output_section)->this_hdr.sh_entsize
2472 /* Fill in the first three entries in the global offset table. */
2475 if (htab->sgot->size > 0 || htab->sgotplt->size > 0)
2477 if (ds.sdyn == NULL)
2478 bfd_put_32 (output_bfd, (bfd_vma) 0,
2479 htab->sgotplt->contents);
2481 bfd_put_32 (output_bfd,
2482 ds.sdyn->output_section->vma + ds.sdyn->output_offset,
2483 htab->sgotplt->contents);
2484 bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 4);
2485 bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 8);
2492 #define ADD_DYNAMIC_SYMBOL(NAME, TAG) \
2493 h = elf_link_hash_lookup (elf_hash_table (info), \
2494 NAME, FALSE, FALSE, FALSE); \
2495 if ((h != NULL && (h->ref_regular || h->def_regular))) \
2496 if (! _bfd_elf_add_dynamic_entry (info, TAG, 0)) \
2499 /* Set the sizes of the dynamic sections. */
2501 elf_arc_size_dynamic_sections (bfd * output_bfd,
2502 struct bfd_link_info *info)
2506 bfd_boolean relocs_exist = FALSE;
2507 bfd_boolean reltext_exist = FALSE;
2508 struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
2509 struct elf_link_hash_table *htab = elf_hash_table (info);
2511 dynobj = (elf_hash_table (info))->dynobj;
2512 BFD_ASSERT (dynobj != NULL);
2514 if ((elf_hash_table (info))->dynamic_sections_created)
2516 struct elf_link_hash_entry *h;
2518 /* Set the contents of the .interp section to the
2520 if (!bfd_link_pic (info))
2522 s = bfd_get_section_by_name (dynobj, ".interp");
2523 BFD_ASSERT (s != NULL);
2524 s->size = sizeof (ELF_DYNAMIC_INTERPRETER);
2525 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2528 /* Add some entries to the .dynamic section. We fill in some of
2529 the values later, in elf_bfd_final_link, but we must add the
2530 entries now so that we know the final size of the .dynamic
2531 section. Checking if the .init section is present. We also
2532 create DT_INIT and DT_FINI entries if the init_str has been
2533 changed by the user. */
2534 ADD_DYNAMIC_SYMBOL ("init", DT_INIT);
2535 ADD_DYNAMIC_SYMBOL ("fini", DT_FINI);
2539 /* We may have created entries in the .rela.got section.
2540 However, if we are not creating the dynamic sections, we will
2541 not actually use these entries. Reset the size of .rela.got,
2542 which will cause it to get stripped from the output file
2544 if (htab->srelgot != NULL)
2545 htab->srelgot->size = 0;
2548 if (htab->splt != NULL && htab->splt->size == 0)
2549 htab->splt->flags |= SEC_EXCLUDE;
2550 for (s = dynobj->sections; s != NULL; s = s->next)
2552 if ((s->flags & SEC_LINKER_CREATED) == 0)
2555 if (strncmp (s->name, ".rela", 5) == 0)
2559 s->flags |= SEC_EXCLUDE;
2563 if (strcmp (s->name, ".rela.plt") != 0)
2565 const char *outname =
2566 bfd_get_section_name (output_bfd,
2567 htab->srelplt->output_section);
2569 asection *target = bfd_get_section_by_name (output_bfd,
2572 relocs_exist = TRUE;
2573 if (target != NULL && target->size != 0
2574 && (target->flags & SEC_READONLY) != 0
2575 && (target->flags & SEC_ALLOC) != 0)
2576 reltext_exist = TRUE;
2580 /* We use the reloc_count field as a counter if we need to
2581 copy relocs into the output file. */
2585 if (strcmp (s->name, ".dynamic") == 0)
2589 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2591 if (s->contents == NULL && s->size != 0)
2597 /* TODO: Check if this is needed. */
2598 if (!bfd_link_pic (info))
2599 if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
2602 if (htab->splt && (htab->splt->flags & SEC_EXCLUDE) == 0)
2603 if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
2604 || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2605 || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2606 || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0)
2610 if (relocs_exist == TRUE)
2611 if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
2612 || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
2613 || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
2614 sizeof (Elf32_External_Rela))
2618 if (reltext_exist == TRUE)
2619 if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
2626 const struct elf_size_info arc_elf32_size_info =
2628 sizeof (Elf32_External_Ehdr),
2629 sizeof (Elf32_External_Phdr),
2630 sizeof (Elf32_External_Shdr),
2631 sizeof (Elf32_External_Rel),
2632 sizeof (Elf32_External_Rela),
2633 sizeof (Elf32_External_Sym),
2634 sizeof (Elf32_External_Dyn),
2635 sizeof (Elf_External_Note),
2639 ELFCLASS32, EV_CURRENT,
2640 bfd_elf32_write_out_phdrs,
2641 bfd_elf32_write_shdrs_and_ehdr,
2642 bfd_elf32_checksum_contents,
2643 bfd_elf32_write_relocs,
2644 bfd_elf32_swap_symbol_in,
2645 bfd_elf32_swap_symbol_out,
2646 bfd_elf32_slurp_reloc_table,
2647 bfd_elf32_slurp_symbol_table,
2648 bfd_elf32_swap_dyn_in,
2649 bfd_elf32_swap_dyn_out,
2650 bfd_elf32_swap_reloc_in,
2651 bfd_elf32_swap_reloc_out,
2652 bfd_elf32_swap_reloca_in,
2653 bfd_elf32_swap_reloca_out
2656 #define elf_backend_size_info arc_elf32_size_info
2658 static struct bfd_link_hash_table *
2659 arc_elf_link_hash_table_create (bfd *abfd)
2661 struct elf_link_hash_table *htab;
2663 htab = bfd_zmalloc (sizeof (*htab));
2667 if (!_bfd_elf_link_hash_table_init (htab, abfd,
2668 _bfd_elf_link_hash_newfunc,
2669 sizeof (struct elf_link_hash_entry),
2676 htab->init_got_refcount.refcount = 0;
2677 htab->init_got_refcount.glist = NULL;
2678 htab->init_got_offset.offset = 0;
2679 htab->init_got_offset.glist = NULL;
2680 return (struct bfd_link_hash_table *) htab;
2683 /* Hook called by the linker routine which adds symbols from an object
2687 elf_arc_add_symbol_hook (bfd * abfd,
2688 struct bfd_link_info * info,
2689 Elf_Internal_Sym * sym,
2690 const char ** namep ATTRIBUTE_UNUSED,
2691 flagword * flagsp ATTRIBUTE_UNUSED,
2692 asection ** secp ATTRIBUTE_UNUSED,
2693 bfd_vma * valp ATTRIBUTE_UNUSED)
2695 if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
2696 || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
2697 && (abfd->flags & DYNAMIC) == 0
2698 && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
2699 elf_tdata (info->output_bfd)->has_gnu_symbols = elf_gnu_symbol_any;
2704 #define TARGET_LITTLE_SYM arc_elf32_le_vec
2705 #define TARGET_LITTLE_NAME "elf32-littlearc"
2706 #define TARGET_BIG_SYM arc_elf32_be_vec
2707 #define TARGET_BIG_NAME "elf32-bigarc"
2708 #define ELF_ARCH bfd_arch_arc
2709 #define ELF_MACHINE_CODE EM_ARC_COMPACT
2710 #define ELF_MACHINE_ALT1 EM_ARC_COMPACT2
2711 #define ELF_MAXPAGESIZE 0x2000
2713 #define bfd_elf32_bfd_link_hash_table_create arc_elf_link_hash_table_create
2715 #define bfd_elf32_bfd_merge_private_bfd_data arc_elf_merge_private_bfd_data
2716 #define bfd_elf32_bfd_reloc_type_lookup arc_elf32_bfd_reloc_type_lookup
2717 #define bfd_elf32_bfd_set_private_flags arc_elf_set_private_flags
2718 #define bfd_elf32_bfd_print_private_bfd_data arc_elf_print_private_bfd_data
2719 #define bfd_elf32_bfd_copy_private_bfd_data arc_elf_copy_private_bfd_data
2721 #define elf_info_to_howto_rel arc_info_to_howto_rel
2722 #define elf_backend_object_p arc_elf_object_p
2723 #define elf_backend_final_write_processing arc_elf_final_write_processing
2725 #define elf_backend_relocate_section elf_arc_relocate_section
2726 #define elf_backend_check_relocs elf_arc_check_relocs
2727 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
2729 #define elf_backend_adjust_dynamic_symbol elf_arc_adjust_dynamic_symbol
2730 #define elf_backend_finish_dynamic_symbol elf_arc_finish_dynamic_symbol
2732 #define elf_backend_finish_dynamic_sections elf_arc_finish_dynamic_sections
2733 #define elf_backend_size_dynamic_sections elf_arc_size_dynamic_sections
2734 #define elf_backend_add_symbol_hook elf_arc_add_symbol_hook
2736 #define elf_backend_can_gc_sections 1
2737 #define elf_backend_want_got_plt 1
2738 #define elf_backend_plt_readonly 1
2739 #define elf_backend_rela_plts_and_copies_p 1
2740 #define elf_backend_want_plt_sym 0
2741 #define elf_backend_got_header_size 12
2743 #define elf_backend_may_use_rel_p 0
2744 #define elf_backend_may_use_rela_p 1
2745 #define elf_backend_default_use_rela_p 1
2747 #include "elf32-target.h"