1 /* ARC-specific support for 32-bit ELF
2 Copyright (C) 1994-2016 Free Software Foundation, Inc.
3 Contributed by Cupertino Miranda (cmiranda@synopsys.com).
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
27 #include "libiberty.h"
28 #include "opcode/arc-func.h"
29 #include "opcode/arc.h"
32 #define PR_DEBUG(fmt, args...) fprintf (stderr, fmt, ##args)
34 /* #define ARC_ENABLE_DEBUG 1 */
35 #ifndef ARC_ENABLE_DEBUG
36 #define ARC_DEBUG(...)
39 name_for_global_symbol (struct elf_link_hash_entry
*h
)
41 static char *local_str
= "(local)";
45 return h
->root
.root
.string
;
47 #define ARC_DEBUG(args...) fprintf (stderr, ##args)
51 #define ADD_RELA(BFD, SECTION, OFFSET, SYM_IDX, TYPE, ADDEND) \
53 struct elf_link_hash_table *_htab = elf_hash_table (info); \
54 Elf_Internal_Rela _rel; \
57 BFD_ASSERT (_htab->srel##SECTION &&_htab->srel##SECTION->contents); \
58 _loc = _htab->srel##SECTION->contents \
59 + ((_htab->srel##SECTION->reloc_count) \
60 * sizeof (Elf32_External_Rela)); \
61 _htab->srel##SECTION->reloc_count++; \
62 _rel.r_addend = ADDEND; \
63 _rel.r_offset = (_htab->s##SECTION)->output_section->vma \
64 + (_htab->s##SECTION)->output_offset + OFFSET; \
65 BFD_ASSERT ((long) SYM_IDX != -1); \
66 _rel.r_info = ELF32_R_INFO (SYM_IDX, TYPE); \
67 bfd_elf32_swap_reloca_out (BFD, &_rel, _loc); \
70 struct dynamic_sections
72 bfd_boolean initialized
;
76 asection
* srelgotplt
;
82 enum dyn_section_types
93 const char * dyn_section_names
[DYN_SECTION_TYPES_END
] =
104 /* The default symbols representing the init and fini dyn values.
105 TODO: Check what is the relation of those strings with arclinux.em
107 #define INIT_SYM_STRING "_init"
108 #define FINI_SYM_STRING "_fini"
110 char * init_str
= INIT_SYM_STRING
;
111 char * fini_str
= FINI_SYM_STRING
;
113 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
118 static ATTRIBUTE_UNUSED
const char *
119 reloc_type_to_name (unsigned int type
)
123 #include "elf/arc-reloc.def"
130 #undef ARC_RELOC_HOWTO
132 /* Try to minimize the amount of space occupied by relocation tables
133 on the ROM (not that the ROM won't be swamped by other ELF overhead). */
137 static ATTRIBUTE_UNUSED bfd_boolean
138 is_reloc_PC_relative (reloc_howto_type
*howto
)
140 return (strstr (howto
->name
, "PC") != NULL
) ? TRUE
: FALSE
;
144 is_reloc_SDA_relative (reloc_howto_type
*howto
)
146 return (strstr (howto
->name
, "SDA") != NULL
) ? TRUE
: FALSE
;
150 is_reloc_for_GOT (reloc_howto_type
* howto
)
152 if (strstr (howto
->name
, "TLS") != NULL
)
154 return (strstr (howto
->name
, "GOT") != NULL
) ? TRUE
: FALSE
;
158 is_reloc_for_PLT (reloc_howto_type
* howto
)
160 return (strstr (howto
->name
, "PLT") != NULL
) ? TRUE
: FALSE
;
164 is_reloc_for_TLS (reloc_howto_type
*howto
)
166 return (strstr (howto
->name
, "TLS") != NULL
) ? TRUE
: FALSE
;
169 struct arc_relocation_data
171 bfd_signed_vma reloc_offset
;
172 bfd_signed_vma reloc_addend
;
173 bfd_signed_vma got_offset_value
;
175 bfd_signed_vma sym_value
;
176 asection
* sym_section
;
178 reloc_howto_type
*howto
;
180 asection
* input_section
;
182 bfd_signed_vma sdata_begin_symbol_vma
;
183 bfd_boolean sdata_begin_symbol_vma_set
;
184 bfd_signed_vma got_symbol_vma
;
186 bfd_boolean should_relocate
;
188 const char * symbol_name
;
191 /* Should be included at this location due to static declarations
192 * defined before this point. */
195 #define arc_bfd_get_8(A,B,C) bfd_get_8(A,B)
196 #define arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
197 #define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
198 #define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C)
199 #define arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
200 #define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)
203 static bfd_reloc_status_type
204 arc_elf_reloc (bfd
*abfd ATTRIBUTE_UNUSED
,
205 arelent
*reloc_entry
,
207 void *data ATTRIBUTE_UNUSED
,
208 asection
*input_section
,
210 char ** error_message ATTRIBUTE_UNUSED
)
212 if (output_bfd
!= NULL
)
214 reloc_entry
->address
+= input_section
->output_offset
;
216 /* In case of relocateable link and if the reloc is against a
217 section symbol, the addend needs to be adjusted according to
218 where the section symbol winds up in the output section. */
219 if ((symbol_in
->flags
& BSF_SECTION_SYM
) && symbol_in
->section
)
220 reloc_entry
->addend
+= symbol_in
->section
->output_offset
;
225 return bfd_reloc_continue
;
229 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
233 #include "elf/arc-reloc.def"
236 #undef ARC_RELOC_HOWTO
238 #define ARC_RELOC_HOWTO(TYPE, VALUE, RSIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
239 [TYPE] = HOWTO (R_##TYPE, 0, RSIZE, BITSIZE, FALSE, 0, complain_overflow_##OVERFLOW, arc_elf_reloc, "R_" #TYPE, FALSE, 0, 0, FALSE),
241 static struct reloc_howto_struct elf_arc_howto_table
[] =
243 #include "elf/arc-reloc.def"
244 /* Example of what is generated by the preprocessor. Currently kept as an
246 HOWTO (R_ARC_NONE, // Type.
248 2, // Size (0 = byte, 1 = short, 2 = long).
250 FALSE, // PC_relative.
252 complain_overflow_bitfield, // Complain_on_overflow.
253 bfd_elf_generic_reloc, // Special_function.
254 "R_ARC_NONE", // Name.
255 TRUE, // Partial_inplace.
258 FALSE), // PCrel_offset.
261 #undef ARC_RELOC_HOWTO
263 static void arc_elf_howto_init (void)
265 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
266 elf_arc_howto_table[TYPE].pc_relative = \
267 (strstr (#FORMULA, " P ") != NULL || strstr (#FORMULA, " PDATA ") != NULL); \
268 elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0); \
269 /* Only 32 bit data relocations should be marked as ME. */ \
270 if (strstr (#FORMULA, " ME ") != NULL) \
272 BFD_ASSERT (SIZE == 2); \
275 #include "elf/arc-reloc.def"
278 #undef ARC_RELOC_HOWTO
281 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
283 const int howto_table_lookup
[] =
285 #include "elf/arc-reloc.def"
287 #undef ARC_RELOC_HOWTO
289 static reloc_howto_type
*
290 arc_elf_howto (unsigned int r_type
)
292 if (elf_arc_howto_table
[R_ARC_32
].dst_mask
== 0)
293 arc_elf_howto_init ();
294 return &elf_arc_howto_table
[r_type
];
297 /* Map BFD reloc types to ARC ELF reloc types. */
301 bfd_reloc_code_real_type bfd_reloc_val
;
302 unsigned char elf_reloc_val
;
305 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
306 { BFD_RELOC_##TYPE, R_##TYPE },
307 static const struct arc_reloc_map arc_reloc_map
[] =
309 #include "elf/arc-reloc.def"
311 {BFD_RELOC_NONE
, R_ARC_NONE
},
312 {BFD_RELOC_8
, R_ARC_8
},
313 {BFD_RELOC_16
, R_ARC_16
},
314 {BFD_RELOC_24
, R_ARC_24
},
315 {BFD_RELOC_32
, R_ARC_32
},
317 #undef ARC_RELOC_HOWTO
319 typedef ATTRIBUTE_UNUSED
bfd_vma (*replace_func
) (unsigned, int ATTRIBUTE_UNUSED
);
321 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
323 func = (void *) RELOC_FUNCTION; \
326 get_replace_function (bfd
*abfd
, unsigned int r_type
)
332 #include "elf/arc-reloc.def"
335 if (func
== replace_bits24
&& bfd_big_endian (abfd
))
336 return (replace_func
) replace_bits24_be
;
338 return (replace_func
) func
;
340 #undef ARC_RELOC_HOWTO
342 static reloc_howto_type
*
343 arc_elf32_bfd_reloc_type_lookup (bfd
* abfd ATTRIBUTE_UNUSED
,
344 bfd_reloc_code_real_type code
)
348 for (i
= ARRAY_SIZE (arc_reloc_map
); i
--;)
350 if (arc_reloc_map
[i
].bfd_reloc_val
== code
)
351 return arc_elf_howto (arc_reloc_map
[i
].elf_reloc_val
);
357 /* Function to set the ELF flag bits. */
359 arc_elf_set_private_flags (bfd
*abfd
, flagword flags
)
361 elf_elfheader (abfd
)->e_flags
= flags
;
362 elf_flags_init (abfd
) = TRUE
;
366 /* Print private flags. */
368 arc_elf_print_private_bfd_data (bfd
*abfd
, void * ptr
)
370 FILE *file
= (FILE *) ptr
;
373 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
375 /* Print normal ELF private data. */
376 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
378 flags
= elf_elfheader (abfd
)->e_flags
;
379 fprintf (file
, _("private flags = 0x%lx:"), (unsigned long) flags
);
381 switch (flags
& EF_ARC_MACH_MSK
)
383 case EF_ARC_CPU_ARCV2HS
: fprintf (file
, " -mcpu=ARCv2HS"); break;
384 case EF_ARC_CPU_ARCV2EM
: fprintf (file
, " -mcpu=ARCv2EM"); break;
385 case E_ARC_MACH_ARC600
: fprintf (file
, " -mcpu=ARC600"); break;
386 case E_ARC_MACH_ARC601
: fprintf (file
, " -mcpu=ARC601"); break;
387 case E_ARC_MACH_ARC700
: fprintf (file
, " -mcpu=ARC700"); break;
389 fprintf (file
, "-mcpu=unknown");
393 switch (flags
& EF_ARC_OSABI_MSK
)
395 case E_ARC_OSABI_ORIG
: fprintf (file
, " (ABI:legacy)"); break;
396 case E_ARC_OSABI_V2
: fprintf (file
, " (ABI:v2)"); break;
397 case E_ARC_OSABI_V3
: fprintf (file
, " (ABI:v3)"); break;
399 fprintf (file
, "(ABI:unknown)");
407 /* Copy backend specific data from one object module to another. */
410 arc_elf_copy_private_bfd_data (bfd
*ibfd
, bfd
*obfd
)
412 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
413 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
416 BFD_ASSERT (!elf_flags_init (obfd
)
417 || elf_elfheader (obfd
)->e_flags
== elf_elfheader (ibfd
)->e_flags
);
419 elf_elfheader (obfd
)->e_flags
= elf_elfheader (ibfd
)->e_flags
;
420 elf_flags_init (obfd
) = TRUE
;
422 /* Copy object attributes. */
423 _bfd_elf_copy_obj_attributes (ibfd
, obfd
);
425 return _bfd_elf_copy_private_bfd_data (ibfd
, obfd
);
428 static reloc_howto_type
*
429 bfd_elf32_bfd_reloc_name_lookup (bfd
* abfd ATTRIBUTE_UNUSED
,
434 for (i
= 0; i
< ARRAY_SIZE (elf_arc_howto_table
); i
++)
435 if (elf_arc_howto_table
[i
].name
!= NULL
436 && strcasecmp (elf_arc_howto_table
[i
].name
, r_name
) == 0)
437 return arc_elf_howto (i
);
442 /* Set the howto pointer for an ARC ELF reloc. */
445 arc_info_to_howto_rel (bfd
* abfd ATTRIBUTE_UNUSED
,
447 Elf_Internal_Rela
* dst
)
451 r_type
= ELF32_R_TYPE (dst
->r_info
);
452 BFD_ASSERT (r_type
< (unsigned int) R_ARC_max
);
453 cache_ptr
->howto
= arc_elf_howto (r_type
);
456 /* Merge backend specific data from an object file to the output
457 object file when linking. */
460 arc_elf_merge_private_bfd_data (bfd
*ibfd
, bfd
*obfd
)
462 unsigned short mach_ibfd
;
463 static unsigned short mach_obfd
= EM_NONE
;
468 /* Check if we have the same endianess. */
469 if (! _bfd_generic_verify_endian_match (ibfd
, obfd
))
471 _bfd_error_handler (_("ERROR: Endian Match failed. Attempting to link "
472 "%B with binary %s of opposite endian-ness"),
473 ibfd
, bfd_get_filename (obfd
));
477 /* Collect ELF flags. */
478 in_flags
= elf_elfheader (ibfd
)->e_flags
& EF_ARC_MACH_MSK
;
479 out_flags
= elf_elfheader (obfd
)->e_flags
& EF_ARC_MACH_MSK
;
481 if (!elf_flags_init (obfd
)) /* First call, no flags set. */
483 elf_flags_init (obfd
) = TRUE
;
484 out_flags
= in_flags
;
487 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
488 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
491 /* Check to see if the input BFD actually contains any sections. Do
492 not short-circuit dynamic objects; their section list may be
493 emptied by elf_link_add_object_symbols. */
494 if (!(ibfd
->flags
& DYNAMIC
))
496 bfd_boolean null_input_bfd
= TRUE
;
497 bfd_boolean only_data_sections
= TRUE
;
499 for (sec
= ibfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
501 if ((bfd_get_section_flags (ibfd
, sec
)
502 & (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
503 == (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
504 only_data_sections
= FALSE
;
506 null_input_bfd
= FALSE
;
509 if (null_input_bfd
|| only_data_sections
)
513 /* Complain about various flag/architecture mismatches. */
514 mach_ibfd
= elf_elfheader (ibfd
)->e_machine
;
515 if (mach_obfd
== EM_NONE
)
517 mach_obfd
= mach_ibfd
;
521 if (mach_ibfd
!= mach_obfd
)
523 _bfd_error_handler (_("ERROR: Attempting to link %B "
524 "with a binary %s of different architecture"),
525 ibfd
, bfd_get_filename (obfd
));
528 else if (in_flags
!= out_flags
)
530 /* Warn if different flags. */
531 (*_bfd_error_handler
)
532 (_("%s: uses different e_flags (0x%lx) fields than "
533 "previous modules (0x%lx)"),
534 bfd_get_filename (ibfd
), (long)in_flags
, (long)out_flags
);
535 if (in_flags
&& out_flags
)
537 /* MWDT doesnt set the eflags hence make sure we choose the
538 eflags set by gcc. */
539 in_flags
= in_flags
> out_flags
? in_flags
: out_flags
;
543 /* Update the flags. */
544 elf_elfheader (obfd
)->e_flags
= in_flags
;
546 if (bfd_get_mach (obfd
) < bfd_get_mach (ibfd
))
548 return bfd_set_arch_mach (obfd
, bfd_arch_arc
, bfd_get_mach (ibfd
));
554 /* Set the right machine number for an ARC ELF file. */
556 arc_elf_object_p (bfd
* abfd
)
558 /* Make sure this is initialised, or you'll have the potential of passing
559 garbage---or misleading values---into the call to
560 bfd_default_set_arch_mach (). */
561 int mach
= bfd_mach_arc_arc700
;
562 unsigned long arch
= elf_elfheader (abfd
)->e_flags
& EF_ARC_MACH_MSK
;
563 unsigned e_machine
= elf_elfheader (abfd
)->e_machine
;
565 if (e_machine
== EM_ARC_COMPACT
|| e_machine
== EM_ARC_COMPACT2
)
569 case E_ARC_MACH_ARC600
:
570 mach
= bfd_mach_arc_arc600
;
572 case E_ARC_MACH_ARC601
:
573 mach
= bfd_mach_arc_arc601
;
575 case E_ARC_MACH_ARC700
:
576 mach
= bfd_mach_arc_arc700
;
578 case EF_ARC_CPU_ARCV2HS
:
579 case EF_ARC_CPU_ARCV2EM
:
580 mach
= bfd_mach_arc_arcv2
;
583 mach
= (e_machine
== EM_ARC_COMPACT
)
584 ? bfd_mach_arc_arc700
: bfd_mach_arc_arcv2
;
590 if (e_machine
== EM_ARC
)
592 (*_bfd_error_handler
)
593 (_("Error: The ARC4 architecture is no longer supported.\n"));
598 (*_bfd_error_handler
)
599 (_("Warning: unset or old architecture flags. \n"
600 " Use default machine.\n"));
604 return bfd_default_set_arch_mach (abfd
, bfd_arch_arc
, mach
);
607 /* The final processing done just before writing out an ARC ELF object file.
608 This gets the ARC architecture right based on the machine number. */
611 arc_elf_final_write_processing (bfd
* abfd
,
612 bfd_boolean linker ATTRIBUTE_UNUSED
)
616 switch (bfd_get_mach (abfd
))
618 case bfd_mach_arc_arc600
:
619 emf
= EM_ARC_COMPACT
;
621 case bfd_mach_arc_arc601
:
622 emf
= EM_ARC_COMPACT
;
624 case bfd_mach_arc_arc700
:
625 emf
= EM_ARC_COMPACT
;
627 case bfd_mach_arc_arcv2
:
628 emf
= EM_ARC_COMPACT2
;
634 elf_elfheader (abfd
)->e_machine
= emf
;
636 /* Record whatever is the current syscall ABI version. */
637 elf_elfheader (abfd
)->e_flags
|= E_ARC_OSABI_CURRENT
;
643 #define BFD_DEBUG_PIC(...)
647 debug_arc_reloc (struct arc_relocation_data reloc_data
)
649 PR_DEBUG ("Reloc type=%s, should_relocate = %s\n",
650 reloc_data
.howto
->name
,
651 reloc_data
.should_relocate
? "true" : "false");
652 PR_DEBUG (" offset = 0x%x, addend = 0x%x\n",
653 (unsigned int) reloc_data
.reloc_offset
,
654 (unsigned int) reloc_data
.reloc_addend
);
655 PR_DEBUG (" Symbol:\n");
656 PR_DEBUG (" value = 0x%08x\n",
657 (unsigned int) reloc_data
.sym_value
);
658 if (reloc_data
.sym_section
!= NULL
)
660 PR_DEBUG (" Symbol Section:\n");
662 " section name = %s, output_offset 0x%08x",
663 reloc_data
.sym_section
->name
,
664 (unsigned int) reloc_data
.sym_section
->output_offset
);
665 if (reloc_data
.sym_section
->output_section
!= NULL
)
668 ", output_section->vma = 0x%08x",
669 ((unsigned int) reloc_data
.sym_section
->output_section
->vma
));
672 PR_DEBUG (" file: %s\n", reloc_data
.sym_section
->owner
->filename
);
676 PR_DEBUG ( " symbol section is NULL\n");
679 PR_DEBUG ( " Input_section:\n");
680 if (reloc_data
.input_section
!= NULL
)
683 " section name = %s, output_offset 0x%08x, output_section->vma = 0x%08x\n",
684 reloc_data
.input_section
->name
,
685 (unsigned int) reloc_data
.input_section
->output_offset
,
686 (unsigned int) reloc_data
.input_section
->output_section
->vma
);
687 PR_DEBUG ( " changed_address = 0x%08x\n",
688 (unsigned int) (reloc_data
.input_section
->output_section
->vma
689 + reloc_data
.input_section
->output_offset
690 + reloc_data
.reloc_offset
));
691 PR_DEBUG (" file: %s\n", reloc_data
.input_section
->owner
->filename
);
695 PR_DEBUG ( " input section is NULL\n");
700 middle_endian_convert (bfd_vma insn
, bfd_boolean do_it
)
705 = ((insn
& 0xffff0000) >> 16)
706 | ((insn
& 0xffff) << 16);
711 /* This function is called for relocations that are otherwise marked as NOT
712 requiring overflow checks. In here we perform non-standard checks of
713 the relocation value. */
715 static inline bfd_reloc_status_type
716 arc_special_overflow_checks (const struct arc_relocation_data reloc_data
,
717 bfd_signed_vma relocation
,
718 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
720 switch (reloc_data
.howto
->type
)
722 case R_ARC_NPS_CMEM16
:
723 if (((relocation
>> 16) & 0xffff) != NPS_CMEM_HIGH_VALUE
)
725 if (reloc_data
.reloc_addend
== 0)
726 (*_bfd_error_handler
)
727 (_("%B(%A+0x%lx): CMEM relocation to `%s' is invalid, "
728 "16 MSB should be 0x%04x (value is 0x%lx)"),
729 reloc_data
.input_section
->owner
,
730 reloc_data
.input_section
,
731 reloc_data
.reloc_offset
,
732 reloc_data
.symbol_name
,
736 (*_bfd_error_handler
)
737 (_("%B(%A+0x%lx): CMEM relocation to `%s+0x%lx' is invalid, "
738 "16 MSB should be 0x%04x (value is 0x%lx)"),
739 reloc_data
.input_section
->owner
,
740 reloc_data
.input_section
,
741 reloc_data
.reloc_offset
,
742 reloc_data
.symbol_name
,
743 reloc_data
.reloc_addend
,
746 return bfd_reloc_overflow
;
757 #define ME(reloc) (reloc)
759 #define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") != NULL) \
760 && (!bfd_big_endian (BFD)))
762 #define S ((bfd_signed_vma) (reloc_data.sym_value \
763 + (reloc_data.sym_section->output_section != NULL ? \
764 (reloc_data.sym_section->output_offset \
765 + reloc_data.sym_section->output_section->vma) : 0)))
766 #define L ((bfd_signed_vma) (reloc_data.sym_value \
767 + (reloc_data.sym_section->output_section != NULL ? \
768 (reloc_data.sym_section->output_offset \
769 + reloc_data.sym_section->output_section->vma) : 0)))
770 #define A (reloc_data.reloc_addend)
772 #define G (reloc_data.got_offset_value)
773 #define GOT (reloc_data.got_symbol_vma)
774 #define GOT_BEGIN (htab->sgot->output_section->vma)
777 /* P: relative offset to PCL The offset should be to the
778 current location aligned to 32 bits. */
779 #define P ((bfd_signed_vma) ( \
781 (reloc_data.input_section->output_section != NULL ? \
782 reloc_data.input_section->output_section->vma : 0) \
783 + reloc_data.input_section->output_offset \
784 + (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0))) \
786 #define PDATA ((bfd_signed_vma) ( \
787 (reloc_data.input_section->output_section->vma \
788 + reloc_data.input_section->output_offset \
789 + (reloc_data.reloc_offset))))
790 #define SECTSTART (bfd_signed_vma) (reloc_data.sym_section->output_section->vma \
791 + reloc_data.sym_section->output_offset)
793 #define _SDA_BASE_ (bfd_signed_vma) (reloc_data.sdata_begin_symbol_vma)
794 #define TLS_REL (bfd_signed_vma) \
795 ((elf_hash_table (info))->tls_sec->output_section->vma)
801 #define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA, TYPE) \
803 asection *sym_section = reloc_data.sym_section; \
804 asection *input_section = reloc_data.input_section; \
805 ARC_DEBUG ("RELOC_TYPE = " TYPE "\n"); \
806 ARC_DEBUG ("FORMULA = " FORMULA "\n"); \
807 ARC_DEBUG ("S = 0x%x\n", S); \
808 ARC_DEBUG ("A = 0x%x\n", A); \
809 ARC_DEBUG ("L = 0x%x\n", L); \
810 if (sym_section->output_section != NULL) \
812 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
813 sym_section->output_section->vma + sym_section->output_offset); \
817 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
819 if (input_section->output_section != NULL) \
821 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
822 input_section->output_section->vma + input_section->output_offset); \
826 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
828 ARC_DEBUG ("PCL = 0x%x\n", P); \
829 ARC_DEBUG ("P = 0x%x\n", P); \
830 ARC_DEBUG ("G = 0x%x\n", G); \
831 ARC_DEBUG ("SDA_OFFSET = 0x%x\n", _SDA_BASE_); \
832 ARC_DEBUG ("SDA_SET = %d\n", reloc_data.sdata_begin_symbol_vma_set); \
833 ARC_DEBUG ("GOT_OFFSET = 0x%x\n", GOT); \
834 ARC_DEBUG ("relocation = 0x%08x\n", relocation); \
835 ARC_DEBUG ("before = 0x%08x\n", (unsigned int) insn); \
836 ARC_DEBUG ("data = 0x%08x (%u) (%d)\n", (unsigned int) relocation, (unsigned int) relocation, (int) relocation); \
839 #define PRINT_DEBUG_RELOC_INFO_AFTER \
841 ARC_DEBUG ("after = 0x%08x\n", (unsigned int) insn); \
844 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
847 bfd_signed_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
848 relocation = FORMULA ; \
849 PRINT_DEBUG_RELOC_INFO_BEFORE (#FORMULA, #TYPE); \
850 insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
851 insn = (* get_replace_function (abfd, TYPE)) (insn, relocation); \
852 insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
853 PRINT_DEBUG_RELOC_INFO_AFTER \
857 static bfd_reloc_status_type
858 arc_do_relocation (bfd_byte
* contents
,
859 struct arc_relocation_data reloc_data
,
860 struct bfd_link_info
*info
)
862 bfd_signed_vma relocation
= 0;
864 bfd_vma orig_insn ATTRIBUTE_UNUSED
;
865 bfd
* abfd
= reloc_data
.input_section
->owner
;
866 struct elf_link_hash_table
*htab ATTRIBUTE_UNUSED
= elf_hash_table (info
);
867 bfd_reloc_status_type flag
;
869 if (reloc_data
.should_relocate
== FALSE
)
872 switch (reloc_data
.howto
->size
)
875 insn
= arc_bfd_get_32 (abfd
,
876 contents
+ reloc_data
.reloc_offset
,
877 reloc_data
.input_section
);
880 insn
= arc_bfd_get_16 (abfd
,
881 contents
+ reloc_data
.reloc_offset
,
882 reloc_data
.input_section
);
885 insn
= arc_bfd_get_8 (abfd
,
886 contents
+ reloc_data
.reloc_offset
,
887 reloc_data
.input_section
);
897 switch (reloc_data
.howto
->type
)
899 #include "elf/arc-reloc.def"
906 /* Check for relocation overflow. */
907 if (reloc_data
.howto
->complain_on_overflow
!= complain_overflow_dont
)
908 flag
= bfd_check_overflow (reloc_data
.howto
->complain_on_overflow
,
909 reloc_data
.howto
->bitsize
,
910 reloc_data
.howto
->rightshift
,
911 bfd_arch_bits_per_address (abfd
),
914 flag
= arc_special_overflow_checks (reloc_data
, relocation
, info
);
916 #undef DEBUG_ARC_RELOC
917 #define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
918 if (flag
!= bfd_reloc_ok
)
920 PR_DEBUG ( "Relocation overflows !!!!\n");
922 DEBUG_ARC_RELOC (reloc_data
);
925 "Relocation value = signed -> %d, unsigned -> %u"
926 ", hex -> (0x%08x)\n",
928 (unsigned int) relocation
,
929 (unsigned int) relocation
);
932 #undef DEBUG_ARC_RELOC
933 #define DEBUG_ARC_RELOC(A)
935 /* Write updated instruction back to memory. */
936 switch (reloc_data
.howto
->size
)
939 arc_bfd_put_32 (abfd
, insn
,
940 contents
+ reloc_data
.reloc_offset
,
941 reloc_data
.input_section
);
944 arc_bfd_put_16 (abfd
, insn
,
945 contents
+ reloc_data
.reloc_offset
,
946 reloc_data
.input_section
);
949 arc_bfd_put_8 (abfd
, insn
,
950 contents
+ reloc_data
.reloc_offset
,
951 reloc_data
.input_section
);
954 ARC_DEBUG ("size = %d\n", reloc_data
.howto
->size
);
974 #undef ARC_RELOC_HOWTO
977 /* Relocate an arc ELF section.
978 Function : elf_arc_relocate_section
979 Brief : Relocate an arc section, by handling all the relocations
980 appearing in that section.
981 Args : output_bfd : The bfd being written to.
982 info : Link information.
983 input_bfd : The input bfd.
984 input_section : The section being relocated.
985 contents : contents of the section being relocated.
986 relocs : List of relocations in the section.
987 local_syms : is a pointer to the swapped in local symbols.
988 local_section : is an array giving the section in the input file
989 corresponding to the st_shndx field of each
992 elf_arc_relocate_section (bfd
* output_bfd
,
993 struct bfd_link_info
* info
,
995 asection
* input_section
,
997 Elf_Internal_Rela
* relocs
,
998 Elf_Internal_Sym
* local_syms
,
999 asection
** local_sections
)
1001 Elf_Internal_Shdr
* symtab_hdr
;
1002 struct elf_link_hash_entry
** sym_hashes
;
1003 Elf_Internal_Rela
* rel
;
1004 Elf_Internal_Rela
* wrel
;
1005 Elf_Internal_Rela
* relend
;
1006 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
1008 symtab_hdr
= &((elf_tdata (input_bfd
))->symtab_hdr
);
1009 sym_hashes
= elf_sym_hashes (input_bfd
);
1011 rel
= wrel
= relocs
;
1012 relend
= relocs
+ input_section
->reloc_count
;
1013 for (; rel
< relend
; wrel
++, rel
++)
1015 enum elf_arc_reloc_type r_type
;
1016 reloc_howto_type
* howto
;
1017 unsigned long r_symndx
;
1018 struct elf_link_hash_entry
* h
;
1019 Elf_Internal_Sym
* sym
;
1021 struct elf_link_hash_entry
*h2
;
1023 struct arc_relocation_data reloc_data
=
1027 .got_offset_value
= 0,
1029 .sym_section
= NULL
,
1031 .input_section
= NULL
,
1032 .sdata_begin_symbol_vma
= 0,
1033 .sdata_begin_symbol_vma_set
= FALSE
,
1034 .got_symbol_vma
= 0,
1035 .should_relocate
= FALSE
1038 r_type
= ELF32_R_TYPE (rel
->r_info
);
1040 if (r_type
>= (int) R_ARC_max
)
1042 bfd_set_error (bfd_error_bad_value
);
1045 howto
= arc_elf_howto (r_type
);
1047 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1049 /* If we are generating another .o file and the symbol in not
1050 local, skip this relocation. */
1051 if (bfd_link_relocatable (info
))
1053 /* This is a relocateable link. We don't have to change
1054 anything, unless the reloc is against a section symbol,
1055 in which case we have to adjust according to where the
1056 section symbol winds up in the output section. */
1058 /* Checks if this is a local symbol and thus the reloc
1059 might (will??) be against a section symbol. */
1060 if (r_symndx
< symtab_hdr
->sh_info
)
1062 sym
= local_syms
+ r_symndx
;
1063 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
1065 sec
= local_sections
[r_symndx
];
1067 /* for RELA relocs.Just adjust the addend
1068 value in the relocation entry. */
1069 rel
->r_addend
+= sec
->output_offset
+ sym
->st_value
;
1072 PR_DEBUG ("local symbols reloc "
1073 "(section=%d %s) seen in %s\n",
1075 local_sections
[r_symndx
]->name
,
1076 __PRETTY_FUNCTION__
)
1082 h2
= elf_link_hash_lookup (elf_hash_table (info
), "__SDATA_BEGIN__",
1083 FALSE
, FALSE
, TRUE
);
1085 if (reloc_data
.sdata_begin_symbol_vma_set
== FALSE
1086 && h2
!= NULL
&& h2
->root
.type
!= bfd_link_hash_undefined
1087 && h2
->root
.u
.def
.section
->output_section
!= NULL
)
1088 /* TODO: Verify this condition. */
1090 reloc_data
.sdata_begin_symbol_vma
=
1091 (h2
->root
.u
.def
.value
1092 + h2
->root
.u
.def
.section
->output_section
->vma
);
1093 reloc_data
.sdata_begin_symbol_vma_set
= TRUE
;
1096 reloc_data
.input_section
= input_section
;
1097 reloc_data
.howto
= howto
;
1098 reloc_data
.reloc_offset
= rel
->r_offset
;
1099 reloc_data
.reloc_addend
= rel
->r_addend
;
1101 /* This is a final link. */
1106 if (r_symndx
< symtab_hdr
->sh_info
) /* A local symbol. */
1108 sym
= local_syms
+ r_symndx
;
1109 sec
= local_sections
[r_symndx
];
1113 /* TODO: This code is repeated from below. We should
1114 clean it and remove duplications.
1115 Sec is used check for discarded sections.
1116 Need to redesign code below. */
1118 /* Get the symbol's entry in the symtab. */
1119 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1121 while (h
->root
.type
== bfd_link_hash_indirect
1122 || h
->root
.type
== bfd_link_hash_warning
)
1123 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1125 /* If we have encountered a definition for this symbol. */
1126 if (h
->root
.type
== bfd_link_hash_defined
1127 || h
->root
.type
== bfd_link_hash_defweak
)
1129 reloc_data
.sym_value
= h
->root
.u
.def
.value
;
1130 sec
= h
->root
.u
.def
.section
;
1134 /* Clean relocs for symbols in discarded sections. */
1135 if (sec
!= NULL
&& discarded_section (sec
))
1137 _bfd_clear_contents (howto
, input_bfd
, input_section
,
1138 contents
+ rel
->r_offset
);
1139 rel
->r_offset
= rel
->r_offset
;
1143 /* For ld -r, remove relocations in debug sections against
1144 sections defined in discarded sections. Not done for
1145 eh_frame editing code expects to be present. */
1146 if (bfd_link_relocatable (info
)
1147 && (input_section
->flags
& SEC_DEBUGGING
))
1153 if (bfd_link_relocatable (info
))
1160 if (r_symndx
< symtab_hdr
->sh_info
) /* A local symbol. */
1162 reloc_data
.sym_value
= sym
->st_value
;
1163 reloc_data
.sym_section
= sec
;
1164 reloc_data
.symbol_name
=
1165 bfd_elf_string_from_elf_section (input_bfd
,
1166 symtab_hdr
->sh_link
,
1169 /* Mergeable section handling. */
1170 if ((sec
->flags
& SEC_MERGE
)
1171 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
1175 rel
->r_addend
= _bfd_elf_rel_local_sym (output_bfd
, sym
,
1176 &msec
, rel
->r_addend
);
1177 rel
->r_addend
-= (sec
->output_section
->vma
1178 + sec
->output_offset
1180 rel
->r_addend
+= msec
->output_section
->vma
+ msec
->output_offset
;
1182 reloc_data
.reloc_addend
= rel
->r_addend
;
1185 BFD_ASSERT (htab
->sgot
!= NULL
|| !is_reloc_for_GOT (howto
));
1186 if (htab
->sgot
!= NULL
)
1187 reloc_data
.got_symbol_vma
= htab
->sgot
->output_section
->vma
1188 + htab
->sgot
->output_offset
;
1190 reloc_data
.should_relocate
= TRUE
;
1192 else /* Global symbol. */
1194 /* Get the symbol's entry in the symtab. */
1195 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1197 while (h
->root
.type
== bfd_link_hash_indirect
1198 || h
->root
.type
== bfd_link_hash_warning
)
1199 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1201 /* TODO: Need to validate what was the intention. */
1202 /* BFD_ASSERT ((h->dynindx == -1) || (h->forced_local != 0)); */
1203 reloc_data
.symbol_name
= h
->root
.root
.string
;
1205 /* If we have encountered a definition for this symbol. */
1206 if (h
->root
.type
== bfd_link_hash_defined
1207 || h
->root
.type
== bfd_link_hash_defweak
)
1209 reloc_data
.sym_value
= h
->root
.u
.def
.value
;
1210 reloc_data
.sym_section
= h
->root
.u
.def
.section
;
1212 reloc_data
.should_relocate
= TRUE
;
1214 if (is_reloc_for_GOT (howto
) && !bfd_link_pic (info
))
1216 /* TODO: Change it to use arc_do_relocation with
1217 ARC_32 reloc. Try to use ADD_RELA macro. */
1218 bfd_vma relocation
=
1219 reloc_data
.sym_value
+ reloc_data
.reloc_addend
1220 + (reloc_data
.sym_section
->output_section
!= NULL
?
1221 (reloc_data
.sym_section
->output_offset
1222 + reloc_data
.sym_section
->output_section
->vma
)
1225 BFD_ASSERT (h
->got
.glist
);
1226 bfd_vma got_offset
= h
->got
.glist
->offset
;
1227 bfd_put_32 (output_bfd
, relocation
,
1228 htab
->sgot
->contents
+ got_offset
);
1230 if (is_reloc_for_PLT (howto
) && h
->plt
.offset
!= (bfd_vma
) -1)
1232 /* TODO: This is repeated up here. */
1233 reloc_data
.sym_value
= h
->plt
.offset
;
1234 reloc_data
.sym_section
= htab
->splt
;
1237 else if (h
->root
.type
== bfd_link_hash_undefweak
)
1239 /* Is weak symbol and has no definition. */
1240 if (is_reloc_for_GOT (howto
))
1242 reloc_data
.sym_value
= h
->root
.u
.def
.value
;
1243 reloc_data
.sym_section
= htab
->sgot
;
1244 reloc_data
.should_relocate
= TRUE
;
1246 else if (is_reloc_for_PLT (howto
)
1247 && h
->plt
.offset
!= (bfd_vma
) -1)
1249 /* TODO: This is repeated up here. */
1250 reloc_data
.sym_value
= h
->plt
.offset
;
1251 reloc_data
.sym_section
= htab
->splt
;
1252 reloc_data
.should_relocate
= TRUE
;
1259 if (is_reloc_for_GOT (howto
))
1261 reloc_data
.sym_value
= h
->root
.u
.def
.value
;
1262 reloc_data
.sym_section
= htab
->sgot
;
1264 reloc_data
.should_relocate
= TRUE
;
1266 else if (is_reloc_for_PLT (howto
))
1268 /* Fail if it is linking for PIE and the symbol is
1270 if (bfd_link_executable (info
))
1271 (*info
->callbacks
->undefined_symbol
)
1272 (info
, h
->root
.root
.string
, input_bfd
, input_section
,
1273 rel
->r_offset
, TRUE
);
1274 reloc_data
.sym_value
= h
->plt
.offset
;
1275 reloc_data
.sym_section
= htab
->splt
;
1277 reloc_data
.should_relocate
= TRUE
;
1279 else if (!bfd_link_pic (info
))
1280 (*info
->callbacks
->undefined_symbol
)
1281 (info
, h
->root
.root
.string
, input_bfd
, input_section
,
1282 rel
->r_offset
, TRUE
);
1285 BFD_ASSERT (htab
->sgot
!= NULL
|| !is_reloc_for_GOT (howto
));
1286 if (htab
->sgot
!= NULL
)
1287 reloc_data
.got_symbol_vma
= htab
->sgot
->output_section
->vma
1288 + htab
->sgot
->output_offset
;
1291 if ((is_reloc_for_GOT (howto
)
1292 || is_reloc_for_TLS (howto
)))
1294 struct got_entry
**list
1295 = get_got_entry_list_for_symbol (output_bfd
, r_symndx
, h
);
1297 reloc_data
.got_offset_value
1298 = relocate_fix_got_relocs_for_got_info (list
,
1299 tls_type_for_reloc (howto
),
1310 create_got_dynrelocs_for_single_entry (
1311 got_entry_for_type (list
,
1312 arc_got_entry_type_for_reloc (howto
)),
1313 output_bfd
, info
, NULL
);
1321 case R_ARC_32_PCREL
:
1322 if ((bfd_link_pic (info
))// || bfd_link_pie (info))
1323 && ((r_type
!= R_ARC_PC32
&& r_type
!= R_ARC_32_PCREL
)
1326 && (!info
->symbolic
|| !h
->def_regular
))))
1328 Elf_Internal_Rela outrel
;
1330 bfd_boolean skip
= FALSE
;
1331 bfd_boolean relocate
= FALSE
;
1332 asection
*sreloc
= _bfd_elf_get_dynamic_reloc_section
1333 (input_bfd
, input_section
,
1336 BFD_ASSERT (sreloc
!= NULL
);
1338 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
,
1342 if (outrel
.r_offset
== (bfd_vma
) -1)
1345 outrel
.r_addend
= rel
->r_addend
;
1346 outrel
.r_offset
+= (input_section
->output_section
->vma
1347 + input_section
->output_offset
);
1349 #define IS_ARC_PCREL_TYPE(TYPE) \
1350 ( (TYPE == R_ARC_PC32) \
1351 || (TYPE == R_ARC_32_PCREL))
1354 memset (&outrel
, 0, sizeof outrel
);
1359 && ((IS_ARC_PCREL_TYPE (r_type
))
1360 || !(bfd_link_executable (info
)
1361 || SYMBOLIC_BIND (info
, h
))
1362 || ! h
->def_regular
))
1364 BFD_ASSERT (h
!= NULL
);
1365 if ((input_section
->flags
& SEC_ALLOC
) != 0)
1370 BFD_ASSERT (h
->dynindx
!= -1);
1371 outrel
.r_info
= ELF32_R_INFO (h
->dynindx
, r_type
);
1375 /* Handle local symbols, they either do not have a
1376 global hash table entry (h == NULL), or are
1377 forced local due to a version script
1378 (h->forced_local), or the third condition is
1379 legacy, it appears to say something like, for
1380 links where we are pre-binding the symbols, or
1381 there's not an entry for this symbol in the
1382 dynamic symbol table, and it's a regular symbol
1383 not defined in a shared object, then treat the
1384 symbol as local, resolve it now. */
1386 /* outrel.r_addend = 0; */
1387 outrel
.r_info
= ELF32_R_INFO (0, R_ARC_RELATIVE
);
1390 BFD_ASSERT (sreloc
->contents
!= 0);
1392 loc
= sreloc
->contents
;
1393 loc
+= sreloc
->reloc_count
* sizeof (Elf32_External_Rela
);
1394 sreloc
->reloc_count
+= 1;
1396 bfd_elf32_swap_reloca_out (output_bfd
, &outrel
, loc
);
1398 if (relocate
== FALSE
)
1406 if (is_reloc_SDA_relative (howto
)
1407 && (reloc_data
.sdata_begin_symbol_vma_set
== FALSE
))
1409 (*_bfd_error_handler
)
1410 ("Error: Linker symbol __SDATA_BEGIN__ not found");
1411 bfd_set_error (bfd_error_bad_value
);
1415 DEBUG_ARC_RELOC (reloc_data
);
1417 /* Make sure we have with a dynamic linker. In case of GOT and PLT
1418 the sym_section should point to .got or .plt respectively. */
1419 if ((is_reloc_for_GOT (howto
) || is_reloc_for_PLT (howto
))
1420 && reloc_data
.sym_section
== NULL
)
1422 (*_bfd_error_handler
)
1423 (_("GOT and PLT relocations cannot be fixed with a non dynamic linker."));
1424 bfd_set_error (bfd_error_bad_value
);
1428 if (arc_do_relocation (contents
, reloc_data
, info
) != bfd_reloc_ok
)
1435 static struct dynamic_sections
1436 arc_create_dynamic_sections (bfd
* abfd
, struct bfd_link_info
*info
)
1438 struct elf_link_hash_table
*htab
;
1440 struct dynamic_sections ds
=
1442 .initialized
= FALSE
,
1452 htab
= elf_hash_table (info
);
1455 /* Create dynamic sections for relocatable executables so that we
1456 can copy relocations. */
1457 if (! htab
->dynamic_sections_created
&& bfd_link_pic (info
))
1459 if (! _bfd_elf_link_create_dynamic_sections (abfd
, info
))
1463 dynobj
= (elf_hash_table (info
))->dynobj
;
1467 ds
.sgot
= htab
->sgot
;
1468 ds
.srelgot
= htab
->srelgot
;
1470 ds
.sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
1471 ds
.srelgotplt
= ds
.srelplt
;
1473 ds
.splt
= bfd_get_section_by_name (dynobj
, ".plt");
1474 ds
.srelplt
= bfd_get_section_by_name (dynobj
, ".rela.plt");
1477 if (htab
->dynamic_sections_created
)
1479 ds
.sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
1482 ds
.initialized
= TRUE
;
1488 elf_arc_check_relocs (bfd
* abfd
,
1489 struct bfd_link_info
* info
,
1491 const Elf_Internal_Rela
* relocs
)
1493 Elf_Internal_Shdr
* symtab_hdr
;
1494 struct elf_link_hash_entry
** sym_hashes
;
1495 const Elf_Internal_Rela
* rel
;
1496 const Elf_Internal_Rela
* rel_end
;
1498 asection
* sreloc
= NULL
;
1500 if (bfd_link_relocatable (info
))
1503 dynobj
= (elf_hash_table (info
))->dynobj
;
1504 symtab_hdr
= &((elf_tdata (abfd
))->symtab_hdr
);
1505 sym_hashes
= elf_sym_hashes (abfd
);
1507 rel_end
= relocs
+ sec
->reloc_count
;
1508 for (rel
= relocs
; rel
< rel_end
; rel
++)
1510 enum elf_arc_reloc_type r_type
;
1511 reloc_howto_type
*howto
;
1512 unsigned long r_symndx
;
1513 struct elf_link_hash_entry
*h
;
1515 r_type
= ELF32_R_TYPE (rel
->r_info
);
1517 if (r_type
>= (int) R_ARC_max
)
1519 bfd_set_error (bfd_error_bad_value
);
1522 howto
= arc_elf_howto (r_type
);
1525 && (is_reloc_for_GOT (howto
) == TRUE
1526 || is_reloc_for_TLS (howto
) == TRUE
))
1528 dynobj
= elf_hash_table (info
)->dynobj
= abfd
;
1529 if (! _bfd_elf_create_got_section (abfd
, info
))
1533 /* Load symbol information. */
1534 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1535 if (r_symndx
< symtab_hdr
->sh_info
) /* Is a local symbol. */
1537 else /* Global one. */
1538 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1544 /* During shared library creation, these relocs should not
1545 appear in a shared library (as memory will be read only
1546 and the dynamic linker can not resolve these. However
1547 the error should not occur for e.g. debugging or
1548 non-readonly sections. */
1549 if ((bfd_link_dll (info
) && !bfd_link_pie (info
))
1550 && (sec
->flags
& SEC_ALLOC
) != 0
1551 && (sec
->flags
& SEC_READONLY
) != 0
1552 && ((sec
->flags
& SEC_CODE
) != 0
1553 || (sec
->flags
& SEC_DEBUGGING
) != 0))
1557 name
= h
->root
.root
.string
;
1559 /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); */
1561 (*_bfd_error_handler
)
1563 %B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
1565 arc_elf_howto (r_type
)->name
,
1567 bfd_set_error (bfd_error_bad_value
);
1571 /* In some cases we are not setting the 'non_got_ref'
1572 flag, even though the relocations don't require a GOT
1573 access. We should extend the testing in this area to
1574 ensure that no significant cases are being missed. */
1579 case R_ARC_32_PCREL
:
1580 if ((bfd_link_pic (info
))// || bfd_link_pie (info))
1581 && ((r_type
!= R_ARC_PC32
&& r_type
!= R_ARC_32_PCREL
)
1584 && (!info
->symbolic
|| !h
->def_regular
))))
1588 sreloc
= _bfd_elf_make_dynamic_reloc_section (sec
, dynobj
,
1596 sreloc
->size
+= sizeof (Elf32_External_Rela
);
1603 if (is_reloc_for_PLT (howto
) == TRUE
)
1611 /* Add info to the symbol got_entry_list. */
1612 if (is_reloc_for_GOT (howto
) == TRUE
1613 || is_reloc_for_TLS (howto
) == TRUE
)
1615 arc_fill_got_info_for_reloc (
1616 arc_got_entry_type_for_reloc (howto
),
1617 get_got_entry_list_for_symbol (abfd
, r_symndx
, h
),
1626 #define ELF_DYNAMIC_INTERPRETER "/sbin/ld-uClibc.so"
1628 static struct plt_version_t
*
1629 arc_get_plt_version (struct bfd_link_info
*info
)
1633 for (i
= 0; i
< 1; i
++)
1635 ARC_DEBUG ("%d: size1 = %d, size2 = %d\n", i
,
1636 plt_versions
[i
].entry_size
,
1637 plt_versions
[i
].elem_size
);
1640 if (bfd_get_mach (info
->output_bfd
) == bfd_mach_arc_arcv2
)
1642 if (bfd_link_pic (info
))
1643 return &(plt_versions
[ELF_ARCV2_PIC
]);
1645 return &(plt_versions
[ELF_ARCV2_ABS
]);
1649 if (bfd_link_pic (info
))
1650 return &(plt_versions
[ELF_ARC_PIC
]);
1652 return &(plt_versions
[ELF_ARC_ABS
]);
1657 add_symbol_to_plt (struct bfd_link_info
*info
)
1659 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
1662 struct plt_version_t
*plt_data
= arc_get_plt_version (info
);
1664 /* If this is the first .plt entry, make room for the special first
1666 if (htab
->splt
->size
== 0)
1667 htab
->splt
->size
+= plt_data
->entry_size
;
1669 ret
= htab
->splt
->size
;
1671 htab
->splt
->size
+= plt_data
->elem_size
;
1672 ARC_DEBUG ("PLT_SIZE = %d\n", htab
->splt
->size
);
1674 htab
->sgotplt
->size
+= 4;
1675 htab
->srelplt
->size
+= sizeof (Elf32_External_Rela
);
1680 #define PLT_DO_RELOCS_FOR_ENTRY(ABFD, DS, RELOCS) \
1681 plt_do_relocs_for_symbol (ABFD, DS, RELOCS, 0, 0)
1684 plt_do_relocs_for_symbol (bfd
*abfd
,
1685 struct elf_link_hash_table
*htab
,
1686 const struct plt_reloc
*reloc
,
1688 bfd_vma symbol_got_offset
)
1690 while (SYM_ONLY (reloc
->symbol
) != LAST_RELOC
)
1692 bfd_vma relocation
= 0;
1694 switch (SYM_ONLY (reloc
->symbol
))
1698 = htab
->sgotplt
->output_section
->vma
1699 + htab
->sgotplt
->output_offset
+ symbol_got_offset
;
1702 relocation
+= reloc
->addend
;
1704 if (IS_RELATIVE (reloc
->symbol
))
1706 bfd_vma reloc_offset
= reloc
->offset
;
1707 reloc_offset
-= (IS_INSN_32 (reloc
->symbol
)) ? 4 : 0;
1708 reloc_offset
-= (IS_INSN_24 (reloc
->symbol
)) ? 2 : 0;
1710 relocation
-= htab
->splt
->output_section
->vma
1711 + htab
->splt
->output_offset
1712 + plt_offset
+ reloc_offset
;
1715 /* TODO: being ME is not a property of the relocation but of the
1716 section of which is applying the relocation. */
1717 if (IS_MIDDLE_ENDIAN (reloc
->symbol
) && !bfd_big_endian (abfd
))
1720 = ((relocation
& 0xffff0000) >> 16)
1721 | ((relocation
& 0xffff) << 16);
1724 switch (reloc
->size
)
1727 bfd_put_32 (htab
->splt
->output_section
->owner
,
1729 htab
->splt
->contents
+ plt_offset
+ reloc
->offset
);
1733 reloc
= &(reloc
[1]); /* Jump to next relocation. */
1738 relocate_plt_for_symbol (bfd
*output_bfd
,
1739 struct bfd_link_info
*info
,
1740 struct elf_link_hash_entry
*h
)
1742 struct plt_version_t
*plt_data
= arc_get_plt_version (info
);
1743 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
1745 bfd_vma plt_index
= (h
->plt
.offset
- plt_data
->entry_size
)
1746 / plt_data
->elem_size
;
1747 bfd_vma got_offset
= (plt_index
+ 3) * 4;
1749 ARC_DEBUG ("arc_info: PLT_OFFSET = 0x%x, PLT_ENTRY_VMA = 0x%x, \
1750 GOT_ENTRY_OFFSET = 0x%x, GOT_ENTRY_VMA = 0x%x, for symbol %s\n",
1752 htab
->splt
->output_section
->vma
1753 + htab
->splt
->output_offset
1756 htab
->sgotplt
->output_section
->vma
1757 + htab
->sgotplt
->output_offset
1759 h
->root
.root
.string
);
1764 uint16_t *ptr
= (uint16_t *) plt_data
->elem
;
1765 for (i
= 0; i
< plt_data
->elem_size
/2; i
++)
1767 uint16_t data
= ptr
[i
];
1768 bfd_put_16 (output_bfd
,
1770 htab
->splt
->contents
+ h
->plt
.offset
+ (i
*2));
1774 plt_do_relocs_for_symbol (output_bfd
, htab
,
1775 plt_data
->elem_relocs
,
1779 /* Fill in the entry in the global offset table. */
1780 bfd_put_32 (output_bfd
,
1781 (bfd_vma
) (htab
->splt
->output_section
->vma
1782 + htab
->splt
->output_offset
),
1783 htab
->sgotplt
->contents
+ got_offset
);
1785 /* TODO: Fill in the entry in the .rela.plt section. */
1787 Elf_Internal_Rela rel
;
1790 rel
.r_offset
= (htab
->sgotplt
->output_section
->vma
1791 + htab
->sgotplt
->output_offset
1795 BFD_ASSERT (h
->dynindx
!= -1);
1796 rel
.r_info
= ELF32_R_INFO (h
->dynindx
, R_ARC_JMP_SLOT
);
1798 loc
= htab
->srelplt
->contents
;
1799 loc
+= plt_index
* sizeof (Elf32_External_Rela
); /* relA */
1800 bfd_elf32_swap_reloca_out (output_bfd
, &rel
, loc
);
1805 relocate_plt_for_entry (bfd
*abfd
,
1806 struct bfd_link_info
*info
)
1808 struct plt_version_t
*plt_data
= arc_get_plt_version (info
);
1809 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
1813 uint16_t *ptr
= (uint16_t *) plt_data
->entry
;
1814 for (i
= 0; i
< plt_data
->entry_size
/2; i
++)
1816 uint16_t data
= ptr
[i
];
1819 htab
->splt
->contents
+ (i
*2));
1822 PLT_DO_RELOCS_FOR_ENTRY (abfd
, htab
, plt_data
->entry_relocs
);
1825 /* Desc : Adjust a symbol defined by a dynamic object and referenced
1826 by a regular object. The current definition is in some section of
1827 the dynamic object, but we're not including those sections. We
1828 have to change the definition to something the rest of the link can
1832 elf_arc_adjust_dynamic_symbol (struct bfd_link_info
*info
,
1833 struct elf_link_hash_entry
*h
)
1836 bfd
*dynobj
= (elf_hash_table (info
))->dynobj
;
1837 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
1839 if (h
->type
== STT_FUNC
1840 || h
->type
== STT_GNU_IFUNC
1841 || h
->needs_plt
== 1)
1843 if (!bfd_link_pic (info
) && !h
->def_dynamic
&& !h
->ref_dynamic
)
1845 /* This case can occur if we saw a PLT32 reloc in an input
1846 file, but the symbol was never referred to by a dynamic
1847 object. In such a case, we don't actually need to build
1848 a procedure linkage table, and we can just do a PC32
1850 BFD_ASSERT (h
->needs_plt
);
1854 /* Make sure this symbol is output as a dynamic symbol. */
1855 if (h
->dynindx
== -1 && !h
->forced_local
1856 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
1859 if (bfd_link_pic (info
)
1860 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h
))
1862 bfd_vma loc
= add_symbol_to_plt (info
);
1864 if (bfd_link_executable (info
) && !h
->def_regular
)
1866 h
->root
.u
.def
.section
= htab
->splt
;
1867 h
->root
.u
.def
.value
= loc
;
1869 h
->plt
.offset
= loc
;
1873 h
->plt
.offset
= (bfd_vma
) -1;
1879 /* If this is a weak symbol, and there is a real definition, the
1880 processor independent code will have arranged for us to see the
1881 real definition first, and we can just use the same value. */
1882 if (h
->u
.weakdef
!= NULL
)
1884 BFD_ASSERT (h
->u
.weakdef
->root
.type
== bfd_link_hash_defined
1885 || h
->u
.weakdef
->root
.type
== bfd_link_hash_defweak
);
1886 h
->root
.u
.def
.section
= h
->u
.weakdef
->root
.u
.def
.section
;
1887 h
->root
.u
.def
.value
= h
->u
.weakdef
->root
.u
.def
.value
;
1891 /* This is a reference to a symbol defined by a dynamic object which
1892 is not a function. */
1894 /* If we are creating a shared library, we must presume that the
1895 only references to the symbol are via the global offset table.
1896 For such cases we need not do anything here; the relocations will
1897 be handled correctly by relocate_section. */
1898 if (!bfd_link_executable (info
))
1901 /* If there are no non-GOT references, we do not need a copy
1903 if (!h
->non_got_ref
)
1906 /* If -z nocopyreloc was given, we won't generate them either. */
1907 if (info
->nocopyreloc
)
1913 /* We must allocate the symbol in our .dynbss section, which will
1914 become part of the .bss section of the executable. There will be
1915 an entry for this symbol in the .dynsym section. The dynamic
1916 object will contain position independent code, so all references
1917 from the dynamic object to this symbol will go through the global
1918 offset table. The dynamic linker will use the .dynsym entry to
1919 determine the address it must put in the global offset table, so
1920 both the dynamic object and the regular object will refer to the
1921 same memory location for the variable. */
1926 /* We must generate a R_ARC_COPY reloc to tell the dynamic linker to
1927 copy the initial value out of the dynamic object and into the
1928 runtime process image. We need to remember the offset into the
1929 .rela.bss section we are going to use. */
1930 if ((h
->root
.u
.def
.section
->flags
& SEC_ALLOC
) != 0)
1934 srel
= bfd_get_section_by_name (dynobj
, ".rela.bss");
1935 BFD_ASSERT (srel
!= NULL
);
1936 srel
->size
+= sizeof (Elf32_External_Rela
);
1940 s
= bfd_get_section_by_name (dynobj
, ".dynbss");
1941 BFD_ASSERT (s
!= NULL
);
1943 return _bfd_elf_adjust_dynamic_copy (info
, h
, s
);
1946 /* Function : elf_arc_finish_dynamic_symbol
1947 Brief : Finish up dynamic symbol handling. We set the
1948 contents of various dynamic sections here.
1953 Returns : True/False as the return status. */
1956 elf_arc_finish_dynamic_symbol (bfd
* output_bfd
,
1957 struct bfd_link_info
*info
,
1958 struct elf_link_hash_entry
*h
,
1959 Elf_Internal_Sym
* sym
)
1961 if (h
->plt
.offset
!= (bfd_vma
) -1)
1963 relocate_plt_for_symbol (output_bfd
, info
, h
);
1965 if (!h
->def_regular
)
1967 /* Mark the symbol as undefined, rather than as defined in
1968 the .plt section. Leave the value alone. */
1969 sym
->st_shndx
= SHN_UNDEF
;
1974 /* This function traverses list of GOT entries and
1975 create respective dynamic relocs. */
1976 /* TODO: Make function to get list and not access the list directly. */
1977 /* TODO: Move function to relocate_section create this relocs eagerly. */
1978 create_got_dynrelocs_for_got_info (&h
->got
.glist
,
1985 bfd_vma rel_offset
= (h
->root
.u
.def
.value
1986 + h
->root
.u
.def
.section
->output_section
->vma
1987 + h
->root
.u
.def
.section
->output_offset
);
1990 = bfd_get_section_by_name (h
->root
.u
.def
.section
->owner
,
1993 bfd_byte
* loc
= srelbss
->contents
1994 + (srelbss
->reloc_count
* sizeof (Elf32_External_Rela
));
1995 srelbss
->reloc_count
++;
1997 Elf_Internal_Rela rel
;
1999 rel
.r_offset
= rel_offset
;
2001 BFD_ASSERT (h
->dynindx
!= -1);
2002 rel
.r_info
= ELF32_R_INFO (h
->dynindx
, R_ARC_COPY
);
2004 bfd_elf32_swap_reloca_out (output_bfd
, &rel
, loc
);
2007 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
2008 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
2009 || strcmp (h
->root
.root
.string
, "__DYNAMIC") == 0
2010 || strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0)
2011 sym
->st_shndx
= SHN_ABS
;
2016 #define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION) \
2018 if (SYMBOL != NULL) \
2019 h = elf_link_hash_lookup (elf_hash_table (info), \
2020 SYMBOL, FALSE, FALSE, TRUE); \
2021 else if (SECTION != NULL) \
2022 s = bfd_get_linker_section (dynobj, SECTION); \
2025 /* Function : elf_arc_finish_dynamic_sections
2026 Brief : Finish up the dynamic sections handling.
2031 Returns : True/False as the return status. */
2034 elf_arc_finish_dynamic_sections (bfd
* output_bfd
,
2035 struct bfd_link_info
*info
)
2037 struct dynamic_sections ds
= arc_create_dynamic_sections (output_bfd
, info
);
2038 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
2039 bfd
*dynobj
= (elf_hash_table (info
))->dynobj
;
2043 Elf32_External_Dyn
*dyncon
, *dynconend
;
2045 dyncon
= (Elf32_External_Dyn
*) ds
.sdyn
->contents
;
2047 = (Elf32_External_Dyn
*) (ds
.sdyn
->contents
+ ds
.sdyn
->size
);
2048 for (; dyncon
< dynconend
; dyncon
++)
2050 Elf_Internal_Dyn internal_dyn
;
2051 bfd_boolean do_it
= FALSE
;
2053 struct elf_link_hash_entry
*h
= NULL
;
2056 bfd_elf32_swap_dyn_in (dynobj
, dyncon
, &internal_dyn
);
2058 switch (internal_dyn
.d_tag
)
2060 GET_SYMBOL_OR_SECTION (DT_INIT
, "_init", NULL
)
2061 GET_SYMBOL_OR_SECTION (DT_FINI
, "_fini", NULL
)
2062 GET_SYMBOL_OR_SECTION (DT_PLTGOT
, NULL
, ".plt")
2063 GET_SYMBOL_OR_SECTION (DT_JMPREL
, NULL
, ".rela.plt")
2064 GET_SYMBOL_OR_SECTION (DT_PLTRELSZ
, NULL
, ".rela.plt")
2065 GET_SYMBOL_OR_SECTION (DT_RELASZ
, NULL
, ".rela.plt")
2066 GET_SYMBOL_OR_SECTION (DT_VERSYM
, NULL
, ".gnu.version")
2067 GET_SYMBOL_OR_SECTION (DT_VERDEF
, NULL
, ".gnu.version_d")
2068 GET_SYMBOL_OR_SECTION (DT_VERNEED
, NULL
, ".gnu.version_r")
2073 /* In case the dynamic symbols should be updated with a symbol. */
2075 && (h
->root
.type
== bfd_link_hash_defined
2076 || h
->root
.type
== bfd_link_hash_defweak
))
2080 internal_dyn
.d_un
.d_val
= h
->root
.u
.def
.value
;
2081 asec_ptr
= h
->root
.u
.def
.section
;
2082 if (asec_ptr
->output_section
!= NULL
)
2084 internal_dyn
.d_un
.d_val
+=
2085 (asec_ptr
->output_section
->vma
2086 + asec_ptr
->output_offset
);
2090 /* The symbol is imported from another shared
2091 library and does not apply to this one. */
2092 internal_dyn
.d_un
.d_val
= 0;
2096 else if (s
!= NULL
) /* With a section information. */
2098 switch (internal_dyn
.d_tag
)
2105 internal_dyn
.d_un
.d_ptr
= (s
->output_section
->vma
2106 + s
->output_offset
);
2111 internal_dyn
.d_un
.d_val
= s
->size
;
2117 internal_dyn
.d_un
.d_val
-= s
->size
;
2127 bfd_elf32_swap_dyn_out (output_bfd
, &internal_dyn
, dyncon
);
2130 if (htab
->splt
->size
> 0)
2132 relocate_plt_for_entry (output_bfd
, info
);
2135 /* TODO: Validate this. */
2136 elf_section_data (htab
->srelplt
->output_section
)->this_hdr
.sh_entsize
2140 /* Fill in the first three entries in the global offset table. */
2143 struct elf_link_hash_entry
*h
;
2144 h
= elf_link_hash_lookup (elf_hash_table (info
), "_GLOBAL_OFFSET_TABLE_",
2145 FALSE
, FALSE
, TRUE
);
2147 if (h
!= NULL
&& h
->root
.type
!= bfd_link_hash_undefined
2148 && h
->root
.u
.def
.section
!= NULL
)
2150 asection
*sec
= h
->root
.u
.def
.section
;
2152 if (ds
.sdyn
== NULL
)
2153 bfd_put_32 (output_bfd
, (bfd_vma
) 0,
2156 bfd_put_32 (output_bfd
,
2157 ds
.sdyn
->output_section
->vma
+ ds
.sdyn
->output_offset
,
2159 bfd_put_32 (output_bfd
, (bfd_vma
) 0, sec
->contents
+ 4);
2160 bfd_put_32 (output_bfd
, (bfd_vma
) 0, sec
->contents
+ 8);
2167 #define ADD_DYNAMIC_SYMBOL(NAME, TAG) \
2168 h = elf_link_hash_lookup (elf_hash_table (info), \
2169 NAME, FALSE, FALSE, FALSE); \
2170 if ((h != NULL && (h->ref_regular || h->def_regular))) \
2171 if (! _bfd_elf_add_dynamic_entry (info, TAG, 0)) \
2174 /* Set the sizes of the dynamic sections. */
2176 elf_arc_size_dynamic_sections (bfd
* output_bfd
,
2177 struct bfd_link_info
*info
)
2181 bfd_boolean relocs_exist
= FALSE
;
2182 bfd_boolean reltext_exist
= FALSE
;
2183 struct dynamic_sections ds
= arc_create_dynamic_sections (output_bfd
, info
);
2184 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
2186 dynobj
= (elf_hash_table (info
))->dynobj
;
2187 BFD_ASSERT (dynobj
!= NULL
);
2189 if ((elf_hash_table (info
))->dynamic_sections_created
)
2191 struct elf_link_hash_entry
*h
;
2193 /* Set the contents of the .interp section to the
2195 if (!bfd_link_pic (info
))
2197 s
= bfd_get_section_by_name (dynobj
, ".interp");
2198 BFD_ASSERT (s
!= NULL
);
2199 s
->size
= sizeof (ELF_DYNAMIC_INTERPRETER
);
2200 s
->contents
= (unsigned char *) ELF_DYNAMIC_INTERPRETER
;
2203 /* Add some entries to the .dynamic section. We fill in some of
2204 the values later, in elf_bfd_final_link, but we must add the
2205 entries now so that we know the final size of the .dynamic
2206 section. Checking if the .init section is present. We also
2207 create DT_INIT and DT_FINI entries if the init_str has been
2208 changed by the user. */
2209 ADD_DYNAMIC_SYMBOL ("init", DT_INIT
);
2210 ADD_DYNAMIC_SYMBOL ("fini", DT_FINI
);
2214 /* We may have created entries in the .rela.got section.
2215 However, if we are not creating the dynamic sections, we will
2216 not actually use these entries. Reset the size of .rela.got,
2217 which will cause it to get stripped from the output file
2219 if (htab
->srelgot
!= NULL
)
2220 htab
->srelgot
->size
= 0;
2223 if (htab
->splt
!= NULL
&& htab
->splt
->size
== 0)
2224 htab
->splt
->flags
|= SEC_EXCLUDE
;
2225 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
2227 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
2230 if (strncmp (s
->name
, ".rela", 5) == 0)
2234 s
->flags
|= SEC_EXCLUDE
;
2238 if (strcmp (s
->name
, ".rela.plt") != 0)
2240 const char *outname
=
2241 bfd_get_section_name (output_bfd
,
2242 htab
->srelplt
->output_section
);
2244 asection
*target
= bfd_get_section_by_name (output_bfd
,
2247 relocs_exist
= TRUE
;
2248 if (target
!= NULL
&& target
->size
!= 0
2249 && (target
->flags
& SEC_READONLY
) != 0
2250 && (target
->flags
& SEC_ALLOC
) != 0)
2251 reltext_exist
= TRUE
;
2255 /* We use the reloc_count field as a counter if we need to
2256 copy relocs into the output file. */
2260 if (strcmp (s
->name
, ".dynamic") == 0)
2264 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
2266 if (s
->contents
== NULL
&& s
->size
!= 0)
2272 /* TODO: Check if this is needed. */
2273 if (!bfd_link_pic (info
))
2274 if (!_bfd_elf_add_dynamic_entry (info
, DT_DEBUG
, 0))
2277 if (htab
->splt
&& (htab
->splt
->flags
& SEC_EXCLUDE
) == 0)
2278 if (!_bfd_elf_add_dynamic_entry (info
, DT_PLTGOT
, 0)
2279 || !_bfd_elf_add_dynamic_entry (info
, DT_PLTRELSZ
, 0)
2280 || !_bfd_elf_add_dynamic_entry (info
, DT_PLTREL
, DT_RELA
)
2281 || !_bfd_elf_add_dynamic_entry (info
, DT_JMPREL
, 0)
2285 if (relocs_exist
== TRUE
)
2286 if (!_bfd_elf_add_dynamic_entry (info
, DT_RELA
, 0)
2287 || !_bfd_elf_add_dynamic_entry (info
, DT_RELASZ
, 0)
2288 || !_bfd_elf_add_dynamic_entry (info
, DT_RELAENT
,
2289 sizeof (Elf32_External_Rela
))
2293 if (reltext_exist
== TRUE
)
2294 if (!_bfd_elf_add_dynamic_entry (info
, DT_TEXTREL
, 0))
2302 /* Classify dynamic relocs such that -z combreloc can reorder and combine
2304 static enum elf_reloc_type_class
2305 elf32_arc_reloc_type_class (const struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
2306 const asection
*rel_sec ATTRIBUTE_UNUSED
,
2307 const Elf_Internal_Rela
*rela
)
2309 switch ((int) ELF32_R_TYPE (rela
->r_info
))
2311 case R_ARC_RELATIVE
:
2312 return reloc_class_relative
;
2313 case R_ARC_JMP_SLOT
:
2314 return reloc_class_plt
;
2316 return reloc_class_copy
;
2317 /* TODO: Needed in future to support ifunc. */
2319 case R_ARC_IRELATIVE:
2320 return reloc_class_ifunc;
2323 return reloc_class_normal
;
2327 const struct elf_size_info arc_elf32_size_info
=
2329 sizeof (Elf32_External_Ehdr
),
2330 sizeof (Elf32_External_Phdr
),
2331 sizeof (Elf32_External_Shdr
),
2332 sizeof (Elf32_External_Rel
),
2333 sizeof (Elf32_External_Rela
),
2334 sizeof (Elf32_External_Sym
),
2335 sizeof (Elf32_External_Dyn
),
2336 sizeof (Elf_External_Note
),
2340 ELFCLASS32
, EV_CURRENT
,
2341 bfd_elf32_write_out_phdrs
,
2342 bfd_elf32_write_shdrs_and_ehdr
,
2343 bfd_elf32_checksum_contents
,
2344 bfd_elf32_write_relocs
,
2345 bfd_elf32_swap_symbol_in
,
2346 bfd_elf32_swap_symbol_out
,
2347 bfd_elf32_slurp_reloc_table
,
2348 bfd_elf32_slurp_symbol_table
,
2349 bfd_elf32_swap_dyn_in
,
2350 bfd_elf32_swap_dyn_out
,
2351 bfd_elf32_swap_reloc_in
,
2352 bfd_elf32_swap_reloc_out
,
2353 bfd_elf32_swap_reloca_in
,
2354 bfd_elf32_swap_reloca_out
2357 #define elf_backend_size_info arc_elf32_size_info
2359 static struct bfd_link_hash_table
*
2360 arc_elf_link_hash_table_create (bfd
*abfd
)
2362 struct elf_link_hash_table
*htab
;
2364 htab
= bfd_zmalloc (sizeof (*htab
));
2368 if (!_bfd_elf_link_hash_table_init (htab
, abfd
,
2369 _bfd_elf_link_hash_newfunc
,
2370 sizeof (struct elf_link_hash_entry
),
2377 htab
->init_got_refcount
.refcount
= 0;
2378 htab
->init_got_refcount
.glist
= NULL
;
2379 htab
->init_got_offset
.offset
= 0;
2380 htab
->init_got_offset
.glist
= NULL
;
2381 return (struct bfd_link_hash_table
*) htab
;
2384 /* Hook called by the linker routine which adds symbols from an object
2388 elf_arc_add_symbol_hook (bfd
* abfd
,
2389 struct bfd_link_info
* info
,
2390 Elf_Internal_Sym
* sym
,
2391 const char ** namep ATTRIBUTE_UNUSED
,
2392 flagword
* flagsp ATTRIBUTE_UNUSED
,
2393 asection
** secp ATTRIBUTE_UNUSED
,
2394 bfd_vma
* valp ATTRIBUTE_UNUSED
)
2396 if (ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
2397 && (abfd
->flags
& DYNAMIC
) == 0
2398 && bfd_get_flavour (info
->output_bfd
) == bfd_target_elf_flavour
)
2399 elf_tdata (info
->output_bfd
)->has_gnu_symbols
|= elf_gnu_symbol_ifunc
;
2404 #define TARGET_LITTLE_SYM arc_elf32_le_vec
2405 #define TARGET_LITTLE_NAME "elf32-littlearc"
2406 #define TARGET_BIG_SYM arc_elf32_be_vec
2407 #define TARGET_BIG_NAME "elf32-bigarc"
2408 #define ELF_ARCH bfd_arch_arc
2409 #define ELF_MACHINE_CODE EM_ARC_COMPACT
2410 #define ELF_MACHINE_ALT1 EM_ARC_COMPACT2
2411 #define ELF_MAXPAGESIZE 0x2000
2413 #define bfd_elf32_bfd_link_hash_table_create arc_elf_link_hash_table_create
2415 #define bfd_elf32_bfd_merge_private_bfd_data arc_elf_merge_private_bfd_data
2416 #define bfd_elf32_bfd_reloc_type_lookup arc_elf32_bfd_reloc_type_lookup
2417 #define bfd_elf32_bfd_set_private_flags arc_elf_set_private_flags
2418 #define bfd_elf32_bfd_print_private_bfd_data arc_elf_print_private_bfd_data
2419 #define bfd_elf32_bfd_copy_private_bfd_data arc_elf_copy_private_bfd_data
2421 #define elf_info_to_howto_rel arc_info_to_howto_rel
2422 #define elf_backend_object_p arc_elf_object_p
2423 #define elf_backend_final_write_processing arc_elf_final_write_processing
2425 #define elf_backend_relocate_section elf_arc_relocate_section
2426 #define elf_backend_check_relocs elf_arc_check_relocs
2427 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
2429 #define elf_backend_reloc_type_class elf32_arc_reloc_type_class
2431 #define elf_backend_adjust_dynamic_symbol elf_arc_adjust_dynamic_symbol
2432 #define elf_backend_finish_dynamic_symbol elf_arc_finish_dynamic_symbol
2434 #define elf_backend_finish_dynamic_sections elf_arc_finish_dynamic_sections
2435 #define elf_backend_size_dynamic_sections elf_arc_size_dynamic_sections
2436 #define elf_backend_add_symbol_hook elf_arc_add_symbol_hook
2438 #define elf_backend_can_gc_sections 1
2439 #define elf_backend_want_got_plt 1
2440 #define elf_backend_plt_readonly 1
2441 #define elf_backend_rela_plts_and_copies_p 1
2442 #define elf_backend_want_plt_sym 0
2443 #define elf_backend_got_header_size 12
2445 #define elf_backend_may_use_rel_p 0
2446 #define elf_backend_may_use_rela_p 1
2447 #define elf_backend_default_use_rela_p 1
2449 #define elf_backend_default_execstack 0
2451 #include "elf32-target.h"