1 /* ARC-specific support for 32-bit ELF
2    Copyright (C) 1994-2018 Free Software Foundation, Inc.
3    Contributed by Cupertino Miranda (cmiranda@synopsys.com).
4 
5    This file is part of BFD, the Binary File Descriptor library.
6 
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.
11 
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.
16 
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.  */
21 
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"
31 
32 #define FEATURE_LIST_NAME bfd_feature_list
33 #define CONFLICT_LIST bfd_conflict_list
34 #include "opcode/arc-attrs.h"
35 
36 /* #define ARC_ENABLE_DEBUG 1  */
37 #ifdef ARC_ENABLE_DEBUG
38 static const char *
name_for_global_symbol(struct elf_link_hash_entry * h)39 name_for_global_symbol (struct elf_link_hash_entry *h)
40 {
41   static char *local_str = "(local)";
42   if (h == NULL)
43     return local_str;
44   return h->root.root.string;
45 }
46 #define ARC_DEBUG(fmt, args...) fprintf (stderr, fmt, ##args)
47 #else
48 #define ARC_DEBUG(...)
49 #endif
50 
51 
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;							\
57 									\
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       }									\
72   }
73 
74 
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"
80 
81 char * init_str = INIT_SYM_STRING;
82 char * fini_str = FINI_SYM_STRING;
83 
84 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
85       case VALUE: \
86 	return "R_" #TYPE; \
87 	break;
88 
89 static ATTRIBUTE_UNUSED const char *
reloc_type_to_name(unsigned int type)90 reloc_type_to_name (unsigned int type)
91 {
92   switch (type)
93     {
94       #include "elf/arc-reloc.def"
95 
96       default:
97 	return "UNKNOWN";
98 	break;
99     }
100 }
101 #undef ARC_RELOC_HOWTO
102 
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).  */
105 
106 #define USE_REL 1
107 
108 static ATTRIBUTE_UNUSED bfd_boolean
is_reloc_PC_relative(reloc_howto_type * howto)109 is_reloc_PC_relative (reloc_howto_type *howto)
110 {
111   return (strstr (howto->name, "PC") != NULL) ? TRUE : FALSE;
112 }
113 
114 static bfd_boolean
is_reloc_SDA_relative(reloc_howto_type * howto)115 is_reloc_SDA_relative (reloc_howto_type *howto)
116 {
117   return (strstr (howto->name, "SDA") != NULL) ? TRUE : FALSE;
118 }
119 
120 static bfd_boolean
is_reloc_for_GOT(reloc_howto_type * howto)121 is_reloc_for_GOT (reloc_howto_type * howto)
122 {
123   if (strstr (howto->name, "TLS") != NULL)
124     return FALSE;
125   return (strstr (howto->name, "GOT") != NULL) ? TRUE : FALSE;
126 }
127 
128 static bfd_boolean
is_reloc_for_PLT(reloc_howto_type * howto)129 is_reloc_for_PLT (reloc_howto_type * howto)
130 {
131   return (strstr (howto->name, "PLT") != NULL) ? TRUE : FALSE;
132 }
133 
134 static bfd_boolean
is_reloc_for_TLS(reloc_howto_type * howto)135 is_reloc_for_TLS (reloc_howto_type *howto)
136 {
137   return (strstr (howto->name, "TLS") != NULL) ? TRUE : FALSE;
138 }
139 
140 struct arc_relocation_data
141 {
142   bfd_signed_vma  reloc_offset;
143   bfd_signed_vma  reloc_addend;
144   bfd_signed_vma  got_offset_value;
145 
146   bfd_signed_vma  sym_value;
147   asection *	  sym_section;
148 
149   reloc_howto_type *howto;
150 
151   asection *	  input_section;
152 
153   bfd_signed_vma  sdata_begin_symbol_vma;
154   bfd_boolean	  sdata_begin_symbol_vma_set;
155   bfd_signed_vma  got_symbol_vma;
156 
157   bfd_boolean	  should_relocate;
158 
159   const char *    symbol_name;
160 };
161 
162 /* Should be included at this location due to static declarations
163  * defined before this point.  */
164 #include "arc-got.h"
165 
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)
172 
173 
174 static bfd_reloc_status_type
arc_elf_reloc(bfd * abfd ATTRIBUTE_UNUSED,arelent * reloc_entry,asymbol * symbol_in,void * data ATTRIBUTE_UNUSED,asection * input_section,bfd * output_bfd,char ** error_message ATTRIBUTE_UNUSED)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)
182 {
183   if (output_bfd != NULL)
184     {
185       reloc_entry->address += input_section->output_offset;
186 
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;
192 
193       return bfd_reloc_ok;
194     }
195 
196   return bfd_reloc_continue;
197 }
198 
199 
200 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
201   TYPE = VALUE,
202 enum howto_list
203 {
204 #include "elf/arc-reloc.def"
205   HOWTO_LIST_LAST
206 };
207 #undef ARC_RELOC_HOWTO
208 
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),
213 
214 static struct reloc_howto_struct elf_arc_howto_table[] =
215 {
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.
232 */
233 };
234 #undef ARC_RELOC_HOWTO
235 
arc_elf_howto_init(void)236 static void arc_elf_howto_init (void)
237 {
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) \
244     { \
245       BFD_ASSERT (SIZE == 2); \
246     }
247 
248 #include "elf/arc-reloc.def"
249 
250 }
251 #undef ARC_RELOC_HOWTO
252 
253 
254 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
255   [TYPE] = VALUE,
256 const int howto_table_lookup[] =
257 {
258 #include "elf/arc-reloc.def"
259 };
260 #undef ARC_RELOC_HOWTO
261 
262 static reloc_howto_type *
arc_elf_howto(unsigned int r_type)263 arc_elf_howto (unsigned int r_type)
264 {
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];
268 }
269 
270 /* Map BFD reloc types to ARC ELF reloc types.  */
271 
272 struct arc_reloc_map
273 {
274   bfd_reloc_code_real_type  bfd_reloc_val;
275   unsigned char		    elf_reloc_val;
276 };
277 
278 /* ARC ELF linker hash entry.  */
279 struct elf_arc_link_hash_entry
280 {
281   struct elf_link_hash_entry root;
282 
283   /* Track dynamic relocs copied for this symbol.  */
284   struct elf_dyn_relocs *dyn_relocs;
285 };
286 
287 /* ARC ELF linker hash table.  */
288 struct elf_arc_link_hash_table
289 {
290   struct elf_link_hash_table elf;
291 };
292 
293 static struct bfd_hash_entry *
elf_arc_link_hash_newfunc(struct bfd_hash_entry * entry,struct bfd_hash_table * table,const char * string)294 elf_arc_link_hash_newfunc (struct bfd_hash_entry *entry,
295 			   struct bfd_hash_table *table,
296 			   const char *string)
297 {
298   /* Allocate the structure if it has not already been allocated by a
299      subclass.  */
300   if (entry == NULL)
301     {
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;
307     }
308 
309   /* Call the allocation method of the superclass.  */
310   entry = _bfd_elf_link_hash_newfunc (entry, table, string);
311   if (entry != NULL)
312     {
313       struct elf_arc_link_hash_entry *eh;
314 
315       eh = (struct elf_arc_link_hash_entry *) entry;
316       eh->dyn_relocs = NULL;
317     }
318 
319   return entry;
320 }
321 
322 /* Destroy an ARC ELF linker hash table.  */
323 static void
elf_arc_link_hash_table_free(bfd * obfd)324 elf_arc_link_hash_table_free (bfd *obfd)
325 {
326   _bfd_elf_link_hash_table_free (obfd);
327 }
328 
329 /* Create an ARC ELF linker hash table.  */
330 
331 static struct bfd_link_hash_table *
arc_elf_link_hash_table_create(bfd * abfd)332 arc_elf_link_hash_table_create (bfd *abfd)
333 {
334   struct elf_arc_link_hash_table *ret;
335 
336   ret = (struct elf_arc_link_hash_table *) bfd_zmalloc (sizeof (*ret));
337   if (ret == NULL)
338     return NULL;
339 
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))
344     {
345       free (ret);
346       return NULL;
347     }
348 
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;
353 
354   ret->elf.root.hash_table_free = elf_arc_link_hash_table_free;
355 
356   return &ret->elf.root;
357 }
358 
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[] =
362 {
363 #include "elf/arc-reloc.def"
364 
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},
370 };
371 #undef ARC_RELOC_HOWTO
372 
373 typedef ATTRIBUTE_UNUSED bfd_vma (*replace_func) (unsigned, int ATTRIBUTE_UNUSED);
374 
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
get_replace_function(bfd * abfd,unsigned int r_type)380 get_replace_function (bfd *abfd, unsigned int r_type)
381 {
382   void *func = NULL;
383 
384   switch (r_type)
385     {
386       #include "elf/arc-reloc.def"
387     }
388 
389   if (func == replace_bits24 && bfd_big_endian (abfd))
390     return (replace_func) replace_bits24_be;
391 
392   return (replace_func) func;
393 }
394 #undef ARC_RELOC_HOWTO
395 
396 static reloc_howto_type *
arc_elf32_bfd_reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)397 arc_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
398 				 bfd_reloc_code_real_type code)
399 {
400   unsigned int i;
401 
402   for (i = ARRAY_SIZE (arc_reloc_map); i--;)
403     {
404       if (arc_reloc_map[i].bfd_reloc_val == code)
405 	return arc_elf_howto (arc_reloc_map[i].elf_reloc_val);
406     }
407 
408   return NULL;
409 }
410 
411 /* Function to set the ELF flag bits.  */
412 static bfd_boolean
arc_elf_set_private_flags(bfd * abfd,flagword flags)413 arc_elf_set_private_flags (bfd *abfd, flagword flags)
414 {
415   elf_elfheader (abfd)->e_flags = flags;
416   elf_flags_init (abfd) = TRUE;
417   return TRUE;
418 }
419 
420 /* Print private flags.  */
421 static bfd_boolean
arc_elf_print_private_bfd_data(bfd * abfd,void * ptr)422 arc_elf_print_private_bfd_data (bfd *abfd, void * ptr)
423 {
424   FILE *file = (FILE *) ptr;
425   flagword flags;
426 
427   BFD_ASSERT (abfd != NULL && ptr != NULL);
428 
429   /* Print normal ELF private data.  */
430   _bfd_elf_print_private_bfd_data (abfd, ptr);
431 
432   flags = elf_elfheader (abfd)->e_flags;
433   fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
434 
435   switch (flags & EF_ARC_MACH_MSK)
436     {
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;
445     }
446 
447   switch (flags & EF_ARC_OSABI_MSK)
448     {
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;
456     }
457 
458   fputc ('\n', file);
459   return TRUE;
460 }
461 
462 /* Copy backend specific data from one object module to another.  */
463 
464 static bfd_boolean
arc_elf_copy_private_bfd_data(bfd * ibfd,bfd * obfd)465 arc_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
466 {
467   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
468       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
469     return TRUE;
470 
471   BFD_ASSERT (!elf_flags_init (obfd)
472 	      || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
473 
474   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
475   elf_flags_init (obfd) = TRUE;
476 
477   /* Copy object attributes.  */
478   _bfd_elf_copy_obj_attributes (ibfd, obfd);
479 
480   return _bfd_elf_copy_private_bfd_data (ibfd, obfd);
481 }
482 
483 static reloc_howto_type *
bfd_elf32_bfd_reloc_name_lookup(bfd * abfd ATTRIBUTE_UNUSED,const char * r_name)484 bfd_elf32_bfd_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED,
485 				 const char *r_name)
486 {
487   unsigned int i;
488 
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);
493 
494   return NULL;
495 }
496 
497 /* Set the howto pointer for an ARC ELF reloc.  */
498 
499 static void
arc_info_to_howto_rel(bfd * abfd ATTRIBUTE_UNUSED,arelent * cache_ptr,Elf_Internal_Rela * dst)500 arc_info_to_howto_rel (bfd * abfd ATTRIBUTE_UNUSED,
501 		       arelent * cache_ptr,
502 		       Elf_Internal_Rela * dst)
503 {
504   unsigned int r_type;
505 
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);
509 }
510 
511 /* Extract CPU features from an NTBS.  */
512 
513 static unsigned
arc_extract_features(const char * p)514 arc_extract_features (const char *p)
515 {
516   unsigned i, r = 0;
517 
518   if (!p)
519     return 0;
520 
521   for (i = 0; i < ARRAY_SIZE (bfd_feature_list); i++)
522     {
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;
529     }
530 
531   return r;
532 }
533 
534 /* Concatenate two strings.  s1 can be NULL but not
535    s2.  */
536 
537 static char *
arc_stralloc(char * s1,const char * s2)538 arc_stralloc (char * s1, const char * s2)
539 {
540   char *p;
541 
542   /* Only s1 can be null.  */
543   BFD_ASSERT (s2);
544 
545   p = s1 ? concat (s1, ",", s2, NULL) : (char *)s2;
546 
547   return p;
548 }
549 
550 /* Merge ARC object attributes from IBFD into OBFD.  Raise an error if
551    there are conflicting attributes.  */
552 
553 static bfd_boolean
arc_elf_merge_attributes(bfd * ibfd,struct bfd_link_info * info)554 arc_elf_merge_attributes (bfd *ibfd, struct bfd_link_info *info)
555 {
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;
563 
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;
569 
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;
575 
576   if (!elf_known_obj_attributes_proc (obfd)[0].i)
577     {
578       /* This is the first object.  Copy the attributes.  */
579       _bfd_elf_copy_obj_attributes (ibfd, obfd);
580 
581       out_attr = elf_known_obj_attributes_proc (obfd);
582 
583       /* Use the Tag_null value to indicate the attributes have been
584 	 initialized.  */
585       out_attr[0].i = 1;
586 
587       return TRUE;
588     }
589 
590   in_attr = elf_known_obj_attributes_proc (ibfd);
591   out_attr = elf_known_obj_attributes_proc (obfd);
592 
593   for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
594     {
595       /* Merge this attribute with existing attributes.  */
596       switch (i)
597 	{
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)
602 	    {
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]);
615 	    }
616 	  break;
617 
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))
623 	    {
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;
637 	    }
638 	  else
639 	    {
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};
650 
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];
656 
657 	      in_feature = arc_extract_features (p1);
658 	      out_feature = arc_extract_features (p2);
659 
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)))
665 		  {
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;
672 		  }
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])
679 		  {
680 		    unsigned k;
681 		    for (k = 0; k < ARRAY_SIZE (bfd_feature_list); k++)
682 		      {
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;
689 		      }
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;
696 		  }
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);
706 	    }
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;
715 
716 	case Tag_ARC_CPU_name:
717 	  break;
718 
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)
723 	    {
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;
729 	    }
730 	  break;
731 
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:
740 	  {
741 	    const char *tagval[] = { "Absent", "MWDT", "GNU" };
742 
743 	    if (!tagname)
744 	      tagname = "TLS";
745 
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)
750 	      {
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;
757 	      }
758 	    tagname = NULL;
759 	    break;
760 	  }
761 
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";
772 
773 	  if (out_attr[i].i != 0 && in_attr[i].i != 0
774 	      && out_attr[i].i != in_attr[i].i)
775 	    {
776 	      _bfd_error_handler
777 		(_("error: %B: conflicting attributes %s.\n"),
778 		 obfd, tagname);
779 	      result = FALSE;
780 	    }
781 	  break;
782 
783 	case Tag_ARC_ISA_apex:
784 	  break; /* Do nothing for APEX attributes.  */
785 
786 	case Tag_ARC_ISA_config:
787 	  /* It is handled in Tag_ARC_CPU_base.  */
788 	  break;
789 
790 	default:
791 	  result
792 	    = result && _bfd_elf_merge_unknown_attribute_low (ibfd, obfd, i);
793 	}
794 
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;
798     }
799 
800   /* Merge Tag_compatibility attributes and any common GNU ones.  */
801   if (!_bfd_elf_merge_object_attributes (ibfd, info))
802     return FALSE;
803 
804   /* Check for any attributes not known on ARC.  */
805   result &= _bfd_elf_merge_unknown_attribute_list (ibfd, obfd);
806 
807   return result;
808 }
809 
810 /* Merge backend specific data from an object file to the output
811    object file when linking.  */
812 
813 static bfd_boolean
arc_elf_merge_private_bfd_data(bfd * ibfd,struct bfd_link_info * info)814 arc_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
815 {
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;
822 
823    /* Check if we have the same endianess.  */
824   if (! _bfd_generic_verify_endian_match (ibfd, info))
825     return FALSE;
826 
827   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
828       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
829     return TRUE;
830 
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;
834 
835   if (!elf_flags_init (obfd)) /* First call, no flags set.  */
836     {
837       elf_flags_init (obfd) = TRUE;
838       out_flags = in_flags;
839     }
840 
841   if (!arc_elf_merge_attributes (ibfd, info))
842     return FALSE;
843 
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))
848     {
849       bfd_boolean null_input_bfd = TRUE;
850       bfd_boolean only_data_sections = TRUE;
851 
852       for (sec = ibfd->sections; sec != NULL; sec = sec->next)
853 	{
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;
858 
859 	  null_input_bfd = FALSE;
860 	}
861 
862       if (null_input_bfd || only_data_sections)
863 	return TRUE;
864     }
865 
866   /* Complain about various flag/architecture mismatches.  */
867   mach_ibfd = elf_elfheader (ibfd)->e_machine;
868   if (mach_obfd == EM_NONE)
869     {
870       mach_obfd = mach_ibfd;
871     }
872   else
873     {
874       if (mach_ibfd != mach_obfd)
875 	{
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;
881 	}
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))
887 	{
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;
899 	}
900       else
901 	{
902 	  /* Everything is correct; don't change the output flags.  */
903 	  in_flags = out_flags;
904 	}
905     }
906 
907   /* Update the flags.  */
908   elf_elfheader (obfd)->e_flags = in_flags;
909 
910   if (bfd_get_mach (obfd) < bfd_get_mach (ibfd))
911     {
912       return bfd_set_arch_mach (obfd, bfd_arch_arc, bfd_get_mach (ibfd));
913     }
914 
915   return TRUE;
916 }
917 
918 /* Return a best guess for the machine number based on the attributes.  */
919 
920 static unsigned int
bfd_arc_get_mach_from_attributes(bfd * abfd)921 bfd_arc_get_mach_from_attributes (bfd * abfd)
922 {
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;
925 
926   switch (arch)
927     {
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;
937     }
938   return (e_machine == EM_ARC_COMPACT)
939     ? bfd_mach_arc_arc700 : bfd_mach_arc_arcv2;
940 }
941 
942 /* Set the right machine number for an ARC ELF file.  */
943 static bfd_boolean
arc_elf_object_p(bfd * abfd)944 arc_elf_object_p (bfd * abfd)
945 {
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;
952 
953   if (e_machine == EM_ARC_COMPACT || e_machine == EM_ARC_COMPACT2)
954     {
955       switch (arch)
956 	{
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;
973 	}
974     }
975   else
976     {
977       if (e_machine == EM_ARC)
978 	{
979 	  _bfd_error_handler
980 	    (_("Error: The ARC4 architecture is no longer supported.\n"));
981 	  return FALSE;
982 	}
983       else
984 	{
985 	  _bfd_error_handler
986 	    (_("Warning: unset or old architecture flags. \n"
987 	       "	       Use default machine.\n"));
988 	}
989     }
990 
991   return bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach);
992 }
993 
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.  */
996 
997 static void
arc_elf_final_write_processing(bfd * abfd,bfd_boolean linker ATTRIBUTE_UNUSED)998 arc_elf_final_write_processing (bfd * abfd,
999 				bfd_boolean linker ATTRIBUTE_UNUSED)
1000 {
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;
1005 
1006   switch (bfd_get_mach (abfd))
1007     {
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;
1022     }
1023 
1024   elf_elfheader (abfd)->e_machine = emf;
1025 
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;
1031 
1032   elf_elfheader (abfd)->e_flags |=  e_flags;
1033 }
1034 
1035 #ifdef ARC_ENABLE_DEBUG
1036 #define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
1037 
1038 static void
debug_arc_reloc(struct arc_relocation_data reloc_data)1039 debug_arc_reloc (struct arc_relocation_data reloc_data)
1040 {
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)
1051     {
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);
1062     }
1063   else
1064     {
1065       ARC_DEBUG ("  symbol section is NULL\n");
1066     }
1067 
1068   ARC_DEBUG (" Input_section:\n");
1069   if (reloc_data.input_section != NULL)
1070     {
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);
1080     }
1081   else
1082     {
1083       ARC_DEBUG ("	input section is NULL\n");
1084     }
1085 }
1086 #else
1087 #define DEBUG_ARC_RELOC(A)
1088 #endif /* ARC_ENABLE_DEBUG */
1089 
1090 static bfd_vma
middle_endian_convert(bfd_vma insn,bfd_boolean do_it)1091 middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
1092 {
1093   if (do_it)
1094     {
1095       insn
1096 	= ((insn & 0xffff0000) >> 16)
1097 	  | ((insn & 0xffff) << 16);
1098     }
1099   return insn;
1100 }
1101 
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.  */
1105 
1106 static inline bfd_reloc_status_type
arc_special_overflow_checks(const struct arc_relocation_data reloc_data,bfd_signed_vma relocation,struct bfd_link_info * info ATTRIBUTE_UNUSED)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)
1110 {
1111   switch (reloc_data.howto->type)
1112     {
1113     case R_ARC_NPS_CMEM16:
1114       if (((relocation >> 16) & 0xffff) != NPS_CMEM_HIGH_VALUE)
1115 	{
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;
1140 	}
1141       break;
1142 
1143     default:
1144       break;
1145     }
1146 
1147   return bfd_reloc_ok;
1148 }
1149 
1150 #define ME(reloc) (reloc)
1151 
1152 #define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") != NULL) \
1153 			    && (!bfd_big_endian (BFD)))
1154 
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)
1168 
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) (						\
1173 	   (								\
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)
1190 
1191 #define none (0)
1192 
1193 #ifdef ARC_ENABLE_DEBUG
1194 #define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA, TYPE)			\
1195   do									\
1196     {									\
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);		\
1226     }									\
1227   while (0)
1228 
1229 #define PRINT_DEBUG_RELOC_INFO_AFTER				\
1230   do								\
1231     {								\
1232       ARC_DEBUG ("after  = 0x%08x\n", (unsigned int) insn);	\
1233     }								\
1234   while (0)
1235 
1236 #else
1237 
1238 #define PRINT_DEBUG_RELOC_INFO_BEFORE(...)
1239 #define PRINT_DEBUG_RELOC_INFO_AFTER
1240 
1241 #endif /* ARC_ENABLE_DEBUG */
1242 
1243 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
1244   case R_##TYPE:							\
1245     {									\
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;					\
1253     }									\
1254     break;
1255 
1256 static bfd_reloc_status_type
arc_do_relocation(bfd_byte * contents,struct arc_relocation_data reloc_data,struct bfd_link_info * info)1257 arc_do_relocation (bfd_byte * contents,
1258 		   struct arc_relocation_data reloc_data,
1259 		   struct bfd_link_info *info)
1260 {
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;
1267 
1268   if (!reloc_data.should_relocate)
1269     return bfd_reloc_ok;
1270 
1271   switch (reloc_data.howto->size)
1272     {
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;
1292     }
1293 
1294   orig_insn = insn;
1295 
1296   switch (reloc_data.howto->type)
1297     {
1298 #include "elf/arc-reloc.def"
1299 
1300       default:
1301 	BFD_ASSERT (0);
1302 	break;
1303     }
1304 
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);
1314 
1315   if (flag != bfd_reloc_ok)
1316     {
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);
1322 
1323       return flag;
1324     }
1325 
1326   /* Write updated instruction back to memory.  */
1327   switch (reloc_data.howto->size)
1328     {
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;
1348     }
1349 
1350   return bfd_reloc_ok;
1351 }
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
1365 
1366 #undef ARC_RELOC_HOWTO
1367 
1368 
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
elf_arc_relocate_section(bfd * output_bfd,struct bfd_link_info * info,bfd * input_bfd,asection * input_section,bfd_byte * contents,Elf_Internal_Rela * relocs,Elf_Internal_Sym * local_syms,asection ** local_sections)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)
1392 {
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);
1399 
1400   symtab_hdr = &((elf_tdata (input_bfd))->symtab_hdr);
1401   sym_hashes = elf_sym_hashes (input_bfd);
1402 
1403   rel = wrel = relocs;
1404   relend = relocs + input_section->reloc_count;
1405   for (; rel < relend; wrel++, rel++)
1406     {
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;
1416 
1417       struct arc_relocation_data reloc_data =
1418       {
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
1430       };
1431 
1432       r_type = ELF32_R_TYPE (rel->r_info);
1433 
1434       if (r_type >= (int) R_ARC_max)
1435 	{
1436 	  bfd_set_error (bfd_error_bad_value);
1437 	  return FALSE;
1438 	}
1439       howto = arc_elf_howto (r_type);
1440 
1441       r_symndx = ELF32_R_SYM (rel->r_info);
1442 
1443       /* If we are generating another .o file and the symbol in not
1444 	 local, skip this relocation.  */
1445       if (bfd_link_relocatable (info))
1446 	{
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.  */
1451 
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)
1455 	    {
1456 	      sym = local_syms + r_symndx;
1457 	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1458 		{
1459 		  sec = local_sections[r_symndx];
1460 
1461 		  /* For RELA relocs.  Just adjust the addend
1462 		     value in the relocation entry.  */
1463 		  rel->r_addend += sec->output_offset + sym->st_value;
1464 
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__);
1468 		}
1469 	    }
1470 	}
1471 
1472       h2 = elf_link_hash_lookup (elf_hash_table (info), "__SDATA_BEGIN__",
1473 				 FALSE, FALSE, TRUE);
1474 
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.  */
1479 	{
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;
1484 	}
1485 
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;
1490 
1491       /* This is a final link.  */
1492       h = NULL;
1493       sym = NULL;
1494       sec = NULL;
1495 
1496       if (r_symndx < symtab_hdr->sh_info) /* A local symbol.  */
1497 	{
1498 	  sym = local_syms + r_symndx;
1499 	  sec = local_sections[r_symndx];
1500 	}
1501       else
1502 	{
1503 	  bfd_boolean warned, ignored;
1504 	  bfd_vma relocation ATTRIBUTE_UNUSED;
1505 
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);
1510 
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.  */
1515 
1516 	  /* Get the symbol's entry in the symtab.  */
1517 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1518 
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;
1522 
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)
1526 	    {
1527 	      reloc_data.sym_value = h->root.u.def.value;
1528 	      sec = h->root.u.def.section;
1529 	    }
1530 	}
1531 
1532       /* Clean relocs for symbols in discarded sections.  */
1533       if (sec != NULL && discarded_section (sec))
1534 	{
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;
1540 
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--;
1547 
1548 	  continue;
1549 	}
1550 
1551       if (bfd_link_relocatable (info))
1552 	{
1553 	  if (wrel != rel)
1554 	    *wrel = *rel;
1555 	  continue;
1556 	}
1557 
1558       if (r_symndx < symtab_hdr->sh_info) /* A local symbol.  */
1559 	{
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);
1566 
1567 	  /* Mergeable section handling.  */
1568 	  if ((sec->flags & SEC_MERGE)
1569 	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1570 	    {
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;
1579 
1580 	      reloc_data.reloc_addend = rel->r_addend;
1581 	    }
1582 
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;
1587 
1588 	  reloc_data.should_relocate = TRUE;
1589 	}
1590       else /* Global symbol.  */
1591 	{
1592 	  /* FIXME: We should use the RELOC_FOR_GLOBAL_SYMBOL macro
1593 	     (defined in elf-bfd.h) here.  */
1594 
1595 	  /* Get the symbol's entry in the symtab.  */
1596 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1597 
1598 	  while (h->root.type == bfd_link_hash_indirect
1599 		 || h->root.type == bfd_link_hash_warning)
1600 	  {
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;
1605 	  }
1606 
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;
1610 
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)
1614 	    {
1615 	      reloc_data.sym_value = h->root.u.def.value;
1616 	      reloc_data.sym_section = h->root.u.def.section;
1617 
1618 	      reloc_data.should_relocate = TRUE;
1619 
1620 	      if (is_reloc_for_GOT (howto) && !bfd_link_pic (info))
1621 		{
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);
1630 
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);
1635 		}
1636 	      if (is_reloc_for_PLT (howto) && h->plt.offset != (bfd_vma) -1)
1637 		{
1638 		  /* TODO: This is repeated up here.  */
1639 		  reloc_data.sym_value = h->plt.offset;
1640 		  reloc_data.sym_section = htab->splt;
1641 		}
1642 	    }
1643 	  else if (h->root.type == bfd_link_hash_undefweak)
1644 	    {
1645 	      /* Is weak symbol and has no definition.  */
1646 	      if (is_reloc_for_GOT (howto))
1647 		{
1648 		  reloc_data.sym_value = h->root.u.def.value;
1649 		  reloc_data.sym_section = htab->sgot;
1650 		  reloc_data.should_relocate = TRUE;
1651 		}
1652 	      else if (is_reloc_for_PLT (howto)
1653 		       && h->plt.offset != (bfd_vma) -1)
1654 		{
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;
1659 		}
1660 	      else
1661 		continue;
1662 	    }
1663 	  else
1664 	    {
1665 	      if (is_reloc_for_GOT (howto))
1666 		{
1667 		  reloc_data.sym_value = h->root.u.def.value;
1668 		  reloc_data.sym_section = htab->sgot;
1669 
1670 		  reloc_data.should_relocate = TRUE;
1671 		}
1672 	      else if (is_reloc_for_PLT (howto))
1673 		{
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;
1682 
1683 		  reloc_data.should_relocate = TRUE;
1684 		}
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);
1689 	    }
1690 
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;
1695 	}
1696 
1697       if ((is_reloc_for_GOT (howto)
1698 	   || is_reloc_for_TLS (howto)))
1699 	{
1700 	  reloc_data.should_relocate = TRUE;
1701 
1702 	  struct got_entry **list
1703 	    = get_got_entry_list_for_symbol (output_bfd, r_symndx, h);
1704 
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,
1713 						    h,
1714 						    &reloc_data);
1715 
1716 	  if (h == NULL)
1717 	    {
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);
1722 	    }
1723 	}
1724 
1725 
1726 #define IS_ARC_PCREL_TYPE(TYPE) \
1727   (   (TYPE == R_ARC_PC32)      \
1728    || (TYPE == R_ARC_32_PCREL))
1729 
1730       switch (r_type)
1731 	{
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))))
1742 	      {
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);
1750 
1751 		BFD_ASSERT (sreloc != NULL);
1752 
1753 		outrel.r_offset = _bfd_elf_section_offset (output_bfd,
1754 							   info,
1755 							   input_section,
1756 							   rel->r_offset);
1757 
1758 		if (outrel.r_offset == (bfd_vma) -1)
1759 		  skip = TRUE;
1760 
1761 		outrel.r_addend = rel->r_addend;
1762 		outrel.r_offset += (input_section->output_section->vma
1763 				    + input_section->output_offset);
1764 
1765 		if (skip)
1766 		  {
1767 		    memset (&outrel, 0, sizeof outrel);
1768 		    relocate = FALSE;
1769 		  }
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))
1776 		  {
1777 		    BFD_ASSERT (h != NULL);
1778 		    if ((input_section->flags & SEC_ALLOC) != 0)
1779 		      relocate = FALSE;
1780 		    else
1781 		      relocate = TRUE;
1782 
1783 		    BFD_ASSERT (h->dynindx != -1);
1784 		    outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1785 		  }
1786 		else
1787 		  {
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);
1801 		  }
1802 
1803 		BFD_ASSERT (sreloc->contents != 0);
1804 
1805 		loc = sreloc->contents;
1806 		loc += sreloc->reloc_count * sizeof (Elf32_External_Rela);
1807 		sreloc->reloc_count += 1;
1808 
1809 		bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1810 
1811 		if (!relocate)
1812 		  continue;
1813 	      }
1814 	    break;
1815 	  default:
1816 	    break;
1817 	}
1818 
1819       if (is_reloc_SDA_relative (howto)
1820 	  && !reloc_data.sdata_begin_symbol_vma_set)
1821 	{
1822 	  _bfd_error_handler
1823 	    ("Error: Linker symbol __SDATA_BEGIN__ not found");
1824 	  bfd_set_error (bfd_error_bad_value);
1825 	  return FALSE;
1826 	}
1827 
1828       DEBUG_ARC_RELOC (reloc_data);
1829 
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)
1834 	{
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;
1839 	}
1840 
1841       msg = NULL;
1842       switch (arc_do_relocation (contents, reloc_data, info))
1843 	{
1844 	case bfd_reloc_ok:
1845 	  continue; /* The reloc processing loop.  */
1846 
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;
1852 
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;
1857 
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;
1862 
1863 	case bfd_reloc_outofrange:
1864 	  /* xgettext:c-format */
1865 	  msg = _("%B(%A): internal error: out of range error");
1866 	  break;
1867 
1868 	case bfd_reloc_notsupported:
1869 	  /* xgettext:c-format */
1870 	  msg = _("%B(%A): internal error: unsupported relocation error");
1871 	  break;
1872 
1873 	case bfd_reloc_dangerous:
1874 	  /* xgettext:c-format */
1875 	  msg = _("%B(%A): internal error: dangerous relocation");
1876 	  break;
1877 
1878 	default:
1879 	  /* xgettext:c-format */
1880 	  msg = _("%B(%A): internal error: unknown error");
1881 	  break;
1882 	}
1883 
1884       if (msg)
1885 	_bfd_error_handler (msg, input_bfd, input_section, reloc_data.symbol_name);
1886       return FALSE;
1887     }
1888 
1889   return TRUE;
1890 }
1891 
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)
1895 
1896 static bfd_boolean
elf_arc_check_relocs(bfd * abfd,struct bfd_link_info * info,asection * sec,const Elf_Internal_Rela * relocs)1897 elf_arc_check_relocs (bfd *			 abfd,
1898 		      struct bfd_link_info *     info,
1899 		      asection *		 sec,
1900 		      const Elf_Internal_Rela *  relocs)
1901 {
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);
1909 
1910   if (bfd_link_relocatable (info))
1911     return TRUE;
1912 
1913   if (htab->dynobj == NULL)
1914     htab->dynobj = abfd;
1915 
1916   dynobj = (elf_hash_table (info))->dynobj;
1917   symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1918   sym_hashes = elf_sym_hashes (abfd);
1919 
1920   rel_end = relocs + sec->reloc_count;
1921   for (rel = relocs; rel < rel_end; rel++)
1922     {
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;
1927 
1928       r_type = ELF32_R_TYPE (rel->r_info);
1929 
1930       if (r_type >= (int) R_ARC_max)
1931 	{
1932 	  bfd_set_error (bfd_error_bad_value);
1933 	  return FALSE;
1934 	}
1935       howto = arc_elf_howto (r_type);
1936 
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];
1943 
1944       switch (r_type)
1945 	{
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))
1959 	      {
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;
1975 	      }
1976 
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))))
1990 	      {
1991 		if (sreloc == NULL)
1992 		  {
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);
2001 
2002 		    if (sreloc == NULL)
2003 		      return FALSE;
2004 		  }
2005 		sreloc->size += sizeof (Elf32_External_Rela);
2006 
2007 	      }
2008 	  default:
2009 	    break;
2010 	}
2011 
2012       if (is_reloc_for_PLT (howto))
2013 	{
2014 	  if (h == NULL)
2015 	    continue;
2016 	  else
2017 	    h->needs_plt = 1;
2018 	}
2019 
2020       /* Add info to the symbol got_entry_list.  */
2021       if (is_reloc_for_GOT (howto)
2022 	  || is_reloc_for_TLS (howto))
2023 	{
2024 	  if (! _bfd_elf_create_got_section (dynobj, info))
2025 	    return FALSE;
2026 
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,
2031 		  h);
2032 	}
2033     }
2034 
2035   return TRUE;
2036 }
2037 
2038 #define ELF_DYNAMIC_INTERPRETER  "/sbin/ld-uClibc.so"
2039 
2040 static struct plt_version_t *
arc_get_plt_version(struct bfd_link_info * info)2041 arc_get_plt_version (struct bfd_link_info *info)
2042 {
2043   int i;
2044 
2045   for (i = 0; i < 1; i++)
2046     {
2047       ARC_DEBUG ("%d: size1 = %d, size2 = %d\n", i,
2048 		 (int) plt_versions[i].entry_size,
2049 		 (int) plt_versions[i].elem_size);
2050     }
2051 
2052   if (bfd_get_mach (info->output_bfd) == bfd_mach_arc_arcv2)
2053     {
2054       if (bfd_link_pic (info))
2055 	return &(plt_versions[ELF_ARCV2_PIC]);
2056       else
2057 	return &(plt_versions[ELF_ARCV2_ABS]);
2058     }
2059   else
2060     {
2061       if (bfd_link_pic (info))
2062 	return &(plt_versions[ELF_ARC_PIC]);
2063       else
2064 	return &(plt_versions[ELF_ARC_ABS]);
2065     }
2066 }
2067 
2068 static bfd_vma
add_symbol_to_plt(struct bfd_link_info * info)2069 add_symbol_to_plt (struct bfd_link_info *info)
2070 {
2071   struct elf_link_hash_table *htab = elf_hash_table (info);
2072   bfd_vma ret;
2073 
2074   struct plt_version_t *plt_data = arc_get_plt_version (info);
2075 
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;
2080 
2081   ret = htab->splt->size;
2082 
2083   htab->splt->size += plt_data->elem_size;
2084   ARC_DEBUG ("PLT_SIZE = %d\n", (int) htab->splt->size);
2085 
2086   htab->sgotplt->size += 4;
2087   htab->srelplt->size += sizeof (Elf32_External_Rela);
2088 
2089   return ret;
2090 }
2091 
2092 #define PLT_DO_RELOCS_FOR_ENTRY(ABFD, DS, RELOCS)	\
2093   plt_do_relocs_for_symbol (ABFD, DS, RELOCS, 0, 0)
2094 
2095 static void
plt_do_relocs_for_symbol(bfd * abfd,struct elf_link_hash_table * htab,const struct plt_reloc * reloc,bfd_vma plt_offset,bfd_vma symbol_got_offset)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)
2101 {
2102   while (SYM_ONLY (reloc->symbol) != LAST_RELOC)
2103     {
2104       bfd_vma relocation = 0;
2105 
2106       switch (SYM_ONLY (reloc->symbol))
2107 	{
2108 	  case SGOT:
2109 		relocation
2110 		  = htab->sgotplt->output_section->vma
2111 		    + htab->sgotplt->output_offset + symbol_got_offset;
2112 		break;
2113 	}
2114       relocation += reloc->addend;
2115 
2116       if (IS_RELATIVE (reloc->symbol))
2117 	{
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;
2121 
2122 	  relocation -= htab->splt->output_section->vma
2123 			 + htab->splt->output_offset
2124 			 + plt_offset + reloc_offset;
2125 	}
2126 
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))
2130 	{
2131 	  relocation
2132 	    = ((relocation & 0xffff0000) >> 16)
2133 	      | ((relocation & 0xffff) << 16);
2134 	}
2135 
2136       switch (reloc->size)
2137 	{
2138 	  case 32:
2139 	    bfd_put_32 (htab->splt->output_section->owner,
2140 			relocation,
2141 			htab->splt->contents + plt_offset + reloc->offset);
2142 	    break;
2143 	}
2144 
2145       reloc = &(reloc[1]); /* Jump to next relocation.  */
2146     }
2147 }
2148 
2149 static void
relocate_plt_for_symbol(bfd * output_bfd,struct bfd_link_info * info,struct elf_link_hash_entry * h)2150 relocate_plt_for_symbol (bfd *output_bfd,
2151 			 struct bfd_link_info *info,
2152 			 struct elf_link_hash_entry *h)
2153 {
2154   struct plt_version_t *plt_data = arc_get_plt_version (info);
2155   struct elf_link_hash_table *htab = elf_hash_table (info);
2156 
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;
2160 
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);
2172 
2173   {
2174     bfd_vma i = 0;
2175     uint16_t *ptr = (uint16_t *) plt_data->elem;
2176 
2177     for (i = 0; i < plt_data->elem_size/2; i++)
2178       {
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));
2183       }
2184   }
2185 
2186   plt_do_relocs_for_symbol (output_bfd, htab,
2187 			    plt_data->elem_relocs,
2188 			    h->plt.offset,
2189 			    got_offset);
2190 
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);
2196 
2197   /* TODO: Fill in the entry in the .rela.plt section.  */
2198   {
2199     Elf_Internal_Rela rel;
2200     bfd_byte *loc;
2201 
2202     rel.r_offset = (htab->sgotplt->output_section->vma
2203 		    + htab->sgotplt->output_offset
2204 		    + got_offset);
2205     rel.r_addend = 0;
2206 
2207     BFD_ASSERT (h->dynindx != -1);
2208     rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_JMP_SLOT);
2209 
2210     loc = htab->srelplt->contents;
2211     loc += plt_index * sizeof (Elf32_External_Rela); /* relA */
2212     bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2213   }
2214 }
2215 
2216 static void
relocate_plt_for_entry(bfd * abfd,struct bfd_link_info * info)2217 relocate_plt_for_entry (bfd *abfd,
2218 			struct bfd_link_info *info)
2219 {
2220   struct plt_version_t *plt_data = arc_get_plt_version (info);
2221   struct elf_link_hash_table *htab = elf_hash_table (info);
2222 
2223   {
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++)
2227       {
2228 	uint16_t data = ptr[i];
2229 	bfd_put_16 (abfd,
2230 		    (bfd_vma) data,
2231 		    htab->splt->contents + (i*2));
2232       }
2233   }
2234   PLT_DO_RELOCS_FOR_ENTRY (abfd, htab, plt_data->entry_relocs);
2235 }
2236 
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.  */
2242 
2243 static bfd_boolean
elf_arc_adjust_dynamic_symbol(struct bfd_link_info * info,struct elf_link_hash_entry * h)2244 elf_arc_adjust_dynamic_symbol (struct bfd_link_info *info,
2245 			      struct elf_link_hash_entry *h)
2246 {
2247   asection *s;
2248   bfd *dynobj = (elf_hash_table (info))->dynobj;
2249   struct elf_link_hash_table *htab = elf_hash_table (info);
2250 
2251   if (h->type == STT_FUNC
2252       || h->type == STT_GNU_IFUNC
2253       || h->needs_plt == 1)
2254     {
2255       if (!bfd_link_pic (info) && !h->def_dynamic && !h->ref_dynamic)
2256 	{
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;
2264 	}
2265 
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;
2270 
2271       if (bfd_link_pic (info)
2272 	  || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
2273 	{
2274 	  bfd_vma loc = add_symbol_to_plt (info);
2275 
2276 	  if (bfd_link_executable (info) && !h->def_regular)
2277 	    {
2278 	      h->root.u.def.section = htab->splt;
2279 	      h->root.u.def.value = loc;
2280 	    }
2281 	  h->plt.offset = loc;
2282 	}
2283       else
2284 	{
2285 	  h->plt.offset = (bfd_vma) -1;
2286 	  h->needs_plt = 0;
2287 	}
2288       return TRUE;
2289     }
2290 
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->is_weakalias)
2295     {
2296       struct elf_link_hash_entry *def = weakdef (h);
2297       BFD_ASSERT (def->root.type == bfd_link_hash_defined);
2298       h->root.u.def.section = def->root.u.def.section;
2299       h->root.u.def.value = def->root.u.def.value;
2300       return TRUE;
2301     }
2302 
2303   /* This is a reference to a symbol defined by a dynamic object which
2304      is not a function.  */
2305 
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;
2312 
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;
2317 
2318   /* If -z nocopyreloc was given, we won't generate them either.  */
2319   if (info->nocopyreloc)
2320     {
2321       h->non_got_ref = 0;
2322       return TRUE;
2323     }
2324 
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.  */
2334 
2335   if (htab == NULL)
2336     return FALSE;
2337 
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)
2343     {
2344       struct elf_arc_link_hash_table *arc_htab = elf_arc_hash_table (info);
2345 
2346       BFD_ASSERT (arc_htab->elf.srelbss != NULL);
2347       arc_htab->elf.srelbss->size += sizeof (Elf32_External_Rela);
2348       h->needs_copy = 1;
2349     }
2350 
2351   /* TODO: Move this also to arc_hash_table.  */
2352   s = bfd_get_section_by_name (dynobj, ".dynbss");
2353   BFD_ASSERT (s != NULL);
2354 
2355   return _bfd_elf_adjust_dynamic_copy (info, h, s);
2356 }
2357 
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	  :
2363 	       h	  :
2364 	       sym	  :
2365    Returns  : True/False as the return status.  */
2366 
2367 static bfd_boolean
elf_arc_finish_dynamic_symbol(bfd * output_bfd,struct bfd_link_info * info,struct elf_link_hash_entry * h,Elf_Internal_Sym * sym)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)
2372 {
2373   if (h->plt.offset != (bfd_vma) -1)
2374     {
2375       relocate_plt_for_symbol (output_bfd, info, h);
2376 
2377       if (!h->def_regular)
2378 	{
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;
2382 	}
2383     }
2384 
2385 
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,
2393 				     h);
2394 
2395   if (h->needs_copy)
2396     {
2397       struct elf_arc_link_hash_table *arc_htab = elf_arc_hash_table (info);
2398 
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 ();
2404 
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);
2408 
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++;
2412 
2413       Elf_Internal_Rela rel;
2414       rel.r_addend = 0;
2415       rel.r_offset = rel_offset;
2416 
2417       BFD_ASSERT (h->dynindx != -1);
2418       rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_COPY);
2419 
2420       bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2421     }
2422 
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;
2428 
2429   return TRUE;
2430 }
2431 
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;
2440 
2441 /* Function :  elf_arc_finish_dynamic_sections
2442    Brief    :  Finish up the dynamic sections handling.
2443    Args     :  output_bfd :
2444 	       info	  :
2445 	       h	  :
2446 	       sym	  :
2447    Returns  : True/False as the return status.  */
2448 
2449 static bfd_boolean
elf_arc_finish_dynamic_sections(bfd * output_bfd,struct bfd_link_info * info)2450 elf_arc_finish_dynamic_sections (bfd * output_bfd,
2451 				 struct bfd_link_info *info)
2452 {
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");
2456 
2457   if (sdyn)
2458     {
2459       Elf32_External_Dyn *dyncon, *dynconend;
2460 
2461       dyncon = (Elf32_External_Dyn *) sdyn->contents;
2462       dynconend
2463 	= (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
2464       for (; dyncon < dynconend; dyncon++)
2465 	{
2466 	  Elf_Internal_Dyn internal_dyn;
2467 	  bfd_boolean	  do_it = FALSE;
2468 
2469 	  struct elf_link_hash_entry *h = NULL;
2470 	  asection	 *s = NULL;
2471 
2472 	  bfd_elf32_swap_dyn_in (dynobj, dyncon, &internal_dyn);
2473 
2474 	  switch (internal_dyn.d_tag)
2475 	    {
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;
2486 	    }
2487 
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))
2492 	    {
2493 	      asection	     *asec_ptr;
2494 
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)
2498 		{
2499 		  internal_dyn.d_un.d_val +=
2500 		    (asec_ptr->output_section->vma
2501 		     + asec_ptr->output_offset);
2502 		}
2503 	      else
2504 		{
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;
2508 		}
2509 	      do_it = TRUE;
2510 	    }
2511 	  else if (s != NULL) /* With a section information.  */
2512 	    {
2513 	      switch (internal_dyn.d_tag)
2514 		{
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;
2524 
2525 		  case DT_PLTRELSZ:
2526 		    internal_dyn.d_un.d_val = s->size;
2527 		    do_it = TRUE;
2528 		    break;
2529 
2530 		  default:
2531 		    break;
2532 		}
2533 	    }
2534 
2535 	  if (do_it)
2536 	    bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon);
2537 	}
2538 
2539       if (htab->splt->size > 0)
2540 	{
2541 	  relocate_plt_for_entry (output_bfd, info);
2542 	}
2543 
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;
2548     }
2549 
2550   /* Fill in the first three entries in the global offset table.  */
2551   if (htab->sgot)
2552     {
2553       struct elf_link_hash_entry *h;
2554       h = elf_link_hash_lookup (elf_hash_table (info), "_GLOBAL_OFFSET_TABLE_",
2555 				 FALSE, FALSE, TRUE);
2556 
2557 	if (h != NULL && h->root.type != bfd_link_hash_undefined
2558 	    && h->root.u.def.section != NULL)
2559 	{
2560 	  asection *sec = h->root.u.def.section;
2561 
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);
2571 	}
2572     }
2573 
2574   return TRUE;
2575 }
2576 
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;
2583 
2584 /* Set the sizes of the dynamic sections.  */
2585 static bfd_boolean
elf_arc_size_dynamic_sections(bfd * output_bfd ATTRIBUTE_UNUSED,struct bfd_link_info * info)2586 elf_arc_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2587 			       struct bfd_link_info *info)
2588 {
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);
2594 
2595   dynobj = htab->dynobj;
2596   BFD_ASSERT (dynobj != NULL);
2597 
2598   if (htab->dynamic_sections_created)
2599     {
2600       struct elf_link_hash_entry *h;
2601 
2602       /* Set the contents of the .interp section to the
2603 	 interpreter.  */
2604       if (bfd_link_executable (info) && !info->nointerp)
2605 	{
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;
2610 	}
2611 
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);
2620     }
2621   else
2622     {
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;
2630     }
2631 
2632   for (s = dynobj->sections; s != NULL; s = s->next)
2633     {
2634       if ((s->flags & SEC_LINKER_CREATED) == 0)
2635 	continue;
2636 
2637       if (s == htab->splt
2638 	  || s == htab->sgot
2639 	  || s == htab->sgotplt
2640 	  || s == htab->sdynbss)
2641 	{
2642 	  /* Strip this section if we don't need it.  */
2643 	}
2644       else if (strncmp (s->name, ".rela", 5) == 0)
2645 	{
2646 	  if (s->size != 0 && s != htab->srelplt)
2647 	    {
2648 	      if (!reltext_exist)
2649 		{
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)
2655 		      {
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)))
2662 			  {
2663 			    reltext_exist = TRUE;
2664 			    break;
2665 			  }
2666 		      }
2667 		}
2668 	      relocs_exist = TRUE;
2669 	    }
2670 
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;
2674 	}
2675       else
2676 	{
2677 	  /* It's not one of our sections, so don't allocate space.  */
2678 	  continue;
2679 	}
2680 
2681       if (s->size == 0)
2682 	{
2683 	  s->flags |= SEC_EXCLUDE;
2684 	  continue;
2685 	}
2686 
2687       if ((s->flags & SEC_HAS_CONTENTS) == 0)
2688 	continue;
2689 
2690       /* Allocate memory for the section contents.  */
2691       s->contents = bfd_zalloc (dynobj, s->size);
2692       if (s->contents == NULL)
2693 	return FALSE;
2694     }
2695 
2696   if (htab->dynamic_sections_created)
2697     {
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;
2702 
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;
2709 
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;
2716 
2717       if (reltext_exist)
2718 	if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
2719 	  return FALSE;
2720     }
2721 
2722   return TRUE;
2723 }
2724 
2725 
2726 /* Classify dynamic relocs such that -z combreloc can reorder and combine
2727    them.  */
2728 static enum elf_reloc_type_class
elf32_arc_reloc_type_class(const struct bfd_link_info * info ATTRIBUTE_UNUSED,const asection * rel_sec ATTRIBUTE_UNUSED,const Elf_Internal_Rela * rela)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)
2732 {
2733   switch ((int) ELF32_R_TYPE (rela->r_info))
2734     {
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.  */
2742     /*
2743     case R_ARC_IRELATIVE:
2744       return reloc_class_ifunc;
2745     */
2746     default:
2747       return reloc_class_normal;
2748     }
2749 }
2750 
2751 const struct elf_size_info arc_elf32_size_info =
2752 {
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),
2761   4,
2762   1,
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
2779 };
2780 
2781 #define elf_backend_size_info		arc_elf32_size_info
2782 
2783 /* Hook called by the linker routine which adds symbols from an object
2784    file.  */
2785 
2786 static bfd_boolean
elf_arc_add_symbol_hook(bfd * abfd,struct bfd_link_info * info,Elf_Internal_Sym * sym,const char ** namep ATTRIBUTE_UNUSED,flagword * flagsp ATTRIBUTE_UNUSED,asection ** secp ATTRIBUTE_UNUSED,bfd_vma * valp ATTRIBUTE_UNUSED)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)
2794 {
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;
2799 
2800   return TRUE;
2801 }
2802 
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.  */
2809 
2810 static bfd_boolean
elf32_arc_grok_prstatus(bfd * abfd,Elf_Internal_Note * note)2811 elf32_arc_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
2812 {
2813   int offset;
2814   size_t size;
2815 
2816   switch (note->descsz)
2817     {
2818     default:
2819       return FALSE;
2820 
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;
2830     }
2831   /* Make a ".reg/999" section.  */
2832   return _bfd_elfcore_make_pseudosection (abfd, ".reg", size,
2833 					  note->descpos + offset);
2834 }
2835 
2836 /* Determine whether an object attribute tag takes an integer, a
2837    string or both.  */
2838 
2839 static int
elf32_arc_obj_attrs_arg_type(int tag)2840 elf32_arc_obj_attrs_arg_type (int tag)
2841 {
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;
2850 }
2851 
2852 /* Attribute numbers >=14 can be safely ignored.  */
2853 
2854 static bfd_boolean
elf32_arc_obj_attrs_handle_unknown(bfd * abfd,int tag)2855 elf32_arc_obj_attrs_handle_unknown (bfd *abfd, int tag)
2856 {
2857   if ((tag & 127) < (Tag_ARC_ISA_mpy_option + 1))
2858     {
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;
2864     }
2865   else
2866     {
2867       _bfd_error_handler
2868 	(_("Warning: %B: Unknown ARC object attribute %d."),
2869 	 abfd, tag);
2870       return TRUE;
2871     }
2872 }
2873 
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.  */
2877 
2878 static bfd_boolean
elf32_arc_section_from_shdr(bfd * abfd,Elf_Internal_Shdr * hdr,const char * name,int shindex)2879 elf32_arc_section_from_shdr (bfd *abfd,
2880 			     Elf_Internal_Shdr * hdr,
2881 			     const char *name,
2882 			     int shindex)
2883 {
2884   switch (hdr->sh_type)
2885     {
2886     case SHT_ARC_ATTRIBUTES:
2887       break;
2888 
2889     default:
2890       return FALSE;
2891     }
2892 
2893   if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
2894     return FALSE;
2895 
2896   return TRUE;
2897 }
2898 
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
2908 
2909 #define bfd_elf32_bfd_link_hash_table_create	arc_elf_link_hash_table_create
2910 
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
2916 
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
2920 
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
2924 
2925 #define elf_backend_reloc_type_class		elf32_arc_reloc_type_class
2926 
2927 #define elf_backend_adjust_dynamic_symbol    elf_arc_adjust_dynamic_symbol
2928 #define elf_backend_finish_dynamic_symbol    elf_arc_finish_dynamic_symbol
2929 
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
2933 
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
2941 
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
2945 
2946 #define elf_backend_grok_prstatus elf32_arc_grok_prstatus
2947 
2948 #define elf_backend_default_execstack	0
2949 
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
2959 
2960 #define elf_backend_section_from_shdr		elf32_arc_section_from_shdr
2961 
2962 #include "elf32-target.h"
2963