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"
29 #include "opcode/arc.h"
33 # define PR_DEBUG(fmt, args...) fprintf (stderr, fmt, ##args)
35 # define PR_DEBUG(fmt, args...)
38 /* #define ARC_ENABLE_DEBUG 1 */
39 #ifndef ARC_ENABLE_DEBUG
40 #define ARC_DEBUG(...)
43 name_for_global_symbol (struct elf_link_hash_entry *h)
45 static char *local_str = "(local)";
49 return h->root.root.string;
51 #define ARC_DEBUG(args...) fprintf (stderr, ##args)
55 #define ADD_RELA(BFD, SECTION, OFFSET, SYM_IDX, TYPE, ADDEND) \
57 struct elf_link_hash_table *_htab = elf_hash_table (info); \
58 Elf_Internal_Rela _rel; \
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); \
75 bfd_vma sdata_begin_symbol_vma;
76 asection * sdata_output_section;
77 bfd_vma got_symbol_vma;
80 struct arc_local_data global_arc_data =
82 .sdata_begin_symbol_vma = 0,
83 .sdata_output_section = NULL,
87 struct dynamic_sections
89 bfd_boolean initialized;
93 asection * srelgotplt;
99 enum dyn_section_types
107 DYN_SECTION_TYPES_END
110 const char * dyn_section_names[DYN_SECTION_TYPES_END] =
139 struct got_entry *next;
140 enum tls_type_e type;
142 bfd_boolean processed;
143 bfd_boolean created_dyn_relocation;
144 enum tls_got_entries existing_entries;
148 new_got_entry_to_list (struct got_entry **list,
149 enum tls_type_e type,
151 enum tls_got_entries existing_entries)
153 /* Find list end. Avoid having multiple entries of the same
155 struct got_entry **p = list;
158 if ((*p)->type == type)
163 struct got_entry *entry =
164 (struct got_entry *) malloc (sizeof(struct got_entry));
167 entry->offset = offset;
169 entry->processed = FALSE;
170 entry->created_dyn_relocation = FALSE;
171 entry->existing_entries = existing_entries;
173 /* Add the entry to the end of the list. */
178 symbol_has_entry_of_type (struct got_entry *list, enum tls_type_e type)
182 if (list->type == type)
190 /* The default symbols representing the init and fini dyn values.
191 TODO: Check what is the relation of those strings with arclinux.em
193 #define INIT_SYM_STRING "_init"
194 #define FINI_SYM_STRING "_fini"
196 char * init_str = INIT_SYM_STRING;
197 char * fini_str = FINI_SYM_STRING;
199 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
204 static ATTRIBUTE_UNUSED const char *
205 reloc_type_to_name (unsigned int type)
209 #include "elf/arc-reloc.def"
216 #undef ARC_RELOC_HOWTO
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). */
223 static ATTRIBUTE_UNUSED bfd_boolean
224 is_reloc_PC_relative (reloc_howto_type *howto)
226 return (strstr (howto->name, "PC") != NULL) ? TRUE : FALSE;
230 is_reloc_SDA_relative (reloc_howto_type *howto)
232 return (strstr (howto->name, "SDA") != NULL) ? TRUE : FALSE;
236 is_reloc_for_GOT (reloc_howto_type * howto)
238 if (strstr (howto->name, "TLS") != NULL)
240 return (strstr (howto->name, "GOT") != NULL) ? TRUE : FALSE;
244 is_reloc_for_PLT (reloc_howto_type * howto)
246 return (strstr (howto->name, "PLT") != NULL) ? TRUE : FALSE;
250 is_reloc_for_TLS (reloc_howto_type *howto)
252 return (strstr (howto->name, "TLS") != NULL) ? TRUE : FALSE;
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)
263 static bfd_reloc_status_type
264 arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
265 arelent *reloc_entry,
267 void *data ATTRIBUTE_UNUSED,
268 asection *input_section,
270 char ** error_message ATTRIBUTE_UNUSED)
272 if (output_bfd != NULL)
274 reloc_entry->address += input_section->output_offset;
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;
285 return bfd_reloc_continue;
289 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
293 #include "elf/arc-reloc.def"
296 #undef ARC_RELOC_HOWTO
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),
301 static struct reloc_howto_struct elf_arc_howto_table[] =
303 #include "elf/arc-reloc.def"
304 /* Example of what is generated by the preprocessor. Currently kept as an
306 HOWTO (R_ARC_NONE, // Type.
308 2, // Size (0 = byte, 1 = short, 2 = long).
310 FALSE, // PC_relative.
312 complain_overflow_bitfield, // Complain_on_overflow.
313 bfd_elf_generic_reloc, // Special_function.
314 "R_ARC_NONE", // Name.
315 TRUE, // Partial_inplace.
318 FALSE), // PCrel_offset.
321 #undef ARC_RELOC_HOWTO
323 static void arc_elf_howto_init (void)
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) \
332 BFD_ASSERT (SIZE == 2); \
335 #include "elf/arc-reloc.def"
338 #undef ARC_RELOC_HOWTO
341 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
343 const int howto_table_lookup[] =
345 #include "elf/arc-reloc.def"
347 #undef ARC_RELOC_HOWTO
349 static reloc_howto_type *
350 arc_elf_howto (unsigned int r_type)
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];
357 /* Map BFD reloc types to ARC ELF reloc types. */
361 bfd_reloc_code_real_type bfd_reloc_val;
362 unsigned char elf_reloc_val;
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[] =
369 #include "elf/arc-reloc.def"
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},
377 #undef ARC_RELOC_HOWTO
379 typedef ATTRIBUTE_UNUSED bfd_vma (*replace_func) (unsigned, int ATTRIBUTE_UNUSED);
381 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
383 func = (void *) RELOC_FUNCTION; \
386 get_replace_function (bfd *abfd, unsigned int r_type)
392 #include "elf/arc-reloc.def"
395 if (func == replace_bits24 && bfd_big_endian (abfd))
396 return (replace_func) replace_bits24_be;
398 return (replace_func) func;
400 #undef ARC_RELOC_HOWTO
402 static reloc_howto_type *
403 arc_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
404 bfd_reloc_code_real_type code)
408 for (i = ARRAY_SIZE (arc_reloc_map); i--;)
410 if (arc_reloc_map[i].bfd_reloc_val == code)
411 return arc_elf_howto (arc_reloc_map[i].elf_reloc_val);
417 /* Function to set the ELF flag bits. */
419 arc_elf_set_private_flags (bfd *abfd, flagword flags)
421 elf_elfheader (abfd)->e_flags = flags;
422 elf_flags_init (abfd) = TRUE;
426 /* Print private flags. */
428 arc_elf_print_private_bfd_data (bfd *abfd, void * ptr)
430 FILE *file = (FILE *) ptr;
433 BFD_ASSERT (abfd != NULL && ptr != NULL);
435 /* Print normal ELF private data. */
436 _bfd_elf_print_private_bfd_data (abfd, ptr);
438 flags = elf_elfheader (abfd)->e_flags;
439 fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
441 switch (flags & EF_ARC_MACH_MSK)
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;
449 fprintf (file, "-mcpu=unknown");
453 switch (flags & EF_ARC_OSABI_MSK)
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;
459 fprintf (file, "(ABI:unknown)");
467 /* Copy backend specific data from one object module to another. */
470 arc_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
472 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
473 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
476 BFD_ASSERT (!elf_flags_init (obfd)
477 || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
479 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
480 elf_flags_init (obfd) = TRUE;
482 /* Copy object attributes. */
483 _bfd_elf_copy_obj_attributes (ibfd, obfd);
485 return _bfd_elf_copy_private_bfd_data (ibfd, obfd);
488 static reloc_howto_type *
489 bfd_elf32_bfd_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED,
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);
502 /* Set the howto pointer for an ARC ELF reloc. */
505 arc_info_to_howto_rel (bfd * abfd ATTRIBUTE_UNUSED,
507 Elf_Internal_Rela * dst)
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);
516 /* Merge backend specific data from an object file to the output
517 object file when linking. */
520 arc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
522 unsigned short mach_ibfd;
523 static unsigned short mach_obfd = EM_NONE;
528 /* Check if we have the same endianess. */
529 if (! _bfd_generic_verify_endian_match (ibfd, obfd))
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));
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;
541 if (!elf_flags_init (obfd)) /* First call, no flags set. */
543 elf_flags_init (obfd) = TRUE;
544 out_flags = in_flags;
547 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
548 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
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))
556 bfd_boolean null_input_bfd = TRUE;
557 bfd_boolean only_data_sections = TRUE;
559 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
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;
566 null_input_bfd = FALSE;
569 if (null_input_bfd || only_data_sections)
573 /* Complain about various flag/architecture mismatches. */
574 mach_ibfd = elf_elfheader (ibfd)->e_machine;
575 if (mach_obfd == EM_NONE)
577 mach_obfd = mach_ibfd;
581 if (mach_ibfd != mach_obfd)
583 _bfd_error_handler (_("ERROR: Attempting to link %B "
584 "with a binary %s of different architecture"),
585 ibfd, bfd_get_filename (obfd));
588 else if (in_flags != out_flags)
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)
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;
603 /* Update the flags. */
604 elf_elfheader (obfd)->e_flags = in_flags;
606 if (bfd_get_mach (obfd) < bfd_get_mach (ibfd))
608 return bfd_set_arch_mach (obfd, bfd_arch_arc, bfd_get_mach (ibfd));
614 /* Set the right machine number for an ARC ELF file. */
616 arc_elf_object_p (bfd * abfd)
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;
625 if (e_machine == EM_ARC_COMPACT || e_machine == EM_ARC_COMPACT2)
629 case E_ARC_MACH_ARC600:
630 mach = bfd_mach_arc_arc600;
632 case E_ARC_MACH_ARC601:
633 mach = bfd_mach_arc_arc601;
635 case E_ARC_MACH_ARC700:
636 mach = bfd_mach_arc_arc700;
638 case E_ARC_MACH_NPS400:
639 mach = bfd_mach_arc_nps400;
641 case EF_ARC_CPU_ARCV2HS:
642 case EF_ARC_CPU_ARCV2EM:
643 mach = bfd_mach_arc_arcv2;
646 mach = (e_machine == EM_ARC_COMPACT) ?
647 bfd_mach_arc_arc700 : bfd_mach_arc_arcv2;
653 if (e_machine == EM_ARC)
655 (*_bfd_error_handler)
656 (_("Error: The ARC4 architecture is no longer supported.\n"));
661 (*_bfd_error_handler)
662 (_("Warning: unset or old architecture flags. \n"
663 " Use default machine.\n"));
667 return bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach);
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. */
674 arc_elf_final_write_processing (bfd * abfd,
675 bfd_boolean linker ATTRIBUTE_UNUSED)
679 switch (bfd_get_mach (abfd))
681 case bfd_mach_arc_arc600:
682 emf = EM_ARC_COMPACT;
684 case bfd_mach_arc_arc601:
685 emf = EM_ARC_COMPACT;
687 case bfd_mach_arc_arc700:
688 emf = EM_ARC_COMPACT;
690 case bfd_mach_arc_nps400:
691 emf = EM_ARC_COMPACT;
693 case bfd_mach_arc_arcv2:
694 emf = EM_ARC_COMPACT2;
700 elf_elfheader (abfd)->e_machine = emf;
702 /* Record whatever is the current syscall ABI version. */
703 elf_elfheader (abfd)->e_flags |= E_ARC_OSABI_CURRENT;
709 #define BFD_DEBUG_PIC(...)
711 struct arc_relocation_data
713 bfd_signed_vma reloc_offset;
714 bfd_signed_vma reloc_addend;
715 bfd_signed_vma got_offset_value;
717 bfd_signed_vma sym_value;
718 asection * sym_section;
720 reloc_howto_type *howto;
722 asection * input_section;
724 bfd_signed_vma sdata_begin_symbol_vma;
725 bfd_boolean sdata_begin_symbol_vma_set;
726 bfd_signed_vma got_symbol_vma;
728 bfd_boolean should_relocate;
730 const char * symbol_name;
734 debug_arc_reloc (struct arc_relocation_data reloc_data)
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)
747 PR_DEBUG (" Symbol Section:\n");
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)
755 ", output_section->vma = 0x%08x",
756 ((unsigned int) reloc_data.sym_section->output_section->vma));
759 PR_DEBUG (" file: %s\n", reloc_data.sym_section->owner->filename);
763 PR_DEBUG ( " symbol section is NULL\n");
766 PR_DEBUG ( " Input_section:\n");
767 if (reloc_data.input_section != NULL)
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);
782 PR_DEBUG ( " input section is NULL\n");
787 middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
792 ((insn & 0xffff0000) >> 16) |
793 ((insn & 0xffff) << 16);
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. */
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)
807 switch (reloc_data.howto->type)
809 case R_ARC_NPS_CMEM16:
810 if (((relocation >> 16) & 0xffff) != NPS_CMEM_HIGH_VALUE)
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,
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,
833 return bfd_reloc_overflow;
844 #define ME(reloc) (reloc)
846 #define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") != NULL) \
847 && (!bfd_big_endian (BFD)))
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)
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)
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) ( \
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))) \
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)
886 #define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA, TYPE) \
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) \
897 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
898 sym_section->output_section->vma + sym_section->output_offset); \
902 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
904 if (input_section->output_section != NULL) \
906 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
907 input_section->output_section->vma + input_section->output_offset); \
911 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
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); \
924 #define PRINT_DEBUG_RELOC_INFO_AFTER \
926 ARC_DEBUG ("after = 0x%08x\n", (unsigned int) insn); \
929 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
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 \
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)
947 bfd_signed_vma relocation = 0;
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;
954 if (reloc_data.should_relocate == FALSE)
957 switch (reloc_data.howto->size)
960 insn = arc_bfd_get_32 (abfd,
961 contents + reloc_data.reloc_offset,
962 reloc_data.input_section);
965 insn = arc_bfd_get_16 (abfd,
966 contents + reloc_data.reloc_offset,
967 reloc_data.input_section);
970 insn = arc_bfd_get_8 (abfd,
971 contents + reloc_data.reloc_offset,
972 reloc_data.input_section);
982 switch (reloc_data.howto->type)
984 #include "elf/arc-reloc.def"
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),
999 flag = arc_special_overflow_checks (reloc_data, relocation, info);
1001 #undef DEBUG_ARC_RELOC
1002 #define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
1003 if (flag != bfd_reloc_ok)
1005 PR_DEBUG ( "Relocation overflows !!!!\n");
1007 DEBUG_ARC_RELOC (reloc_data);
1010 "Relocation value = signed -> %d, unsigned -> %u"
1011 ", hex -> (0x%08x)\n",
1013 (unsigned int) relocation,
1014 (unsigned int) relocation);
1017 #undef DEBUG_ARC_RELOC
1018 #define DEBUG_ARC_RELOC(A)
1020 /* Write updated instruction back to memory. */
1021 switch (reloc_data.howto->size)
1024 arc_bfd_put_32 (abfd, insn,
1025 contents + reloc_data.reloc_offset,
1026 reloc_data.input_section);
1029 arc_bfd_put_16 (abfd, insn,
1030 contents + reloc_data.reloc_offset,
1031 reloc_data.input_section);
1034 arc_bfd_put_8 (abfd, insn,
1035 contents + reloc_data.reloc_offset,
1036 reloc_data.input_section);
1039 ARC_DEBUG ("size = %d\n", reloc_data.howto->size);
1044 return bfd_reloc_ok;
1059 #undef ARC_RELOC_HOWTO
1061 static struct got_entry **
1062 arc_get_local_got_ents (bfd * abfd)
1064 static struct got_entry **local_got_ents = NULL;
1066 if (local_got_ents == NULL)
1069 Elf_Internal_Shdr *symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
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)
1077 memset (local_got_ents, 0, sizeof(struct got_entry *) * size);
1078 elf_local_got_ents (abfd) = local_got_ents;
1081 return local_got_ents;
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
1099 elf_arc_relocate_section (bfd * output_bfd,
1100 struct bfd_link_info * info,
1102 asection * input_section,
1103 bfd_byte * contents,
1104 Elf_Internal_Rela * relocs,
1105 Elf_Internal_Sym * local_syms,
1106 asection ** local_sections)
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);
1116 symtab_hdr = &((elf_tdata (input_bfd))->symtab_hdr);
1117 sym_hashes = elf_sym_hashes (input_bfd);
1119 rel = wrel = relocs;
1120 relend = relocs + input_section->reloc_count;
1121 for (; rel < relend; wrel++, rel++)
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;
1129 struct elf_link_hash_entry *h2;
1131 struct arc_relocation_data reloc_data =
1135 .got_offset_value = 0,
1137 .sym_section = 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
1146 r_type = ELF32_R_TYPE (rel->r_info);
1148 if (r_type >= (int) R_ARC_max)
1150 bfd_set_error (bfd_error_bad_value);
1153 howto = arc_elf_howto (r_type);
1155 r_symndx = ELF32_R_SYM (rel->r_info);
1157 /* If we are generating another .o file and the symbol in not
1158 local, skip this relocation. */
1159 if (bfd_link_relocatable (info))
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. */
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)
1170 sym = local_syms + r_symndx;
1171 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1173 sec = local_sections[r_symndx];
1175 /* for RELA relocs.Just adjust the addend
1176 value in the relocation entry. */
1177 rel->r_addend += sec->output_offset + sym->st_value;
1180 PR_DEBUG ("local symbols reloc "
1181 "(section=%d %s) seen in %s\n",
1183 local_sections[r_symndx]->name,
1184 __PRETTY_FUNCTION__)
1190 h2 = elf_link_hash_lookup (elf_hash_table (info), "__SDATA_BEGIN__",
1191 FALSE, FALSE, TRUE);
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. */
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;
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;
1209 /* This is a final link. */
1214 if (r_symndx < symtab_hdr->sh_info) /* A local symbol. */
1216 sym = local_syms + r_symndx;
1217 sec = local_sections[r_symndx];
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. */
1226 /* Get the symbol's entry in the symtab. */
1227 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
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;
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)
1237 reloc_data.sym_value = h->root.u.def.value;
1238 sec = h->root.u.def.section;
1242 /* Clean relocs for symbols in discarded sections. */
1243 if (sec != NULL && discarded_section (sec))
1245 _bfd_clear_contents (howto, input_bfd, input_section,
1246 contents + rel->r_offset);
1247 rel->r_offset = rel->r_offset;
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))
1261 if (bfd_link_relocatable (info))
1268 if (r_symndx < symtab_hdr->sh_info) /* A local symbol. */
1270 struct got_entry *entry;
1272 local_got_ents = arc_get_local_got_ents (output_bfd);
1273 entry = local_got_ents[r_symndx];
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,
1282 /* Mergeable section handling. */
1283 if ((sec->flags & SEC_MERGE)
1284 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
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
1293 rel->r_addend += msec->output_section->vma + msec->output_offset;
1295 reloc_data.reloc_addend = rel->r_addend;
1298 if ((is_reloc_for_GOT (howto)
1299 || is_reloc_for_TLS (howto)) && entry != NULL)
1301 if (is_reloc_for_TLS (howto))
1302 while (entry->type == GOT_NORMAL && entry->next != NULL)
1303 entry = entry->next;
1305 if (is_reloc_for_GOT (howto))
1306 while (entry->type != GOT_NORMAL && entry->next != NULL)
1307 entry = entry->next;
1309 if (entry->type == GOT_TLS_GD && entry->processed == FALSE)
1311 bfd_vma sym_vma = sym->st_value
1312 + sec->output_section->vma
1313 + sec->output_offset;
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);
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);
1326 ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_GD value "
1327 "= 0x%x @ 0x%x, for symbol %s\n",
1329 htab->sgot->contents + entry->offset + 4,
1332 entry->processed = TRUE;
1334 if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
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. */
1345 ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_IE value = "
1346 "0x%x @ 0x%x, for symbol %s\n",
1348 htab->sgot->contents + entry->offset,
1351 entry->processed = TRUE;
1353 if (entry->type == GOT_NORMAL && entry->processed == FALSE)
1355 bfd_vma sec_vma = reloc_data.sym_section->output_section->vma
1356 + reloc_data.sym_section->output_offset;
1358 bfd_put_32 (output_bfd, reloc_data.sym_value + sec_vma,
1359 htab->sgot->contents + entry->offset);
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,
1368 entry->processed = TRUE;
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,
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;
1385 reloc_data.should_relocate = TRUE;
1387 else /* Global symbol. */
1389 /* Get the symbol's entry in the symtab. */
1390 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
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;
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;
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)
1404 reloc_data.sym_value = h->root.u.def.value;
1405 reloc_data.sym_section = h->root.u.def.section;
1407 reloc_data.should_relocate = TRUE;
1409 if (is_reloc_for_GOT (howto) && !bfd_link_pic (info))
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)
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);
1425 if (is_reloc_for_PLT (howto) && h->plt.offset != (bfd_vma) -1)
1427 /* TODO: This is repeated up here. */
1428 reloc_data.sym_value = h->plt.offset;
1429 reloc_data.sym_section = htab->splt;
1432 else if (h->root.type == bfd_link_hash_undefweak)
1434 /* Is weak symbol and has no definition. */
1435 if (is_reloc_for_GOT (howto))
1437 reloc_data.sym_value = h->root.u.def.value;
1438 reloc_data.sym_section = htab->sgot;
1439 reloc_data.should_relocate = TRUE;
1441 else if (is_reloc_for_PLT (howto)
1442 && h->plt.offset != (bfd_vma) -1)
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;
1454 if (is_reloc_for_GOT (howto))
1456 reloc_data.sym_value = h->root.u.def.value;
1457 reloc_data.sym_section = htab->sgot;
1459 reloc_data.should_relocate = TRUE;
1461 else if (is_reloc_for_PLT (howto))
1463 /* Fail if it is linking for PIE and the symbol is
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))
1472 reloc_data.sym_value = h->plt.offset;
1473 reloc_data.sym_section = htab->splt;
1475 reloc_data.should_relocate = TRUE;
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))
1486 if (h->got.glist != NULL)
1488 struct got_entry *entry = h->got.glist;
1490 if (is_reloc_for_GOT (howto) || is_reloc_for_TLS (howto))
1492 if (! elf_hash_table (info)->dynamic_sections_created
1493 || (bfd_link_pic (info)
1494 && SYMBOL_REFERENCES_LOCAL (info, h)))
1496 reloc_data.sym_value = h->root.u.def.value;
1497 reloc_data.sym_section = h->root.u.def.section;
1499 if (is_reloc_for_TLS (howto))
1500 while (entry->type == GOT_NORMAL && entry->next != NULL)
1501 entry = entry->next;
1503 if (entry->processed == FALSE
1504 && (entry->type == GOT_TLS_GD
1505 || entry->type == GOT_TLS_IE))
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;
1512 elf_hash_table (info)->tls_sec->output_section->vma;
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));
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" :
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);
1528 entry->processed = TRUE;
1531 if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
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);
1539 if (entry->type == GOT_NORMAL && entry->processed == FALSE)
1542 reloc_data.sym_section->output_section->vma
1543 + reloc_data.sym_section->output_offset;
1545 if (h->root.type != bfd_link_hash_undefweak)
1547 bfd_put_32 (output_bfd,
1548 reloc_data.sym_value + sec_vma,
1549 htab->sgot->contents + entry->offset);
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,
1561 ARC_DEBUG ("arc_info: PATCHED: NOT_PATCHED "
1562 "@ 0x%08x for sym %s in got offset 0x%x "
1564 htab->sgot->output_section->vma
1565 + htab->sgot->output_offset + entry->offset,
1566 h->root.root.string,
1570 entry->processed = TRUE;
1575 reloc_data.got_offset_value = entry->offset;
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);
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;
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)
1601 && (!info->symbolic || !h->def_regular))))
1603 Elf_Internal_Rela outrel;
1605 bfd_boolean skip = FALSE;
1606 bfd_boolean relocate = FALSE;
1607 asection *sreloc = _bfd_elf_get_dynamic_reloc_section
1608 (input_bfd, input_section,
1611 BFD_ASSERT (sreloc != NULL);
1613 outrel.r_offset = _bfd_elf_section_offset (output_bfd,
1617 if (outrel.r_offset == (bfd_vma) -1)
1620 outrel.r_addend = rel->r_addend;
1621 outrel.r_offset += (input_section->output_section->vma
1622 + input_section->output_offset);
1624 #define IS_ARC_PCREL_TYPE(TYPE) \
1625 ( (TYPE == R_ARC_PC32) \
1626 || (TYPE == R_ARC_32_PCREL))
1629 memset (&outrel, 0, sizeof outrel);
1634 && ((IS_ARC_PCREL_TYPE (r_type))
1635 || !(bfd_link_executable (info)
1636 || SYMBOLIC_BIND (info, h))
1637 || ! h->def_regular))
1639 BFD_ASSERT (h != NULL);
1640 if ((input_section->flags & SEC_ALLOC) != 0)
1645 BFD_ASSERT (h->dynindx != -1);
1646 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
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. */
1661 /* outrel.r_addend = 0; */
1662 outrel.r_info = ELF32_R_INFO (0, R_ARC_RELATIVE);
1665 BFD_ASSERT (sreloc->contents != 0);
1667 loc = sreloc->contents;
1668 loc += sreloc->reloc_count * sizeof (Elf32_External_Rela);
1669 sreloc->reloc_count += 1;
1671 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1673 if (relocate == FALSE)
1681 if (is_reloc_SDA_relative (howto)
1682 && (reloc_data.sdata_begin_symbol_vma_set == FALSE))
1684 (*_bfd_error_handler)
1685 ("Error: Linker symbol __SDATA_BEGIN__ not found");
1686 bfd_set_error (bfd_error_bad_value);
1690 DEBUG_ARC_RELOC (reloc_data);
1692 if (arc_do_relocation (contents, reloc_data, info) != bfd_reloc_ok)
1699 static struct dynamic_sections
1700 arc_create_dynamic_sections (bfd * abfd, struct bfd_link_info *info)
1702 struct elf_link_hash_table *htab;
1704 struct dynamic_sections ds =
1706 .initialized = FALSE,
1716 htab = elf_hash_table (info);
1719 /* Create dynamic sections for relocatable executables so that we
1720 can copy relocations. */
1721 if (! htab->dynamic_sections_created && bfd_link_pic (info))
1723 if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
1727 dynobj = (elf_hash_table (info))->dynobj;
1731 ds.sgot = htab->sgot;
1732 ds.srelgot = htab->srelgot;
1734 ds.sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
1735 ds.srelgotplt = ds.srelplt;
1737 ds.splt = bfd_get_section_by_name (dynobj, ".plt");
1738 ds.srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
1741 if (htab->dynamic_sections_created)
1743 ds.sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
1746 ds.initialized = TRUE;
1751 #define ADD_SYMBOL_REF_SEC_AND_RELOC(SECNAME, COND_FOR_RELOC, H) \
1752 htab->s##SECNAME->size; \
1754 if (COND_FOR_RELOC) \
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)); \
1763 if (h->dynindx == -1 && !h->forced_local) \
1764 if (! bfd_elf_link_record_dynamic_symbol (info, H)) \
1766 htab->s##SECNAME->size += 4; \
1770 elf_arc_check_relocs (bfd * abfd,
1771 struct bfd_link_info * info,
1773 const Elf_Internal_Rela * relocs)
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;
1781 asection * sreloc = NULL;
1782 struct elf_link_hash_table * htab = elf_hash_table (info);
1784 if (bfd_link_relocatable (info))
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);
1792 rel_end = relocs + sec->reloc_count;
1793 for (rel = relocs; rel < rel_end; rel++)
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;
1800 r_type = ELF32_R_TYPE (rel->r_info);
1802 if (r_type >= (int) R_ARC_max)
1804 bfd_set_error (bfd_error_bad_value);
1807 howto = arc_elf_howto (r_type);
1810 && (is_reloc_for_GOT (howto) == TRUE
1811 || is_reloc_for_TLS (howto) == TRUE))
1813 dynobj = elf_hash_table (info)->dynobj = abfd;
1814 if (! _bfd_elf_create_got_section (abfd, info))
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. */
1822 else /* Global one. */
1823 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
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))
1842 name = h->root.root.string;
1844 /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); */
1846 (*_bfd_error_handler)
1848 %B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
1850 arc_elf_howto (r_type)->name,
1852 bfd_set_error (bfd_error_bad_value);
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. */
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)
1869 && (!info->symbolic || !h->def_regular))))
1873 sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
1881 sreloc->size += sizeof (Elf32_External_Rela);
1888 if (is_reloc_for_PLT (howto) == TRUE)
1896 if (is_reloc_for_GOT (howto) == TRUE)
1901 if (local_got_ents[r_symndx] == NULL)
1904 ADD_SYMBOL_REF_SEC_AND_RELOC (got,
1905 bfd_link_pic (info),
1907 new_got_entry_to_list (&(local_got_ents[r_symndx]),
1908 GOT_NORMAL, offset, TLS_GOT_NONE);
1913 /* Global symbol. */
1914 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1915 if (h->got.glist == NULL)
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);
1925 if (is_reloc_for_TLS (howto) == TRUE)
1927 enum tls_type_e type = GOT_UNKNOWN;
1931 case R_ARC_TLS_GD_GOT:
1934 case R_ARC_TLS_IE_GOT:
1941 struct got_entry **list = NULL;
1943 list = &(h->got.glist);
1945 list = &(local_got_ents[r_symndx]);
1947 if (type != GOT_UNKNOWN && !symbol_has_entry_of_type (*list, type))
1949 enum tls_got_entries entries = TLS_GOT_NONE;
1951 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1953 if (type == GOT_TLS_GD)
1955 bfd_vma ATTRIBUTE_UNUSED notneeded =
1956 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1957 entries = TLS_GOT_MOD_AND_OFF;
1960 if (entries == TLS_GOT_NONE)
1961 entries = TLS_GOT_OFF;
1963 new_got_entry_to_list (list, type, offset, entries);
1971 #define ELF_DYNAMIC_INTERPRETER "/sbin/ld-uClibc.so"
1973 static struct plt_version_t *
1974 arc_get_plt_version (struct bfd_link_info *info)
1978 for (i = 0; i < 1; i++)
1980 ARC_DEBUG ("%d: size1 = %d, size2 = %d\n", i,
1981 plt_versions[i].entry_size,
1982 plt_versions[i].elem_size);
1985 if (bfd_get_mach (info->output_bfd) == bfd_mach_arc_arcv2)
1987 if (bfd_link_pic (info))
1988 return &(plt_versions[ELF_ARCV2_PIC]);
1990 return &(plt_versions[ELF_ARCV2_ABS]);
1994 if (bfd_link_pic (info))
1995 return &(plt_versions[ELF_ARC_PIC]);
1997 return &(plt_versions[ELF_ARC_ABS]);
2002 add_symbol_to_plt (struct bfd_link_info *info)
2004 struct elf_link_hash_table *htab = elf_hash_table (info);
2007 struct plt_version_t *plt_data = arc_get_plt_version (info);
2009 /* If this is the first .plt entry, make room for the special first
2011 if (htab->splt->size == 0)
2012 htab->splt->size += plt_data->entry_size;
2014 ret = htab->splt->size;
2016 htab->splt->size += plt_data->elem_size;
2017 ARC_DEBUG ("PLT_SIZE = %d\n", htab->splt->size);
2019 htab->sgotplt->size += 4;
2020 htab->srelplt->size += sizeof (Elf32_External_Rela);
2025 #define PLT_DO_RELOCS_FOR_ENTRY(ABFD, DS, RELOCS) \
2026 plt_do_relocs_for_symbol (ABFD, DS, RELOCS, 0, 0)
2029 plt_do_relocs_for_symbol (bfd *abfd,
2030 struct elf_link_hash_table *htab,
2031 const struct plt_reloc *reloc,
2033 bfd_vma symbol_got_offset)
2035 while (SYM_ONLY (reloc->symbol) != LAST_RELOC)
2037 bfd_vma relocation = 0;
2039 switch (SYM_ONLY (reloc->symbol))
2043 htab->sgotplt->output_section->vma +
2044 htab->sgotplt->output_offset + symbol_got_offset;
2047 relocation += reloc->addend;
2049 if (IS_RELATIVE (reloc->symbol))
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;
2055 relocation -= htab->splt->output_section->vma
2056 + htab->splt->output_offset
2057 + plt_offset + reloc_offset;
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))
2065 ((relocation & 0xffff0000) >> 16) |
2066 ((relocation & 0xffff) << 16);
2069 switch (reloc->size)
2072 bfd_put_32 (htab->splt->output_section->owner,
2074 htab->splt->contents + plt_offset + reloc->offset);
2078 reloc = &(reloc[1]); /* Jump to next relocation. */
2083 relocate_plt_for_symbol (bfd *output_bfd,
2084 struct bfd_link_info *info,
2085 struct elf_link_hash_entry *h)
2087 struct plt_version_t *plt_data = arc_get_plt_version (info);
2088 struct elf_link_hash_table *htab = elf_hash_table (info);
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;
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",
2097 htab->splt->output_section->vma
2098 + htab->splt->output_offset
2101 htab->sgotplt->output_section->vma
2102 + htab->sgotplt->output_offset
2104 h->root.root.string);
2109 uint16_t *ptr = (uint16_t *) plt_data->elem;
2110 for (i = 0; i < plt_data->elem_size/2; i++)
2112 uint16_t data = ptr[i];
2113 bfd_put_16 (output_bfd,
2115 htab->splt->contents + h->plt.offset + (i*2));
2119 plt_do_relocs_for_symbol (output_bfd, htab,
2120 plt_data->elem_relocs,
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);
2130 /* TODO: Fill in the entry in the .rela.plt section. */
2132 Elf_Internal_Rela rel;
2135 rel.r_offset = (htab->sgotplt->output_section->vma
2136 + htab->sgotplt->output_offset
2140 BFD_ASSERT (h->dynindx != -1);
2141 rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_JMP_SLOT);
2143 loc = htab->srelplt->contents;
2144 loc += plt_index * sizeof (Elf32_External_Rela); /* relA */
2145 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2150 relocate_plt_for_entry (bfd *abfd,
2151 struct bfd_link_info *info)
2153 struct plt_version_t *plt_data = arc_get_plt_version (info);
2154 struct elf_link_hash_table *htab = elf_hash_table (info);
2158 uint16_t *ptr = (uint16_t *) plt_data->entry;
2159 for (i = 0; i < plt_data->entry_size/2; i++)
2161 uint16_t data = ptr[i];
2164 htab->splt->contents + (i*2));
2167 PLT_DO_RELOCS_FOR_ENTRY (abfd, htab, plt_data->entry_relocs);
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
2177 elf_arc_adjust_dynamic_symbol (struct bfd_link_info *info,
2178 struct elf_link_hash_entry *h)
2181 bfd *dynobj = (elf_hash_table (info))->dynobj;
2182 struct elf_link_hash_table *htab = elf_hash_table (info);
2184 if (h->type == STT_FUNC
2185 || h->type == STT_GNU_IFUNC
2186 || h->needs_plt == 1)
2188 if (!bfd_link_pic (info) && !h->def_dynamic && !h->ref_dynamic)
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
2195 BFD_ASSERT (h->needs_plt);
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))
2204 if (bfd_link_pic (info)
2205 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
2207 bfd_vma loc = add_symbol_to_plt (info);
2209 if (!bfd_link_pic (info) && !h->def_regular)
2211 h->root.u.def.section = htab->splt;
2212 h->root.u.def.value = loc;
2214 h->plt.offset = loc;
2218 h->plt.offset = (bfd_vma) -1;
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)
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;
2236 /* This is a reference to a symbol defined by a dynamic object which
2237 is not a function. */
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))
2246 /* If there are no non-GOT references, we do not need a copy
2248 if (!h->non_got_ref)
2251 /* If -z nocopyreloc was given, we won't generate them either. */
2252 if (info->nocopyreloc)
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. */
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)
2279 srel = bfd_get_section_by_name (dynobj, ".rela.bss");
2280 BFD_ASSERT (srel != NULL);
2281 srel->size += sizeof (Elf32_External_Rela);
2285 s = bfd_get_section_by_name (dynobj, ".dynbss");
2286 BFD_ASSERT (s != NULL);
2288 return _bfd_elf_adjust_dynamic_copy (info, h, s);
2291 /* Function : elf_arc_finish_dynamic_symbol
2292 Brief : Finish up dynamic symbol handling. We set the
2293 contents of various dynamic sections here.
2298 Returns : True/False as the return status. */
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)
2306 if (h->plt.offset != (bfd_vma) -1)
2308 relocate_plt_for_symbol (output_bfd, info, h);
2310 if (!h->def_regular)
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;
2318 if (h->got.glist != NULL)
2320 struct got_entry *list = h->got.glist;
2322 /* Traverse the list of got entries for this symbol. */
2325 bfd_vma got_offset = h->got.glist->offset;
2327 if (list->type == GOT_NORMAL
2328 && list->created_dyn_relocation == FALSE)
2330 if (bfd_link_pic (info)
2331 && (info->symbolic || h->dynindx == -1)
2334 ADD_RELA (output_bfd, got, got_offset, 0, R_ARC_RELATIVE, 0);
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)
2341 ADD_RELA (output_bfd, got, got_offset, h->dynindx,
2344 list->created_dyn_relocation = TRUE;
2346 else if (list->existing_entries != TLS_GOT_NONE)
2348 struct elf_link_hash_table *htab = elf_hash_table (info);
2349 enum tls_got_entries e = list->existing_entries;
2351 BFD_ASSERT (list->type != GOT_TLS_GD
2352 || list->existing_entries == TLS_GOT_MOD_AND_OFF);
2354 bfd_vma dynindx = h->dynindx == -1 ? 0 : h->dynindx;
2355 if (e == TLS_GOT_MOD_AND_OFF || e == TLS_GOT_MOD)
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",
2363 htab->sgot->output_section->vma
2364 + htab->sgot->output_offset + got_offset,
2367 if (e == TLS_GOT_MOD_AND_OFF || e == TLS_GOT_OFF)
2370 if (list->type == GOT_TLS_IE)
2371 addend = bfd_get_32 (output_bfd,
2372 htab->sgot->contents + got_offset);
2374 ADD_RELA (output_bfd, got,
2375 got_offset + (e == TLS_GOT_MOD_AND_OFF ? 4 : 0),
2377 (list->type == GOT_TLS_IE ?
2378 R_ARC_TLS_TPOFF : R_ARC_TLS_DTPOFF),
2381 ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2382 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2385 htab->sgot->output_section->vma
2386 + htab->sgot->output_offset + got_offset,
2394 h->got.glist = NULL;
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);
2404 bfd_get_section_by_name (h->root.u.def.section->owner,
2407 bfd_byte * loc = srelbss->contents
2408 + (srelbss->reloc_count * sizeof (Elf32_External_Rela));
2409 srelbss->reloc_count++;
2411 Elf_Internal_Rela rel;
2413 rel.r_offset = rel_offset;
2415 BFD_ASSERT (h->dynindx != -1);
2416 rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_COPY);
2418 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
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;
2430 #define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION) \
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); \
2439 /* Function : elf_arc_finish_dynamic_sections
2440 Brief : Finish up the dynamic sections handling.
2445 Returns : True/False as the return status. */
2448 elf_arc_finish_dynamic_sections (bfd * output_bfd,
2449 struct bfd_link_info *info)
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;
2457 Elf32_External_Dyn *dyncon, *dynconend;
2459 dyncon = (Elf32_External_Dyn *) ds.sdyn->contents;
2461 (Elf32_External_Dyn *) (ds.sdyn->contents + ds.sdyn->size);
2462 for (; dyncon < dynconend; dyncon++)
2464 Elf_Internal_Dyn internal_dyn;
2465 bfd_boolean do_it = FALSE;
2467 struct elf_link_hash_entry *h = NULL;
2470 bfd_elf32_swap_dyn_in (dynobj, dyncon, &internal_dyn);
2472 switch (internal_dyn.d_tag)
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")
2487 /* In case the dynamic symbols should be updated with a symbol. */
2489 && (h->root.type == bfd_link_hash_defined
2490 || h->root.type == bfd_link_hash_defweak))
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)
2498 internal_dyn.d_un.d_val +=
2499 (asec_ptr->output_section->vma +
2500 asec_ptr->output_offset);
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;
2510 else if (s != NULL) /* With a section information. */
2512 switch (internal_dyn.d_tag)
2519 internal_dyn.d_un.d_ptr = (s->output_section->vma
2520 + s->output_offset);
2525 internal_dyn.d_un.d_val = s->size;
2531 internal_dyn.d_un.d_val -= s->size;
2541 bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon);
2544 if (htab->splt->size > 0)
2546 relocate_plt_for_entry (output_bfd, info);
2549 /* TODO: Validate this. */
2550 elf_section_data (htab->srelplt->output_section)->this_hdr.sh_entsize
2554 /* Fill in the first three entries in the global offset table. */
2557 if (htab->sgot->size > 0 || htab->sgotplt->size > 0)
2559 if (ds.sdyn == NULL)
2560 bfd_put_32 (output_bfd, (bfd_vma) 0,
2561 htab->sgotplt->contents);
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);
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)) \
2581 /* Set the sizes of the dynamic sections. */
2583 elf_arc_size_dynamic_sections (bfd * output_bfd,
2584 struct bfd_link_info *info)
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);
2593 dynobj = (elf_hash_table (info))->dynobj;
2594 BFD_ASSERT (dynobj != NULL);
2596 if ((elf_hash_table (info))->dynamic_sections_created)
2598 struct elf_link_hash_entry *h;
2600 /* Set the contents of the .interp section to the
2602 if (!bfd_link_pic (info))
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;
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);
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
2626 if (htab->srelgot != NULL)
2627 htab->srelgot->size = 0;
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)
2634 if ((s->flags & SEC_LINKER_CREATED) == 0)
2637 if (strncmp (s->name, ".rela", 5) == 0)
2641 s->flags |= SEC_EXCLUDE;
2645 if (strcmp (s->name, ".rela.plt") != 0)
2647 const char *outname =
2648 bfd_get_section_name (output_bfd,
2649 htab->srelplt->output_section);
2651 asection *target = bfd_get_section_by_name (output_bfd,
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;
2662 /* We use the reloc_count field as a counter if we need to
2663 copy relocs into the output file. */
2667 if (strcmp (s->name, ".dynamic") == 0)
2671 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2673 if (s->contents == NULL && s->size != 0)
2679 /* TODO: Check if this is needed. */
2680 if (!bfd_link_pic (info))
2681 if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
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)
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))
2700 if (reltext_exist == TRUE)
2701 if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
2708 const struct elf_size_info arc_elf32_size_info =
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),
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
2738 #define elf_backend_size_info arc_elf32_size_info
2740 static struct bfd_link_hash_table *
2741 arc_elf_link_hash_table_create (bfd *abfd)
2743 struct elf_link_hash_table *htab;
2745 htab = bfd_zmalloc (sizeof (*htab));
2749 if (!_bfd_elf_link_hash_table_init (htab, abfd,
2750 _bfd_elf_link_hash_newfunc,
2751 sizeof (struct elf_link_hash_entry),
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;
2765 /* Hook called by the linker routine which adds symbols from an object
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)
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;
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
2794 #define bfd_elf32_bfd_link_hash_table_create arc_elf_link_hash_table_create
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
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
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
2810 #define elf_backend_adjust_dynamic_symbol elf_arc_adjust_dynamic_symbol
2811 #define elf_backend_finish_dynamic_symbol elf_arc_finish_dynamic_symbol
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
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
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
2828 #define elf_backend_default_execstack 0
2830 #include "elf32-target.h"