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;
706 #define BFD_DEBUG_PIC(...)
708 struct arc_relocation_data
710 bfd_signed_vma reloc_offset;
711 bfd_signed_vma reloc_addend;
712 bfd_signed_vma got_offset_value;
714 bfd_signed_vma sym_value;
715 asection * sym_section;
717 reloc_howto_type *howto;
719 asection * input_section;
721 bfd_signed_vma sdata_begin_symbol_vma;
722 bfd_boolean sdata_begin_symbol_vma_set;
723 bfd_signed_vma got_symbol_vma;
725 bfd_boolean should_relocate;
727 const char * symbol_name;
731 debug_arc_reloc (struct arc_relocation_data reloc_data)
733 PR_DEBUG ("Reloc type=%s, should_relocate = %s\n",
734 reloc_data.howto->name,
735 reloc_data.should_relocate ? "true" : "false");
736 PR_DEBUG (" offset = 0x%x, addend = 0x%x\n",
737 (unsigned int) reloc_data.reloc_offset,
738 (unsigned int) reloc_data.reloc_addend);
739 PR_DEBUG (" Symbol:\n");
740 PR_DEBUG (" value = 0x%08x\n",
741 (unsigned int) reloc_data.sym_value);
742 if (reloc_data.sym_section != NULL)
744 PR_DEBUG ("IN IF\n");
746 " section name = %s, output_offset 0x%08x",
747 reloc_data.sym_section->name,
748 (unsigned int) reloc_data.sym_section->output_offset);
749 if (reloc_data.sym_section->output_section != NULL)
752 ", output_section->vma = 0x%08x",
753 ((unsigned int) reloc_data.sym_section->output_section->vma));
760 PR_DEBUG ( " symbol section is NULL\n");
763 PR_DEBUG ( " Input_section:\n");
764 if (reloc_data.input_section != NULL)
767 " section name = %s, output_offset 0x%08x, output_section->vma = 0x%08x\n",
768 reloc_data.input_section->name,
769 (unsigned int) reloc_data.input_section->output_offset,
770 (unsigned int) reloc_data.input_section->output_section->vma);
771 PR_DEBUG ( " changed_address = 0x%08x\n",
772 (unsigned int) (reloc_data.input_section->output_section->vma +
773 reloc_data.input_section->output_offset +
774 reloc_data.reloc_offset));
778 PR_DEBUG ( " input section is NULL\n");
783 middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
788 ((insn & 0xffff0000) >> 16) |
789 ((insn & 0xffff) << 16);
794 /* This function is called for relocations that are otherwise marked as NOT
795 requiring overflow checks. In here we perform non-standard checks of
796 the relocation value. */
798 static inline bfd_reloc_status_type
799 arc_special_overflow_checks (const struct arc_relocation_data reloc_data,
800 bfd_signed_vma relocation,
801 struct bfd_link_info *info ATTRIBUTE_UNUSED)
803 switch (reloc_data.howto->type)
805 case R_ARC_NPS_CMEM16:
806 if (((relocation >> 16) & 0xffff) != NPS_CMEM_HIGH_VALUE)
808 if (reloc_data.reloc_addend == 0)
809 (*_bfd_error_handler)
810 (_("%B(%A+0x%lx): CMEM relocation to `%s' is invalid, "
811 "16 MSB should be 0x%04x (value is 0x%lx)"),
812 reloc_data.input_section->owner,
813 reloc_data.input_section,
814 reloc_data.reloc_offset,
815 reloc_data.symbol_name,
819 (*_bfd_error_handler)
820 (_("%B(%A+0x%lx): CMEM relocation to `%s+0x%lx' is invalid, "
821 "16 MSB should be 0x%04x (value is 0x%lx)"),
822 reloc_data.input_section->owner,
823 reloc_data.input_section,
824 reloc_data.reloc_offset,
825 reloc_data.symbol_name,
826 reloc_data.reloc_addend,
829 return bfd_reloc_overflow;
840 #define ME(reloc) (reloc)
842 #define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") != NULL) \
843 && (!bfd_big_endian (BFD)))
845 #define S ((bfd_signed_vma) (reloc_data.sym_value \
846 + (reloc_data.sym_section->output_section != NULL ? \
847 (reloc_data.sym_section->output_offset \
848 + reloc_data.sym_section->output_section->vma) : 0)))
849 #define L ((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 A (reloc_data.reloc_addend)
855 #define G (reloc_data.got_offset_value)
856 #define GOT (reloc_data.got_symbol_vma)
857 #define GOT_BEGIN (htab->sgot->output_section->vma)
860 /* P: relative offset to PCL The offset should be to the
861 current location aligned to 32 bits. */
862 #define P ((bfd_signed_vma) ( \
864 (reloc_data.input_section->output_section != NULL ? \
865 reloc_data.input_section->output_section->vma : 0) \
866 + reloc_data.input_section->output_offset \
867 + (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0))) \
869 #define PDATA ((bfd_signed_vma) ( \
870 (reloc_data.input_section->output_section->vma \
871 + reloc_data.input_section->output_offset \
872 + (reloc_data.reloc_offset))))
873 #define SECTSTART (bfd_signed_vma) (reloc_data.input_section->output_offset)
874 #define _SDA_BASE_ (bfd_signed_vma) (reloc_data.sdata_begin_symbol_vma)
875 #define TLS_REL (bfd_signed_vma) \
876 ((elf_hash_table (info))->tls_sec->output_section->vma)
882 #define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA, TYPE) \
884 asection *sym_section = reloc_data.sym_section; \
885 asection *input_section = reloc_data.input_section; \
886 ARC_DEBUG ("RELOC_TYPE = " TYPE "\n"); \
887 ARC_DEBUG ("FORMULA = " FORMULA "\n"); \
888 ARC_DEBUG ("S = 0x%x\n", S); \
889 ARC_DEBUG ("A = 0x%x\n", A); \
890 ARC_DEBUG ("L = 0x%x\n", L); \
891 if (sym_section->output_section != NULL) \
893 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
894 sym_section->output_section->vma + sym_section->output_offset); \
898 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
900 if (input_section->output_section != NULL) \
902 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
903 input_section->output_section->vma + input_section->output_offset); \
907 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
909 ARC_DEBUG ("PCL = 0x%x\n", P); \
910 ARC_DEBUG ("P = 0x%x\n", P); \
911 ARC_DEBUG ("G = 0x%x\n", G); \
912 ARC_DEBUG ("SDA_OFFSET = 0x%x\n", _SDA_BASE_); \
913 ARC_DEBUG ("SDA_SET = %d\n", reloc_data.sdata_begin_symbol_vma_set); \
914 ARC_DEBUG ("GOT_OFFSET = 0x%x\n", GOT); \
915 ARC_DEBUG ("relocation = 0x%08x\n", relocation); \
916 ARC_DEBUG ("before = 0x%08x\n", (unsigned int) insn); \
917 ARC_DEBUG ("data = 0x%08x (%u) (%d)\n", (unsigned int) relocation, (unsigned int) relocation, (int) relocation); \
920 #define PRINT_DEBUG_RELOC_INFO_AFTER \
922 ARC_DEBUG ("after = 0x%08x\n", (unsigned int) insn); \
925 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
928 bfd_signed_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
929 relocation = FORMULA ; \
930 PRINT_DEBUG_RELOC_INFO_BEFORE (#FORMULA, #TYPE); \
931 insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
932 insn = (* get_replace_function (abfd, TYPE)) (insn, relocation); \
933 insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
934 PRINT_DEBUG_RELOC_INFO_AFTER \
938 static bfd_reloc_status_type
939 arc_do_relocation (bfd_byte * contents,
940 struct arc_relocation_data reloc_data,
941 struct bfd_link_info *info)
943 bfd_signed_vma relocation = 0;
945 bfd_vma orig_insn ATTRIBUTE_UNUSED;
946 bfd * abfd = reloc_data.input_section->owner;
947 struct elf_link_hash_table *htab ATTRIBUTE_UNUSED = elf_hash_table (info);
948 bfd_reloc_status_type flag;
950 if (reloc_data.should_relocate == FALSE)
953 switch (reloc_data.howto->size)
956 insn = arc_bfd_get_32 (abfd,
957 contents + reloc_data.reloc_offset,
958 reloc_data.input_section);
961 insn = arc_bfd_get_16 (abfd,
962 contents + reloc_data.reloc_offset,
963 reloc_data.input_section);
966 insn = arc_bfd_get_8 (abfd,
967 contents + reloc_data.reloc_offset,
968 reloc_data.input_section);
978 switch (reloc_data.howto->type)
980 #include "elf/arc-reloc.def"
987 /* Check for relocation overflow. */
988 if (reloc_data.howto->complain_on_overflow != complain_overflow_dont)
989 flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
990 reloc_data.howto->bitsize,
991 reloc_data.howto->rightshift,
992 bfd_arch_bits_per_address (abfd),
995 flag = arc_special_overflow_checks (reloc_data, relocation, info);
997 #undef DEBUG_ARC_RELOC
998 #define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
999 if (flag != bfd_reloc_ok)
1001 PR_DEBUG ( "Relocation overflows !!!!\n");
1003 DEBUG_ARC_RELOC (reloc_data);
1006 "Relocation value = signed -> %d, unsigned -> %u"
1007 ", hex -> (0x%08x)\n",
1009 (unsigned int) relocation,
1010 (unsigned int) relocation);
1013 #undef DEBUG_ARC_RELOC
1014 #define DEBUG_ARC_RELOC(A)
1016 /* Write updated instruction back to memory. */
1017 switch (reloc_data.howto->size)
1020 arc_bfd_put_32 (abfd, insn,
1021 contents + reloc_data.reloc_offset,
1022 reloc_data.input_section);
1025 arc_bfd_put_16 (abfd, insn,
1026 contents + reloc_data.reloc_offset,
1027 reloc_data.input_section);
1030 arc_bfd_put_8 (abfd, insn,
1031 contents + reloc_data.reloc_offset,
1032 reloc_data.input_section);
1035 ARC_DEBUG ("size = %d\n", reloc_data.howto->size);
1040 return bfd_reloc_ok;
1055 #undef ARC_RELOC_HOWTO
1057 static struct got_entry **
1058 arc_get_local_got_ents (bfd * abfd)
1060 static struct got_entry **local_got_ents = NULL;
1062 if (local_got_ents == NULL)
1065 Elf_Internal_Shdr *symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1067 size = symtab_hdr->sh_info * sizeof (bfd_vma);
1068 local_got_ents = (struct got_entry **)
1069 bfd_alloc (abfd, sizeof(struct got_entry *) * size);
1070 if (local_got_ents == NULL)
1073 memset (local_got_ents, 0, sizeof(struct got_entry *) * size);
1074 elf_local_got_ents (abfd) = local_got_ents;
1077 return local_got_ents;
1080 /* Relocate an arc ELF section.
1081 Function : elf_arc_relocate_section
1082 Brief : Relocate an arc section, by handling all the relocations
1083 appearing in that section.
1084 Args : output_bfd : The bfd being written to.
1085 info : Link information.
1086 input_bfd : The input bfd.
1087 input_section : The section being relocated.
1088 contents : contents of the section being relocated.
1089 relocs : List of relocations in the section.
1090 local_syms : is a pointer to the swapped in local symbols.
1091 local_section : is an array giving the section in the input file
1092 corresponding to the st_shndx field of each
1095 elf_arc_relocate_section (bfd * output_bfd,
1096 struct bfd_link_info * info,
1098 asection * input_section,
1099 bfd_byte * contents,
1100 Elf_Internal_Rela * relocs,
1101 Elf_Internal_Sym * local_syms,
1102 asection ** local_sections)
1104 Elf_Internal_Shdr * symtab_hdr;
1105 struct elf_link_hash_entry ** sym_hashes;
1106 struct got_entry ** local_got_ents;
1107 Elf_Internal_Rela * rel;
1108 Elf_Internal_Rela * relend;
1109 struct elf_link_hash_table *htab = elf_hash_table (info);
1111 symtab_hdr = &((elf_tdata (input_bfd))->symtab_hdr);
1112 sym_hashes = elf_sym_hashes (input_bfd);
1115 relend = relocs + input_section->reloc_count;
1116 for (; rel < relend; rel++)
1118 enum elf_arc_reloc_type r_type;
1119 reloc_howto_type * howto;
1120 unsigned long r_symndx;
1121 struct elf_link_hash_entry * h;
1122 Elf_Internal_Sym * sym;
1124 struct elf_link_hash_entry *h2;
1126 struct arc_relocation_data reloc_data =
1130 .got_offset_value = 0,
1132 .sym_section = NULL,
1134 .input_section = NULL,
1135 .sdata_begin_symbol_vma = 0,
1136 .sdata_begin_symbol_vma_set = FALSE,
1137 .got_symbol_vma = 0,
1138 .should_relocate = FALSE
1141 r_type = ELF32_R_TYPE (rel->r_info);
1143 if (r_type >= (int) R_ARC_max)
1145 bfd_set_error (bfd_error_bad_value);
1148 howto = &elf_arc_howto_table[r_type];
1150 r_symndx = ELF32_R_SYM (rel->r_info);
1152 /* If we are generating another .o file and the symbol in not
1153 local, skip this relocation. */
1154 if (bfd_link_relocatable (info))
1156 /* This is a relocateable link. We don't have to change
1157 anything, unless the reloc is against a section symbol,
1158 in which case we have to adjust according to where the
1159 section symbol winds up in the output section. */
1161 /* Checks if this is a local symbol and thus the reloc
1162 might (will??) be against a section symbol. */
1163 if (r_symndx < symtab_hdr->sh_info)
1165 sym = local_syms + r_symndx;
1166 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1168 sec = local_sections[r_symndx];
1170 /* for RELA relocs.Just adjust the addend
1171 value in the relocation entry. */
1172 rel->r_addend += sec->output_offset + sym->st_value;
1175 PR_DEBUG ("local symbols reloc "
1176 "(section=%d %s) seen in %s\n",
1178 local_sections[r_symndx]->name,
1179 __PRETTY_FUNCTION__)
1187 h2 = elf_link_hash_lookup (elf_hash_table (info), "__SDATA_BEGIN__",
1188 FALSE, FALSE, TRUE);
1190 if (reloc_data.sdata_begin_symbol_vma_set == FALSE
1191 && h2 != NULL && h2->root.type != bfd_link_hash_undefined
1192 && h2->root.u.def.section->output_section != NULL)
1193 /* TODO: Verify this condition. */
1195 reloc_data.sdata_begin_symbol_vma =
1196 (h2->root.u.def.value +
1197 h2->root.u.def.section->output_section->vma);
1198 reloc_data.sdata_begin_symbol_vma_set = TRUE;
1201 reloc_data.input_section = input_section;
1202 reloc_data.howto = howto;
1203 reloc_data.reloc_offset = rel->r_offset;
1204 reloc_data.reloc_addend = rel->r_addend;
1206 /* This is a final link. */
1211 if (r_symndx < symtab_hdr->sh_info) /* A local symbol. */
1213 local_got_ents = arc_get_local_got_ents (output_bfd);
1214 struct got_entry *entry = local_got_ents[r_symndx];
1216 sym = local_syms + r_symndx;
1217 sec = local_sections[r_symndx];
1219 reloc_data.sym_value = sym->st_value;
1220 reloc_data.sym_section = sec;
1221 reloc_data.symbol_name =
1222 bfd_elf_string_from_elf_section (input_bfd,
1223 symtab_hdr->sh_link,
1226 /* Mergeable section handling. */
1227 if ((sec->flags & SEC_MERGE)
1228 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1232 rel->r_addend = _bfd_elf_rel_local_sym (output_bfd, sym,
1233 &msec, rel->r_addend);
1234 rel->r_addend -= (sec->output_section->vma
1235 + sec->output_offset
1237 rel->r_addend += msec->output_section->vma + msec->output_offset;
1239 reloc_data.reloc_addend = rel->r_addend;
1242 if ((is_reloc_for_GOT (howto)
1243 || is_reloc_for_TLS (howto)) && entry != NULL)
1245 if (is_reloc_for_TLS (howto))
1246 while (entry->type == GOT_NORMAL && entry->next != NULL)
1247 entry = entry->next;
1249 if (is_reloc_for_GOT (howto))
1250 while (entry->type != GOT_NORMAL && entry->next != NULL)
1251 entry = entry->next;
1253 if (entry->type == GOT_TLS_GD && entry->processed == FALSE)
1255 bfd_vma sym_vma = sym->st_value
1256 + sec->output_section->vma
1257 + sec->output_offset;
1259 /* Create dynamic relocation for local sym. */
1260 ADD_RELA (output_bfd, got, entry->offset, 0,
1261 R_ARC_TLS_DTPMOD, 0);
1262 ADD_RELA (output_bfd, got, entry->offset+4, 0,
1263 R_ARC_TLS_DTPOFF, 0);
1265 bfd_vma sec_vma = sec->output_section->vma
1266 + sec->output_offset;
1267 bfd_put_32 (output_bfd, sym_vma - sec_vma,
1268 htab->sgot->contents + entry->offset + 4);
1270 ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_GD value "
1271 "= 0x%x @ 0x%x, for symbol %s\n",
1273 htab->sgot->contents + entry->offset + 4,
1276 entry->processed = TRUE;
1278 if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
1280 bfd_vma sym_vma = sym->st_value
1281 + sec->output_section->vma
1282 + sec->output_offset;
1283 bfd_vma sec_vma = htab->tls_sec->output_section->vma;
1284 bfd_put_32 (output_bfd, sym_vma - sec_vma,
1285 htab->sgot->contents + entry->offset);
1286 /* TODO: Check if this type of relocs is the cause
1287 for all the ARC_NONE dynamic relocs. */
1289 ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_IE value = "
1290 "0x%x @ 0x%x, for symbol %s\n",
1292 htab->sgot->contents + entry->offset,
1295 entry->processed = TRUE;
1297 if (entry->type == GOT_NORMAL && entry->processed == FALSE)
1299 bfd_vma sec_vma = reloc_data.sym_section->output_section->vma
1300 + reloc_data.sym_section->output_offset;
1302 bfd_put_32 (output_bfd, reloc_data.sym_value + sec_vma,
1303 htab->sgot->contents + entry->offset);
1305 ARC_DEBUG ("arc_info: PATCHED: 0x%08x @ 0x%08x for "
1306 "sym %s in got offset 0x%x\n",
1307 reloc_data.sym_value + sec_vma,
1308 htab->sgot->output_section->vma
1309 + htab->sgot->output_offset + entry->offset,
1312 entry->processed = TRUE;
1315 reloc_data.got_offset_value = entry->offset;
1316 ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
1317 "vma = 0x%x for symbol %s\n",
1318 entry->type, entry->offset,
1319 htab->sgot->output_section->vma
1320 + htab->sgot->output_offset + entry->offset,
1324 BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1325 if (htab->sgot != NULL)
1326 reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1327 + htab->sgot->output_offset;
1329 reloc_data.should_relocate = TRUE;
1331 else /* Global symbol. */
1333 /* Get the symbol's entry in the symtab. */
1334 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1336 while (h->root.type == bfd_link_hash_indirect
1337 || h->root.type == bfd_link_hash_warning)
1338 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1340 BFD_ASSERT ((h->dynindx == -1) >= (h->forced_local != 0));
1341 reloc_data.symbol_name = h->root.root.string;
1342 /* If we have encountered a definition for this symbol. */
1343 if (h->root.type == bfd_link_hash_defined
1344 || h->root.type == bfd_link_hash_defweak)
1346 reloc_data.sym_value = h->root.u.def.value;
1347 reloc_data.sym_section = h->root.u.def.section;
1349 reloc_data.should_relocate = TRUE;
1351 if (is_reloc_for_GOT (howto) && !bfd_link_pic (info))
1353 /* TODO: Change it to use arc_do_relocation with
1354 ARC_32 reloc. Try to use ADD_RELA macro. */
1355 bfd_vma relocation =
1356 reloc_data.sym_value + reloc_data.reloc_addend
1357 + (reloc_data.sym_section->output_section != NULL ?
1358 (reloc_data.sym_section->output_offset
1359 + reloc_data.sym_section->output_section->vma)
1362 BFD_ASSERT (h->got.glist);
1363 bfd_vma got_offset = h->got.glist->offset;
1364 bfd_put_32 (output_bfd, relocation,
1365 htab->sgot->contents + got_offset);
1367 if (is_reloc_for_PLT (howto) && h->plt.offset != (bfd_vma) -1)
1369 /* TODO: This is repeated up here. */
1370 reloc_data.sym_value = h->plt.offset;
1371 reloc_data.sym_section = htab->splt;
1374 else if (h->root.type == bfd_link_hash_undefweak)
1376 /* Is weak symbol and has no definition. */
1377 if (is_reloc_for_GOT (howto))
1379 reloc_data.sym_value = h->root.u.def.value;
1380 reloc_data.sym_section = htab->sgot;
1381 reloc_data.should_relocate = TRUE;
1383 else if (is_reloc_for_PLT (howto)
1384 && h->plt.offset != (bfd_vma) -1)
1386 /* TODO: This is repeated up here. */
1387 reloc_data.sym_value = h->plt.offset;
1388 reloc_data.sym_section = htab->splt;
1389 reloc_data.should_relocate = TRUE;
1396 if (is_reloc_for_GOT (howto))
1398 reloc_data.sym_value = h->root.u.def.value;
1399 reloc_data.sym_section = htab->sgot;
1401 reloc_data.should_relocate = TRUE;
1403 else if (is_reloc_for_PLT (howto))
1405 /* Fail if it is linking for PIE and the symbol is
1407 if (bfd_link_executable (info)
1408 && !(*info->callbacks->undefined_symbol)
1409 (info, h->root.root.string, input_bfd, input_section,
1410 rel->r_offset, TRUE))
1414 reloc_data.sym_value = h->plt.offset;
1415 reloc_data.sym_section = htab->splt;
1417 reloc_data.should_relocate = TRUE;
1419 else if (!bfd_link_pic (info)
1420 && !(*info->callbacks->undefined_symbol)
1421 (info, h->root.root.string, input_bfd, input_section,
1422 rel->r_offset, TRUE))
1428 if (h->got.glist != NULL)
1430 struct got_entry *entry = h->got.glist;
1432 if (is_reloc_for_GOT (howto) || is_reloc_for_TLS (howto))
1434 if (! elf_hash_table (info)->dynamic_sections_created
1435 || (bfd_link_pic (info)
1436 && SYMBOL_REFERENCES_LOCAL (info, h)))
1438 reloc_data.sym_value = h->root.u.def.value;
1439 reloc_data.sym_section = h->root.u.def.section;
1441 if (is_reloc_for_TLS (howto))
1442 while (entry->type == GOT_NORMAL && entry->next != NULL)
1443 entry = entry->next;
1445 if (entry->processed == FALSE
1446 && (entry->type == GOT_TLS_GD
1447 || entry->type == GOT_TLS_IE))
1449 bfd_vma sym_value = h->root.u.def.value
1450 + h->root.u.def.section->output_section->vma
1451 + h->root.u.def.section->output_offset;
1454 elf_hash_table (info)->tls_sec->output_section->vma;
1456 bfd_put_32 (output_bfd,
1457 sym_value - sec_vma,
1458 htab->sgot->contents + entry->offset
1459 + (entry->existing_entries == TLS_GOT_MOD_AND_OFF ? 4 : 0));
1461 ARC_DEBUG ("arc_info: FIXED -> %s value = 0x%x "
1462 "@ 0x%x, for symbol %s\n",
1463 (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
1465 sym_value - sec_vma,
1466 htab->sgot->contents + entry->offset
1467 + (entry->existing_entries == TLS_GOT_MOD_AND_OFF ? 4 : 0),
1468 h->root.root.string);
1470 entry->processed = TRUE;
1473 if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
1475 bfd_vma sec_vma = htab->tls_sec->output_section->vma;
1476 bfd_put_32 (output_bfd,
1477 reloc_data.sym_value - sec_vma,
1478 htab->sgot->contents + entry->offset);
1481 if (entry->type == GOT_NORMAL && entry->processed == FALSE)
1484 reloc_data.sym_section->output_section->vma
1485 + reloc_data.sym_section->output_offset;
1487 if (h->root.type != bfd_link_hash_undefweak)
1489 bfd_put_32 (output_bfd,
1490 reloc_data.sym_value + sec_vma,
1491 htab->sgot->contents + entry->offset);
1493 ARC_DEBUG ("arc_info: PATCHED: 0x%08x "
1494 "@ 0x%08x for sym %s in got offset 0x%x\n",
1495 reloc_data.sym_value + sec_vma,
1496 htab->sgot->output_section->vma
1497 + htab->sgot->output_offset + entry->offset,
1498 h->root.root.string,
1503 ARC_DEBUG ("arc_info: PATCHED: NOT_PATCHED "
1504 "@ 0x%08x for sym %s in got offset 0x%x "
1506 htab->sgot->output_section->vma
1507 + htab->sgot->output_offset + entry->offset,
1508 h->root.root.string,
1512 entry->processed = TRUE;
1517 reloc_data.got_offset_value = entry->offset;
1519 ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
1520 "vma = 0x%x for symbol %s\n",
1521 entry->type, entry->offset,
1522 htab->sgot->output_section->vma
1523 + htab->sgot->output_offset + entry->offset,
1524 h->root.root.string);
1527 BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1528 if (htab->sgot != NULL)
1529 reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1530 + htab->sgot->output_offset;
1538 case R_ARC_32_PCREL:
1539 if (bfd_link_pic (info) && !bfd_link_pie (info)
1540 && ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1543 && (!info->symbolic || !h->def_regular))))
1545 Elf_Internal_Rela outrel;
1547 bfd_boolean skip = FALSE;
1548 bfd_boolean relocate = FALSE;
1549 asection *sreloc = _bfd_elf_get_dynamic_reloc_section
1550 (input_bfd, input_section,
1553 BFD_ASSERT (sreloc != NULL);
1555 outrel.r_offset = _bfd_elf_section_offset (output_bfd,
1559 if (outrel.r_offset == (bfd_vma) -1)
1562 outrel.r_addend = rel->r_addend;
1563 outrel.r_offset += (input_section->output_section->vma
1564 + input_section->output_offset);
1568 memset (&outrel, 0, sizeof outrel);
1571 else if (r_type == R_ARC_PC32
1572 || r_type == R_ARC_32_PCREL)
1574 BFD_ASSERT (h != NULL);
1575 if ((input_section->flags & SEC_ALLOC) != 0)
1580 BFD_ASSERT (h->dynindx != -1);
1581 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1585 /* Handle local symbols, they either do not have a
1586 global hash table entry (h == NULL), or are
1587 forced local due to a version script
1588 (h->forced_local), or the third condition is
1589 legacy, it appears to say something like, for
1590 links where we are pre-binding the symbols, or
1591 there's not an entry for this symbol in the
1592 dynamic symbol table, and it's a regular symbol
1593 not defined in a shared object, then treat the
1594 symbol as local, resolve it now. */
1596 || ((info->symbolic || h->dynindx == -1)
1601 /* outrel.r_addend = 0; */
1602 outrel.r_info = ELF32_R_INFO (0, R_ARC_RELATIVE);
1606 BFD_ASSERT (h->dynindx != -1);
1608 /* This type of dynamic relocation cannot be created
1609 for code sections. */
1610 BFD_ASSERT ((input_section->flags & SEC_CODE) == 0);
1612 if ((input_section->flags & SEC_ALLOC) != 0)
1617 BFD_ASSERT (h->dynindx != -1);
1618 outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_32);
1622 BFD_ASSERT (sreloc->contents != 0);
1624 loc = sreloc->contents;
1625 loc += sreloc->reloc_count * sizeof (Elf32_External_Rela);
1626 sreloc->reloc_count += 1;
1628 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1630 if (relocate == FALSE)
1638 if (is_reloc_SDA_relative (howto)
1639 && (reloc_data.sdata_begin_symbol_vma_set == FALSE))
1641 (*_bfd_error_handler)
1642 ("Error: Linker symbol __SDATA_BEGIN__ not found");
1643 bfd_set_error (bfd_error_bad_value);
1647 DEBUG_ARC_RELOC (reloc_data);
1649 if (arc_do_relocation (contents, reloc_data, info) != bfd_reloc_ok)
1656 static struct dynamic_sections
1657 arc_create_dynamic_sections (bfd * abfd, struct bfd_link_info *info)
1659 struct elf_link_hash_table *htab;
1661 struct dynamic_sections ds =
1663 .initialized = FALSE,
1673 htab = elf_hash_table (info);
1676 /* Create dynamic sections for relocatable executables so that we
1677 can copy relocations. */
1678 if (! htab->dynamic_sections_created && bfd_link_pic (info))
1680 if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
1684 dynobj = (elf_hash_table (info))->dynobj;
1688 ds.sgot = htab->sgot;
1689 ds.srelgot = htab->srelgot;
1691 ds.sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
1692 ds.srelgotplt = ds.srelplt;
1694 ds.splt = bfd_get_section_by_name (dynobj, ".plt");
1695 ds.srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
1698 if (htab->dynamic_sections_created)
1700 ds.sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
1703 ds.initialized = TRUE;
1708 #define ADD_SYMBOL_REF_SEC_AND_RELOC(SECNAME, COND_FOR_RELOC, H) \
1709 htab->s##SECNAME->size; \
1711 if (COND_FOR_RELOC) \
1713 htab->srel##SECNAME->size += sizeof (Elf32_External_Rela); \
1714 ARC_DEBUG ("arc_info: Added reloc space in " \
1715 #SECNAME " section at " __FILE__ \
1716 ":%d for symbol\n", \
1717 __LINE__, name_for_global_symbol (H)); \
1720 if (h->dynindx == -1 && !h->forced_local) \
1721 if (! bfd_elf_link_record_dynamic_symbol (info, H)) \
1723 htab->s##SECNAME->size += 4; \
1727 elf_arc_check_relocs (bfd * abfd,
1728 struct bfd_link_info * info,
1730 const Elf_Internal_Rela * relocs)
1732 Elf_Internal_Shdr * symtab_hdr;
1733 struct elf_link_hash_entry ** sym_hashes;
1734 struct got_entry ** local_got_ents;
1735 const Elf_Internal_Rela * rel;
1736 const Elf_Internal_Rela * rel_end;
1738 asection * sreloc = NULL;
1739 struct elf_link_hash_table * htab = elf_hash_table (info);
1741 if (bfd_link_relocatable (info))
1744 dynobj = (elf_hash_table (info))->dynobj;
1745 symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1746 sym_hashes = elf_sym_hashes (abfd);
1747 local_got_ents = arc_get_local_got_ents (abfd);
1749 rel_end = relocs + sec->reloc_count;
1750 for (rel = relocs; rel < rel_end; rel++)
1752 enum elf_arc_reloc_type r_type;
1753 reloc_howto_type *howto;
1754 unsigned long r_symndx;
1755 struct elf_link_hash_entry *h;
1757 r_type = ELF32_R_TYPE (rel->r_info);
1759 if (r_type >= (int) R_ARC_max)
1761 bfd_set_error (bfd_error_bad_value);
1764 howto = &elf_arc_howto_table[r_type];
1767 && (is_reloc_for_GOT (howto) == TRUE
1768 || is_reloc_for_TLS (howto) == TRUE))
1770 dynobj = elf_hash_table (info)->dynobj = abfd;
1771 if (! _bfd_elf_create_got_section (abfd, info))
1775 /* Load symbol information. */
1776 r_symndx = ELF32_R_SYM (rel->r_info);
1777 if (r_symndx < symtab_hdr->sh_info) /* Is a local symbol. */
1779 else /* Global one. */
1780 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1786 /* During shared library creation, these relocs should not
1787 appear in a shared library (as memory will be read only
1788 and the dynamic linker can not resolve these. However
1789 the error should not occur for e.g. debugging or
1790 non-readonly sections. */
1791 if (bfd_link_dll (info) && !bfd_link_pie (info)
1792 && (sec->flags & SEC_ALLOC) != 0
1793 && (sec->flags & SEC_READONLY) == 0
1794 && (sec->flags & SEC_CODE) != 0)
1798 name = h->root.root.string;
1800 /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); */
1802 (*_bfd_error_handler)
1804 %B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
1806 arc_elf_howto (r_type)->name,
1808 bfd_set_error (bfd_error_bad_value);
1812 /* In some cases we are not setting the 'non_got_ref'
1813 flag, even though the relocations don't require a GOT
1814 access. We should extend the testing in this area to
1815 ensure that no significant cases are being missed. */
1820 case R_ARC_32_PCREL:
1821 if (bfd_link_pic (info) && !bfd_link_pie (info)
1822 && ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1825 && (!info->symbolic || !h->def_regular))))
1829 sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
1837 sreloc->size += sizeof (Elf32_External_Rela);
1844 if (is_reloc_for_PLT (howto) == TRUE)
1852 if (is_reloc_for_GOT (howto) == TRUE)
1857 if (local_got_ents[r_symndx] == NULL)
1860 ADD_SYMBOL_REF_SEC_AND_RELOC (got,
1861 bfd_link_pic (info),
1863 new_got_entry_to_list (&(local_got_ents[r_symndx]),
1864 GOT_NORMAL, offset, TLS_GOT_NONE);
1869 /* Global symbol. */
1870 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1871 if (h->got.glist == NULL)
1874 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1875 new_got_entry_to_list (&h->got.glist,
1876 GOT_NORMAL, offset, TLS_GOT_NONE);
1881 if (is_reloc_for_TLS (howto) == TRUE)
1883 enum tls_type_e type = GOT_UNKNOWN;
1887 case R_ARC_TLS_GD_GOT:
1890 case R_ARC_TLS_IE_GOT:
1897 struct got_entry **list = NULL;
1899 list = &(h->got.glist);
1901 list = &(local_got_ents[r_symndx]);
1903 if (type != GOT_UNKNOWN && !symbol_has_entry_of_type (*list, type))
1905 enum tls_got_entries entries = TLS_GOT_NONE;
1907 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1909 if (type == GOT_TLS_GD)
1911 bfd_vma ATTRIBUTE_UNUSED notneeded =
1912 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1913 entries = TLS_GOT_MOD_AND_OFF;
1916 if (entries == TLS_GOT_NONE)
1917 entries = TLS_GOT_OFF;
1919 new_got_entry_to_list (list, type, offset, entries);
1927 #define ELF_DYNAMIC_INTERPRETER "/sbin/ld-uClibc.so"
1929 static struct plt_version_t *
1930 arc_get_plt_version (struct bfd_link_info *info)
1934 for (i = 0; i < 1; i++)
1936 ARC_DEBUG ("%d: size1 = %d, size2 = %d\n", i,
1937 plt_versions[i].entry_size,
1938 plt_versions[i].elem_size);
1941 if (bfd_get_mach (info->output_bfd) == bfd_mach_arc_arcv2)
1943 if (bfd_link_pic (info))
1944 return &(plt_versions[ELF_ARCV2_PIC]);
1946 return &(plt_versions[ELF_ARCV2_ABS]);
1950 if (bfd_link_pic (info))
1951 return &(plt_versions[ELF_ARC_PIC]);
1953 return &(plt_versions[ELF_ARC_ABS]);
1958 add_symbol_to_plt (struct bfd_link_info *info)
1960 struct elf_link_hash_table *htab = elf_hash_table (info);
1963 struct plt_version_t *plt_data = arc_get_plt_version (info);
1965 /* If this is the first .plt entry, make room for the special first
1967 if (htab->splt->size == 0)
1968 htab->splt->size += plt_data->entry_size;
1970 ret = htab->splt->size;
1972 htab->splt->size += plt_data->elem_size;
1973 ARC_DEBUG ("PLT_SIZE = %d\n", htab->splt->size);
1975 htab->sgotplt->size += 4;
1976 htab->srelplt->size += sizeof (Elf32_External_Rela);
1981 #define PLT_DO_RELOCS_FOR_ENTRY(ABFD, DS, RELOCS) \
1982 plt_do_relocs_for_symbol (ABFD, DS, RELOCS, 0, 0)
1985 plt_do_relocs_for_symbol (bfd *abfd,
1986 struct elf_link_hash_table *htab,
1987 const struct plt_reloc *reloc,
1989 bfd_vma symbol_got_offset)
1991 while (SYM_ONLY (reloc->symbol) != LAST_RELOC)
1993 bfd_vma relocation = 0;
1995 switch (SYM_ONLY (reloc->symbol))
1999 htab->sgotplt->output_section->vma +
2000 htab->sgotplt->output_offset + symbol_got_offset;
2003 relocation += reloc->addend;
2005 if (IS_RELATIVE (reloc->symbol))
2007 bfd_vma reloc_offset = reloc->offset;
2008 reloc_offset -= (IS_INSN_32 (reloc->symbol)) ? 4 : 0;
2009 reloc_offset -= (IS_INSN_24 (reloc->symbol)) ? 2 : 0;
2011 relocation -= htab->splt->output_section->vma
2012 + htab->splt->output_offset
2013 + plt_offset + reloc_offset;
2016 /* TODO: being ME is not a property of the relocation but of the
2017 section of which is applying the relocation. */
2018 if (IS_MIDDLE_ENDIAN (reloc->symbol) && !bfd_big_endian (abfd))
2021 ((relocation & 0xffff0000) >> 16) |
2022 ((relocation & 0xffff) << 16);
2025 switch (reloc->size)
2028 bfd_put_32 (htab->splt->output_section->owner,
2030 htab->splt->contents + plt_offset + reloc->offset);
2034 reloc = &(reloc[1]); /* Jump to next relocation. */
2039 relocate_plt_for_symbol (bfd *output_bfd,
2040 struct bfd_link_info *info,
2041 struct elf_link_hash_entry *h)
2043 struct plt_version_t *plt_data = arc_get_plt_version (info);
2044 struct elf_link_hash_table *htab = elf_hash_table (info);
2046 bfd_vma plt_index = (h->plt.offset - plt_data->entry_size)
2047 / plt_data->elem_size;
2048 bfd_vma got_offset = (plt_index + 3) * 4;
2050 ARC_DEBUG ("arc_info: PLT_OFFSET = 0x%x, PLT_ENTRY_VMA = 0x%x, \
2051 GOT_ENTRY_OFFSET = 0x%x, GOT_ENTRY_VMA = 0x%x, for symbol %s\n",
2053 htab->splt->output_section->vma
2054 + htab->splt->output_offset
2057 htab->sgotplt->output_section->vma
2058 + htab->sgotplt->output_offset
2060 h->root.root.string);
2065 uint16_t *ptr = (uint16_t *) plt_data->elem;
2066 for (i = 0; i < plt_data->elem_size/2; i++)
2068 uint16_t data = ptr[i];
2069 bfd_put_16 (output_bfd,
2071 htab->splt->contents + h->plt.offset + (i*2));
2075 plt_do_relocs_for_symbol (output_bfd, htab,
2076 plt_data->elem_relocs,
2080 /* Fill in the entry in the global offset table. */
2081 bfd_put_32 (output_bfd,
2082 (bfd_vma) (htab->splt->output_section->vma
2083 + htab->splt->output_offset),
2084 htab->sgotplt->contents + got_offset);
2086 /* TODO: Fill in the entry in the .rela.plt section. */
2088 Elf_Internal_Rela rel;
2091 rel.r_offset = (htab->sgotplt->output_section->vma
2092 + htab->sgotplt->output_offset
2096 BFD_ASSERT (h->dynindx != -1);
2097 rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_JMP_SLOT);
2099 loc = htab->srelplt->contents;
2100 loc += plt_index * sizeof (Elf32_External_Rela); /* relA */
2101 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2106 relocate_plt_for_entry (bfd *abfd,
2107 struct bfd_link_info *info)
2109 struct plt_version_t *plt_data = arc_get_plt_version (info);
2110 struct elf_link_hash_table *htab = elf_hash_table (info);
2114 uint16_t *ptr = (uint16_t *) plt_data->entry;
2115 for (i = 0; i < plt_data->entry_size/2; i++)
2117 uint16_t data = ptr[i];
2120 htab->splt->contents + (i*2));
2123 PLT_DO_RELOCS_FOR_ENTRY (abfd, htab, plt_data->entry_relocs);
2126 /* Desc : Adjust a symbol defined by a dynamic object and referenced
2127 by a regular object. The current definition is in some section of
2128 the dynamic object, but we're not including those sections. We
2129 have to change the definition to something the rest of the link can
2133 elf_arc_adjust_dynamic_symbol (struct bfd_link_info *info,
2134 struct elf_link_hash_entry *h)
2137 unsigned int power_of_two;
2138 bfd *dynobj = (elf_hash_table (info))->dynobj;
2139 struct elf_link_hash_table *htab = elf_hash_table (info);
2141 if (h->type == STT_FUNC
2142 || h->type == STT_GNU_IFUNC
2143 || h->needs_plt == 1)
2145 if (!bfd_link_pic (info) && !h->def_dynamic && !h->ref_dynamic)
2147 /* This case can occur if we saw a PLT32 reloc in an input
2148 file, but the symbol was never referred to by a dynamic
2149 object. In such a case, we don't actually need to build
2150 a procedure linkage table, and we can just do a PC32
2152 BFD_ASSERT (h->needs_plt);
2156 /* Make sure this symbol is output as a dynamic symbol. */
2157 if (h->dynindx == -1 && !h->forced_local
2158 && !bfd_elf_link_record_dynamic_symbol (info, h))
2161 if (bfd_link_pic (info)
2162 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
2164 bfd_vma loc = add_symbol_to_plt (info);
2166 if (!bfd_link_pic (info) && !h->def_regular)
2168 h->root.u.def.section = htab->splt;
2169 h->root.u.def.value = loc;
2171 h->plt.offset = loc;
2175 h->plt.offset = (bfd_vma) -1;
2181 /* If this is a weak symbol, and there is a real definition, the
2182 processor independent code will have arranged for us to see the
2183 real definition first, and we can just use the same value. */
2184 if (h->u.weakdef != NULL)
2186 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2187 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2188 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2189 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2193 /* If there are no non-GOT references, we do not need a copy
2195 if (!h->non_got_ref)
2198 /* This is a reference to a symbol defined by a dynamic object which
2199 is not a function. */
2201 /* If we are creating a shared library, we must presume that the
2202 only references to the symbol are via the global offset table.
2203 For such cases we need not do anything here; the relocations will
2204 be handled correctly by relocate_section. */
2205 if (bfd_link_pic (info))
2208 /* We must allocate the symbol in our .dynbss section, which will
2209 become part of the .bss section of the executable. There will be
2210 an entry for this symbol in the .dynsym section. The dynamic
2211 object will contain position independent code, so all references
2212 from the dynamic object to this symbol will go through the global
2213 offset table. The dynamic linker will use the .dynsym entry to
2214 determine the address it must put in the global offset table, so
2215 both the dynamic object and the regular object will refer to the
2216 same memory location for the variable. */
2218 s = bfd_get_section_by_name (dynobj, ".dynbss");
2219 BFD_ASSERT (s != NULL);
2221 /* We must generate a R_ARC_COPY reloc to tell the dynamic linker to
2222 copy the initial value out of the dynamic object and into the
2223 runtime process image. We need to remember the offset into the
2224 .rela.bss section we are going to use. */
2225 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2229 srel = bfd_get_section_by_name (dynobj, ".rela.bss");
2230 BFD_ASSERT (srel != NULL);
2231 srel->size += sizeof (Elf32_External_Rela);
2235 /* We need to figure out the alignment required for this symbol. I
2236 have no idea how ELF linkers handle this. */
2237 power_of_two = bfd_log2 (h->size);
2238 if (power_of_two > 3)
2241 /* Apply the required alignment. */
2242 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
2243 if (power_of_two > bfd_get_section_alignment (dynobj, s))
2245 if (! bfd_set_section_alignment (dynobj, s, power_of_two))
2249 /* Define the symbol as being at this point in the section. */
2250 h->root.u.def.section = s;
2251 h->root.u.def.value = s->size;
2253 /* Increment the section size to make room for the symbol. */
2259 /* Function : elf_arc_finish_dynamic_symbol
2260 Brief : Finish up dynamic symbol handling. We set the
2261 contents of various dynamic sections here.
2266 Returns : True/False as the return status. */
2269 elf_arc_finish_dynamic_symbol (bfd * output_bfd,
2270 struct bfd_link_info *info,
2271 struct elf_link_hash_entry *h,
2272 Elf_Internal_Sym * sym)
2274 if (h->plt.offset != (bfd_vma) -1)
2276 relocate_plt_for_symbol (output_bfd, info, h);
2278 if (!h->def_regular)
2280 /* Mark the symbol as undefined, rather than as defined in
2281 the .plt section. Leave the value alone. */
2282 sym->st_shndx = SHN_UNDEF;
2286 if (h->got.glist != NULL)
2288 struct got_entry *list = h->got.glist;
2290 /* Traverse the list of got entries for this symbol. */
2293 bfd_vma got_offset = h->got.glist->offset;
2295 if (list->type == GOT_NORMAL
2296 && list->created_dyn_relocation == FALSE)
2298 if (bfd_link_pic (info)
2299 && (info->symbolic || h->dynindx == -1)
2302 ADD_RELA (output_bfd, got, got_offset, 0, R_ARC_RELATIVE, 0);
2304 /* Do not fully understand the side effects of this condition.
2305 The relocation space might still being reserved. Perhaps
2306 I should clear its value. */
2307 else if (h->dynindx != -1)
2309 ADD_RELA (output_bfd, got, got_offset, h->dynindx,
2312 list->created_dyn_relocation = TRUE;
2314 else if (list->existing_entries != TLS_GOT_NONE)
2316 struct elf_link_hash_table *htab = elf_hash_table (info);
2317 enum tls_got_entries e = list->existing_entries;
2319 BFD_ASSERT (list->type != GOT_TLS_GD
2320 || list->existing_entries == TLS_GOT_MOD_AND_OFF);
2322 bfd_vma dynindx = h->dynindx == -1 ? 0 : h->dynindx;
2323 if (e == TLS_GOT_MOD_AND_OFF || e == TLS_GOT_MOD)
2325 ADD_RELA (output_bfd, got, got_offset, dynindx,
2326 R_ARC_TLS_DTPMOD, 0);
2327 ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2328 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2331 htab->sgot->output_section->vma
2332 + htab->sgot->output_offset + got_offset,
2335 if (e == TLS_GOT_MOD_AND_OFF || e == TLS_GOT_OFF)
2338 if (list->type == GOT_TLS_IE)
2339 addend = bfd_get_32 (output_bfd,
2340 htab->sgot->contents + got_offset);
2342 ADD_RELA (output_bfd, got,
2343 got_offset + (e == TLS_GOT_MOD_AND_OFF ? 4 : 0),
2345 (list->type == GOT_TLS_IE ?
2346 R_ARC_TLS_TPOFF : R_ARC_TLS_DTPOFF),
2349 ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2350 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2353 htab->sgot->output_section->vma
2354 + htab->sgot->output_offset + got_offset,
2362 h->got.glist = NULL;
2367 bfd_vma rel_offset = (h->root.u.def.value
2368 + h->root.u.def.section->output_section->vma
2369 + h->root.u.def.section->output_offset);
2372 bfd_get_section_by_name (h->root.u.def.section->owner,
2375 bfd_byte * loc = srelbss->contents
2376 + (srelbss->reloc_count * sizeof (Elf32_External_Rela));
2377 srelbss->reloc_count++;
2379 Elf_Internal_Rela rel;
2381 rel.r_offset = rel_offset;
2383 BFD_ASSERT (h->dynindx != -1);
2384 rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_COPY);
2386 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2389 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
2390 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2391 || strcmp (h->root.root.string, "__DYNAMIC") == 0
2392 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
2393 sym->st_shndx = SHN_ABS;
2398 #define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION, ASSERT) \
2400 if (SYMBOL != NULL) \
2402 h = elf_link_hash_lookup (elf_hash_table (info), \
2403 SYMBOL, FALSE, FALSE, TRUE); \
2405 else if (SECTION != NULL) \
2407 s = bfd_get_section_by_name (output_bfd, SECTION); \
2408 BFD_ASSERT (s != NULL || !ASSERT); \
2413 /* Function : elf_arc_finish_dynamic_sections
2414 Brief : Finish up the dynamic sections handling.
2419 Returns : True/False as the return status. */
2422 elf_arc_finish_dynamic_sections (bfd * output_bfd,
2423 struct bfd_link_info *info)
2425 struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
2426 struct elf_link_hash_table *htab = elf_hash_table (info);
2427 bfd *dynobj = (elf_hash_table (info))->dynobj;
2431 Elf32_External_Dyn *dyncon, *dynconend;
2433 dyncon = (Elf32_External_Dyn *) ds.sdyn->contents;
2435 (Elf32_External_Dyn *) (ds.sdyn->contents + ds.sdyn->size);
2436 for (; dyncon < dynconend; dyncon++)
2438 Elf_Internal_Dyn internal_dyn;
2439 bfd_boolean do_it = FALSE;
2441 struct elf_link_hash_entry *h = NULL;
2444 bfd_elf32_swap_dyn_in (dynobj, dyncon, &internal_dyn);
2446 switch (internal_dyn.d_tag)
2448 GET_SYMBOL_OR_SECTION (DT_INIT, "_init", NULL, TRUE)
2449 GET_SYMBOL_OR_SECTION (DT_FINI, "_fini", NULL, TRUE)
2450 GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt", TRUE)
2451 GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt", TRUE)
2452 GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt", TRUE)
2453 GET_SYMBOL_OR_SECTION (DT_RELASZ, NULL, ".rela.plt", FALSE)
2454 GET_SYMBOL_OR_SECTION (DT_VERSYM, NULL, ".gnu.version", TRUE)
2455 GET_SYMBOL_OR_SECTION (DT_VERDEF, NULL, ".gnu.version_d", TRUE)
2456 GET_SYMBOL_OR_SECTION (DT_VERNEED, NULL, ".gnu.version_r", TRUE)
2461 /* In case the dynamic symbols should be updated with a symbol. */
2463 && (h->root.type == bfd_link_hash_defined
2464 || h->root.type == bfd_link_hash_defweak))
2468 internal_dyn.d_un.d_val = h->root.u.def.value;
2469 asec_ptr = h->root.u.def.section;
2470 if (asec_ptr->output_section != NULL)
2472 internal_dyn.d_un.d_val +=
2473 (asec_ptr->output_section->vma +
2474 asec_ptr->output_offset);
2478 /* The symbol is imported from another shared
2479 library and does not apply to this one. */
2480 internal_dyn.d_un.d_val = 0;
2484 else if (s != NULL) /* With a section information. */
2486 switch (internal_dyn.d_tag)
2493 internal_dyn.d_un.d_ptr = s->vma;
2498 internal_dyn.d_un.d_val = s->size;
2504 internal_dyn.d_un.d_val -= s->size;
2514 bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon);
2517 if (htab->splt->size > 0)
2519 relocate_plt_for_entry (output_bfd, info);
2522 /* TODO: Validate this. */
2523 elf_section_data (htab->srelplt->output_section)->this_hdr.sh_entsize
2527 /* Fill in the first three entries in the global offset table. */
2530 if (htab->sgot->size > 0 || htab->sgotplt->size > 0)
2532 if (ds.sdyn == NULL)
2533 bfd_put_32 (output_bfd, (bfd_vma) 0,
2534 htab->sgotplt->contents);
2536 bfd_put_32 (output_bfd,
2537 ds.sdyn->output_section->vma + ds.sdyn->output_offset,
2538 htab->sgotplt->contents);
2539 bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 4);
2540 bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 8);
2547 #define ADD_DYNAMIC_SYMBOL(NAME, TAG) \
2548 h = elf_link_hash_lookup (elf_hash_table (info), \
2549 NAME, FALSE, FALSE, FALSE); \
2550 if ((h != NULL && (h->ref_regular || h->def_regular))) \
2551 if (! _bfd_elf_add_dynamic_entry (info, TAG, 0)) \
2554 /* Set the sizes of the dynamic sections. */
2556 elf_arc_size_dynamic_sections (bfd * output_bfd,
2557 struct bfd_link_info *info)
2561 bfd_boolean relocs_exist = FALSE;
2562 bfd_boolean reltext_exist = FALSE;
2563 struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
2564 struct elf_link_hash_table *htab = elf_hash_table (info);
2566 dynobj = (elf_hash_table (info))->dynobj;
2567 BFD_ASSERT (dynobj != NULL);
2569 if ((elf_hash_table (info))->dynamic_sections_created)
2571 struct elf_link_hash_entry *h;
2573 /* Set the contents of the .interp section to the
2575 if (!bfd_link_pic (info))
2577 s = bfd_get_section_by_name (dynobj, ".interp");
2578 BFD_ASSERT (s != NULL);
2579 s->size = sizeof (ELF_DYNAMIC_INTERPRETER);
2580 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2583 /* Add some entries to the .dynamic section. We fill in some of
2584 the values later, in elf_bfd_final_link, but we must add the
2585 entries now so that we know the final size of the .dynamic
2586 section. Checking if the .init section is present. We also
2587 create DT_INIT and DT_FINI entries if the init_str has been
2588 changed by the user. */
2589 ADD_DYNAMIC_SYMBOL ("init", DT_INIT);
2590 ADD_DYNAMIC_SYMBOL ("fini", DT_FINI);
2594 /* We may have created entries in the .rela.got section.
2595 However, if we are not creating the dynamic sections, we will
2596 not actually use these entries. Reset the size of .rela.got,
2597 which will cause it to get stripped from the output file
2599 if (htab->srelgot != NULL)
2600 htab->srelgot->size = 0;
2603 if (htab->splt != NULL && htab->splt->size == 0)
2604 htab->splt->flags |= SEC_EXCLUDE;
2605 for (s = dynobj->sections; s != NULL; s = s->next)
2607 if ((s->flags & SEC_LINKER_CREATED) == 0)
2610 if (strncmp (s->name, ".rela", 5) == 0)
2614 s->flags |= SEC_EXCLUDE;
2618 if (strcmp (s->name, ".rela.plt") != 0)
2620 const char *outname =
2621 bfd_get_section_name (output_bfd,
2622 htab->srelplt->output_section);
2624 asection *target = bfd_get_section_by_name (output_bfd,
2627 relocs_exist = TRUE;
2628 if (target != NULL && target->size != 0
2629 && (target->flags & SEC_READONLY) != 0
2630 && (target->flags & SEC_ALLOC) != 0)
2631 reltext_exist = TRUE;
2635 /* We use the reloc_count field as a counter if we need to
2636 copy relocs into the output file. */
2640 if (strcmp (s->name, ".dynamic") == 0)
2644 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2646 if (s->contents == NULL && s->size != 0)
2652 /* TODO: Check if this is needed. */
2653 if (!bfd_link_pic (info))
2654 if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
2657 if (htab->splt && (htab->splt->flags & SEC_EXCLUDE) == 0)
2658 if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
2659 || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2660 || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2661 || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0)
2665 if (relocs_exist == TRUE)
2666 if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
2667 || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
2668 || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
2669 sizeof (Elf32_External_Rela))
2673 if (reltext_exist == TRUE)
2674 if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
2681 const struct elf_size_info arc_elf32_size_info =
2683 sizeof (Elf32_External_Ehdr),
2684 sizeof (Elf32_External_Phdr),
2685 sizeof (Elf32_External_Shdr),
2686 sizeof (Elf32_External_Rel),
2687 sizeof (Elf32_External_Rela),
2688 sizeof (Elf32_External_Sym),
2689 sizeof (Elf32_External_Dyn),
2690 sizeof (Elf_External_Note),
2694 ELFCLASS32, EV_CURRENT,
2695 bfd_elf32_write_out_phdrs,
2696 bfd_elf32_write_shdrs_and_ehdr,
2697 bfd_elf32_checksum_contents,
2698 bfd_elf32_write_relocs,
2699 bfd_elf32_swap_symbol_in,
2700 bfd_elf32_swap_symbol_out,
2701 bfd_elf32_slurp_reloc_table,
2702 bfd_elf32_slurp_symbol_table,
2703 bfd_elf32_swap_dyn_in,
2704 bfd_elf32_swap_dyn_out,
2705 bfd_elf32_swap_reloc_in,
2706 bfd_elf32_swap_reloc_out,
2707 bfd_elf32_swap_reloca_in,
2708 bfd_elf32_swap_reloca_out
2711 #define elf_backend_size_info arc_elf32_size_info
2713 static struct bfd_link_hash_table *
2714 arc_elf_link_hash_table_create (bfd *abfd)
2716 struct elf_link_hash_table *htab;
2718 htab = bfd_zmalloc (sizeof (*htab));
2722 if (!_bfd_elf_link_hash_table_init (htab, abfd,
2723 _bfd_elf_link_hash_newfunc,
2724 sizeof (struct elf_link_hash_entry),
2731 htab->init_got_refcount.refcount = 0;
2732 htab->init_got_refcount.glist = NULL;
2733 htab->init_got_offset.offset = 0;
2734 htab->init_got_offset.glist = NULL;
2735 return (struct bfd_link_hash_table *) htab;
2738 /* Hook called by the linker routine which adds symbols from an object
2742 elf_arc_add_symbol_hook (bfd * abfd,
2743 struct bfd_link_info * info,
2744 Elf_Internal_Sym * sym,
2745 const char ** namep ATTRIBUTE_UNUSED,
2746 flagword * flagsp ATTRIBUTE_UNUSED,
2747 asection ** secp ATTRIBUTE_UNUSED,
2748 bfd_vma * valp ATTRIBUTE_UNUSED)
2750 if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
2751 || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
2752 && (abfd->flags & DYNAMIC) == 0
2753 && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
2754 elf_tdata (info->output_bfd)->has_gnu_symbols = elf_gnu_symbol_any;
2759 #define TARGET_LITTLE_SYM arc_elf32_le_vec
2760 #define TARGET_LITTLE_NAME "elf32-littlearc"
2761 #define TARGET_BIG_SYM arc_elf32_be_vec
2762 #define TARGET_BIG_NAME "elf32-bigarc"
2763 #define ELF_ARCH bfd_arch_arc
2764 #define ELF_MACHINE_CODE EM_ARC_COMPACT
2765 #define ELF_MACHINE_ALT1 EM_ARC_COMPACT2
2766 #define ELF_MAXPAGESIZE 0x2000
2768 #define bfd_elf32_bfd_link_hash_table_create arc_elf_link_hash_table_create
2770 #define bfd_elf32_bfd_merge_private_bfd_data arc_elf_merge_private_bfd_data
2771 #define bfd_elf32_bfd_reloc_type_lookup arc_elf32_bfd_reloc_type_lookup
2772 #define bfd_elf32_bfd_set_private_flags arc_elf_set_private_flags
2773 #define bfd_elf32_bfd_print_private_bfd_data arc_elf_print_private_bfd_data
2774 #define bfd_elf32_bfd_copy_private_bfd_data arc_elf_copy_private_bfd_data
2776 #define elf_info_to_howto_rel arc_info_to_howto_rel
2777 #define elf_backend_object_p arc_elf_object_p
2778 #define elf_backend_final_write_processing arc_elf_final_write_processing
2780 #define elf_backend_relocate_section elf_arc_relocate_section
2781 #define elf_backend_check_relocs elf_arc_check_relocs
2782 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
2784 #define elf_backend_adjust_dynamic_symbol elf_arc_adjust_dynamic_symbol
2785 #define elf_backend_finish_dynamic_symbol elf_arc_finish_dynamic_symbol
2787 #define elf_backend_finish_dynamic_sections elf_arc_finish_dynamic_sections
2788 #define elf_backend_size_dynamic_sections elf_arc_size_dynamic_sections
2789 #define elf_backend_add_symbol_hook elf_arc_add_symbol_hook
2791 #define elf_backend_can_gc_sections 1
2792 #define elf_backend_want_got_plt 1
2793 #define elf_backend_plt_readonly 1
2794 #define elf_backend_rela_plts_and_copies_p 1
2795 #define elf_backend_want_plt_sym 0
2796 #define elf_backend_got_header_size 12
2798 #define elf_backend_may_use_rel_p 0
2799 #define elf_backend_may_use_rela_p 1
2800 #define elf_backend_default_use_rela_p 1
2802 #include "elf32-target.h"