1/* ARC-specific support for 32-bit ELF
2   Copyright (C) 1994-2020 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
38static const char *
39name_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#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
75      case VALUE: \
76	return "R_" #TYPE; \
77	break;
78
79static ATTRIBUTE_UNUSED const char *
80reloc_type_to_name (unsigned int type)
81{
82  switch (type)
83    {
84#include "elf/arc-reloc.def"
85
86    default:
87      return "UNKNOWN";
88      break;
89    }
90}
91
92#undef ARC_RELOC_HOWTO
93
94/* Try to minimize the amount of space occupied by relocation tables
95   on the ROM (not that the ROM won't be swamped by other ELF overhead).  */
96
97#define USE_REL 1
98
99/* Similar with bfd_get_32 but taking into account the
100   middle-endianess of the ARC CPUs.  Only to be used in code
101   sections.  */
102
103static bfd_vma
104bfd_get_32_me (bfd * abfd,const unsigned char * data)
105{
106  bfd_vma value = 0;
107
108  if (bfd_big_endian (abfd))
109    value = bfd_get_32 (abfd, data);
110  else
111    {
112      value = ((bfd_get_8 (abfd, data) & 255) << 16);
113      value |= ((bfd_get_8 (abfd, data + 1) & 255) << 24);
114      value |= (bfd_get_8 (abfd, data + 2) & 255);
115      value |= ((bfd_get_8 (abfd, data + 3) & 255) << 8);
116    }
117
118  return value;
119}
120
121static void
122bfd_put_32_me (bfd *abfd, bfd_vma value,unsigned char *data)
123{
124  bfd_put_16 (abfd, (value & 0xffff0000) >> 16, data);
125  bfd_put_16 (abfd, value & 0xffff, data + 2);
126}
127
128static ATTRIBUTE_UNUSED bfd_boolean
129is_reloc_PC_relative (reloc_howto_type *howto)
130{
131  return (strstr (howto->name, "PC") != NULL) ? TRUE : FALSE;
132}
133
134static bfd_boolean
135is_reloc_SDA_relative (reloc_howto_type *howto)
136{
137  return (strstr (howto->name, "SDA") != NULL) ? TRUE : FALSE;
138}
139
140static bfd_boolean
141is_reloc_for_GOT (reloc_howto_type * howto)
142{
143  if (strstr (howto->name, "TLS") != NULL)
144    return FALSE;
145  return (strstr (howto->name, "GOT") != NULL) ? TRUE : FALSE;
146}
147
148static bfd_boolean
149is_reloc_for_PLT (reloc_howto_type * howto)
150{
151  return (strstr (howto->name, "PLT") != NULL) ? TRUE : FALSE;
152}
153
154static bfd_boolean
155is_reloc_for_TLS (reloc_howto_type *howto)
156{
157  return (strstr (howto->name, "TLS") != NULL) ? TRUE : FALSE;
158}
159
160struct arc_relocation_data
161{
162  bfd_signed_vma  reloc_offset;
163  bfd_signed_vma  reloc_addend;
164  bfd_signed_vma  got_offset_value;
165
166  bfd_signed_vma  sym_value;
167  asection *	  sym_section;
168
169  reloc_howto_type *howto;
170
171  asection *	  input_section;
172
173  bfd_signed_vma  sdata_begin_symbol_vma;
174  bfd_boolean	  sdata_begin_symbol_vma_set;
175  bfd_signed_vma  got_symbol_vma;
176
177  bfd_boolean	  should_relocate;
178
179  const char *    symbol_name;
180};
181
182/* ARC ELF linker hash entry.  */
183struct elf_arc_link_hash_entry
184{
185  struct elf_link_hash_entry root;
186
187  /* Track dynamic relocs copied for this symbol.  */
188  struct elf_dyn_relocs *dyn_relocs;
189
190  struct got_entry *got_ents;
191};
192
193
194/* Should be included at this location due to static declarations
195   defined before this point.  */
196#include "arc-got.h"
197
198#define arc_bfd_get_8(A,B,C) bfd_get_8(A,B)
199#define arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
200#define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
201#define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C)
202#define arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
203#define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)
204
205
206static bfd_reloc_status_type
207arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
208	       arelent *reloc_entry,
209	       asymbol *symbol_in,
210	       void *data ATTRIBUTE_UNUSED,
211	       asection *input_section,
212	       bfd *output_bfd,
213	       char ** error_message ATTRIBUTE_UNUSED)
214{
215  if (output_bfd != NULL)
216    {
217      reloc_entry->address += input_section->output_offset;
218
219      /* In case of relocateable link and if the reloc is against a
220	 section symbol, the addend needs to be adjusted according to
221	 where the section symbol winds up in the output section.  */
222      if ((symbol_in->flags & BSF_SECTION_SYM) && symbol_in->section)
223	reloc_entry->addend += symbol_in->section->output_offset;
224
225      return bfd_reloc_ok;
226    }
227
228  return bfd_reloc_continue;
229}
230
231
232#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
233  TYPE = VALUE,
234
235enum howto_list
236{
237#include "elf/arc-reloc.def"
238  HOWTO_LIST_LAST
239};
240
241#undef ARC_RELOC_HOWTO
242
243#define ARC_RELOC_HOWTO(TYPE, VALUE, RSIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
244  [TYPE] = HOWTO (R_##TYPE, 0, RSIZE, BITSIZE, FALSE, 0,		\
245		  complain_overflow_##OVERFLOW, arc_elf_reloc,		\
246		  "R_" #TYPE, FALSE, 0, 0, FALSE),
247
248static struct reloc_howto_struct elf_arc_howto_table[] =
249{
250#include "elf/arc-reloc.def"
251/* Example of what is generated by the preprocessor.  Currently kept as an
252   example.
253 HOWTO (R_ARC_NONE, // Type.
254    0, // Rightshift.
255    2, // Size (0 = byte, 1 = short, 2 = long).
256    32, // Bitsize.
257    FALSE, // PC_relative.
258    0, // Bitpos.
259    complain_overflow_bitfield, // Complain_on_overflow.
260    bfd_elf_generic_reloc, // Special_function.
261    "R_ARC_NONE", // Name.
262    TRUE, // Partial_inplace.
263    0, // Src_mask.
264    0, // Dst_mask.
265    FALSE), // PCrel_offset.
266*/
267};
268#undef ARC_RELOC_HOWTO
269
270static void
271arc_elf_howto_init (void)
272{
273#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
274  elf_arc_howto_table[TYPE].pc_relative =				\
275    (strstr (#FORMULA, " P ") != NULL || strstr (#FORMULA, " PDATA ") != NULL); \
276  elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0);		\
277  /* Only 32 bit data relocations should be marked as ME.  */		\
278  if (strstr (#FORMULA, " ME ") != NULL)				\
279    {									\
280      BFD_ASSERT (SIZE == 2);						\
281    }
282
283#include "elf/arc-reloc.def"
284
285}
286#undef ARC_RELOC_HOWTO
287
288
289#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
290  [TYPE] = VALUE,
291
292const int howto_table_lookup[] =
293{
294#include "elf/arc-reloc.def"
295};
296
297#undef ARC_RELOC_HOWTO
298
299static reloc_howto_type *
300arc_elf_howto (unsigned int r_type)
301{
302  if (elf_arc_howto_table[R_ARC_32].dst_mask == 0)
303    arc_elf_howto_init ();
304  return &elf_arc_howto_table[r_type];
305}
306
307/* Map BFD reloc types to ARC ELF reloc types.  */
308
309struct arc_reloc_map
310{
311  bfd_reloc_code_real_type  bfd_reloc_val;
312  unsigned char		    elf_reloc_val;
313};
314
315/* ARC ELF linker hash table.  */
316struct elf_arc_link_hash_table
317{
318  struct elf_link_hash_table elf;
319};
320
321static struct bfd_hash_entry *
322elf_arc_link_hash_newfunc (struct bfd_hash_entry *entry,
323			   struct bfd_hash_table *table,
324			   const char *string)
325{
326  struct elf_arc_link_hash_entry * ret =
327    (struct elf_arc_link_hash_entry *) entry;
328
329  /* Allocate the structure if it has not already been allocated by a
330     subclass.  */
331  if (ret == NULL)
332    ret = (struct elf_arc_link_hash_entry *)
333	bfd_hash_allocate (table, sizeof (struct elf_arc_link_hash_entry));
334  if (ret == NULL)
335    return (struct bfd_hash_entry *) ret;
336
337  /* Call the allocation method of the superclass.  */
338  ret = ((struct elf_arc_link_hash_entry *)
339	 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
340				     table, string));
341  if (ret != NULL)
342    {
343      ret->dyn_relocs = NULL;
344      ret->got_ents = NULL;
345    }
346
347  return (struct bfd_hash_entry *) ret;
348}
349
350/* Destroy an ARC ELF linker hash table.  */
351static void
352elf_arc_link_hash_table_free (bfd *obfd)
353{
354  _bfd_elf_link_hash_table_free (obfd);
355}
356
357/* Create an ARC ELF linker hash table.  */
358
359static struct bfd_link_hash_table *
360arc_elf_link_hash_table_create (bfd *abfd)
361{
362  struct elf_arc_link_hash_table *ret;
363
364  ret = (struct elf_arc_link_hash_table *) bfd_zmalloc (sizeof (*ret));
365  if (ret == NULL)
366    return NULL;
367
368  if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
369				      elf_arc_link_hash_newfunc,
370				      sizeof (struct elf_arc_link_hash_entry),
371				      ARC_ELF_DATA))
372    {
373      free (ret);
374      return NULL;
375    }
376
377  ret->elf.root.hash_table_free = elf_arc_link_hash_table_free;
378
379  return &ret->elf.root;
380}
381
382#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
383  { BFD_RELOC_##TYPE, R_##TYPE },
384
385static const struct arc_reloc_map arc_reloc_map[] =
386{
387#include "elf/arc-reloc.def"
388
389  {BFD_RELOC_NONE,  R_ARC_NONE},
390  {BFD_RELOC_8,  R_ARC_8},
391  {BFD_RELOC_16, R_ARC_16},
392  {BFD_RELOC_24, R_ARC_24},
393  {BFD_RELOC_32, R_ARC_32},
394};
395
396#undef ARC_RELOC_HOWTO
397
398typedef ATTRIBUTE_UNUSED bfd_vma (*replace_func) (unsigned, int ATTRIBUTE_UNUSED);
399
400#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
401  case TYPE: \
402    func = (void *) RELOC_FUNCTION; \
403    break;
404
405static replace_func
406get_replace_function (bfd *abfd, unsigned int r_type)
407{
408  void *func = NULL;
409
410  switch (r_type)
411    {
412      #include "elf/arc-reloc.def"
413    }
414
415  if (func == replace_bits24 && bfd_big_endian (abfd))
416    func = replace_bits24_be;
417
418  return (replace_func) func;
419}
420#undef ARC_RELOC_HOWTO
421
422static reloc_howto_type *
423arc_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
424				 bfd_reloc_code_real_type code)
425{
426  unsigned int i;
427
428  for (i = ARRAY_SIZE (arc_reloc_map); i--;)
429    {
430      if (arc_reloc_map[i].bfd_reloc_val == code)
431	return arc_elf_howto (arc_reloc_map[i].elf_reloc_val);
432    }
433
434  return NULL;
435}
436
437/* Function to set the ELF flag bits.  */
438static bfd_boolean
439arc_elf_set_private_flags (bfd *abfd, flagword flags)
440{
441  elf_elfheader (abfd)->e_flags = flags;
442  elf_flags_init (abfd) = TRUE;
443  return TRUE;
444}
445
446/* Print private flags.  */
447static bfd_boolean
448arc_elf_print_private_bfd_data (bfd *abfd, void * ptr)
449{
450  FILE *file = (FILE *) ptr;
451  flagword flags;
452
453  BFD_ASSERT (abfd != NULL && ptr != NULL);
454
455  /* Print normal ELF private data.  */
456  _bfd_elf_print_private_bfd_data (abfd, ptr);
457
458  flags = elf_elfheader (abfd)->e_flags;
459  fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
460
461  switch (flags & EF_ARC_MACH_MSK)
462    {
463    case EF_ARC_CPU_ARCV2HS : fprintf (file, " -mcpu=ARCv2HS");    break;
464    case EF_ARC_CPU_ARCV2EM : fprintf (file, " -mcpu=ARCv2EM");    break;
465    case E_ARC_MACH_ARC600  : fprintf (file, " -mcpu=ARC600");     break;
466    case E_ARC_MACH_ARC601  : fprintf (file, " -mcpu=ARC601");     break;
467    case E_ARC_MACH_ARC700  : fprintf (file, " -mcpu=ARC700");     break;
468    default:
469      fprintf (file, "-mcpu=unknown");
470      break;
471    }
472
473  switch (flags & EF_ARC_OSABI_MSK)
474    {
475    case E_ARC_OSABI_ORIG : fprintf (file, " (ABI:legacy)"); break;
476    case E_ARC_OSABI_V2   : fprintf (file, " (ABI:v2)");     break;
477    case E_ARC_OSABI_V3   : fprintf (file, " (ABI:v3)");     break;
478    case E_ARC_OSABI_V4   : fprintf (file, " (ABI:v4)");     break;
479    default:
480      fprintf (file, " (ABI:unknown)");
481      break;
482    }
483
484  fputc ('\n', file);
485  return TRUE;
486}
487
488/* Copy backend specific data from one object module to another.  */
489
490static bfd_boolean
491arc_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
492{
493  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
494      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
495    return TRUE;
496
497  BFD_ASSERT (!elf_flags_init (obfd)
498	      || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
499
500  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
501  elf_flags_init (obfd) = TRUE;
502
503  /* Copy object attributes.  */
504  _bfd_elf_copy_obj_attributes (ibfd, obfd);
505
506  return _bfd_elf_copy_private_bfd_data (ibfd, obfd);
507}
508
509static reloc_howto_type *
510bfd_elf32_bfd_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED,
511				 const char *r_name)
512{
513  unsigned int i;
514
515  for (i = 0; i < ARRAY_SIZE (elf_arc_howto_table); i++)
516    if (elf_arc_howto_table[i].name != NULL
517	&& strcasecmp (elf_arc_howto_table[i].name, r_name) == 0)
518      return arc_elf_howto (i);
519
520  return NULL;
521}
522
523/* Set the howto pointer for an ARC ELF reloc.  */
524
525static bfd_boolean
526arc_info_to_howto_rel (bfd * abfd,
527		       arelent * cache_ptr,
528		       Elf_Internal_Rela * dst)
529{
530  unsigned int r_type;
531
532  r_type = ELF32_R_TYPE (dst->r_info);
533  if (r_type >= (unsigned int) R_ARC_max)
534    {
535      /* xgettext:c-format */
536      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
537			  abfd, r_type);
538      bfd_set_error (bfd_error_bad_value);
539      return FALSE;
540    }
541
542  cache_ptr->howto = arc_elf_howto (r_type);
543  return TRUE;
544}
545
546/* Extract CPU features from an NTBS.  */
547
548static unsigned
549arc_extract_features (const char *p)
550{
551  unsigned i, r = 0;
552
553  if (!p)
554    return 0;
555
556  for (i = 0; i < ARRAY_SIZE (bfd_feature_list); i++)
557    {
558      char *t = strstr (p, bfd_feature_list[i].attr);
559      unsigned l = strlen (bfd_feature_list[i].attr);
560      if ((t != NULL)
561	  && (t[l] == ','
562	      || t[l] == '\0'))
563	r |= bfd_feature_list[i].feature;
564    }
565
566  return r;
567}
568
569/* Concatenate two strings.  s1 can be NULL but not
570   s2.  */
571
572static char *
573arc_stralloc (char * s1, const char * s2)
574{
575  char *p;
576
577  /* Only s1 can be null.  */
578  BFD_ASSERT (s2);
579
580  p = s1 ? concat (s1, ",", s2, NULL) : (char *)s2;
581
582  return p;
583}
584
585/* Merge ARC object attributes from IBFD into OBFD.  Raise an error if
586   there are conflicting attributes.  */
587
588static bfd_boolean
589arc_elf_merge_attributes (bfd *ibfd, struct bfd_link_info *info)
590{
591  bfd *obfd = info->output_bfd;
592  obj_attribute *in_attr;
593  obj_attribute *out_attr;
594  int i;
595  bfd_boolean result = TRUE;
596  const char *sec_name = get_elf_backend_data (ibfd)->obj_attrs_section;
597  char *tagname = NULL;
598
599  /* Skip the linker stubs file.  This preserves previous behavior
600     of accepting unknown attributes in the first input file - but
601     is that a bug?  */
602  if (ibfd->flags & BFD_LINKER_CREATED)
603    return TRUE;
604
605  /* Skip any input that hasn't attribute section.
606     This enables to link object files without attribute section with
607     any others.  */
608  if (bfd_get_section_by_name (ibfd, sec_name) == NULL)
609    return TRUE;
610
611  if (!elf_known_obj_attributes_proc (obfd)[0].i)
612    {
613      /* This is the first object.  Copy the attributes.  */
614      _bfd_elf_copy_obj_attributes (ibfd, obfd);
615
616      out_attr = elf_known_obj_attributes_proc (obfd);
617
618      /* Use the Tag_null value to indicate the attributes have been
619	 initialized.  */
620      out_attr[0].i = 1;
621
622      return TRUE;
623    }
624
625  in_attr = elf_known_obj_attributes_proc (ibfd);
626  out_attr = elf_known_obj_attributes_proc (obfd);
627
628  for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
629    {
630      /* Merge this attribute with existing attributes.  */
631      switch (i)
632	{
633	case Tag_ARC_PCS_config:
634	  if (out_attr[i].i == 0)
635	    out_attr[i].i = in_attr[i].i;
636	  else if (in_attr[i].i != 0 && out_attr[i].i != in_attr[i].i)
637	    {
638	      const char *tagval[] = { "Absent", "Bare-metal/mwdt",
639					"Bare-metal/newlib", "Linux/uclibc",
640					"Linux/glibc" };
641	      BFD_ASSERT (in_attr[i].i < 5);
642	      BFD_ASSERT (out_attr[i].i < 5);
643	      /* It's sometimes ok to mix different configs, so this is only
644		 a warning.  */
645	      _bfd_error_handler
646		(_("warning: %pB: conflicting platform configuration "
647		   "%s with %s"), ibfd,
648		 tagval[in_attr[i].i],
649		 tagval[out_attr[i].i]);
650	    }
651	  break;
652
653	case Tag_ARC_CPU_base:
654	  if (out_attr[i].i == 0)
655	    out_attr[i].i = in_attr[i].i;
656	  else if (in_attr[i].i != 0 && out_attr[i].i != in_attr[i].i
657		   && ((out_attr[i].i + in_attr[i].i) < 6))
658	    {
659	      const char *tagval[] = { "Absent", "ARC6xx", "ARC7xx",
660					"ARCEM", "ARCHS" };
661	      BFD_ASSERT (in_attr[i].i < 5);
662	      BFD_ASSERT (out_attr[i].i < 5);
663	      /* We cannot mix code for different CPUs.  */
664	      _bfd_error_handler
665		(_("error: %pB: unable to merge CPU base attributes "
666		   "%s with %s"),
667		 obfd,
668		 tagval[in_attr[i].i],
669		 tagval[out_attr[i].i]);
670	      result = FALSE;
671	      break;
672	    }
673	  else
674	    {
675	      /* The CPUs may be different, check if we can still mix
676		 the objects against the output choosen CPU.  */
677	      unsigned in_feature = 0;
678	      unsigned out_feature = 0;
679	      char *p1 = in_attr[Tag_ARC_ISA_config].s;
680	      char *p2 = out_attr[Tag_ARC_ISA_config].s;
681	      unsigned j;
682	      unsigned cpu_out;
683	      unsigned opcode_map[] = {0, ARC_OPCODE_ARC600, ARC_OPCODE_ARC700,
684				       ARC_OPCODE_ARCv2EM, ARC_OPCODE_ARCv2HS};
685
686	      BFD_ASSERT (in_attr[i].i < (sizeof (opcode_map)
687					  / sizeof (unsigned)));
688	      BFD_ASSERT (out_attr[i].i < (sizeof (opcode_map)
689					   / sizeof (unsigned)));
690	      cpu_out = opcode_map[out_attr[i].i];
691
692	      in_feature = arc_extract_features (p1);
693	      out_feature = arc_extract_features (p2);
694
695	      /* First, check if a feature is compatible with the
696		 output object chosen CPU.  */
697	      for (j = 0; j < ARRAY_SIZE (bfd_feature_list); j++)
698		if (((in_feature | out_feature) & bfd_feature_list[j].feature)
699		    && (!(cpu_out & bfd_feature_list[j].cpus)))
700		  {
701		    _bfd_error_handler
702		      (_("error: %pB: unable to merge ISA extension attributes "
703			 "%s"),
704		       obfd, bfd_feature_list[j].name);
705		    result = FALSE;
706		    break;
707		  }
708	      /* Second, if we have compatible features with the
709		 chosen CPU, check if they are compatible among
710		 them.  */
711	      for (j = 0; j < ARRAY_SIZE (bfd_conflict_list); j++)
712		if (((in_feature | out_feature) & bfd_conflict_list[j])
713		    == bfd_conflict_list[j])
714		  {
715		    unsigned k;
716		    for (k = 0; k < ARRAY_SIZE (bfd_feature_list); k++)
717		      {
718			if (in_feature &  bfd_feature_list[k].feature
719			    & bfd_conflict_list[j])
720			  p1 = (char *) bfd_feature_list[k].name;
721			if (out_feature &  bfd_feature_list[k].feature
722			    & bfd_conflict_list[j])
723			  p2 = (char *) bfd_feature_list[k].name;
724		      }
725		    _bfd_error_handler
726		      (_("error: %pB: conflicting ISA extension attributes "
727			 "%s with %s"),
728		       obfd, p1, p2);
729		    result = FALSE;
730		    break;
731		  }
732	      /* Everithing is alright.  */
733	      out_feature |= in_feature;
734	      p1 = NULL;
735	      for (j = 0; j < ARRAY_SIZE (bfd_feature_list); j++)
736		if (out_feature & bfd_feature_list[j].feature)
737		  p1 = arc_stralloc (p1, bfd_feature_list[j].attr);
738	      if (p1)
739		out_attr[Tag_ARC_ISA_config].s =
740		  _bfd_elf_attr_strdup (obfd, p1);
741	    }
742	  /* Fall through.  */
743	case Tag_ARC_CPU_variation:
744	case Tag_ARC_ISA_mpy_option:
745	case Tag_ARC_ABI_osver:
746	  /* Use the largest value specified.  */
747	  if (in_attr[i].i > out_attr[i].i)
748	    out_attr[i].i = in_attr[i].i;
749	  break;
750
751	  /* The CPU name is given by the vendor, just choose an
752	     existing one if missing or different.  There are no fail
753	     criteria if they different or both missing.  */
754	case Tag_ARC_CPU_name:
755	  if (!out_attr[i].s && in_attr[i].s)
756	    out_attr[i].s = _bfd_elf_attr_strdup (obfd, in_attr[i].s);
757	  break;
758
759	case Tag_ARC_ABI_rf16:
760	  if (out_attr[i].i == 0)
761	    out_attr[i].i = in_attr[i].i;
762	  else if (out_attr[i].i != in_attr[i].i)
763	    {
764	      /* We cannot mix code with rf16 and without.  */
765	      _bfd_error_handler
766		(_("error: %pB: cannot mix rf16 with full register set %pB"),
767		 obfd, ibfd);
768	      result = FALSE;
769	    }
770	  break;
771
772	case Tag_ARC_ABI_pic:
773	  tagname = "PIC";
774	  /* fall through */
775	case Tag_ARC_ABI_sda:
776	  if (!tagname)
777	    tagname = "SDA";
778	  /* fall through */
779	case Tag_ARC_ABI_tls:
780	  {
781	    const char *tagval[] = { "Absent", "MWDT", "GNU" };
782
783	    if (!tagname)
784	      tagname = "TLS";
785
786	    BFD_ASSERT (in_attr[i].i < 3);
787	    BFD_ASSERT (out_attr[i].i < 3);
788	    if (out_attr[i].i == 0)
789	      out_attr[i].i = in_attr[i].i;
790	    else if (out_attr[i].i != 0 && in_attr[i].i != 0
791		&& out_attr[i].i != in_attr[i].i)
792	      {
793		_bfd_error_handler
794		  (_("error: %pB: conflicting attributes %s: %s with %s"),
795		   obfd, tagname,
796		   tagval[in_attr[i].i],
797		   tagval[out_attr[i].i]);
798		result = FALSE;
799	      }
800	    tagname = NULL;
801	    break;
802	  }
803
804	case Tag_ARC_ABI_double_size:
805	  tagname = "Double size";
806	  /* fall through */
807	case Tag_ARC_ABI_enumsize:
808	  if (!tagname)
809	    tagname = "Enum size";
810	  /* fall through */
811	case Tag_ARC_ABI_exceptions:
812	  if (!tagname)
813	    tagname = "ABI exceptions";
814
815	  if (out_attr[i].i == 0)
816	    out_attr[i].i = in_attr[i].i;
817	  else if (out_attr[i].i != 0 && in_attr[i].i != 0
818	      && out_attr[i].i != in_attr[i].i)
819	    {
820	      _bfd_error_handler
821		(_("error: %pB: conflicting attributes %s"),
822		 obfd, tagname);
823	      result = FALSE;
824	    }
825	  break;
826
827	case Tag_ARC_ISA_apex:
828	  break; /* Do nothing for APEX attributes.  */
829
830	case Tag_ARC_ISA_config:
831	  /* It is handled in Tag_ARC_CPU_base.  */
832	  break;
833
834	case Tag_ARC_ATR_version:
835	  if (out_attr[i].i == 0)
836	    out_attr[i].i = in_attr[i].i;
837	  break;
838
839	default:
840	  result
841	    = result && _bfd_elf_merge_unknown_attribute_low (ibfd, obfd, i);
842	}
843
844      /* If out_attr was copied from in_attr then it won't have a type yet.  */
845      if (in_attr[i].type && !out_attr[i].type)
846	out_attr[i].type = in_attr[i].type;
847    }
848
849  /* Merge Tag_compatibility attributes and any common GNU ones.  */
850  if (!_bfd_elf_merge_object_attributes (ibfd, info))
851    return FALSE;
852
853  /* Check for any attributes not known on ARC.  */
854  result &= _bfd_elf_merge_unknown_attribute_list (ibfd, obfd);
855
856  return result;
857}
858
859/* Merge backend specific data from an object file to the output
860   object file when linking.  */
861
862static bfd_boolean
863arc_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
864{
865  bfd *obfd = info->output_bfd;
866  unsigned short mach_ibfd;
867  static unsigned short mach_obfd = EM_NONE;
868  flagword out_flags;
869  flagword in_flags;
870  asection *sec;
871
872   /* Check if we have the same endianess.  */
873  if (! _bfd_generic_verify_endian_match (ibfd, info))
874    return FALSE;
875
876  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
877      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
878    return TRUE;
879
880  /* Collect ELF flags.  */
881  in_flags = elf_elfheader (ibfd)->e_flags & EF_ARC_MACH_MSK;
882  out_flags = elf_elfheader (obfd)->e_flags & EF_ARC_MACH_MSK;
883
884  if (!elf_flags_init (obfd)) /* First call, no flags set.  */
885    {
886      elf_flags_init (obfd) = TRUE;
887      out_flags = in_flags;
888    }
889
890  if (!arc_elf_merge_attributes (ibfd, info))
891    return FALSE;
892
893  /* Check to see if the input BFD actually contains any sections.  Do
894     not short-circuit dynamic objects; their section list may be
895     emptied by elf_link_add_object_symbols.  */
896  if (!(ibfd->flags & DYNAMIC))
897    {
898      bfd_boolean null_input_bfd = TRUE;
899      bfd_boolean only_data_sections = TRUE;
900
901      for (sec = ibfd->sections; sec != NULL; sec = sec->next)
902	{
903	  if ((bfd_section_flags (sec)
904	       & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
905	      == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
906	    only_data_sections = FALSE;
907
908	  null_input_bfd = FALSE;
909	}
910
911      if (null_input_bfd || only_data_sections)
912	return TRUE;
913    }
914
915  /* Complain about various flag/architecture mismatches.  */
916  mach_ibfd = elf_elfheader (ibfd)->e_machine;
917  if (mach_obfd == EM_NONE)
918    {
919      mach_obfd = mach_ibfd;
920    }
921  else
922    {
923      if (mach_ibfd != mach_obfd)
924	{
925	  /* xgettext:c-format */
926	  _bfd_error_handler (_("error: attempting to link %pB "
927				"with a binary %pB of different architecture"),
928			      ibfd, obfd);
929	  return FALSE;
930	}
931      else if ((in_flags != out_flags)
932	       /* If we have object attributes, then we already
933		  checked the objects compatibility, skip it.  */
934	       && !bfd_elf_get_obj_attr_int (ibfd, OBJ_ATTR_PROC,
935					     Tag_ARC_CPU_base))
936	{
937	  if (in_flags && out_flags)
938	    {
939	      /* Warn if different flags.  */
940	      _bfd_error_handler
941		/* xgettext:c-format */
942		(_("%pB: uses different e_flags (%#x) fields than "
943		   "previous modules (%#x)"),
944		 ibfd, in_flags, out_flags);
945	      return FALSE;
946	    }
947	  /* MWDT doesnt set the eflags hence make sure we choose the
948	     eflags set by gcc.  */
949	  in_flags = in_flags > out_flags ? in_flags : out_flags;
950	}
951      else
952	{
953	  /* Everything is correct; don't change the output flags.  */
954	  in_flags = out_flags;
955	}
956    }
957
958  /* Update the flags.  */
959  elf_elfheader (obfd)->e_flags = in_flags;
960
961  if (bfd_get_mach (obfd) < bfd_get_mach (ibfd))
962    {
963      return bfd_set_arch_mach (obfd, bfd_arch_arc, bfd_get_mach (ibfd));
964    }
965
966  return TRUE;
967}
968
969/* Return a best guess for the machine number based on the attributes.  */
970
971static unsigned int
972bfd_arc_get_mach_from_attributes (bfd * abfd)
973{
974  int arch = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_PROC, Tag_ARC_CPU_base);
975  unsigned e_machine = elf_elfheader (abfd)->e_machine;
976
977  switch (arch)
978    {
979    case TAG_CPU_ARC6xx:
980      return bfd_mach_arc_arc600;
981    case TAG_CPU_ARC7xx:
982      return bfd_mach_arc_arc700;
983    case TAG_CPU_ARCEM:
984    case TAG_CPU_ARCHS:
985      return bfd_mach_arc_arcv2;
986    default:
987      break;
988    }
989  return (e_machine == EM_ARC_COMPACT)
990    ? bfd_mach_arc_arc700 : bfd_mach_arc_arcv2;
991}
992
993/* Set the right machine number for an ARC ELF file.  */
994static bfd_boolean
995arc_elf_object_p (bfd * abfd)
996{
997  /* Make sure this is initialised, or you'll have the potential of passing
998     garbage---or misleading values---into the call to
999     bfd_default_set_arch_mach ().  */
1000  unsigned int	  mach = bfd_mach_arc_arc700;
1001  unsigned long   arch = elf_elfheader (abfd)->e_flags & EF_ARC_MACH_MSK;
1002  unsigned	  e_machine = elf_elfheader (abfd)->e_machine;
1003
1004  if (e_machine == EM_ARC_COMPACT || e_machine == EM_ARC_COMPACT2)
1005    {
1006      switch (arch)
1007	{
1008	case E_ARC_MACH_ARC600:
1009	  mach = bfd_mach_arc_arc600;
1010	  break;
1011	case E_ARC_MACH_ARC601:
1012	  mach = bfd_mach_arc_arc601;
1013	  break;
1014	case E_ARC_MACH_ARC700:
1015	  mach = bfd_mach_arc_arc700;
1016	  break;
1017	case EF_ARC_CPU_ARCV2HS:
1018	case EF_ARC_CPU_ARCV2EM:
1019	  mach = bfd_mach_arc_arcv2;
1020	  break;
1021	default:
1022	  mach = bfd_arc_get_mach_from_attributes (abfd);
1023	  break;
1024	}
1025    }
1026  else
1027    {
1028      if (e_machine == EM_ARC)
1029	{
1030	  _bfd_error_handler
1031	    (_("error: the ARC4 architecture is no longer supported"));
1032	  return FALSE;
1033	}
1034      else
1035	{
1036	  _bfd_error_handler
1037	    (_("warning: unset or old architecture flags; "
1038	       "use default machine"));
1039	}
1040    }
1041
1042  return bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach);
1043}
1044
1045/* The final processing done just before writing out an ARC ELF object file.
1046   This gets the ARC architecture right based on the machine number.  */
1047
1048static bfd_boolean
1049arc_elf_final_write_processing (bfd *abfd)
1050{
1051  unsigned long emf;
1052  int osver = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_PROC,
1053					Tag_ARC_ABI_osver);
1054  flagword e_flags = elf_elfheader (abfd)->e_flags & ~EF_ARC_OSABI_MSK;
1055
1056  switch (bfd_get_mach (abfd))
1057    {
1058    case bfd_mach_arc_arcv2:
1059      emf = EM_ARC_COMPACT2;
1060      break;
1061    default:
1062      emf = EM_ARC_COMPACT;
1063      break;
1064    }
1065
1066  elf_elfheader (abfd)->e_machine = emf;
1067
1068  /* Record whatever is the current syscall ABI version.  */
1069  if (osver)
1070    e_flags |= ((osver & 0x0f) << 8);
1071  else
1072    e_flags |= E_ARC_OSABI_V3;
1073
1074  elf_elfheader (abfd)->e_flags |= e_flags;
1075  return _bfd_elf_final_write_processing (abfd);
1076}
1077
1078#ifdef ARC_ENABLE_DEBUG
1079#define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
1080
1081static void
1082debug_arc_reloc (struct arc_relocation_data reloc_data)
1083{
1084  ARC_DEBUG ("Reloc type=%s, should_relocate = %s\n",
1085	     reloc_data.howto->name,
1086	     reloc_data.should_relocate ? "true" : "false");
1087  ARC_DEBUG ("  offset = 0x%x, addend = 0x%x\n",
1088	     (unsigned int) reloc_data.reloc_offset,
1089	     (unsigned int) reloc_data.reloc_addend);
1090  ARC_DEBUG (" Symbol:\n");
1091  ARC_DEBUG ("  value = 0x%08x\n",
1092	     (unsigned int) reloc_data.sym_value);
1093  if (reloc_data.sym_section != NULL)
1094    {
1095      ARC_DEBUG (" Symbol Section:\n");
1096      ARC_DEBUG ("  section name = %s, output_offset 0x%08x",
1097		 reloc_data.sym_section->name,
1098		 (unsigned int) reloc_data.sym_section->output_offset);
1099      if (reloc_data.sym_section->output_section != NULL)
1100	ARC_DEBUG (", output_section->vma = 0x%08x",
1101		   ((unsigned int) reloc_data.sym_section->output_section->vma));
1102      ARC_DEBUG ("\n");
1103      if (reloc_data.sym_section->owner
1104	  && reloc_data.sym_section->owner->filename)
1105	ARC_DEBUG ("  file: %s\n", reloc_data.sym_section->owner->filename);
1106    }
1107  else
1108    {
1109      ARC_DEBUG ("  symbol section is NULL\n");
1110    }
1111
1112  ARC_DEBUG (" Input_section:\n");
1113  if (reloc_data.input_section != NULL)
1114    {
1115      ARC_DEBUG ("  section name = %s, output_offset 0x%08x, output_section->vma = 0x%08x\n",
1116		 reloc_data.input_section->name,
1117		 (unsigned int) reloc_data.input_section->output_offset,
1118		 (unsigned int) reloc_data.input_section->output_section->vma);
1119      ARC_DEBUG ("  changed_address = 0x%08x\n",
1120		 (unsigned int) (reloc_data.input_section->output_section->vma
1121				 + reloc_data.input_section->output_offset
1122				 + reloc_data.reloc_offset));
1123      ARC_DEBUG ("  file: %s\n", reloc_data.input_section->owner->filename);
1124    }
1125  else
1126    {
1127      ARC_DEBUG ("	input section is NULL\n");
1128    }
1129}
1130#else
1131#define DEBUG_ARC_RELOC(A)
1132#endif /* ARC_ENABLE_DEBUG */
1133
1134static bfd_vma
1135middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
1136{
1137  if (do_it)
1138    {
1139      insn
1140	= ((insn & 0xffff0000) >> 16)
1141	  | ((insn & 0xffff) << 16);
1142    }
1143  return insn;
1144}
1145
1146/* This function is called for relocations that are otherwise marked as NOT
1147   requiring overflow checks.  In here we perform non-standard checks of
1148   the relocation value.  */
1149
1150static inline bfd_reloc_status_type
1151arc_special_overflow_checks (const struct arc_relocation_data reloc_data,
1152			     bfd_signed_vma relocation,
1153			     struct bfd_link_info *info ATTRIBUTE_UNUSED)
1154{
1155  switch (reloc_data.howto->type)
1156    {
1157    case R_ARC_NPS_CMEM16:
1158      if (((relocation >> 16) & 0xffff) != NPS_CMEM_HIGH_VALUE)
1159	{
1160	  if (reloc_data.reloc_addend == 0)
1161	    _bfd_error_handler
1162	      /* xgettext:c-format */
1163	      (_("%pB(%pA+%#" PRIx64 "): CMEM relocation to `%s' is invalid, "
1164		 "16 MSB should be %#x (value is %#" PRIx64 ")"),
1165	       reloc_data.input_section->owner,
1166	       reloc_data.input_section,
1167	       (uint64_t) reloc_data.reloc_offset,
1168	       reloc_data.symbol_name,
1169	       NPS_CMEM_HIGH_VALUE,
1170	       (uint64_t) relocation);
1171	  else
1172	    _bfd_error_handler
1173	      /* xgettext:c-format */
1174	      (_("%pB(%pA+%#" PRIx64 "): CMEM relocation to `%s+%#" PRIx64
1175		 "' is invalid, 16 MSB should be %#x (value is %#" PRIx64 ")"),
1176	       reloc_data.input_section->owner,
1177	       reloc_data.input_section,
1178	       (uint64_t) reloc_data.reloc_offset,
1179	       reloc_data.symbol_name,
1180	       (uint64_t) reloc_data.reloc_addend,
1181	       NPS_CMEM_HIGH_VALUE,
1182	       (uint64_t) relocation);
1183	  return bfd_reloc_overflow;
1184	}
1185      break;
1186
1187    default:
1188      break;
1189    }
1190
1191  return bfd_reloc_ok;
1192}
1193
1194#define ME(reloc) (reloc)
1195
1196#define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") != NULL) \
1197			    && (!bfd_big_endian (BFD)))
1198
1199#define S ((bfd_signed_vma) (reloc_data.sym_value			\
1200	   + (reloc_data.sym_section->output_section != NULL ?		\
1201	      (reloc_data.sym_section->output_offset			\
1202	       + reloc_data.sym_section->output_section->vma) : 0)))
1203#define L ((bfd_signed_vma) (reloc_data.sym_value			\
1204	   + (reloc_data.sym_section->output_section != NULL ?		\
1205	      (reloc_data.sym_section->output_offset			\
1206	      + reloc_data.sym_section->output_section->vma) : 0)))
1207#define A (reloc_data.reloc_addend)
1208#define B (0)
1209#define G (reloc_data.got_offset_value)
1210#define GOT (reloc_data.got_symbol_vma)
1211#define GOT_BEGIN (htab->sgot->output_section->vma)
1212
1213#define MES (0)
1214	/* P: relative offset to PCL The offset should be to the
1215	  current location aligned to 32 bits.  */
1216#define P ((bfd_signed_vma) (						\
1217	   (								\
1218	    (reloc_data.input_section->output_section != NULL ?		\
1219	     reloc_data.input_section->output_section->vma : 0)		\
1220	    + reloc_data.input_section->output_offset			\
1221	    + (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0)))	\
1222	   & ~0x3))
1223#define PDATA ((bfd_signed_vma) ( \
1224	    (reloc_data.input_section->output_section->vma \
1225	     + reloc_data.input_section->output_offset \
1226	     + (reloc_data.reloc_offset))))
1227#define SECTSTART (bfd_signed_vma) (reloc_data.sym_section->output_section->vma \
1228				    + reloc_data.sym_section->output_offset)
1229#define FINAL_SECTSTART \
1230  (bfd_signed_vma) (reloc_data.sym_section->output_section->vma)
1231#define JLI (bfd_signed_vma) (reloc_data.sym_section->output_section->vma)
1232#define _SDA_BASE_ (bfd_signed_vma) (reloc_data.sdata_begin_symbol_vma)
1233#define TLS_REL (bfd_signed_vma) \
1234  ((elf_hash_table (info))->tls_sec->output_section->vma)
1235#define TLS_TBSS (align_power(TCB_SIZE, \
1236		  reloc_data.sym_section->alignment_power))
1237
1238#define none (0)
1239
1240#ifdef ARC_ENABLE_DEBUG
1241#define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA, TYPE)			\
1242  do									\
1243    {									\
1244      asection *sym_section = reloc_data.sym_section;			\
1245      asection *input_section = reloc_data.input_section;		\
1246      ARC_DEBUG ("RELOC_TYPE = " TYPE "\n");				\
1247      ARC_DEBUG ("FORMULA = " FORMULA "\n");				\
1248      ARC_DEBUG ("S = %#lx\n", S);					\
1249      ARC_DEBUG ("A = %#lx\n", A);					\
1250      ARC_DEBUG ("L = %lx\n", L);					\
1251      if (sym_section->output_section != NULL)				\
1252	ARC_DEBUG ("symbol_section->vma = %#lx\n",			\
1253		   sym_section->output_section->vma			\
1254		   + sym_section->output_offset);			\
1255      else								\
1256	ARC_DEBUG ("symbol_section->vma = NULL\n");			\
1257      if (input_section->output_section != NULL)			\
1258	ARC_DEBUG ("symbol_section->vma = %#lx\n",			\
1259		   input_section->output_section->vma			\
1260		   + input_section->output_offset);			\
1261      else								\
1262	ARC_DEBUG ("symbol_section->vma = NULL\n");			\
1263      ARC_DEBUG ("PCL = %#lx\n", P);					\
1264      ARC_DEBUG ("P = %#lx\n", P);					\
1265      ARC_DEBUG ("G = %#lx\n", G);					\
1266      ARC_DEBUG ("SDA_OFFSET = %#lx\n", _SDA_BASE_);			\
1267      ARC_DEBUG ("SDA_SET = %d\n", reloc_data.sdata_begin_symbol_vma_set); \
1268      ARC_DEBUG ("GOT_OFFSET = %#lx\n", GOT);				\
1269      ARC_DEBUG ("relocation = %#08lx\n", relocation);			\
1270      ARC_DEBUG ("before = %#08x\n", (unsigned) insn);			\
1271      ARC_DEBUG ("data   = %08x (%u) (%d)\n", (unsigned) relocation,	\
1272		 (unsigned) relocation, (int) relocation);		\
1273    }									\
1274  while (0)
1275
1276#define PRINT_DEBUG_RELOC_INFO_AFTER				\
1277  do								\
1278    {								\
1279      ARC_DEBUG ("after  = 0x%08x\n", (unsigned int) insn);	\
1280    }								\
1281  while (0)
1282
1283#else
1284
1285#define PRINT_DEBUG_RELOC_INFO_BEFORE(...)
1286#define PRINT_DEBUG_RELOC_INFO_AFTER
1287
1288#endif /* ARC_ENABLE_DEBUG */
1289
1290#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
1291  case R_##TYPE:							\
1292    {									\
1293      bfd_signed_vma bitsize ATTRIBUTE_UNUSED = BITSIZE;		\
1294      relocation = FORMULA  ;						\
1295      PRINT_DEBUG_RELOC_INFO_BEFORE (#FORMULA, #TYPE);			\
1296      insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd));	\
1297      insn = (* get_replace_function (abfd, TYPE)) (insn, relocation);	\
1298      insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd));	\
1299      PRINT_DEBUG_RELOC_INFO_AFTER;					\
1300    }									\
1301    break;
1302
1303static bfd_reloc_status_type
1304arc_do_relocation (bfd_byte * contents,
1305		   struct arc_relocation_data reloc_data,
1306		   struct bfd_link_info *info)
1307{
1308  bfd_signed_vma relocation = 0;
1309  bfd_vma insn;
1310  bfd_vma orig_insn ATTRIBUTE_UNUSED;
1311  bfd * abfd = reloc_data.input_section->owner;
1312  struct elf_link_hash_table *htab ATTRIBUTE_UNUSED = elf_hash_table (info);
1313  bfd_reloc_status_type flag;
1314
1315  if (!reloc_data.should_relocate)
1316    return bfd_reloc_ok;
1317
1318  switch (reloc_data.howto->size)
1319    {
1320    case 2:
1321      insn = arc_bfd_get_32 (abfd,
1322			     contents + reloc_data.reloc_offset,
1323			     reloc_data.input_section);
1324      break;
1325    case 1:
1326      insn = arc_bfd_get_16 (abfd,
1327			     contents + reloc_data.reloc_offset,
1328			     reloc_data.input_section);
1329      break;
1330    case 0:
1331      insn = arc_bfd_get_8 (abfd,
1332			    contents + reloc_data.reloc_offset,
1333			    reloc_data.input_section);
1334      break;
1335    default:
1336      insn = 0;
1337      BFD_ASSERT (0);
1338      break;
1339    }
1340
1341  orig_insn = insn;
1342
1343  switch (reloc_data.howto->type)
1344    {
1345#include "elf/arc-reloc.def"
1346
1347    default:
1348      BFD_ASSERT (0);
1349      break;
1350    }
1351
1352  /* Check for relocation overflow.  */
1353  if (reloc_data.howto->complain_on_overflow != complain_overflow_dont)
1354    flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
1355			       reloc_data.howto->bitsize,
1356			       reloc_data.howto->rightshift,
1357			       bfd_arch_bits_per_address (abfd),
1358			       relocation);
1359  else
1360    flag = arc_special_overflow_checks (reloc_data, relocation, info);
1361
1362  if (flag != bfd_reloc_ok)
1363    {
1364      ARC_DEBUG ("Relocation overflows !\n");
1365      DEBUG_ARC_RELOC (reloc_data);
1366      ARC_DEBUG ("Relocation value = signed -> %d, unsigned -> %u"
1367		 ", hex -> (0x%08x)\n",
1368		(int) relocation, (unsigned) relocation, (int) relocation);
1369
1370      return flag;
1371    }
1372
1373  /* Write updated instruction back to memory.  */
1374  switch (reloc_data.howto->size)
1375    {
1376    case 2:
1377      arc_bfd_put_32 (abfd, insn,
1378		      contents + reloc_data.reloc_offset,
1379		      reloc_data.input_section);
1380      break;
1381    case 1:
1382	arc_bfd_put_16 (abfd, insn,
1383			contents + reloc_data.reloc_offset,
1384			reloc_data.input_section);
1385	break;
1386    case 0:
1387      arc_bfd_put_8 (abfd, insn,
1388		     contents + reloc_data.reloc_offset,
1389		     reloc_data.input_section);
1390      break;
1391    default:
1392      ARC_DEBUG ("size = %d\n", reloc_data.howto->size);
1393      BFD_ASSERT (0);
1394      break;
1395    }
1396
1397  return bfd_reloc_ok;
1398}
1399#undef S
1400#undef A
1401#undef B
1402#undef G
1403#undef GOT
1404#undef L
1405#undef MES
1406#undef P
1407#undef SECTSTAR
1408#undef SECTSTART
1409#undef JLI
1410#undef _SDA_BASE_
1411#undef none
1412
1413#undef ARC_RELOC_HOWTO
1414
1415
1416/* Relocate an arc ELF section.
1417   Function : elf_arc_relocate_section
1418   Brief    : Relocate an arc section, by handling all the relocations
1419	     appearing in that section.
1420   Args     : output_bfd    : The bfd being written to.
1421	      info	    : Link information.
1422	      input_bfd     : The input bfd.
1423	      input_section : The section being relocated.
1424	      contents	    : contents of the section being relocated.
1425	      relocs	    : List of relocations in the section.
1426	      local_syms    : is a pointer to the swapped in local symbols.
1427	      local_section : is an array giving the section in the input file
1428			      corresponding to the st_shndx field of each
1429			      local symbol.  */
1430static bfd_boolean
1431elf_arc_relocate_section (bfd *			  output_bfd,
1432			  struct bfd_link_info *  info,
1433			  bfd *			  input_bfd,
1434			  asection *		  input_section,
1435			  bfd_byte *		  contents,
1436			  Elf_Internal_Rela *     relocs,
1437			  Elf_Internal_Sym *      local_syms,
1438			  asection **		  local_sections)
1439{
1440  Elf_Internal_Shdr *		 symtab_hdr;
1441  struct elf_link_hash_entry **  sym_hashes;
1442  Elf_Internal_Rela *		 rel;
1443  Elf_Internal_Rela *		 wrel;
1444  Elf_Internal_Rela *		 relend;
1445  struct elf_link_hash_table *   htab = elf_hash_table (info);
1446
1447  symtab_hdr = &((elf_tdata (input_bfd))->symtab_hdr);
1448  sym_hashes = elf_sym_hashes (input_bfd);
1449
1450  rel = wrel = relocs;
1451  relend = relocs + input_section->reloc_count;
1452  for (; rel < relend; wrel++, rel++)
1453    {
1454      enum elf_arc_reloc_type	    r_type;
1455      reloc_howto_type *	    howto;
1456      unsigned long		    r_symndx;
1457      struct elf_link_hash_entry *  h;
1458      Elf_Internal_Sym *	    sym;
1459      asection *		    sec;
1460      struct elf_link_hash_entry *  h2;
1461      const char *		    msg;
1462      bfd_boolean		    unresolved_reloc = FALSE;
1463
1464      struct arc_relocation_data reloc_data =
1465      {
1466	.reloc_offset = 0,
1467	.reloc_addend = 0,
1468	.got_offset_value = 0,
1469	.sym_value = 0,
1470	.sym_section = NULL,
1471	.howto = NULL,
1472	.input_section = NULL,
1473	.sdata_begin_symbol_vma = 0,
1474	.sdata_begin_symbol_vma_set = FALSE,
1475	.got_symbol_vma = 0,
1476	.should_relocate = FALSE
1477      };
1478
1479      r_type = ELF32_R_TYPE (rel->r_info);
1480
1481      if (r_type >= (int) R_ARC_max)
1482	{
1483	  bfd_set_error (bfd_error_bad_value);
1484	  return FALSE;
1485	}
1486      howto = arc_elf_howto (r_type);
1487
1488      r_symndx = ELF32_R_SYM (rel->r_info);
1489
1490      /* If we are generating another .o file and the symbol in not
1491	 local, skip this relocation.  */
1492      if (bfd_link_relocatable (info))
1493	{
1494	  /* This is a relocateable link.  We don't have to change
1495	     anything, unless the reloc is against a section symbol,
1496	     in which case we have to adjust according to where the
1497	     section symbol winds up in the output section.  */
1498
1499	  /* Checks if this is a local symbol and thus the reloc
1500	     might (will??) be against a section symbol.  */
1501	  if (r_symndx < symtab_hdr->sh_info)
1502	    {
1503	      sym = local_syms + r_symndx;
1504	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1505		{
1506		  sec = local_sections[r_symndx];
1507
1508		  /* For RELA relocs.  Just adjust the addend
1509		     value in the relocation entry.  */
1510		  rel->r_addend += sec->output_offset + sym->st_value;
1511
1512		  ARC_DEBUG ("local symbols reloc (section=%d %s) seen in %s\n",
1513			     (int) r_symndx, local_sections[r_symndx]->name,
1514			     __PRETTY_FUNCTION__);
1515		}
1516	    }
1517	}
1518
1519      h2 = elf_link_hash_lookup (elf_hash_table (info), "__SDATA_BEGIN__",
1520				 FALSE, FALSE, TRUE);
1521
1522      if (!reloc_data.sdata_begin_symbol_vma_set
1523	  && h2 != NULL && h2->root.type != bfd_link_hash_undefined
1524	  && h2->root.u.def.section->output_section != NULL)
1525	/* TODO: Verify this condition.  */
1526	{
1527	  reloc_data.sdata_begin_symbol_vma =
1528	    (h2->root.u.def.value
1529	     + h2->root.u.def.section->output_section->vma);
1530	  reloc_data.sdata_begin_symbol_vma_set = TRUE;
1531	}
1532
1533      reloc_data.input_section = input_section;
1534      reloc_data.howto = howto;
1535      reloc_data.reloc_offset = rel->r_offset;
1536      reloc_data.reloc_addend = rel->r_addend;
1537
1538      /* This is a final link.  */
1539      h = NULL;
1540      sym = NULL;
1541      sec = NULL;
1542
1543      if (r_symndx < symtab_hdr->sh_info) /* A local symbol.  */
1544	{
1545	  sym = local_syms + r_symndx;
1546	  sec = local_sections[r_symndx];
1547	}
1548      else
1549	{
1550	  bfd_boolean warned, ignored;
1551	  bfd_vma relocation ATTRIBUTE_UNUSED;
1552
1553	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1554				   r_symndx, symtab_hdr, sym_hashes,
1555				   h, sec, relocation,
1556				   unresolved_reloc, warned, ignored);
1557
1558	  /* TODO: This code is repeated from below.  We should
1559	     clean it and remove duplications.
1560	     Sec is used check for discarded sections.
1561	     Need to redesign code below.  */
1562
1563	  /* Get the symbol's entry in the symtab.  */
1564	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1565
1566	  while (h->root.type == bfd_link_hash_indirect
1567		 || h->root.type == bfd_link_hash_warning)
1568	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1569
1570	  /* If we have encountered a definition for this symbol.  */
1571	  if (h->root.type == bfd_link_hash_defined
1572	      || h->root.type == bfd_link_hash_defweak)
1573	    {
1574	      reloc_data.sym_value = h->root.u.def.value;
1575	      sec = h->root.u.def.section;
1576	    }
1577	}
1578
1579      /* Clean relocs for symbols in discarded sections.  */
1580      if (sec != NULL && discarded_section (sec))
1581	{
1582	  _bfd_clear_contents (howto, input_bfd, input_section,
1583			       contents, rel->r_offset);
1584	  rel->r_info = 0;
1585	  rel->r_addend = 0;
1586
1587	  /* For ld -r, remove relocations in debug sections against
1588	     sections defined in discarded sections.  Not done for
1589	     eh_frame editing code expects to be present.  */
1590	   if (bfd_link_relocatable (info)
1591	       && (input_section->flags & SEC_DEBUGGING))
1592	     wrel--;
1593
1594	  continue;
1595	}
1596
1597      if (bfd_link_relocatable (info))
1598	{
1599	  if (wrel != rel)
1600	    *wrel = *rel;
1601	  continue;
1602	}
1603
1604      if (r_symndx < symtab_hdr->sh_info) /* A local symbol.  */
1605	{
1606	  reloc_data.sym_value = sym->st_value;
1607	  reloc_data.sym_section = sec;
1608	  reloc_data.symbol_name =
1609	    bfd_elf_string_from_elf_section (input_bfd,
1610					     symtab_hdr->sh_link,
1611					     sym->st_name);
1612
1613	  /* Mergeable section handling.  */
1614	  if ((sec->flags & SEC_MERGE)
1615	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1616	    {
1617	      asection *msec;
1618	      msec = sec;
1619	      rel->r_addend = _bfd_elf_rel_local_sym (output_bfd, sym,
1620						      &msec, rel->r_addend);
1621	      rel->r_addend -= (sec->output_section->vma
1622				+ sec->output_offset
1623				+ sym->st_value);
1624	      rel->r_addend += msec->output_section->vma + msec->output_offset;
1625
1626	      reloc_data.reloc_addend = rel->r_addend;
1627	    }
1628
1629	  BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1630	  if (htab->sgot != NULL)
1631	    reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1632					+ htab->sgot->output_offset;
1633
1634	  reloc_data.should_relocate = TRUE;
1635	}
1636      else /* Global symbol.  */
1637	{
1638	  /* FIXME: We should use the RELOC_FOR_GLOBAL_SYMBOL macro
1639	     (defined in elf-bfd.h) here.  */
1640
1641	  /* Get the symbol's entry in the symtab.  */
1642	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1643
1644	  while (h->root.type == bfd_link_hash_indirect
1645		 || h->root.type == bfd_link_hash_warning)
1646	  {
1647	    struct elf_arc_link_hash_entry *ah_old =
1648	      (struct elf_arc_link_hash_entry *) h;
1649	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1650	    struct elf_arc_link_hash_entry *ah =
1651	      (struct elf_arc_link_hash_entry *) h;
1652
1653	    if (ah->got_ents == 0 && ah_old->got_ents != ah->got_ents)
1654	      ah->got_ents = ah_old->got_ents;
1655	  }
1656
1657	  /* TODO: Need to validate what was the intention.  */
1658	  /* BFD_ASSERT ((h->dynindx == -1) || (h->forced_local != 0)); */
1659	  reloc_data.symbol_name = h->root.root.string;
1660
1661	  /* If we have encountered a definition for this symbol.  */
1662	  if (h->root.type == bfd_link_hash_defined
1663	      || h->root.type == bfd_link_hash_defweak)
1664	    {
1665	      reloc_data.sym_value = h->root.u.def.value;
1666	      reloc_data.sym_section = h->root.u.def.section;
1667
1668	      reloc_data.should_relocate = TRUE;
1669
1670	      if (is_reloc_for_GOT (howto) && !bfd_link_pic (info))
1671		{
1672		  struct elf_arc_link_hash_entry *ah =
1673		    (struct elf_arc_link_hash_entry *) h;
1674		  /* TODO: Change it to use arc_do_relocation with
1675		    ARC_32 reloc.  Try to use ADD_RELA macro.  */
1676		  bfd_vma relocation =
1677		    reloc_data.sym_value + reloc_data.reloc_addend
1678		    + (reloc_data.sym_section->output_section != NULL ?
1679			(reloc_data.sym_section->output_offset
1680			 + reloc_data.sym_section->output_section->vma)
1681		      : 0);
1682
1683		  BFD_ASSERT (ah->got_ents);
1684		  bfd_vma got_offset = ah->got_ents->offset;
1685		  bfd_put_32 (output_bfd, relocation,
1686			      htab->sgot->contents + got_offset);
1687		}
1688	      if (is_reloc_for_PLT (howto) && h->plt.offset != (bfd_vma) -1)
1689		{
1690		  /* TODO: This is repeated up here.  */
1691		  reloc_data.sym_value = h->plt.offset;
1692		  reloc_data.sym_section = htab->splt;
1693		}
1694	    }
1695	  else if (h->root.type == bfd_link_hash_undefweak)
1696	    {
1697	      /* Is weak symbol and has no definition.  */
1698	      if (is_reloc_for_GOT (howto))
1699		{
1700		  reloc_data.sym_value = h->root.u.def.value;
1701		  reloc_data.sym_section = htab->sgot;
1702		  reloc_data.should_relocate = TRUE;
1703		}
1704	      else if (is_reloc_for_PLT (howto)
1705		       && h->plt.offset != (bfd_vma) -1)
1706		{
1707		  /* TODO: This is repeated up here.  */
1708		  reloc_data.sym_value = h->plt.offset;
1709		  reloc_data.sym_section = htab->splt;
1710		  reloc_data.should_relocate = TRUE;
1711		}
1712	      else
1713		continue;
1714	    }
1715	  else
1716	    {
1717	      if (is_reloc_for_GOT (howto))
1718		{
1719		  reloc_data.sym_value = h->root.u.def.value;
1720		  reloc_data.sym_section = htab->sgot;
1721
1722		  reloc_data.should_relocate = TRUE;
1723		}
1724	      else if (is_reloc_for_PLT (howto))
1725		{
1726		  /* Fail if it is linking for PIE and the symbol is
1727		     undefined.  */
1728		  if (bfd_link_executable (info))
1729		    (*info->callbacks->undefined_symbol)
1730		      (info, h->root.root.string, input_bfd, input_section,
1731		       rel->r_offset, TRUE);
1732		  reloc_data.sym_value = h->plt.offset;
1733		  reloc_data.sym_section = htab->splt;
1734
1735		  reloc_data.should_relocate = TRUE;
1736		}
1737	      else if (!bfd_link_pic (info) || bfd_link_executable (info))
1738		(*info->callbacks->undefined_symbol)
1739		  (info, h->root.root.string, input_bfd, input_section,
1740		   rel->r_offset, TRUE);
1741	    }
1742
1743	  BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1744	  if (htab->sgot != NULL)
1745	    reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1746					+ htab->sgot->output_offset;
1747	}
1748
1749      if ((is_reloc_for_GOT (howto)
1750	   || is_reloc_for_TLS (howto)))
1751	{
1752	  reloc_data.should_relocate = TRUE;
1753
1754	  struct got_entry **list
1755	    = get_got_entry_list_for_symbol (input_bfd, r_symndx, h);
1756
1757	  reloc_data.got_offset_value
1758	    = relocate_fix_got_relocs_for_got_info (list,
1759						    tls_type_for_reloc (howto),
1760						    info,
1761						    output_bfd,
1762						    r_symndx,
1763						    local_syms,
1764						    local_sections,
1765						    h,
1766						    &reloc_data);
1767
1768	  if (h == NULL)
1769	    {
1770	      create_got_dynrelocs_for_single_entry (
1771		  got_entry_for_type (list,
1772				arc_got_entry_type_for_reloc (howto)),
1773		  output_bfd, info, NULL);
1774	    }
1775	}
1776
1777
1778#define IS_ARC_PCREL_TYPE(TYPE) \
1779  (   (TYPE == R_ARC_PC32)      \
1780   || (TYPE == R_ARC_32_PCREL))
1781
1782      switch (r_type)
1783	{
1784	  case R_ARC_32:
1785	  case R_ARC_32_ME:
1786	  case R_ARC_PC32:
1787	  case R_ARC_32_PCREL:
1788	    if (bfd_link_pic (info)
1789		&& (!IS_ARC_PCREL_TYPE (r_type)
1790		    || (h != NULL
1791			&& h->dynindx != -1
1792			&& !h->def_regular
1793			&& (!info->symbolic || !h->def_regular))))
1794	      {
1795		Elf_Internal_Rela outrel;
1796		bfd_byte *loc;
1797		bfd_boolean skip = FALSE;
1798		bfd_boolean relocate = FALSE;
1799		asection *sreloc = _bfd_elf_get_dynamic_reloc_section
1800				 (input_bfd, input_section,
1801				  /*RELA*/ TRUE);
1802
1803		BFD_ASSERT (sreloc != NULL);
1804
1805		outrel.r_offset = _bfd_elf_section_offset (output_bfd,
1806							   info,
1807							   input_section,
1808							   rel->r_offset);
1809
1810		if (outrel.r_offset == (bfd_vma) -1)
1811		  skip = TRUE;
1812
1813		outrel.r_addend = rel->r_addend;
1814		outrel.r_offset += (input_section->output_section->vma
1815				    + input_section->output_offset);
1816
1817		if (skip)
1818		  {
1819		    memset (&outrel, 0, sizeof outrel);
1820		    relocate = FALSE;
1821		  }
1822		else if (h != NULL
1823			 && h->dynindx != -1
1824			 && (IS_ARC_PCREL_TYPE (r_type)
1825			     || !(bfd_link_executable (info)
1826				  || SYMBOLIC_BIND (info, h))
1827			     || ! h->def_regular))
1828		  {
1829		    BFD_ASSERT (h != NULL);
1830		    if ((input_section->flags & SEC_ALLOC) != 0)
1831		      relocate = FALSE;
1832		    else
1833		      relocate = TRUE;
1834
1835		    BFD_ASSERT (h->dynindx != -1);
1836		    outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1837		  }
1838		else
1839		  {
1840		    /* Handle local symbols, they either do not have a
1841		       global hash table entry (h == NULL), or are
1842		       forced local due to a version script
1843		       (h->forced_local), or the third condition is
1844		       legacy, it appears to say something like, for
1845		       links where we are pre-binding the symbols, or
1846		       there's not an entry for this symbol in the
1847		       dynamic symbol table, and it's a regular symbol
1848		       not defined in a shared object, then treat the
1849		       symbol as local, resolve it now.  */
1850		    relocate = TRUE;
1851		    /* outrel.r_addend = 0; */
1852		    outrel.r_info = ELF32_R_INFO (0, R_ARC_RELATIVE);
1853		  }
1854
1855		BFD_ASSERT (sreloc->contents != 0);
1856
1857		loc = sreloc->contents;
1858		loc += sreloc->reloc_count * sizeof (Elf32_External_Rela);
1859		sreloc->reloc_count += 1;
1860
1861		bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1862
1863		if (!relocate)
1864		  continue;
1865	      }
1866	    break;
1867	  default:
1868	    break;
1869	}
1870
1871      if (is_reloc_SDA_relative (howto)
1872	  && !reloc_data.sdata_begin_symbol_vma_set)
1873	{
1874	  _bfd_error_handler
1875	    ("error: linker symbol __SDATA_BEGIN__ not found");
1876	  bfd_set_error (bfd_error_bad_value);
1877	  return FALSE;
1878	}
1879
1880      DEBUG_ARC_RELOC (reloc_data);
1881
1882      /* Make sure we have with a dynamic linker.  In case of GOT and PLT
1883	 the sym_section should point to .got or .plt respectively.  */
1884      if ((is_reloc_for_GOT (howto) || is_reloc_for_PLT (howto))
1885	  && reloc_data.sym_section == NULL)
1886	{
1887	  _bfd_error_handler
1888	    (_("GOT and PLT relocations cannot be fixed with a non dynamic linker"));
1889	  bfd_set_error (bfd_error_bad_value);
1890	  return FALSE;
1891	}
1892
1893      msg = NULL;
1894      switch (arc_do_relocation (contents, reloc_data, info))
1895	{
1896	case bfd_reloc_ok:
1897	  continue; /* The reloc processing loop.  */
1898
1899	case bfd_reloc_overflow:
1900	  (*info->callbacks->reloc_overflow)
1901	    (info, (h ? &h->root : NULL), reloc_data.symbol_name, howto->name, (bfd_vma) 0,
1902	     input_bfd, input_section, rel->r_offset);
1903	  break;
1904
1905	case bfd_reloc_undefined:
1906	  (*info->callbacks->undefined_symbol)
1907	    (info, reloc_data.symbol_name, input_bfd, input_section, rel->r_offset, TRUE);
1908	  break;
1909
1910	case bfd_reloc_other:
1911	  /* xgettext:c-format */
1912	  msg = _("%pB(%pA): warning: unaligned access to symbol '%s' in the small data area");
1913	  break;
1914
1915	case bfd_reloc_outofrange:
1916	  /* xgettext:c-format */
1917	  msg = _("%pB(%pA): internal error: out of range error");
1918	  break;
1919
1920	case bfd_reloc_notsupported:
1921	  /* xgettext:c-format */
1922	  msg = _("%pB(%pA): internal error: unsupported relocation error");
1923	  break;
1924
1925	case bfd_reloc_dangerous:
1926	  /* xgettext:c-format */
1927	  msg = _("%pB(%pA): internal error: dangerous relocation");
1928	  break;
1929
1930	default:
1931	  /* xgettext:c-format */
1932	  msg = _("%pB(%pA): internal error: unknown error");
1933	  break;
1934	}
1935
1936      if (msg)
1937	_bfd_error_handler (msg, input_bfd, input_section, reloc_data.symbol_name);
1938      return FALSE;
1939    }
1940
1941  return TRUE;
1942}
1943
1944#define elf_arc_hash_table(p) \
1945    (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
1946  == ARC_ELF_DATA ? ((struct elf_arc_link_hash_table *) ((p)->hash)) : NULL)
1947
1948static bfd_boolean
1949elf_arc_check_relocs (bfd *			 abfd,
1950		      struct bfd_link_info *     info,
1951		      asection *		 sec,
1952		      const Elf_Internal_Rela *  relocs)
1953{
1954  Elf_Internal_Shdr *		symtab_hdr;
1955  struct elf_link_hash_entry **	sym_hashes;
1956  const Elf_Internal_Rela *	rel;
1957  const Elf_Internal_Rela *	rel_end;
1958  bfd *				dynobj;
1959  asection *			sreloc = NULL;
1960  struct elf_link_hash_table *	htab = elf_hash_table (info);
1961
1962  if (bfd_link_relocatable (info))
1963    return TRUE;
1964
1965  if (htab->dynobj == NULL)
1966    htab->dynobj = abfd;
1967
1968  dynobj = (elf_hash_table (info))->dynobj;
1969  symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1970  sym_hashes = elf_sym_hashes (abfd);
1971
1972  rel_end = relocs + sec->reloc_count;
1973  for (rel = relocs; rel < rel_end; rel++)
1974    {
1975      enum elf_arc_reloc_type r_type;
1976      reloc_howto_type *howto;
1977      unsigned long   r_symndx;
1978      struct elf_link_hash_entry *h;
1979
1980      r_type = ELF32_R_TYPE (rel->r_info);
1981
1982      if (r_type >= (int) R_ARC_max)
1983	{
1984	  bfd_set_error (bfd_error_bad_value);
1985	  return FALSE;
1986	}
1987      howto = arc_elf_howto (r_type);
1988
1989      /* Load symbol information.  */
1990      r_symndx = ELF32_R_SYM (rel->r_info);
1991      if (r_symndx < symtab_hdr->sh_info) /* Is a local symbol.  */
1992	h = NULL;
1993      else /* Global one.  */
1994	{
1995	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1996	  while (h->root.type == bfd_link_hash_indirect
1997		 || h->root.type == bfd_link_hash_warning)
1998	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1999	}
2000
2001
2002      switch (r_type)
2003	{
2004	case R_ARC_32:
2005	case R_ARC_32_ME:
2006	  /* During shared library creation, these relocs should not
2007	     appear in a shared library (as memory will be read only
2008	     and the dynamic linker can not resolve these.  However
2009	     the error should not occur for e.g. debugging or
2010	     non-readonly sections.  */
2011	  if (h != NULL
2012	      && (bfd_link_dll (info) && !bfd_link_pie (info))
2013	      && (sec->flags & SEC_ALLOC) != 0
2014	      && (sec->flags & SEC_READONLY) != 0
2015	      && ((sec->flags & SEC_CODE) != 0
2016		  || (sec->flags & SEC_DEBUGGING) != 0))
2017	    {
2018	      const char *name;
2019	      if (h)
2020		name = h->root.root.string;
2021	      else
2022		name = "UNKNOWN";
2023	      _bfd_error_handler
2024	      /* xgettext:c-format */
2025	      (_("%pB: relocation %s against `%s' can not be used"
2026		 " when making a shared object; recompile with -fPIC"),
2027		 abfd,
2028		 arc_elf_howto (r_type)->name,
2029		 name);
2030	      bfd_set_error (bfd_error_bad_value);
2031	      return FALSE;
2032	    }
2033
2034	    /* In some cases we are not setting the 'non_got_ref'
2035	       flag, even though the relocations don't require a GOT
2036	       access.  We should extend the testing in this area to
2037	       ensure that no significant cases are being missed.  */
2038	    if (h)
2039	      h->non_got_ref = 1;
2040	    /* FALLTHROUGH */
2041	  case R_ARC_PC32:
2042	  case R_ARC_32_PCREL:
2043	    if ((bfd_link_pic (info))
2044		&& ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
2045		    || (h != NULL
2046			&& (!info->symbolic || !h->def_regular))))
2047	      {
2048		if (sreloc == NULL)
2049		  {
2050		    if (info->dynamic
2051			&& ! htab->dynamic_sections_created
2052			&& ! _bfd_elf_link_create_dynamic_sections (abfd, info))
2053		      return FALSE;
2054		    sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
2055								  2, abfd,
2056								  /*rela*/
2057								  TRUE);
2058
2059		    if (sreloc == NULL)
2060		      return FALSE;
2061		  }
2062		sreloc->size += sizeof (Elf32_External_Rela);
2063
2064	      }
2065	  default:
2066	    break;
2067	}
2068
2069      if (is_reloc_for_PLT (howto))
2070	{
2071	  if (h == NULL)
2072	    continue;
2073	  else
2074	    if (h->forced_local == 0)
2075	      h->needs_plt = 1;
2076	}
2077
2078      /* Add info to the symbol got_entry_list.  */
2079      if (is_reloc_for_GOT (howto)
2080	  || is_reloc_for_TLS (howto))
2081	{
2082	  if (bfd_link_dll (info) && !bfd_link_pie (info)
2083	      && (r_type == R_ARC_TLS_LE_32 || r_type == R_ARC_TLS_LE_S9))
2084	    {
2085	      const char *name;
2086	      if (h)
2087		name = h->root.root.string;
2088	      else
2089		/* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);  */
2090		name = "UNKNOWN";
2091	      _bfd_error_handler
2092		/* xgettext:c-format */
2093		(_("%pB: relocation %s against `%s' can not be used"
2094		   " when making a shared object; recompile with -fPIC"),
2095		   abfd,
2096		   arc_elf_howto (r_type)->name,
2097		   name);
2098	      bfd_set_error (bfd_error_bad_value);
2099	      return FALSE;
2100	    }
2101	  if (! _bfd_elf_create_got_section (dynobj, info))
2102	    return FALSE;
2103
2104	  arc_fill_got_info_for_reloc (
2105		  arc_got_entry_type_for_reloc (howto),
2106		  get_got_entry_list_for_symbol (abfd, r_symndx, h),
2107		  info,
2108		  h);
2109	}
2110    }
2111
2112  return TRUE;
2113}
2114
2115#define ELF_DYNAMIC_INTERPRETER  "/sbin/ld-uClibc.so"
2116
2117static struct plt_version_t *
2118arc_get_plt_version (struct bfd_link_info *info)
2119{
2120  int i;
2121
2122  for (i = 0; i < 1; i++)
2123    {
2124      ARC_DEBUG ("%d: size1 = %d, size2 = %d\n", i,
2125		 (int) plt_versions[i].entry_size,
2126		 (int) plt_versions[i].elem_size);
2127    }
2128
2129  if (bfd_get_mach (info->output_bfd) == bfd_mach_arc_arcv2)
2130    {
2131      if (bfd_link_pic (info))
2132	return &(plt_versions[ELF_ARCV2_PIC]);
2133      else
2134	return &(plt_versions[ELF_ARCV2_ABS]);
2135    }
2136  else
2137    {
2138      if (bfd_link_pic (info))
2139	return &(plt_versions[ELF_ARC_PIC]);
2140      else
2141	return &(plt_versions[ELF_ARC_ABS]);
2142    }
2143}
2144
2145static bfd_vma
2146add_symbol_to_plt (struct bfd_link_info *info)
2147{
2148  struct elf_link_hash_table *htab = elf_hash_table (info);
2149  bfd_vma ret;
2150
2151  struct plt_version_t *plt_data = arc_get_plt_version (info);
2152
2153  /* If this is the first .plt entry, make room for the special first
2154     entry.  */
2155  if (htab->splt->size == 0)
2156    htab->splt->size += plt_data->entry_size;
2157
2158  ret = htab->splt->size;
2159
2160  htab->splt->size += plt_data->elem_size;
2161  ARC_DEBUG ("PLT_SIZE = %d\n", (int) htab->splt->size);
2162
2163  htab->sgotplt->size += 4;
2164  htab->srelplt->size += sizeof (Elf32_External_Rela);
2165
2166  return ret;
2167}
2168
2169#define PLT_DO_RELOCS_FOR_ENTRY(ABFD, DS, RELOCS)	\
2170  plt_do_relocs_for_symbol (ABFD, DS, RELOCS, 0, 0)
2171
2172static void
2173plt_do_relocs_for_symbol (bfd *abfd,
2174			  struct elf_link_hash_table *htab,
2175			  const struct plt_reloc *reloc,
2176			  bfd_vma plt_offset,
2177			  bfd_vma symbol_got_offset)
2178{
2179  while (SYM_ONLY (reloc->symbol) != LAST_RELOC)
2180    {
2181      bfd_vma relocation = 0;
2182
2183      switch (SYM_ONLY (reloc->symbol))
2184	{
2185	  case SGOT:
2186		relocation
2187		  = htab->sgotplt->output_section->vma
2188		    + htab->sgotplt->output_offset + symbol_got_offset;
2189		break;
2190	}
2191      relocation += reloc->addend;
2192
2193      if (IS_RELATIVE (reloc->symbol))
2194	{
2195	  bfd_vma reloc_offset = reloc->offset;
2196	  reloc_offset -= (IS_INSN_32 (reloc->symbol)) ? 4 : 0;
2197	  reloc_offset -= (IS_INSN_24 (reloc->symbol)) ? 2 : 0;
2198
2199	  relocation -= htab->splt->output_section->vma
2200			 + htab->splt->output_offset
2201			 + plt_offset + reloc_offset;
2202	}
2203
2204      /* TODO: being ME is not a property of the relocation but of the
2205	 section of which is applying the relocation. */
2206      if (IS_MIDDLE_ENDIAN (reloc->symbol) && !bfd_big_endian (abfd))
2207	{
2208	  relocation
2209	    = ((relocation & 0xffff0000) >> 16)
2210	      | ((relocation & 0xffff) << 16);
2211	}
2212
2213      switch (reloc->size)
2214	{
2215	  case 32:
2216	    bfd_put_32 (htab->splt->output_section->owner,
2217			relocation,
2218			htab->splt->contents + plt_offset + reloc->offset);
2219	    break;
2220	}
2221
2222      reloc = &(reloc[1]); /* Jump to next relocation.  */
2223    }
2224}
2225
2226static void
2227relocate_plt_for_symbol (bfd *output_bfd,
2228			 struct bfd_link_info *info,
2229			 struct elf_link_hash_entry *h)
2230{
2231  struct plt_version_t *plt_data = arc_get_plt_version (info);
2232  struct elf_link_hash_table *htab = elf_hash_table (info);
2233
2234  bfd_vma plt_index = (h->plt.offset  - plt_data->entry_size)
2235		      / plt_data->elem_size;
2236  bfd_vma got_offset = (plt_index + 3) * 4;
2237
2238  ARC_DEBUG ("arc_info: PLT_OFFSET = %#lx, PLT_ENTRY_VMA = %#lx, \
2239GOT_ENTRY_OFFSET = %#lx, GOT_ENTRY_VMA = %#lx, for symbol %s\n",
2240	     (long) h->plt.offset,
2241	     (long) (htab->splt->output_section->vma
2242		     + htab->splt->output_offset
2243		     + h->plt.offset),
2244	     (long) got_offset,
2245	     (long) (htab->sgotplt->output_section->vma
2246		     + htab->sgotplt->output_offset
2247		     + got_offset),
2248	     h->root.root.string);
2249
2250  {
2251    bfd_vma i = 0;
2252    uint16_t *ptr = (uint16_t *) plt_data->elem;
2253
2254    for (i = 0; i < plt_data->elem_size/2; i++)
2255      {
2256	uint16_t data = ptr[i];
2257	bfd_put_16 (output_bfd,
2258		    (bfd_vma) data,
2259		    htab->splt->contents + h->plt.offset + (i*2));
2260      }
2261  }
2262
2263  plt_do_relocs_for_symbol (output_bfd, htab,
2264			    plt_data->elem_relocs,
2265			    h->plt.offset,
2266			    got_offset);
2267
2268  /* Fill in the entry in the global offset table.  */
2269  bfd_put_32 (output_bfd,
2270	      (bfd_vma) (htab->splt->output_section->vma
2271			 + htab->splt->output_offset),
2272	      htab->sgotplt->contents + got_offset);
2273
2274  /* TODO: Fill in the entry in the .rela.plt section.  */
2275  {
2276    Elf_Internal_Rela rel;
2277    bfd_byte *loc;
2278
2279    rel.r_offset = (htab->sgotplt->output_section->vma
2280		    + htab->sgotplt->output_offset
2281		    + got_offset);
2282    rel.r_addend = 0;
2283
2284    BFD_ASSERT (h->dynindx != -1);
2285    rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_JMP_SLOT);
2286
2287    loc = htab->srelplt->contents;
2288    loc += plt_index * sizeof (Elf32_External_Rela); /* relA */
2289    bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2290  }
2291}
2292
2293static void
2294relocate_plt_for_entry (bfd *abfd,
2295			struct bfd_link_info *info)
2296{
2297  struct plt_version_t *plt_data = arc_get_plt_version (info);
2298  struct elf_link_hash_table *htab = elf_hash_table (info);
2299
2300  {
2301    bfd_vma i = 0;
2302    uint16_t *ptr = (uint16_t *) plt_data->entry;
2303    for (i = 0; i < plt_data->entry_size/2; i++)
2304      {
2305	uint16_t data = ptr[i];
2306	bfd_put_16 (abfd,
2307		    (bfd_vma) data,
2308		    htab->splt->contents + (i*2));
2309      }
2310  }
2311  PLT_DO_RELOCS_FOR_ENTRY (abfd, htab, plt_data->entry_relocs);
2312}
2313
2314/* Desc : Adjust a symbol defined by a dynamic object and referenced
2315   by a regular object.  The current definition is in some section of
2316   the dynamic object, but we're not including those sections.  We
2317   have to change the definition to something the rest of the link can
2318   understand.  */
2319
2320static bfd_boolean
2321elf_arc_adjust_dynamic_symbol (struct bfd_link_info *info,
2322			      struct elf_link_hash_entry *h)
2323{
2324  asection *s;
2325  bfd *dynobj = (elf_hash_table (info))->dynobj;
2326  struct elf_link_hash_table *htab = elf_hash_table (info);
2327
2328  if (h->type == STT_FUNC
2329      || h->type == STT_GNU_IFUNC
2330      || h->needs_plt == 1)
2331    {
2332      if (!bfd_link_pic (info) && !h->def_dynamic && !h->ref_dynamic)
2333	{
2334	  /* This case can occur if we saw a PLT32 reloc in an input
2335	     file, but the symbol was never referred to by a dynamic
2336	     object.  In such a case, we don't actually need to build
2337	     a procedure linkage table, and we can just do a PC32
2338	     reloc instead.  */
2339	  BFD_ASSERT (h->needs_plt);
2340	  return TRUE;
2341	}
2342
2343      /* Make sure this symbol is output as a dynamic symbol.  */
2344      if (h->dynindx == -1 && !h->forced_local
2345	  && !bfd_elf_link_record_dynamic_symbol (info, h))
2346	return FALSE;
2347
2348      if (bfd_link_pic (info)
2349	  || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
2350	{
2351	  bfd_vma loc = add_symbol_to_plt (info);
2352
2353	  if (bfd_link_executable (info) && !h->def_regular)
2354	    {
2355	      h->root.u.def.section = htab->splt;
2356	      h->root.u.def.value = loc;
2357	    }
2358	  h->plt.offset = loc;
2359	}
2360      else
2361	{
2362	  h->plt.offset = (bfd_vma) -1;
2363	  h->needs_plt = 0;
2364	}
2365      return TRUE;
2366    }
2367
2368  /* If this is a weak symbol, and there is a real definition, the
2369     processor independent code will have arranged for us to see the
2370     real definition first, and we can just use the same value.  */
2371  if (h->is_weakalias)
2372    {
2373      struct elf_link_hash_entry *def = weakdef (h);
2374      BFD_ASSERT (def->root.type == bfd_link_hash_defined);
2375      h->root.u.def.section = def->root.u.def.section;
2376      h->root.u.def.value = def->root.u.def.value;
2377      return TRUE;
2378    }
2379
2380  /* This is a reference to a symbol defined by a dynamic object which
2381     is not a function.  */
2382
2383  /* If we are creating a shared library, we must presume that the
2384     only references to the symbol are via the global offset table.
2385     For such cases we need not do anything here; the relocations will
2386     be handled correctly by relocate_section.  */
2387  if (!bfd_link_executable (info))
2388    return TRUE;
2389
2390  /* If there are no non-GOT references, we do not need a copy
2391     relocation.  */
2392  if (!h->non_got_ref)
2393    return TRUE;
2394
2395  /* If -z nocopyreloc was given, we won't generate them either.  */
2396  if (info->nocopyreloc)
2397    {
2398      h->non_got_ref = 0;
2399      return TRUE;
2400    }
2401
2402  /* We must allocate the symbol in our .dynbss section, which will
2403     become part of the .bss section of the executable.  There will be
2404     an entry for this symbol in the .dynsym section.  The dynamic
2405     object will contain position independent code, so all references
2406     from the dynamic object to this symbol will go through the global
2407     offset table.  The dynamic linker will use the .dynsym entry to
2408     determine the address it must put in the global offset table, so
2409     both the dynamic object and the regular object will refer to the
2410     same memory location for the variable.  */
2411
2412  if (htab == NULL)
2413    return FALSE;
2414
2415  /* We must generate a R_ARC_COPY reloc to tell the dynamic linker to
2416     copy the initial value out of the dynamic object and into the
2417     runtime process image.  We need to remember the offset into the
2418     .rela.bss section we are going to use.  */
2419  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2420    {
2421      struct elf_arc_link_hash_table *arc_htab = elf_arc_hash_table (info);
2422
2423      BFD_ASSERT (arc_htab->elf.srelbss != NULL);
2424      arc_htab->elf.srelbss->size += sizeof (Elf32_External_Rela);
2425      h->needs_copy = 1;
2426    }
2427
2428  /* TODO: Move this also to arc_hash_table.  */
2429  s = bfd_get_section_by_name (dynobj, ".dynbss");
2430  BFD_ASSERT (s != NULL);
2431
2432  return _bfd_elf_adjust_dynamic_copy (info, h, s);
2433}
2434
2435/* Function :  elf_arc_finish_dynamic_symbol
2436   Brief    :  Finish up dynamic symbol handling.  We set the
2437	     contents of various dynamic sections here.
2438   Args     :  output_bfd :
2439	       info	  :
2440	       h	  :
2441	       sym	  :
2442   Returns  : True/False as the return status.  */
2443
2444static bfd_boolean
2445elf_arc_finish_dynamic_symbol (bfd * output_bfd,
2446			       struct bfd_link_info *info,
2447			       struct elf_link_hash_entry *h,
2448			       Elf_Internal_Sym * sym)
2449{
2450  if (h->plt.offset != (bfd_vma) -1)
2451    {
2452      relocate_plt_for_symbol (output_bfd, info, h);
2453
2454      if (!h->def_regular)
2455	{
2456	  /* Mark the symbol as undefined, rather than as defined in
2457	     the .plt section.  Leave the value alone.  */
2458	  sym->st_shndx = SHN_UNDEF;
2459	}
2460    }
2461
2462
2463  /* This function traverses list of GOT entries and
2464     create respective dynamic relocs.  */
2465  /* TODO: Make function to get list and not access the list directly.  */
2466  /* TODO: Move function to relocate_section create this relocs eagerly.  */
2467  struct elf_arc_link_hash_entry *ah =
2468    (struct elf_arc_link_hash_entry *) h;
2469  create_got_dynrelocs_for_got_info (&ah->got_ents,
2470				     output_bfd,
2471				     info,
2472				     h);
2473
2474  if (h->needs_copy)
2475    {
2476      struct elf_arc_link_hash_table *arc_htab = elf_arc_hash_table (info);
2477
2478      if (arc_htab == NULL)
2479	return FALSE;
2480
2481      if (h->dynindx == -1
2482	  || (h->root.type != bfd_link_hash_defined
2483	      && h->root.type != bfd_link_hash_defweak)
2484	  || arc_htab->elf.srelbss == NULL)
2485	abort ();
2486
2487      bfd_vma rel_offset = (h->root.u.def.value
2488			    + h->root.u.def.section->output_section->vma
2489			    + h->root.u.def.section->output_offset);
2490
2491      bfd_byte * loc = arc_htab->elf.srelbss->contents
2492	+ (arc_htab->elf.srelbss->reloc_count * sizeof (Elf32_External_Rela));
2493      arc_htab->elf.srelbss->reloc_count++;
2494
2495      Elf_Internal_Rela rel;
2496      rel.r_addend = 0;
2497      rel.r_offset = rel_offset;
2498
2499      BFD_ASSERT (h->dynindx != -1);
2500      rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_COPY);
2501
2502      bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2503    }
2504
2505  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
2506  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2507      || strcmp (h->root.root.string, "__DYNAMIC") == 0
2508      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
2509    sym->st_shndx = SHN_ABS;
2510
2511  return TRUE;
2512}
2513
2514#define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION)		\
2515  case TAG:							\
2516  if (SYMBOL != NULL)						\
2517    h = elf_link_hash_lookup (elf_hash_table (info),		\
2518			      SYMBOL, FALSE, FALSE, TRUE);	\
2519  else if (SECTION != NULL)					\
2520    s = bfd_get_linker_section (dynobj, SECTION);		\
2521  break;
2522
2523
2524struct obfd_info_group {
2525  bfd *output_bfd;
2526  struct bfd_link_info *info;
2527};
2528
2529static bfd_boolean
2530arc_create_forced_local_got_entries_for_tls (struct bfd_hash_entry *bh,
2531					     void *data)
2532{
2533  struct elf_arc_link_hash_entry * h =
2534    (struct elf_arc_link_hash_entry *) bh;
2535  struct obfd_info_group *tmp = (struct obfd_info_group *) data;
2536
2537  if (h->got_ents != NULL)
2538    {
2539      BFD_ASSERT (h);
2540
2541      struct got_entry *list = h->got_ents;
2542
2543      while (list != NULL)
2544	{
2545	  create_got_dynrelocs_for_single_entry (list, tmp->output_bfd,
2546	    tmp->info,
2547	    (struct elf_link_hash_entry *) h);
2548	  list = list->next;
2549	}
2550    }
2551
2552  return TRUE;
2553}
2554
2555
2556/* Function :  elf_arc_finish_dynamic_sections
2557   Brief    :  Finish up the dynamic sections handling.
2558   Args     :  output_bfd :
2559	       info	  :
2560	       h	  :
2561	       sym	  :
2562   Returns  : True/False as the return status.  */
2563
2564static bfd_boolean
2565elf_arc_finish_dynamic_sections (bfd * output_bfd,
2566				 struct bfd_link_info *info)
2567{
2568  struct elf_link_hash_table *htab = elf_hash_table (info);
2569  bfd *dynobj = (elf_hash_table (info))->dynobj;
2570  asection *sdyn = bfd_get_linker_section (dynobj, ".dynamic");
2571
2572  if (sdyn)
2573    {
2574      Elf32_External_Dyn *dyncon, *dynconend;
2575
2576      dyncon = (Elf32_External_Dyn *) sdyn->contents;
2577      dynconend
2578	= (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
2579      for (; dyncon < dynconend; dyncon++)
2580	{
2581	  Elf_Internal_Dyn internal_dyn;
2582	  bfd_boolean	  do_it = FALSE;
2583
2584	  struct elf_link_hash_entry *h = NULL;
2585	  asection	 *s = NULL;
2586
2587	  bfd_elf32_swap_dyn_in (dynobj, dyncon, &internal_dyn);
2588
2589	  switch (internal_dyn.d_tag)
2590	    {
2591	      GET_SYMBOL_OR_SECTION (DT_INIT, info->init_function, NULL)
2592	      GET_SYMBOL_OR_SECTION (DT_FINI, info->fini_function, NULL)
2593	      GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt")
2594	      GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt")
2595	      GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt")
2596	      GET_SYMBOL_OR_SECTION (DT_VERSYM, NULL, ".gnu.version")
2597	      GET_SYMBOL_OR_SECTION (DT_VERDEF, NULL, ".gnu.version_d")
2598	      GET_SYMBOL_OR_SECTION (DT_VERNEED, NULL, ".gnu.version_r")
2599	      default:
2600		break;
2601	    }
2602
2603	  /* In case the dynamic symbols should be updated with a symbol.  */
2604	  if (h != NULL
2605	      && (h->root.type == bfd_link_hash_defined
2606		  || h->root.type == bfd_link_hash_defweak))
2607	    {
2608	      asection	     *asec_ptr;
2609
2610	      internal_dyn.d_un.d_val = h->root.u.def.value;
2611	      asec_ptr = h->root.u.def.section;
2612	      if (asec_ptr->output_section != NULL)
2613		{
2614		  internal_dyn.d_un.d_val +=
2615		    (asec_ptr->output_section->vma
2616		     + asec_ptr->output_offset);
2617		}
2618	      else
2619		{
2620		  /* The symbol is imported from another shared
2621		     library and does not apply to this one.  */
2622		  internal_dyn.d_un.d_val = 0;
2623		}
2624	      do_it = TRUE;
2625	    }
2626	  else if (s != NULL) /* With a section information.  */
2627	    {
2628	      switch (internal_dyn.d_tag)
2629		{
2630		  case DT_PLTGOT:
2631		  case DT_JMPREL:
2632		  case DT_VERSYM:
2633		  case DT_VERDEF:
2634		  case DT_VERNEED:
2635		    internal_dyn.d_un.d_ptr = (s->output_section->vma
2636					       + s->output_offset);
2637		    do_it = TRUE;
2638		    break;
2639
2640		  case DT_PLTRELSZ:
2641		    internal_dyn.d_un.d_val = s->size;
2642		    do_it = TRUE;
2643		    break;
2644
2645		  default:
2646		    break;
2647		}
2648	    }
2649
2650	  if (do_it)
2651	    bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon);
2652	}
2653
2654      if (htab->splt->size > 0)
2655	{
2656	  relocate_plt_for_entry (output_bfd, info);
2657	}
2658
2659      /* TODO: Validate this.  */
2660      if (htab->srelplt->output_section != bfd_abs_section_ptr)
2661	elf_section_data (htab->srelplt->output_section)
2662	  ->this_hdr.sh_entsize = 12;
2663    }
2664
2665  /* Fill in the first three entries in the global offset table.  */
2666  if (htab->sgot)
2667    {
2668      struct elf_link_hash_entry *h;
2669      h = elf_link_hash_lookup (elf_hash_table (info), "_GLOBAL_OFFSET_TABLE_",
2670				 FALSE, FALSE, TRUE);
2671
2672	if (h != NULL && h->root.type != bfd_link_hash_undefined
2673	    && h->root.u.def.section != NULL)
2674	{
2675	  asection *sec = h->root.u.def.section;
2676
2677	  if (sdyn == NULL)
2678	    bfd_put_32 (output_bfd, (bfd_vma) 0,
2679			sec->contents);
2680	  else
2681	    bfd_put_32 (output_bfd,
2682			sdyn->output_section->vma + sdyn->output_offset,
2683			sec->contents);
2684	  bfd_put_32 (output_bfd, (bfd_vma) 0, sec->contents + 4);
2685	  bfd_put_32 (output_bfd, (bfd_vma) 0, sec->contents + 8);
2686	}
2687    }
2688
2689  struct obfd_info_group group;
2690  group.output_bfd = output_bfd;
2691  group.info = info;
2692  bfd_hash_traverse (&info->hash->table,
2693		     arc_create_forced_local_got_entries_for_tls, &group);
2694
2695  return TRUE;
2696}
2697
2698#define ADD_DYNAMIC_SYMBOL(NAME, TAG)					\
2699  h =  elf_link_hash_lookup (elf_hash_table (info),			\
2700			     NAME, FALSE, FALSE, FALSE);		\
2701  if ((h != NULL && (h->ref_regular || h->def_regular)))		\
2702    if (! _bfd_elf_add_dynamic_entry (info, TAG, 0))			\
2703      return FALSE;
2704
2705/* Set the sizes of the dynamic sections.  */
2706static bfd_boolean
2707elf_arc_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2708			       struct bfd_link_info *info)
2709{
2710  bfd *dynobj;
2711  asection *s;
2712  bfd_boolean relocs_exist = FALSE;
2713  bfd_boolean reltext_exist = FALSE;
2714  struct elf_link_hash_table *htab = elf_hash_table (info);
2715
2716  dynobj = htab->dynobj;
2717  BFD_ASSERT (dynobj != NULL);
2718
2719  if (htab->dynamic_sections_created)
2720    {
2721      struct elf_link_hash_entry *h;
2722
2723      /* Set the contents of the .interp section to the
2724	 interpreter.  */
2725      if (bfd_link_executable (info) && !info->nointerp)
2726	{
2727	  s = bfd_get_section_by_name (dynobj, ".interp");
2728	  BFD_ASSERT (s != NULL);
2729	  s->size = sizeof (ELF_DYNAMIC_INTERPRETER);
2730	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2731	}
2732
2733      /* Add some entries to the .dynamic section.  We fill in some of
2734	 the values later, in elf_bfd_final_link, but we must add the
2735	 entries now so that we know the final size of the .dynamic
2736	 section.  Checking if the .init section is present.  We also
2737	 create DT_INIT and DT_FINI entries if the init_str has been
2738	 changed by the user.  */
2739      ADD_DYNAMIC_SYMBOL (info->init_function, DT_INIT);
2740      ADD_DYNAMIC_SYMBOL (info->fini_function, DT_FINI);
2741    }
2742  else
2743    {
2744      /* We may have created entries in the .rela.got section.
2745	 However, if we are not creating the dynamic sections, we will
2746	 not actually use these entries.  Reset the size of .rela.got,
2747	 which will cause it to get stripped from the output file
2748	 below.  */
2749      if (htab->srelgot != NULL)
2750	htab->srelgot->size = 0;
2751    }
2752
2753  for (s = dynobj->sections; s != NULL; s = s->next)
2754    {
2755      if ((s->flags & SEC_LINKER_CREATED) == 0)
2756	continue;
2757
2758      if (s == htab->splt
2759	  || s == htab->sgot
2760	  || s == htab->sgotplt
2761	  || s == htab->sdynbss)
2762	{
2763	  /* Strip this section if we don't need it.  */
2764	}
2765      else if (strncmp (s->name, ".rela", 5) == 0)
2766	{
2767	  if (s->size != 0 && s != htab->srelplt)
2768	    {
2769	      if (!reltext_exist)
2770		{
2771		  const char *name = s->name + 5;
2772		  bfd *ibfd;
2773		  for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next)
2774		    if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
2775			&& ibfd->flags & DYNAMIC)
2776		      {
2777			asection *target = bfd_get_section_by_name (ibfd, name);
2778			if (target != NULL
2779			    && elf_section_data (target)->sreloc == s
2780			    && ((target->output_section->flags
2781				 & (SEC_READONLY | SEC_ALLOC))
2782				== (SEC_READONLY | SEC_ALLOC)))
2783			  {
2784			    reltext_exist = TRUE;
2785			    break;
2786			  }
2787		      }
2788		}
2789	      relocs_exist = TRUE;
2790	    }
2791
2792	  /* We use the reloc_count field as a counter if we need to
2793	     copy relocs into the output file.  */
2794	  s->reloc_count = 0;
2795	}
2796      else
2797	{
2798	  /* It's not one of our sections, so don't allocate space.  */
2799	  continue;
2800	}
2801
2802      if (s->size == 0)
2803	{
2804	  s->flags |= SEC_EXCLUDE;
2805	  continue;
2806	}
2807
2808      if ((s->flags & SEC_HAS_CONTENTS) == 0)
2809	continue;
2810
2811      /* Allocate memory for the section contents.  */
2812      s->contents = bfd_zalloc (dynobj, s->size);
2813      if (s->contents == NULL)
2814	return FALSE;
2815    }
2816
2817  if (htab->dynamic_sections_created)
2818    {
2819      /* TODO: Check if this is needed.  */
2820      if (!bfd_link_pic (info))
2821	if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
2822		return FALSE;
2823
2824      if (htab->splt && (htab->splt->flags & SEC_EXCLUDE) == 0)
2825	if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
2826	    || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2827	    || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2828	    || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
2829	  return FALSE;
2830
2831      if (relocs_exist)
2832	if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
2833	    || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
2834	    || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
2835					    sizeof (Elf32_External_Rela)))
2836	  return FALSE;
2837
2838      if (reltext_exist)
2839	if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
2840	  return FALSE;
2841    }
2842
2843  return TRUE;
2844}
2845
2846
2847/* Classify dynamic relocs such that -z combreloc can reorder and combine
2848   them.  */
2849static enum elf_reloc_type_class
2850elf32_arc_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
2851			    const asection *rel_sec ATTRIBUTE_UNUSED,
2852			    const Elf_Internal_Rela *rela)
2853{
2854  switch ((int) ELF32_R_TYPE (rela->r_info))
2855    {
2856    case R_ARC_RELATIVE:
2857      return reloc_class_relative;
2858    case R_ARC_JMP_SLOT:
2859      return reloc_class_plt;
2860    case R_ARC_COPY:
2861      return reloc_class_copy;
2862    /* TODO: Needed in future to support ifunc.  */
2863    /*
2864    case R_ARC_IRELATIVE:
2865      return reloc_class_ifunc;
2866    */
2867    default:
2868      return reloc_class_normal;
2869    }
2870}
2871
2872const struct elf_size_info arc_elf32_size_info =
2873{
2874  sizeof (Elf32_External_Ehdr),
2875  sizeof (Elf32_External_Phdr),
2876  sizeof (Elf32_External_Shdr),
2877  sizeof (Elf32_External_Rel),
2878  sizeof (Elf32_External_Rela),
2879  sizeof (Elf32_External_Sym),
2880  sizeof (Elf32_External_Dyn),
2881  sizeof (Elf_External_Note),
2882  4,
2883  1,
2884  32, 2,
2885  ELFCLASS32, EV_CURRENT,
2886  bfd_elf32_write_out_phdrs,
2887  bfd_elf32_write_shdrs_and_ehdr,
2888  bfd_elf32_checksum_contents,
2889  bfd_elf32_write_relocs,
2890  bfd_elf32_swap_symbol_in,
2891  bfd_elf32_swap_symbol_out,
2892  bfd_elf32_slurp_reloc_table,
2893  bfd_elf32_slurp_symbol_table,
2894  bfd_elf32_swap_dyn_in,
2895  bfd_elf32_swap_dyn_out,
2896  bfd_elf32_swap_reloc_in,
2897  bfd_elf32_swap_reloc_out,
2898  bfd_elf32_swap_reloca_in,
2899  bfd_elf32_swap_reloca_out
2900};
2901
2902#define elf_backend_size_info		arc_elf32_size_info
2903
2904/* GDB expects general purpose registers to be in section .reg.  However Linux
2905   kernel doesn't create this section and instead writes registers to NOTE
2906   section.  It is up to the binutils to create a pseudo-section .reg from the
2907   contents of NOTE.  Also BFD will read pid and signal number from NOTE.  This
2908   function relies on offsets inside elf_prstatus structure in Linux to be
2909   stable.  */
2910
2911static bfd_boolean
2912elf32_arc_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
2913{
2914  int offset;
2915  size_t size;
2916
2917  switch (note->descsz)
2918    {
2919    default:
2920      return FALSE;
2921
2922    case 236: /* sizeof (struct elf_prstatus) on Linux/arc.  */
2923      /* pr_cursig */
2924      elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
2925      /* pr_pid */
2926      elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
2927      /* pr_regs */
2928      offset = 72;
2929      size = (40 * 4); /* There are 40 registers in user_regs_struct.  */
2930      break;
2931    }
2932  /* Make a ".reg/999" section.  */
2933  return _bfd_elfcore_make_pseudosection (abfd, ".reg", size,
2934					  note->descpos + offset);
2935}
2936
2937/* Determine whether an object attribute tag takes an integer, a
2938   string or both.  */
2939
2940static int
2941elf32_arc_obj_attrs_arg_type (int tag)
2942{
2943  if (tag == Tag_ARC_CPU_name
2944	   || tag == Tag_ARC_ISA_config
2945	   || tag == Tag_ARC_ISA_apex)
2946    return ATTR_TYPE_FLAG_STR_VAL;
2947  else if (tag < (Tag_ARC_ISA_mpy_option + 1))
2948    return ATTR_TYPE_FLAG_INT_VAL;
2949  else
2950    return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL;
2951}
2952
2953/* Attribute numbers >=14 can be safely ignored.  */
2954
2955static bfd_boolean
2956elf32_arc_obj_attrs_handle_unknown (bfd *abfd, int tag)
2957{
2958  if ((tag & 127) < (Tag_ARC_ISA_mpy_option + 1))
2959    {
2960      _bfd_error_handler
2961	(_("%pB: unknown mandatory ARC object attribute %d"),
2962	 abfd, tag);
2963      bfd_set_error (bfd_error_bad_value);
2964      return FALSE;
2965    }
2966  else
2967    {
2968      _bfd_error_handler
2969	(_("warning: %pB: unknown ARC object attribute %d"),
2970	 abfd, tag);
2971      return TRUE;
2972    }
2973}
2974
2975/* Handle an ARC specific section when reading an object file.  This is
2976   called when bfd_section_from_shdr finds a section with an unknown
2977   type.  */
2978
2979static bfd_boolean
2980elf32_arc_section_from_shdr (bfd *abfd,
2981			     Elf_Internal_Shdr * hdr,
2982			     const char *name,
2983			     int shindex)
2984{
2985  switch (hdr->sh_type)
2986    {
2987    case 0x0c: /* MWDT specific section, don't complain about it.  */
2988    case SHT_ARC_ATTRIBUTES:
2989      break;
2990
2991    default:
2992      return FALSE;
2993    }
2994
2995  if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
2996    return FALSE;
2997
2998  return TRUE;
2999}
3000
3001/* Relaxation hook.
3002
3003   These are the current relaxing opportunities available:
3004
3005   * R_ARC_GOTPC32 => R_ARC_PCREL.
3006
3007*/
3008
3009static bfd_boolean
3010arc_elf_relax_section (bfd *abfd, asection *sec,
3011		       struct bfd_link_info *link_info, bfd_boolean *again)
3012{
3013  Elf_Internal_Shdr *symtab_hdr;
3014  Elf_Internal_Rela *internal_relocs;
3015  Elf_Internal_Rela *irel, *irelend;
3016  bfd_byte *contents = NULL;
3017  Elf_Internal_Sym *isymbuf = NULL;
3018
3019  /* Assume nothing changes.  */
3020  *again = FALSE;
3021
3022  /* We don't have to do anything for a relocatable link, if this
3023     section does not have relocs, or if this is not a code
3024     section.  */
3025  if (bfd_link_relocatable (link_info)
3026      || (sec->flags & SEC_RELOC) == 0
3027      || sec->reloc_count == 0
3028      || (sec->flags & SEC_CODE) == 0)
3029    return TRUE;
3030
3031  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
3032
3033  /* Get a copy of the native relocations.  */
3034  internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
3035                                               link_info->keep_memory);
3036  if (internal_relocs == NULL)
3037    goto error_return;
3038
3039  /* Walk through them looking for relaxing opportunities.  */
3040  irelend = internal_relocs + sec->reloc_count;
3041  for (irel = internal_relocs; irel < irelend; irel++)
3042    {
3043      /* If this isn't something that can be relaxed, then ignore
3044         this reloc.  */
3045      if (ELF32_R_TYPE (irel->r_info) != (int) R_ARC_GOTPC32)
3046        continue;
3047
3048      /* Get the section contents if we haven't done so already.  */
3049      if (contents == NULL)
3050        {
3051          /* Get cached copy if it exists.  */
3052          if (elf_section_data (sec)->this_hdr.contents != NULL)
3053            contents = elf_section_data (sec)->this_hdr.contents;
3054          /* Go get them off disk.  */
3055          else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
3056            goto error_return;
3057        }
3058
3059      /* Read this BFD's local symbols if we haven't done so already.  */
3060      if (isymbuf == NULL && symtab_hdr->sh_info != 0)
3061        {
3062          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
3063          if (isymbuf == NULL)
3064            isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
3065                                            symtab_hdr->sh_info, 0,
3066                                            NULL, NULL, NULL);
3067          if (isymbuf == NULL)
3068            goto error_return;
3069        }
3070
3071      struct elf_link_hash_entry *htop = NULL;
3072
3073      if (ELF32_R_SYM (irel->r_info) >= symtab_hdr->sh_info)
3074	{
3075	  /* An external symbol.  */
3076	  unsigned int indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
3077	  htop = elf_sym_hashes (abfd)[indx];
3078	}
3079
3080      if (ELF32_R_TYPE (irel->r_info) == (int) R_ARC_GOTPC32
3081	  && SYMBOL_REFERENCES_LOCAL (link_info, htop))
3082	{
3083	  unsigned int code;
3084
3085	  /* Get the opcode.  */
3086	  code = bfd_get_32_me (abfd, contents + irel->r_offset - 4);
3087
3088	  /* Note that we've changed the relocs, section contents, etc.  */
3089	  elf_section_data (sec)->relocs = internal_relocs;
3090	  elf_section_data (sec)->this_hdr.contents = contents;
3091	  symtab_hdr->contents = (unsigned char *) isymbuf;
3092
3093	  /* Fix the relocation's type.  */
3094	  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_ARC_PC32);
3095
3096	  /* ld rA,[pcl,symbol@tgot] -> add rA,pcl,symbol@pcl.  */
3097	  /* 0010 0bbb aa11 0ZZX DBBB 1111 10AA AAAA.
3098	           111 00    000 0111        xx xxxx*/
3099	  code &= ~0x27307F80;
3100	  BFD_ASSERT (code <= 62UL);
3101	  code |= 0x27007F80;
3102
3103	  /* Write back the new instruction.  */
3104	  bfd_put_32_me (abfd, code, contents + irel->r_offset - 4);
3105
3106	  /* The size isn't changed, don't redo.  */
3107	  *again = FALSE;
3108	}
3109    }
3110
3111  if (isymbuf != NULL
3112      && symtab_hdr->contents != (unsigned char *) isymbuf)
3113    {
3114      if (!link_info->keep_memory)
3115        free (isymbuf);
3116      else
3117       /* Cache the symbols for elf_link_input_bfd.  */
3118       symtab_hdr->contents = (unsigned char *) isymbuf;
3119    }
3120
3121  if (contents != NULL
3122      && elf_section_data (sec)->this_hdr.contents != contents)
3123    {
3124      if (!link_info->keep_memory)
3125        free (contents);
3126      else
3127       /* Cache the section contents for elf_link_input_bfd.  */
3128       elf_section_data (sec)->this_hdr.contents = contents;
3129    }
3130
3131  if (internal_relocs != NULL
3132      && elf_section_data (sec)->relocs != internal_relocs)
3133    free (internal_relocs);
3134
3135  return TRUE;
3136
3137 error_return:
3138  if (isymbuf != NULL
3139      && symtab_hdr->contents != (unsigned char *) isymbuf)
3140    free (isymbuf);
3141  if (contents != NULL
3142      && elf_section_data (sec)->this_hdr.contents != contents)
3143    free (contents);
3144  if (internal_relocs != NULL
3145      && elf_section_data (sec)->relocs != internal_relocs)
3146    free (internal_relocs);
3147
3148  return FALSE;
3149}
3150
3151#define TARGET_LITTLE_SYM   arc_elf32_le_vec
3152#define TARGET_LITTLE_NAME  "elf32-littlearc"
3153#define TARGET_BIG_SYM	    arc_elf32_be_vec
3154#define TARGET_BIG_NAME     "elf32-bigarc"
3155#define ELF_ARCH	    bfd_arch_arc
3156#define ELF_TARGET_ID	    ARC_ELF_DATA
3157#define ELF_MACHINE_CODE    EM_ARC_COMPACT
3158#define ELF_MACHINE_ALT1    EM_ARC_COMPACT2
3159#define ELF_MAXPAGESIZE     0x2000
3160
3161#define bfd_elf32_bfd_link_hash_table_create	arc_elf_link_hash_table_create
3162
3163#define bfd_elf32_bfd_merge_private_bfd_data    arc_elf_merge_private_bfd_data
3164#define bfd_elf32_bfd_reloc_type_lookup		arc_elf32_bfd_reloc_type_lookup
3165#define bfd_elf32_bfd_set_private_flags		arc_elf_set_private_flags
3166#define bfd_elf32_bfd_print_private_bfd_data    arc_elf_print_private_bfd_data
3167#define bfd_elf32_bfd_copy_private_bfd_data     arc_elf_copy_private_bfd_data
3168#define bfd_elf32_bfd_relax_section		arc_elf_relax_section
3169
3170#define elf_info_to_howto_rel		     arc_info_to_howto_rel
3171#define elf_backend_object_p		     arc_elf_object_p
3172#define elf_backend_final_write_processing   arc_elf_final_write_processing
3173
3174#define elf_backend_relocate_section	     elf_arc_relocate_section
3175#define elf_backend_check_relocs	     elf_arc_check_relocs
3176#define elf_backend_create_dynamic_sections  _bfd_elf_create_dynamic_sections
3177
3178#define elf_backend_reloc_type_class		elf32_arc_reloc_type_class
3179
3180#define elf_backend_adjust_dynamic_symbol    elf_arc_adjust_dynamic_symbol
3181#define elf_backend_finish_dynamic_symbol    elf_arc_finish_dynamic_symbol
3182
3183#define elf_backend_finish_dynamic_sections  elf_arc_finish_dynamic_sections
3184#define elf_backend_size_dynamic_sections    elf_arc_size_dynamic_sections
3185
3186#define elf_backend_can_gc_sections	1
3187#define elf_backend_want_got_plt	1
3188#define elf_backend_plt_readonly	1
3189#define elf_backend_rela_plts_and_copies_p 1
3190#define elf_backend_want_plt_sym	0
3191#define elf_backend_got_header_size	12
3192#define elf_backend_dtrel_excludes_plt	1
3193
3194#define elf_backend_may_use_rel_p	0
3195#define elf_backend_may_use_rela_p	1
3196#define elf_backend_default_use_rela_p	1
3197
3198#define elf_backend_grok_prstatus elf32_arc_grok_prstatus
3199
3200#define elf_backend_default_execstack	0
3201
3202#undef  elf_backend_obj_attrs_vendor
3203#define elf_backend_obj_attrs_vendor		"ARC"
3204#undef  elf_backend_obj_attrs_section
3205#define elf_backend_obj_attrs_section		".ARC.attributes"
3206#undef  elf_backend_obj_attrs_arg_type
3207#define elf_backend_obj_attrs_arg_type		elf32_arc_obj_attrs_arg_type
3208#undef  elf_backend_obj_attrs_section_type
3209#define elf_backend_obj_attrs_section_type	SHT_ARC_ATTRIBUTES
3210#define elf_backend_obj_attrs_handle_unknown	elf32_arc_obj_attrs_handle_unknown
3211
3212#define elf_backend_section_from_shdr		elf32_arc_section_from_shdr
3213
3214#include "elf32-target.h"
3215