Update my e-mail address.
[binutils-gdb.git] / bfd / elf32-arc.c
blobcdecdb145289706caddc1b6f4e57b5dad0cd577d
1 /* ARC-specific support for 32-bit ELF
2 Copyright (C) 1994-2017 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. */
22 #include "sysdep.h"
23 #include "bfd.h"
24 #include "libbfd.h"
25 #include "elf-bfd.h"
26 #include "elf/arc.h"
27 #include "libiberty.h"
28 #include "opcode/arc-func.h"
29 #include "opcode/arc.h"
30 #include "arc-plt.h"
32 #define FEATURE_LIST_NAME bfd_feature_list
33 #define CONFLICT_LIST bfd_conflict_list
34 #include "opcode/arc-attrs.h"
36 /* #define ARC_ENABLE_DEBUG 1 */
37 #ifdef ARC_ENABLE_DEBUG
38 static const char *
39 name_for_global_symbol (struct elf_link_hash_entry *h)
41 static char *local_str = "(local)";
42 if (h == NULL)
43 return local_str;
44 return h->root.root.string;
46 #define ARC_DEBUG(fmt, args...) fprintf (stderr, fmt, ##args)
47 #else
48 #define ARC_DEBUG(...)
49 #endif
52 #define ADD_RELA(BFD, SECTION, OFFSET, SYM_IDX, TYPE, ADDEND) \
53 { \
54 struct elf_link_hash_table *_htab = elf_hash_table (info); \
55 Elf_Internal_Rela _rel; \
56 bfd_byte * _loc; \
58 if (_htab->dynamic_sections_created == TRUE) \
59 { \
60 BFD_ASSERT (_htab->srel##SECTION &&_htab->srel##SECTION->contents); \
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); \
71 } \
75 /* The default symbols representing the init and fini dyn values.
76 TODO: Check what is the relation of those strings with arclinux.em
77 and DT_INIT. */
78 #define INIT_SYM_STRING "_init"
79 #define FINI_SYM_STRING "_fini"
81 char * init_str = INIT_SYM_STRING;
82 char * fini_str = FINI_SYM_STRING;
84 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
85 case VALUE: \
86 return "R_" #TYPE; \
87 break;
89 static ATTRIBUTE_UNUSED const char *
90 reloc_type_to_name (unsigned int type)
92 switch (type)
94 #include "elf/arc-reloc.def"
96 default:
97 return "UNKNOWN";
98 break;
101 #undef ARC_RELOC_HOWTO
103 /* Try to minimize the amount of space occupied by relocation tables
104 on the ROM (not that the ROM won't be swamped by other ELF overhead). */
106 #define USE_REL 1
108 static ATTRIBUTE_UNUSED bfd_boolean
109 is_reloc_PC_relative (reloc_howto_type *howto)
111 return (strstr (howto->name, "PC") != NULL) ? TRUE : FALSE;
114 static bfd_boolean
115 is_reloc_SDA_relative (reloc_howto_type *howto)
117 return (strstr (howto->name, "SDA") != NULL) ? TRUE : FALSE;
120 static bfd_boolean
121 is_reloc_for_GOT (reloc_howto_type * howto)
123 if (strstr (howto->name, "TLS") != NULL)
124 return FALSE;
125 return (strstr (howto->name, "GOT") != NULL) ? TRUE : FALSE;
128 static bfd_boolean
129 is_reloc_for_PLT (reloc_howto_type * howto)
131 return (strstr (howto->name, "PLT") != NULL) ? TRUE : FALSE;
134 static bfd_boolean
135 is_reloc_for_TLS (reloc_howto_type *howto)
137 return (strstr (howto->name, "TLS") != NULL) ? TRUE : FALSE;
140 struct arc_relocation_data
142 bfd_signed_vma reloc_offset;
143 bfd_signed_vma reloc_addend;
144 bfd_signed_vma got_offset_value;
146 bfd_signed_vma sym_value;
147 asection * sym_section;
149 reloc_howto_type *howto;
151 asection * input_section;
153 bfd_signed_vma sdata_begin_symbol_vma;
154 bfd_boolean sdata_begin_symbol_vma_set;
155 bfd_signed_vma got_symbol_vma;
157 bfd_boolean should_relocate;
159 const char * symbol_name;
162 /* Should be included at this location due to static declarations
163 * defined before this point. */
164 #include "arc-got.h"
166 #define arc_bfd_get_8(A,B,C) bfd_get_8(A,B)
167 #define arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
168 #define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
169 #define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C)
170 #define arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
171 #define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)
174 static bfd_reloc_status_type
175 arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
176 arelent *reloc_entry,
177 asymbol *symbol_in,
178 void *data ATTRIBUTE_UNUSED,
179 asection *input_section,
180 bfd *output_bfd,
181 char ** error_message ATTRIBUTE_UNUSED)
183 if (output_bfd != NULL)
185 reloc_entry->address += input_section->output_offset;
187 /* In case of relocateable link and if the reloc is against a
188 section symbol, the addend needs to be adjusted according to
189 where the section symbol winds up in the output section. */
190 if ((symbol_in->flags & BSF_SECTION_SYM) && symbol_in->section)
191 reloc_entry->addend += symbol_in->section->output_offset;
193 return bfd_reloc_ok;
196 return bfd_reloc_continue;
200 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
201 TYPE = VALUE,
202 enum howto_list
204 #include "elf/arc-reloc.def"
205 HOWTO_LIST_LAST
207 #undef ARC_RELOC_HOWTO
209 #define ARC_RELOC_HOWTO(TYPE, VALUE, RSIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
210 [TYPE] = HOWTO (R_##TYPE, 0, RSIZE, BITSIZE, FALSE, 0, \
211 complain_overflow_##OVERFLOW, arc_elf_reloc, \
212 "R_" #TYPE, FALSE, 0, 0, FALSE),
214 static struct reloc_howto_struct elf_arc_howto_table[] =
216 #include "elf/arc-reloc.def"
217 /* Example of what is generated by the preprocessor. Currently kept as an
218 example.
219 HOWTO (R_ARC_NONE, // Type.
220 0, // Rightshift.
221 2, // Size (0 = byte, 1 = short, 2 = long).
222 32, // Bitsize.
223 FALSE, // PC_relative.
224 0, // Bitpos.
225 complain_overflow_bitfield, // Complain_on_overflow.
226 bfd_elf_generic_reloc, // Special_function.
227 "R_ARC_NONE", // Name.
228 TRUE, // Partial_inplace.
229 0, // Src_mask.
230 0, // Dst_mask.
231 FALSE), // PCrel_offset.
234 #undef ARC_RELOC_HOWTO
236 static void arc_elf_howto_init (void)
238 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
239 elf_arc_howto_table[TYPE].pc_relative = \
240 (strstr (#FORMULA, " P ") != NULL || strstr (#FORMULA, " PDATA ") != NULL); \
241 elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0); \
242 /* Only 32 bit data relocations should be marked as ME. */ \
243 if (strstr (#FORMULA, " ME ") != NULL) \
245 BFD_ASSERT (SIZE == 2); \
248 #include "elf/arc-reloc.def"
251 #undef ARC_RELOC_HOWTO
254 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
255 [TYPE] = VALUE,
256 const int howto_table_lookup[] =
258 #include "elf/arc-reloc.def"
260 #undef ARC_RELOC_HOWTO
262 static reloc_howto_type *
263 arc_elf_howto (unsigned int r_type)
265 if (elf_arc_howto_table[R_ARC_32].dst_mask == 0)
266 arc_elf_howto_init ();
267 return &elf_arc_howto_table[r_type];
270 /* Map BFD reloc types to ARC ELF reloc types. */
272 struct arc_reloc_map
274 bfd_reloc_code_real_type bfd_reloc_val;
275 unsigned char elf_reloc_val;
278 /* ARC ELF linker hash entry. */
279 struct elf_arc_link_hash_entry
281 struct elf_link_hash_entry root;
283 /* Track dynamic relocs copied for this symbol. */
284 struct elf_dyn_relocs *dyn_relocs;
287 /* ARC ELF linker hash table. */
288 struct elf_arc_link_hash_table
290 struct elf_link_hash_table elf;
293 static struct bfd_hash_entry *
294 elf_arc_link_hash_newfunc (struct bfd_hash_entry *entry,
295 struct bfd_hash_table *table,
296 const char *string)
298 /* Allocate the structure if it has not already been allocated by a
299 subclass. */
300 if (entry == NULL)
302 entry = (struct bfd_hash_entry *)
303 bfd_hash_allocate (table,
304 sizeof (struct elf_arc_link_hash_entry));
305 if (entry == NULL)
306 return entry;
309 /* Call the allocation method of the superclass. */
310 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
311 if (entry != NULL)
313 struct elf_arc_link_hash_entry *eh;
315 eh = (struct elf_arc_link_hash_entry *) entry;
316 eh->dyn_relocs = NULL;
319 return entry;
322 /* Destroy an ARC ELF linker hash table. */
323 static void
324 elf_arc_link_hash_table_free (bfd *obfd)
326 _bfd_elf_link_hash_table_free (obfd);
329 /* Create an ARC ELF linker hash table. */
331 static struct bfd_link_hash_table *
332 arc_elf_link_hash_table_create (bfd *abfd)
334 struct elf_arc_link_hash_table *ret;
336 ret = (struct elf_arc_link_hash_table *) bfd_zmalloc (sizeof (*ret));
337 if (ret == NULL)
338 return NULL;
340 if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
341 elf_arc_link_hash_newfunc,
342 sizeof (struct elf_arc_link_hash_entry),
343 ARC_ELF_DATA))
345 free (ret);
346 return NULL;
349 ret->elf.init_got_refcount.refcount = 0;
350 ret->elf.init_got_refcount.glist = NULL;
351 ret->elf.init_got_offset.offset = 0;
352 ret->elf.init_got_offset.glist = NULL;
354 ret->elf.root.hash_table_free = elf_arc_link_hash_table_free;
356 return &ret->elf.root;
359 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
360 { BFD_RELOC_##TYPE, R_##TYPE },
361 static const struct arc_reloc_map arc_reloc_map[] =
363 #include "elf/arc-reloc.def"
365 {BFD_RELOC_NONE, R_ARC_NONE},
366 {BFD_RELOC_8, R_ARC_8},
367 {BFD_RELOC_16, R_ARC_16},
368 {BFD_RELOC_24, R_ARC_24},
369 {BFD_RELOC_32, R_ARC_32},
371 #undef ARC_RELOC_HOWTO
373 typedef ATTRIBUTE_UNUSED bfd_vma (*replace_func) (unsigned, int ATTRIBUTE_UNUSED);
375 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
376 case TYPE: \
377 func = (void *) RELOC_FUNCTION; \
378 break;
379 static replace_func
380 get_replace_function (bfd *abfd, unsigned int r_type)
382 void *func = NULL;
384 switch (r_type)
386 #include "elf/arc-reloc.def"
389 if (func == replace_bits24 && bfd_big_endian (abfd))
390 return (replace_func) replace_bits24_be;
392 return (replace_func) func;
394 #undef ARC_RELOC_HOWTO
396 static reloc_howto_type *
397 arc_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
398 bfd_reloc_code_real_type code)
400 unsigned int i;
402 for (i = ARRAY_SIZE (arc_reloc_map); i--;)
404 if (arc_reloc_map[i].bfd_reloc_val == code)
405 return arc_elf_howto (arc_reloc_map[i].elf_reloc_val);
408 return NULL;
411 /* Function to set the ELF flag bits. */
412 static bfd_boolean
413 arc_elf_set_private_flags (bfd *abfd, flagword flags)
415 elf_elfheader (abfd)->e_flags = flags;
416 elf_flags_init (abfd) = TRUE;
417 return TRUE;
420 /* Print private flags. */
421 static bfd_boolean
422 arc_elf_print_private_bfd_data (bfd *abfd, void * ptr)
424 FILE *file = (FILE *) ptr;
425 flagword flags;
427 BFD_ASSERT (abfd != NULL && ptr != NULL);
429 /* Print normal ELF private data. */
430 _bfd_elf_print_private_bfd_data (abfd, ptr);
432 flags = elf_elfheader (abfd)->e_flags;
433 fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
435 switch (flags & EF_ARC_MACH_MSK)
437 case EF_ARC_CPU_ARCV2HS : fprintf (file, " -mcpu=ARCv2HS"); break;
438 case EF_ARC_CPU_ARCV2EM : fprintf (file, " -mcpu=ARCv2EM"); break;
439 case E_ARC_MACH_ARC600 : fprintf (file, " -mcpu=ARC600"); break;
440 case E_ARC_MACH_ARC601 : fprintf (file, " -mcpu=ARC601"); break;
441 case E_ARC_MACH_ARC700 : fprintf (file, " -mcpu=ARC700"); break;
442 default:
443 fprintf (file, "-mcpu=unknown");
444 break;
447 switch (flags & EF_ARC_OSABI_MSK)
449 case E_ARC_OSABI_ORIG : fprintf (file, " (ABI:legacy)"); break;
450 case E_ARC_OSABI_V2 : fprintf (file, " (ABI:v2)"); break;
451 case E_ARC_OSABI_V3 : fprintf (file, " (ABI:v3)"); break;
452 case E_ARC_OSABI_V4 : fprintf (file, " (ABI:v4)"); break;
453 default:
454 fprintf (file, " (ABI:unknown)");
455 break;
458 fputc ('\n', file);
459 return TRUE;
462 /* Copy backend specific data from one object module to another. */
464 static bfd_boolean
465 arc_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
467 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
468 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
469 return TRUE;
471 BFD_ASSERT (!elf_flags_init (obfd)
472 || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
474 elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
475 elf_flags_init (obfd) = TRUE;
477 /* Copy object attributes. */
478 _bfd_elf_copy_obj_attributes (ibfd, obfd);
480 return _bfd_elf_copy_private_bfd_data (ibfd, obfd);
483 static reloc_howto_type *
484 bfd_elf32_bfd_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED,
485 const char *r_name)
487 unsigned int i;
489 for (i = 0; i < ARRAY_SIZE (elf_arc_howto_table); i++)
490 if (elf_arc_howto_table[i].name != NULL
491 && strcasecmp (elf_arc_howto_table[i].name, r_name) == 0)
492 return arc_elf_howto (i);
494 return NULL;
497 /* Set the howto pointer for an ARC ELF reloc. */
499 static void
500 arc_info_to_howto_rel (bfd * abfd ATTRIBUTE_UNUSED,
501 arelent * cache_ptr,
502 Elf_Internal_Rela * dst)
504 unsigned int r_type;
506 r_type = ELF32_R_TYPE (dst->r_info);
507 BFD_ASSERT (r_type < (unsigned int) R_ARC_max);
508 cache_ptr->howto = arc_elf_howto (r_type);
511 /* Extract CPU features from an NTBS. */
513 static unsigned
514 arc_extract_features (const char *p)
516 unsigned i, r = 0;
518 if (!p)
519 return 0;
521 for (i = 0; i < ARRAY_SIZE (bfd_feature_list); i++)
523 char *t = strstr (p, bfd_feature_list[i].attr);
524 unsigned l = strlen (bfd_feature_list[i].attr);
525 if ((t != NULL)
526 && (t[l] == ','
527 || t[l] == '\0'))
528 r |= bfd_feature_list[i].feature;
531 return r;
534 /* Concatenate two strings. s1 can be NULL but not
535 s2. */
537 static char *
538 arc_stralloc (char * s1, const char * s2)
540 char *p;
542 /* Only s1 can be null. */
543 BFD_ASSERT (s2);
545 p = s1 ? concat (s1, ",", s2, NULL) : (char *)s2;
547 return p;
550 /* Merge ARC object attributes from IBFD into OBFD. Raise an error if
551 there are conflicting attributes. */
553 static bfd_boolean
554 arc_elf_merge_attributes (bfd *ibfd, struct bfd_link_info *info)
556 bfd *obfd = info->output_bfd;
557 obj_attribute *in_attr;
558 obj_attribute *out_attr;
559 int i;
560 bfd_boolean result = TRUE;
561 const char *sec_name = get_elf_backend_data (ibfd)->obj_attrs_section;
562 char *tagname = NULL;
564 /* Skip the linker stubs file. This preserves previous behavior
565 of accepting unknown attributes in the first input file - but
566 is that a bug? */
567 if (ibfd->flags & BFD_LINKER_CREATED)
568 return TRUE;
570 /* Skip any input that hasn't attribute section.
571 This enables to link object files without attribute section with
572 any others. */
573 if (bfd_get_section_by_name (ibfd, sec_name) == NULL)
574 return TRUE;
576 if (!elf_known_obj_attributes_proc (obfd)[0].i)
578 /* This is the first object. Copy the attributes. */
579 _bfd_elf_copy_obj_attributes (ibfd, obfd);
581 out_attr = elf_known_obj_attributes_proc (obfd);
583 /* Use the Tag_null value to indicate the attributes have been
584 initialized. */
585 out_attr[0].i = 1;
587 return TRUE;
590 in_attr = elf_known_obj_attributes_proc (ibfd);
591 out_attr = elf_known_obj_attributes_proc (obfd);
593 for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
595 /* Merge this attribute with existing attributes. */
596 switch (i)
598 case Tag_ARC_PCS_config:
599 if (out_attr[i].i == 0)
600 out_attr[i].i = in_attr[i].i;
601 else if (in_attr[i].i != 0 && out_attr[i].i != in_attr[i].i)
603 const char *tagval[] = { "Absent", "Bare-metal/mwdt",
604 "Bare-metal/newlib", "Linux/uclibc",
605 "Linux/glibc" };
606 BFD_ASSERT (in_attr[i].i < 5);
607 BFD_ASSERT (out_attr[i].i < 5);
608 /* It's sometimes ok to mix different configs, so this is only
609 a warning. */
610 _bfd_error_handler
611 (_("Warning: %B: Conflicting platform configuration "
612 "%s with %s.\n"), ibfd,
613 tagval[in_attr[i].i],
614 tagval[out_attr[i].i]);
616 break;
618 case Tag_ARC_CPU_base:
619 if (out_attr[i].i == 0)
620 out_attr[i].i = in_attr[i].i;
621 else if (in_attr[i].i != 0 && out_attr[i].i != in_attr[i].i
622 && ((out_attr[i].i + in_attr[i].i) < 6))
624 const char *tagval[] = { "Absent", "ARC6xx", "ARC7xx",
625 "ARCEM", "ARCHS" };
626 BFD_ASSERT (in_attr[i].i < 5);
627 BFD_ASSERT (out_attr[i].i < 5);
628 /* We cannot mix code for different CPUs. */
629 _bfd_error_handler
630 (_("error: %B: unable to merge CPU base attributes "
631 "%s with %s.\n"),
632 obfd,
633 tagval[in_attr[i].i],
634 tagval[out_attr[i].i]);
635 result = FALSE;
636 break;
638 else
640 /* The CPUs may be different, check if we can still mix
641 the objects against the output choosen CPU. */
642 unsigned in_feature = 0;
643 unsigned out_feature = 0;
644 char *p1 = in_attr[Tag_ARC_ISA_config].s;
645 char *p2 = out_attr[Tag_ARC_ISA_config].s;
646 unsigned j;
647 unsigned cpu_out;
648 unsigned opcode_map[] = {0, ARC_OPCODE_ARC600, ARC_OPCODE_ARC700,
649 ARC_OPCODE_ARCv2EM, ARC_OPCODE_ARCv2HS};
651 BFD_ASSERT (in_attr[i].i < (sizeof (opcode_map)
652 / sizeof (unsigned)));
653 BFD_ASSERT (out_attr[i].i < (sizeof (opcode_map)
654 / sizeof (unsigned)));
655 cpu_out = opcode_map[out_attr[i].i];
657 in_feature = arc_extract_features (p1);
658 out_feature = arc_extract_features (p2);
660 /* First, check if a feature is compatible with the
661 output object chosen CPU. */
662 for (j = 0; j < ARRAY_SIZE (bfd_feature_list); j++)
663 if (((in_feature | out_feature) & bfd_feature_list[j].feature)
664 && (!(cpu_out & bfd_feature_list[j].cpus)))
666 _bfd_error_handler
667 (_("error: %B: unable to merge ISA extension attributes "
668 "%s.\n"),
669 obfd, bfd_feature_list[j].name);
670 result = FALSE;
671 break;
673 /* Second, if we have compatible features with the
674 chosen CPU, check if they are compatible among
675 them. */
676 for (j = 0; j < ARRAY_SIZE (bfd_conflict_list); j++)
677 if (((in_feature | out_feature) & bfd_conflict_list[j])
678 == bfd_conflict_list[j])
680 unsigned k;
681 for (k = 0; k < ARRAY_SIZE (bfd_feature_list); k++)
683 if (in_feature & bfd_feature_list[k].feature
684 & bfd_conflict_list[j])
685 p1 = (char *) bfd_feature_list[k].name;
686 if (out_feature & bfd_feature_list[k].feature
687 & bfd_conflict_list[j])
688 p2 = (char *) bfd_feature_list[k].name;
690 _bfd_error_handler
691 (_("error: %B: conflicting ISA extension attributes "
692 "%s with %s.\n"),
693 obfd, p1, p2);
694 result = FALSE;
695 break;
697 /* Everithing is alright. */
698 out_feature |= in_feature;
699 p1 = NULL;
700 for (j = 0; j < ARRAY_SIZE (bfd_feature_list); j++)
701 if (out_feature & bfd_feature_list[j].feature)
702 p1 = arc_stralloc (p1, bfd_feature_list[j].attr);
703 if (p1)
704 out_attr[Tag_ARC_ISA_config].s =
705 _bfd_elf_attr_strdup (obfd, p1);
707 /* Fall through. */
708 case Tag_ARC_CPU_variation:
709 case Tag_ARC_ISA_mpy_option:
710 case Tag_ARC_ABI_osver:
711 /* Use the largest value specified. */
712 if (in_attr[i].i > out_attr[i].i)
713 out_attr[i].i = in_attr[i].i;
714 break;
716 case Tag_ARC_CPU_name:
717 break;
719 case Tag_ARC_ABI_rf16:
720 if (out_attr[i].i == 0)
721 out_attr[i].i = in_attr[i].i;
722 else if (out_attr[i].i != in_attr[i].i)
724 /* We cannot mix code with rf16 and without. */
725 _bfd_error_handler
726 (_("error: %B: cannot mix rf16 with full register set %B.\n"),
727 obfd, ibfd);
728 result = FALSE;
730 break;
732 case Tag_ARC_ABI_pic:
733 tagname = "PIC";
734 /* fall through */
735 case Tag_ARC_ABI_sda:
736 if (!tagname)
737 tagname = "SDA";
738 /* fall through */
739 case Tag_ARC_ABI_tls:
741 const char *tagval[] = { "Absent", "MWDT", "GNU" };
743 if (!tagname)
744 tagname = "TLS";
746 BFD_ASSERT (in_attr[i].i < 3);
747 BFD_ASSERT (out_attr[i].i < 3);
748 if (out_attr[i].i != 0 && in_attr[i].i != 0
749 && out_attr[i].i != in_attr[i].i)
751 _bfd_error_handler
752 (_("error: %B: conflicting attributes %s: %s with %s.\n"),
753 obfd, tagname,
754 tagval[in_attr[i].i],
755 tagval[out_attr[i].i]);
756 result = FALSE;
758 tagname = NULL;
759 break;
762 case Tag_ARC_ABI_double_size:
763 tagname = "Double size";
764 /* fall through */
765 case Tag_ARC_ABI_enumsize:
766 if (!tagname)
767 tagname = "Enum size";
768 /* fall through */
769 case Tag_ARC_ABI_exceptions:
770 if (!tagname)
771 tagname = "ABI exceptions";
773 if (out_attr[i].i != 0 && in_attr[i].i != 0
774 && out_attr[i].i != in_attr[i].i)
776 _bfd_error_handler
777 (_("error: %B: conflicting attributes %s.\n"),
778 obfd, tagname);
779 result = FALSE;
781 break;
783 case Tag_ARC_ISA_apex:
784 break; /* Do nothing for APEX attributes. */
786 case Tag_ARC_ISA_config:
787 /* It is handled in Tag_ARC_CPU_base. */
788 break;
790 default:
791 result
792 = result && _bfd_elf_merge_unknown_attribute_low (ibfd, obfd, i);
795 /* If out_attr was copied from in_attr then it won't have a type yet. */
796 if (in_attr[i].type && !out_attr[i].type)
797 out_attr[i].type = in_attr[i].type;
800 /* Merge Tag_compatibility attributes and any common GNU ones. */
801 if (!_bfd_elf_merge_object_attributes (ibfd, info))
802 return FALSE;
804 /* Check for any attributes not known on ARC. */
805 result &= _bfd_elf_merge_unknown_attribute_list (ibfd, obfd);
807 return result;
810 /* Merge backend specific data from an object file to the output
811 object file when linking. */
813 static bfd_boolean
814 arc_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
816 bfd *obfd = info->output_bfd;
817 unsigned short mach_ibfd;
818 static unsigned short mach_obfd = EM_NONE;
819 flagword out_flags;
820 flagword in_flags;
821 asection *sec;
823 /* Check if we have the same endianess. */
824 if (! _bfd_generic_verify_endian_match (ibfd, info))
825 return FALSE;
827 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
828 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
829 return TRUE;
831 /* Collect ELF flags. */
832 in_flags = elf_elfheader (ibfd)->e_flags & EF_ARC_MACH_MSK;
833 out_flags = elf_elfheader (obfd)->e_flags & EF_ARC_MACH_MSK;
835 if (!elf_flags_init (obfd)) /* First call, no flags set. */
837 elf_flags_init (obfd) = TRUE;
838 out_flags = in_flags;
841 if (!arc_elf_merge_attributes (ibfd, info))
842 return FALSE;
844 /* Check to see if the input BFD actually contains any sections. Do
845 not short-circuit dynamic objects; their section list may be
846 emptied by elf_link_add_object_symbols. */
847 if (!(ibfd->flags & DYNAMIC))
849 bfd_boolean null_input_bfd = TRUE;
850 bfd_boolean only_data_sections = TRUE;
852 for (sec = ibfd->sections; sec != NULL; sec = sec->next)
854 if ((bfd_get_section_flags (ibfd, sec)
855 & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
856 == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
857 only_data_sections = FALSE;
859 null_input_bfd = FALSE;
862 if (null_input_bfd || only_data_sections)
863 return TRUE;
866 /* Complain about various flag/architecture mismatches. */
867 mach_ibfd = elf_elfheader (ibfd)->e_machine;
868 if (mach_obfd == EM_NONE)
870 mach_obfd = mach_ibfd;
872 else
874 if (mach_ibfd != mach_obfd)
876 /* xgettext:c-format */
877 _bfd_error_handler (_("ERROR: Attempting to link %B "
878 "with a binary %B of different architecture"),
879 ibfd, obfd);
880 return FALSE;
882 else if ((in_flags != out_flags)
883 /* If we have object attributes, then we already
884 checked the objects compatibility, skip it. */
885 && !bfd_elf_get_obj_attr_int (ibfd, OBJ_ATTR_PROC,
886 Tag_ARC_CPU_base))
888 /* Warn if different flags. */
889 _bfd_error_handler
890 /* xgettext:c-format */
891 (_("%B: uses different e_flags (%#x) fields than "
892 "previous modules (%#x)"),
893 ibfd, in_flags, out_flags);
894 if (in_flags && out_flags)
895 return FALSE;
896 /* MWDT doesnt set the eflags hence make sure we choose the
897 eflags set by gcc. */
898 in_flags = in_flags > out_flags ? in_flags : out_flags;
900 else
902 /* Everything is correct; don't change the output flags. */
903 in_flags = out_flags;
907 /* Update the flags. */
908 elf_elfheader (obfd)->e_flags = in_flags;
910 if (bfd_get_mach (obfd) < bfd_get_mach (ibfd))
912 return bfd_set_arch_mach (obfd, bfd_arch_arc, bfd_get_mach (ibfd));
915 return TRUE;
918 /* Return a best guess for the machine number based on the attributes. */
920 static unsigned int
921 bfd_arc_get_mach_from_attributes (bfd * abfd)
923 int arch = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_PROC, Tag_ARC_CPU_base);
924 unsigned e_machine = elf_elfheader (abfd)->e_machine;
926 switch (arch)
928 case TAG_CPU_ARC6xx:
929 return bfd_mach_arc_arc600;
930 case TAG_CPU_ARC7xx:
931 return bfd_mach_arc_arc700;
932 case TAG_CPU_ARCEM:
933 case TAG_CPU_ARCHS:
934 return bfd_mach_arc_arcv2;
935 default:
936 break;
938 return (e_machine == EM_ARC_COMPACT)
939 ? bfd_mach_arc_arc700 : bfd_mach_arc_arcv2;
942 /* Set the right machine number for an ARC ELF file. */
943 static bfd_boolean
944 arc_elf_object_p (bfd * abfd)
946 /* Make sure this is initialised, or you'll have the potential of passing
947 garbage---or misleading values---into the call to
948 bfd_default_set_arch_mach (). */
949 unsigned int mach = bfd_mach_arc_arc700;
950 unsigned long arch = elf_elfheader (abfd)->e_flags & EF_ARC_MACH_MSK;
951 unsigned e_machine = elf_elfheader (abfd)->e_machine;
953 if (e_machine == EM_ARC_COMPACT || e_machine == EM_ARC_COMPACT2)
955 switch (arch)
957 case E_ARC_MACH_ARC600:
958 mach = bfd_mach_arc_arc600;
959 break;
960 case E_ARC_MACH_ARC601:
961 mach = bfd_mach_arc_arc601;
962 break;
963 case E_ARC_MACH_ARC700:
964 mach = bfd_mach_arc_arc700;
965 break;
966 case EF_ARC_CPU_ARCV2HS:
967 case EF_ARC_CPU_ARCV2EM:
968 mach = bfd_mach_arc_arcv2;
969 break;
970 default:
971 mach = bfd_arc_get_mach_from_attributes (abfd);
972 break;
975 else
977 if (e_machine == EM_ARC)
979 _bfd_error_handler
980 (_("Error: The ARC4 architecture is no longer supported.\n"));
981 return FALSE;
983 else
985 _bfd_error_handler
986 (_("Warning: unset or old architecture flags. \n"
987 " Use default machine.\n"));
991 return bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach);
994 /* The final processing done just before writing out an ARC ELF object file.
995 This gets the ARC architecture right based on the machine number. */
997 static void
998 arc_elf_final_write_processing (bfd * abfd,
999 bfd_boolean linker ATTRIBUTE_UNUSED)
1001 unsigned long emf;
1002 int osver = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_PROC,
1003 Tag_ARC_ABI_osver);
1004 flagword e_flags = elf_elfheader (abfd)->e_flags & ~EF_ARC_OSABI_MSK;
1006 switch (bfd_get_mach (abfd))
1008 case bfd_mach_arc_arc600:
1009 emf = EM_ARC_COMPACT;
1010 break;
1011 case bfd_mach_arc_arc601:
1012 emf = EM_ARC_COMPACT;
1013 break;
1014 case bfd_mach_arc_arc700:
1015 emf = EM_ARC_COMPACT;
1016 break;
1017 case bfd_mach_arc_arcv2:
1018 emf = EM_ARC_COMPACT2;
1019 break;
1020 default:
1021 return;
1024 elf_elfheader (abfd)->e_machine = emf;
1026 /* Record whatever is the current syscall ABI version. */
1027 if (osver)
1028 e_flags |= ((osver & 0x0f) << 8);
1029 else
1030 e_flags |= E_ARC_OSABI_V3;
1032 elf_elfheader (abfd)->e_flags |= e_flags;
1035 #ifdef ARC_ENABLE_DEBUG
1036 #define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
1038 static void
1039 debug_arc_reloc (struct arc_relocation_data reloc_data)
1041 ARC_DEBUG ("Reloc type=%s, should_relocate = %s\n",
1042 reloc_data.howto->name,
1043 reloc_data.should_relocate ? "true" : "false");
1044 ARC_DEBUG (" offset = 0x%x, addend = 0x%x\n",
1045 (unsigned int) reloc_data.reloc_offset,
1046 (unsigned int) reloc_data.reloc_addend);
1047 ARC_DEBUG (" Symbol:\n");
1048 ARC_DEBUG (" value = 0x%08x\n",
1049 (unsigned int) reloc_data.sym_value);
1050 if (reloc_data.sym_section != NULL)
1052 ARC_DEBUG (" Symbol Section:\n");
1053 ARC_DEBUG (" section name = %s, output_offset 0x%08x",
1054 reloc_data.sym_section->name,
1055 (unsigned int) reloc_data.sym_section->output_offset);
1056 if (reloc_data.sym_section->output_section != NULL)
1057 ARC_DEBUG (", output_section->vma = 0x%08x",
1058 ((unsigned int) reloc_data.sym_section->output_section->vma));
1059 ARC_DEBUG ("\n");
1060 if (reloc_data.sym_section->owner && reloc_data.sym_section->owner->filename)
1061 ARC_DEBUG (" file: %s\n", reloc_data.sym_section->owner->filename);
1063 else
1065 ARC_DEBUG (" symbol section is NULL\n");
1068 ARC_DEBUG (" Input_section:\n");
1069 if (reloc_data.input_section != NULL)
1071 ARC_DEBUG (" section name = %s, output_offset 0x%08x, output_section->vma = 0x%08x\n",
1072 reloc_data.input_section->name,
1073 (unsigned int) reloc_data.input_section->output_offset,
1074 (unsigned int) reloc_data.input_section->output_section->vma);
1075 ARC_DEBUG (" changed_address = 0x%08x\n",
1076 (unsigned int) (reloc_data.input_section->output_section->vma
1077 + reloc_data.input_section->output_offset
1078 + reloc_data.reloc_offset));
1079 ARC_DEBUG (" file: %s\n", reloc_data.input_section->owner->filename);
1081 else
1083 ARC_DEBUG (" input section is NULL\n");
1086 #else
1087 #define DEBUG_ARC_RELOC(A)
1088 #endif /* ARC_ENABLE_DEBUG */
1090 static bfd_vma
1091 middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
1093 if (do_it)
1095 insn
1096 = ((insn & 0xffff0000) >> 16)
1097 | ((insn & 0xffff) << 16);
1099 return insn;
1102 /* This function is called for relocations that are otherwise marked as NOT
1103 requiring overflow checks. In here we perform non-standard checks of
1104 the relocation value. */
1106 static inline bfd_reloc_status_type
1107 arc_special_overflow_checks (const struct arc_relocation_data reloc_data,
1108 bfd_signed_vma relocation,
1109 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1111 switch (reloc_data.howto->type)
1113 case R_ARC_NPS_CMEM16:
1114 if (((relocation >> 16) & 0xffff) != NPS_CMEM_HIGH_VALUE)
1116 if (reloc_data.reloc_addend == 0)
1117 _bfd_error_handler
1118 /* xgettext:c-format */
1119 (_("%B(%A+%#Lx): CMEM relocation to `%s' is invalid, "
1120 "16 MSB should be %#x (value is %#Lx)"),
1121 reloc_data.input_section->owner,
1122 reloc_data.input_section,
1123 reloc_data.reloc_offset,
1124 reloc_data.symbol_name,
1125 NPS_CMEM_HIGH_VALUE,
1126 relocation);
1127 else
1128 _bfd_error_handler
1129 /* xgettext:c-format */
1130 (_("%B(%A+%#Lx): CMEM relocation to `%s+%#Lx' is invalid, "
1131 "16 MSB should be %#x (value is %#Lx)"),
1132 reloc_data.input_section->owner,
1133 reloc_data.input_section,
1134 reloc_data.reloc_offset,
1135 reloc_data.symbol_name,
1136 reloc_data.reloc_addend,
1137 NPS_CMEM_HIGH_VALUE,
1138 relocation);
1139 return bfd_reloc_overflow;
1141 break;
1143 default:
1144 break;
1147 return bfd_reloc_ok;
1150 #define ME(reloc) (reloc)
1152 #define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") != NULL) \
1153 && (!bfd_big_endian (BFD)))
1155 #define S ((bfd_signed_vma) (reloc_data.sym_value \
1156 + (reloc_data.sym_section->output_section != NULL ? \
1157 (reloc_data.sym_section->output_offset \
1158 + reloc_data.sym_section->output_section->vma) : 0)))
1159 #define L ((bfd_signed_vma) (reloc_data.sym_value \
1160 + (reloc_data.sym_section->output_section != NULL ? \
1161 (reloc_data.sym_section->output_offset \
1162 + reloc_data.sym_section->output_section->vma) : 0)))
1163 #define A (reloc_data.reloc_addend)
1164 #define B (0)
1165 #define G (reloc_data.got_offset_value)
1166 #define GOT (reloc_data.got_symbol_vma)
1167 #define GOT_BEGIN (htab->sgot->output_section->vma)
1169 #define MES (0)
1170 /* P: relative offset to PCL The offset should be to the
1171 current location aligned to 32 bits. */
1172 #define P ((bfd_signed_vma) ( \
1174 (reloc_data.input_section->output_section != NULL ? \
1175 reloc_data.input_section->output_section->vma : 0) \
1176 + reloc_data.input_section->output_offset \
1177 + (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0))) \
1178 & ~0x3))
1179 #define PDATA ((bfd_signed_vma) ( \
1180 (reloc_data.input_section->output_section->vma \
1181 + reloc_data.input_section->output_offset \
1182 + (reloc_data.reloc_offset))))
1183 #define SECTSTART (bfd_signed_vma) (reloc_data.sym_section->output_section->vma \
1184 + reloc_data.sym_section->output_offset)
1185 #define JLI (bfd_signed_vma) (reloc_data.sym_section->output_section->vma)
1186 #define _SDA_BASE_ (bfd_signed_vma) (reloc_data.sdata_begin_symbol_vma)
1187 #define TLS_REL (bfd_signed_vma) \
1188 ((elf_hash_table (info))->tls_sec->output_section->vma)
1189 #define TLS_TBSS (8)
1191 #define none (0)
1193 #ifdef ARC_ENABLE_DEBUG
1194 #define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA, TYPE) \
1195 do \
1197 asection *sym_section = reloc_data.sym_section; \
1198 asection *input_section = reloc_data.input_section; \
1199 ARC_DEBUG ("RELOC_TYPE = " TYPE "\n"); \
1200 ARC_DEBUG ("FORMULA = " FORMULA "\n"); \
1201 ARC_DEBUG ("S = %#lx\n", S); \
1202 ARC_DEBUG ("A = %#lx\n", A); \
1203 ARC_DEBUG ("L = %lx\n", L); \
1204 if (sym_section->output_section != NULL) \
1205 ARC_DEBUG ("symbol_section->vma = %#lx\n", \
1206 sym_section->output_section->vma \
1207 + sym_section->output_offset); \
1208 else \
1209 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
1210 if (input_section->output_section != NULL) \
1211 ARC_DEBUG ("symbol_section->vma = %#lx\n", \
1212 input_section->output_section->vma \
1213 + input_section->output_offset); \
1214 else \
1215 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
1216 ARC_DEBUG ("PCL = %#lx\n", P); \
1217 ARC_DEBUG ("P = %#lx\n", P); \
1218 ARC_DEBUG ("G = %#lx\n", G); \
1219 ARC_DEBUG ("SDA_OFFSET = %#lx\n", _SDA_BASE_); \
1220 ARC_DEBUG ("SDA_SET = %d\n", reloc_data.sdata_begin_symbol_vma_set); \
1221 ARC_DEBUG ("GOT_OFFSET = %#lx\n", GOT); \
1222 ARC_DEBUG ("relocation = %#08lx\n", relocation); \
1223 ARC_DEBUG ("before = %#08x\n", (unsigned) insn); \
1224 ARC_DEBUG ("data = %08x (%u) (%d)\n", (unsigned) relocation, \
1225 (unsigned) relocation, (int) relocation); \
1227 while (0)
1229 #define PRINT_DEBUG_RELOC_INFO_AFTER \
1230 do \
1232 ARC_DEBUG ("after = 0x%08x\n", (unsigned int) insn); \
1234 while (0)
1236 #else
1238 #define PRINT_DEBUG_RELOC_INFO_BEFORE(...)
1239 #define PRINT_DEBUG_RELOC_INFO_AFTER
1241 #endif /* ARC_ENABLE_DEBUG */
1243 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
1244 case R_##TYPE: \
1246 bfd_signed_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
1247 relocation = FORMULA ; \
1248 PRINT_DEBUG_RELOC_INFO_BEFORE (#FORMULA, #TYPE); \
1249 insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
1250 insn = (* get_replace_function (abfd, TYPE)) (insn, relocation); \
1251 insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
1252 PRINT_DEBUG_RELOC_INFO_AFTER; \
1254 break;
1256 static bfd_reloc_status_type
1257 arc_do_relocation (bfd_byte * contents,
1258 struct arc_relocation_data reloc_data,
1259 struct bfd_link_info *info)
1261 bfd_signed_vma relocation = 0;
1262 bfd_vma insn;
1263 bfd_vma orig_insn ATTRIBUTE_UNUSED;
1264 bfd * abfd = reloc_data.input_section->owner;
1265 struct elf_link_hash_table *htab ATTRIBUTE_UNUSED = elf_hash_table (info);
1266 bfd_reloc_status_type flag;
1268 if (!reloc_data.should_relocate)
1269 return bfd_reloc_ok;
1271 switch (reloc_data.howto->size)
1273 case 2:
1274 insn = arc_bfd_get_32 (abfd,
1275 contents + reloc_data.reloc_offset,
1276 reloc_data.input_section);
1277 break;
1278 case 1:
1279 insn = arc_bfd_get_16 (abfd,
1280 contents + reloc_data.reloc_offset,
1281 reloc_data.input_section);
1282 break;
1283 case 0:
1284 insn = arc_bfd_get_8 (abfd,
1285 contents + reloc_data.reloc_offset,
1286 reloc_data.input_section);
1287 break;
1288 default:
1289 insn = 0;
1290 BFD_ASSERT (0);
1291 break;
1294 orig_insn = insn;
1296 switch (reloc_data.howto->type)
1298 #include "elf/arc-reloc.def"
1300 default:
1301 BFD_ASSERT (0);
1302 break;
1305 /* Check for relocation overflow. */
1306 if (reloc_data.howto->complain_on_overflow != complain_overflow_dont)
1307 flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
1308 reloc_data.howto->bitsize,
1309 reloc_data.howto->rightshift,
1310 bfd_arch_bits_per_address (abfd),
1311 relocation);
1312 else
1313 flag = arc_special_overflow_checks (reloc_data, relocation, info);
1315 if (flag != bfd_reloc_ok)
1317 ARC_DEBUG ("Relocation overflows !\n");
1318 DEBUG_ARC_RELOC (reloc_data);
1319 ARC_DEBUG ("Relocation value = signed -> %d, unsigned -> %u"
1320 ", hex -> (0x%08x)\n",
1321 (int) relocation, (unsigned) relocation, (int) relocation);
1323 return flag;
1326 /* Write updated instruction back to memory. */
1327 switch (reloc_data.howto->size)
1329 case 2:
1330 arc_bfd_put_32 (abfd, insn,
1331 contents + reloc_data.reloc_offset,
1332 reloc_data.input_section);
1333 break;
1334 case 1:
1335 arc_bfd_put_16 (abfd, insn,
1336 contents + reloc_data.reloc_offset,
1337 reloc_data.input_section);
1338 break;
1339 case 0:
1340 arc_bfd_put_8 (abfd, insn,
1341 contents + reloc_data.reloc_offset,
1342 reloc_data.input_section);
1343 break;
1344 default:
1345 ARC_DEBUG ("size = %d\n", reloc_data.howto->size);
1346 BFD_ASSERT (0);
1347 break;
1350 return bfd_reloc_ok;
1352 #undef S
1353 #undef A
1354 #undef B
1355 #undef G
1356 #undef GOT
1357 #undef L
1358 #undef MES
1359 #undef P
1360 #undef SECTSTAR
1361 #undef SECTSTART
1362 #undef JLI
1363 #undef _SDA_BASE_
1364 #undef none
1366 #undef ARC_RELOC_HOWTO
1369 /* Relocate an arc ELF section.
1370 Function : elf_arc_relocate_section
1371 Brief : Relocate an arc section, by handling all the relocations
1372 appearing in that section.
1373 Args : output_bfd : The bfd being written to.
1374 info : Link information.
1375 input_bfd : The input bfd.
1376 input_section : The section being relocated.
1377 contents : contents of the section being relocated.
1378 relocs : List of relocations in the section.
1379 local_syms : is a pointer to the swapped in local symbols.
1380 local_section : is an array giving the section in the input file
1381 corresponding to the st_shndx field of each
1382 local symbol. */
1383 static bfd_boolean
1384 elf_arc_relocate_section (bfd * output_bfd,
1385 struct bfd_link_info * info,
1386 bfd * input_bfd,
1387 asection * input_section,
1388 bfd_byte * contents,
1389 Elf_Internal_Rela * relocs,
1390 Elf_Internal_Sym * local_syms,
1391 asection ** local_sections)
1393 Elf_Internal_Shdr * symtab_hdr;
1394 struct elf_link_hash_entry ** sym_hashes;
1395 Elf_Internal_Rela * rel;
1396 Elf_Internal_Rela * wrel;
1397 Elf_Internal_Rela * relend;
1398 struct elf_link_hash_table * htab = elf_hash_table (info);
1400 symtab_hdr = &((elf_tdata (input_bfd))->symtab_hdr);
1401 sym_hashes = elf_sym_hashes (input_bfd);
1403 rel = wrel = relocs;
1404 relend = relocs + input_section->reloc_count;
1405 for (; rel < relend; wrel++, rel++)
1407 enum elf_arc_reloc_type r_type;
1408 reloc_howto_type * howto;
1409 unsigned long r_symndx;
1410 struct elf_link_hash_entry * h;
1411 Elf_Internal_Sym * sym;
1412 asection * sec;
1413 struct elf_link_hash_entry * h2;
1414 const char * msg;
1415 bfd_boolean unresolved_reloc = FALSE;
1417 struct arc_relocation_data reloc_data =
1419 .reloc_offset = 0,
1420 .reloc_addend = 0,
1421 .got_offset_value = 0,
1422 .sym_value = 0,
1423 .sym_section = NULL,
1424 .howto = NULL,
1425 .input_section = NULL,
1426 .sdata_begin_symbol_vma = 0,
1427 .sdata_begin_symbol_vma_set = FALSE,
1428 .got_symbol_vma = 0,
1429 .should_relocate = FALSE
1432 r_type = ELF32_R_TYPE (rel->r_info);
1434 if (r_type >= (int) R_ARC_max)
1436 bfd_set_error (bfd_error_bad_value);
1437 return FALSE;
1439 howto = arc_elf_howto (r_type);
1441 r_symndx = ELF32_R_SYM (rel->r_info);
1443 /* If we are generating another .o file and the symbol in not
1444 local, skip this relocation. */
1445 if (bfd_link_relocatable (info))
1447 /* This is a relocateable link. We don't have to change
1448 anything, unless the reloc is against a section symbol,
1449 in which case we have to adjust according to where the
1450 section symbol winds up in the output section. */
1452 /* Checks if this is a local symbol and thus the reloc
1453 might (will??) be against a section symbol. */
1454 if (r_symndx < symtab_hdr->sh_info)
1456 sym = local_syms + r_symndx;
1457 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1459 sec = local_sections[r_symndx];
1461 /* For RELA relocs. Just adjust the addend
1462 value in the relocation entry. */
1463 rel->r_addend += sec->output_offset + sym->st_value;
1465 ARC_DEBUG ("local symbols reloc (section=%d %s) seen in %s\n",
1466 (int) r_symndx, local_sections[r_symndx]->name,
1467 __PRETTY_FUNCTION__);
1472 h2 = elf_link_hash_lookup (elf_hash_table (info), "__SDATA_BEGIN__",
1473 FALSE, FALSE, TRUE);
1475 if (!reloc_data.sdata_begin_symbol_vma_set
1476 && h2 != NULL && h2->root.type != bfd_link_hash_undefined
1477 && h2->root.u.def.section->output_section != NULL)
1478 /* TODO: Verify this condition. */
1480 reloc_data.sdata_begin_symbol_vma =
1481 (h2->root.u.def.value
1482 + h2->root.u.def.section->output_section->vma);
1483 reloc_data.sdata_begin_symbol_vma_set = TRUE;
1486 reloc_data.input_section = input_section;
1487 reloc_data.howto = howto;
1488 reloc_data.reloc_offset = rel->r_offset;
1489 reloc_data.reloc_addend = rel->r_addend;
1491 /* This is a final link. */
1492 h = NULL;
1493 sym = NULL;
1494 sec = NULL;
1496 if (r_symndx < symtab_hdr->sh_info) /* A local symbol. */
1498 sym = local_syms + r_symndx;
1499 sec = local_sections[r_symndx];
1501 else
1503 bfd_boolean warned, ignored;
1504 bfd_vma relocation ATTRIBUTE_UNUSED;
1506 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1507 r_symndx, symtab_hdr, sym_hashes,
1508 h, sec, relocation,
1509 unresolved_reloc, warned, ignored);
1511 /* TODO: This code is repeated from below. We should
1512 clean it and remove duplications.
1513 Sec is used check for discarded sections.
1514 Need to redesign code below. */
1516 /* Get the symbol's entry in the symtab. */
1517 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1519 while (h->root.type == bfd_link_hash_indirect
1520 || h->root.type == bfd_link_hash_warning)
1521 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1523 /* If we have encountered a definition for this symbol. */
1524 if (h->root.type == bfd_link_hash_defined
1525 || h->root.type == bfd_link_hash_defweak)
1527 reloc_data.sym_value = h->root.u.def.value;
1528 sec = h->root.u.def.section;
1532 /* Clean relocs for symbols in discarded sections. */
1533 if (sec != NULL && discarded_section (sec))
1535 _bfd_clear_contents (howto, input_bfd, input_section,
1536 contents + rel->r_offset);
1537 rel->r_offset = rel->r_offset;
1538 rel->r_info = 0;
1539 rel->r_addend = 0;
1541 /* For ld -r, remove relocations in debug sections against
1542 sections defined in discarded sections. Not done for
1543 eh_frame editing code expects to be present. */
1544 if (bfd_link_relocatable (info)
1545 && (input_section->flags & SEC_DEBUGGING))
1546 wrel--;
1548 continue;
1551 if (bfd_link_relocatable (info))
1553 if (wrel != rel)
1554 *wrel = *rel;
1555 continue;
1558 if (r_symndx < symtab_hdr->sh_info) /* A local symbol. */
1560 reloc_data.sym_value = sym->st_value;
1561 reloc_data.sym_section = sec;
1562 reloc_data.symbol_name =
1563 bfd_elf_string_from_elf_section (input_bfd,
1564 symtab_hdr->sh_link,
1565 sym->st_name);
1567 /* Mergeable section handling. */
1568 if ((sec->flags & SEC_MERGE)
1569 && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1571 asection *msec;
1572 msec = sec;
1573 rel->r_addend = _bfd_elf_rel_local_sym (output_bfd, sym,
1574 &msec, rel->r_addend);
1575 rel->r_addend -= (sec->output_section->vma
1576 + sec->output_offset
1577 + sym->st_value);
1578 rel->r_addend += msec->output_section->vma + msec->output_offset;
1580 reloc_data.reloc_addend = rel->r_addend;
1583 BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1584 if (htab->sgot != NULL)
1585 reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1586 + htab->sgot->output_offset;
1588 reloc_data.should_relocate = TRUE;
1590 else /* Global symbol. */
1592 /* FIXME: We should use the RELOC_FOR_GLOBAL_SYMBOL macro
1593 (defined in elf-bfd.h) here. */
1595 /* Get the symbol's entry in the symtab. */
1596 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1598 while (h->root.type == bfd_link_hash_indirect
1599 || h->root.type == bfd_link_hash_warning)
1601 struct elf_link_hash_entry *h_old = h;
1602 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1603 if (h->got.glist == 0 && h_old->got.glist != h->got.glist)
1604 h->got.glist = h_old->got.glist;
1607 /* TODO: Need to validate what was the intention. */
1608 /* BFD_ASSERT ((h->dynindx == -1) || (h->forced_local != 0)); */
1609 reloc_data.symbol_name = h->root.root.string;
1611 /* If we have encountered a definition for this symbol. */
1612 if (h->root.type == bfd_link_hash_defined
1613 || h->root.type == bfd_link_hash_defweak)
1615 reloc_data.sym_value = h->root.u.def.value;
1616 reloc_data.sym_section = h->root.u.def.section;
1618 reloc_data.should_relocate = TRUE;
1620 if (is_reloc_for_GOT (howto) && !bfd_link_pic (info))
1622 /* TODO: Change it to use arc_do_relocation with
1623 ARC_32 reloc. Try to use ADD_RELA macro. */
1624 bfd_vma relocation =
1625 reloc_data.sym_value + reloc_data.reloc_addend
1626 + (reloc_data.sym_section->output_section != NULL ?
1627 (reloc_data.sym_section->output_offset
1628 + reloc_data.sym_section->output_section->vma)
1629 : 0);
1631 BFD_ASSERT (h->got.glist);
1632 bfd_vma got_offset = h->got.glist->offset;
1633 bfd_put_32 (output_bfd, relocation,
1634 htab->sgot->contents + got_offset);
1636 if (is_reloc_for_PLT (howto) && h->plt.offset != (bfd_vma) -1)
1638 /* TODO: This is repeated up here. */
1639 reloc_data.sym_value = h->plt.offset;
1640 reloc_data.sym_section = htab->splt;
1643 else if (h->root.type == bfd_link_hash_undefweak)
1645 /* Is weak symbol and has no definition. */
1646 if (is_reloc_for_GOT (howto))
1648 reloc_data.sym_value = h->root.u.def.value;
1649 reloc_data.sym_section = htab->sgot;
1650 reloc_data.should_relocate = TRUE;
1652 else if (is_reloc_for_PLT (howto)
1653 && h->plt.offset != (bfd_vma) -1)
1655 /* TODO: This is repeated up here. */
1656 reloc_data.sym_value = h->plt.offset;
1657 reloc_data.sym_section = htab->splt;
1658 reloc_data.should_relocate = TRUE;
1660 else
1661 continue;
1663 else
1665 if (is_reloc_for_GOT (howto))
1667 reloc_data.sym_value = h->root.u.def.value;
1668 reloc_data.sym_section = htab->sgot;
1670 reloc_data.should_relocate = TRUE;
1672 else if (is_reloc_for_PLT (howto))
1674 /* Fail if it is linking for PIE and the symbol is
1675 undefined. */
1676 if (bfd_link_executable (info))
1677 (*info->callbacks->undefined_symbol)
1678 (info, h->root.root.string, input_bfd, input_section,
1679 rel->r_offset, TRUE);
1680 reloc_data.sym_value = h->plt.offset;
1681 reloc_data.sym_section = htab->splt;
1683 reloc_data.should_relocate = TRUE;
1685 else if (!bfd_link_pic (info) || bfd_link_executable (info))
1686 (*info->callbacks->undefined_symbol)
1687 (info, h->root.root.string, input_bfd, input_section,
1688 rel->r_offset, TRUE);
1691 BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1692 if (htab->sgot != NULL)
1693 reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1694 + htab->sgot->output_offset;
1697 if ((is_reloc_for_GOT (howto)
1698 || is_reloc_for_TLS (howto)))
1700 reloc_data.should_relocate = TRUE;
1702 struct got_entry **list
1703 = get_got_entry_list_for_symbol (output_bfd, r_symndx, h);
1705 reloc_data.got_offset_value
1706 = relocate_fix_got_relocs_for_got_info (list,
1707 tls_type_for_reloc (howto),
1708 info,
1709 output_bfd,
1710 r_symndx,
1711 local_syms,
1712 local_sections,
1714 &reloc_data);
1716 if (h == NULL)
1718 create_got_dynrelocs_for_single_entry (
1719 got_entry_for_type (list,
1720 arc_got_entry_type_for_reloc (howto)),
1721 output_bfd, info, NULL);
1726 #define IS_ARC_PCREL_TYPE(TYPE) \
1727 ( (TYPE == R_ARC_PC32) \
1728 || (TYPE == R_ARC_32_PCREL))
1730 switch (r_type)
1732 case R_ARC_32:
1733 case R_ARC_32_ME:
1734 case R_ARC_PC32:
1735 case R_ARC_32_PCREL:
1736 if (bfd_link_pic (info)
1737 && (!IS_ARC_PCREL_TYPE (r_type)
1738 || (h != NULL
1739 && h->dynindx != -1
1740 && !h->def_regular
1741 && (!info->symbolic || !h->def_regular))))
1743 Elf_Internal_Rela outrel;
1744 bfd_byte *loc;
1745 bfd_boolean skip = FALSE;
1746 bfd_boolean relocate = FALSE;
1747 asection *sreloc = _bfd_elf_get_dynamic_reloc_section
1748 (input_bfd, input_section,
1749 /*RELA*/ TRUE);
1751 BFD_ASSERT (sreloc != NULL);
1753 outrel.r_offset = _bfd_elf_section_offset (output_bfd,
1754 info,
1755 input_section,
1756 rel->r_offset);
1758 if (outrel.r_offset == (bfd_vma) -1)
1759 skip = TRUE;
1761 outrel.r_addend = rel->r_addend;
1762 outrel.r_offset += (input_section->output_section->vma
1763 + input_section->output_offset);
1765 if (skip)
1767 memset (&outrel, 0, sizeof outrel);
1768 relocate = FALSE;
1770 else if (h != NULL
1771 && h->dynindx != -1
1772 && (IS_ARC_PCREL_TYPE (r_type)
1773 || !(bfd_link_executable (info)
1774 || SYMBOLIC_BIND (info, h))
1775 || ! h->def_regular))
1777 BFD_ASSERT (h != NULL);
1778 if ((input_section->flags & SEC_ALLOC) != 0)
1779 relocate = FALSE;
1780 else
1781 relocate = TRUE;
1783 BFD_ASSERT (h->dynindx != -1);
1784 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1786 else
1788 /* Handle local symbols, they either do not have a
1789 global hash table entry (h == NULL), or are
1790 forced local due to a version script
1791 (h->forced_local), or the third condition is
1792 legacy, it appears to say something like, for
1793 links where we are pre-binding the symbols, or
1794 there's not an entry for this symbol in the
1795 dynamic symbol table, and it's a regular symbol
1796 not defined in a shared object, then treat the
1797 symbol as local, resolve it now. */
1798 relocate = TRUE;
1799 /* outrel.r_addend = 0; */
1800 outrel.r_info = ELF32_R_INFO (0, R_ARC_RELATIVE);
1803 BFD_ASSERT (sreloc->contents != 0);
1805 loc = sreloc->contents;
1806 loc += sreloc->reloc_count * sizeof (Elf32_External_Rela);
1807 sreloc->reloc_count += 1;
1809 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1811 if (!relocate)
1812 continue;
1814 break;
1815 default:
1816 break;
1819 if (is_reloc_SDA_relative (howto)
1820 && !reloc_data.sdata_begin_symbol_vma_set)
1822 _bfd_error_handler
1823 ("Error: Linker symbol __SDATA_BEGIN__ not found");
1824 bfd_set_error (bfd_error_bad_value);
1825 return FALSE;
1828 DEBUG_ARC_RELOC (reloc_data);
1830 /* Make sure we have with a dynamic linker. In case of GOT and PLT
1831 the sym_section should point to .got or .plt respectively. */
1832 if ((is_reloc_for_GOT (howto) || is_reloc_for_PLT (howto))
1833 && reloc_data.sym_section == NULL)
1835 _bfd_error_handler
1836 (_("GOT and PLT relocations cannot be fixed with a non dynamic linker."));
1837 bfd_set_error (bfd_error_bad_value);
1838 return FALSE;
1841 msg = NULL;
1842 switch (arc_do_relocation (contents, reloc_data, info))
1844 case bfd_reloc_ok:
1845 continue; /* The reloc processing loop. */
1847 case bfd_reloc_overflow:
1848 (*info->callbacks->reloc_overflow)
1849 (info, (h ? &h->root : NULL), reloc_data.symbol_name, howto->name, (bfd_vma) 0,
1850 input_bfd, input_section, rel->r_offset);
1851 break;
1853 case bfd_reloc_undefined:
1854 (*info->callbacks->undefined_symbol)
1855 (info, reloc_data.symbol_name, input_bfd, input_section, rel->r_offset, TRUE);
1856 break;
1858 case bfd_reloc_other:
1859 /* xgettext:c-format */
1860 msg = _("%B(%A): warning: unaligned access to symbol '%s' in the small data area");
1861 break;
1863 case bfd_reloc_outofrange:
1864 /* xgettext:c-format */
1865 msg = _("%B(%A): internal error: out of range error");
1866 break;
1868 case bfd_reloc_notsupported:
1869 /* xgettext:c-format */
1870 msg = _("%B(%A): internal error: unsupported relocation error");
1871 break;
1873 case bfd_reloc_dangerous:
1874 /* xgettext:c-format */
1875 msg = _("%B(%A): internal error: dangerous relocation");
1876 break;
1878 default:
1879 /* xgettext:c-format */
1880 msg = _("%B(%A): internal error: unknown error");
1881 break;
1884 if (msg)
1885 _bfd_error_handler (msg, input_bfd, input_section, reloc_data.symbol_name);
1886 return FALSE;
1889 return TRUE;
1892 #define elf_arc_hash_table(p) \
1893 (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
1894 == ARC_ELF_DATA ? ((struct elf_arc_link_hash_table *) ((p)->hash)) : NULL)
1896 static bfd_boolean
1897 elf_arc_check_relocs (bfd * abfd,
1898 struct bfd_link_info * info,
1899 asection * sec,
1900 const Elf_Internal_Rela * relocs)
1902 Elf_Internal_Shdr * symtab_hdr;
1903 struct elf_link_hash_entry ** sym_hashes;
1904 const Elf_Internal_Rela * rel;
1905 const Elf_Internal_Rela * rel_end;
1906 bfd * dynobj;
1907 asection * sreloc = NULL;
1908 struct elf_link_hash_table * htab = elf_hash_table (info);
1910 if (bfd_link_relocatable (info))
1911 return TRUE;
1913 if (htab->dynobj == NULL)
1914 htab->dynobj = abfd;
1916 dynobj = (elf_hash_table (info))->dynobj;
1917 symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1918 sym_hashes = elf_sym_hashes (abfd);
1920 rel_end = relocs + sec->reloc_count;
1921 for (rel = relocs; rel < rel_end; rel++)
1923 enum elf_arc_reloc_type r_type;
1924 reloc_howto_type *howto;
1925 unsigned long r_symndx;
1926 struct elf_link_hash_entry *h;
1928 r_type = ELF32_R_TYPE (rel->r_info);
1930 if (r_type >= (int) R_ARC_max)
1932 bfd_set_error (bfd_error_bad_value);
1933 return FALSE;
1935 howto = arc_elf_howto (r_type);
1937 /* Load symbol information. */
1938 r_symndx = ELF32_R_SYM (rel->r_info);
1939 if (r_symndx < symtab_hdr->sh_info) /* Is a local symbol. */
1940 h = NULL;
1941 else /* Global one. */
1942 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1944 switch (r_type)
1946 case R_ARC_32:
1947 case R_ARC_32_ME:
1948 /* During shared library creation, these relocs should not
1949 appear in a shared library (as memory will be read only
1950 and the dynamic linker can not resolve these. However
1951 the error should not occur for e.g. debugging or
1952 non-readonly sections. */
1953 if (h != NULL
1954 && (bfd_link_dll (info) && !bfd_link_pie (info))
1955 && (sec->flags & SEC_ALLOC) != 0
1956 && (sec->flags & SEC_READONLY) != 0
1957 && ((sec->flags & SEC_CODE) != 0
1958 || (sec->flags & SEC_DEBUGGING) != 0))
1960 const char *name;
1961 if (h)
1962 name = h->root.root.string;
1963 else
1964 /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); */
1965 name = "UNKNOWN";
1966 _bfd_error_handler
1967 /* xgettext:c-format */
1968 (_("\
1969 %B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
1970 abfd,
1971 arc_elf_howto (r_type)->name,
1972 name);
1973 bfd_set_error (bfd_error_bad_value);
1974 return FALSE;
1977 /* In some cases we are not setting the 'non_got_ref'
1978 flag, even though the relocations don't require a GOT
1979 access. We should extend the testing in this area to
1980 ensure that no significant cases are being missed. */
1981 if (h)
1982 h->non_got_ref = 1;
1983 /* FALLTHROUGH */
1984 case R_ARC_PC32:
1985 case R_ARC_32_PCREL:
1986 if ((bfd_link_pic (info))
1987 && ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1988 || (h != NULL
1989 && (!info->symbolic || !h->def_regular))))
1991 if (sreloc == NULL)
1993 if (info->dynamic
1994 && ! htab->dynamic_sections_created
1995 && ! _bfd_elf_link_create_dynamic_sections (abfd, info))
1996 return FALSE;
1997 sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
1998 2, abfd,
1999 /*rela*/
2000 TRUE);
2002 if (sreloc == NULL)
2003 return FALSE;
2005 sreloc->size += sizeof (Elf32_External_Rela);
2008 default:
2009 break;
2012 if (is_reloc_for_PLT (howto))
2014 if (h == NULL)
2015 continue;
2016 else
2017 h->needs_plt = 1;
2020 /* Add info to the symbol got_entry_list. */
2021 if (is_reloc_for_GOT (howto)
2022 || is_reloc_for_TLS (howto))
2024 if (! _bfd_elf_create_got_section (dynobj, info))
2025 return FALSE;
2027 arc_fill_got_info_for_reloc (
2028 arc_got_entry_type_for_reloc (howto),
2029 get_got_entry_list_for_symbol (abfd, r_symndx, h),
2030 info,
2035 return TRUE;
2038 #define ELF_DYNAMIC_INTERPRETER "/sbin/ld-uClibc.so"
2040 static struct plt_version_t *
2041 arc_get_plt_version (struct bfd_link_info *info)
2043 int i;
2045 for (i = 0; i < 1; i++)
2047 ARC_DEBUG ("%d: size1 = %d, size2 = %d\n", i,
2048 (int) plt_versions[i].entry_size,
2049 (int) plt_versions[i].elem_size);
2052 if (bfd_get_mach (info->output_bfd) == bfd_mach_arc_arcv2)
2054 if (bfd_link_pic (info))
2055 return &(plt_versions[ELF_ARCV2_PIC]);
2056 else
2057 return &(plt_versions[ELF_ARCV2_ABS]);
2059 else
2061 if (bfd_link_pic (info))
2062 return &(plt_versions[ELF_ARC_PIC]);
2063 else
2064 return &(plt_versions[ELF_ARC_ABS]);
2068 static bfd_vma
2069 add_symbol_to_plt (struct bfd_link_info *info)
2071 struct elf_link_hash_table *htab = elf_hash_table (info);
2072 bfd_vma ret;
2074 struct plt_version_t *plt_data = arc_get_plt_version (info);
2076 /* If this is the first .plt entry, make room for the special first
2077 entry. */
2078 if (htab->splt->size == 0)
2079 htab->splt->size += plt_data->entry_size;
2081 ret = htab->splt->size;
2083 htab->splt->size += plt_data->elem_size;
2084 ARC_DEBUG ("PLT_SIZE = %d\n", (int) htab->splt->size);
2086 htab->sgotplt->size += 4;
2087 htab->srelplt->size += sizeof (Elf32_External_Rela);
2089 return ret;
2092 #define PLT_DO_RELOCS_FOR_ENTRY(ABFD, DS, RELOCS) \
2093 plt_do_relocs_for_symbol (ABFD, DS, RELOCS, 0, 0)
2095 static void
2096 plt_do_relocs_for_symbol (bfd *abfd,
2097 struct elf_link_hash_table *htab,
2098 const struct plt_reloc *reloc,
2099 bfd_vma plt_offset,
2100 bfd_vma symbol_got_offset)
2102 while (SYM_ONLY (reloc->symbol) != LAST_RELOC)
2104 bfd_vma relocation = 0;
2106 switch (SYM_ONLY (reloc->symbol))
2108 case SGOT:
2109 relocation
2110 = htab->sgotplt->output_section->vma
2111 + htab->sgotplt->output_offset + symbol_got_offset;
2112 break;
2114 relocation += reloc->addend;
2116 if (IS_RELATIVE (reloc->symbol))
2118 bfd_vma reloc_offset = reloc->offset;
2119 reloc_offset -= (IS_INSN_32 (reloc->symbol)) ? 4 : 0;
2120 reloc_offset -= (IS_INSN_24 (reloc->symbol)) ? 2 : 0;
2122 relocation -= htab->splt->output_section->vma
2123 + htab->splt->output_offset
2124 + plt_offset + reloc_offset;
2127 /* TODO: being ME is not a property of the relocation but of the
2128 section of which is applying the relocation. */
2129 if (IS_MIDDLE_ENDIAN (reloc->symbol) && !bfd_big_endian (abfd))
2131 relocation
2132 = ((relocation & 0xffff0000) >> 16)
2133 | ((relocation & 0xffff) << 16);
2136 switch (reloc->size)
2138 case 32:
2139 bfd_put_32 (htab->splt->output_section->owner,
2140 relocation,
2141 htab->splt->contents + plt_offset + reloc->offset);
2142 break;
2145 reloc = &(reloc[1]); /* Jump to next relocation. */
2149 static void
2150 relocate_plt_for_symbol (bfd *output_bfd,
2151 struct bfd_link_info *info,
2152 struct elf_link_hash_entry *h)
2154 struct plt_version_t *plt_data = arc_get_plt_version (info);
2155 struct elf_link_hash_table *htab = elf_hash_table (info);
2157 bfd_vma plt_index = (h->plt.offset - plt_data->entry_size)
2158 / plt_data->elem_size;
2159 bfd_vma got_offset = (plt_index + 3) * 4;
2161 ARC_DEBUG ("arc_info: PLT_OFFSET = %#lx, PLT_ENTRY_VMA = %#lx, \
2162 GOT_ENTRY_OFFSET = %#lx, GOT_ENTRY_VMA = %#lx, for symbol %s\n",
2163 (long) h->plt.offset,
2164 (long) (htab->splt->output_section->vma
2165 + htab->splt->output_offset
2166 + h->plt.offset),
2167 (long) got_offset,
2168 (long) (htab->sgotplt->output_section->vma
2169 + htab->sgotplt->output_offset
2170 + got_offset),
2171 h->root.root.string);
2174 bfd_vma i = 0;
2175 uint16_t *ptr = (uint16_t *) plt_data->elem;
2177 for (i = 0; i < plt_data->elem_size/2; i++)
2179 uint16_t data = ptr[i];
2180 bfd_put_16 (output_bfd,
2181 (bfd_vma) data,
2182 htab->splt->contents + h->plt.offset + (i*2));
2186 plt_do_relocs_for_symbol (output_bfd, htab,
2187 plt_data->elem_relocs,
2188 h->plt.offset,
2189 got_offset);
2191 /* Fill in the entry in the global offset table. */
2192 bfd_put_32 (output_bfd,
2193 (bfd_vma) (htab->splt->output_section->vma
2194 + htab->splt->output_offset),
2195 htab->sgotplt->contents + got_offset);
2197 /* TODO: Fill in the entry in the .rela.plt section. */
2199 Elf_Internal_Rela rel;
2200 bfd_byte *loc;
2202 rel.r_offset = (htab->sgotplt->output_section->vma
2203 + htab->sgotplt->output_offset
2204 + got_offset);
2205 rel.r_addend = 0;
2207 BFD_ASSERT (h->dynindx != -1);
2208 rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_JMP_SLOT);
2210 loc = htab->srelplt->contents;
2211 loc += plt_index * sizeof (Elf32_External_Rela); /* relA */
2212 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2216 static void
2217 relocate_plt_for_entry (bfd *abfd,
2218 struct bfd_link_info *info)
2220 struct plt_version_t *plt_data = arc_get_plt_version (info);
2221 struct elf_link_hash_table *htab = elf_hash_table (info);
2224 bfd_vma i = 0;
2225 uint16_t *ptr = (uint16_t *) plt_data->entry;
2226 for (i = 0; i < plt_data->entry_size/2; i++)
2228 uint16_t data = ptr[i];
2229 bfd_put_16 (abfd,
2230 (bfd_vma) data,
2231 htab->splt->contents + (i*2));
2234 PLT_DO_RELOCS_FOR_ENTRY (abfd, htab, plt_data->entry_relocs);
2237 /* Desc : Adjust a symbol defined by a dynamic object and referenced
2238 by a regular object. The current definition is in some section of
2239 the dynamic object, but we're not including those sections. We
2240 have to change the definition to something the rest of the link can
2241 understand. */
2243 static bfd_boolean
2244 elf_arc_adjust_dynamic_symbol (struct bfd_link_info *info,
2245 struct elf_link_hash_entry *h)
2247 asection *s;
2248 bfd *dynobj = (elf_hash_table (info))->dynobj;
2249 struct elf_link_hash_table *htab = elf_hash_table (info);
2251 if (h->type == STT_FUNC
2252 || h->type == STT_GNU_IFUNC
2253 || h->needs_plt == 1)
2255 if (!bfd_link_pic (info) && !h->def_dynamic && !h->ref_dynamic)
2257 /* This case can occur if we saw a PLT32 reloc in an input
2258 file, but the symbol was never referred to by a dynamic
2259 object. In such a case, we don't actually need to build
2260 a procedure linkage table, and we can just do a PC32
2261 reloc instead. */
2262 BFD_ASSERT (h->needs_plt);
2263 return TRUE;
2266 /* Make sure this symbol is output as a dynamic symbol. */
2267 if (h->dynindx == -1 && !h->forced_local
2268 && !bfd_elf_link_record_dynamic_symbol (info, h))
2269 return FALSE;
2271 if (bfd_link_pic (info)
2272 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
2274 bfd_vma loc = add_symbol_to_plt (info);
2276 if (bfd_link_executable (info) && !h->def_regular)
2278 h->root.u.def.section = htab->splt;
2279 h->root.u.def.value = loc;
2281 h->plt.offset = loc;
2283 else
2285 h->plt.offset = (bfd_vma) -1;
2286 h->needs_plt = 0;
2288 return TRUE;
2291 /* If this is a weak symbol, and there is a real definition, the
2292 processor independent code will have arranged for us to see the
2293 real definition first, and we can just use the same value. */
2294 if (h->u.weakdef != NULL)
2296 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2297 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2298 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2299 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2300 return TRUE;
2303 /* This is a reference to a symbol defined by a dynamic object which
2304 is not a function. */
2306 /* If we are creating a shared library, we must presume that the
2307 only references to the symbol are via the global offset table.
2308 For such cases we need not do anything here; the relocations will
2309 be handled correctly by relocate_section. */
2310 if (!bfd_link_executable (info))
2311 return TRUE;
2313 /* If there are no non-GOT references, we do not need a copy
2314 relocation. */
2315 if (!h->non_got_ref)
2316 return TRUE;
2318 /* If -z nocopyreloc was given, we won't generate them either. */
2319 if (info->nocopyreloc)
2321 h->non_got_ref = 0;
2322 return TRUE;
2325 /* We must allocate the symbol in our .dynbss section, which will
2326 become part of the .bss section of the executable. There will be
2327 an entry for this symbol in the .dynsym section. The dynamic
2328 object will contain position independent code, so all references
2329 from the dynamic object to this symbol will go through the global
2330 offset table. The dynamic linker will use the .dynsym entry to
2331 determine the address it must put in the global offset table, so
2332 both the dynamic object and the regular object will refer to the
2333 same memory location for the variable. */
2335 if (htab == NULL)
2336 return FALSE;
2338 /* We must generate a R_ARC_COPY reloc to tell the dynamic linker to
2339 copy the initial value out of the dynamic object and into the
2340 runtime process image. We need to remember the offset into the
2341 .rela.bss section we are going to use. */
2342 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2344 struct elf_arc_link_hash_table *arc_htab = elf_arc_hash_table (info);
2346 BFD_ASSERT (arc_htab->elf.srelbss != NULL);
2347 arc_htab->elf.srelbss->size += sizeof (Elf32_External_Rela);
2348 h->needs_copy = 1;
2351 /* TODO: Move this also to arc_hash_table. */
2352 s = bfd_get_section_by_name (dynobj, ".dynbss");
2353 BFD_ASSERT (s != NULL);
2355 return _bfd_elf_adjust_dynamic_copy (info, h, s);
2358 /* Function : elf_arc_finish_dynamic_symbol
2359 Brief : Finish up dynamic symbol handling. We set the
2360 contents of various dynamic sections here.
2361 Args : output_bfd :
2362 info :
2364 sym :
2365 Returns : True/False as the return status. */
2367 static bfd_boolean
2368 elf_arc_finish_dynamic_symbol (bfd * output_bfd,
2369 struct bfd_link_info *info,
2370 struct elf_link_hash_entry *h,
2371 Elf_Internal_Sym * sym)
2373 if (h->plt.offset != (bfd_vma) -1)
2375 relocate_plt_for_symbol (output_bfd, info, h);
2377 if (!h->def_regular)
2379 /* Mark the symbol as undefined, rather than as defined in
2380 the .plt section. Leave the value alone. */
2381 sym->st_shndx = SHN_UNDEF;
2386 /* This function traverses list of GOT entries and
2387 create respective dynamic relocs. */
2388 /* TODO: Make function to get list and not access the list directly. */
2389 /* TODO: Move function to relocate_section create this relocs eagerly. */
2390 create_got_dynrelocs_for_got_info (&h->got.glist,
2391 output_bfd,
2392 info,
2395 if (h->needs_copy)
2397 struct elf_arc_link_hash_table *arc_htab = elf_arc_hash_table (info);
2399 if (h->dynindx == -1
2400 || (h->root.type != bfd_link_hash_defined
2401 && h->root.type != bfd_link_hash_defweak)
2402 || arc_htab->elf.srelbss == NULL)
2403 abort ();
2405 bfd_vma rel_offset = (h->root.u.def.value
2406 + h->root.u.def.section->output_section->vma
2407 + h->root.u.def.section->output_offset);
2409 bfd_byte * loc = arc_htab->elf.srelbss->contents
2410 + (arc_htab->elf.srelbss->reloc_count * sizeof (Elf32_External_Rela));
2411 arc_htab->elf.srelbss->reloc_count++;
2413 Elf_Internal_Rela rel;
2414 rel.r_addend = 0;
2415 rel.r_offset = rel_offset;
2417 BFD_ASSERT (h->dynindx != -1);
2418 rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_COPY);
2420 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2423 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
2424 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2425 || strcmp (h->root.root.string, "__DYNAMIC") == 0
2426 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
2427 sym->st_shndx = SHN_ABS;
2429 return TRUE;
2432 #define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION) \
2433 case TAG: \
2434 if (SYMBOL != NULL) \
2435 h = elf_link_hash_lookup (elf_hash_table (info), \
2436 SYMBOL, FALSE, FALSE, TRUE); \
2437 else if (SECTION != NULL) \
2438 s = bfd_get_linker_section (dynobj, SECTION); \
2439 break;
2441 /* Function : elf_arc_finish_dynamic_sections
2442 Brief : Finish up the dynamic sections handling.
2443 Args : output_bfd :
2444 info :
2446 sym :
2447 Returns : True/False as the return status. */
2449 static bfd_boolean
2450 elf_arc_finish_dynamic_sections (bfd * output_bfd,
2451 struct bfd_link_info *info)
2453 struct elf_link_hash_table *htab = elf_hash_table (info);
2454 bfd *dynobj = (elf_hash_table (info))->dynobj;
2455 asection *sdyn = bfd_get_linker_section (dynobj, ".dynamic");
2457 if (sdyn)
2459 Elf32_External_Dyn *dyncon, *dynconend;
2461 dyncon = (Elf32_External_Dyn *) sdyn->contents;
2462 dynconend
2463 = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
2464 for (; dyncon < dynconend; dyncon++)
2466 Elf_Internal_Dyn internal_dyn;
2467 bfd_boolean do_it = FALSE;
2469 struct elf_link_hash_entry *h = NULL;
2470 asection *s = NULL;
2472 bfd_elf32_swap_dyn_in (dynobj, dyncon, &internal_dyn);
2474 switch (internal_dyn.d_tag)
2476 GET_SYMBOL_OR_SECTION (DT_INIT, info->init_function, NULL)
2477 GET_SYMBOL_OR_SECTION (DT_FINI, info->fini_function, NULL)
2478 GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt")
2479 GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt")
2480 GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt")
2481 GET_SYMBOL_OR_SECTION (DT_VERSYM, NULL, ".gnu.version")
2482 GET_SYMBOL_OR_SECTION (DT_VERDEF, NULL, ".gnu.version_d")
2483 GET_SYMBOL_OR_SECTION (DT_VERNEED, NULL, ".gnu.version_r")
2484 default:
2485 break;
2488 /* In case the dynamic symbols should be updated with a symbol. */
2489 if (h != NULL
2490 && (h->root.type == bfd_link_hash_defined
2491 || h->root.type == bfd_link_hash_defweak))
2493 asection *asec_ptr;
2495 internal_dyn.d_un.d_val = h->root.u.def.value;
2496 asec_ptr = h->root.u.def.section;
2497 if (asec_ptr->output_section != NULL)
2499 internal_dyn.d_un.d_val +=
2500 (asec_ptr->output_section->vma
2501 + asec_ptr->output_offset);
2503 else
2505 /* The symbol is imported from another shared
2506 library and does not apply to this one. */
2507 internal_dyn.d_un.d_val = 0;
2509 do_it = TRUE;
2511 else if (s != NULL) /* With a section information. */
2513 switch (internal_dyn.d_tag)
2515 case DT_PLTGOT:
2516 case DT_JMPREL:
2517 case DT_VERSYM:
2518 case DT_VERDEF:
2519 case DT_VERNEED:
2520 internal_dyn.d_un.d_ptr = (s->output_section->vma
2521 + s->output_offset);
2522 do_it = TRUE;
2523 break;
2525 case DT_PLTRELSZ:
2526 internal_dyn.d_un.d_val = s->size;
2527 do_it = TRUE;
2528 break;
2530 default:
2531 break;
2535 if (do_it)
2536 bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon);
2539 if (htab->splt->size > 0)
2541 relocate_plt_for_entry (output_bfd, info);
2544 /* TODO: Validate this. */
2545 if (htab->srelplt->output_section != bfd_abs_section_ptr)
2546 elf_section_data (htab->srelplt->output_section)
2547 ->this_hdr.sh_entsize = 12;
2550 /* Fill in the first three entries in the global offset table. */
2551 if (htab->sgot)
2553 struct elf_link_hash_entry *h;
2554 h = elf_link_hash_lookup (elf_hash_table (info), "_GLOBAL_OFFSET_TABLE_",
2555 FALSE, FALSE, TRUE);
2557 if (h != NULL && h->root.type != bfd_link_hash_undefined
2558 && h->root.u.def.section != NULL)
2560 asection *sec = h->root.u.def.section;
2562 if (sdyn == NULL)
2563 bfd_put_32 (output_bfd, (bfd_vma) 0,
2564 sec->contents);
2565 else
2566 bfd_put_32 (output_bfd,
2567 sdyn->output_section->vma + sdyn->output_offset,
2568 sec->contents);
2569 bfd_put_32 (output_bfd, (bfd_vma) 0, sec->contents + 4);
2570 bfd_put_32 (output_bfd, (bfd_vma) 0, sec->contents + 8);
2574 return TRUE;
2577 #define ADD_DYNAMIC_SYMBOL(NAME, TAG) \
2578 h = elf_link_hash_lookup (elf_hash_table (info), \
2579 NAME, FALSE, FALSE, FALSE); \
2580 if ((h != NULL && (h->ref_regular || h->def_regular))) \
2581 if (! _bfd_elf_add_dynamic_entry (info, TAG, 0)) \
2582 return FALSE;
2584 /* Set the sizes of the dynamic sections. */
2585 static bfd_boolean
2586 elf_arc_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2587 struct bfd_link_info *info)
2589 bfd *dynobj;
2590 asection *s;
2591 bfd_boolean relocs_exist = FALSE;
2592 bfd_boolean reltext_exist = FALSE;
2593 struct elf_link_hash_table *htab = elf_hash_table (info);
2595 dynobj = htab->dynobj;
2596 BFD_ASSERT (dynobj != NULL);
2598 if (htab->dynamic_sections_created)
2600 struct elf_link_hash_entry *h;
2602 /* Set the contents of the .interp section to the
2603 interpreter. */
2604 if (bfd_link_executable (info) && !info->nointerp)
2606 s = bfd_get_section_by_name (dynobj, ".interp");
2607 BFD_ASSERT (s != NULL);
2608 s->size = sizeof (ELF_DYNAMIC_INTERPRETER);
2609 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2612 /* Add some entries to the .dynamic section. We fill in some of
2613 the values later, in elf_bfd_final_link, but we must add the
2614 entries now so that we know the final size of the .dynamic
2615 section. Checking if the .init section is present. We also
2616 create DT_INIT and DT_FINI entries if the init_str has been
2617 changed by the user. */
2618 ADD_DYNAMIC_SYMBOL (info->init_function, DT_INIT);
2619 ADD_DYNAMIC_SYMBOL (info->fini_function, DT_FINI);
2621 else
2623 /* We may have created entries in the .rela.got section.
2624 However, if we are not creating the dynamic sections, we will
2625 not actually use these entries. Reset the size of .rela.got,
2626 which will cause it to get stripped from the output file
2627 below. */
2628 if (htab->srelgot != NULL)
2629 htab->srelgot->size = 0;
2632 for (s = dynobj->sections; s != NULL; s = s->next)
2634 if ((s->flags & SEC_LINKER_CREATED) == 0)
2635 continue;
2637 if (s == htab->splt
2638 || s == htab->sgot
2639 || s == htab->sgotplt
2640 || s == htab->sdynbss)
2642 /* Strip this section if we don't need it. */
2644 else if (strncmp (s->name, ".rela", 5) == 0)
2646 if (s->size != 0 && s != htab->srelplt)
2648 if (!reltext_exist)
2650 const char *name = s->name + 5;
2651 bfd *ibfd;
2652 for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next)
2653 if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
2654 && ibfd->flags & DYNAMIC)
2656 asection *target = bfd_get_section_by_name (ibfd, name);
2657 if (target != NULL
2658 && elf_section_data (target)->sreloc == s
2659 && ((target->output_section->flags
2660 & (SEC_READONLY | SEC_ALLOC))
2661 == (SEC_READONLY | SEC_ALLOC)))
2663 reltext_exist = TRUE;
2664 break;
2668 relocs_exist = TRUE;
2671 /* We use the reloc_count field as a counter if we need to
2672 copy relocs into the output file. */
2673 s->reloc_count = 0;
2675 else
2677 /* It's not one of our sections, so don't allocate space. */
2678 continue;
2681 if (s->size == 0)
2683 s->flags |= SEC_EXCLUDE;
2684 continue;
2687 if ((s->flags & SEC_HAS_CONTENTS) == 0)
2688 continue;
2690 /* Allocate memory for the section contents. */
2691 s->contents = bfd_zalloc (dynobj, s->size);
2692 if (s->contents == NULL)
2693 return FALSE;
2696 if (htab->dynamic_sections_created)
2698 /* TODO: Check if this is needed. */
2699 if (!bfd_link_pic (info))
2700 if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
2701 return FALSE;
2703 if (htab->splt && (htab->splt->flags & SEC_EXCLUDE) == 0)
2704 if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
2705 || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2706 || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2707 || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
2708 return FALSE;
2710 if (relocs_exist)
2711 if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
2712 || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
2713 || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
2714 sizeof (Elf32_External_Rela)))
2715 return FALSE;
2717 if (reltext_exist)
2718 if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
2719 return FALSE;
2722 return TRUE;
2726 /* Classify dynamic relocs such that -z combreloc can reorder and combine
2727 them. */
2728 static enum elf_reloc_type_class
2729 elf32_arc_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
2730 const asection *rel_sec ATTRIBUTE_UNUSED,
2731 const Elf_Internal_Rela *rela)
2733 switch ((int) ELF32_R_TYPE (rela->r_info))
2735 case R_ARC_RELATIVE:
2736 return reloc_class_relative;
2737 case R_ARC_JMP_SLOT:
2738 return reloc_class_plt;
2739 case R_ARC_COPY:
2740 return reloc_class_copy;
2741 /* TODO: Needed in future to support ifunc. */
2743 case R_ARC_IRELATIVE:
2744 return reloc_class_ifunc;
2746 default:
2747 return reloc_class_normal;
2751 const struct elf_size_info arc_elf32_size_info =
2753 sizeof (Elf32_External_Ehdr),
2754 sizeof (Elf32_External_Phdr),
2755 sizeof (Elf32_External_Shdr),
2756 sizeof (Elf32_External_Rel),
2757 sizeof (Elf32_External_Rela),
2758 sizeof (Elf32_External_Sym),
2759 sizeof (Elf32_External_Dyn),
2760 sizeof (Elf_External_Note),
2763 32, 2,
2764 ELFCLASS32, EV_CURRENT,
2765 bfd_elf32_write_out_phdrs,
2766 bfd_elf32_write_shdrs_and_ehdr,
2767 bfd_elf32_checksum_contents,
2768 bfd_elf32_write_relocs,
2769 bfd_elf32_swap_symbol_in,
2770 bfd_elf32_swap_symbol_out,
2771 bfd_elf32_slurp_reloc_table,
2772 bfd_elf32_slurp_symbol_table,
2773 bfd_elf32_swap_dyn_in,
2774 bfd_elf32_swap_dyn_out,
2775 bfd_elf32_swap_reloc_in,
2776 bfd_elf32_swap_reloc_out,
2777 bfd_elf32_swap_reloca_in,
2778 bfd_elf32_swap_reloca_out
2781 #define elf_backend_size_info arc_elf32_size_info
2783 /* Hook called by the linker routine which adds symbols from an object
2784 file. */
2786 static bfd_boolean
2787 elf_arc_add_symbol_hook (bfd * abfd,
2788 struct bfd_link_info * info,
2789 Elf_Internal_Sym * sym,
2790 const char ** namep ATTRIBUTE_UNUSED,
2791 flagword * flagsp ATTRIBUTE_UNUSED,
2792 asection ** secp ATTRIBUTE_UNUSED,
2793 bfd_vma * valp ATTRIBUTE_UNUSED)
2795 if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
2796 && (abfd->flags & DYNAMIC) == 0
2797 && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
2798 elf_tdata (info->output_bfd)->has_gnu_symbols |= elf_gnu_symbol_ifunc;
2800 return TRUE;
2803 /* GDB expects general purpose registers to be in section .reg. However Linux
2804 kernel doesn't create this section and instead writes registers to NOTE
2805 section. It is up to the binutils to create a pseudo-section .reg from the
2806 contents of NOTE. Also BFD will read pid and signal number from NOTE. This
2807 function relies on offsets inside elf_prstatus structure in Linux to be
2808 stable. */
2810 static bfd_boolean
2811 elf32_arc_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
2813 int offset;
2814 size_t size;
2816 switch (note->descsz)
2818 default:
2819 return FALSE;
2821 case 236: /* sizeof (struct elf_prstatus) on Linux/arc. */
2822 /* pr_cursig */
2823 elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
2824 /* pr_pid */
2825 elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
2826 /* pr_regs */
2827 offset = 72;
2828 size = (40 * 4); /* There are 40 registers in user_regs_struct. */
2829 break;
2831 /* Make a ".reg/999" section. */
2832 return _bfd_elfcore_make_pseudosection (abfd, ".reg", size,
2833 note->descpos + offset);
2836 /* Determine whether an object attribute tag takes an integer, a
2837 string or both. */
2839 static int
2840 elf32_arc_obj_attrs_arg_type (int tag)
2842 if (tag == Tag_ARC_CPU_name
2843 || tag == Tag_ARC_ISA_config
2844 || tag == Tag_ARC_ISA_apex)
2845 return ATTR_TYPE_FLAG_STR_VAL;
2846 else if (tag < (Tag_ARC_ISA_mpy_option + 1))
2847 return ATTR_TYPE_FLAG_INT_VAL;
2848 else
2849 return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL;
2852 /* Attribute numbers >=14 can be safely ignored. */
2854 static bfd_boolean
2855 elf32_arc_obj_attrs_handle_unknown (bfd *abfd, int tag)
2857 if ((tag & 127) < (Tag_ARC_ISA_mpy_option + 1))
2859 _bfd_error_handler
2860 (_("%B: Unknown mandatory ARC object attribute %d."),
2861 abfd, tag);
2862 bfd_set_error (bfd_error_bad_value);
2863 return FALSE;
2865 else
2867 _bfd_error_handler
2868 (_("Warning: %B: Unknown ARC object attribute %d."),
2869 abfd, tag);
2870 return TRUE;
2874 /* Handle an ARC specific section when reading an object file. This is
2875 called when bfd_section_from_shdr finds a section with an unknown
2876 type. */
2878 static bfd_boolean
2879 elf32_arc_section_from_shdr (bfd *abfd,
2880 Elf_Internal_Shdr * hdr,
2881 const char *name,
2882 int shindex)
2884 switch (hdr->sh_type)
2886 case SHT_ARC_ATTRIBUTES:
2887 break;
2889 default:
2890 return FALSE;
2893 if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
2894 return FALSE;
2896 return TRUE;
2899 #define TARGET_LITTLE_SYM arc_elf32_le_vec
2900 #define TARGET_LITTLE_NAME "elf32-littlearc"
2901 #define TARGET_BIG_SYM arc_elf32_be_vec
2902 #define TARGET_BIG_NAME "elf32-bigarc"
2903 #define ELF_ARCH bfd_arch_arc
2904 #define ELF_TARGET_ID ARC_ELF_DATA
2905 #define ELF_MACHINE_CODE EM_ARC_COMPACT
2906 #define ELF_MACHINE_ALT1 EM_ARC_COMPACT2
2907 #define ELF_MAXPAGESIZE 0x2000
2909 #define bfd_elf32_bfd_link_hash_table_create arc_elf_link_hash_table_create
2911 #define bfd_elf32_bfd_merge_private_bfd_data arc_elf_merge_private_bfd_data
2912 #define bfd_elf32_bfd_reloc_type_lookup arc_elf32_bfd_reloc_type_lookup
2913 #define bfd_elf32_bfd_set_private_flags arc_elf_set_private_flags
2914 #define bfd_elf32_bfd_print_private_bfd_data arc_elf_print_private_bfd_data
2915 #define bfd_elf32_bfd_copy_private_bfd_data arc_elf_copy_private_bfd_data
2917 #define elf_info_to_howto_rel arc_info_to_howto_rel
2918 #define elf_backend_object_p arc_elf_object_p
2919 #define elf_backend_final_write_processing arc_elf_final_write_processing
2921 #define elf_backend_relocate_section elf_arc_relocate_section
2922 #define elf_backend_check_relocs elf_arc_check_relocs
2923 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
2925 #define elf_backend_reloc_type_class elf32_arc_reloc_type_class
2927 #define elf_backend_adjust_dynamic_symbol elf_arc_adjust_dynamic_symbol
2928 #define elf_backend_finish_dynamic_symbol elf_arc_finish_dynamic_symbol
2930 #define elf_backend_finish_dynamic_sections elf_arc_finish_dynamic_sections
2931 #define elf_backend_size_dynamic_sections elf_arc_size_dynamic_sections
2932 #define elf_backend_add_symbol_hook elf_arc_add_symbol_hook
2934 #define elf_backend_can_gc_sections 1
2935 #define elf_backend_want_got_plt 1
2936 #define elf_backend_plt_readonly 1
2937 #define elf_backend_rela_plts_and_copies_p 1
2938 #define elf_backend_want_plt_sym 0
2939 #define elf_backend_got_header_size 12
2940 #define elf_backend_dtrel_excludes_plt 1
2942 #define elf_backend_may_use_rel_p 0
2943 #define elf_backend_may_use_rela_p 1
2944 #define elf_backend_default_use_rela_p 1
2946 #define elf_backend_grok_prstatus elf32_arc_grok_prstatus
2948 #define elf_backend_default_execstack 0
2950 #undef elf_backend_obj_attrs_vendor
2951 #define elf_backend_obj_attrs_vendor "ARC"
2952 #undef elf_backend_obj_attrs_section
2953 #define elf_backend_obj_attrs_section ".ARC.attributes"
2954 #undef elf_backend_obj_attrs_arg_type
2955 #define elf_backend_obj_attrs_arg_type elf32_arc_obj_attrs_arg_type
2956 #undef elf_backend_obj_attrs_section_type
2957 #define elf_backend_obj_attrs_section_type SHT_ARC_ATTRIBUTES
2958 #define elf_backend_obj_attrs_handle_unknown elf32_arc_obj_attrs_handle_unknown
2960 #define elf_backend_section_from_shdr elf32_arc_section_from_shdr
2962 #include "elf32-target.h"