1 /* ARC-specific support for 32-bit ELF
2 Copyright (C) 1994-2016 Free Software Foundation, Inc.
3 Contributed by Cupertino Miranda (cmiranda@synopsys.com).
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
27 #include "libiberty.h"
28 #include "opcode/arc-func.h"
32 # define PR_DEBUG(fmt, args...) fprintf (stderr, fmt, ##args)
34 # define PR_DEBUG(fmt, args...)
37 /* #define ARC_ENABLE_DEBUG 1 */
38 #ifndef ARC_ENABLE_DEBUG
39 #define ARC_DEBUG(...)
42 name_for_global_symbol (struct elf_link_hash_entry *h)
44 static char *local_str = "(local)";
48 return h->root.root.string;
50 #define ARC_DEBUG(args...) fprintf (stderr, ##args)
54 #define ADD_RELA(BFD, SECTION, OFFSET, SYM_IDX, TYPE, ADDEND) \
56 struct elf_link_hash_table *_htab = elf_hash_table (info); \
57 Elf_Internal_Rela _rel; \
60 _loc = _htab->srel##SECTION->contents \
61 + ((_htab->srel##SECTION->reloc_count) \
62 * sizeof (Elf32_External_Rela)); \
63 _htab->srel##SECTION->reloc_count++; \
64 _rel.r_addend = ADDEND; \
65 _rel.r_offset = (_htab->s##SECTION)->output_section->vma \
66 + (_htab->s##SECTION)->output_offset + OFFSET; \
67 _rel.r_info = ELF32_R_INFO (SYM_IDX, TYPE); \
68 bfd_elf32_swap_reloca_out (BFD, &_rel, _loc); \
73 bfd_vma sdata_begin_symbol_vma;
74 asection * sdata_output_section;
75 bfd_vma got_symbol_vma;
78 struct arc_local_data global_arc_data =
80 .sdata_begin_symbol_vma = 0,
81 .sdata_output_section = NULL,
85 struct dynamic_sections
87 bfd_boolean initialized;
91 asection * srelgotplt;
97 enum dyn_section_types
105 DYN_SECTION_TYPES_END
108 const char * dyn_section_names[DYN_SECTION_TYPES_END] =
137 struct got_entry *next;
138 enum tls_type_e type;
140 bfd_boolean processed;
141 bfd_boolean created_dyn_relocation;
142 enum tls_got_entries existing_entries;
146 new_got_entry_to_list (struct got_entry **list,
147 enum tls_type_e type,
149 enum tls_got_entries existing_entries)
151 /* Find list end. Avoid having multiple entries of the same
153 struct got_entry **p = list;
156 if ((*p)->type == type)
161 struct got_entry *entry =
162 (struct got_entry *) malloc (sizeof(struct got_entry));
165 entry->offset = offset;
167 entry->processed = FALSE;
168 entry->created_dyn_relocation = FALSE;
169 entry->existing_entries = existing_entries;
171 /* Add the entry to the end of the list. */
176 symbol_has_entry_of_type (struct got_entry *list, enum tls_type_e type)
180 if (list->type == type)
188 /* The default symbols representing the init and fini dyn values.
189 TODO: Check what is the relation of those strings with arclinux.em
191 #define INIT_SYM_STRING "_init"
192 #define FINI_SYM_STRING "_fini"
194 char * init_str = INIT_SYM_STRING;
195 char * fini_str = FINI_SYM_STRING;
197 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
202 static ATTRIBUTE_UNUSED const char *
203 reloc_type_to_name (unsigned int type)
207 #include "elf/arc-reloc.def"
214 #undef ARC_RELOC_HOWTO
216 /* Try to minimize the amount of space occupied by relocation tables
217 on the ROM (not that the ROM won't be swamped by other ELF overhead). */
221 static ATTRIBUTE_UNUSED bfd_boolean
222 is_reloc_PC_relative (reloc_howto_type *howto)
224 return (strstr (howto->name, "PC") != NULL) ? TRUE : FALSE;
228 is_reloc_SDA_relative (reloc_howto_type *howto)
230 return (strstr (howto->name, "SDA") != NULL) ? TRUE : FALSE;
234 is_reloc_for_GOT (reloc_howto_type * howto)
236 if (strstr (howto->name, "TLS") != NULL)
238 return (strstr (howto->name, "GOT") != NULL) ? TRUE : FALSE;
242 is_reloc_for_PLT (reloc_howto_type * howto)
244 return (strstr (howto->name, "PLT") != NULL) ? TRUE : FALSE;
248 is_reloc_for_TLS (reloc_howto_type *howto)
250 return (strstr (howto->name, "TLS") != NULL) ? TRUE : FALSE;
253 #define arc_bfd_get_8(A,B,C) bfd_get_8(A,B)
254 #define arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
255 #define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C)
256 #define arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
259 arc_bfd_get_32 (bfd * abfd, void *loc, asection * input_section)
261 long insn = bfd_get_32 (abfd, loc);
263 if (!bfd_big_endian (abfd)
265 && (input_section->flags & SEC_CODE))
266 insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
272 arc_bfd_put_32 (bfd * abfd, long insn, void *loc, asection * input_section)
274 if (!bfd_big_endian (abfd)
276 && (input_section->flags & SEC_CODE))
277 insn = ((0x0000fffff & insn) << 16) | ((0xffff0000 & insn) >> 16);
279 bfd_put_32 (abfd, insn, loc);
282 static bfd_reloc_status_type
283 arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
284 arelent *reloc_entry,
286 void *data ATTRIBUTE_UNUSED,
287 asection *input_section,
289 char ** error_message ATTRIBUTE_UNUSED)
291 if (output_bfd != NULL)
293 reloc_entry->address += input_section->output_offset;
295 /* In case of relocateable link and if the reloc is against a
296 section symbol, the addend needs to be adjusted according to
297 where the section symbol winds up in the output section. */
298 if ((symbol_in->flags & BSF_SECTION_SYM) && symbol_in->section)
299 reloc_entry->addend += symbol_in->section->output_offset;
304 return bfd_reloc_continue;
308 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
312 #include "elf/arc-reloc.def"
315 #undef ARC_RELOC_HOWTO
317 #define ARC_RELOC_HOWTO(TYPE, VALUE, RSIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
318 [TYPE] = HOWTO (R_##TYPE, 0, RSIZE, BITSIZE, FALSE, 0, complain_overflow_##OVERFLOW, arc_elf_reloc, "R_" #TYPE, FALSE, 0, 0, FALSE),
320 static struct reloc_howto_struct elf_arc_howto_table[] =
322 #include "elf/arc-reloc.def"
323 /* Example of what is generated by the preprocessor. Currently kept as an
325 HOWTO (R_ARC_NONE, // Type.
327 2, // Size (0 = byte, 1 = short, 2 = long).
329 FALSE, // PC_relative.
331 complain_overflow_bitfield, // Complain_on_overflow.
332 bfd_elf_generic_reloc, // Special_function.
333 "R_ARC_NONE", // Name.
334 TRUE, // Partial_inplace.
337 FALSE), // PCrel_offset.
340 #undef ARC_RELOC_HOWTO
342 static void arc_elf_howto_init (void)
344 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
345 elf_arc_howto_table[TYPE].pc_relative = \
346 (strstr (#FORMULA, " P ") != NULL || strstr (#FORMULA, " PDATA ") != NULL); \
347 elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0);
349 #include "elf/arc-reloc.def"
351 #undef ARC_RELOC_HOWTO
354 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
356 const int howto_table_lookup[] =
358 #include "elf/arc-reloc.def"
360 #undef ARC_RELOC_HOWTO
362 static reloc_howto_type *
363 arc_elf_howto (unsigned int r_type)
365 if (elf_arc_howto_table[R_ARC_32].dst_mask == 0)
366 arc_elf_howto_init ();
367 return &elf_arc_howto_table[r_type];
370 /* Map BFD reloc types to ARC ELF reloc types. */
374 bfd_reloc_code_real_type bfd_reloc_val;
375 unsigned char elf_reloc_val;
378 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
379 { BFD_RELOC_##TYPE, R_##TYPE },
380 static const struct arc_reloc_map arc_reloc_map[] =
382 #include "elf/arc-reloc.def"
384 {BFD_RELOC_NONE, R_ARC_NONE},
385 {BFD_RELOC_8, R_ARC_8},
386 {BFD_RELOC_16, R_ARC_16},
387 {BFD_RELOC_24, R_ARC_24},
388 {BFD_RELOC_32, R_ARC_32},
390 #undef ARC_RELOC_HOWTO
392 static reloc_howto_type *
393 arc_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
394 bfd_reloc_code_real_type code)
398 for (i = ARRAY_SIZE (arc_reloc_map); i--;)
400 if (arc_reloc_map[i].bfd_reloc_val == code)
401 return arc_elf_howto (arc_reloc_map[i].elf_reloc_val);
407 /* Function to set the ELF flag bits. */
409 arc_elf_set_private_flags (bfd *abfd, flagword flags)
411 elf_elfheader (abfd)->e_flags = flags;
412 elf_flags_init (abfd) = TRUE;
416 /* Print private flags. */
418 arc_elf_print_private_bfd_data (bfd *abfd, void * ptr)
420 FILE *file = (FILE *) ptr;
423 BFD_ASSERT (abfd != NULL && ptr != NULL);
425 /* Print normal ELF private data. */
426 _bfd_elf_print_private_bfd_data (abfd, ptr);
428 flags = elf_elfheader (abfd)->e_flags;
429 fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
431 switch (flags & EF_ARC_MACH_MSK)
433 case EF_ARC_CPU_GENERIC : fprintf (file, " -mcpu=generic"); break;
434 case EF_ARC_CPU_ARCV2HS : fprintf (file, " -mcpu=ARCv2HS"); break;
435 case EF_ARC_CPU_ARCV2EM : fprintf (file, " -mcpu=ARCv2EM"); break;
436 case E_ARC_MACH_ARC600 : fprintf (file, " -mcpu=ARC600"); break;
437 case E_ARC_MACH_ARC601 : fprintf (file, " -mcpu=ARC601"); break;
438 case E_ARC_MACH_ARC700 : fprintf (file, " -mcpu=ARC700"); break;
440 fprintf (file, "-mcpu=unknown");
444 switch (flags & EF_ARC_OSABI_MSK)
446 case E_ARC_OSABI_ORIG : fprintf (file, " (ABI:legacy)"); break;
447 case E_ARC_OSABI_V2 : fprintf (file, " (ABI:v2)"); break;
448 case E_ARC_OSABI_V3 : fprintf (file, " (ABI:v3)"); break;
450 fprintf (file, "(ABI:unknown)");
458 /* Copy backend specific data from one object module to another. */
461 arc_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
463 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
464 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
467 BFD_ASSERT (!elf_flags_init (obfd)
468 || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
470 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
471 elf_flags_init (obfd) = TRUE;
473 /* Copy object attributes. */
474 _bfd_elf_copy_obj_attributes (ibfd, obfd);
476 return _bfd_elf_copy_private_bfd_data (ibfd, obfd);
479 static reloc_howto_type *
480 bfd_elf32_bfd_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED,
485 for (i = 0; i < ARRAY_SIZE (elf_arc_howto_table); i++)
486 if (elf_arc_howto_table[i].name != NULL
487 && strcasecmp (elf_arc_howto_table[i].name, r_name) == 0)
488 return arc_elf_howto (i);
493 /* Set the howto pointer for an ARC ELF reloc. */
496 arc_info_to_howto_rel (bfd * abfd ATTRIBUTE_UNUSED,
498 Elf_Internal_Rela * dst)
502 r_type = ELF32_R_TYPE (dst->r_info);
503 BFD_ASSERT (r_type < (unsigned int) R_ARC_max);
504 cache_ptr->howto = arc_elf_howto (r_type);
507 /* Merge backend specific data from an object file to the output
508 object file when linking. */
511 arc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
513 unsigned short mach_ibfd;
514 static unsigned short mach_obfd = EM_NONE;
519 /* Check if we have the same endianess. */
520 if (! _bfd_generic_verify_endian_match (ibfd, obfd))
522 _bfd_error_handler (_("ERROR: Endian Match failed. Attempting to link "
523 "%B with binary %s of opposite endian-ness"),
524 ibfd, bfd_get_filename (obfd));
528 /* Collect ELF flags. */
529 in_flags = elf_elfheader (ibfd)->e_flags & EF_ARC_MACH_MSK;
530 out_flags = elf_elfheader (obfd)->e_flags & EF_ARC_MACH_MSK;
532 if (!elf_flags_init (obfd)) /* First call, no flags set. */
534 elf_flags_init (obfd) = TRUE;
535 out_flags = in_flags;
538 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
539 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
542 /* Check to see if the input BFD actually contains any sections. Do
543 not short-circuit dynamic objects; their section list may be
544 emptied by elf_link_add_object_symbols. */
545 if (!(ibfd->flags & DYNAMIC))
547 bfd_boolean null_input_bfd = TRUE;
548 bfd_boolean only_data_sections = TRUE;
550 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
552 if ((bfd_get_section_flags (ibfd, sec)
553 & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
554 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
555 only_data_sections = FALSE;
557 null_input_bfd = FALSE;
560 if (null_input_bfd || only_data_sections)
564 /* Complain about various flag/architecture mismatches. */
565 mach_ibfd = elf_elfheader (ibfd)->e_machine;
566 if (mach_obfd == EM_NONE)
568 mach_obfd = mach_ibfd;
572 if (mach_ibfd != mach_obfd)
574 _bfd_error_handler (_("ERROR: Attempting to link %B "
575 "with a binary %s of different architecture"),
576 ibfd, bfd_get_filename (obfd));
579 else if (in_flags != out_flags)
581 /* Warn if different flags. */
582 (*_bfd_error_handler)
583 (_("%s: uses different e_flags (0x%lx) fields than "
584 "previous modules (0x%lx)"),
585 bfd_get_filename (ibfd), (long)in_flags, (long)out_flags);
586 if (in_flags && out_flags)
588 /* MWDT doesnt set the eflags hence make sure we choose the
589 eflags set by gcc. */
590 in_flags = in_flags > out_flags ? in_flags : out_flags;
594 /* Update the flags. */
595 elf_elfheader (obfd)->e_flags = in_flags;
597 if (bfd_get_mach (obfd) < bfd_get_mach (ibfd))
599 return bfd_set_arch_mach (obfd, bfd_arch_arc, bfd_get_mach (ibfd));
605 /* Set the right machine number for an ARC ELF file. */
607 arc_elf_object_p (bfd * abfd)
609 /* Make sure this is initialised, or you'll have the potential of passing
610 garbage---or misleading values---into the call to
611 bfd_default_set_arch_mach (). */
612 int mach = bfd_mach_arc_arc700;
613 unsigned long arch = elf_elfheader (abfd)->e_flags & EF_ARC_MACH_MSK;
614 unsigned e_machine = elf_elfheader (abfd)->e_machine;
616 if (e_machine == EM_ARC_COMPACT || e_machine == EM_ARC_COMPACT2)
620 case E_ARC_MACH_ARC600:
621 mach = bfd_mach_arc_arc600;
623 case E_ARC_MACH_ARC601:
624 mach = bfd_mach_arc_arc601;
626 case E_ARC_MACH_ARC700:
627 mach = bfd_mach_arc_arc700;
629 case EF_ARC_CPU_ARCV2HS:
630 case EF_ARC_CPU_ARCV2EM:
631 mach = bfd_mach_arc_arcv2;
634 mach = (e_machine == EM_ARC_COMPACT) ?
635 bfd_mach_arc_arc700 : bfd_mach_arc_arcv2;
641 if (e_machine == EM_ARC)
643 (*_bfd_error_handler)
644 (_("Error: The ARC4 architecture is no longer supported.\n"));
649 (*_bfd_error_handler)
650 (_("Warning: unset or old architecture flags. \n"
651 " Use default machine.\n"));
655 return bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach);
658 /* The final processing done just before writing out an ARC ELF object file.
659 This gets the ARC architecture right based on the machine number. */
662 arc_elf_final_write_processing (bfd * abfd,
663 bfd_boolean linker ATTRIBUTE_UNUSED)
668 switch (bfd_get_mach (abfd))
670 case bfd_mach_arc_arc600:
671 val = E_ARC_MACH_ARC600;
672 emf = EM_ARC_COMPACT;
674 case bfd_mach_arc_arc601:
675 val = E_ARC_MACH_ARC601;
676 emf = EM_ARC_COMPACT;
678 case bfd_mach_arc_arc700:
679 val = E_ARC_MACH_ARC700;
680 emf = EM_ARC_COMPACT;
682 case bfd_mach_arc_arcv2:
683 val = EF_ARC_CPU_GENERIC;
684 emf = EM_ARC_COMPACT2;
685 /* TODO: Check validity of this. It can also be ARCV2EM here.
686 Previous version sets the e_machine here. */
692 elf_elfheader (abfd)->e_flags &= ~EF_ARC_MACH;
693 elf_elfheader (abfd)->e_flags |= val;
694 elf_elfheader (abfd)->e_machine = emf;
695 /* Record whatever is the current syscall ABI version. */
696 elf_elfheader (abfd)->e_flags |= E_ARC_OSABI_CURRENT;
699 #define BFD_DEBUG_PIC(...)
701 struct arc_relocation_data
703 bfd_vma reloc_offset;
704 bfd_vma reloc_addend;
705 bfd_vma got_offset_value;
708 asection * sym_section;
710 reloc_howto_type *howto;
712 asection * input_section;
714 bfd_vma sdata_begin_symbol_vma;
715 bfd_boolean sdata_begin_symbol_vma_set;
716 bfd_vma got_symbol_vma;
718 bfd_boolean should_relocate;
722 debug_arc_reloc (struct arc_relocation_data reloc_data)
724 PR_DEBUG ("Reloc type=%s, should_relocate = %s\n",
725 reloc_data.howto->name,
726 reloc_data.should_relocate ? "true" : "false");
727 PR_DEBUG (" offset = 0x%x, addend = 0x%x\n",
728 (unsigned int) reloc_data.reloc_offset,
729 (unsigned int) reloc_data.reloc_addend);
730 PR_DEBUG (" Symbol:\n");
731 PR_DEBUG (" value = 0x%08x\n",
732 (unsigned int) reloc_data.sym_value);
733 if (reloc_data.sym_section != NULL)
735 PR_DEBUG ("IN IF\n");
737 " section name = %s, output_offset 0x%08x",
738 reloc_data.sym_section->name,
739 (unsigned int) reloc_data.sym_section->output_offset);
740 if (reloc_data.sym_section->output_section != NULL)
743 ", output_section->vma = 0x%08x",
744 ((unsigned int) reloc_data.sym_section->output_section->vma));
751 PR_DEBUG ( " symbol section is NULL\n");
754 PR_DEBUG ( " Input_section:\n");
755 if (reloc_data.input_section != NULL)
758 " section name = %s, output_offset 0x%08x, output_section->vma = 0x%08x\n",
759 reloc_data.input_section->name,
760 (unsigned int) reloc_data.input_section->output_offset,
761 (unsigned int) reloc_data.input_section->output_section->vma);
762 PR_DEBUG ( " changed_address = 0x%08x\n",
763 (unsigned int) (reloc_data.input_section->output_section->vma +
764 reloc_data.input_section->output_offset +
765 reloc_data.reloc_offset));
769 PR_DEBUG ( " input section is NULL\n");
773 static ATTRIBUTE_UNUSED bfd_vma
774 get_middle_endian_relocation (bfd_vma reloc)
776 bfd_vma ret = ((reloc & 0xffff0000) >> 16) |
777 ((reloc & 0xffff) << 16);
781 #define S (reloc_data.sym_value \
782 + (reloc_data.sym_section->output_section != NULL ? \
783 (reloc_data.sym_section->output_offset \
784 + reloc_data.sym_section->output_section->vma) : 0) \
786 #define L (reloc_data.sym_value \
787 + (reloc_data.sym_section->output_section != NULL ? \
788 (reloc_data.sym_section->output_offset \
789 + reloc_data.sym_section->output_section->vma) : 0) \
791 #define A (reloc_data.reloc_addend)
793 #define G (reloc_data.got_offset_value)
794 #define GOT (reloc_data.got_symbol_vma)
795 #define GOT_BEGIN (htab->sgot->output_section->vma)
798 /* P: relative offset to PCL The offset should be to the
799 current location aligned to 32 bits. */
802 (reloc_data.input_section->output_section != NULL ? \
803 reloc_data.input_section->output_section->vma : 0) \
804 + reloc_data.input_section->output_offset \
805 + (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0)) \
808 (reloc_data.input_section->output_section->vma \
809 + reloc_data.input_section->output_offset \
810 + (reloc_data.reloc_offset) \
812 #define SECTSTAR (reloc_data.input_section->output_offset)
813 #define SECTSTART (reloc_data.input_section->output_offset)
814 #define _SDA_BASE_ (reloc_data.sdata_begin_symbol_vma)
815 #define TLS_REL ((elf_hash_table (info))->tls_sec->output_section->vma)
816 #define _SDA_BASE_ (reloc_data.sdata_begin_symbol_vma)
820 #define NON_ME(VALUE) (reverse_me (reloc_data, VALUE))
824 #define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA) \
826 asection *sym_section = reloc_data.sym_section; \
827 asection *input_section = reloc_data.input_section; \
828 ARC_DEBUG ("FORMULA = " #FORMULA "\n"); \
829 ARC_DEBUG ("S = 0x%x\n", S); \
830 ARC_DEBUG ("A = 0x%x\n", A); \
831 ARC_DEBUG ("L = 0x%x\n", L); \
832 if (sym_section->output_section != NULL) \
834 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
835 sym_section->output_section->vma + sym_section->output_offset); \
839 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
841 if (input_section->output_section != NULL) \
843 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
844 input_section->output_section->vma + input_section->output_offset); \
848 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
850 ARC_DEBUG ("PCL = 0x%x\n", P); \
851 ARC_DEBUG ("P = 0x%x\n", P); \
852 ARC_DEBUG ("G = 0x%x\n", G); \
853 ARC_DEBUG ("SDA_OFFSET = 0x%x\n", _SDA_BASE_); \
854 ARC_DEBUG ("SDA_SET = %d\n", reloc_data.sdata_begin_symbol_vma_set); \
855 ARC_DEBUG ("GOT_OFFSET = 0x%x\n", GOT); \
856 ARC_DEBUG ("relocation = 0x%08x\n", relocation); \
857 ARC_DEBUG ("before = 0x%08x\n", (unsigned int) insn); \
858 ARC_DEBUG ("data = 0x%08x (%u) (%d)\n", (unsigned int) relocation, (unsigned int) relocation, (int) relocation); \
861 #define PRINT_DEBUG_RELOC_INFO_AFTER \
863 ARC_DEBUG ("after = 0x%08x\n", (unsigned int) insn); \
866 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
869 bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
870 relocation = FORMULA ; \
871 PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA) \
872 insn = RELOC_FUNCTION (insn, relocation); \
873 PRINT_DEBUG_RELOC_INFO_AFTER \
878 reverse_me (struct arc_relocation_data reloc_data, bfd_vma reloc)
880 if (reloc_data.input_section && reloc_data.input_section->flags & SEC_CODE)
881 return ((0x0000fffff & reloc) << 16) | ((0xffff0000 & reloc) >> 16);
886 static bfd_reloc_status_type
887 arc_do_relocation (bfd_byte * contents,
888 struct arc_relocation_data reloc_data,
889 struct bfd_link_info *info)
891 bfd_vma relocation = 0;
893 bfd_vma orig_insn ATTRIBUTE_UNUSED;
894 struct elf_link_hash_table *htab ATTRIBUTE_UNUSED = elf_hash_table (info);
896 if (reloc_data.should_relocate == FALSE)
899 switch (reloc_data.howto->size)
902 insn = arc_bfd_get_32 (reloc_data.input_section->owner,
903 contents + reloc_data.reloc_offset,
904 reloc_data.input_section);
908 insn = arc_bfd_get_16 (reloc_data.input_section->owner,
909 contents + reloc_data.reloc_offset,
910 reloc_data.input_section);
920 switch (reloc_data.howto->type)
922 #include "elf/arc-reloc.def"
929 /* Check for relocation overflow. */
930 if (reloc_data.howto->complain_on_overflow != complain_overflow_dont)
932 bfd_reloc_status_type flag;
933 flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
934 reloc_data.howto->bitsize,
935 reloc_data.howto->rightshift,
936 bfd_arch_bits_per_address (reloc_data.input_section->owner),
939 #undef DEBUG_ARC_RELOC
940 #define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
941 if (flag != bfd_reloc_ok)
943 PR_DEBUG ( "Relocation overflows !!!!\n");
945 DEBUG_ARC_RELOC (reloc_data);
948 "Relocation value = signed -> %d, unsigned -> %u"
949 ", hex -> (0x%08x)\n",
951 (unsigned int) relocation,
952 (unsigned int) relocation);
956 #undef DEBUG_ARC_RELOC
957 #define DEBUG_ARC_RELOC(A)
959 switch (reloc_data.howto->size)
962 arc_bfd_put_32 (reloc_data.input_section->owner, insn,
963 contents + reloc_data.reloc_offset,
964 reloc_data.input_section);
968 arc_bfd_put_16 (reloc_data.input_section->owner, insn,
969 contents + reloc_data.reloc_offset,
970 reloc_data.input_section);
973 ARC_DEBUG ("size = %d\n", reloc_data.howto->size);
993 #undef ARC_RELOC_HOWTO
995 static struct got_entry **
996 arc_get_local_got_ents (bfd * abfd)
998 static struct got_entry **local_got_ents = NULL;
1000 if (local_got_ents == NULL)
1003 Elf_Internal_Shdr *symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1005 size = symtab_hdr->sh_info * sizeof (bfd_vma);
1006 local_got_ents = (struct got_entry **)
1007 bfd_alloc (abfd, sizeof(struct got_entry *) * size);
1008 if (local_got_ents == NULL)
1011 memset (local_got_ents, 0, sizeof(struct got_entry *) * size);
1012 elf_local_got_ents (abfd) = local_got_ents;
1015 return local_got_ents;
1018 /* Relocate an arc ELF section.
1019 Function : elf_arc_relocate_section
1020 Brief : Relocate an arc section, by handling all the relocations
1021 appearing in that section.
1022 Args : output_bfd : The bfd being written to.
1023 info : Link information.
1024 input_bfd : The input bfd.
1025 input_section : The section being relocated.
1026 contents : contents of the section being relocated.
1027 relocs : List of relocations in the section.
1028 local_syms : is a pointer to the swapped in local symbols.
1029 local_section : is an array giving the section in the input file
1030 corresponding to the st_shndx field of each
1033 elf_arc_relocate_section (bfd * output_bfd,
1034 struct bfd_link_info * info,
1036 asection * input_section,
1037 bfd_byte * contents,
1038 Elf_Internal_Rela * relocs,
1039 Elf_Internal_Sym * local_syms,
1040 asection ** local_sections)
1042 Elf_Internal_Shdr * symtab_hdr;
1043 struct elf_link_hash_entry ** sym_hashes;
1044 struct got_entry ** local_got_ents;
1045 Elf_Internal_Rela * rel;
1046 Elf_Internal_Rela * relend;
1047 struct elf_link_hash_table *htab = elf_hash_table (info);
1049 symtab_hdr = &((elf_tdata (input_bfd))->symtab_hdr);
1050 sym_hashes = elf_sym_hashes (input_bfd);
1053 relend = relocs + input_section->reloc_count;
1054 for (; rel < relend; rel++)
1056 enum elf_arc_reloc_type r_type;
1057 reloc_howto_type * howto;
1058 unsigned long r_symndx;
1059 struct elf_link_hash_entry * h;
1060 Elf_Internal_Sym * sym;
1062 struct elf_link_hash_entry *h2;
1064 struct arc_relocation_data reloc_data =
1068 .got_offset_value = 0,
1070 .sym_section = NULL,
1072 .input_section = NULL,
1073 .sdata_begin_symbol_vma = 0,
1074 .sdata_begin_symbol_vma_set = FALSE,
1075 .got_symbol_vma = 0,
1076 .should_relocate = FALSE
1079 r_type = ELF32_R_TYPE (rel->r_info);
1081 if (r_type >= (int) R_ARC_max)
1083 bfd_set_error (bfd_error_bad_value);
1086 howto = &elf_arc_howto_table[r_type];
1088 r_symndx = ELF32_R_SYM (rel->r_info);
1090 /* If we are generating another .o file and the symbol in not
1091 local, skip this relocation. */
1092 if (bfd_link_relocatable (info))
1094 /* This is a relocateable link. We don't have to change
1095 anything, unless the reloc is against a section symbol,
1096 in which case we have to adjust according to where the
1097 section symbol winds up in the output section. */
1099 /* Checks if this is a local symbol and thus the reloc
1100 might (will??) be against a section symbol. */
1101 if (r_symndx < symtab_hdr->sh_info)
1103 sym = local_syms + r_symndx;
1104 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1106 sec = local_sections[r_symndx];
1108 /* for RELA relocs.Just adjust the addend
1109 value in the relocation entry. */
1110 rel->r_addend += sec->output_offset + sym->st_value;
1113 PR_DEBUG ("local symbols reloc "
1114 "(section=%d %s) seen in %s\n",
1116 local_sections[r_symndx]->name,
1117 __PRETTY_FUNCTION__)
1125 h2 = elf_link_hash_lookup (elf_hash_table (info), "__SDATA_BEGIN__",
1126 FALSE, FALSE, TRUE);
1128 if (reloc_data.sdata_begin_symbol_vma_set == FALSE
1129 && h2 != NULL && h2->root.type != bfd_link_hash_undefined
1130 && h2->root.u.def.section->output_section != NULL)
1131 /* TODO: Verify this condition. */
1133 reloc_data.sdata_begin_symbol_vma =
1134 (h2->root.u.def.value +
1135 h2->root.u.def.section->output_section->vma);
1136 reloc_data.sdata_begin_symbol_vma_set = TRUE;
1139 reloc_data.input_section = input_section;
1140 reloc_data.howto = howto;
1141 reloc_data.reloc_offset = rel->r_offset;
1142 reloc_data.reloc_addend = rel->r_addend;
1144 /* This is a final link. */
1149 if (r_symndx < symtab_hdr->sh_info) /* A local symbol. */
1151 local_got_ents = arc_get_local_got_ents (output_bfd);
1152 struct got_entry *entry = local_got_ents[r_symndx];
1154 sym = local_syms + r_symndx;
1155 sec = local_sections[r_symndx];
1157 reloc_data.sym_value = sym->st_value;
1158 reloc_data.sym_section = sec;
1160 if ((is_reloc_for_GOT (howto)
1161 || is_reloc_for_TLS (howto)) && entry != NULL)
1163 if (is_reloc_for_TLS (howto))
1164 while (entry->type == GOT_NORMAL && entry->next != NULL)
1165 entry = entry->next;
1167 if (is_reloc_for_GOT (howto))
1168 while (entry->type != GOT_NORMAL && entry->next != NULL)
1169 entry = entry->next;
1171 if (entry->type == GOT_TLS_GD && entry->processed == FALSE)
1173 bfd_vma sym_vma = sym->st_value
1174 + sec->output_section->vma
1175 + sec->output_offset;
1177 /* Create dynamic relocation for local sym. */
1178 ADD_RELA (output_bfd, got, entry->offset, 0,
1179 R_ARC_TLS_DTPMOD, 0);
1180 ADD_RELA (output_bfd, got, entry->offset+4, 0,
1181 R_ARC_TLS_DTPOFF, 0);
1183 bfd_vma sec_vma = sec->output_section->vma
1184 + sec->output_offset;
1185 bfd_put_32 (output_bfd, sym_vma - sec_vma,
1186 htab->sgot->contents + entry->offset + 4);
1188 ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_GD value "
1189 "= 0x%x @ 0x%x, for symbol %s\n",
1191 htab->sgot->contents + entry->offset + 4,
1194 entry->processed = TRUE;
1196 if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
1198 bfd_vma sym_vma = sym->st_value
1199 + sec->output_section->vma
1200 + sec->output_offset;
1201 bfd_vma sec_vma = htab->tls_sec->output_section->vma;
1202 bfd_put_32 (output_bfd, sym_vma - sec_vma,
1203 htab->sgot->contents + entry->offset);
1204 /* TODO: Check if this type of relocs is the cause
1205 for all the ARC_NONE dynamic relocs. */
1207 ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_IE value = "
1208 "0x%x @ 0x%x, for symbol %s\n",
1210 htab->sgot->contents + entry->offset,
1213 entry->processed = TRUE;
1215 if (entry->type == GOT_NORMAL && entry->processed == FALSE)
1217 bfd_vma sec_vma = reloc_data.sym_section->output_section->vma
1218 + reloc_data.sym_section->output_offset;
1220 bfd_put_32 (output_bfd, reloc_data.sym_value + sec_vma,
1221 htab->sgot->contents + entry->offset);
1223 ARC_DEBUG ("arc_info: PATCHED: 0x%08x @ 0x%08x for "
1224 "sym %s in got offset 0x%x\n",
1225 reloc_data.sym_value + sec_vma,
1226 htab->sgot->output_section->vma
1227 + htab->sgot->output_offset + entry->offset,
1230 entry->processed = TRUE;
1233 reloc_data.got_offset_value = entry->offset;
1234 ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
1235 "vma = 0x%x for symbol %s\n",
1236 entry->type, entry->offset,
1237 htab->sgot->output_section->vma
1238 + htab->sgot->output_offset + entry->offset,
1242 BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1243 if (htab->sgot != NULL)
1244 reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1245 + htab->sgot->output_offset;
1247 reloc_data.should_relocate = TRUE;
1249 else /* Global symbol. */
1251 /* Get the symbol's entry in the symtab. */
1252 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1254 while (h->root.type == bfd_link_hash_indirect
1255 || h->root.type == bfd_link_hash_warning)
1256 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1258 BFD_ASSERT ((h->dynindx == -1) >= (h->forced_local != 0));
1259 /* If we have encountered a definition for this symbol. */
1260 if (h->root.type == bfd_link_hash_defined
1261 || h->root.type == bfd_link_hash_defweak)
1263 reloc_data.sym_value = h->root.u.def.value;
1264 reloc_data.sym_section = h->root.u.def.section;
1266 reloc_data.should_relocate = TRUE;
1268 if (is_reloc_for_GOT (howto) && !bfd_link_pic (info))
1270 /* TODO: Change it to use arc_do_relocation with
1271 ARC_32 reloc. Try to use ADD_RELA macro. */
1272 bfd_vma relocation =
1273 reloc_data.sym_value + reloc_data.reloc_addend
1274 + (reloc_data.sym_section->output_section != NULL ?
1275 (reloc_data.sym_section->output_offset
1276 + reloc_data.sym_section->output_section->vma)
1279 BFD_ASSERT (h->got.glist);
1280 bfd_vma got_offset = h->got.glist->offset;
1281 bfd_put_32 (output_bfd, relocation,
1282 htab->sgot->contents + got_offset);
1284 if (is_reloc_for_PLT (howto) && h->plt.offset != (bfd_vma) -1)
1286 /* TODO: This is repeated up here. */
1287 reloc_data.sym_value = h->plt.offset;
1288 reloc_data.sym_section = htab->splt;
1291 else if (h->root.type == bfd_link_hash_undefweak)
1293 /* Is weak symbol and has no definition. */
1294 if (is_reloc_for_GOT (howto))
1296 reloc_data.sym_value = h->root.u.def.value;
1297 reloc_data.sym_section = htab->sgot;
1298 reloc_data.should_relocate = TRUE;
1300 else if (is_reloc_for_PLT (howto)
1301 && h->plt.offset != (bfd_vma) -1)
1303 /* TODO: This is repeated up here. */
1304 reloc_data.sym_value = h->plt.offset;
1305 reloc_data.sym_section = htab->splt;
1306 reloc_data.should_relocate = TRUE;
1313 if (is_reloc_for_GOT (howto))
1315 reloc_data.sym_value = h->root.u.def.value;
1316 reloc_data.sym_section = htab->sgot;
1318 reloc_data.should_relocate = TRUE;
1320 else if (is_reloc_for_PLT (howto))
1322 reloc_data.sym_value = h->plt.offset;
1323 reloc_data.sym_section = htab->splt;
1325 reloc_data.should_relocate = TRUE;
1327 else if (!(*info->callbacks->undefined_symbol)
1328 (info, h->root.root.string, input_bfd, input_section,
1329 rel->r_offset,!bfd_link_pic (info)))
1335 if (h->got.glist != NULL)
1337 struct got_entry *entry = h->got.glist;
1339 if (is_reloc_for_GOT (howto) || is_reloc_for_TLS (howto))
1341 if (! elf_hash_table (info)->dynamic_sections_created
1342 || (bfd_link_pic (info)
1343 && SYMBOL_REFERENCES_LOCAL (info, h)))
1345 reloc_data.sym_value = h->root.u.def.value;
1346 reloc_data.sym_section = h->root.u.def.section;
1348 if (is_reloc_for_TLS (howto))
1349 while (entry->type == GOT_NORMAL && entry->next != NULL)
1350 entry = entry->next;
1352 if (entry->processed == FALSE
1353 && (entry->type == GOT_TLS_GD
1354 || entry->type == GOT_TLS_IE))
1356 bfd_vma sym_value = h->root.u.def.value
1357 + h->root.u.def.section->output_section->vma
1358 + h->root.u.def.section->output_offset;
1361 elf_hash_table (info)->tls_sec->output_section->vma;
1363 bfd_put_32 (output_bfd,
1364 sym_value - sec_vma,
1365 htab->sgot->contents + entry->offset
1366 + (entry->existing_entries == MOD_AND_OFF ? 4 : 0));
1368 ARC_DEBUG ("arc_info: FIXED -> %s value = 0x%x "
1369 "@ 0x%x, for symbol %s\n",
1370 (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
1372 sym_value - sec_vma,
1373 htab->sgot->contents + entry->offset
1374 + (entry->existing_entries == MOD_AND_OFF ? 4 : 0),
1375 h->root.root.string);
1377 entry->processed = TRUE;
1380 if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
1382 bfd_vma sec_vma = htab->tls_sec->output_section->vma;
1383 bfd_put_32 (output_bfd,
1384 reloc_data.sym_value - sec_vma,
1385 htab->sgot->contents + entry->offset);
1388 if (entry->type == GOT_NORMAL && entry->processed == FALSE)
1391 reloc_data.sym_section->output_section->vma
1392 + reloc_data.sym_section->output_offset;
1394 if (h->root.type != bfd_link_hash_undefweak)
1396 bfd_put_32 (output_bfd,
1397 reloc_data.sym_value + sec_vma,
1398 htab->sgot->contents + entry->offset);
1400 ARC_DEBUG ("arc_info: PATCHED: 0x%08x "
1401 "@ 0x%08x for sym %s in got offset 0x%x\n",
1402 reloc_data.sym_value + sec_vma,
1403 htab->sgot->output_section->vma
1404 + htab->sgot->output_offset + entry->offset,
1405 h->root.root.string,
1410 ARC_DEBUG ("arc_info: PATCHED: NOT_PATCHED "
1411 "@ 0x%08x for sym %s in got offset 0x%x "
1413 htab->sgot->output_section->vma
1414 + htab->sgot->output_offset + entry->offset,
1415 h->root.root.string,
1419 entry->processed = TRUE;
1424 reloc_data.got_offset_value = entry->offset;
1426 ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
1427 "vma = 0x%x for symbol %s\n",
1428 entry->type, entry->offset,
1429 htab->sgot->output_section->vma
1430 + htab->sgot->output_offset + entry->offset,
1431 h->root.root.string);
1434 BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1435 if (htab->sgot != NULL)
1436 reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1437 + htab->sgot->output_offset;
1445 case R_ARC_32_PCREL:
1446 if (bfd_link_pic (info)
1447 && ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1450 && (!info->symbolic || !h->def_regular))))
1452 Elf_Internal_Rela outrel;
1454 bfd_boolean skip = FALSE;
1455 bfd_boolean relocate = FALSE;
1456 asection *sreloc = _bfd_elf_get_dynamic_reloc_section
1457 (input_bfd, input_section,
1460 BFD_ASSERT (sreloc != NULL);
1462 outrel.r_offset = _bfd_elf_section_offset (output_bfd,
1466 if (outrel.r_offset == (bfd_vma) -1)
1469 outrel.r_addend = rel->r_addend;
1470 outrel.r_offset += (input_section->output_section->vma
1471 + input_section->output_offset);
1475 memset (&outrel, 0, sizeof outrel);
1478 else if (r_type == R_ARC_PC32
1479 || r_type == R_ARC_32_PCREL)
1481 BFD_ASSERT (h != NULL && h->dynindx != -1);
1482 if ((input_section->flags & SEC_ALLOC) != 0)
1486 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1490 /* Handle local symbols, they either do not have a
1491 global hash table entry (h == NULL), or are
1492 forced local due to a version script
1493 (h->forced_local), or the third condition is
1494 legacy, it appears to say something like, for
1495 links where we are pre-binding the symbols, or
1496 there's not an entry for this symbol in the
1497 dynamic symbol table, and it's a regular symbol
1498 not defined in a shared object, then treat the
1499 symbol as local, resolve it now. */
1501 || ((info->symbolic || h->dynindx == -1)
1506 /* outrel.r_addend = 0; */
1507 outrel.r_info = ELF32_R_INFO (0, R_ARC_RELATIVE);
1511 BFD_ASSERT (h->dynindx != -1);
1512 if ((input_section->flags & SEC_ALLOC) != 0)
1516 outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_32);
1520 BFD_ASSERT (sreloc->contents != 0);
1522 loc = sreloc->contents;
1523 loc += sreloc->reloc_count * sizeof (Elf32_External_Rela);
1524 sreloc->reloc_count += 1;
1526 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1528 if (relocate == FALSE)
1536 if (is_reloc_SDA_relative (howto)
1537 && (reloc_data.sdata_begin_symbol_vma_set == FALSE))
1539 (*_bfd_error_handler)
1540 ("Error: Linker symbol __SDATA_BEGIN__ not found");
1541 bfd_set_error (bfd_error_bad_value);
1545 DEBUG_ARC_RELOC (reloc_data);
1547 if (arc_do_relocation (contents, reloc_data, info) != bfd_reloc_ok)
1554 static struct dynamic_sections
1555 arc_create_dynamic_sections (bfd * abfd, struct bfd_link_info *info)
1557 struct elf_link_hash_table *htab;
1559 struct dynamic_sections ds =
1561 .initialized = FALSE,
1571 htab = elf_hash_table (info);
1574 /* Create dynamic sections for relocatable executables so that we
1575 can copy relocations. */
1576 if (! htab->dynamic_sections_created && bfd_link_pic (info))
1578 if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
1582 dynobj = (elf_hash_table (info))->dynobj;
1586 ds.sgot = htab->sgot;
1587 ds.srelgot = htab->srelgot;
1589 ds.sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
1590 ds.srelgotplt = ds.srelplt;
1592 ds.splt = bfd_get_section_by_name (dynobj, ".plt");
1593 ds.srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
1596 if (htab->dynamic_sections_created)
1598 ds.sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
1601 ds.initialized = TRUE;
1606 #define ADD_SYMBOL_REF_SEC_AND_RELOC(SECNAME, COND_FOR_RELOC, H) \
1607 htab->s##SECNAME->size; \
1609 if (COND_FOR_RELOC) \
1611 htab->srel##SECNAME->size += sizeof (Elf32_External_Rela); \
1612 ARC_DEBUG ("arc_info: Added reloc space in " \
1613 #SECNAME " section at " __FILE__ \
1614 ":%d for symbol\n", \
1615 __LINE__, name_for_global_symbol (H)); \
1618 if (h->dynindx == -1 && !h->forced_local) \
1619 if (! bfd_elf_link_record_dynamic_symbol (info, H)) \
1621 htab->s##SECNAME->size += 4; \
1625 elf_arc_check_relocs (bfd * abfd,
1626 struct bfd_link_info * info,
1628 const Elf_Internal_Rela * relocs)
1630 Elf_Internal_Shdr * symtab_hdr;
1631 struct elf_link_hash_entry ** sym_hashes;
1632 struct got_entry ** local_got_ents;
1633 const Elf_Internal_Rela * rel;
1634 const Elf_Internal_Rela * rel_end;
1636 asection * sreloc = NULL;
1637 struct elf_link_hash_table * htab = elf_hash_table (info);
1639 if (bfd_link_relocatable (info))
1642 dynobj = (elf_hash_table (info))->dynobj;
1643 symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1644 sym_hashes = elf_sym_hashes (abfd);
1645 local_got_ents = arc_get_local_got_ents (abfd);
1647 rel_end = relocs + sec->reloc_count;
1648 for (rel = relocs; rel < rel_end; rel++)
1650 enum elf_arc_reloc_type r_type;
1651 reloc_howto_type *howto;
1652 unsigned long r_symndx;
1653 struct elf_link_hash_entry *h;
1655 r_type = ELF32_R_TYPE (rel->r_info);
1657 if (r_type >= (int) R_ARC_max)
1659 bfd_set_error (bfd_error_bad_value);
1662 howto = &elf_arc_howto_table[r_type];
1665 && (is_reloc_for_GOT (howto) == TRUE
1666 || is_reloc_for_TLS (howto) == TRUE))
1668 dynobj = elf_hash_table (info)->dynobj = abfd;
1669 if (! _bfd_elf_create_got_section (abfd, info))
1673 /* Load symbol information. */
1674 r_symndx = ELF32_R_SYM (rel->r_info);
1675 if (r_symndx < symtab_hdr->sh_info) /* Is a local symbol. */
1677 else /* Global one. */
1678 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1684 /* During shared library creation, these relocs should not
1685 appear in a shared library (as memory will be read only
1686 and the dynamic linker can not resolve these. However
1687 the error should not occur for e.g. debugging or
1688 non-readonly sections. */
1689 if (bfd_link_dll (info) && !bfd_link_pie (info)
1690 && (sec->flags & SEC_ALLOC) != 0
1691 && (sec->flags & SEC_READONLY) != 0)
1695 name = h->root.root.string;
1697 /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); */
1699 (*_bfd_error_handler)
1701 %B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
1703 arc_elf_howto (r_type)->name,
1705 bfd_set_error (bfd_error_bad_value);
1709 /* In some cases we are not setting the 'non_got_ref'
1710 flag, even though the relocations don't require a GOT
1711 access. We should extend the testing in this area to
1712 ensure that no significant cases are being missed. */
1717 case R_ARC_32_PCREL:
1718 if (bfd_link_pic (info)
1719 && ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1722 && (!info->symbolic || !h->def_regular))))
1726 sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
1734 sreloc->size += sizeof (Elf32_External_Rela);
1741 if (is_reloc_for_PLT (howto) == TRUE)
1749 if (is_reloc_for_GOT (howto) == TRUE)
1754 if (local_got_ents[r_symndx] == NULL)
1757 ADD_SYMBOL_REF_SEC_AND_RELOC (got,
1758 bfd_link_pic (info),
1760 new_got_entry_to_list (&(local_got_ents[r_symndx]),
1761 GOT_NORMAL, offset, NONE);
1766 /* Global symbol. */
1767 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1768 if (h->got.glist == NULL)
1771 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1772 new_got_entry_to_list (&h->got.glist,
1773 GOT_NORMAL, offset, NONE);
1778 if (is_reloc_for_TLS (howto) == TRUE)
1780 enum tls_type_e type = GOT_UNKNOWN;
1784 case R_ARC_TLS_GD_GOT:
1787 case R_ARC_TLS_IE_GOT:
1794 struct got_entry **list = NULL;
1796 list = &(h->got.glist);
1798 list = &(local_got_ents[r_symndx]);
1800 if (type != GOT_UNKNOWN && !symbol_has_entry_of_type (*list, type))
1802 enum tls_got_entries entries = NONE;
1804 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1806 if (type == GOT_TLS_GD)
1808 bfd_vma ATTRIBUTE_UNUSED notneeded =
1809 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1810 entries = MOD_AND_OFF;
1813 if (entries == NONE)
1816 new_got_entry_to_list (list, type, offset, entries);
1824 #define ELF_DYNAMIC_INTERPRETER "/sbin/ld-uClibc.so"
1826 static struct plt_version_t *
1827 arc_get_plt_version (struct bfd_link_info *info)
1831 for (i = 0; i < 1; i++)
1833 ARC_DEBUG ("%d: size1 = %d, size2 = %d\n", i,
1834 plt_versions[i].entry_size,
1835 plt_versions[i].elem_size);
1838 if (bfd_get_mach (info->output_bfd) == bfd_mach_arc_arcv2)
1840 if (bfd_link_pic (info))
1841 return &(plt_versions[ELF_ARCV2_PIC]);
1843 return &(plt_versions[ELF_ARCV2_ABS]);
1847 if (bfd_link_pic (info))
1848 return &(plt_versions[ELF_ARC_PIC]);
1850 return &(plt_versions[ELF_ARC_ABS]);
1855 add_symbol_to_plt (struct bfd_link_info *info)
1857 struct elf_link_hash_table *htab = elf_hash_table (info);
1860 struct plt_version_t *plt_data = arc_get_plt_version (info);
1862 /* If this is the first .plt entry, make room for the special first
1864 if (htab->splt->size == 0)
1865 htab->splt->size += plt_data->entry_size;
1867 ret = htab->splt->size;
1869 htab->splt->size += plt_data->elem_size;
1870 ARC_DEBUG ("PLT_SIZE = %d\n", htab->splt->size);
1872 htab->sgotplt->size += 4;
1873 htab->srelplt->size += sizeof (Elf32_External_Rela);
1878 #define PLT_DO_RELOCS_FOR_ENTRY(ABFD, DS, RELOCS) \
1879 plt_do_relocs_for_symbol (ABFD, DS, RELOCS, 0, 0)
1882 plt_do_relocs_for_symbol (bfd *abfd,
1883 struct elf_link_hash_table *htab,
1884 const struct plt_reloc *reloc,
1886 bfd_vma symbol_got_offset)
1888 while (SYM_ONLY (reloc->symbol) != LAST_RELOC)
1890 bfd_vma relocation = 0;
1892 switch (SYM_ONLY (reloc->symbol))
1896 htab->sgotplt->output_section->vma +
1897 htab->sgotplt->output_offset + symbol_got_offset;
1900 relocation += reloc->addend;
1902 if (IS_RELATIVE (reloc->symbol))
1904 bfd_vma reloc_offset = reloc->offset;
1905 reloc_offset -= (IS_INSN_32 (reloc->symbol)) ? 4 : 0;
1906 reloc_offset -= (IS_INSN_24 (reloc->symbol)) ? 2 : 0;
1908 relocation -= htab->splt->output_section->vma
1909 + htab->splt->output_offset
1910 + plt_offset + reloc_offset;
1913 /* TODO: being ME is not a property of the relocation but of the
1914 section of which is applying the relocation. */
1915 if (IS_MIDDLE_ENDIAN (reloc->symbol) || bfd_big_endian (abfd))
1918 ((relocation & 0xffff0000) >> 16) |
1919 ((relocation & 0xffff) << 16);
1922 switch (reloc->size)
1925 bfd_put_32 (htab->splt->output_section->owner,
1927 htab->splt->contents + plt_offset + reloc->offset);
1931 reloc = &(reloc[1]); /* Jump to next relocation. */
1936 relocate_plt_for_symbol (bfd *output_bfd,
1937 struct bfd_link_info *info,
1938 struct elf_link_hash_entry *h)
1940 struct plt_version_t *plt_data = arc_get_plt_version (info);
1941 struct elf_link_hash_table *htab = elf_hash_table (info);
1943 bfd_vma plt_index = (h->plt.offset - plt_data->entry_size)
1944 / plt_data->elem_size;
1945 bfd_vma got_offset = (plt_index + 3) * 4;
1947 ARC_DEBUG ("arc_info: PLT_OFFSET = 0x%x, PLT_ENTRY_VMA = 0x%x, \
1948 GOT_ENTRY_OFFSET = 0x%x, GOT_ENTRY_VMA = 0x%x, for symbol %s\n",
1950 htab->splt->output_section->vma
1951 + htab->splt->output_offset
1954 htab->sgotplt->output_section->vma
1955 + htab->sgotplt->output_offset
1957 h->root.root.string);
1959 memcpy (htab->splt->contents + h->plt.offset,
1961 plt_data->elem_size);
1962 plt_do_relocs_for_symbol (output_bfd, htab,
1963 plt_data->elem_relocs,
1967 /* Fill in the entry in the global offset table. */
1968 bfd_put_32 (output_bfd,
1969 (bfd_vma) (htab->splt->output_section->vma
1970 + htab->splt->output_offset),
1971 htab->sgotplt->contents + got_offset);
1973 /* TODO: Fill in the entry in the .rela.plt section. */
1975 Elf_Internal_Rela rel;
1978 rel.r_offset = (htab->sgotplt->output_section->vma
1979 + htab->sgotplt->output_offset
1982 rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_JMP_SLOT);
1984 loc = htab->srelplt->contents;
1985 loc += plt_index * sizeof (Elf32_External_Rela); /* relA */
1986 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
1991 relocate_plt_for_entry (bfd *abfd,
1992 struct bfd_link_info *info)
1994 struct plt_version_t *plt_data = arc_get_plt_version (info);
1995 struct elf_link_hash_table *htab = elf_hash_table (info);
1997 memcpy (htab->splt->contents, plt_data->entry,
1998 plt_data->entry_size);
1999 PLT_DO_RELOCS_FOR_ENTRY (abfd, htab, plt_data->entry_relocs);
2002 /* Desc : Adjust a symbol defined by a dynamic object and referenced
2003 by a regular object. The current definition is in some section of
2004 the dynamic object, but we're not including those sections. We
2005 have to change the definition to something the rest of the link can
2009 elf_arc_adjust_dynamic_symbol (struct bfd_link_info *info,
2010 struct elf_link_hash_entry *h)
2013 unsigned int power_of_two;
2014 bfd *dynobj = (elf_hash_table (info))->dynobj;
2015 struct elf_link_hash_table *htab = elf_hash_table (info);
2017 if (h->type == STT_FUNC
2018 || h->type == STT_GNU_IFUNC
2019 || h->needs_plt == 1)
2021 if (!bfd_link_pic (info) && !h->def_dynamic && !h->ref_dynamic)
2023 /* This case can occur if we saw a PLT32 reloc in an input
2024 file, but the symbol was never referred to by a dynamic
2025 object. In such a case, we don't actually need to build
2026 a procedure linkage table, and we can just do a PC32
2028 BFD_ASSERT (h->needs_plt);
2032 /* Make sure this symbol is output as a dynamic symbol. */
2033 if (h->dynindx == -1 && !h->forced_local
2034 && !bfd_elf_link_record_dynamic_symbol (info, h))
2037 if (bfd_link_pic (info)
2038 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
2040 bfd_vma loc = add_symbol_to_plt (info);
2042 if (!bfd_link_pic (info) && !h->def_regular)
2044 h->root.u.def.section = htab->splt;
2045 h->root.u.def.value = loc;
2047 h->plt.offset = loc;
2051 h->plt.offset = (bfd_vma) -1;
2057 /* If this is a weak symbol, and there is a real definition, the
2058 processor independent code will have arranged for us to see the
2059 real definition first, and we can just use the same value. */
2060 if (h->u.weakdef != NULL)
2062 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2063 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2064 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2065 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2069 /* If there are no non-GOT references, we do not need a copy
2071 if (!h->non_got_ref)
2074 /* This is a reference to a symbol defined by a dynamic object which
2075 is not a function. */
2077 /* If we are creating a shared library, we must presume that the
2078 only references to the symbol are via the global offset table.
2079 For such cases we need not do anything here; the relocations will
2080 be handled correctly by relocate_section. */
2081 if (bfd_link_pic (info))
2084 /* We must allocate the symbol in our .dynbss section, which will
2085 become part of the .bss section of the executable. There will be
2086 an entry for this symbol in the .dynsym section. The dynamic
2087 object will contain position independent code, so all references
2088 from the dynamic object to this symbol will go through the global
2089 offset table. The dynamic linker will use the .dynsym entry to
2090 determine the address it must put in the global offset table, so
2091 both the dynamic object and the regular object will refer to the
2092 same memory location for the variable. */
2094 s = bfd_get_section_by_name (dynobj, ".dynbss");
2095 BFD_ASSERT (s != NULL);
2097 /* We must generate a R_ARC_COPY reloc to tell the dynamic linker to
2098 copy the initial value out of the dynamic object and into the
2099 runtime process image. We need to remember the offset into the
2100 .rela.bss section we are going to use. */
2101 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2105 srel = bfd_get_section_by_name (dynobj, ".rela.bss");
2106 BFD_ASSERT (srel != NULL);
2107 srel->size += sizeof (Elf32_External_Rela);
2111 /* We need to figure out the alignment required for this symbol. I
2112 have no idea how ELF linkers handle this. */
2113 power_of_two = bfd_log2 (h->size);
2114 if (power_of_two > 3)
2117 /* Apply the required alignment. */
2118 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
2119 if (power_of_two > bfd_get_section_alignment (dynobj, s))
2121 if (! bfd_set_section_alignment (dynobj, s, power_of_two))
2125 /* Define the symbol as being at this point in the section. */
2126 h->root.u.def.section = s;
2127 h->root.u.def.value = s->size;
2129 /* Increment the section size to make room for the symbol. */
2135 /* Function : elf_arc_finish_dynamic_symbol
2136 Brief : Finish up dynamic symbol handling. We set the
2137 contents of various dynamic sections here.
2142 Returns : True/False as the return status. */
2145 elf_arc_finish_dynamic_symbol (bfd * output_bfd,
2146 struct bfd_link_info *info,
2147 struct elf_link_hash_entry *h,
2148 Elf_Internal_Sym * sym)
2150 if (h->plt.offset != (bfd_vma) -1)
2152 relocate_plt_for_symbol (output_bfd, info, h);
2154 if (!h->def_regular)
2156 /* Mark the symbol as undefined, rather than as defined in
2157 the .plt section. Leave the value alone. */
2158 sym->st_shndx = SHN_UNDEF;
2162 if (h->got.glist != NULL)
2164 struct got_entry *list = h->got.glist;
2166 /* Traverse the list of got entries for this symbol. */
2169 bfd_vma got_offset = h->got.glist->offset;
2171 if (list->type == GOT_NORMAL
2172 && list->created_dyn_relocation == FALSE)
2174 if (bfd_link_pic (info)
2175 && (info->symbolic || h->dynindx == -1)
2178 ADD_RELA (output_bfd, got, got_offset, 0, R_ARC_RELATIVE, 0);
2182 ADD_RELA (output_bfd, got, got_offset, h->dynindx,
2185 list->created_dyn_relocation = TRUE;
2187 else if (list->existing_entries != NONE)
2189 struct elf_link_hash_table *htab = elf_hash_table (info);
2190 enum tls_got_entries e = list->existing_entries;
2192 BFD_ASSERT (list->type != GOT_TLS_GD
2193 || list->existing_entries == MOD_AND_OFF);
2195 bfd_vma dynindx = h->dynindx == -1 ? 0 : h->dynindx;
2196 if (e == MOD_AND_OFF || e == MOD)
2198 ADD_RELA (output_bfd, got, got_offset, dynindx,
2199 R_ARC_TLS_DTPMOD, 0);
2200 ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2201 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2204 htab->sgot->output_section->vma
2205 + htab->sgot->output_offset + got_offset,
2208 if (e == MOD_AND_OFF || e == OFF)
2211 if (list->type == GOT_TLS_IE)
2212 addend = bfd_get_32 (output_bfd,
2213 htab->sgot->contents + got_offset);
2215 ADD_RELA (output_bfd, got,
2216 got_offset + (e == MOD_AND_OFF ? 4 : 0),
2218 (list->type == GOT_TLS_IE ?
2219 R_ARC_TLS_TPOFF : R_ARC_TLS_DTPOFF),
2222 ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2223 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2226 htab->sgot->output_section->vma
2227 + htab->sgot->output_offset + got_offset,
2235 h->got.glist = NULL;
2240 bfd_vma rel_offset = (h->root.u.def.value
2241 + h->root.u.def.section->output_section->vma
2242 + h->root.u.def.section->output_offset);
2245 bfd_get_section_by_name (h->root.u.def.section->owner,
2248 bfd_byte * loc = srelbss->contents
2249 + (srelbss->reloc_count * sizeof (Elf32_External_Rela));
2250 srelbss->reloc_count++;
2252 Elf_Internal_Rela rel;
2254 rel.r_offset = rel_offset;
2255 rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_COPY);
2257 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2260 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
2261 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2262 || strcmp (h->root.root.string, "__DYNAMIC") == 0
2263 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
2264 sym->st_shndx = SHN_ABS;
2269 #define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION, ASSERT) \
2271 if (SYMBOL != NULL) \
2273 h = elf_link_hash_lookup (elf_hash_table (info), \
2274 SYMBOL, FALSE, FALSE, TRUE); \
2276 else if (SECTION != NULL) \
2278 s = bfd_get_section_by_name (output_bfd, SECTION); \
2279 BFD_ASSERT (s != NULL || !ASSERT); \
2284 /* Function : elf_arc_finish_dynamic_sections
2285 Brief : Finish up the dynamic sections handling.
2290 Returns : True/False as the return status. */
2293 elf_arc_finish_dynamic_sections (bfd * output_bfd,
2294 struct bfd_link_info *info)
2296 struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
2297 struct elf_link_hash_table *htab = elf_hash_table (info);
2298 bfd *dynobj = (elf_hash_table (info))->dynobj;
2302 Elf32_External_Dyn *dyncon, *dynconend;
2304 dyncon = (Elf32_External_Dyn *) ds.sdyn->contents;
2306 (Elf32_External_Dyn *) (ds.sdyn->contents + ds.sdyn->size);
2307 for (; dyncon < dynconend; dyncon++)
2309 Elf_Internal_Dyn internal_dyn;
2310 bfd_boolean do_it = FALSE;
2312 struct elf_link_hash_entry *h = NULL;
2315 bfd_elf32_swap_dyn_in (dynobj, dyncon, &internal_dyn);
2317 switch (internal_dyn.d_tag)
2319 GET_SYMBOL_OR_SECTION (DT_INIT, "_init", NULL, TRUE)
2320 GET_SYMBOL_OR_SECTION (DT_FINI, "_fini", NULL, TRUE)
2321 GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt", TRUE)
2322 GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt", TRUE)
2323 GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt", TRUE)
2324 GET_SYMBOL_OR_SECTION (DT_RELASZ, NULL, ".rela.plt", FALSE)
2325 GET_SYMBOL_OR_SECTION (DT_VERSYM, NULL, ".gnu.version", TRUE)
2326 GET_SYMBOL_OR_SECTION (DT_VERDEF, NULL, ".gnu.version_d", TRUE)
2327 GET_SYMBOL_OR_SECTION (DT_VERNEED, NULL, ".gnu.version_r", TRUE)
2332 /* In case the dynamic symbols should be updated with a symbol. */
2334 && (h->root.type == bfd_link_hash_defined
2335 || h->root.type == bfd_link_hash_defweak))
2339 internal_dyn.d_un.d_val = h->root.u.def.value;
2340 asec_ptr = h->root.u.def.section;
2341 if (asec_ptr->output_section != NULL)
2343 internal_dyn.d_un.d_val +=
2344 (asec_ptr->output_section->vma +
2345 asec_ptr->output_offset);
2349 /* The symbol is imported from another shared
2350 library and does not apply to this one. */
2351 internal_dyn.d_un.d_val = 0;
2355 else if (s != NULL) /* With a section information. */
2357 switch (internal_dyn.d_tag)
2364 internal_dyn.d_un.d_ptr = s->vma;
2369 internal_dyn.d_un.d_val = s->size;
2375 internal_dyn.d_un.d_val -= s->size;
2385 bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon);
2388 if (htab->splt->size > 0)
2390 relocate_plt_for_entry (output_bfd, info);
2393 /* TODO: Validate this. */
2394 elf_section_data (htab->srelplt->output_section)->this_hdr.sh_entsize
2398 /* Fill in the first three entries in the global offset table. */
2401 if (htab->sgot->size > 0 || htab->sgotplt->size > 0)
2403 if (ds.sdyn == NULL)
2404 bfd_put_32 (output_bfd, (bfd_vma) 0,
2405 htab->sgotplt->contents);
2407 bfd_put_32 (output_bfd,
2408 ds.sdyn->output_section->vma + ds.sdyn->output_offset,
2409 htab->sgotplt->contents);
2410 bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 4);
2411 bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 8);
2418 #define ADD_DYNAMIC_SYMBOL(NAME, TAG) \
2419 h = elf_link_hash_lookup (elf_hash_table (info), \
2420 NAME, FALSE, FALSE, FALSE); \
2421 if ((h != NULL && (h->ref_regular || h->def_regular))) \
2422 if (! _bfd_elf_add_dynamic_entry (info, TAG, 0)) \
2425 /* Set the sizes of the dynamic sections. */
2427 elf_arc_size_dynamic_sections (bfd * output_bfd,
2428 struct bfd_link_info *info)
2432 bfd_boolean relocs_exist = FALSE;
2433 bfd_boolean reltext_exist = FALSE;
2434 struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
2435 struct elf_link_hash_table *htab = elf_hash_table (info);
2437 dynobj = (elf_hash_table (info))->dynobj;
2438 BFD_ASSERT (dynobj != NULL);
2440 if ((elf_hash_table (info))->dynamic_sections_created)
2442 struct elf_link_hash_entry *h;
2444 /* Set the contents of the .interp section to the
2446 if (!bfd_link_pic (info))
2448 s = bfd_get_section_by_name (dynobj, ".interp");
2449 BFD_ASSERT (s != NULL);
2450 s->size = sizeof (ELF_DYNAMIC_INTERPRETER);
2451 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2454 /* Add some entries to the .dynamic section. We fill in some of
2455 the values later, in elf_bfd_final_link, but we must add the
2456 entries now so that we know the final size of the .dynamic
2457 section. Checking if the .init section is present. We also
2458 create DT_INIT and DT_FINI entries if the init_str has been
2459 changed by the user. */
2460 ADD_DYNAMIC_SYMBOL ("init", DT_INIT);
2461 ADD_DYNAMIC_SYMBOL ("fini", DT_FINI);
2465 /* We may have created entries in the .rela.got section.
2466 However, if we are not creating the dynamic sections, we will
2467 not actually use these entries. Reset the size of .rela.got,
2468 which will cause it to get stripped from the output file
2470 if (htab->srelgot != NULL)
2471 htab->srelgot->size = 0;
2474 if (htab->splt != NULL && htab->splt->size == 0)
2475 htab->splt->flags |= SEC_EXCLUDE;
2476 for (s = dynobj->sections; s != NULL; s = s->next)
2478 if ((s->flags & SEC_LINKER_CREATED) == 0)
2481 if (strncmp (s->name, ".rela", 5) == 0)
2485 s->flags |= SEC_EXCLUDE;
2489 if (strcmp (s->name, ".rela.plt") != 0)
2491 const char *outname =
2492 bfd_get_section_name (output_bfd,
2493 htab->srelplt->output_section);
2495 asection *target = bfd_get_section_by_name (output_bfd,
2498 relocs_exist = TRUE;
2499 if (target != NULL && target->size != 0
2500 && (target->flags & SEC_READONLY) != 0
2501 && (target->flags & SEC_ALLOC) != 0)
2502 reltext_exist = TRUE;
2506 /* We use the reloc_count field as a counter if we need to
2507 copy relocs into the output file. */
2511 if (strcmp (s->name, ".dynamic") == 0)
2515 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2517 if (s->contents == NULL && s->size != 0)
2523 /* TODO: Check if this is needed. */
2524 if (!bfd_link_pic (info))
2525 if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
2528 if (htab->splt && (htab->splt->flags & SEC_EXCLUDE) == 0)
2529 if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
2530 || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2531 || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2532 || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0)
2536 if (relocs_exist == TRUE)
2537 if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
2538 || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
2539 || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
2540 sizeof (Elf32_External_Rela))
2544 if (reltext_exist == TRUE)
2545 if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
2552 const struct elf_size_info arc_elf32_size_info =
2554 sizeof (Elf32_External_Ehdr),
2555 sizeof (Elf32_External_Phdr),
2556 sizeof (Elf32_External_Shdr),
2557 sizeof (Elf32_External_Rel),
2558 sizeof (Elf32_External_Rela),
2559 sizeof (Elf32_External_Sym),
2560 sizeof (Elf32_External_Dyn),
2561 sizeof (Elf_External_Note),
2565 ELFCLASS32, EV_CURRENT,
2566 bfd_elf32_write_out_phdrs,
2567 bfd_elf32_write_shdrs_and_ehdr,
2568 bfd_elf32_checksum_contents,
2569 bfd_elf32_write_relocs,
2570 bfd_elf32_swap_symbol_in,
2571 bfd_elf32_swap_symbol_out,
2572 bfd_elf32_slurp_reloc_table,
2573 bfd_elf32_slurp_symbol_table,
2574 bfd_elf32_swap_dyn_in,
2575 bfd_elf32_swap_dyn_out,
2576 bfd_elf32_swap_reloc_in,
2577 bfd_elf32_swap_reloc_out,
2578 bfd_elf32_swap_reloca_in,
2579 bfd_elf32_swap_reloca_out
2582 #define elf_backend_size_info arc_elf32_size_info
2584 static struct bfd_link_hash_table *
2585 arc_elf_link_hash_table_create (bfd *abfd)
2587 struct elf_link_hash_table *htab;
2589 htab = bfd_zmalloc (sizeof (*htab));
2593 if (!_bfd_elf_link_hash_table_init (htab, abfd,
2594 _bfd_elf_link_hash_newfunc,
2595 sizeof (struct elf_link_hash_entry),
2602 htab->init_got_refcount.refcount = 0;
2603 htab->init_got_refcount.glist = NULL;
2604 htab->init_got_offset.offset = 0;
2605 htab->init_got_offset.glist = NULL;
2606 return (struct bfd_link_hash_table *) htab;
2609 /* Hook called by the linker routine which adds symbols from an object
2613 elf_arc_add_symbol_hook (bfd * abfd,
2614 struct bfd_link_info * info,
2615 Elf_Internal_Sym * sym,
2616 const char ** namep ATTRIBUTE_UNUSED,
2617 flagword * flagsp ATTRIBUTE_UNUSED,
2618 asection ** secp ATTRIBUTE_UNUSED,
2619 bfd_vma * valp ATTRIBUTE_UNUSED)
2621 if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
2622 || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
2623 && (abfd->flags & DYNAMIC) == 0
2624 && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
2625 elf_tdata (info->output_bfd)->has_gnu_symbols = elf_gnu_symbol_any;
2630 #define TARGET_LITTLE_SYM arc_elf32_le_vec
2631 #define TARGET_LITTLE_NAME "elf32-littlearc"
2632 #define TARGET_BIG_SYM arc_elf32_be_vec
2633 #define TARGET_BIG_NAME "elf32-bigarc"
2634 #define ELF_ARCH bfd_arch_arc
2635 #define ELF_MACHINE_CODE EM_ARC_COMPACT
2636 #define ELF_MACHINE_ALT1 EM_ARC_COMPACT2
2637 #define ELF_MAXPAGESIZE 0x2000
2639 #define bfd_elf32_bfd_link_hash_table_create arc_elf_link_hash_table_create
2641 #define bfd_elf32_bfd_merge_private_bfd_data arc_elf_merge_private_bfd_data
2642 #define bfd_elf32_bfd_reloc_type_lookup arc_elf32_bfd_reloc_type_lookup
2643 #define bfd_elf32_bfd_set_private_flags arc_elf_set_private_flags
2644 #define bfd_elf32_bfd_print_private_bfd_data arc_elf_print_private_bfd_data
2645 #define bfd_elf32_bfd_copy_private_bfd_data arc_elf_copy_private_bfd_data
2647 #define elf_info_to_howto_rel arc_info_to_howto_rel
2648 #define elf_backend_object_p arc_elf_object_p
2649 #define elf_backend_final_write_processing arc_elf_final_write_processing
2651 #define elf_backend_relocate_section elf_arc_relocate_section
2652 #define elf_backend_check_relocs elf_arc_check_relocs
2653 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
2655 #define elf_backend_adjust_dynamic_symbol elf_arc_adjust_dynamic_symbol
2656 #define elf_backend_finish_dynamic_symbol elf_arc_finish_dynamic_symbol
2658 #define elf_backend_finish_dynamic_sections elf_arc_finish_dynamic_sections
2659 #define elf_backend_size_dynamic_sections elf_arc_size_dynamic_sections
2660 #define elf_backend_add_symbol_hook elf_arc_add_symbol_hook
2662 #define elf_backend_can_gc_sections 1
2663 #define elf_backend_want_got_plt 1
2664 #define elf_backend_plt_readonly 1
2665 #define elf_backend_rela_plts_and_copies_p 1
2666 #define elf_backend_want_plt_sym 0
2667 #define elf_backend_got_header_size 12
2669 #define elf_backend_may_use_rel_p 0
2670 #define elf_backend_may_use_rela_p 1
2671 #define elf_backend_default_use_rela_p 1
2673 #include "elf32-target.h"