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_get_32(A,B,C) bfd_get_32(A,B)
256 #define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C)
257 #define arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
258 #define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)
261 static bfd_reloc_status_type
262 arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
263 arelent *reloc_entry,
265 void *data ATTRIBUTE_UNUSED,
266 asection *input_section,
268 char ** error_message ATTRIBUTE_UNUSED)
270 if (output_bfd != NULL)
272 reloc_entry->address += input_section->output_offset;
274 /* In case of relocateable link and if the reloc is against a
275 section symbol, the addend needs to be adjusted according to
276 where the section symbol winds up in the output section. */
277 if ((symbol_in->flags & BSF_SECTION_SYM) && symbol_in->section)
278 reloc_entry->addend += symbol_in->section->output_offset;
283 return bfd_reloc_continue;
287 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
291 #include "elf/arc-reloc.def"
294 #undef ARC_RELOC_HOWTO
296 #define ARC_RELOC_HOWTO(TYPE, VALUE, RSIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
297 [TYPE] = HOWTO (R_##TYPE, 0, RSIZE, BITSIZE, FALSE, 0, complain_overflow_##OVERFLOW, arc_elf_reloc, "R_" #TYPE, FALSE, 0, 0, FALSE),
299 static struct reloc_howto_struct elf_arc_howto_table[] =
301 #include "elf/arc-reloc.def"
302 /* Example of what is generated by the preprocessor. Currently kept as an
304 HOWTO (R_ARC_NONE, // Type.
306 2, // Size (0 = byte, 1 = short, 2 = long).
308 FALSE, // PC_relative.
310 complain_overflow_bitfield, // Complain_on_overflow.
311 bfd_elf_generic_reloc, // Special_function.
312 "R_ARC_NONE", // Name.
313 TRUE, // Partial_inplace.
316 FALSE), // PCrel_offset.
319 #undef ARC_RELOC_HOWTO
321 static void arc_elf_howto_init (void)
323 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
324 elf_arc_howto_table[TYPE].pc_relative = \
325 (strstr (#FORMULA, " P ") != NULL || strstr (#FORMULA, " PDATA ") != NULL); \
326 elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0); \
327 /* Only 32 bit data relocations should be marked as ME. */ \
328 if (strstr (#FORMULA, " ME ") != NULL) \
330 BFD_ASSERT (SIZE == 2); \
333 #include "elf/arc-reloc.def"
336 #undef ARC_RELOC_HOWTO
339 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
341 const int howto_table_lookup[] =
343 #include "elf/arc-reloc.def"
345 #undef ARC_RELOC_HOWTO
347 static reloc_howto_type *
348 arc_elf_howto (unsigned int r_type)
350 if (elf_arc_howto_table[R_ARC_32].dst_mask == 0)
351 arc_elf_howto_init ();
352 return &elf_arc_howto_table[r_type];
355 /* Map BFD reloc types to ARC ELF reloc types. */
359 bfd_reloc_code_real_type bfd_reloc_val;
360 unsigned char elf_reloc_val;
363 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
364 { BFD_RELOC_##TYPE, R_##TYPE },
365 static const struct arc_reloc_map arc_reloc_map[] =
367 #include "elf/arc-reloc.def"
369 {BFD_RELOC_NONE, R_ARC_NONE},
370 {BFD_RELOC_8, R_ARC_8},
371 {BFD_RELOC_16, R_ARC_16},
372 {BFD_RELOC_24, R_ARC_24},
373 {BFD_RELOC_32, R_ARC_32},
375 #undef ARC_RELOC_HOWTO
377 static reloc_howto_type *
378 arc_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
379 bfd_reloc_code_real_type code)
383 for (i = ARRAY_SIZE (arc_reloc_map); i--;)
385 if (arc_reloc_map[i].bfd_reloc_val == code)
386 return arc_elf_howto (arc_reloc_map[i].elf_reloc_val);
392 /* Function to set the ELF flag bits. */
394 arc_elf_set_private_flags (bfd *abfd, flagword flags)
396 elf_elfheader (abfd)->e_flags = flags;
397 elf_flags_init (abfd) = TRUE;
401 /* Print private flags. */
403 arc_elf_print_private_bfd_data (bfd *abfd, void * ptr)
405 FILE *file = (FILE *) ptr;
408 BFD_ASSERT (abfd != NULL && ptr != NULL);
410 /* Print normal ELF private data. */
411 _bfd_elf_print_private_bfd_data (abfd, ptr);
413 flags = elf_elfheader (abfd)->e_flags;
414 fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
416 switch (flags & EF_ARC_MACH_MSK)
418 case EF_ARC_CPU_GENERIC : fprintf (file, " -mcpu=generic"); break;
419 case EF_ARC_CPU_ARCV2HS : fprintf (file, " -mcpu=ARCv2HS"); break;
420 case EF_ARC_CPU_ARCV2EM : fprintf (file, " -mcpu=ARCv2EM"); break;
421 case E_ARC_MACH_ARC600 : fprintf (file, " -mcpu=ARC600"); break;
422 case E_ARC_MACH_ARC601 : fprintf (file, " -mcpu=ARC601"); break;
423 case E_ARC_MACH_ARC700 : fprintf (file, " -mcpu=ARC700"); break;
425 fprintf (file, "-mcpu=unknown");
429 switch (flags & EF_ARC_OSABI_MSK)
431 case E_ARC_OSABI_ORIG : fprintf (file, " (ABI:legacy)"); break;
432 case E_ARC_OSABI_V2 : fprintf (file, " (ABI:v2)"); break;
433 case E_ARC_OSABI_V3 : fprintf (file, " (ABI:v3)"); break;
435 fprintf (file, "(ABI:unknown)");
443 /* Copy backend specific data from one object module to another. */
446 arc_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
448 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
449 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
452 BFD_ASSERT (!elf_flags_init (obfd)
453 || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
455 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
456 elf_flags_init (obfd) = TRUE;
458 /* Copy object attributes. */
459 _bfd_elf_copy_obj_attributes (ibfd, obfd);
461 return _bfd_elf_copy_private_bfd_data (ibfd, obfd);
464 static reloc_howto_type *
465 bfd_elf32_bfd_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED,
470 for (i = 0; i < ARRAY_SIZE (elf_arc_howto_table); i++)
471 if (elf_arc_howto_table[i].name != NULL
472 && strcasecmp (elf_arc_howto_table[i].name, r_name) == 0)
473 return arc_elf_howto (i);
478 /* Set the howto pointer for an ARC ELF reloc. */
481 arc_info_to_howto_rel (bfd * abfd ATTRIBUTE_UNUSED,
483 Elf_Internal_Rela * dst)
487 r_type = ELF32_R_TYPE (dst->r_info);
488 BFD_ASSERT (r_type < (unsigned int) R_ARC_max);
489 cache_ptr->howto = arc_elf_howto (r_type);
492 /* Merge backend specific data from an object file to the output
493 object file when linking. */
496 arc_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
498 unsigned short mach_ibfd;
499 static unsigned short mach_obfd = EM_NONE;
504 /* Check if we have the same endianess. */
505 if (! _bfd_generic_verify_endian_match (ibfd, obfd))
507 _bfd_error_handler (_("ERROR: Endian Match failed. Attempting to link "
508 "%B with binary %s of opposite endian-ness"),
509 ibfd, bfd_get_filename (obfd));
513 /* Collect ELF flags. */
514 in_flags = elf_elfheader (ibfd)->e_flags & EF_ARC_MACH_MSK;
515 out_flags = elf_elfheader (obfd)->e_flags & EF_ARC_MACH_MSK;
517 if (!elf_flags_init (obfd)) /* First call, no flags set. */
519 elf_flags_init (obfd) = TRUE;
520 out_flags = in_flags;
523 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
524 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
527 /* Check to see if the input BFD actually contains any sections. Do
528 not short-circuit dynamic objects; their section list may be
529 emptied by elf_link_add_object_symbols. */
530 if (!(ibfd->flags & DYNAMIC))
532 bfd_boolean null_input_bfd = TRUE;
533 bfd_boolean only_data_sections = TRUE;
535 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
537 if ((bfd_get_section_flags (ibfd, sec)
538 & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
539 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
540 only_data_sections = FALSE;
542 null_input_bfd = FALSE;
545 if (null_input_bfd || only_data_sections)
549 /* Complain about various flag/architecture mismatches. */
550 mach_ibfd = elf_elfheader (ibfd)->e_machine;
551 if (mach_obfd == EM_NONE)
553 mach_obfd = mach_ibfd;
557 if (mach_ibfd != mach_obfd)
559 _bfd_error_handler (_("ERROR: Attempting to link %B "
560 "with a binary %s of different architecture"),
561 ibfd, bfd_get_filename (obfd));
564 else if (in_flags != out_flags)
566 /* Warn if different flags. */
567 (*_bfd_error_handler)
568 (_("%s: uses different e_flags (0x%lx) fields than "
569 "previous modules (0x%lx)"),
570 bfd_get_filename (ibfd), (long)in_flags, (long)out_flags);
571 if (in_flags && out_flags)
573 /* MWDT doesnt set the eflags hence make sure we choose the
574 eflags set by gcc. */
575 in_flags = in_flags > out_flags ? in_flags : out_flags;
579 /* Update the flags. */
580 elf_elfheader (obfd)->e_flags = in_flags;
582 if (bfd_get_mach (obfd) < bfd_get_mach (ibfd))
584 return bfd_set_arch_mach (obfd, bfd_arch_arc, bfd_get_mach (ibfd));
590 /* Set the right machine number for an ARC ELF file. */
592 arc_elf_object_p (bfd * abfd)
594 /* Make sure this is initialised, or you'll have the potential of passing
595 garbage---or misleading values---into the call to
596 bfd_default_set_arch_mach (). */
597 int mach = bfd_mach_arc_arc700;
598 unsigned long arch = elf_elfheader (abfd)->e_flags & EF_ARC_MACH_MSK;
599 unsigned e_machine = elf_elfheader (abfd)->e_machine;
601 if (e_machine == EM_ARC_COMPACT || e_machine == EM_ARC_COMPACT2)
605 case E_ARC_MACH_ARC600:
606 mach = bfd_mach_arc_arc600;
608 case E_ARC_MACH_ARC601:
609 mach = bfd_mach_arc_arc601;
611 case E_ARC_MACH_ARC700:
612 mach = bfd_mach_arc_arc700;
614 case EF_ARC_CPU_ARCV2HS:
615 case EF_ARC_CPU_ARCV2EM:
616 mach = bfd_mach_arc_arcv2;
619 mach = (e_machine == EM_ARC_COMPACT) ?
620 bfd_mach_arc_arc700 : bfd_mach_arc_arcv2;
626 if (e_machine == EM_ARC)
628 (*_bfd_error_handler)
629 (_("Error: The ARC4 architecture is no longer supported.\n"));
634 (*_bfd_error_handler)
635 (_("Warning: unset or old architecture flags. \n"
636 " Use default machine.\n"));
640 return bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach);
643 /* The final processing done just before writing out an ARC ELF object file.
644 This gets the ARC architecture right based on the machine number. */
647 arc_elf_final_write_processing (bfd * abfd,
648 bfd_boolean linker ATTRIBUTE_UNUSED)
653 switch (bfd_get_mach (abfd))
655 case bfd_mach_arc_arc600:
656 val = E_ARC_MACH_ARC600;
657 emf = EM_ARC_COMPACT;
659 case bfd_mach_arc_arc601:
660 val = E_ARC_MACH_ARC601;
661 emf = EM_ARC_COMPACT;
663 case bfd_mach_arc_arc700:
664 val = E_ARC_MACH_ARC700;
665 emf = EM_ARC_COMPACT;
667 case bfd_mach_arc_arcv2:
668 val = EF_ARC_CPU_GENERIC;
669 emf = EM_ARC_COMPACT2;
670 /* TODO: Check validity of this. It can also be ARCV2EM here.
671 Previous version sets the e_machine here. */
676 if ((elf_elfheader (abfd)->e_flags & EF_ARC_MACH) == EF_ARC_CPU_GENERIC)
677 elf_elfheader (abfd)->e_flags |= val;
679 elf_elfheader (abfd)->e_machine = emf;
681 /* Record whatever is the current syscall ABI version. */
682 elf_elfheader (abfd)->e_flags |= E_ARC_OSABI_CURRENT;
685 #define BFD_DEBUG_PIC(...)
687 struct arc_relocation_data
689 bfd_vma reloc_offset;
690 bfd_vma reloc_addend;
691 bfd_vma got_offset_value;
694 asection * sym_section;
696 reloc_howto_type *howto;
698 asection * input_section;
700 bfd_vma sdata_begin_symbol_vma;
701 bfd_boolean sdata_begin_symbol_vma_set;
702 bfd_vma got_symbol_vma;
704 bfd_boolean should_relocate;
708 debug_arc_reloc (struct arc_relocation_data reloc_data)
710 PR_DEBUG ("Reloc type=%s, should_relocate = %s\n",
711 reloc_data.howto->name,
712 reloc_data.should_relocate ? "true" : "false");
713 PR_DEBUG (" offset = 0x%x, addend = 0x%x\n",
714 (unsigned int) reloc_data.reloc_offset,
715 (unsigned int) reloc_data.reloc_addend);
716 PR_DEBUG (" Symbol:\n");
717 PR_DEBUG (" value = 0x%08x\n",
718 (unsigned int) reloc_data.sym_value);
719 if (reloc_data.sym_section != NULL)
721 PR_DEBUG ("IN IF\n");
723 " section name = %s, output_offset 0x%08x",
724 reloc_data.sym_section->name,
725 (unsigned int) reloc_data.sym_section->output_offset);
726 if (reloc_data.sym_section->output_section != NULL)
729 ", output_section->vma = 0x%08x",
730 ((unsigned int) reloc_data.sym_section->output_section->vma));
737 PR_DEBUG ( " symbol section is NULL\n");
740 PR_DEBUG ( " Input_section:\n");
741 if (reloc_data.input_section != NULL)
744 " section name = %s, output_offset 0x%08x, output_section->vma = 0x%08x\n",
745 reloc_data.input_section->name,
746 (unsigned int) reloc_data.input_section->output_offset,
747 (unsigned int) reloc_data.input_section->output_section->vma);
748 PR_DEBUG ( " changed_address = 0x%08x\n",
749 (unsigned int) (reloc_data.input_section->output_section->vma +
750 reloc_data.input_section->output_offset +
751 reloc_data.reloc_offset));
755 PR_DEBUG ( " input section is NULL\n");
760 middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
765 ((insn & 0xffff0000) >> 16) |
766 ((insn & 0xffff) << 16);
771 #define ME(reloc) (reloc)
773 #define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") != NULL) \
774 && (!bfd_big_endian (BFD)))
776 #define S (reloc_data.sym_value \
777 + (reloc_data.sym_section->output_section != NULL ? \
778 (reloc_data.sym_section->output_offset \
779 + reloc_data.sym_section->output_section->vma) : 0) \
781 #define L (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 A (reloc_data.reloc_addend)
788 #define G (reloc_data.got_offset_value)
789 #define GOT (reloc_data.got_symbol_vma)
790 #define GOT_BEGIN (htab->sgot->output_section->vma)
793 /* P: relative offset to PCL The offset should be to the
794 current location aligned to 32 bits. */
797 (reloc_data.input_section->output_section != NULL ? \
798 reloc_data.input_section->output_section->vma : 0) \
799 + reloc_data.input_section->output_offset \
800 + (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0)) \
803 (reloc_data.input_section->output_section->vma \
804 + reloc_data.input_section->output_offset \
805 + (reloc_data.reloc_offset) \
807 #define SECTSTAR (reloc_data.input_section->output_offset)
808 #define SECTSTART (reloc_data.input_section->output_offset)
809 #define _SDA_BASE_ (reloc_data.sdata_begin_symbol_vma)
810 #define TLS_REL ((elf_hash_table (info))->tls_sec->output_section->vma)
811 #define _SDA_BASE_ (reloc_data.sdata_begin_symbol_vma)
817 #define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA) \
819 asection *sym_section = reloc_data.sym_section; \
820 asection *input_section = reloc_data.input_section; \
821 ARC_DEBUG ("FORMULA = " #FORMULA "\n"); \
822 ARC_DEBUG ("S = 0x%x\n", S); \
823 ARC_DEBUG ("A = 0x%x\n", A); \
824 ARC_DEBUG ("L = 0x%x\n", L); \
825 if (sym_section->output_section != NULL) \
827 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
828 sym_section->output_section->vma + sym_section->output_offset); \
832 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
834 if (input_section->output_section != NULL) \
836 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
837 input_section->output_section->vma + input_section->output_offset); \
841 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
843 ARC_DEBUG ("PCL = 0x%x\n", P); \
844 ARC_DEBUG ("P = 0x%x\n", P); \
845 ARC_DEBUG ("G = 0x%x\n", G); \
846 ARC_DEBUG ("SDA_OFFSET = 0x%x\n", _SDA_BASE_); \
847 ARC_DEBUG ("SDA_SET = %d\n", reloc_data.sdata_begin_symbol_vma_set); \
848 ARC_DEBUG ("GOT_OFFSET = 0x%x\n", GOT); \
849 ARC_DEBUG ("relocation = 0x%08x\n", relocation); \
850 ARC_DEBUG ("before = 0x%08x\n", (unsigned int) insn); \
851 ARC_DEBUG ("data = 0x%08x (%u) (%d)\n", (unsigned int) relocation, (unsigned int) relocation, (int) relocation); \
854 #define PRINT_DEBUG_RELOC_INFO_AFTER \
856 ARC_DEBUG ("after = 0x%08x\n", (unsigned int) insn); \
859 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
862 bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
863 relocation = FORMULA ; \
864 PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA) \
865 insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
866 insn = RELOC_FUNCTION (insn, relocation); \
867 insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
868 PRINT_DEBUG_RELOC_INFO_AFTER \
872 static bfd_reloc_status_type
873 arc_do_relocation (bfd_byte * contents,
874 struct arc_relocation_data reloc_data,
875 struct bfd_link_info *info)
877 bfd_vma relocation = 0;
879 bfd_vma orig_insn ATTRIBUTE_UNUSED;
880 bfd * abfd = reloc_data.input_section->owner;
881 struct elf_link_hash_table *htab ATTRIBUTE_UNUSED = elf_hash_table (info);
883 if (reloc_data.should_relocate == FALSE)
886 switch (reloc_data.howto->size)
889 insn = arc_bfd_get_32 (abfd,
890 contents + reloc_data.reloc_offset,
891 reloc_data.input_section);
894 insn = arc_bfd_get_16 (abfd,
895 contents + reloc_data.reloc_offset,
896 reloc_data.input_section);
899 insn = arc_bfd_get_8 (abfd,
900 contents + reloc_data.reloc_offset,
901 reloc_data.input_section);
911 switch (reloc_data.howto->type)
913 #include "elf/arc-reloc.def"
920 /* Check for relocation overflow. */
921 if (reloc_data.howto->complain_on_overflow != complain_overflow_dont)
923 bfd_reloc_status_type flag;
924 flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
925 reloc_data.howto->bitsize,
926 reloc_data.howto->rightshift,
927 bfd_arch_bits_per_address (abfd),
930 #undef DEBUG_ARC_RELOC
931 #define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
932 if (flag != bfd_reloc_ok)
934 PR_DEBUG ( "Relocation overflows !!!!\n");
936 DEBUG_ARC_RELOC (reloc_data);
939 "Relocation value = signed -> %d, unsigned -> %u"
940 ", hex -> (0x%08x)\n",
942 (unsigned int) relocation,
943 (unsigned int) relocation);
947 #undef DEBUG_ARC_RELOC
948 #define DEBUG_ARC_RELOC(A)
950 switch (reloc_data.howto->size)
953 arc_bfd_put_32 (abfd, insn,
954 contents + reloc_data.reloc_offset,
955 reloc_data.input_section);
958 arc_bfd_put_16 (abfd, insn,
959 contents + reloc_data.reloc_offset,
960 reloc_data.input_section);
963 arc_bfd_put_8 (abfd, insn,
964 contents + reloc_data.reloc_offset,
965 reloc_data.input_section);
968 ARC_DEBUG ("size = %d\n", reloc_data.howto->size);
988 #undef ARC_RELOC_HOWTO
990 static struct got_entry **
991 arc_get_local_got_ents (bfd * abfd)
993 static struct got_entry **local_got_ents = NULL;
995 if (local_got_ents == NULL)
998 Elf_Internal_Shdr *symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1000 size = symtab_hdr->sh_info * sizeof (bfd_vma);
1001 local_got_ents = (struct got_entry **)
1002 bfd_alloc (abfd, sizeof(struct got_entry *) * size);
1003 if (local_got_ents == NULL)
1006 memset (local_got_ents, 0, sizeof(struct got_entry *) * size);
1007 elf_local_got_ents (abfd) = local_got_ents;
1010 return local_got_ents;
1013 /* Relocate an arc ELF section.
1014 Function : elf_arc_relocate_section
1015 Brief : Relocate an arc section, by handling all the relocations
1016 appearing in that section.
1017 Args : output_bfd : The bfd being written to.
1018 info : Link information.
1019 input_bfd : The input bfd.
1020 input_section : The section being relocated.
1021 contents : contents of the section being relocated.
1022 relocs : List of relocations in the section.
1023 local_syms : is a pointer to the swapped in local symbols.
1024 local_section : is an array giving the section in the input file
1025 corresponding to the st_shndx field of each
1028 elf_arc_relocate_section (bfd * output_bfd,
1029 struct bfd_link_info * info,
1031 asection * input_section,
1032 bfd_byte * contents,
1033 Elf_Internal_Rela * relocs,
1034 Elf_Internal_Sym * local_syms,
1035 asection ** local_sections)
1037 Elf_Internal_Shdr * symtab_hdr;
1038 struct elf_link_hash_entry ** sym_hashes;
1039 struct got_entry ** local_got_ents;
1040 Elf_Internal_Rela * rel;
1041 Elf_Internal_Rela * relend;
1042 struct elf_link_hash_table *htab = elf_hash_table (info);
1044 symtab_hdr = &((elf_tdata (input_bfd))->symtab_hdr);
1045 sym_hashes = elf_sym_hashes (input_bfd);
1048 relend = relocs + input_section->reloc_count;
1049 for (; rel < relend; rel++)
1051 enum elf_arc_reloc_type r_type;
1052 reloc_howto_type * howto;
1053 unsigned long r_symndx;
1054 struct elf_link_hash_entry * h;
1055 Elf_Internal_Sym * sym;
1057 struct elf_link_hash_entry *h2;
1059 struct arc_relocation_data reloc_data =
1063 .got_offset_value = 0,
1065 .sym_section = NULL,
1067 .input_section = NULL,
1068 .sdata_begin_symbol_vma = 0,
1069 .sdata_begin_symbol_vma_set = FALSE,
1070 .got_symbol_vma = 0,
1071 .should_relocate = FALSE
1074 r_type = ELF32_R_TYPE (rel->r_info);
1076 if (r_type >= (int) R_ARC_max)
1078 bfd_set_error (bfd_error_bad_value);
1081 howto = &elf_arc_howto_table[r_type];
1083 r_symndx = ELF32_R_SYM (rel->r_info);
1085 /* If we are generating another .o file and the symbol in not
1086 local, skip this relocation. */
1087 if (bfd_link_relocatable (info))
1089 /* This is a relocateable link. We don't have to change
1090 anything, unless the reloc is against a section symbol,
1091 in which case we have to adjust according to where the
1092 section symbol winds up in the output section. */
1094 /* Checks if this is a local symbol and thus the reloc
1095 might (will??) be against a section symbol. */
1096 if (r_symndx < symtab_hdr->sh_info)
1098 sym = local_syms + r_symndx;
1099 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1101 sec = local_sections[r_symndx];
1103 /* for RELA relocs.Just adjust the addend
1104 value in the relocation entry. */
1105 rel->r_addend += sec->output_offset + sym->st_value;
1108 PR_DEBUG ("local symbols reloc "
1109 "(section=%d %s) seen in %s\n",
1111 local_sections[r_symndx]->name,
1112 __PRETTY_FUNCTION__)
1120 h2 = elf_link_hash_lookup (elf_hash_table (info), "__SDATA_BEGIN__",
1121 FALSE, FALSE, TRUE);
1123 if (reloc_data.sdata_begin_symbol_vma_set == FALSE
1124 && h2 != NULL && h2->root.type != bfd_link_hash_undefined
1125 && h2->root.u.def.section->output_section != NULL)
1126 /* TODO: Verify this condition. */
1128 reloc_data.sdata_begin_symbol_vma =
1129 (h2->root.u.def.value +
1130 h2->root.u.def.section->output_section->vma);
1131 reloc_data.sdata_begin_symbol_vma_set = TRUE;
1134 reloc_data.input_section = input_section;
1135 reloc_data.howto = howto;
1136 reloc_data.reloc_offset = rel->r_offset;
1137 reloc_data.reloc_addend = rel->r_addend;
1139 /* This is a final link. */
1144 if (r_symndx < symtab_hdr->sh_info) /* A local symbol. */
1146 local_got_ents = arc_get_local_got_ents (output_bfd);
1147 struct got_entry *entry = local_got_ents[r_symndx];
1149 sym = local_syms + r_symndx;
1150 sec = local_sections[r_symndx];
1152 reloc_data.sym_value = sym->st_value;
1153 reloc_data.sym_section = sec;
1155 /* Mergeable section handling. */
1156 if ((sec->flags & SEC_MERGE)
1157 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1161 rel->r_addend = _bfd_elf_rel_local_sym (output_bfd, sym,
1162 &msec, rel->r_addend);
1163 rel->r_addend -= (sec->output_section->vma
1164 + sec->output_offset
1166 rel->r_addend += msec->output_section->vma + msec->output_offset;
1168 reloc_data.reloc_addend = rel->r_addend;
1171 if ((is_reloc_for_GOT (howto)
1172 || is_reloc_for_TLS (howto)) && entry != NULL)
1174 if (is_reloc_for_TLS (howto))
1175 while (entry->type == GOT_NORMAL && entry->next != NULL)
1176 entry = entry->next;
1178 if (is_reloc_for_GOT (howto))
1179 while (entry->type != GOT_NORMAL && entry->next != NULL)
1180 entry = entry->next;
1182 if (entry->type == GOT_TLS_GD && entry->processed == FALSE)
1184 bfd_vma sym_vma = sym->st_value
1185 + sec->output_section->vma
1186 + sec->output_offset;
1188 /* Create dynamic relocation for local sym. */
1189 ADD_RELA (output_bfd, got, entry->offset, 0,
1190 R_ARC_TLS_DTPMOD, 0);
1191 ADD_RELA (output_bfd, got, entry->offset+4, 0,
1192 R_ARC_TLS_DTPOFF, 0);
1194 bfd_vma sec_vma = sec->output_section->vma
1195 + sec->output_offset;
1196 bfd_put_32 (output_bfd, sym_vma - sec_vma,
1197 htab->sgot->contents + entry->offset + 4);
1199 ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_GD value "
1200 "= 0x%x @ 0x%x, for symbol %s\n",
1202 htab->sgot->contents + entry->offset + 4,
1205 entry->processed = TRUE;
1207 if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
1209 bfd_vma sym_vma = sym->st_value
1210 + sec->output_section->vma
1211 + sec->output_offset;
1212 bfd_vma sec_vma = htab->tls_sec->output_section->vma;
1213 bfd_put_32 (output_bfd, sym_vma - sec_vma,
1214 htab->sgot->contents + entry->offset);
1215 /* TODO: Check if this type of relocs is the cause
1216 for all the ARC_NONE dynamic relocs. */
1218 ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_IE value = "
1219 "0x%x @ 0x%x, for symbol %s\n",
1221 htab->sgot->contents + entry->offset,
1224 entry->processed = TRUE;
1226 if (entry->type == GOT_NORMAL && entry->processed == FALSE)
1228 bfd_vma sec_vma = reloc_data.sym_section->output_section->vma
1229 + reloc_data.sym_section->output_offset;
1231 bfd_put_32 (output_bfd, reloc_data.sym_value + sec_vma,
1232 htab->sgot->contents + entry->offset);
1234 ARC_DEBUG ("arc_info: PATCHED: 0x%08x @ 0x%08x for "
1235 "sym %s in got offset 0x%x\n",
1236 reloc_data.sym_value + sec_vma,
1237 htab->sgot->output_section->vma
1238 + htab->sgot->output_offset + entry->offset,
1241 entry->processed = TRUE;
1244 reloc_data.got_offset_value = entry->offset;
1245 ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
1246 "vma = 0x%x for symbol %s\n",
1247 entry->type, entry->offset,
1248 htab->sgot->output_section->vma
1249 + htab->sgot->output_offset + entry->offset,
1253 BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1254 if (htab->sgot != NULL)
1255 reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1256 + htab->sgot->output_offset;
1258 reloc_data.should_relocate = TRUE;
1260 else /* Global symbol. */
1262 /* Get the symbol's entry in the symtab. */
1263 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1265 while (h->root.type == bfd_link_hash_indirect
1266 || h->root.type == bfd_link_hash_warning)
1267 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1269 BFD_ASSERT ((h->dynindx == -1) >= (h->forced_local != 0));
1270 /* If we have encountered a definition for this symbol. */
1271 if (h->root.type == bfd_link_hash_defined
1272 || h->root.type == bfd_link_hash_defweak)
1274 reloc_data.sym_value = h->root.u.def.value;
1275 reloc_data.sym_section = h->root.u.def.section;
1277 reloc_data.should_relocate = TRUE;
1279 if (is_reloc_for_GOT (howto) && !bfd_link_pic (info))
1281 /* TODO: Change it to use arc_do_relocation with
1282 ARC_32 reloc. Try to use ADD_RELA macro. */
1283 bfd_vma relocation =
1284 reloc_data.sym_value + reloc_data.reloc_addend
1285 + (reloc_data.sym_section->output_section != NULL ?
1286 (reloc_data.sym_section->output_offset
1287 + reloc_data.sym_section->output_section->vma)
1290 BFD_ASSERT (h->got.glist);
1291 bfd_vma got_offset = h->got.glist->offset;
1292 bfd_put_32 (output_bfd, relocation,
1293 htab->sgot->contents + got_offset);
1295 if (is_reloc_for_PLT (howto) && h->plt.offset != (bfd_vma) -1)
1297 /* TODO: This is repeated up here. */
1298 reloc_data.sym_value = h->plt.offset;
1299 reloc_data.sym_section = htab->splt;
1302 else if (h->root.type == bfd_link_hash_undefweak)
1304 /* Is weak symbol and has no definition. */
1305 if (is_reloc_for_GOT (howto))
1307 reloc_data.sym_value = h->root.u.def.value;
1308 reloc_data.sym_section = htab->sgot;
1309 reloc_data.should_relocate = TRUE;
1311 else if (is_reloc_for_PLT (howto)
1312 && h->plt.offset != (bfd_vma) -1)
1314 /* TODO: This is repeated up here. */
1315 reloc_data.sym_value = h->plt.offset;
1316 reloc_data.sym_section = htab->splt;
1317 reloc_data.should_relocate = TRUE;
1324 if (is_reloc_for_GOT (howto))
1326 reloc_data.sym_value = h->root.u.def.value;
1327 reloc_data.sym_section = htab->sgot;
1329 reloc_data.should_relocate = TRUE;
1331 else if (is_reloc_for_PLT (howto))
1333 /* Fail if it is linking for PIE and the symbol is
1335 if (bfd_link_executable (info)
1336 && !(*info->callbacks->undefined_symbol)
1337 (info, h->root.root.string, input_bfd, input_section,
1338 rel->r_offset, TRUE))
1342 reloc_data.sym_value = h->plt.offset;
1343 reloc_data.sym_section = htab->splt;
1345 reloc_data.should_relocate = TRUE;
1347 else if (!bfd_link_pic (info)
1348 && !(*info->callbacks->undefined_symbol)
1349 (info, h->root.root.string, input_bfd, input_section,
1350 rel->r_offset, TRUE))
1356 if (h->got.glist != NULL)
1358 struct got_entry *entry = h->got.glist;
1360 if (is_reloc_for_GOT (howto) || is_reloc_for_TLS (howto))
1362 if (! elf_hash_table (info)->dynamic_sections_created
1363 || (bfd_link_pic (info)
1364 && SYMBOL_REFERENCES_LOCAL (info, h)))
1366 reloc_data.sym_value = h->root.u.def.value;
1367 reloc_data.sym_section = h->root.u.def.section;
1369 if (is_reloc_for_TLS (howto))
1370 while (entry->type == GOT_NORMAL && entry->next != NULL)
1371 entry = entry->next;
1373 if (entry->processed == FALSE
1374 && (entry->type == GOT_TLS_GD
1375 || entry->type == GOT_TLS_IE))
1377 bfd_vma sym_value = h->root.u.def.value
1378 + h->root.u.def.section->output_section->vma
1379 + h->root.u.def.section->output_offset;
1382 elf_hash_table (info)->tls_sec->output_section->vma;
1384 bfd_put_32 (output_bfd,
1385 sym_value - sec_vma,
1386 htab->sgot->contents + entry->offset
1387 + (entry->existing_entries == MOD_AND_OFF ? 4 : 0));
1389 ARC_DEBUG ("arc_info: FIXED -> %s value = 0x%x "
1390 "@ 0x%x, for symbol %s\n",
1391 (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
1393 sym_value - sec_vma,
1394 htab->sgot->contents + entry->offset
1395 + (entry->existing_entries == MOD_AND_OFF ? 4 : 0),
1396 h->root.root.string);
1398 entry->processed = TRUE;
1401 if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
1403 bfd_vma sec_vma = htab->tls_sec->output_section->vma;
1404 bfd_put_32 (output_bfd,
1405 reloc_data.sym_value - sec_vma,
1406 htab->sgot->contents + entry->offset);
1409 if (entry->type == GOT_NORMAL && entry->processed == FALSE)
1412 reloc_data.sym_section->output_section->vma
1413 + reloc_data.sym_section->output_offset;
1415 if (h->root.type != bfd_link_hash_undefweak)
1417 bfd_put_32 (output_bfd,
1418 reloc_data.sym_value + sec_vma,
1419 htab->sgot->contents + entry->offset);
1421 ARC_DEBUG ("arc_info: PATCHED: 0x%08x "
1422 "@ 0x%08x for sym %s in got offset 0x%x\n",
1423 reloc_data.sym_value + sec_vma,
1424 htab->sgot->output_section->vma
1425 + htab->sgot->output_offset + entry->offset,
1426 h->root.root.string,
1431 ARC_DEBUG ("arc_info: PATCHED: NOT_PATCHED "
1432 "@ 0x%08x for sym %s in got offset 0x%x "
1434 htab->sgot->output_section->vma
1435 + htab->sgot->output_offset + entry->offset,
1436 h->root.root.string,
1440 entry->processed = TRUE;
1445 reloc_data.got_offset_value = entry->offset;
1447 ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
1448 "vma = 0x%x for symbol %s\n",
1449 entry->type, entry->offset,
1450 htab->sgot->output_section->vma
1451 + htab->sgot->output_offset + entry->offset,
1452 h->root.root.string);
1455 BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1456 if (htab->sgot != NULL)
1457 reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1458 + htab->sgot->output_offset;
1466 case R_ARC_32_PCREL:
1467 if (bfd_link_pic (info) && !bfd_link_pie (info)
1468 && ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1471 && (!info->symbolic || !h->def_regular))))
1473 Elf_Internal_Rela outrel;
1475 bfd_boolean skip = FALSE;
1476 bfd_boolean relocate = FALSE;
1477 asection *sreloc = _bfd_elf_get_dynamic_reloc_section
1478 (input_bfd, input_section,
1481 BFD_ASSERT (sreloc != NULL);
1483 outrel.r_offset = _bfd_elf_section_offset (output_bfd,
1487 if (outrel.r_offset == (bfd_vma) -1)
1490 outrel.r_addend = rel->r_addend;
1491 outrel.r_offset += (input_section->output_section->vma
1492 + input_section->output_offset);
1496 memset (&outrel, 0, sizeof outrel);
1499 else if (r_type == R_ARC_PC32
1500 || r_type == R_ARC_32_PCREL)
1502 BFD_ASSERT (h != NULL && h->dynindx != -1);
1503 if ((input_section->flags & SEC_ALLOC) != 0)
1507 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1511 /* Handle local symbols, they either do not have a
1512 global hash table entry (h == NULL), or are
1513 forced local due to a version script
1514 (h->forced_local), or the third condition is
1515 legacy, it appears to say something like, for
1516 links where we are pre-binding the symbols, or
1517 there's not an entry for this symbol in the
1518 dynamic symbol table, and it's a regular symbol
1519 not defined in a shared object, then treat the
1520 symbol as local, resolve it now. */
1522 || ((info->symbolic || h->dynindx == -1)
1527 /* outrel.r_addend = 0; */
1528 outrel.r_info = ELF32_R_INFO (0, R_ARC_RELATIVE);
1532 BFD_ASSERT (h->dynindx != -1);
1534 /* This type of dynamic relocation cannot be created
1535 for code sections. */
1536 BFD_ASSERT ((input_section->flags & SEC_CODE) == 0);
1538 if ((input_section->flags & SEC_ALLOC) != 0)
1542 outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_32);
1546 BFD_ASSERT (sreloc->contents != 0);
1548 loc = sreloc->contents;
1549 loc += sreloc->reloc_count * sizeof (Elf32_External_Rela);
1550 sreloc->reloc_count += 1;
1552 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1554 if (relocate == FALSE)
1562 if (is_reloc_SDA_relative (howto)
1563 && (reloc_data.sdata_begin_symbol_vma_set == FALSE))
1565 (*_bfd_error_handler)
1566 ("Error: Linker symbol __SDATA_BEGIN__ not found");
1567 bfd_set_error (bfd_error_bad_value);
1571 DEBUG_ARC_RELOC (reloc_data);
1573 if (arc_do_relocation (contents, reloc_data, info) != bfd_reloc_ok)
1580 static struct dynamic_sections
1581 arc_create_dynamic_sections (bfd * abfd, struct bfd_link_info *info)
1583 struct elf_link_hash_table *htab;
1585 struct dynamic_sections ds =
1587 .initialized = FALSE,
1597 htab = elf_hash_table (info);
1600 /* Create dynamic sections for relocatable executables so that we
1601 can copy relocations. */
1602 if (! htab->dynamic_sections_created && bfd_link_pic (info))
1604 if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
1608 dynobj = (elf_hash_table (info))->dynobj;
1612 ds.sgot = htab->sgot;
1613 ds.srelgot = htab->srelgot;
1615 ds.sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
1616 ds.srelgotplt = ds.srelplt;
1618 ds.splt = bfd_get_section_by_name (dynobj, ".plt");
1619 ds.srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
1622 if (htab->dynamic_sections_created)
1624 ds.sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
1627 ds.initialized = TRUE;
1632 #define ADD_SYMBOL_REF_SEC_AND_RELOC(SECNAME, COND_FOR_RELOC, H) \
1633 htab->s##SECNAME->size; \
1635 if (COND_FOR_RELOC) \
1637 htab->srel##SECNAME->size += sizeof (Elf32_External_Rela); \
1638 ARC_DEBUG ("arc_info: Added reloc space in " \
1639 #SECNAME " section at " __FILE__ \
1640 ":%d for symbol\n", \
1641 __LINE__, name_for_global_symbol (H)); \
1644 if (h->dynindx == -1 && !h->forced_local) \
1645 if (! bfd_elf_link_record_dynamic_symbol (info, H)) \
1647 htab->s##SECNAME->size += 4; \
1651 elf_arc_check_relocs (bfd * abfd,
1652 struct bfd_link_info * info,
1654 const Elf_Internal_Rela * relocs)
1656 Elf_Internal_Shdr * symtab_hdr;
1657 struct elf_link_hash_entry ** sym_hashes;
1658 struct got_entry ** local_got_ents;
1659 const Elf_Internal_Rela * rel;
1660 const Elf_Internal_Rela * rel_end;
1662 asection * sreloc = NULL;
1663 struct elf_link_hash_table * htab = elf_hash_table (info);
1665 if (bfd_link_relocatable (info))
1668 dynobj = (elf_hash_table (info))->dynobj;
1669 symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1670 sym_hashes = elf_sym_hashes (abfd);
1671 local_got_ents = arc_get_local_got_ents (abfd);
1673 rel_end = relocs + sec->reloc_count;
1674 for (rel = relocs; rel < rel_end; rel++)
1676 enum elf_arc_reloc_type r_type;
1677 reloc_howto_type *howto;
1678 unsigned long r_symndx;
1679 struct elf_link_hash_entry *h;
1681 r_type = ELF32_R_TYPE (rel->r_info);
1683 if (r_type >= (int) R_ARC_max)
1685 bfd_set_error (bfd_error_bad_value);
1688 howto = &elf_arc_howto_table[r_type];
1691 && (is_reloc_for_GOT (howto) == TRUE
1692 || is_reloc_for_TLS (howto) == TRUE))
1694 dynobj = elf_hash_table (info)->dynobj = abfd;
1695 if (! _bfd_elf_create_got_section (abfd, info))
1699 /* Load symbol information. */
1700 r_symndx = ELF32_R_SYM (rel->r_info);
1701 if (r_symndx < symtab_hdr->sh_info) /* Is a local symbol. */
1703 else /* Global one. */
1704 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1710 /* During shared library creation, these relocs should not
1711 appear in a shared library (as memory will be read only
1712 and the dynamic linker can not resolve these. However
1713 the error should not occur for e.g. debugging or
1714 non-readonly sections. */
1715 if (bfd_link_dll (info) && !bfd_link_pie (info)
1716 && (sec->flags & SEC_ALLOC) != 0
1717 && (sec->flags & SEC_READONLY) != 0)
1721 name = h->root.root.string;
1723 /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); */
1725 (*_bfd_error_handler)
1727 %B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
1729 arc_elf_howto (r_type)->name,
1731 bfd_set_error (bfd_error_bad_value);
1735 /* In some cases we are not setting the 'non_got_ref'
1736 flag, even though the relocations don't require a GOT
1737 access. We should extend the testing in this area to
1738 ensure that no significant cases are being missed. */
1743 case R_ARC_32_PCREL:
1744 if (bfd_link_pic (info) && !bfd_link_pie (info)
1745 && ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1748 && (!info->symbolic || !h->def_regular))))
1752 sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
1760 sreloc->size += sizeof (Elf32_External_Rela);
1767 if (is_reloc_for_PLT (howto) == TRUE)
1775 if (is_reloc_for_GOT (howto) == TRUE)
1780 if (local_got_ents[r_symndx] == NULL)
1783 ADD_SYMBOL_REF_SEC_AND_RELOC (got,
1784 bfd_link_pic (info),
1786 new_got_entry_to_list (&(local_got_ents[r_symndx]),
1787 GOT_NORMAL, offset, NONE);
1792 /* Global symbol. */
1793 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1794 if (h->got.glist == NULL)
1797 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1798 new_got_entry_to_list (&h->got.glist,
1799 GOT_NORMAL, offset, NONE);
1804 if (is_reloc_for_TLS (howto) == TRUE)
1806 enum tls_type_e type = GOT_UNKNOWN;
1810 case R_ARC_TLS_GD_GOT:
1813 case R_ARC_TLS_IE_GOT:
1820 struct got_entry **list = NULL;
1822 list = &(h->got.glist);
1824 list = &(local_got_ents[r_symndx]);
1826 if (type != GOT_UNKNOWN && !symbol_has_entry_of_type (*list, type))
1828 enum tls_got_entries entries = NONE;
1830 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1832 if (type == GOT_TLS_GD)
1834 bfd_vma ATTRIBUTE_UNUSED notneeded =
1835 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1836 entries = MOD_AND_OFF;
1839 if (entries == NONE)
1842 new_got_entry_to_list (list, type, offset, entries);
1850 #define ELF_DYNAMIC_INTERPRETER "/sbin/ld-uClibc.so"
1852 static struct plt_version_t *
1853 arc_get_plt_version (struct bfd_link_info *info)
1857 for (i = 0; i < 1; i++)
1859 ARC_DEBUG ("%d: size1 = %d, size2 = %d\n", i,
1860 plt_versions[i].entry_size,
1861 plt_versions[i].elem_size);
1864 if (bfd_get_mach (info->output_bfd) == bfd_mach_arc_arcv2)
1866 if (bfd_link_pic (info))
1867 return &(plt_versions[ELF_ARCV2_PIC]);
1869 return &(plt_versions[ELF_ARCV2_ABS]);
1873 if (bfd_link_pic (info))
1874 return &(plt_versions[ELF_ARC_PIC]);
1876 return &(plt_versions[ELF_ARC_ABS]);
1881 add_symbol_to_plt (struct bfd_link_info *info)
1883 struct elf_link_hash_table *htab = elf_hash_table (info);
1886 struct plt_version_t *plt_data = arc_get_plt_version (info);
1888 /* If this is the first .plt entry, make room for the special first
1890 if (htab->splt->size == 0)
1891 htab->splt->size += plt_data->entry_size;
1893 ret = htab->splt->size;
1895 htab->splt->size += plt_data->elem_size;
1896 ARC_DEBUG ("PLT_SIZE = %d\n", htab->splt->size);
1898 htab->sgotplt->size += 4;
1899 htab->srelplt->size += sizeof (Elf32_External_Rela);
1904 #define PLT_DO_RELOCS_FOR_ENTRY(ABFD, DS, RELOCS) \
1905 plt_do_relocs_for_symbol (ABFD, DS, RELOCS, 0, 0)
1908 plt_do_relocs_for_symbol (bfd *abfd,
1909 struct elf_link_hash_table *htab,
1910 const struct plt_reloc *reloc,
1912 bfd_vma symbol_got_offset)
1914 while (SYM_ONLY (reloc->symbol) != LAST_RELOC)
1916 bfd_vma relocation = 0;
1918 switch (SYM_ONLY (reloc->symbol))
1922 htab->sgotplt->output_section->vma +
1923 htab->sgotplt->output_offset + symbol_got_offset;
1926 relocation += reloc->addend;
1928 if (IS_RELATIVE (reloc->symbol))
1930 bfd_vma reloc_offset = reloc->offset;
1931 reloc_offset -= (IS_INSN_32 (reloc->symbol)) ? 4 : 0;
1932 reloc_offset -= (IS_INSN_24 (reloc->symbol)) ? 2 : 0;
1934 relocation -= htab->splt->output_section->vma
1935 + htab->splt->output_offset
1936 + plt_offset + reloc_offset;
1939 /* TODO: being ME is not a property of the relocation but of the
1940 section of which is applying the relocation. */
1941 if (IS_MIDDLE_ENDIAN (reloc->symbol) || bfd_big_endian (abfd))
1944 ((relocation & 0xffff0000) >> 16) |
1945 ((relocation & 0xffff) << 16);
1948 switch (reloc->size)
1951 bfd_put_32 (htab->splt->output_section->owner,
1953 htab->splt->contents + plt_offset + reloc->offset);
1957 reloc = &(reloc[1]); /* Jump to next relocation. */
1962 relocate_plt_for_symbol (bfd *output_bfd,
1963 struct bfd_link_info *info,
1964 struct elf_link_hash_entry *h)
1966 struct plt_version_t *plt_data = arc_get_plt_version (info);
1967 struct elf_link_hash_table *htab = elf_hash_table (info);
1969 bfd_vma plt_index = (h->plt.offset - plt_data->entry_size)
1970 / plt_data->elem_size;
1971 bfd_vma got_offset = (plt_index + 3) * 4;
1973 ARC_DEBUG ("arc_info: PLT_OFFSET = 0x%x, PLT_ENTRY_VMA = 0x%x, \
1974 GOT_ENTRY_OFFSET = 0x%x, GOT_ENTRY_VMA = 0x%x, for symbol %s\n",
1976 htab->splt->output_section->vma
1977 + htab->splt->output_offset
1980 htab->sgotplt->output_section->vma
1981 + htab->sgotplt->output_offset
1983 h->root.root.string);
1985 memcpy (htab->splt->contents + h->plt.offset,
1987 plt_data->elem_size);
1988 plt_do_relocs_for_symbol (output_bfd, htab,
1989 plt_data->elem_relocs,
1993 /* Fill in the entry in the global offset table. */
1994 bfd_put_32 (output_bfd,
1995 (bfd_vma) (htab->splt->output_section->vma
1996 + htab->splt->output_offset),
1997 htab->sgotplt->contents + got_offset);
1999 /* TODO: Fill in the entry in the .rela.plt section. */
2001 Elf_Internal_Rela rel;
2004 rel.r_offset = (htab->sgotplt->output_section->vma
2005 + htab->sgotplt->output_offset
2008 rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_JMP_SLOT);
2010 loc = htab->srelplt->contents;
2011 loc += plt_index * sizeof (Elf32_External_Rela); /* relA */
2012 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2017 relocate_plt_for_entry (bfd *abfd,
2018 struct bfd_link_info *info)
2020 struct plt_version_t *plt_data = arc_get_plt_version (info);
2021 struct elf_link_hash_table *htab = elf_hash_table (info);
2023 memcpy (htab->splt->contents, plt_data->entry,
2024 plt_data->entry_size);
2025 PLT_DO_RELOCS_FOR_ENTRY (abfd, htab, plt_data->entry_relocs);
2028 /* Desc : Adjust a symbol defined by a dynamic object and referenced
2029 by a regular object. The current definition is in some section of
2030 the dynamic object, but we're not including those sections. We
2031 have to change the definition to something the rest of the link can
2035 elf_arc_adjust_dynamic_symbol (struct bfd_link_info *info,
2036 struct elf_link_hash_entry *h)
2039 unsigned int power_of_two;
2040 bfd *dynobj = (elf_hash_table (info))->dynobj;
2041 struct elf_link_hash_table *htab = elf_hash_table (info);
2043 if (h->type == STT_FUNC
2044 || h->type == STT_GNU_IFUNC
2045 || h->needs_plt == 1)
2047 if (!bfd_link_pic (info) && !h->def_dynamic && !h->ref_dynamic)
2049 /* This case can occur if we saw a PLT32 reloc in an input
2050 file, but the symbol was never referred to by a dynamic
2051 object. In such a case, we don't actually need to build
2052 a procedure linkage table, and we can just do a PC32
2054 BFD_ASSERT (h->needs_plt);
2058 /* Make sure this symbol is output as a dynamic symbol. */
2059 if (h->dynindx == -1 && !h->forced_local
2060 && !bfd_elf_link_record_dynamic_symbol (info, h))
2063 if (bfd_link_pic (info)
2064 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
2066 bfd_vma loc = add_symbol_to_plt (info);
2068 if (!bfd_link_pic (info) && !h->def_regular)
2070 h->root.u.def.section = htab->splt;
2071 h->root.u.def.value = loc;
2073 h->plt.offset = loc;
2077 h->plt.offset = (bfd_vma) -1;
2083 /* If this is a weak symbol, and there is a real definition, the
2084 processor independent code will have arranged for us to see the
2085 real definition first, and we can just use the same value. */
2086 if (h->u.weakdef != NULL)
2088 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2089 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2090 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2091 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2095 /* If there are no non-GOT references, we do not need a copy
2097 if (!h->non_got_ref)
2100 /* This is a reference to a symbol defined by a dynamic object which
2101 is not a function. */
2103 /* If we are creating a shared library, we must presume that the
2104 only references to the symbol are via the global offset table.
2105 For such cases we need not do anything here; the relocations will
2106 be handled correctly by relocate_section. */
2107 if (bfd_link_pic (info))
2110 /* We must allocate the symbol in our .dynbss section, which will
2111 become part of the .bss section of the executable. There will be
2112 an entry for this symbol in the .dynsym section. The dynamic
2113 object will contain position independent code, so all references
2114 from the dynamic object to this symbol will go through the global
2115 offset table. The dynamic linker will use the .dynsym entry to
2116 determine the address it must put in the global offset table, so
2117 both the dynamic object and the regular object will refer to the
2118 same memory location for the variable. */
2120 s = bfd_get_section_by_name (dynobj, ".dynbss");
2121 BFD_ASSERT (s != NULL);
2123 /* We must generate a R_ARC_COPY reloc to tell the dynamic linker to
2124 copy the initial value out of the dynamic object and into the
2125 runtime process image. We need to remember the offset into the
2126 .rela.bss section we are going to use. */
2127 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2131 srel = bfd_get_section_by_name (dynobj, ".rela.bss");
2132 BFD_ASSERT (srel != NULL);
2133 srel->size += sizeof (Elf32_External_Rela);
2137 /* We need to figure out the alignment required for this symbol. I
2138 have no idea how ELF linkers handle this. */
2139 power_of_two = bfd_log2 (h->size);
2140 if (power_of_two > 3)
2143 /* Apply the required alignment. */
2144 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
2145 if (power_of_two > bfd_get_section_alignment (dynobj, s))
2147 if (! bfd_set_section_alignment (dynobj, s, power_of_two))
2151 /* Define the symbol as being at this point in the section. */
2152 h->root.u.def.section = s;
2153 h->root.u.def.value = s->size;
2155 /* Increment the section size to make room for the symbol. */
2161 /* Function : elf_arc_finish_dynamic_symbol
2162 Brief : Finish up dynamic symbol handling. We set the
2163 contents of various dynamic sections here.
2168 Returns : True/False as the return status. */
2171 elf_arc_finish_dynamic_symbol (bfd * output_bfd,
2172 struct bfd_link_info *info,
2173 struct elf_link_hash_entry *h,
2174 Elf_Internal_Sym * sym)
2176 if (h->plt.offset != (bfd_vma) -1)
2178 relocate_plt_for_symbol (output_bfd, info, h);
2180 if (!h->def_regular)
2182 /* Mark the symbol as undefined, rather than as defined in
2183 the .plt section. Leave the value alone. */
2184 sym->st_shndx = SHN_UNDEF;
2188 if (h->got.glist != NULL)
2190 struct got_entry *list = h->got.glist;
2192 /* Traverse the list of got entries for this symbol. */
2195 bfd_vma got_offset = h->got.glist->offset;
2197 if (list->type == GOT_NORMAL
2198 && list->created_dyn_relocation == FALSE)
2200 if (bfd_link_pic (info)
2201 && (info->symbolic || h->dynindx == -1)
2204 ADD_RELA (output_bfd, got, got_offset, 0, R_ARC_RELATIVE, 0);
2208 ADD_RELA (output_bfd, got, got_offset, h->dynindx,
2211 list->created_dyn_relocation = TRUE;
2213 else if (list->existing_entries != NONE)
2215 struct elf_link_hash_table *htab = elf_hash_table (info);
2216 enum tls_got_entries e = list->existing_entries;
2218 BFD_ASSERT (list->type != GOT_TLS_GD
2219 || list->existing_entries == MOD_AND_OFF);
2221 bfd_vma dynindx = h->dynindx == -1 ? 0 : h->dynindx;
2222 if (e == MOD_AND_OFF || e == MOD)
2224 ADD_RELA (output_bfd, got, got_offset, dynindx,
2225 R_ARC_TLS_DTPMOD, 0);
2226 ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2227 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2230 htab->sgot->output_section->vma
2231 + htab->sgot->output_offset + got_offset,
2234 if (e == MOD_AND_OFF || e == OFF)
2237 if (list->type == GOT_TLS_IE)
2238 addend = bfd_get_32 (output_bfd,
2239 htab->sgot->contents + got_offset);
2241 ADD_RELA (output_bfd, got,
2242 got_offset + (e == MOD_AND_OFF ? 4 : 0),
2244 (list->type == GOT_TLS_IE ?
2245 R_ARC_TLS_TPOFF : R_ARC_TLS_DTPOFF),
2248 ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2249 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2252 htab->sgot->output_section->vma
2253 + htab->sgot->output_offset + got_offset,
2261 h->got.glist = NULL;
2266 bfd_vma rel_offset = (h->root.u.def.value
2267 + h->root.u.def.section->output_section->vma
2268 + h->root.u.def.section->output_offset);
2271 bfd_get_section_by_name (h->root.u.def.section->owner,
2274 bfd_byte * loc = srelbss->contents
2275 + (srelbss->reloc_count * sizeof (Elf32_External_Rela));
2276 srelbss->reloc_count++;
2278 Elf_Internal_Rela rel;
2280 rel.r_offset = rel_offset;
2281 rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_COPY);
2283 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2286 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
2287 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2288 || strcmp (h->root.root.string, "__DYNAMIC") == 0
2289 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
2290 sym->st_shndx = SHN_ABS;
2295 #define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION, ASSERT) \
2297 if (SYMBOL != NULL) \
2299 h = elf_link_hash_lookup (elf_hash_table (info), \
2300 SYMBOL, FALSE, FALSE, TRUE); \
2302 else if (SECTION != NULL) \
2304 s = bfd_get_section_by_name (output_bfd, SECTION); \
2305 BFD_ASSERT (s != NULL || !ASSERT); \
2310 /* Function : elf_arc_finish_dynamic_sections
2311 Brief : Finish up the dynamic sections handling.
2316 Returns : True/False as the return status. */
2319 elf_arc_finish_dynamic_sections (bfd * output_bfd,
2320 struct bfd_link_info *info)
2322 struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
2323 struct elf_link_hash_table *htab = elf_hash_table (info);
2324 bfd *dynobj = (elf_hash_table (info))->dynobj;
2328 Elf32_External_Dyn *dyncon, *dynconend;
2330 dyncon = (Elf32_External_Dyn *) ds.sdyn->contents;
2332 (Elf32_External_Dyn *) (ds.sdyn->contents + ds.sdyn->size);
2333 for (; dyncon < dynconend; dyncon++)
2335 Elf_Internal_Dyn internal_dyn;
2336 bfd_boolean do_it = FALSE;
2338 struct elf_link_hash_entry *h = NULL;
2341 bfd_elf32_swap_dyn_in (dynobj, dyncon, &internal_dyn);
2343 switch (internal_dyn.d_tag)
2345 GET_SYMBOL_OR_SECTION (DT_INIT, "_init", NULL, TRUE)
2346 GET_SYMBOL_OR_SECTION (DT_FINI, "_fini", NULL, TRUE)
2347 GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt", TRUE)
2348 GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt", TRUE)
2349 GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt", TRUE)
2350 GET_SYMBOL_OR_SECTION (DT_RELASZ, NULL, ".rela.plt", FALSE)
2351 GET_SYMBOL_OR_SECTION (DT_VERSYM, NULL, ".gnu.version", TRUE)
2352 GET_SYMBOL_OR_SECTION (DT_VERDEF, NULL, ".gnu.version_d", TRUE)
2353 GET_SYMBOL_OR_SECTION (DT_VERNEED, NULL, ".gnu.version_r", TRUE)
2358 /* In case the dynamic symbols should be updated with a symbol. */
2360 && (h->root.type == bfd_link_hash_defined
2361 || h->root.type == bfd_link_hash_defweak))
2365 internal_dyn.d_un.d_val = h->root.u.def.value;
2366 asec_ptr = h->root.u.def.section;
2367 if (asec_ptr->output_section != NULL)
2369 internal_dyn.d_un.d_val +=
2370 (asec_ptr->output_section->vma +
2371 asec_ptr->output_offset);
2375 /* The symbol is imported from another shared
2376 library and does not apply to this one. */
2377 internal_dyn.d_un.d_val = 0;
2381 else if (s != NULL) /* With a section information. */
2383 switch (internal_dyn.d_tag)
2390 internal_dyn.d_un.d_ptr = s->vma;
2395 internal_dyn.d_un.d_val = s->size;
2401 internal_dyn.d_un.d_val -= s->size;
2411 bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon);
2414 if (htab->splt->size > 0)
2416 relocate_plt_for_entry (output_bfd, info);
2419 /* TODO: Validate this. */
2420 elf_section_data (htab->srelplt->output_section)->this_hdr.sh_entsize
2424 /* Fill in the first three entries in the global offset table. */
2427 if (htab->sgot->size > 0 || htab->sgotplt->size > 0)
2429 if (ds.sdyn == NULL)
2430 bfd_put_32 (output_bfd, (bfd_vma) 0,
2431 htab->sgotplt->contents);
2433 bfd_put_32 (output_bfd,
2434 ds.sdyn->output_section->vma + ds.sdyn->output_offset,
2435 htab->sgotplt->contents);
2436 bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 4);
2437 bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 8);
2444 #define ADD_DYNAMIC_SYMBOL(NAME, TAG) \
2445 h = elf_link_hash_lookup (elf_hash_table (info), \
2446 NAME, FALSE, FALSE, FALSE); \
2447 if ((h != NULL && (h->ref_regular || h->def_regular))) \
2448 if (! _bfd_elf_add_dynamic_entry (info, TAG, 0)) \
2451 /* Set the sizes of the dynamic sections. */
2453 elf_arc_size_dynamic_sections (bfd * output_bfd,
2454 struct bfd_link_info *info)
2458 bfd_boolean relocs_exist = FALSE;
2459 bfd_boolean reltext_exist = FALSE;
2460 struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
2461 struct elf_link_hash_table *htab = elf_hash_table (info);
2463 dynobj = (elf_hash_table (info))->dynobj;
2464 BFD_ASSERT (dynobj != NULL);
2466 if ((elf_hash_table (info))->dynamic_sections_created)
2468 struct elf_link_hash_entry *h;
2470 /* Set the contents of the .interp section to the
2472 if (!bfd_link_pic (info))
2474 s = bfd_get_section_by_name (dynobj, ".interp");
2475 BFD_ASSERT (s != NULL);
2476 s->size = sizeof (ELF_DYNAMIC_INTERPRETER);
2477 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2480 /* Add some entries to the .dynamic section. We fill in some of
2481 the values later, in elf_bfd_final_link, but we must add the
2482 entries now so that we know the final size of the .dynamic
2483 section. Checking if the .init section is present. We also
2484 create DT_INIT and DT_FINI entries if the init_str has been
2485 changed by the user. */
2486 ADD_DYNAMIC_SYMBOL ("init", DT_INIT);
2487 ADD_DYNAMIC_SYMBOL ("fini", DT_FINI);
2491 /* We may have created entries in the .rela.got section.
2492 However, if we are not creating the dynamic sections, we will
2493 not actually use these entries. Reset the size of .rela.got,
2494 which will cause it to get stripped from the output file
2496 if (htab->srelgot != NULL)
2497 htab->srelgot->size = 0;
2500 if (htab->splt != NULL && htab->splt->size == 0)
2501 htab->splt->flags |= SEC_EXCLUDE;
2502 for (s = dynobj->sections; s != NULL; s = s->next)
2504 if ((s->flags & SEC_LINKER_CREATED) == 0)
2507 if (strncmp (s->name, ".rela", 5) == 0)
2511 s->flags |= SEC_EXCLUDE;
2515 if (strcmp (s->name, ".rela.plt") != 0)
2517 const char *outname =
2518 bfd_get_section_name (output_bfd,
2519 htab->srelplt->output_section);
2521 asection *target = bfd_get_section_by_name (output_bfd,
2524 relocs_exist = TRUE;
2525 if (target != NULL && target->size != 0
2526 && (target->flags & SEC_READONLY) != 0
2527 && (target->flags & SEC_ALLOC) != 0)
2528 reltext_exist = TRUE;
2532 /* We use the reloc_count field as a counter if we need to
2533 copy relocs into the output file. */
2537 if (strcmp (s->name, ".dynamic") == 0)
2541 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2543 if (s->contents == NULL && s->size != 0)
2549 /* TODO: Check if this is needed. */
2550 if (!bfd_link_pic (info))
2551 if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
2554 if (htab->splt && (htab->splt->flags & SEC_EXCLUDE) == 0)
2555 if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
2556 || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2557 || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2558 || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0)
2562 if (relocs_exist == TRUE)
2563 if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
2564 || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
2565 || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
2566 sizeof (Elf32_External_Rela))
2570 if (reltext_exist == TRUE)
2571 if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
2578 const struct elf_size_info arc_elf32_size_info =
2580 sizeof (Elf32_External_Ehdr),
2581 sizeof (Elf32_External_Phdr),
2582 sizeof (Elf32_External_Shdr),
2583 sizeof (Elf32_External_Rel),
2584 sizeof (Elf32_External_Rela),
2585 sizeof (Elf32_External_Sym),
2586 sizeof (Elf32_External_Dyn),
2587 sizeof (Elf_External_Note),
2591 ELFCLASS32, EV_CURRENT,
2592 bfd_elf32_write_out_phdrs,
2593 bfd_elf32_write_shdrs_and_ehdr,
2594 bfd_elf32_checksum_contents,
2595 bfd_elf32_write_relocs,
2596 bfd_elf32_swap_symbol_in,
2597 bfd_elf32_swap_symbol_out,
2598 bfd_elf32_slurp_reloc_table,
2599 bfd_elf32_slurp_symbol_table,
2600 bfd_elf32_swap_dyn_in,
2601 bfd_elf32_swap_dyn_out,
2602 bfd_elf32_swap_reloc_in,
2603 bfd_elf32_swap_reloc_out,
2604 bfd_elf32_swap_reloca_in,
2605 bfd_elf32_swap_reloca_out
2608 #define elf_backend_size_info arc_elf32_size_info
2610 static struct bfd_link_hash_table *
2611 arc_elf_link_hash_table_create (bfd *abfd)
2613 struct elf_link_hash_table *htab;
2615 htab = bfd_zmalloc (sizeof (*htab));
2619 if (!_bfd_elf_link_hash_table_init (htab, abfd,
2620 _bfd_elf_link_hash_newfunc,
2621 sizeof (struct elf_link_hash_entry),
2628 htab->init_got_refcount.refcount = 0;
2629 htab->init_got_refcount.glist = NULL;
2630 htab->init_got_offset.offset = 0;
2631 htab->init_got_offset.glist = NULL;
2632 return (struct bfd_link_hash_table *) htab;
2635 /* Hook called by the linker routine which adds symbols from an object
2639 elf_arc_add_symbol_hook (bfd * abfd,
2640 struct bfd_link_info * info,
2641 Elf_Internal_Sym * sym,
2642 const char ** namep ATTRIBUTE_UNUSED,
2643 flagword * flagsp ATTRIBUTE_UNUSED,
2644 asection ** secp ATTRIBUTE_UNUSED,
2645 bfd_vma * valp ATTRIBUTE_UNUSED)
2647 if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
2648 || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
2649 && (abfd->flags & DYNAMIC) == 0
2650 && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
2651 elf_tdata (info->output_bfd)->has_gnu_symbols = elf_gnu_symbol_any;
2656 #define TARGET_LITTLE_SYM arc_elf32_le_vec
2657 #define TARGET_LITTLE_NAME "elf32-littlearc"
2658 #define TARGET_BIG_SYM arc_elf32_be_vec
2659 #define TARGET_BIG_NAME "elf32-bigarc"
2660 #define ELF_ARCH bfd_arch_arc
2661 #define ELF_MACHINE_CODE EM_ARC_COMPACT
2662 #define ELF_MACHINE_ALT1 EM_ARC_COMPACT2
2663 #define ELF_MAXPAGESIZE 0x2000
2665 #define bfd_elf32_bfd_link_hash_table_create arc_elf_link_hash_table_create
2667 #define bfd_elf32_bfd_merge_private_bfd_data arc_elf_merge_private_bfd_data
2668 #define bfd_elf32_bfd_reloc_type_lookup arc_elf32_bfd_reloc_type_lookup
2669 #define bfd_elf32_bfd_set_private_flags arc_elf_set_private_flags
2670 #define bfd_elf32_bfd_print_private_bfd_data arc_elf_print_private_bfd_data
2671 #define bfd_elf32_bfd_copy_private_bfd_data arc_elf_copy_private_bfd_data
2673 #define elf_info_to_howto_rel arc_info_to_howto_rel
2674 #define elf_backend_object_p arc_elf_object_p
2675 #define elf_backend_final_write_processing arc_elf_final_write_processing
2677 #define elf_backend_relocate_section elf_arc_relocate_section
2678 #define elf_backend_check_relocs elf_arc_check_relocs
2679 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
2681 #define elf_backend_adjust_dynamic_symbol elf_arc_adjust_dynamic_symbol
2682 #define elf_backend_finish_dynamic_symbol elf_arc_finish_dynamic_symbol
2684 #define elf_backend_finish_dynamic_sections elf_arc_finish_dynamic_sections
2685 #define elf_backend_size_dynamic_sections elf_arc_size_dynamic_sections
2686 #define elf_backend_add_symbol_hook elf_arc_add_symbol_hook
2688 #define elf_backend_can_gc_sections 1
2689 #define elf_backend_want_got_plt 1
2690 #define elf_backend_plt_readonly 1
2691 #define elf_backend_rela_plts_and_copies_p 1
2692 #define elf_backend_want_plt_sym 0
2693 #define elf_backend_got_header_size 12
2695 #define elf_backend_may_use_rel_p 0
2696 #define elf_backend_may_use_rela_p 1
2697 #define elf_backend_default_use_rela_p 1
2699 #include "elf32-target.h"