1 /* ARC-specific support for 32-bit ELF
2 Copyright (C) 1994-2016 Free Software Foundation, Inc.
3 Contributed by Cupertino Miranda (cmiranda@synopsys.com).
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
27 #include "libiberty.h"
28 #include "opcode/arc-func.h"
29 #include "opcode/arc.h"
33 # define PR_DEBUG(fmt, args...) fprintf (stderr, fmt, ##args)
35 # define PR_DEBUG(fmt, args...)
38 /* #define ARC_ENABLE_DEBUG 1 */
39 #ifndef ARC_ENABLE_DEBUG
40 #define ARC_DEBUG(...)
43 name_for_global_symbol (struct elf_link_hash_entry
*h
)
45 static char *local_str
= "(local)";
49 return h
->root
.root
.string
;
51 #define ARC_DEBUG(args...) fprintf (stderr, ##args)
55 #define ADD_RELA(BFD, SECTION, OFFSET, SYM_IDX, TYPE, ADDEND) \
57 struct elf_link_hash_table *_htab = elf_hash_table (info); \
58 Elf_Internal_Rela _rel; \
61 _loc = _htab->srel##SECTION->contents \
62 + ((_htab->srel##SECTION->reloc_count) \
63 * sizeof (Elf32_External_Rela)); \
64 _htab->srel##SECTION->reloc_count++; \
65 _rel.r_addend = ADDEND; \
66 _rel.r_offset = (_htab->s##SECTION)->output_section->vma \
67 + (_htab->s##SECTION)->output_offset + OFFSET; \
68 BFD_ASSERT ((long) SYM_IDX != -1); \
69 _rel.r_info = ELF32_R_INFO (SYM_IDX, TYPE); \
70 bfd_elf32_swap_reloca_out (BFD, &_rel, _loc); \
73 struct dynamic_sections
75 bfd_boolean initialized
;
79 asection
* srelgotplt
;
85 enum dyn_section_types
96 const char * dyn_section_names
[DYN_SECTION_TYPES_END
] =
125 struct got_entry
*next
;
126 enum tls_type_e type
;
128 bfd_boolean processed
;
129 bfd_boolean created_dyn_relocation
;
130 enum tls_got_entries existing_entries
;
134 new_got_entry_to_list (struct got_entry
**list
,
135 enum tls_type_e type
,
137 enum tls_got_entries existing_entries
)
139 /* Find list end. Avoid having multiple entries of the same
141 struct got_entry
**p
= list
;
144 if ((*p
)->type
== type
)
149 struct got_entry
*entry
=
150 (struct got_entry
*) malloc (sizeof(struct got_entry
));
153 entry
->offset
= offset
;
155 entry
->processed
= FALSE
;
156 entry
->created_dyn_relocation
= FALSE
;
157 entry
->existing_entries
= existing_entries
;
159 /* Add the entry to the end of the list. */
164 symbol_has_entry_of_type (struct got_entry
*list
, enum tls_type_e type
)
168 if (list
->type
== type
)
176 /* The default symbols representing the init and fini dyn values.
177 TODO: Check what is the relation of those strings with arclinux.em
179 #define INIT_SYM_STRING "_init"
180 #define FINI_SYM_STRING "_fini"
182 char * init_str
= INIT_SYM_STRING
;
183 char * fini_str
= FINI_SYM_STRING
;
185 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
190 static ATTRIBUTE_UNUSED
const char *
191 reloc_type_to_name (unsigned int type
)
195 #include "elf/arc-reloc.def"
202 #undef ARC_RELOC_HOWTO
204 /* Try to minimize the amount of space occupied by relocation tables
205 on the ROM (not that the ROM won't be swamped by other ELF overhead). */
209 static ATTRIBUTE_UNUSED bfd_boolean
210 is_reloc_PC_relative (reloc_howto_type
*howto
)
212 return (strstr (howto
->name
, "PC") != NULL
) ? TRUE
: FALSE
;
216 is_reloc_SDA_relative (reloc_howto_type
*howto
)
218 return (strstr (howto
->name
, "SDA") != NULL
) ? TRUE
: FALSE
;
222 is_reloc_for_GOT (reloc_howto_type
* howto
)
224 if (strstr (howto
->name
, "TLS") != NULL
)
226 return (strstr (howto
->name
, "GOT") != NULL
) ? TRUE
: FALSE
;
230 is_reloc_for_PLT (reloc_howto_type
* howto
)
232 return (strstr (howto
->name
, "PLT") != NULL
) ? TRUE
: FALSE
;
236 is_reloc_for_TLS (reloc_howto_type
*howto
)
238 return (strstr (howto
->name
, "TLS") != NULL
) ? TRUE
: FALSE
;
241 #define arc_bfd_get_8(A,B,C) bfd_get_8(A,B)
242 #define arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
243 #define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
244 #define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C)
245 #define arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
246 #define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)
249 static bfd_reloc_status_type
250 arc_elf_reloc (bfd
*abfd ATTRIBUTE_UNUSED
,
251 arelent
*reloc_entry
,
253 void *data ATTRIBUTE_UNUSED
,
254 asection
*input_section
,
256 char ** error_message ATTRIBUTE_UNUSED
)
258 if (output_bfd
!= NULL
)
260 reloc_entry
->address
+= input_section
->output_offset
;
262 /* In case of relocateable link and if the reloc is against a
263 section symbol, the addend needs to be adjusted according to
264 where the section symbol winds up in the output section. */
265 if ((symbol_in
->flags
& BSF_SECTION_SYM
) && symbol_in
->section
)
266 reloc_entry
->addend
+= symbol_in
->section
->output_offset
;
271 return bfd_reloc_continue
;
275 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
279 #include "elf/arc-reloc.def"
282 #undef ARC_RELOC_HOWTO
284 #define ARC_RELOC_HOWTO(TYPE, VALUE, RSIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
285 [TYPE] = HOWTO (R_##TYPE, 0, RSIZE, BITSIZE, FALSE, 0, complain_overflow_##OVERFLOW, arc_elf_reloc, "R_" #TYPE, FALSE, 0, 0, FALSE),
287 static struct reloc_howto_struct elf_arc_howto_table
[] =
289 #include "elf/arc-reloc.def"
290 /* Example of what is generated by the preprocessor. Currently kept as an
292 HOWTO (R_ARC_NONE, // Type.
294 2, // Size (0 = byte, 1 = short, 2 = long).
296 FALSE, // PC_relative.
298 complain_overflow_bitfield, // Complain_on_overflow.
299 bfd_elf_generic_reloc, // Special_function.
300 "R_ARC_NONE", // Name.
301 TRUE, // Partial_inplace.
304 FALSE), // PCrel_offset.
307 #undef ARC_RELOC_HOWTO
309 static void arc_elf_howto_init (void)
311 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
312 elf_arc_howto_table[TYPE].pc_relative = \
313 (strstr (#FORMULA, " P ") != NULL || strstr (#FORMULA, " PDATA ") != NULL); \
314 elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0); \
315 /* Only 32 bit data relocations should be marked as ME. */ \
316 if (strstr (#FORMULA, " ME ") != NULL) \
318 BFD_ASSERT (SIZE == 2); \
321 #include "elf/arc-reloc.def"
324 #undef ARC_RELOC_HOWTO
327 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
329 const int howto_table_lookup
[] =
331 #include "elf/arc-reloc.def"
333 #undef ARC_RELOC_HOWTO
335 static reloc_howto_type
*
336 arc_elf_howto (unsigned int r_type
)
338 if (elf_arc_howto_table
[R_ARC_32
].dst_mask
== 0)
339 arc_elf_howto_init ();
340 return &elf_arc_howto_table
[r_type
];
343 /* Map BFD reloc types to ARC ELF reloc types. */
347 bfd_reloc_code_real_type bfd_reloc_val
;
348 unsigned char elf_reloc_val
;
351 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
352 { BFD_RELOC_##TYPE, R_##TYPE },
353 static const struct arc_reloc_map arc_reloc_map
[] =
355 #include "elf/arc-reloc.def"
357 {BFD_RELOC_NONE
, R_ARC_NONE
},
358 {BFD_RELOC_8
, R_ARC_8
},
359 {BFD_RELOC_16
, R_ARC_16
},
360 {BFD_RELOC_24
, R_ARC_24
},
361 {BFD_RELOC_32
, R_ARC_32
},
363 #undef ARC_RELOC_HOWTO
365 typedef ATTRIBUTE_UNUSED
bfd_vma (*replace_func
) (unsigned, int ATTRIBUTE_UNUSED
);
367 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
369 func = (void *) RELOC_FUNCTION; \
372 get_replace_function (bfd
*abfd
, unsigned int r_type
)
378 #include "elf/arc-reloc.def"
381 if (func
== replace_bits24
&& bfd_big_endian (abfd
))
382 return (replace_func
) replace_bits24_be
;
384 return (replace_func
) func
;
386 #undef ARC_RELOC_HOWTO
388 static reloc_howto_type
*
389 arc_elf32_bfd_reloc_type_lookup (bfd
* abfd ATTRIBUTE_UNUSED
,
390 bfd_reloc_code_real_type code
)
394 for (i
= ARRAY_SIZE (arc_reloc_map
); i
--;)
396 if (arc_reloc_map
[i
].bfd_reloc_val
== code
)
397 return arc_elf_howto (arc_reloc_map
[i
].elf_reloc_val
);
403 /* Function to set the ELF flag bits. */
405 arc_elf_set_private_flags (bfd
*abfd
, flagword flags
)
407 elf_elfheader (abfd
)->e_flags
= flags
;
408 elf_flags_init (abfd
) = TRUE
;
412 /* Print private flags. */
414 arc_elf_print_private_bfd_data (bfd
*abfd
, void * ptr
)
416 FILE *file
= (FILE *) ptr
;
419 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
421 /* Print normal ELF private data. */
422 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
424 flags
= elf_elfheader (abfd
)->e_flags
;
425 fprintf (file
, _("private flags = 0x%lx:"), (unsigned long) flags
);
427 switch (flags
& EF_ARC_MACH_MSK
)
429 case EF_ARC_CPU_ARCV2HS
: fprintf (file
, " -mcpu=ARCv2HS"); break;
430 case EF_ARC_CPU_ARCV2EM
: fprintf (file
, " -mcpu=ARCv2EM"); break;
431 case E_ARC_MACH_ARC600
: fprintf (file
, " -mcpu=ARC600"); break;
432 case E_ARC_MACH_ARC601
: fprintf (file
, " -mcpu=ARC601"); break;
433 case E_ARC_MACH_ARC700
: fprintf (file
, " -mcpu=ARC700"); break;
435 fprintf (file
, "-mcpu=unknown");
439 switch (flags
& EF_ARC_OSABI_MSK
)
441 case E_ARC_OSABI_ORIG
: fprintf (file
, " (ABI:legacy)"); break;
442 case E_ARC_OSABI_V2
: fprintf (file
, " (ABI:v2)"); break;
443 case E_ARC_OSABI_V3
: fprintf (file
, " (ABI:v3)"); break;
445 fprintf (file
, "(ABI:unknown)");
453 /* Copy backend specific data from one object module to another. */
456 arc_elf_copy_private_bfd_data (bfd
*ibfd
, bfd
*obfd
)
458 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
459 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
462 BFD_ASSERT (!elf_flags_init (obfd
)
463 || elf_elfheader (obfd
)->e_flags
== elf_elfheader (ibfd
)->e_flags
);
465 elf_elfheader (obfd
)->e_flags
= elf_elfheader (ibfd
)->e_flags
;
466 elf_flags_init (obfd
) = TRUE
;
468 /* Copy object attributes. */
469 _bfd_elf_copy_obj_attributes (ibfd
, obfd
);
471 return _bfd_elf_copy_private_bfd_data (ibfd
, obfd
);
474 static reloc_howto_type
*
475 bfd_elf32_bfd_reloc_name_lookup (bfd
* abfd ATTRIBUTE_UNUSED
,
480 for (i
= 0; i
< ARRAY_SIZE (elf_arc_howto_table
); i
++)
481 if (elf_arc_howto_table
[i
].name
!= NULL
482 && strcasecmp (elf_arc_howto_table
[i
].name
, r_name
) == 0)
483 return arc_elf_howto (i
);
488 /* Set the howto pointer for an ARC ELF reloc. */
491 arc_info_to_howto_rel (bfd
* abfd ATTRIBUTE_UNUSED
,
493 Elf_Internal_Rela
* dst
)
497 r_type
= ELF32_R_TYPE (dst
->r_info
);
498 BFD_ASSERT (r_type
< (unsigned int) R_ARC_max
);
499 cache_ptr
->howto
= arc_elf_howto (r_type
);
502 /* Merge backend specific data from an object file to the output
503 object file when linking. */
506 arc_elf_merge_private_bfd_data (bfd
*ibfd
, bfd
*obfd
)
508 unsigned short mach_ibfd
;
509 static unsigned short mach_obfd
= EM_NONE
;
514 /* Check if we have the same endianess. */
515 if (! _bfd_generic_verify_endian_match (ibfd
, obfd
))
517 _bfd_error_handler (_("ERROR: Endian Match failed. Attempting to link "
518 "%B with binary %s of opposite endian-ness"),
519 ibfd
, bfd_get_filename (obfd
));
523 /* Collect ELF flags. */
524 in_flags
= elf_elfheader (ibfd
)->e_flags
& EF_ARC_MACH_MSK
;
525 out_flags
= elf_elfheader (obfd
)->e_flags
& EF_ARC_MACH_MSK
;
527 if (!elf_flags_init (obfd
)) /* First call, no flags set. */
529 elf_flags_init (obfd
) = TRUE
;
530 out_flags
= in_flags
;
533 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
534 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
537 /* Check to see if the input BFD actually contains any sections. Do
538 not short-circuit dynamic objects; their section list may be
539 emptied by elf_link_add_object_symbols. */
540 if (!(ibfd
->flags
& DYNAMIC
))
542 bfd_boolean null_input_bfd
= TRUE
;
543 bfd_boolean only_data_sections
= TRUE
;
545 for (sec
= ibfd
->sections
; sec
!= NULL
; sec
= sec
->next
)
547 if ((bfd_get_section_flags (ibfd
, sec
)
548 & (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
549 == (SEC_LOAD
| SEC_CODE
| SEC_HAS_CONTENTS
))
550 only_data_sections
= FALSE
;
552 null_input_bfd
= FALSE
;
555 if (null_input_bfd
|| only_data_sections
)
559 /* Complain about various flag/architecture mismatches. */
560 mach_ibfd
= elf_elfheader (ibfd
)->e_machine
;
561 if (mach_obfd
== EM_NONE
)
563 mach_obfd
= mach_ibfd
;
567 if (mach_ibfd
!= mach_obfd
)
569 _bfd_error_handler (_("ERROR: Attempting to link %B "
570 "with a binary %s of different architecture"),
571 ibfd
, bfd_get_filename (obfd
));
574 else if (in_flags
!= out_flags
)
576 /* Warn if different flags. */
577 (*_bfd_error_handler
)
578 (_("%s: uses different e_flags (0x%lx) fields than "
579 "previous modules (0x%lx)"),
580 bfd_get_filename (ibfd
), (long)in_flags
, (long)out_flags
);
581 if (in_flags
&& out_flags
)
583 /* MWDT doesnt set the eflags hence make sure we choose the
584 eflags set by gcc. */
585 in_flags
= in_flags
> out_flags
? in_flags
: out_flags
;
589 /* Update the flags. */
590 elf_elfheader (obfd
)->e_flags
= in_flags
;
592 if (bfd_get_mach (obfd
) < bfd_get_mach (ibfd
))
594 return bfd_set_arch_mach (obfd
, bfd_arch_arc
, bfd_get_mach (ibfd
));
600 /* Set the right machine number for an ARC ELF file. */
602 arc_elf_object_p (bfd
* abfd
)
604 /* Make sure this is initialised, or you'll have the potential of passing
605 garbage---or misleading values---into the call to
606 bfd_default_set_arch_mach (). */
607 int mach
= bfd_mach_arc_arc700
;
608 unsigned long arch
= elf_elfheader (abfd
)->e_flags
& EF_ARC_MACH_MSK
;
609 unsigned e_machine
= elf_elfheader (abfd
)->e_machine
;
611 if (e_machine
== EM_ARC_COMPACT
|| e_machine
== EM_ARC_COMPACT2
)
615 case E_ARC_MACH_ARC600
:
616 mach
= bfd_mach_arc_arc600
;
618 case E_ARC_MACH_ARC601
:
619 mach
= bfd_mach_arc_arc601
;
621 case E_ARC_MACH_ARC700
:
622 mach
= bfd_mach_arc_arc700
;
624 case EF_ARC_CPU_ARCV2HS
:
625 case EF_ARC_CPU_ARCV2EM
:
626 mach
= bfd_mach_arc_arcv2
;
629 mach
= (e_machine
== EM_ARC_COMPACT
) ?
630 bfd_mach_arc_arc700
: bfd_mach_arc_arcv2
;
636 if (e_machine
== EM_ARC
)
638 (*_bfd_error_handler
)
639 (_("Error: The ARC4 architecture is no longer supported.\n"));
644 (*_bfd_error_handler
)
645 (_("Warning: unset or old architecture flags. \n"
646 " Use default machine.\n"));
650 return bfd_default_set_arch_mach (abfd
, bfd_arch_arc
, mach
);
653 /* The final processing done just before writing out an ARC ELF object file.
654 This gets the ARC architecture right based on the machine number. */
657 arc_elf_final_write_processing (bfd
* abfd
,
658 bfd_boolean linker ATTRIBUTE_UNUSED
)
662 switch (bfd_get_mach (abfd
))
664 case bfd_mach_arc_arc600
:
665 emf
= EM_ARC_COMPACT
;
667 case bfd_mach_arc_arc601
:
668 emf
= EM_ARC_COMPACT
;
670 case bfd_mach_arc_arc700
:
671 emf
= EM_ARC_COMPACT
;
673 case bfd_mach_arc_arcv2
:
674 emf
= EM_ARC_COMPACT2
;
680 elf_elfheader (abfd
)->e_machine
= emf
;
682 /* Record whatever is the current syscall ABI version. */
683 elf_elfheader (abfd
)->e_flags
|= E_ARC_OSABI_CURRENT
;
689 #define BFD_DEBUG_PIC(...)
691 struct arc_relocation_data
693 bfd_signed_vma reloc_offset
;
694 bfd_signed_vma reloc_addend
;
695 bfd_signed_vma got_offset_value
;
697 bfd_signed_vma sym_value
;
698 asection
* sym_section
;
700 reloc_howto_type
*howto
;
702 asection
* input_section
;
704 bfd_signed_vma sdata_begin_symbol_vma
;
705 bfd_boolean sdata_begin_symbol_vma_set
;
706 bfd_signed_vma got_symbol_vma
;
708 bfd_boolean should_relocate
;
710 const char * symbol_name
;
714 debug_arc_reloc (struct arc_relocation_data reloc_data
)
716 PR_DEBUG ("Reloc type=%s, should_relocate = %s\n",
717 reloc_data
.howto
->name
,
718 reloc_data
.should_relocate
? "true" : "false");
719 PR_DEBUG (" offset = 0x%x, addend = 0x%x\n",
720 (unsigned int) reloc_data
.reloc_offset
,
721 (unsigned int) reloc_data
.reloc_addend
);
722 PR_DEBUG (" Symbol:\n");
723 PR_DEBUG (" value = 0x%08x\n",
724 (unsigned int) reloc_data
.sym_value
);
725 if (reloc_data
.sym_section
!= NULL
)
727 PR_DEBUG (" Symbol Section:\n");
729 " section name = %s, output_offset 0x%08x",
730 reloc_data
.sym_section
->name
,
731 (unsigned int) reloc_data
.sym_section
->output_offset
);
732 if (reloc_data
.sym_section
->output_section
!= NULL
)
735 ", output_section->vma = 0x%08x",
736 ((unsigned int) reloc_data
.sym_section
->output_section
->vma
));
739 PR_DEBUG (" file: %s\n", reloc_data
.sym_section
->owner
->filename
);
743 PR_DEBUG ( " symbol section is NULL\n");
746 PR_DEBUG ( " Input_section:\n");
747 if (reloc_data
.input_section
!= NULL
)
750 " section name = %s, output_offset 0x%08x, output_section->vma = 0x%08x\n",
751 reloc_data
.input_section
->name
,
752 (unsigned int) reloc_data
.input_section
->output_offset
,
753 (unsigned int) reloc_data
.input_section
->output_section
->vma
);
754 PR_DEBUG ( " changed_address = 0x%08x\n",
755 (unsigned int) (reloc_data
.input_section
->output_section
->vma
+
756 reloc_data
.input_section
->output_offset
+
757 reloc_data
.reloc_offset
));
758 PR_DEBUG (" file: %s\n", reloc_data
.input_section
->owner
->filename
);
762 PR_DEBUG ( " input section is NULL\n");
767 middle_endian_convert (bfd_vma insn
, bfd_boolean do_it
)
772 ((insn
& 0xffff0000) >> 16) |
773 ((insn
& 0xffff) << 16);
778 /* This function is called for relocations that are otherwise marked as NOT
779 requiring overflow checks. In here we perform non-standard checks of
780 the relocation value. */
782 static inline bfd_reloc_status_type
783 arc_special_overflow_checks (const struct arc_relocation_data reloc_data
,
784 bfd_signed_vma relocation
,
785 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
787 switch (reloc_data
.howto
->type
)
789 case R_ARC_NPS_CMEM16
:
790 if (((relocation
>> 16) & 0xffff) != NPS_CMEM_HIGH_VALUE
)
792 if (reloc_data
.reloc_addend
== 0)
793 (*_bfd_error_handler
)
794 (_("%B(%A+0x%lx): CMEM relocation to `%s' is invalid, "
795 "16 MSB should be 0x%04x (value is 0x%lx)"),
796 reloc_data
.input_section
->owner
,
797 reloc_data
.input_section
,
798 reloc_data
.reloc_offset
,
799 reloc_data
.symbol_name
,
803 (*_bfd_error_handler
)
804 (_("%B(%A+0x%lx): CMEM relocation to `%s+0x%lx' is invalid, "
805 "16 MSB should be 0x%04x (value is 0x%lx)"),
806 reloc_data
.input_section
->owner
,
807 reloc_data
.input_section
,
808 reloc_data
.reloc_offset
,
809 reloc_data
.symbol_name
,
810 reloc_data
.reloc_addend
,
813 return bfd_reloc_overflow
;
824 #define ME(reloc) (reloc)
826 #define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") != NULL) \
827 && (!bfd_big_endian (BFD)))
829 #define S ((bfd_signed_vma) (reloc_data.sym_value \
830 + (reloc_data.sym_section->output_section != NULL ? \
831 (reloc_data.sym_section->output_offset \
832 + reloc_data.sym_section->output_section->vma) : 0)))
833 #define L ((bfd_signed_vma) (reloc_data.sym_value \
834 + (reloc_data.sym_section->output_section != NULL ? \
835 (reloc_data.sym_section->output_offset \
836 + reloc_data.sym_section->output_section->vma) : 0)))
837 #define A (reloc_data.reloc_addend)
839 #define G (reloc_data.got_offset_value)
840 #define GOT (reloc_data.got_symbol_vma)
841 #define GOT_BEGIN (htab->sgot->output_section->vma)
844 /* P: relative offset to PCL The offset should be to the
845 current location aligned to 32 bits. */
846 #define P ((bfd_signed_vma) ( \
848 (reloc_data.input_section->output_section != NULL ? \
849 reloc_data.input_section->output_section->vma : 0) \
850 + reloc_data.input_section->output_offset \
851 + (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0))) \
853 #define PDATA ((bfd_signed_vma) ( \
854 (reloc_data.input_section->output_section->vma \
855 + reloc_data.input_section->output_offset \
856 + (reloc_data.reloc_offset))))
857 #define SECTSTART (bfd_signed_vma) (reloc_data.sym_section->output_section->vma \
858 + reloc_data.sym_section->output_offset)
860 #define _SDA_BASE_ (bfd_signed_vma) (reloc_data.sdata_begin_symbol_vma)
861 #define TLS_REL (bfd_signed_vma) \
862 ((elf_hash_table (info))->tls_sec->output_section->vma)
868 #define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA, TYPE) \
870 asection *sym_section = reloc_data.sym_section; \
871 asection *input_section = reloc_data.input_section; \
872 ARC_DEBUG ("RELOC_TYPE = " TYPE "\n"); \
873 ARC_DEBUG ("FORMULA = " FORMULA "\n"); \
874 ARC_DEBUG ("S = 0x%x\n", S); \
875 ARC_DEBUG ("A = 0x%x\n", A); \
876 ARC_DEBUG ("L = 0x%x\n", L); \
877 if (sym_section->output_section != NULL) \
879 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
880 sym_section->output_section->vma + sym_section->output_offset); \
884 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
886 if (input_section->output_section != NULL) \
888 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
889 input_section->output_section->vma + input_section->output_offset); \
893 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
895 ARC_DEBUG ("PCL = 0x%x\n", P); \
896 ARC_DEBUG ("P = 0x%x\n", P); \
897 ARC_DEBUG ("G = 0x%x\n", G); \
898 ARC_DEBUG ("SDA_OFFSET = 0x%x\n", _SDA_BASE_); \
899 ARC_DEBUG ("SDA_SET = %d\n", reloc_data.sdata_begin_symbol_vma_set); \
900 ARC_DEBUG ("GOT_OFFSET = 0x%x\n", GOT); \
901 ARC_DEBUG ("relocation = 0x%08x\n", relocation); \
902 ARC_DEBUG ("before = 0x%08x\n", (unsigned int) insn); \
903 ARC_DEBUG ("data = 0x%08x (%u) (%d)\n", (unsigned int) relocation, (unsigned int) relocation, (int) relocation); \
906 #define PRINT_DEBUG_RELOC_INFO_AFTER \
908 ARC_DEBUG ("after = 0x%08x\n", (unsigned int) insn); \
911 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
914 bfd_signed_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
915 relocation = FORMULA ; \
916 PRINT_DEBUG_RELOC_INFO_BEFORE (#FORMULA, #TYPE); \
917 insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
918 insn = (* get_replace_function (abfd, TYPE)) (insn, relocation); \
919 insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
920 PRINT_DEBUG_RELOC_INFO_AFTER \
924 static bfd_reloc_status_type
925 arc_do_relocation (bfd_byte
* contents
,
926 struct arc_relocation_data reloc_data
,
927 struct bfd_link_info
*info
)
929 bfd_signed_vma relocation
= 0;
931 bfd_vma orig_insn ATTRIBUTE_UNUSED
;
932 bfd
* abfd
= reloc_data
.input_section
->owner
;
933 struct elf_link_hash_table
*htab ATTRIBUTE_UNUSED
= elf_hash_table (info
);
934 bfd_reloc_status_type flag
;
936 if (reloc_data
.should_relocate
== FALSE
)
939 switch (reloc_data
.howto
->size
)
942 insn
= arc_bfd_get_32 (abfd
,
943 contents
+ reloc_data
.reloc_offset
,
944 reloc_data
.input_section
);
947 insn
= arc_bfd_get_16 (abfd
,
948 contents
+ reloc_data
.reloc_offset
,
949 reloc_data
.input_section
);
952 insn
= arc_bfd_get_8 (abfd
,
953 contents
+ reloc_data
.reloc_offset
,
954 reloc_data
.input_section
);
964 switch (reloc_data
.howto
->type
)
966 #include "elf/arc-reloc.def"
973 /* Check for relocation overflow. */
974 if (reloc_data
.howto
->complain_on_overflow
!= complain_overflow_dont
)
975 flag
= bfd_check_overflow (reloc_data
.howto
->complain_on_overflow
,
976 reloc_data
.howto
->bitsize
,
977 reloc_data
.howto
->rightshift
,
978 bfd_arch_bits_per_address (abfd
),
981 flag
= arc_special_overflow_checks (reloc_data
, relocation
, info
);
983 #undef DEBUG_ARC_RELOC
984 #define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
985 if (flag
!= bfd_reloc_ok
)
987 PR_DEBUG ( "Relocation overflows !!!!\n");
989 DEBUG_ARC_RELOC (reloc_data
);
992 "Relocation value = signed -> %d, unsigned -> %u"
993 ", hex -> (0x%08x)\n",
995 (unsigned int) relocation
,
996 (unsigned int) relocation
);
999 #undef DEBUG_ARC_RELOC
1000 #define DEBUG_ARC_RELOC(A)
1002 /* Write updated instruction back to memory. */
1003 switch (reloc_data
.howto
->size
)
1006 arc_bfd_put_32 (abfd
, insn
,
1007 contents
+ reloc_data
.reloc_offset
,
1008 reloc_data
.input_section
);
1011 arc_bfd_put_16 (abfd
, insn
,
1012 contents
+ reloc_data
.reloc_offset
,
1013 reloc_data
.input_section
);
1016 arc_bfd_put_8 (abfd
, insn
,
1017 contents
+ reloc_data
.reloc_offset
,
1018 reloc_data
.input_section
);
1021 ARC_DEBUG ("size = %d\n", reloc_data
.howto
->size
);
1026 return bfd_reloc_ok
;
1041 #undef ARC_RELOC_HOWTO
1043 static struct got_entry
**
1044 arc_get_local_got_ents (bfd
* abfd
)
1046 static struct got_entry
**local_got_ents
= NULL
;
1048 if (local_got_ents
== NULL
)
1051 Elf_Internal_Shdr
*symtab_hdr
= &((elf_tdata (abfd
))->symtab_hdr
);
1053 size
= symtab_hdr
->sh_info
* sizeof (bfd_vma
);
1054 local_got_ents
= (struct got_entry
**)
1055 bfd_alloc (abfd
, sizeof(struct got_entry
*) * size
);
1056 if (local_got_ents
== NULL
)
1059 memset (local_got_ents
, 0, sizeof(struct got_entry
*) * size
);
1060 elf_local_got_ents (abfd
) = local_got_ents
;
1063 return local_got_ents
;
1066 /* Relocate an arc ELF section.
1067 Function : elf_arc_relocate_section
1068 Brief : Relocate an arc section, by handling all the relocations
1069 appearing in that section.
1070 Args : output_bfd : The bfd being written to.
1071 info : Link information.
1072 input_bfd : The input bfd.
1073 input_section : The section being relocated.
1074 contents : contents of the section being relocated.
1075 relocs : List of relocations in the section.
1076 local_syms : is a pointer to the swapped in local symbols.
1077 local_section : is an array giving the section in the input file
1078 corresponding to the st_shndx field of each
1081 elf_arc_relocate_section (bfd
* output_bfd
,
1082 struct bfd_link_info
* info
,
1084 asection
* input_section
,
1085 bfd_byte
* contents
,
1086 Elf_Internal_Rela
* relocs
,
1087 Elf_Internal_Sym
* local_syms
,
1088 asection
** local_sections
)
1090 Elf_Internal_Shdr
* symtab_hdr
;
1091 struct elf_link_hash_entry
** sym_hashes
;
1092 struct got_entry
** local_got_ents
;
1093 Elf_Internal_Rela
* rel
;
1094 Elf_Internal_Rela
* wrel
;
1095 Elf_Internal_Rela
* relend
;
1096 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
1098 symtab_hdr
= &((elf_tdata (input_bfd
))->symtab_hdr
);
1099 sym_hashes
= elf_sym_hashes (input_bfd
);
1101 rel
= wrel
= relocs
;
1102 relend
= relocs
+ input_section
->reloc_count
;
1103 for (; rel
< relend
; wrel
++, rel
++)
1105 enum elf_arc_reloc_type r_type
;
1106 reloc_howto_type
* howto
;
1107 unsigned long r_symndx
;
1108 struct elf_link_hash_entry
* h
;
1109 Elf_Internal_Sym
* sym
;
1111 struct elf_link_hash_entry
*h2
;
1113 struct arc_relocation_data reloc_data
=
1117 .got_offset_value
= 0,
1119 .sym_section
= NULL
,
1121 .input_section
= NULL
,
1122 .sdata_begin_symbol_vma
= 0,
1123 .sdata_begin_symbol_vma_set
= FALSE
,
1124 .got_symbol_vma
= 0,
1125 .should_relocate
= FALSE
1128 r_type
= ELF32_R_TYPE (rel
->r_info
);
1130 if (r_type
>= (int) R_ARC_max
)
1132 bfd_set_error (bfd_error_bad_value
);
1135 howto
= arc_elf_howto (r_type
);
1137 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1139 /* If we are generating another .o file and the symbol in not
1140 local, skip this relocation. */
1141 if (bfd_link_relocatable (info
))
1143 /* This is a relocateable link. We don't have to change
1144 anything, unless the reloc is against a section symbol,
1145 in which case we have to adjust according to where the
1146 section symbol winds up in the output section. */
1148 /* Checks if this is a local symbol and thus the reloc
1149 might (will??) be against a section symbol. */
1150 if (r_symndx
< symtab_hdr
->sh_info
)
1152 sym
= local_syms
+ r_symndx
;
1153 if (ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
1155 sec
= local_sections
[r_symndx
];
1157 /* for RELA relocs.Just adjust the addend
1158 value in the relocation entry. */
1159 rel
->r_addend
+= sec
->output_offset
+ sym
->st_value
;
1162 PR_DEBUG ("local symbols reloc "
1163 "(section=%d %s) seen in %s\n",
1165 local_sections
[r_symndx
]->name
,
1166 __PRETTY_FUNCTION__
)
1172 h2
= elf_link_hash_lookup (elf_hash_table (info
), "__SDATA_BEGIN__",
1173 FALSE
, FALSE
, TRUE
);
1175 if (reloc_data
.sdata_begin_symbol_vma_set
== FALSE
1176 && h2
!= NULL
&& h2
->root
.type
!= bfd_link_hash_undefined
1177 && h2
->root
.u
.def
.section
->output_section
!= NULL
)
1178 /* TODO: Verify this condition. */
1180 reloc_data
.sdata_begin_symbol_vma
=
1181 (h2
->root
.u
.def
.value
+
1182 h2
->root
.u
.def
.section
->output_section
->vma
);
1183 reloc_data
.sdata_begin_symbol_vma_set
= TRUE
;
1186 reloc_data
.input_section
= input_section
;
1187 reloc_data
.howto
= howto
;
1188 reloc_data
.reloc_offset
= rel
->r_offset
;
1189 reloc_data
.reloc_addend
= rel
->r_addend
;
1191 /* This is a final link. */
1196 if (r_symndx
< symtab_hdr
->sh_info
) /* A local symbol. */
1198 sym
= local_syms
+ r_symndx
;
1199 sec
= local_sections
[r_symndx
];
1203 /* TODO: This code is repeated from below. We should
1204 clean it and remove duplications.
1205 Sec is used check for discarded sections.
1206 Need to redesign code below. */
1208 /* Get the symbol's entry in the symtab. */
1209 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1211 while (h
->root
.type
== bfd_link_hash_indirect
1212 || h
->root
.type
== bfd_link_hash_warning
)
1213 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1215 /* If we have encountered a definition for this symbol. */
1216 if (h
->root
.type
== bfd_link_hash_defined
1217 || h
->root
.type
== bfd_link_hash_defweak
)
1219 reloc_data
.sym_value
= h
->root
.u
.def
.value
;
1220 sec
= h
->root
.u
.def
.section
;
1224 /* Clean relocs for symbols in discarded sections. */
1225 if (sec
!= NULL
&& discarded_section (sec
))
1227 _bfd_clear_contents (howto
, input_bfd
, input_section
,
1228 contents
+ rel
->r_offset
);
1229 rel
->r_offset
= rel
->r_offset
;
1233 /* For ld -r, remove relocations in debug sections against
1234 sections defined in discarded sections. Not done for
1235 eh_frame editing code expects to be present. */
1236 if (bfd_link_relocatable (info
)
1237 && (input_section
->flags
& SEC_DEBUGGING
))
1243 if (bfd_link_relocatable (info
))
1250 if (r_symndx
< symtab_hdr
->sh_info
) /* A local symbol. */
1252 struct got_entry
*entry
;
1254 local_got_ents
= arc_get_local_got_ents (output_bfd
);
1255 entry
= local_got_ents
[r_symndx
];
1257 reloc_data
.sym_value
= sym
->st_value
;
1258 reloc_data
.sym_section
= sec
;
1259 reloc_data
.symbol_name
=
1260 bfd_elf_string_from_elf_section (input_bfd
,
1261 symtab_hdr
->sh_link
,
1264 /* Mergeable section handling. */
1265 if ((sec
->flags
& SEC_MERGE
)
1266 && ELF_ST_TYPE (sym
->st_info
) == STT_SECTION
)
1270 rel
->r_addend
= _bfd_elf_rel_local_sym (output_bfd
, sym
,
1271 &msec
, rel
->r_addend
);
1272 rel
->r_addend
-= (sec
->output_section
->vma
1273 + sec
->output_offset
1275 rel
->r_addend
+= msec
->output_section
->vma
+ msec
->output_offset
;
1277 reloc_data
.reloc_addend
= rel
->r_addend
;
1280 if ((is_reloc_for_GOT (howto
)
1281 || is_reloc_for_TLS (howto
)) && entry
!= NULL
)
1283 if (is_reloc_for_TLS (howto
))
1284 while (entry
->type
== GOT_NORMAL
&& entry
->next
!= NULL
)
1285 entry
= entry
->next
;
1287 if (is_reloc_for_GOT (howto
))
1288 while (entry
->type
!= GOT_NORMAL
&& entry
->next
!= NULL
)
1289 entry
= entry
->next
;
1291 if (entry
->type
== GOT_TLS_GD
&& entry
->processed
== FALSE
)
1293 bfd_vma sym_vma
= sym
->st_value
1294 + sec
->output_section
->vma
1295 + sec
->output_offset
;
1297 /* Create dynamic relocation for local sym. */
1298 ADD_RELA (output_bfd
, got
, entry
->offset
, 0,
1299 R_ARC_TLS_DTPMOD
, 0);
1300 ADD_RELA (output_bfd
, got
, entry
->offset
+4, 0,
1301 R_ARC_TLS_DTPOFF
, 0);
1303 bfd_vma sec_vma
= sec
->output_section
->vma
1304 + sec
->output_offset
;
1305 bfd_put_32 (output_bfd
, sym_vma
- sec_vma
,
1306 htab
->sgot
->contents
+ entry
->offset
+ 4);
1308 ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_GD value "
1309 "= 0x%x @ 0x%x, for symbol %s\n",
1311 htab
->sgot
->contents
+ entry
->offset
+ 4,
1314 entry
->processed
= TRUE
;
1316 if (entry
->type
== GOT_TLS_IE
&& entry
->processed
== FALSE
)
1318 bfd_vma sym_vma
= sym
->st_value
1319 + sec
->output_section
->vma
1320 + sec
->output_offset
;
1321 bfd_vma sec_vma
= htab
->tls_sec
->output_section
->vma
;
1322 bfd_put_32 (output_bfd
, sym_vma
- sec_vma
,
1323 htab
->sgot
->contents
+ entry
->offset
);
1324 /* TODO: Check if this type of relocs is the cause
1325 for all the ARC_NONE dynamic relocs. */
1327 ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_IE value = "
1328 "0x%x @ 0x%x, for symbol %s\n",
1330 htab
->sgot
->contents
+ entry
->offset
,
1333 entry
->processed
= TRUE
;
1335 if (entry
->type
== GOT_NORMAL
&& entry
->processed
== FALSE
)
1337 bfd_vma sec_vma
= reloc_data
.sym_section
->output_section
->vma
1338 + reloc_data
.sym_section
->output_offset
;
1340 bfd_put_32 (output_bfd
, reloc_data
.sym_value
+ sec_vma
,
1341 htab
->sgot
->contents
+ entry
->offset
);
1343 ARC_DEBUG ("arc_info: PATCHED: 0x%08x @ 0x%08x for "
1344 "sym %s in got offset 0x%x\n",
1345 reloc_data
.sym_value
+ sec_vma
,
1346 htab
->sgot
->output_section
->vma
1347 + htab
->sgot
->output_offset
+ entry
->offset
,
1350 entry
->processed
= TRUE
;
1353 reloc_data
.got_offset_value
= entry
->offset
;
1354 ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
1355 "vma = 0x%x for symbol %s\n",
1356 entry
->type
, entry
->offset
,
1357 htab
->sgot
->output_section
->vma
1358 + htab
->sgot
->output_offset
+ entry
->offset
,
1362 BFD_ASSERT (htab
->sgot
!= NULL
|| !is_reloc_for_GOT (howto
));
1363 if (htab
->sgot
!= NULL
)
1364 reloc_data
.got_symbol_vma
= htab
->sgot
->output_section
->vma
1365 + htab
->sgot
->output_offset
;
1367 reloc_data
.should_relocate
= TRUE
;
1369 else /* Global symbol. */
1371 /* Get the symbol's entry in the symtab. */
1372 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1374 while (h
->root
.type
== bfd_link_hash_indirect
1375 || h
->root
.type
== bfd_link_hash_warning
)
1376 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1378 /* TODO: Need to validate what was the intention. */
1379 /* BFD_ASSERT ((h->dynindx == -1) || (h->forced_local != 0)); */
1380 reloc_data
.symbol_name
= h
->root
.root
.string
;
1382 /* If we have encountered a definition for this symbol. */
1383 if (h
->root
.type
== bfd_link_hash_defined
1384 || h
->root
.type
== bfd_link_hash_defweak
)
1386 reloc_data
.sym_value
= h
->root
.u
.def
.value
;
1387 reloc_data
.sym_section
= h
->root
.u
.def
.section
;
1389 reloc_data
.should_relocate
= TRUE
;
1391 if (is_reloc_for_GOT (howto
) && !bfd_link_pic (info
))
1393 /* TODO: Change it to use arc_do_relocation with
1394 ARC_32 reloc. Try to use ADD_RELA macro. */
1395 bfd_vma relocation
=
1396 reloc_data
.sym_value
+ reloc_data
.reloc_addend
1397 + (reloc_data
.sym_section
->output_section
!= NULL
?
1398 (reloc_data
.sym_section
->output_offset
1399 + reloc_data
.sym_section
->output_section
->vma
)
1402 BFD_ASSERT (h
->got
.glist
);
1403 bfd_vma got_offset
= h
->got
.glist
->offset
;
1404 bfd_put_32 (output_bfd
, relocation
,
1405 htab
->sgot
->contents
+ got_offset
);
1407 if (is_reloc_for_PLT (howto
) && h
->plt
.offset
!= (bfd_vma
) -1)
1409 /* TODO: This is repeated up here. */
1410 reloc_data
.sym_value
= h
->plt
.offset
;
1411 reloc_data
.sym_section
= htab
->splt
;
1414 else if (h
->root
.type
== bfd_link_hash_undefweak
)
1416 /* Is weak symbol and has no definition. */
1417 if (is_reloc_for_GOT (howto
))
1419 reloc_data
.sym_value
= h
->root
.u
.def
.value
;
1420 reloc_data
.sym_section
= htab
->sgot
;
1421 reloc_data
.should_relocate
= TRUE
;
1423 else if (is_reloc_for_PLT (howto
)
1424 && h
->plt
.offset
!= (bfd_vma
) -1)
1426 /* TODO: This is repeated up here. */
1427 reloc_data
.sym_value
= h
->plt
.offset
;
1428 reloc_data
.sym_section
= htab
->splt
;
1429 reloc_data
.should_relocate
= TRUE
;
1436 if (is_reloc_for_GOT (howto
))
1438 reloc_data
.sym_value
= h
->root
.u
.def
.value
;
1439 reloc_data
.sym_section
= htab
->sgot
;
1441 reloc_data
.should_relocate
= TRUE
;
1443 else if (is_reloc_for_PLT (howto
))
1445 /* Fail if it is linking for PIE and the symbol is
1447 if (bfd_link_executable (info
))
1448 (*info
->callbacks
->undefined_symbol
)
1449 (info
, h
->root
.root
.string
, input_bfd
, input_section
,
1450 rel
->r_offset
, TRUE
);
1451 reloc_data
.sym_value
= h
->plt
.offset
;
1452 reloc_data
.sym_section
= htab
->splt
;
1454 reloc_data
.should_relocate
= TRUE
;
1456 else if (!bfd_link_pic (info
))
1457 (*info
->callbacks
->undefined_symbol
)
1458 (info
, h
->root
.root
.string
, input_bfd
, input_section
,
1459 rel
->r_offset
, TRUE
);
1462 if (h
->got
.glist
!= NULL
)
1464 struct got_entry
*entry
= h
->got
.glist
;
1466 if (is_reloc_for_GOT (howto
) || is_reloc_for_TLS (howto
))
1468 if (! elf_hash_table (info
)->dynamic_sections_created
1469 || (bfd_link_pic (info
)
1470 && SYMBOL_REFERENCES_LOCAL (info
, h
)))
1472 reloc_data
.sym_value
= h
->root
.u
.def
.value
;
1473 reloc_data
.sym_section
= h
->root
.u
.def
.section
;
1475 if (is_reloc_for_TLS (howto
))
1476 while (entry
->type
== GOT_NORMAL
&& entry
->next
!= NULL
)
1477 entry
= entry
->next
;
1479 if (entry
->processed
== FALSE
1480 && (entry
->type
== GOT_TLS_GD
1481 || entry
->type
== GOT_TLS_IE
))
1483 bfd_vma sym_value
= h
->root
.u
.def
.value
1484 + h
->root
.u
.def
.section
->output_section
->vma
1485 + h
->root
.u
.def
.section
->output_offset
;
1488 elf_hash_table (info
)->tls_sec
->output_section
->vma
;
1490 bfd_put_32 (output_bfd
,
1491 sym_value
- sec_vma
,
1492 htab
->sgot
->contents
+ entry
->offset
1493 + (entry
->existing_entries
== TLS_GOT_MOD_AND_OFF
? 4 : 0));
1495 ARC_DEBUG ("arc_info: FIXED -> %s value = 0x%x "
1496 "@ 0x%x, for symbol %s\n",
1497 (entry
->type
== GOT_TLS_GD
? "GOT_TLS_GD" :
1499 sym_value
- sec_vma
,
1500 htab
->sgot
->contents
+ entry
->offset
1501 + (entry
->existing_entries
== TLS_GOT_MOD_AND_OFF
? 4 : 0),
1502 h
->root
.root
.string
);
1504 entry
->processed
= TRUE
;
1507 if (entry
->type
== GOT_TLS_IE
&& entry
->processed
== FALSE
)
1509 bfd_vma sec_vma
= htab
->tls_sec
->output_section
->vma
;
1510 bfd_put_32 (output_bfd
,
1511 reloc_data
.sym_value
- sec_vma
,
1512 htab
->sgot
->contents
+ entry
->offset
);
1515 if (entry
->type
== GOT_NORMAL
&& entry
->processed
== FALSE
)
1518 reloc_data
.sym_section
->output_section
->vma
1519 + reloc_data
.sym_section
->output_offset
;
1521 if (h
->root
.type
!= bfd_link_hash_undefweak
)
1523 bfd_put_32 (output_bfd
,
1524 reloc_data
.sym_value
+ sec_vma
,
1525 htab
->sgot
->contents
+ entry
->offset
);
1527 ARC_DEBUG ("arc_info: PATCHED: 0x%08x "
1528 "@ 0x%08x for sym %s in got offset 0x%x\n",
1529 reloc_data
.sym_value
+ sec_vma
,
1530 htab
->sgot
->output_section
->vma
1531 + htab
->sgot
->output_offset
+ entry
->offset
,
1532 h
->root
.root
.string
,
1537 ARC_DEBUG ("arc_info: PATCHED: NOT_PATCHED "
1538 "@ 0x%08x for sym %s in got offset 0x%x "
1540 htab
->sgot
->output_section
->vma
1541 + htab
->sgot
->output_offset
+ entry
->offset
,
1542 h
->root
.root
.string
,
1546 entry
->processed
= TRUE
;
1551 reloc_data
.got_offset_value
= entry
->offset
;
1553 ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
1554 "vma = 0x%x for symbol %s\n",
1555 entry
->type
, entry
->offset
,
1556 htab
->sgot
->output_section
->vma
1557 + htab
->sgot
->output_offset
+ entry
->offset
,
1558 h
->root
.root
.string
);
1561 BFD_ASSERT (htab
->sgot
!= NULL
|| !is_reloc_for_GOT (howto
));
1562 if (htab
->sgot
!= NULL
)
1563 reloc_data
.got_symbol_vma
= htab
->sgot
->output_section
->vma
1564 + htab
->sgot
->output_offset
;
1572 case R_ARC_32_PCREL
:
1573 if ((bfd_link_pic (info
) || bfd_link_pie (info
))
1574 && ((r_type
!= R_ARC_PC32
&& r_type
!= R_ARC_32_PCREL
)
1577 && (!info
->symbolic
|| !h
->def_regular
))))
1579 Elf_Internal_Rela outrel
;
1581 bfd_boolean skip
= FALSE
;
1582 bfd_boolean relocate
= FALSE
;
1583 asection
*sreloc
= _bfd_elf_get_dynamic_reloc_section
1584 (input_bfd
, input_section
,
1587 BFD_ASSERT (sreloc
!= NULL
);
1589 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
,
1593 if (outrel
.r_offset
== (bfd_vma
) -1)
1596 outrel
.r_addend
= rel
->r_addend
;
1597 outrel
.r_offset
+= (input_section
->output_section
->vma
1598 + input_section
->output_offset
);
1600 #define IS_ARC_PCREL_TYPE(TYPE) \
1601 ( (TYPE == R_ARC_PC32) \
1602 || (TYPE == R_ARC_32_PCREL))
1605 memset (&outrel
, 0, sizeof outrel
);
1610 && ((IS_ARC_PCREL_TYPE (r_type
))
1611 || !(bfd_link_executable (info
)
1612 || SYMBOLIC_BIND (info
, h
))
1613 || ! h
->def_regular
))
1615 BFD_ASSERT (h
!= NULL
);
1616 if ((input_section
->flags
& SEC_ALLOC
) != 0)
1621 BFD_ASSERT (h
->dynindx
!= -1);
1622 outrel
.r_info
= ELF32_R_INFO (h
->dynindx
, r_type
);
1626 /* Handle local symbols, they either do not have a
1627 global hash table entry (h == NULL), or are
1628 forced local due to a version script
1629 (h->forced_local), or the third condition is
1630 legacy, it appears to say something like, for
1631 links where we are pre-binding the symbols, or
1632 there's not an entry for this symbol in the
1633 dynamic symbol table, and it's a regular symbol
1634 not defined in a shared object, then treat the
1635 symbol as local, resolve it now. */
1637 /* outrel.r_addend = 0; */
1638 outrel
.r_info
= ELF32_R_INFO (0, R_ARC_RELATIVE
);
1641 BFD_ASSERT (sreloc
->contents
!= 0);
1643 loc
= sreloc
->contents
;
1644 loc
+= sreloc
->reloc_count
* sizeof (Elf32_External_Rela
);
1645 sreloc
->reloc_count
+= 1;
1647 bfd_elf32_swap_reloca_out (output_bfd
, &outrel
, loc
);
1649 if (relocate
== FALSE
)
1657 if (is_reloc_SDA_relative (howto
)
1658 && (reloc_data
.sdata_begin_symbol_vma_set
== FALSE
))
1660 (*_bfd_error_handler
)
1661 ("Error: Linker symbol __SDATA_BEGIN__ not found");
1662 bfd_set_error (bfd_error_bad_value
);
1666 DEBUG_ARC_RELOC (reloc_data
);
1668 /* Make sure we have with a dynamic linker. In case of GOT and PLT
1669 the sym_section should point to .got or .plt respectively. */
1670 if ((is_reloc_for_GOT (howto
) || is_reloc_for_PLT (howto
))
1671 && reloc_data
.sym_section
== NULL
)
1673 (*_bfd_error_handler
)
1674 (_("GOT and PLT relocations cannot be fixed with a non dynamic linker."));
1675 bfd_set_error (bfd_error_bad_value
);
1679 if (arc_do_relocation (contents
, reloc_data
, info
) != bfd_reloc_ok
)
1686 static struct dynamic_sections
1687 arc_create_dynamic_sections (bfd
* abfd
, struct bfd_link_info
*info
)
1689 struct elf_link_hash_table
*htab
;
1691 struct dynamic_sections ds
=
1693 .initialized
= FALSE
,
1703 htab
= elf_hash_table (info
);
1706 /* Create dynamic sections for relocatable executables so that we
1707 can copy relocations. */
1708 if (! htab
->dynamic_sections_created
&& bfd_link_pic (info
))
1710 if (! _bfd_elf_link_create_dynamic_sections (abfd
, info
))
1714 dynobj
= (elf_hash_table (info
))->dynobj
;
1718 ds
.sgot
= htab
->sgot
;
1719 ds
.srelgot
= htab
->srelgot
;
1721 ds
.sgotplt
= bfd_get_section_by_name (dynobj
, ".got.plt");
1722 ds
.srelgotplt
= ds
.srelplt
;
1724 ds
.splt
= bfd_get_section_by_name (dynobj
, ".plt");
1725 ds
.srelplt
= bfd_get_section_by_name (dynobj
, ".rela.plt");
1728 if (htab
->dynamic_sections_created
)
1730 ds
.sdyn
= bfd_get_section_by_name (dynobj
, ".dynamic");
1733 ds
.initialized
= TRUE
;
1738 #define ADD_SYMBOL_REF_SEC_AND_RELOC(SECNAME, COND_FOR_RELOC, H) \
1739 htab->s##SECNAME->size; \
1741 if (COND_FOR_RELOC) \
1743 htab->srel##SECNAME->size += sizeof (Elf32_External_Rela); \
1744 ARC_DEBUG ("arc_info: Added reloc space in " \
1745 #SECNAME " section at " __FILE__ \
1746 ":%d for symbol\n", \
1747 __LINE__, name_for_global_symbol (H)); \
1750 if (h->dynindx == -1 && !h->forced_local) \
1751 if (! bfd_elf_link_record_dynamic_symbol (info, H)) \
1753 htab->s##SECNAME->size += 4; \
1757 elf_arc_check_relocs (bfd
* abfd
,
1758 struct bfd_link_info
* info
,
1760 const Elf_Internal_Rela
* relocs
)
1762 Elf_Internal_Shdr
* symtab_hdr
;
1763 struct elf_link_hash_entry
** sym_hashes
;
1764 struct got_entry
** local_got_ents
;
1765 const Elf_Internal_Rela
* rel
;
1766 const Elf_Internal_Rela
* rel_end
;
1768 asection
* sreloc
= NULL
;
1769 struct elf_link_hash_table
* htab
= elf_hash_table (info
);
1771 if (bfd_link_relocatable (info
))
1774 dynobj
= (elf_hash_table (info
))->dynobj
;
1775 symtab_hdr
= &((elf_tdata (abfd
))->symtab_hdr
);
1776 sym_hashes
= elf_sym_hashes (abfd
);
1777 local_got_ents
= arc_get_local_got_ents (abfd
);
1779 rel_end
= relocs
+ sec
->reloc_count
;
1780 for (rel
= relocs
; rel
< rel_end
; rel
++)
1782 enum elf_arc_reloc_type r_type
;
1783 reloc_howto_type
*howto
;
1784 unsigned long r_symndx
;
1785 struct elf_link_hash_entry
*h
;
1787 r_type
= ELF32_R_TYPE (rel
->r_info
);
1789 if (r_type
>= (int) R_ARC_max
)
1791 bfd_set_error (bfd_error_bad_value
);
1794 howto
= arc_elf_howto (r_type
);
1797 && (is_reloc_for_GOT (howto
) == TRUE
1798 || is_reloc_for_TLS (howto
) == TRUE
))
1800 dynobj
= elf_hash_table (info
)->dynobj
= abfd
;
1801 if (! _bfd_elf_create_got_section (abfd
, info
))
1805 /* Load symbol information. */
1806 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1807 if (r_symndx
< symtab_hdr
->sh_info
) /* Is a local symbol. */
1809 else /* Global one. */
1810 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1816 /* During shared library creation, these relocs should not
1817 appear in a shared library (as memory will be read only
1818 and the dynamic linker can not resolve these. However
1819 the error should not occur for e.g. debugging or
1820 non-readonly sections. */
1821 if ((bfd_link_dll (info
) && !bfd_link_pie (info
))
1822 && (sec
->flags
& SEC_ALLOC
) != 0
1823 && (sec
->flags
& SEC_READONLY
) != 0
1824 && ((sec
->flags
& SEC_CODE
) != 0
1825 || (sec
->flags
& SEC_DEBUGGING
) != 0))
1829 name
= h
->root
.root
.string
;
1831 /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); */
1833 (*_bfd_error_handler
)
1835 %B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
1837 arc_elf_howto (r_type
)->name
,
1839 bfd_set_error (bfd_error_bad_value
);
1843 /* In some cases we are not setting the 'non_got_ref'
1844 flag, even though the relocations don't require a GOT
1845 access. We should extend the testing in this area to
1846 ensure that no significant cases are being missed. */
1851 case R_ARC_32_PCREL
:
1852 if ((bfd_link_pic (info
) || bfd_link_pie (info
))
1853 && ((r_type
!= R_ARC_PC32
&& r_type
!= R_ARC_32_PCREL
)
1856 && (!info
->symbolic
|| !h
->def_regular
))))
1860 sreloc
= _bfd_elf_make_dynamic_reloc_section (sec
, dynobj
,
1868 sreloc
->size
+= sizeof (Elf32_External_Rela
);
1875 if (is_reloc_for_PLT (howto
) == TRUE
)
1883 if (is_reloc_for_GOT (howto
) == TRUE
)
1888 if (local_got_ents
[r_symndx
] == NULL
)
1891 ADD_SYMBOL_REF_SEC_AND_RELOC (got
,
1892 bfd_link_pic (info
),
1894 new_got_entry_to_list (&(local_got_ents
[r_symndx
]),
1895 GOT_NORMAL
, offset
, TLS_GOT_NONE
);
1900 /* Global symbol. */
1901 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1902 if (h
->got
.glist
== NULL
)
1905 ADD_SYMBOL_REF_SEC_AND_RELOC (got
, TRUE
, h
);
1906 new_got_entry_to_list (&h
->got
.glist
,
1907 GOT_NORMAL
, offset
, TLS_GOT_NONE
);
1912 if (is_reloc_for_TLS (howto
) == TRUE
)
1914 enum tls_type_e type
= GOT_UNKNOWN
;
1918 case R_ARC_TLS_GD_GOT
:
1921 case R_ARC_TLS_IE_GOT
:
1928 struct got_entry
**list
= NULL
;
1930 list
= &(h
->got
.glist
);
1932 list
= &(local_got_ents
[r_symndx
]);
1934 if (type
!= GOT_UNKNOWN
&& !symbol_has_entry_of_type (*list
, type
))
1936 enum tls_got_entries entries
= TLS_GOT_NONE
;
1938 ADD_SYMBOL_REF_SEC_AND_RELOC (got
, TRUE
, h
);
1940 if (type
== GOT_TLS_GD
)
1942 bfd_vma ATTRIBUTE_UNUSED notneeded
=
1943 ADD_SYMBOL_REF_SEC_AND_RELOC (got
, TRUE
, h
);
1944 entries
= TLS_GOT_MOD_AND_OFF
;
1947 if (entries
== TLS_GOT_NONE
)
1948 entries
= TLS_GOT_OFF
;
1950 new_got_entry_to_list (list
, type
, offset
, entries
);
1958 #define ELF_DYNAMIC_INTERPRETER "/sbin/ld-uClibc.so"
1960 static struct plt_version_t
*
1961 arc_get_plt_version (struct bfd_link_info
*info
)
1965 for (i
= 0; i
< 1; i
++)
1967 ARC_DEBUG ("%d: size1 = %d, size2 = %d\n", i
,
1968 plt_versions
[i
].entry_size
,
1969 plt_versions
[i
].elem_size
);
1972 if (bfd_get_mach (info
->output_bfd
) == bfd_mach_arc_arcv2
)
1974 if (bfd_link_pic (info
))
1975 return &(plt_versions
[ELF_ARCV2_PIC
]);
1977 return &(plt_versions
[ELF_ARCV2_ABS
]);
1981 if (bfd_link_pic (info
))
1982 return &(plt_versions
[ELF_ARC_PIC
]);
1984 return &(plt_versions
[ELF_ARC_ABS
]);
1989 add_symbol_to_plt (struct bfd_link_info
*info
)
1991 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
1994 struct plt_version_t
*plt_data
= arc_get_plt_version (info
);
1996 /* If this is the first .plt entry, make room for the special first
1998 if (htab
->splt
->size
== 0)
1999 htab
->splt
->size
+= plt_data
->entry_size
;
2001 ret
= htab
->splt
->size
;
2003 htab
->splt
->size
+= plt_data
->elem_size
;
2004 ARC_DEBUG ("PLT_SIZE = %d\n", htab
->splt
->size
);
2006 htab
->sgotplt
->size
+= 4;
2007 htab
->srelplt
->size
+= sizeof (Elf32_External_Rela
);
2012 #define PLT_DO_RELOCS_FOR_ENTRY(ABFD, DS, RELOCS) \
2013 plt_do_relocs_for_symbol (ABFD, DS, RELOCS, 0, 0)
2016 plt_do_relocs_for_symbol (bfd
*abfd
,
2017 struct elf_link_hash_table
*htab
,
2018 const struct plt_reloc
*reloc
,
2020 bfd_vma symbol_got_offset
)
2022 while (SYM_ONLY (reloc
->symbol
) != LAST_RELOC
)
2024 bfd_vma relocation
= 0;
2026 switch (SYM_ONLY (reloc
->symbol
))
2030 htab
->sgotplt
->output_section
->vma
+
2031 htab
->sgotplt
->output_offset
+ symbol_got_offset
;
2034 relocation
+= reloc
->addend
;
2036 if (IS_RELATIVE (reloc
->symbol
))
2038 bfd_vma reloc_offset
= reloc
->offset
;
2039 reloc_offset
-= (IS_INSN_32 (reloc
->symbol
)) ? 4 : 0;
2040 reloc_offset
-= (IS_INSN_24 (reloc
->symbol
)) ? 2 : 0;
2042 relocation
-= htab
->splt
->output_section
->vma
2043 + htab
->splt
->output_offset
2044 + plt_offset
+ reloc_offset
;
2047 /* TODO: being ME is not a property of the relocation but of the
2048 section of which is applying the relocation. */
2049 if (IS_MIDDLE_ENDIAN (reloc
->symbol
) && !bfd_big_endian (abfd
))
2052 ((relocation
& 0xffff0000) >> 16) |
2053 ((relocation
& 0xffff) << 16);
2056 switch (reloc
->size
)
2059 bfd_put_32 (htab
->splt
->output_section
->owner
,
2061 htab
->splt
->contents
+ plt_offset
+ reloc
->offset
);
2065 reloc
= &(reloc
[1]); /* Jump to next relocation. */
2070 relocate_plt_for_symbol (bfd
*output_bfd
,
2071 struct bfd_link_info
*info
,
2072 struct elf_link_hash_entry
*h
)
2074 struct plt_version_t
*plt_data
= arc_get_plt_version (info
);
2075 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
2077 bfd_vma plt_index
= (h
->plt
.offset
- plt_data
->entry_size
)
2078 / plt_data
->elem_size
;
2079 bfd_vma got_offset
= (plt_index
+ 3) * 4;
2081 ARC_DEBUG ("arc_info: PLT_OFFSET = 0x%x, PLT_ENTRY_VMA = 0x%x, \
2082 GOT_ENTRY_OFFSET = 0x%x, GOT_ENTRY_VMA = 0x%x, for symbol %s\n",
2084 htab
->splt
->output_section
->vma
2085 + htab
->splt
->output_offset
2088 htab
->sgotplt
->output_section
->vma
2089 + htab
->sgotplt
->output_offset
2091 h
->root
.root
.string
);
2096 uint16_t *ptr
= (uint16_t *) plt_data
->elem
;
2097 for (i
= 0; i
< plt_data
->elem_size
/2; i
++)
2099 uint16_t data
= ptr
[i
];
2100 bfd_put_16 (output_bfd
,
2102 htab
->splt
->contents
+ h
->plt
.offset
+ (i
*2));
2106 plt_do_relocs_for_symbol (output_bfd
, htab
,
2107 plt_data
->elem_relocs
,
2111 /* Fill in the entry in the global offset table. */
2112 bfd_put_32 (output_bfd
,
2113 (bfd_vma
) (htab
->splt
->output_section
->vma
2114 + htab
->splt
->output_offset
),
2115 htab
->sgotplt
->contents
+ got_offset
);
2117 /* TODO: Fill in the entry in the .rela.plt section. */
2119 Elf_Internal_Rela rel
;
2122 rel
.r_offset
= (htab
->sgotplt
->output_section
->vma
2123 + htab
->sgotplt
->output_offset
2127 BFD_ASSERT (h
->dynindx
!= -1);
2128 rel
.r_info
= ELF32_R_INFO (h
->dynindx
, R_ARC_JMP_SLOT
);
2130 loc
= htab
->srelplt
->contents
;
2131 loc
+= plt_index
* sizeof (Elf32_External_Rela
); /* relA */
2132 bfd_elf32_swap_reloca_out (output_bfd
, &rel
, loc
);
2137 relocate_plt_for_entry (bfd
*abfd
,
2138 struct bfd_link_info
*info
)
2140 struct plt_version_t
*plt_data
= arc_get_plt_version (info
);
2141 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
2145 uint16_t *ptr
= (uint16_t *) plt_data
->entry
;
2146 for (i
= 0; i
< plt_data
->entry_size
/2; i
++)
2148 uint16_t data
= ptr
[i
];
2151 htab
->splt
->contents
+ (i
*2));
2154 PLT_DO_RELOCS_FOR_ENTRY (abfd
, htab
, plt_data
->entry_relocs
);
2157 /* Desc : Adjust a symbol defined by a dynamic object and referenced
2158 by a regular object. The current definition is in some section of
2159 the dynamic object, but we're not including those sections. We
2160 have to change the definition to something the rest of the link can
2164 elf_arc_adjust_dynamic_symbol (struct bfd_link_info
*info
,
2165 struct elf_link_hash_entry
*h
)
2168 bfd
*dynobj
= (elf_hash_table (info
))->dynobj
;
2169 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
2171 if (h
->type
== STT_FUNC
2172 || h
->type
== STT_GNU_IFUNC
2173 || h
->needs_plt
== 1)
2175 if (!bfd_link_pic (info
) && !h
->def_dynamic
&& !h
->ref_dynamic
)
2177 /* This case can occur if we saw a PLT32 reloc in an input
2178 file, but the symbol was never referred to by a dynamic
2179 object. In such a case, we don't actually need to build
2180 a procedure linkage table, and we can just do a PC32
2182 BFD_ASSERT (h
->needs_plt
);
2186 /* Make sure this symbol is output as a dynamic symbol. */
2187 if (h
->dynindx
== -1 && !h
->forced_local
2188 && !bfd_elf_link_record_dynamic_symbol (info
, h
))
2191 if (bfd_link_pic (info
)
2192 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h
))
2194 bfd_vma loc
= add_symbol_to_plt (info
);
2196 if (!bfd_link_pic (info
) && !h
->def_regular
)
2198 h
->root
.u
.def
.section
= htab
->splt
;
2199 h
->root
.u
.def
.value
= loc
;
2201 h
->plt
.offset
= loc
;
2205 h
->plt
.offset
= (bfd_vma
) -1;
2211 /* If this is a weak symbol, and there is a real definition, the
2212 processor independent code will have arranged for us to see the
2213 real definition first, and we can just use the same value. */
2214 if (h
->u
.weakdef
!= NULL
)
2216 BFD_ASSERT (h
->u
.weakdef
->root
.type
== bfd_link_hash_defined
2217 || h
->u
.weakdef
->root
.type
== bfd_link_hash_defweak
);
2218 h
->root
.u
.def
.section
= h
->u
.weakdef
->root
.u
.def
.section
;
2219 h
->root
.u
.def
.value
= h
->u
.weakdef
->root
.u
.def
.value
;
2223 /* This is a reference to a symbol defined by a dynamic object which
2224 is not a function. */
2226 /* If we are creating a shared library, we must presume that the
2227 only references to the symbol are via the global offset table.
2228 For such cases we need not do anything here; the relocations will
2229 be handled correctly by relocate_section. */
2230 if (!bfd_link_executable (info
))
2233 /* If there are no non-GOT references, we do not need a copy
2235 if (!h
->non_got_ref
)
2238 /* If -z nocopyreloc was given, we won't generate them either. */
2239 if (info
->nocopyreloc
)
2245 /* We must allocate the symbol in our .dynbss section, which will
2246 become part of the .bss section of the executable. There will be
2247 an entry for this symbol in the .dynsym section. The dynamic
2248 object will contain position independent code, so all references
2249 from the dynamic object to this symbol will go through the global
2250 offset table. The dynamic linker will use the .dynsym entry to
2251 determine the address it must put in the global offset table, so
2252 both the dynamic object and the regular object will refer to the
2253 same memory location for the variable. */
2258 /* We must generate a R_ARC_COPY reloc to tell the dynamic linker to
2259 copy the initial value out of the dynamic object and into the
2260 runtime process image. We need to remember the offset into the
2261 .rela.bss section we are going to use. */
2262 if ((h
->root
.u
.def
.section
->flags
& SEC_ALLOC
) != 0)
2266 srel
= bfd_get_section_by_name (dynobj
, ".rela.bss");
2267 BFD_ASSERT (srel
!= NULL
);
2268 srel
->size
+= sizeof (Elf32_External_Rela
);
2272 s
= bfd_get_section_by_name (dynobj
, ".dynbss");
2273 BFD_ASSERT (s
!= NULL
);
2275 return _bfd_elf_adjust_dynamic_copy (info
, h
, s
);
2278 /* Function : elf_arc_finish_dynamic_symbol
2279 Brief : Finish up dynamic symbol handling. We set the
2280 contents of various dynamic sections here.
2285 Returns : True/False as the return status. */
2288 elf_arc_finish_dynamic_symbol (bfd
* output_bfd
,
2289 struct bfd_link_info
*info
,
2290 struct elf_link_hash_entry
*h
,
2291 Elf_Internal_Sym
* sym
)
2293 if (h
->plt
.offset
!= (bfd_vma
) -1)
2295 relocate_plt_for_symbol (output_bfd
, info
, h
);
2297 if (!h
->def_regular
)
2299 /* Mark the symbol as undefined, rather than as defined in
2300 the .plt section. Leave the value alone. */
2301 sym
->st_shndx
= SHN_UNDEF
;
2305 if (h
->got
.glist
!= NULL
)
2307 struct got_entry
*list
= h
->got
.glist
;
2309 /* Traverse the list of got entries for this symbol. */
2312 bfd_vma got_offset
= h
->got
.glist
->offset
;
2314 if (list
->type
== GOT_NORMAL
2315 && list
->created_dyn_relocation
== FALSE
)
2317 if (bfd_link_pic (info
)
2318 && (info
->symbolic
|| h
->dynindx
== -1)
2321 ADD_RELA (output_bfd
, got
, got_offset
, 0, R_ARC_RELATIVE
, 0);
2323 /* Do not fully understand the side effects of this condition.
2324 The relocation space might still being reserved. Perhaps
2325 I should clear its value. */
2326 else if (h
->dynindx
!= -1)
2328 ADD_RELA (output_bfd
, got
, got_offset
, h
->dynindx
,
2331 list
->created_dyn_relocation
= TRUE
;
2333 else if (list
->existing_entries
!= TLS_GOT_NONE
)
2335 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
2336 enum tls_got_entries e
= list
->existing_entries
;
2338 BFD_ASSERT (list
->type
!= GOT_TLS_GD
2339 || list
->existing_entries
== TLS_GOT_MOD_AND_OFF
);
2341 bfd_vma dynindx
= h
->dynindx
== -1 ? 0 : h
->dynindx
;
2342 if (e
== TLS_GOT_MOD_AND_OFF
|| e
== TLS_GOT_MOD
)
2344 ADD_RELA (output_bfd
, got
, got_offset
, dynindx
,
2345 R_ARC_TLS_DTPMOD
, 0);
2346 ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2347 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2350 htab
->sgot
->output_section
->vma
2351 + htab
->sgot
->output_offset
+ got_offset
,
2354 if (e
== TLS_GOT_MOD_AND_OFF
|| e
== TLS_GOT_OFF
)
2357 if (list
->type
== GOT_TLS_IE
)
2358 addend
= bfd_get_32 (output_bfd
,
2359 htab
->sgot
->contents
+ got_offset
);
2361 ADD_RELA (output_bfd
, got
,
2362 got_offset
+ (e
== TLS_GOT_MOD_AND_OFF
? 4 : 0),
2364 (list
->type
== GOT_TLS_IE
?
2365 R_ARC_TLS_TPOFF
: R_ARC_TLS_DTPOFF
),
2368 ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2369 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2372 htab
->sgot
->output_section
->vma
2373 + htab
->sgot
->output_offset
+ got_offset
,
2381 h
->got
.glist
= NULL
;
2386 bfd_vma rel_offset
= (h
->root
.u
.def
.value
2387 + h
->root
.u
.def
.section
->output_section
->vma
2388 + h
->root
.u
.def
.section
->output_offset
);
2391 bfd_get_section_by_name (h
->root
.u
.def
.section
->owner
,
2394 bfd_byte
* loc
= srelbss
->contents
2395 + (srelbss
->reloc_count
* sizeof (Elf32_External_Rela
));
2396 srelbss
->reloc_count
++;
2398 Elf_Internal_Rela rel
;
2400 rel
.r_offset
= rel_offset
;
2402 BFD_ASSERT (h
->dynindx
!= -1);
2403 rel
.r_info
= ELF32_R_INFO (h
->dynindx
, R_ARC_COPY
);
2405 bfd_elf32_swap_reloca_out (output_bfd
, &rel
, loc
);
2408 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
2409 if (strcmp (h
->root
.root
.string
, "_DYNAMIC") == 0
2410 || strcmp (h
->root
.root
.string
, "__DYNAMIC") == 0
2411 || strcmp (h
->root
.root
.string
, "_GLOBAL_OFFSET_TABLE_") == 0)
2412 sym
->st_shndx
= SHN_ABS
;
2417 #define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION) \
2419 if (SYMBOL != NULL) \
2420 h = elf_link_hash_lookup (elf_hash_table (info), \
2421 SYMBOL, FALSE, FALSE, TRUE); \
2422 else if (SECTION != NULL) \
2423 s = bfd_get_linker_section (dynobj, SECTION); \
2426 /* Function : elf_arc_finish_dynamic_sections
2427 Brief : Finish up the dynamic sections handling.
2432 Returns : True/False as the return status. */
2435 elf_arc_finish_dynamic_sections (bfd
* output_bfd
,
2436 struct bfd_link_info
*info
)
2438 struct dynamic_sections ds
= arc_create_dynamic_sections (output_bfd
, info
);
2439 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
2440 bfd
*dynobj
= (elf_hash_table (info
))->dynobj
;
2444 Elf32_External_Dyn
*dyncon
, *dynconend
;
2446 dyncon
= (Elf32_External_Dyn
*) ds
.sdyn
->contents
;
2448 (Elf32_External_Dyn
*) (ds
.sdyn
->contents
+ ds
.sdyn
->size
);
2449 for (; dyncon
< dynconend
; dyncon
++)
2451 Elf_Internal_Dyn internal_dyn
;
2452 bfd_boolean do_it
= FALSE
;
2454 struct elf_link_hash_entry
*h
= NULL
;
2457 bfd_elf32_swap_dyn_in (dynobj
, dyncon
, &internal_dyn
);
2459 switch (internal_dyn
.d_tag
)
2461 GET_SYMBOL_OR_SECTION (DT_INIT
, "_init", NULL
)
2462 GET_SYMBOL_OR_SECTION (DT_FINI
, "_fini", NULL
)
2463 GET_SYMBOL_OR_SECTION (DT_PLTGOT
, NULL
, ".plt")
2464 GET_SYMBOL_OR_SECTION (DT_JMPREL
, NULL
, ".rela.plt")
2465 GET_SYMBOL_OR_SECTION (DT_PLTRELSZ
, NULL
, ".rela.plt")
2466 GET_SYMBOL_OR_SECTION (DT_RELASZ
, NULL
, ".rela.plt")
2467 GET_SYMBOL_OR_SECTION (DT_VERSYM
, NULL
, ".gnu.version")
2468 GET_SYMBOL_OR_SECTION (DT_VERDEF
, NULL
, ".gnu.version_d")
2469 GET_SYMBOL_OR_SECTION (DT_VERNEED
, NULL
, ".gnu.version_r")
2474 /* In case the dynamic symbols should be updated with a symbol. */
2476 && (h
->root
.type
== bfd_link_hash_defined
2477 || h
->root
.type
== bfd_link_hash_defweak
))
2481 internal_dyn
.d_un
.d_val
= h
->root
.u
.def
.value
;
2482 asec_ptr
= h
->root
.u
.def
.section
;
2483 if (asec_ptr
->output_section
!= NULL
)
2485 internal_dyn
.d_un
.d_val
+=
2486 (asec_ptr
->output_section
->vma
+
2487 asec_ptr
->output_offset
);
2491 /* The symbol is imported from another shared
2492 library and does not apply to this one. */
2493 internal_dyn
.d_un
.d_val
= 0;
2497 else if (s
!= NULL
) /* With a section information. */
2499 switch (internal_dyn
.d_tag
)
2506 internal_dyn
.d_un
.d_ptr
= (s
->output_section
->vma
2507 + s
->output_offset
);
2512 internal_dyn
.d_un
.d_val
= s
->size
;
2518 internal_dyn
.d_un
.d_val
-= s
->size
;
2528 bfd_elf32_swap_dyn_out (output_bfd
, &internal_dyn
, dyncon
);
2531 if (htab
->splt
->size
> 0)
2533 relocate_plt_for_entry (output_bfd
, info
);
2536 /* TODO: Validate this. */
2537 elf_section_data (htab
->srelplt
->output_section
)->this_hdr
.sh_entsize
2541 /* Fill in the first three entries in the global offset table. */
2544 struct elf_link_hash_entry
*h
;
2545 h
= elf_link_hash_lookup (elf_hash_table (info
), "_GLOBAL_OFFSET_TABLE_",
2546 FALSE
, FALSE
, TRUE
);
2548 if (h
!= NULL
&& h
->root
.type
!= bfd_link_hash_undefined
2549 && h
->root
.u
.def
.section
!= NULL
)
2551 asection
*sec
= h
->root
.u
.def
.section
;
2553 if (ds
.sdyn
== NULL
)
2554 bfd_put_32 (output_bfd
, (bfd_vma
) 0,
2557 bfd_put_32 (output_bfd
,
2558 ds
.sdyn
->output_section
->vma
+ ds
.sdyn
->output_offset
,
2560 bfd_put_32 (output_bfd
, (bfd_vma
) 0, sec
->contents
+ 4);
2561 bfd_put_32 (output_bfd
, (bfd_vma
) 0, sec
->contents
+ 8);
2568 #define ADD_DYNAMIC_SYMBOL(NAME, TAG) \
2569 h = elf_link_hash_lookup (elf_hash_table (info), \
2570 NAME, FALSE, FALSE, FALSE); \
2571 if ((h != NULL && (h->ref_regular || h->def_regular))) \
2572 if (! _bfd_elf_add_dynamic_entry (info, TAG, 0)) \
2575 /* Set the sizes of the dynamic sections. */
2577 elf_arc_size_dynamic_sections (bfd
* output_bfd
,
2578 struct bfd_link_info
*info
)
2582 bfd_boolean relocs_exist
= FALSE
;
2583 bfd_boolean reltext_exist
= FALSE
;
2584 struct dynamic_sections ds
= arc_create_dynamic_sections (output_bfd
, info
);
2585 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
2587 dynobj
= (elf_hash_table (info
))->dynobj
;
2588 BFD_ASSERT (dynobj
!= NULL
);
2590 if ((elf_hash_table (info
))->dynamic_sections_created
)
2592 struct elf_link_hash_entry
*h
;
2594 /* Set the contents of the .interp section to the
2596 if (!bfd_link_pic (info
))
2598 s
= bfd_get_section_by_name (dynobj
, ".interp");
2599 BFD_ASSERT (s
!= NULL
);
2600 s
->size
= sizeof (ELF_DYNAMIC_INTERPRETER
);
2601 s
->contents
= (unsigned char *) ELF_DYNAMIC_INTERPRETER
;
2604 /* Add some entries to the .dynamic section. We fill in some of
2605 the values later, in elf_bfd_final_link, but we must add the
2606 entries now so that we know the final size of the .dynamic
2607 section. Checking if the .init section is present. We also
2608 create DT_INIT and DT_FINI entries if the init_str has been
2609 changed by the user. */
2610 ADD_DYNAMIC_SYMBOL ("init", DT_INIT
);
2611 ADD_DYNAMIC_SYMBOL ("fini", DT_FINI
);
2615 /* We may have created entries in the .rela.got section.
2616 However, if we are not creating the dynamic sections, we will
2617 not actually use these entries. Reset the size of .rela.got,
2618 which will cause it to get stripped from the output file
2620 if (htab
->srelgot
!= NULL
)
2621 htab
->srelgot
->size
= 0;
2624 if (htab
->splt
!= NULL
&& htab
->splt
->size
== 0)
2625 htab
->splt
->flags
|= SEC_EXCLUDE
;
2626 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
2628 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
2631 if (strncmp (s
->name
, ".rela", 5) == 0)
2635 s
->flags
|= SEC_EXCLUDE
;
2639 if (strcmp (s
->name
, ".rela.plt") != 0)
2641 const char *outname
=
2642 bfd_get_section_name (output_bfd
,
2643 htab
->srelplt
->output_section
);
2645 asection
*target
= bfd_get_section_by_name (output_bfd
,
2648 relocs_exist
= TRUE
;
2649 if (target
!= NULL
&& target
->size
!= 0
2650 && (target
->flags
& SEC_READONLY
) != 0
2651 && (target
->flags
& SEC_ALLOC
) != 0)
2652 reltext_exist
= TRUE
;
2656 /* We use the reloc_count field as a counter if we need to
2657 copy relocs into the output file. */
2661 if (strcmp (s
->name
, ".dynamic") == 0)
2665 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
2667 if (s
->contents
== NULL
&& s
->size
!= 0)
2673 /* TODO: Check if this is needed. */
2674 if (!bfd_link_pic (info
))
2675 if (!_bfd_elf_add_dynamic_entry (info
, DT_DEBUG
, 0))
2678 if (htab
->splt
&& (htab
->splt
->flags
& SEC_EXCLUDE
) == 0)
2679 if (!_bfd_elf_add_dynamic_entry (info
, DT_PLTGOT
, 0)
2680 || !_bfd_elf_add_dynamic_entry (info
, DT_PLTRELSZ
, 0)
2681 || !_bfd_elf_add_dynamic_entry (info
, DT_PLTREL
, DT_RELA
)
2682 || !_bfd_elf_add_dynamic_entry (info
, DT_JMPREL
, 0)
2686 if (relocs_exist
== TRUE
)
2687 if (!_bfd_elf_add_dynamic_entry (info
, DT_RELA
, 0)
2688 || !_bfd_elf_add_dynamic_entry (info
, DT_RELASZ
, 0)
2689 || !_bfd_elf_add_dynamic_entry (info
, DT_RELAENT
,
2690 sizeof (Elf32_External_Rela
))
2694 if (reltext_exist
== TRUE
)
2695 if (!_bfd_elf_add_dynamic_entry (info
, DT_TEXTREL
, 0))
2703 /* Classify dynamic relocs such that -z combreloc can reorder and combine
2705 static enum elf_reloc_type_class
2706 elf32_arc_reloc_type_class (const struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
2707 const asection
*rel_sec ATTRIBUTE_UNUSED
,
2708 const Elf_Internal_Rela
*rela
)
2710 switch ((int) ELF32_R_TYPE (rela
->r_info
))
2712 case R_ARC_RELATIVE
:
2713 return reloc_class_relative
;
2714 case R_ARC_JMP_SLOT
:
2715 return reloc_class_plt
;
2717 return reloc_class_copy
;
2718 /* TODO: Needed in future to support ifunc. */
2720 case R_ARC_IRELATIVE:
2721 return reloc_class_ifunc;
2724 return reloc_class_normal
;
2728 const struct elf_size_info arc_elf32_size_info
=
2730 sizeof (Elf32_External_Ehdr
),
2731 sizeof (Elf32_External_Phdr
),
2732 sizeof (Elf32_External_Shdr
),
2733 sizeof (Elf32_External_Rel
),
2734 sizeof (Elf32_External_Rela
),
2735 sizeof (Elf32_External_Sym
),
2736 sizeof (Elf32_External_Dyn
),
2737 sizeof (Elf_External_Note
),
2741 ELFCLASS32
, EV_CURRENT
,
2742 bfd_elf32_write_out_phdrs
,
2743 bfd_elf32_write_shdrs_and_ehdr
,
2744 bfd_elf32_checksum_contents
,
2745 bfd_elf32_write_relocs
,
2746 bfd_elf32_swap_symbol_in
,
2747 bfd_elf32_swap_symbol_out
,
2748 bfd_elf32_slurp_reloc_table
,
2749 bfd_elf32_slurp_symbol_table
,
2750 bfd_elf32_swap_dyn_in
,
2751 bfd_elf32_swap_dyn_out
,
2752 bfd_elf32_swap_reloc_in
,
2753 bfd_elf32_swap_reloc_out
,
2754 bfd_elf32_swap_reloca_in
,
2755 bfd_elf32_swap_reloca_out
2758 #define elf_backend_size_info arc_elf32_size_info
2760 static struct bfd_link_hash_table
*
2761 arc_elf_link_hash_table_create (bfd
*abfd
)
2763 struct elf_link_hash_table
*htab
;
2765 htab
= bfd_zmalloc (sizeof (*htab
));
2769 if (!_bfd_elf_link_hash_table_init (htab
, abfd
,
2770 _bfd_elf_link_hash_newfunc
,
2771 sizeof (struct elf_link_hash_entry
),
2778 htab
->init_got_refcount
.refcount
= 0;
2779 htab
->init_got_refcount
.glist
= NULL
;
2780 htab
->init_got_offset
.offset
= 0;
2781 htab
->init_got_offset
.glist
= NULL
;
2782 return (struct bfd_link_hash_table
*) htab
;
2785 /* Hook called by the linker routine which adds symbols from an object
2789 elf_arc_add_symbol_hook (bfd
* abfd
,
2790 struct bfd_link_info
* info
,
2791 Elf_Internal_Sym
* sym
,
2792 const char ** namep ATTRIBUTE_UNUSED
,
2793 flagword
* flagsp ATTRIBUTE_UNUSED
,
2794 asection
** secp ATTRIBUTE_UNUSED
,
2795 bfd_vma
* valp ATTRIBUTE_UNUSED
)
2797 if (ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
2798 && (abfd
->flags
& DYNAMIC
) == 0
2799 && bfd_get_flavour (info
->output_bfd
) == bfd_target_elf_flavour
)
2800 elf_tdata (info
->output_bfd
)->has_gnu_symbols
|= elf_gnu_symbol_ifunc
;
2805 #define TARGET_LITTLE_SYM arc_elf32_le_vec
2806 #define TARGET_LITTLE_NAME "elf32-littlearc"
2807 #define TARGET_BIG_SYM arc_elf32_be_vec
2808 #define TARGET_BIG_NAME "elf32-bigarc"
2809 #define ELF_ARCH bfd_arch_arc
2810 #define ELF_MACHINE_CODE EM_ARC_COMPACT
2811 #define ELF_MACHINE_ALT1 EM_ARC_COMPACT2
2812 #define ELF_MAXPAGESIZE 0x2000
2814 #define bfd_elf32_bfd_link_hash_table_create arc_elf_link_hash_table_create
2816 #define bfd_elf32_bfd_merge_private_bfd_data arc_elf_merge_private_bfd_data
2817 #define bfd_elf32_bfd_reloc_type_lookup arc_elf32_bfd_reloc_type_lookup
2818 #define bfd_elf32_bfd_set_private_flags arc_elf_set_private_flags
2819 #define bfd_elf32_bfd_print_private_bfd_data arc_elf_print_private_bfd_data
2820 #define bfd_elf32_bfd_copy_private_bfd_data arc_elf_copy_private_bfd_data
2822 #define elf_info_to_howto_rel arc_info_to_howto_rel
2823 #define elf_backend_object_p arc_elf_object_p
2824 #define elf_backend_final_write_processing arc_elf_final_write_processing
2826 #define elf_backend_relocate_section elf_arc_relocate_section
2827 #define elf_backend_check_relocs elf_arc_check_relocs
2828 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
2830 #define elf_backend_reloc_type_class elf32_arc_reloc_type_class
2832 #define elf_backend_adjust_dynamic_symbol elf_arc_adjust_dynamic_symbol
2833 #define elf_backend_finish_dynamic_symbol elf_arc_finish_dynamic_symbol
2835 #define elf_backend_finish_dynamic_sections elf_arc_finish_dynamic_sections
2836 #define elf_backend_size_dynamic_sections elf_arc_size_dynamic_sections
2837 #define elf_backend_add_symbol_hook elf_arc_add_symbol_hook
2839 #define elf_backend_can_gc_sections 1
2840 #define elf_backend_want_got_plt 1
2841 #define elf_backend_plt_readonly 1
2842 #define elf_backend_rela_plts_and_copies_p 1
2843 #define elf_backend_want_plt_sym 0
2844 #define elf_backend_got_header_size 12
2846 #define elf_backend_may_use_rel_p 0
2847 #define elf_backend_may_use_rela_p 1
2848 #define elf_backend_default_use_rela_p 1
2850 #define elf_backend_default_execstack 0
2852 #include "elf32-target.h"