xref: /netbsd-src/external/gpl3/gdb/dist/bfd/elf32-arc.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /* ARC-specific support for 32-bit ELF
2    Copyright (C) 1994-2017 Free Software Foundation, Inc.
3    Contributed by Cupertino Miranda (cmiranda@synopsys.com).
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 ARC_ENABLE_DEBUG 1  */
33 #ifdef ARC_ENABLE_DEBUG
34 static const char *
35 name_for_global_symbol (struct elf_link_hash_entry *h)
36 {
37   static char *local_str = "(local)";
38   if (h == NULL)
39     return local_str;
40   return h->root.root.string;
41 }
42 #define ARC_DEBUG(fmt, args...) fprintf (stderr, fmt, ##args)
43 #else
44 #define ARC_DEBUG(...)
45 #endif
46 
47 
48 #define ADD_RELA(BFD, SECTION, OFFSET, SYM_IDX, TYPE, ADDEND)		\
49   {									\
50     struct elf_link_hash_table *_htab = elf_hash_table (info);		\
51     Elf_Internal_Rela _rel;						\
52     bfd_byte * _loc;							\
53 									\
54     BFD_ASSERT (_htab->srel##SECTION &&_htab->srel##SECTION->contents); \
55     _loc = _htab->srel##SECTION->contents				\
56       + ((_htab->srel##SECTION->reloc_count)				\
57 	 * sizeof (Elf32_External_Rela));				\
58     _htab->srel##SECTION->reloc_count++;				\
59     _rel.r_addend = ADDEND;						\
60     _rel.r_offset = (_htab->s##SECTION)->output_section->vma		\
61       + (_htab->s##SECTION)->output_offset + OFFSET;			\
62     BFD_ASSERT ((long) SYM_IDX != -1);					\
63     _rel.r_info = ELF32_R_INFO (SYM_IDX, TYPE);				\
64     bfd_elf32_swap_reloca_out (BFD, &_rel, _loc);			\
65   }
66 
67 
68 /* The default symbols representing the init and fini dyn values.
69    TODO: Check what is the relation of those strings with arclinux.em
70    and DT_INIT.  */
71 #define INIT_SYM_STRING "_init"
72 #define FINI_SYM_STRING "_fini"
73 
74 char * init_str = INIT_SYM_STRING;
75 char * fini_str = FINI_SYM_STRING;
76 
77 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
78       case VALUE: \
79 	return "R_" #TYPE; \
80 	break;
81 
82 static ATTRIBUTE_UNUSED const char *
83 reloc_type_to_name (unsigned int type)
84 {
85   switch (type)
86     {
87       #include "elf/arc-reloc.def"
88 
89       default:
90 	return "UNKNOWN";
91 	break;
92     }
93 }
94 #undef ARC_RELOC_HOWTO
95 
96 /* Try to minimize the amount of space occupied by relocation tables
97    on the ROM (not that the ROM won't be swamped by other ELF overhead).  */
98 
99 #define USE_REL 1
100 
101 static ATTRIBUTE_UNUSED bfd_boolean
102 is_reloc_PC_relative (reloc_howto_type *howto)
103 {
104   return (strstr (howto->name, "PC") != NULL) ? TRUE : FALSE;
105 }
106 
107 static bfd_boolean
108 is_reloc_SDA_relative (reloc_howto_type *howto)
109 {
110   return (strstr (howto->name, "SDA") != NULL) ? TRUE : FALSE;
111 }
112 
113 static bfd_boolean
114 is_reloc_for_GOT (reloc_howto_type * howto)
115 {
116   if (strstr (howto->name, "TLS") != NULL)
117     return FALSE;
118   return (strstr (howto->name, "GOT") != NULL) ? TRUE : FALSE;
119 }
120 
121 static bfd_boolean
122 is_reloc_for_PLT (reloc_howto_type * howto)
123 {
124   return (strstr (howto->name, "PLT") != NULL) ? TRUE : FALSE;
125 }
126 
127 static bfd_boolean
128 is_reloc_for_TLS (reloc_howto_type *howto)
129 {
130   return (strstr (howto->name, "TLS") != NULL) ? TRUE : FALSE;
131 }
132 
133 struct arc_relocation_data
134 {
135   bfd_signed_vma  reloc_offset;
136   bfd_signed_vma  reloc_addend;
137   bfd_signed_vma  got_offset_value;
138 
139   bfd_signed_vma  sym_value;
140   asection *	  sym_section;
141 
142   reloc_howto_type *howto;
143 
144   asection *	  input_section;
145 
146   bfd_signed_vma  sdata_begin_symbol_vma;
147   bfd_boolean	  sdata_begin_symbol_vma_set;
148   bfd_signed_vma  got_symbol_vma;
149 
150   bfd_boolean	  should_relocate;
151 
152   const char *    symbol_name;
153 };
154 
155 /* Should be included at this location due to static declarations
156  * defined before this point.  */
157 #include "arc-got.h"
158 
159 #define arc_bfd_get_8(A,B,C) bfd_get_8(A,B)
160 #define arc_bfd_get_16(A,B,C) bfd_get_16(A,B)
161 #define arc_bfd_get_32(A,B,C) bfd_get_32(A,B)
162 #define arc_bfd_put_8(A,B,C,D) bfd_put_8(A,B,C)
163 #define arc_bfd_put_16(A,B,C,D) bfd_put_16(A,B,C)
164 #define arc_bfd_put_32(A,B,C,D) bfd_put_32(A,B,C)
165 
166 
167 static bfd_reloc_status_type
168 arc_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED,
169 	       arelent *reloc_entry,
170 	       asymbol *symbol_in,
171 	       void *data ATTRIBUTE_UNUSED,
172 	       asection *input_section,
173 	       bfd *output_bfd,
174 	       char ** error_message ATTRIBUTE_UNUSED)
175 {
176   if (output_bfd != NULL)
177     {
178       reloc_entry->address += input_section->output_offset;
179 
180       /* In case of relocateable link and if the reloc is against a
181 	 section symbol, the addend needs to be adjusted according to
182 	 where the section symbol winds up in the output section.  */
183       if ((symbol_in->flags & BSF_SECTION_SYM) && symbol_in->section)
184 	reloc_entry->addend += symbol_in->section->output_offset;
185 
186       return bfd_reloc_ok;
187     }
188 
189   return bfd_reloc_continue;
190 }
191 
192 
193 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
194   TYPE = VALUE,
195 enum howto_list
196 {
197 #include "elf/arc-reloc.def"
198   HOWTO_LIST_LAST
199 };
200 #undef ARC_RELOC_HOWTO
201 
202 #define ARC_RELOC_HOWTO(TYPE, VALUE, RSIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
203   [TYPE] = HOWTO (R_##TYPE, 0, RSIZE, BITSIZE, FALSE, 0,		\
204 		  complain_overflow_##OVERFLOW, arc_elf_reloc,		\
205 		  "R_" #TYPE, FALSE, 0, 0, FALSE),
206 
207 static struct reloc_howto_struct elf_arc_howto_table[] =
208 {
209 #include "elf/arc-reloc.def"
210 /* Example of what is generated by the preprocessor.  Currently kept as an
211    example.
212  HOWTO (R_ARC_NONE, // Type.
213     0, // Rightshift.
214     2, // Size (0 = byte, 1 = short, 2 = long).
215     32, // Bitsize.
216     FALSE, // PC_relative.
217     0, // Bitpos.
218     complain_overflow_bitfield, // Complain_on_overflow.
219     bfd_elf_generic_reloc, // Special_function.
220     "R_ARC_NONE", // Name.
221     TRUE, // Partial_inplace.
222     0, // Src_mask.
223     0, // Dst_mask.
224     FALSE), // PCrel_offset.
225 */
226 };
227 #undef ARC_RELOC_HOWTO
228 
229 static void arc_elf_howto_init (void)
230 {
231 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
232   elf_arc_howto_table[TYPE].pc_relative = \
233     (strstr (#FORMULA, " P ") != NULL || strstr (#FORMULA, " PDATA ") != NULL); \
234   elf_arc_howto_table[TYPE].dst_mask = RELOC_FUNCTION(0, ~0); \
235   /* Only 32 bit data relocations should be marked as ME.  */ \
236   if (strstr (#FORMULA, " ME ") != NULL) \
237     { \
238       BFD_ASSERT (SIZE == 2); \
239     }
240 
241 #include "elf/arc-reloc.def"
242 
243 }
244 #undef ARC_RELOC_HOWTO
245 
246 
247 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
248   [TYPE] = VALUE,
249 const int howto_table_lookup[] =
250 {
251 #include "elf/arc-reloc.def"
252 };
253 #undef ARC_RELOC_HOWTO
254 
255 static reloc_howto_type *
256 arc_elf_howto (unsigned int r_type)
257 {
258   if (elf_arc_howto_table[R_ARC_32].dst_mask == 0)
259     arc_elf_howto_init ();
260   return &elf_arc_howto_table[r_type];
261 }
262 
263 /* Map BFD reloc types to ARC ELF reloc types.  */
264 
265 struct arc_reloc_map
266 {
267   bfd_reloc_code_real_type  bfd_reloc_val;
268   unsigned char		    elf_reloc_val;
269 };
270 
271 /* ARC ELF linker hash entry.  */
272 struct elf_arc_link_hash_entry
273 {
274   struct elf_link_hash_entry root;
275 
276   /* Track dynamic relocs copied for this symbol.  */
277   struct elf_dyn_relocs *dyn_relocs;
278 };
279 
280 /* ARC ELF linker hash table.  */
281 struct elf_arc_link_hash_table
282 {
283   struct elf_link_hash_table elf;
284 };
285 
286 static struct bfd_hash_entry *
287 elf_arc_link_hash_newfunc (struct bfd_hash_entry *entry,
288 			   struct bfd_hash_table *table,
289 			   const char *string)
290 {
291   /* Allocate the structure if it has not already been allocated by a
292      subclass.  */
293   if (entry == NULL)
294     {
295       entry = (struct bfd_hash_entry *)
296 	  bfd_hash_allocate (table,
297 			     sizeof (struct elf_arc_link_hash_entry));
298       if (entry == NULL)
299 	return entry;
300     }
301 
302   /* Call the allocation method of the superclass.  */
303   entry = _bfd_elf_link_hash_newfunc (entry, table, string);
304   if (entry != NULL)
305     {
306       struct elf_arc_link_hash_entry *eh;
307 
308       eh = (struct elf_arc_link_hash_entry *) entry;
309       eh->dyn_relocs = NULL;
310     }
311 
312   return entry;
313 }
314 
315 /* Destroy an ARC ELF linker hash table.  */
316 static void
317 elf_arc_link_hash_table_free (bfd *obfd)
318 {
319   _bfd_elf_link_hash_table_free (obfd);
320 }
321 
322 /* Create an ARC ELF linker hash table.  */
323 
324 static struct bfd_link_hash_table *
325 arc_elf_link_hash_table_create (bfd *abfd)
326 {
327   struct elf_arc_link_hash_table *ret;
328 
329   ret = (struct elf_arc_link_hash_table *) bfd_zmalloc (sizeof (*ret));
330   if (ret == NULL)
331     return NULL;
332 
333   if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
334 				      elf_arc_link_hash_newfunc,
335 				      sizeof (struct elf_arc_link_hash_entry),
336 				      ARC_ELF_DATA))
337     {
338       free (ret);
339       return NULL;
340     }
341 
342   ret->elf.init_got_refcount.refcount = 0;
343   ret->elf.init_got_refcount.glist = NULL;
344   ret->elf.init_got_offset.offset = 0;
345   ret->elf.init_got_offset.glist = NULL;
346 
347   ret->elf.root.hash_table_free = elf_arc_link_hash_table_free;
348 
349   return &ret->elf.root;
350 }
351 
352 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
353   { BFD_RELOC_##TYPE, R_##TYPE },
354 static const struct arc_reloc_map arc_reloc_map[] =
355 {
356 #include "elf/arc-reloc.def"
357 
358   {BFD_RELOC_NONE,  R_ARC_NONE},
359   {BFD_RELOC_8,  R_ARC_8},
360   {BFD_RELOC_16, R_ARC_16},
361   {BFD_RELOC_24, R_ARC_24},
362   {BFD_RELOC_32, R_ARC_32},
363 };
364 #undef ARC_RELOC_HOWTO
365 
366 typedef ATTRIBUTE_UNUSED bfd_vma (*replace_func) (unsigned, int ATTRIBUTE_UNUSED);
367 
368 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
369   case TYPE: \
370     func = (void *) RELOC_FUNCTION; \
371     break;
372 static replace_func
373 get_replace_function (bfd *abfd, unsigned int r_type)
374 {
375   void *func = NULL;
376 
377   switch (r_type)
378     {
379       #include "elf/arc-reloc.def"
380     }
381 
382   if (func == replace_bits24 && bfd_big_endian (abfd))
383     return (replace_func) replace_bits24_be;
384 
385   return (replace_func) func;
386 }
387 #undef ARC_RELOC_HOWTO
388 
389 static reloc_howto_type *
390 arc_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
391 				 bfd_reloc_code_real_type code)
392 {
393   unsigned int i;
394 
395   for (i = ARRAY_SIZE (arc_reloc_map); i--;)
396     {
397       if (arc_reloc_map[i].bfd_reloc_val == code)
398 	return arc_elf_howto (arc_reloc_map[i].elf_reloc_val);
399     }
400 
401   return NULL;
402 }
403 
404 /* Function to set the ELF flag bits.  */
405 static bfd_boolean
406 arc_elf_set_private_flags (bfd *abfd, flagword flags)
407 {
408   elf_elfheader (abfd)->e_flags = flags;
409   elf_flags_init (abfd) = TRUE;
410   return TRUE;
411 }
412 
413 /* Print private flags.  */
414 static bfd_boolean
415 arc_elf_print_private_bfd_data (bfd *abfd, void * ptr)
416 {
417   FILE *file = (FILE *) ptr;
418   flagword flags;
419 
420   BFD_ASSERT (abfd != NULL && ptr != NULL);
421 
422   /* Print normal ELF private data.  */
423   _bfd_elf_print_private_bfd_data (abfd, ptr);
424 
425   flags = elf_elfheader (abfd)->e_flags;
426   fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
427 
428   switch (flags & EF_ARC_MACH_MSK)
429     {
430     case EF_ARC_CPU_ARCV2HS : fprintf (file, " -mcpu=ARCv2HS");    break;
431     case EF_ARC_CPU_ARCV2EM : fprintf (file, " -mcpu=ARCv2EM");    break;
432     case E_ARC_MACH_ARC600  : fprintf (file, " -mcpu=ARC600");     break;
433     case E_ARC_MACH_ARC601  : fprintf (file, " -mcpu=ARC601");     break;
434     case E_ARC_MACH_ARC700  : fprintf (file, " -mcpu=ARC700");     break;
435     default:
436       fprintf (file, "-mcpu=unknown");
437       break;
438     }
439 
440   switch (flags & EF_ARC_OSABI_MSK)
441     {
442     case E_ARC_OSABI_ORIG : fprintf (file, " (ABI:legacy)"); break;
443     case E_ARC_OSABI_V2   : fprintf (file, " (ABI:v2)");     break;
444     case E_ARC_OSABI_V3   : fprintf (file, " (ABI:v3)");     break;
445     default:
446       fprintf (file, "(ABI:unknown)");
447       break;
448     }
449 
450   fputc ('\n', file);
451   return TRUE;
452 }
453 
454 /* Copy backend specific data from one object module to another.  */
455 
456 static bfd_boolean
457 arc_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
458 {
459   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
460       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
461     return TRUE;
462 
463   BFD_ASSERT (!elf_flags_init (obfd)
464 	      || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
465 
466   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
467   elf_flags_init (obfd) = TRUE;
468 
469   /* Copy object attributes.  */
470   _bfd_elf_copy_obj_attributes (ibfd, obfd);
471 
472   return _bfd_elf_copy_private_bfd_data (ibfd, obfd);
473 }
474 
475 static reloc_howto_type *
476 bfd_elf32_bfd_reloc_name_lookup (bfd * abfd ATTRIBUTE_UNUSED,
477 				 const char *r_name)
478 {
479   unsigned int i;
480 
481   for (i = 0; i < ARRAY_SIZE (elf_arc_howto_table); i++)
482     if (elf_arc_howto_table[i].name != NULL
483 	&& strcasecmp (elf_arc_howto_table[i].name, r_name) == 0)
484       return arc_elf_howto (i);
485 
486   return NULL;
487 }
488 
489 /* Set the howto pointer for an ARC ELF reloc.  */
490 
491 static void
492 arc_info_to_howto_rel (bfd * abfd ATTRIBUTE_UNUSED,
493 		       arelent * cache_ptr,
494 		       Elf_Internal_Rela * dst)
495 {
496   unsigned int r_type;
497 
498   r_type = ELF32_R_TYPE (dst->r_info);
499   BFD_ASSERT (r_type < (unsigned int) R_ARC_max);
500   cache_ptr->howto = arc_elf_howto (r_type);
501 }
502 
503 /* Merge backend specific data from an object file to the output
504    object file when linking.  */
505 
506 static bfd_boolean
507 arc_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
508 {
509   bfd *obfd = info->output_bfd;
510   unsigned short mach_ibfd;
511   static unsigned short mach_obfd = EM_NONE;
512   flagword out_flags;
513   flagword in_flags;
514   asection *sec;
515 
516    /* Check if we have the same endianess.  */
517   if (! _bfd_generic_verify_endian_match (ibfd, info))
518     return FALSE;
519 
520   /* Collect ELF flags.  */
521   in_flags = elf_elfheader (ibfd)->e_flags & EF_ARC_MACH_MSK;
522   out_flags = elf_elfheader (obfd)->e_flags & EF_ARC_MACH_MSK;
523 
524   if (!elf_flags_init (obfd)) /* First call, no flags set.  */
525     {
526       elf_flags_init (obfd) = TRUE;
527       out_flags = in_flags;
528     }
529 
530   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
531       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
532     return TRUE;
533 
534   /* Check to see if the input BFD actually contains any sections.  Do
535      not short-circuit dynamic objects; their section list may be
536      emptied by elf_link_add_object_symbols.  */
537   if (!(ibfd->flags & DYNAMIC))
538     {
539       bfd_boolean null_input_bfd = TRUE;
540       bfd_boolean only_data_sections = TRUE;
541 
542       for (sec = ibfd->sections; sec != NULL; sec = sec->next)
543 	{
544 	  if ((bfd_get_section_flags (ibfd, sec)
545 	       & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
546 	      == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
547 	    only_data_sections = FALSE;
548 
549 	  null_input_bfd = FALSE;
550 	}
551 
552       if (null_input_bfd || only_data_sections)
553 	return TRUE;
554     }
555 
556   /* Complain about various flag/architecture mismatches.  */
557   mach_ibfd = elf_elfheader (ibfd)->e_machine;
558   if (mach_obfd == EM_NONE)
559     {
560       mach_obfd = mach_ibfd;
561     }
562   else
563     {
564       if (mach_ibfd != mach_obfd)
565 	{
566 	  /* xgettext:c-format */
567 	  _bfd_error_handler (_("ERROR: Attempting to link %B "
568 				"with a binary %B of different architecture"),
569 			      ibfd, obfd);
570 	  return FALSE;
571 	}
572       else if (in_flags != out_flags)
573 	{
574 	  /* Warn if different flags.  */
575 	  _bfd_error_handler
576 	    /* xgettext:c-format */
577 	    (_("%B: uses different e_flags (0x%lx) fields than "
578 	       "previous modules (0x%lx)"),
579 	     ibfd, (long) in_flags, (long) out_flags);
580 	  if (in_flags && out_flags)
581 	    return FALSE;
582 	  /* MWDT doesnt set the eflags hence make sure we choose the
583 	     eflags set by gcc.  */
584 	  in_flags = in_flags > out_flags ? in_flags : out_flags;
585 	}
586     }
587 
588   /* Update the flags.  */
589   elf_elfheader (obfd)->e_flags = in_flags;
590 
591   if (bfd_get_mach (obfd) < bfd_get_mach (ibfd))
592     {
593       return bfd_set_arch_mach (obfd, bfd_arch_arc, bfd_get_mach (ibfd));
594     }
595 
596   return TRUE;
597 }
598 
599 /* Set the right machine number for an ARC ELF file.  */
600 static bfd_boolean
601 arc_elf_object_p (bfd * abfd)
602 {
603   /* Make sure this is initialised, or you'll have the potential of passing
604      garbage---or misleading values---into the call to
605      bfd_default_set_arch_mach ().  */
606   int		  mach = bfd_mach_arc_arc700;
607   unsigned long   arch = elf_elfheader (abfd)->e_flags & EF_ARC_MACH_MSK;
608   unsigned	  e_machine = elf_elfheader (abfd)->e_machine;
609 
610   if (e_machine == EM_ARC_COMPACT || e_machine == EM_ARC_COMPACT2)
611     {
612       switch (arch)
613 	{
614 	  case E_ARC_MACH_ARC600:
615 	    mach = bfd_mach_arc_arc600;
616 	    break;
617 	  case E_ARC_MACH_ARC601:
618 	    mach = bfd_mach_arc_arc601;
619 	    break;
620 	  case E_ARC_MACH_ARC700:
621 	    mach = bfd_mach_arc_arc700;
622 	    break;
623 	  case EF_ARC_CPU_ARCV2HS:
624 	  case EF_ARC_CPU_ARCV2EM:
625 	    mach = bfd_mach_arc_arcv2;
626 	    break;
627 	  default:
628 	    mach = (e_machine == EM_ARC_COMPACT)
629 	      ? bfd_mach_arc_arc700 : bfd_mach_arc_arcv2;
630 	    break;
631 	}
632     }
633   else
634     {
635       if (e_machine == EM_ARC)
636 	{
637 	  _bfd_error_handler
638 	    (_("Error: The ARC4 architecture is no longer supported.\n"));
639 	  return FALSE;
640 	}
641       else
642 	{
643 	  _bfd_error_handler
644 	    (_("Warning: unset or old architecture flags. \n"
645 	       "	       Use default machine.\n"));
646 	}
647     }
648 
649   return bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach);
650 }
651 
652 /* The final processing done just before writing out an ARC ELF object file.
653    This gets the ARC architecture right based on the machine number.  */
654 
655 static void
656 arc_elf_final_write_processing (bfd * abfd,
657 				bfd_boolean linker ATTRIBUTE_UNUSED)
658 {
659   unsigned long emf;
660 
661   switch (bfd_get_mach (abfd))
662     {
663     case bfd_mach_arc_arc600:
664       emf = EM_ARC_COMPACT;
665       break;
666     case bfd_mach_arc_arc601:
667       emf = EM_ARC_COMPACT;
668       break;
669     case bfd_mach_arc_arc700:
670       emf = EM_ARC_COMPACT;
671       break;
672     case bfd_mach_arc_arcv2:
673       emf = EM_ARC_COMPACT2;
674       break;
675     default:
676       goto DO_NOTHING;
677     }
678 
679   elf_elfheader (abfd)->e_machine = emf;
680 
681   /* Record whatever is the current syscall ABI version.  */
682   elf_elfheader (abfd)->e_flags |= E_ARC_OSABI_CURRENT;
683 
684 DO_NOTHING:
685   return;
686 }
687 
688 #ifdef ARC_ENABLE_DEBUG
689 #define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
690 
691 static void
692 debug_arc_reloc (struct arc_relocation_data reloc_data)
693 {
694   ARC_DEBUG ("Reloc type=%s, should_relocate = %s\n",
695 	     reloc_data.howto->name,
696 	     reloc_data.should_relocate ? "true" : "false");
697   ARC_DEBUG ("  offset = 0x%x, addend = 0x%x\n",
698 	     (unsigned int) reloc_data.reloc_offset,
699 	     (unsigned int) reloc_data.reloc_addend);
700   ARC_DEBUG (" Symbol:\n");
701   ARC_DEBUG ("  value = 0x%08x\n",
702 	     (unsigned int) reloc_data.sym_value);
703   if (reloc_data.sym_section != NULL)
704     {
705       ARC_DEBUG (" Symbol Section:\n");
706       ARC_DEBUG ("  section name = %s, output_offset 0x%08x",
707 		 reloc_data.sym_section->name,
708 		 (unsigned int) reloc_data.sym_section->output_offset);
709       if (reloc_data.sym_section->output_section != NULL)
710 	ARC_DEBUG (", output_section->vma = 0x%08x",
711 		   ((unsigned int) reloc_data.sym_section->output_section->vma));
712       ARC_DEBUG ("\n");
713       if (reloc_data.sym_section->owner && reloc_data.sym_section->owner->filename)
714 	ARC_DEBUG ("  file: %s\n", reloc_data.sym_section->owner->filename);
715     }
716   else
717     {
718       ARC_DEBUG ("  symbol section is NULL\n");
719     }
720 
721   ARC_DEBUG (" Input_section:\n");
722   if (reloc_data.input_section != NULL)
723     {
724       ARC_DEBUG ("  section name = %s, output_offset 0x%08x, output_section->vma = 0x%08x\n",
725 		 reloc_data.input_section->name,
726 		 (unsigned int) reloc_data.input_section->output_offset,
727 		 (unsigned int) reloc_data.input_section->output_section->vma);
728       ARC_DEBUG ("  changed_address = 0x%08x\n",
729 		 (unsigned int) (reloc_data.input_section->output_section->vma
730 				 + reloc_data.input_section->output_offset
731 				 + reloc_data.reloc_offset));
732       ARC_DEBUG ("  file: %s\n", reloc_data.input_section->owner->filename);
733     }
734   else
735     {
736       ARC_DEBUG ("	input section is NULL\n");
737     }
738 }
739 #else
740 #define DEBUG_ARC_RELOC(A)
741 #endif /* ARC_ENABLE_DEBUG */
742 
743 static bfd_vma
744 middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
745 {
746   if (do_it)
747     {
748       insn
749 	= ((insn & 0xffff0000) >> 16)
750 	  | ((insn & 0xffff) << 16);
751     }
752   return insn;
753 }
754 
755 /* This function is called for relocations that are otherwise marked as NOT
756    requiring overflow checks.  In here we perform non-standard checks of
757    the relocation value.  */
758 
759 static inline bfd_reloc_status_type
760 arc_special_overflow_checks (const struct arc_relocation_data reloc_data,
761 			     bfd_signed_vma relocation,
762 			     struct bfd_link_info *info ATTRIBUTE_UNUSED)
763 {
764   switch (reloc_data.howto->type)
765     {
766     case R_ARC_NPS_CMEM16:
767       if (((relocation >> 16) & 0xffff) != NPS_CMEM_HIGH_VALUE)
768 	{
769 	  if (reloc_data.reloc_addend == 0)
770 	    _bfd_error_handler
771 	      /* xgettext:c-format */
772 	      (_("%B(%A+0x%lx): CMEM relocation to `%s' is invalid, "
773 		 "16 MSB should be 0x%04x (value is 0x%lx)"),
774 	       reloc_data.input_section->owner,
775 	       reloc_data.input_section,
776 	       reloc_data.reloc_offset,
777 	       reloc_data.symbol_name,
778 	       NPS_CMEM_HIGH_VALUE,
779 	       (relocation));
780 	  else
781 	    _bfd_error_handler
782 	      /* xgettext:c-format */
783 	      (_("%B(%A+0x%lx): CMEM relocation to `%s+0x%lx' is invalid, "
784 		 "16 MSB should be 0x%04x (value is 0x%lx)"),
785 	       reloc_data.input_section->owner,
786 	       reloc_data.input_section,
787 	       reloc_data.reloc_offset,
788 	       reloc_data.symbol_name,
789 	       reloc_data.reloc_addend,
790 	       NPS_CMEM_HIGH_VALUE,
791 	       (relocation));
792 	  return bfd_reloc_overflow;
793 	}
794       break;
795 
796     default:
797       break;
798     }
799 
800   return bfd_reloc_ok;
801 }
802 
803 #define ME(reloc) (reloc)
804 
805 #define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") != NULL) \
806 			    && (!bfd_big_endian (BFD)))
807 
808 #define S ((bfd_signed_vma) (reloc_data.sym_value			\
809 	   + (reloc_data.sym_section->output_section != NULL ?		\
810 	      (reloc_data.sym_section->output_offset			\
811 	       + reloc_data.sym_section->output_section->vma) : 0)))
812 #define L ((bfd_signed_vma) (reloc_data.sym_value			\
813 	   + (reloc_data.sym_section->output_section != NULL ?		\
814 	      (reloc_data.sym_section->output_offset			\
815 	      + reloc_data.sym_section->output_section->vma) : 0)))
816 #define A (reloc_data.reloc_addend)
817 #define B (0)
818 #define G (reloc_data.got_offset_value)
819 #define GOT (reloc_data.got_symbol_vma)
820 #define GOT_BEGIN (htab->sgot->output_section->vma)
821 
822 #define MES (0)
823 	/* P: relative offset to PCL The offset should be to the
824 	  current location aligned to 32 bits.  */
825 #define P ((bfd_signed_vma) (						\
826 	   (								\
827 	    (reloc_data.input_section->output_section != NULL ?		\
828 	     reloc_data.input_section->output_section->vma : 0)		\
829 	    + reloc_data.input_section->output_offset			\
830 	    + (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0)))	\
831 	   & ~0x3))
832 #define PDATA ((bfd_signed_vma) ( \
833 	    (reloc_data.input_section->output_section->vma \
834 	     + reloc_data.input_section->output_offset \
835 	     + (reloc_data.reloc_offset))))
836 #define SECTSTART (bfd_signed_vma) (reloc_data.sym_section->output_section->vma \
837 				    + reloc_data.sym_section->output_offset)
838 
839 #define _SDA_BASE_ (bfd_signed_vma) (reloc_data.sdata_begin_symbol_vma)
840 #define TLS_REL (bfd_signed_vma) \
841   ((elf_hash_table (info))->tls_sec->output_section->vma)
842 #define TLS_TBSS (8)
843 #define TCB_SIZE (8)
844 
845 #define none (0)
846 
847 #ifdef ARC_ENABLE_DEBUG
848 #define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA, TYPE)			\
849   do									\
850     {									\
851       asection *sym_section = reloc_data.sym_section;			\
852       asection *input_section = reloc_data.input_section;		\
853       ARC_DEBUG ("RELOC_TYPE = " TYPE "\n");				\
854       ARC_DEBUG ("FORMULA = " FORMULA "\n");				\
855       ARC_DEBUG ("S = %#lx\n", S);					\
856       ARC_DEBUG ("A = %#lx\n", A);					\
857       ARC_DEBUG ("L = %lx\n", L);					\
858       if (sym_section->output_section != NULL)				\
859 	ARC_DEBUG ("symbol_section->vma = %#lx\n",			\
860 		   sym_section->output_section->vma			\
861 		   + sym_section->output_offset);			\
862       else								\
863 	ARC_DEBUG ("symbol_section->vma = NULL\n");			\
864       if (input_section->output_section != NULL)			\
865 	ARC_DEBUG ("symbol_section->vma = %#lx\n",			\
866 		   input_section->output_section->vma			\
867 		   + input_section->output_offset);			\
868       else								\
869 	ARC_DEBUG ("symbol_section->vma = NULL\n");			\
870       ARC_DEBUG ("PCL = %#lx\n", P);					\
871       ARC_DEBUG ("P = %#lx\n", P);					\
872       ARC_DEBUG ("G = %#lx\n", G);					\
873       ARC_DEBUG ("SDA_OFFSET = %#lx\n", _SDA_BASE_);			\
874       ARC_DEBUG ("SDA_SET = %d\n", reloc_data.sdata_begin_symbol_vma_set); \
875       ARC_DEBUG ("GOT_OFFSET = %#lx\n", GOT);				\
876       ARC_DEBUG ("relocation = %#08lx\n", relocation);			\
877       ARC_DEBUG ("before = %#08x\n", (unsigned) insn);			\
878       ARC_DEBUG ("data   = %08x (%u) (%d)\n", (unsigned) relocation,	\
879 		 (unsigned) relocation, (int) relocation);		\
880     }									\
881   while (0)
882 
883 #define PRINT_DEBUG_RELOC_INFO_AFTER				\
884   do								\
885     {								\
886       ARC_DEBUG ("after  = 0x%08x\n", (unsigned int) insn);	\
887     }								\
888   while (0)
889 
890 #else
891 
892 #define PRINT_DEBUG_RELOC_INFO_BEFORE(...)
893 #define PRINT_DEBUG_RELOC_INFO_AFTER
894 
895 #endif /* ARC_ENABLE_DEBUG */
896 
897 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
898   case R_##TYPE:							\
899     {									\
900       bfd_signed_vma bitsize ATTRIBUTE_UNUSED = BITSIZE;		\
901       relocation = FORMULA  ;						\
902       PRINT_DEBUG_RELOC_INFO_BEFORE (#FORMULA, #TYPE);			\
903       insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd));	\
904       insn = (* get_replace_function (abfd, TYPE)) (insn, relocation);	\
905       insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd));	\
906       PRINT_DEBUG_RELOC_INFO_AFTER;					\
907     }									\
908     break;
909 
910 static bfd_reloc_status_type
911 arc_do_relocation (bfd_byte * contents,
912 		   struct arc_relocation_data reloc_data,
913 		   struct bfd_link_info *info)
914 {
915   bfd_signed_vma relocation = 0;
916   bfd_vma insn;
917   bfd_vma orig_insn ATTRIBUTE_UNUSED;
918   bfd * abfd = reloc_data.input_section->owner;
919   struct elf_link_hash_table *htab ATTRIBUTE_UNUSED = elf_hash_table (info);
920   bfd_reloc_status_type flag;
921 
922   if (reloc_data.should_relocate == FALSE)
923     return bfd_reloc_ok;
924 
925   switch (reloc_data.howto->size)
926     {
927       case 2:
928 	insn = arc_bfd_get_32 (abfd,
929 			       contents + reloc_data.reloc_offset,
930 			       reloc_data.input_section);
931 	break;
932       case 1:
933 	insn = arc_bfd_get_16 (abfd,
934 			       contents + reloc_data.reloc_offset,
935 			       reloc_data.input_section);
936 	break;
937       case 0:
938 	insn = arc_bfd_get_8 (abfd,
939 			       contents + reloc_data.reloc_offset,
940 			       reloc_data.input_section);
941 	break;
942       default:
943 	insn = 0;
944 	BFD_ASSERT (0);
945 	break;
946     }
947 
948   orig_insn = insn;
949 
950   switch (reloc_data.howto->type)
951     {
952 #include "elf/arc-reloc.def"
953 
954       default:
955 	BFD_ASSERT (0);
956 	break;
957     }
958 
959   /* Check for relocation overflow.  */
960   if (reloc_data.howto->complain_on_overflow != complain_overflow_dont)
961     flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
962 			       reloc_data.howto->bitsize,
963 			       reloc_data.howto->rightshift,
964 			       bfd_arch_bits_per_address (abfd),
965 			       relocation);
966   else
967     flag = arc_special_overflow_checks (reloc_data, relocation, info);
968 
969   if (flag != bfd_reloc_ok)
970     {
971       ARC_DEBUG ("Relocation overflows !\n");
972       DEBUG_ARC_RELOC (reloc_data);
973       ARC_DEBUG ("Relocation value = signed -> %d, unsigned -> %u"
974 		 ", hex -> (0x%08x)\n",
975 		(int) relocation, (unsigned) relocation, (int) relocation);
976 
977       return flag;
978     }
979 
980   /* Write updated instruction back to memory.  */
981   switch (reloc_data.howto->size)
982     {
983       case 2:
984 	arc_bfd_put_32 (abfd, insn,
985 		       contents + reloc_data.reloc_offset,
986 		       reloc_data.input_section);
987 	break;
988       case 1:
989 	arc_bfd_put_16 (abfd, insn,
990 		       contents + reloc_data.reloc_offset,
991 		       reloc_data.input_section);
992 	break;
993       case 0:
994 	arc_bfd_put_8 (abfd, insn,
995 		       contents + reloc_data.reloc_offset,
996 		       reloc_data.input_section);
997 	break;
998       default:
999 	ARC_DEBUG ("size = %d\n", reloc_data.howto->size);
1000 	BFD_ASSERT (0);
1001 	break;
1002     }
1003 
1004   return bfd_reloc_ok;
1005 }
1006 #undef S
1007 #undef A
1008 #undef B
1009 #undef G
1010 #undef GOT
1011 #undef L
1012 #undef MES
1013 #undef P
1014 #undef SECTSTAR
1015 #undef SECTSTART
1016 #undef _SDA_BASE_
1017 #undef none
1018 
1019 #undef ARC_RELOC_HOWTO
1020 
1021 
1022 /* Relocate an arc ELF section.
1023    Function : elf_arc_relocate_section
1024    Brief    : Relocate an arc section, by handling all the relocations
1025 	     appearing in that section.
1026    Args     : output_bfd    : The bfd being written to.
1027 	      info	    : Link information.
1028 	      input_bfd     : The input bfd.
1029 	      input_section : The section being relocated.
1030 	      contents	    : contents of the section being relocated.
1031 	      relocs	    : List of relocations in the section.
1032 	      local_syms    : is a pointer to the swapped in local symbols.
1033 	      local_section : is an array giving the section in the input file
1034 			      corresponding to the st_shndx field of each
1035 			      local symbol.  */
1036 static bfd_boolean
1037 elf_arc_relocate_section (bfd *		          output_bfd,
1038 			  struct bfd_link_info *  info,
1039 			  bfd *		          input_bfd,
1040 			  asection *	          input_section,
1041 			  bfd_byte *	          contents,
1042 			  Elf_Internal_Rela *     relocs,
1043 			  Elf_Internal_Sym *      local_syms,
1044 			  asection **	          local_sections)
1045 {
1046   Elf_Internal_Shdr *	         symtab_hdr;
1047   struct elf_link_hash_entry **  sym_hashes;
1048   Elf_Internal_Rela *	         rel;
1049   Elf_Internal_Rela *	         wrel;
1050   Elf_Internal_Rela *	         relend;
1051   struct elf_link_hash_table *   htab = elf_hash_table (info);
1052 
1053   symtab_hdr = &((elf_tdata (input_bfd))->symtab_hdr);
1054   sym_hashes = elf_sym_hashes (input_bfd);
1055 
1056   rel = wrel = relocs;
1057   relend = relocs + input_section->reloc_count;
1058   for (; rel < relend; wrel++, rel++)
1059     {
1060       enum elf_arc_reloc_type       r_type;
1061       reloc_howto_type *	    howto;
1062       unsigned long		    r_symndx;
1063       struct elf_link_hash_entry *  h;
1064       Elf_Internal_Sym *	    sym;
1065       asection *		    sec;
1066       struct elf_link_hash_entry *  h2;
1067       const char *                  msg;
1068 
1069       struct arc_relocation_data reloc_data =
1070       {
1071 	.reloc_offset = 0,
1072 	.reloc_addend = 0,
1073 	.got_offset_value = 0,
1074 	.sym_value = 0,
1075 	.sym_section = NULL,
1076 	.howto = NULL,
1077 	.input_section = NULL,
1078 	.sdata_begin_symbol_vma = 0,
1079 	.sdata_begin_symbol_vma_set = FALSE,
1080 	.got_symbol_vma = 0,
1081 	.should_relocate = FALSE
1082       };
1083 
1084       r_type = ELF32_R_TYPE (rel->r_info);
1085 
1086       if (r_type >= (int) R_ARC_max)
1087 	{
1088 	  bfd_set_error (bfd_error_bad_value);
1089 	  return FALSE;
1090 	}
1091       howto = arc_elf_howto (r_type);
1092 
1093       r_symndx = ELF32_R_SYM (rel->r_info);
1094 
1095       /* If we are generating another .o file and the symbol in not
1096 	 local, skip this relocation.  */
1097       if (bfd_link_relocatable (info))
1098 	{
1099 	  /* This is a relocateable link.  We don't have to change
1100 	     anything, unless the reloc is against a section symbol,
1101 	     in which case we have to adjust according to where the
1102 	     section symbol winds up in the output section.  */
1103 
1104 	  /* Checks if this is a local symbol and thus the reloc
1105 	     might (will??) be against a section symbol.  */
1106 	  if (r_symndx < symtab_hdr->sh_info)
1107 	    {
1108 	      sym = local_syms + r_symndx;
1109 	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1110 		{
1111 		  sec = local_sections[r_symndx];
1112 
1113 		  /* For RELA relocs.  Just adjust the addend
1114 		     value in the relocation entry.  */
1115 		  rel->r_addend += sec->output_offset + sym->st_value;
1116 
1117 		  ARC_DEBUG ("local symbols reloc (section=%d %s) seen in %s\n",
1118 			     (int) r_symndx, local_sections[r_symndx]->name,
1119 			     __PRETTY_FUNCTION__);
1120 		}
1121 	    }
1122 	}
1123 
1124       h2 = elf_link_hash_lookup (elf_hash_table (info), "__SDATA_BEGIN__",
1125 				 FALSE, FALSE, TRUE);
1126 
1127       if (reloc_data.sdata_begin_symbol_vma_set == FALSE
1128 	    && h2 != NULL && h2->root.type != bfd_link_hash_undefined
1129 	    && h2->root.u.def.section->output_section != NULL)
1130 	/* TODO: Verify this condition.  */
1131 	{
1132 	  reloc_data.sdata_begin_symbol_vma =
1133 	    (h2->root.u.def.value
1134 	     + h2->root.u.def.section->output_section->vma);
1135 	  reloc_data.sdata_begin_symbol_vma_set = TRUE;
1136 	}
1137 
1138       reloc_data.input_section = input_section;
1139       reloc_data.howto = howto;
1140       reloc_data.reloc_offset = rel->r_offset;
1141       reloc_data.reloc_addend = rel->r_addend;
1142 
1143       /* This is a final link.  */
1144       h = NULL;
1145       sym = NULL;
1146       sec = NULL;
1147 
1148       if (r_symndx < symtab_hdr->sh_info) /* A local symbol.  */
1149 	{
1150 	  sym = local_syms + r_symndx;
1151 	  sec = local_sections[r_symndx];
1152 	}
1153       else
1154 	{
1155 	  /* TODO: This code is repeated from below.  We should
1156 	     clean it and remove duplications.
1157 	     Sec is used check for discarded sections.
1158 	     Need to redesign code below.  */
1159 
1160 	  /* Get the symbol's entry in the symtab.  */
1161 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1162 
1163 	  while (h->root.type == bfd_link_hash_indirect
1164 		 || h->root.type == bfd_link_hash_warning)
1165 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1166 
1167 	  /* If we have encountered a definition for this symbol.  */
1168 	  if (h->root.type == bfd_link_hash_defined
1169 	      || h->root.type == bfd_link_hash_defweak)
1170 	    {
1171 	      reloc_data.sym_value = h->root.u.def.value;
1172 	      sec = h->root.u.def.section;
1173 	    }
1174 	}
1175 
1176       /* Clean relocs for symbols in discarded sections.  */
1177       if (sec != NULL && discarded_section (sec))
1178 	{
1179 	  _bfd_clear_contents (howto, input_bfd, input_section,
1180 			       contents + rel->r_offset);
1181 	  rel->r_offset = rel->r_offset;
1182 	  rel->r_info = 0;
1183 	  rel->r_addend = 0;
1184 
1185 	  /* For ld -r, remove relocations in debug sections against
1186 	     sections defined in discarded sections.  Not done for
1187 	     eh_frame editing code expects to be present.  */
1188 	   if (bfd_link_relocatable (info)
1189 	       && (input_section->flags & SEC_DEBUGGING))
1190 	     wrel--;
1191 
1192 	  continue;
1193 	}
1194 
1195       if (bfd_link_relocatable (info))
1196 	{
1197 	  if (wrel != rel)
1198 	    *wrel = *rel;
1199 	  continue;
1200 	}
1201 
1202       if (r_symndx < symtab_hdr->sh_info) /* A local symbol.  */
1203 	{
1204 	  reloc_data.sym_value = sym->st_value;
1205 	  reloc_data.sym_section = sec;
1206 	  reloc_data.symbol_name =
1207 	    bfd_elf_string_from_elf_section (input_bfd,
1208 					     symtab_hdr->sh_link,
1209 					     sym->st_name);
1210 
1211 	  /* Mergeable section handling.  */
1212 	  if ((sec->flags & SEC_MERGE)
1213 	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1214 	    {
1215 	      asection *msec;
1216 	      msec = sec;
1217 	      rel->r_addend = _bfd_elf_rel_local_sym (output_bfd, sym,
1218 						      &msec, rel->r_addend);
1219 	      rel->r_addend -= (sec->output_section->vma
1220 				+ sec->output_offset
1221 				+ sym->st_value);
1222 	      rel->r_addend += msec->output_section->vma + msec->output_offset;
1223 
1224 	      reloc_data.reloc_addend = rel->r_addend;
1225 	    }
1226 
1227 	  BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1228 	  if (htab->sgot != NULL)
1229 	    reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1230 					+ htab->sgot->output_offset;
1231 
1232 	  reloc_data.should_relocate = TRUE;
1233 	}
1234       else /* Global symbol.  */
1235 	{
1236 	  /* FIXME: We should use the RELOC_FOR_GLOBAL_SYMBOL macro
1237 	     (defined in elf-bfd.h) here.  */
1238 
1239 	  /* Get the symbol's entry in the symtab.  */
1240 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1241 
1242 	  while (h->root.type == bfd_link_hash_indirect
1243 		 || h->root.type == bfd_link_hash_warning)
1244 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1245 
1246 	  /* TODO: Need to validate what was the intention.  */
1247 	  /* BFD_ASSERT ((h->dynindx == -1) || (h->forced_local != 0)); */
1248 	  reloc_data.symbol_name = h->root.root.string;
1249 
1250 	  /* If we have encountered a definition for this symbol.  */
1251 	  if (h->root.type == bfd_link_hash_defined
1252 	      || h->root.type == bfd_link_hash_defweak)
1253 	    {
1254 	      reloc_data.sym_value = h->root.u.def.value;
1255 	      reloc_data.sym_section = h->root.u.def.section;
1256 
1257 	      reloc_data.should_relocate = TRUE;
1258 
1259 	      if (is_reloc_for_GOT (howto) && !bfd_link_pic (info))
1260 		{
1261 		  /* TODO: Change it to use arc_do_relocation with
1262 		    ARC_32 reloc.  Try to use ADD_RELA macro.  */
1263 		  bfd_vma relocation =
1264 		    reloc_data.sym_value + reloc_data.reloc_addend
1265 		    + (reloc_data.sym_section->output_section != NULL ?
1266 			(reloc_data.sym_section->output_offset
1267 			 + reloc_data.sym_section->output_section->vma)
1268 		      : 0);
1269 
1270 		  BFD_ASSERT (h->got.glist);
1271 		  bfd_vma got_offset = h->got.glist->offset;
1272 		  bfd_put_32 (output_bfd, relocation,
1273 			      htab->sgot->contents + got_offset);
1274 		}
1275 	      if (is_reloc_for_PLT (howto) && h->plt.offset != (bfd_vma) -1)
1276 		{
1277 		  /* TODO: This is repeated up here.  */
1278 		  reloc_data.sym_value = h->plt.offset;
1279 		  reloc_data.sym_section = htab->splt;
1280 		}
1281 	    }
1282 	  else if (h->root.type == bfd_link_hash_undefweak)
1283 	    {
1284 	      /* Is weak symbol and has no definition.  */
1285 	      if (is_reloc_for_GOT (howto))
1286 		{
1287 		  reloc_data.sym_value = h->root.u.def.value;
1288 		  reloc_data.sym_section = htab->sgot;
1289 		  reloc_data.should_relocate = TRUE;
1290 		}
1291 	      else if (is_reloc_for_PLT (howto)
1292 		       && h->plt.offset != (bfd_vma) -1)
1293 		{
1294 		  /* TODO: This is repeated up here.  */
1295 		  reloc_data.sym_value = h->plt.offset;
1296 		  reloc_data.sym_section = htab->splt;
1297 		  reloc_data.should_relocate = TRUE;
1298 		}
1299 	      else
1300 		continue;
1301 	    }
1302 	  else
1303 	    {
1304 	      if (is_reloc_for_GOT (howto))
1305 		{
1306 		  reloc_data.sym_value = h->root.u.def.value;
1307 		  reloc_data.sym_section = htab->sgot;
1308 
1309 		  reloc_data.should_relocate = TRUE;
1310 		}
1311 	      else if (is_reloc_for_PLT (howto))
1312 		{
1313 		  /* Fail if it is linking for PIE and the symbol is
1314 		     undefined.  */
1315 		  if (bfd_link_executable (info))
1316 		    (*info->callbacks->undefined_symbol)
1317 		      (info, h->root.root.string, input_bfd, input_section,
1318 		       rel->r_offset, TRUE);
1319 		  reloc_data.sym_value = h->plt.offset;
1320 		  reloc_data.sym_section = htab->splt;
1321 
1322 		  reloc_data.should_relocate = TRUE;
1323 		}
1324 	      else if (!bfd_link_pic (info) || bfd_link_executable (info))
1325 		(*info->callbacks->undefined_symbol)
1326 		  (info, h->root.root.string, input_bfd, input_section,
1327 		   rel->r_offset, TRUE);
1328 	    }
1329 
1330 	  BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1331 	  if (htab->sgot != NULL)
1332 	    reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1333 					+ htab->sgot->output_offset;
1334 	}
1335 
1336       if ((is_reloc_for_GOT (howto)
1337 	   || is_reloc_for_TLS (howto)))
1338 	{
1339 	  reloc_data.should_relocate = TRUE;
1340 
1341 	  struct got_entry **list
1342 	    = get_got_entry_list_for_symbol (output_bfd, r_symndx, h);
1343 
1344 	  reloc_data.got_offset_value
1345 	    = relocate_fix_got_relocs_for_got_info (list,
1346 						    tls_type_for_reloc (howto),
1347 						    info,
1348 						    output_bfd,
1349 						    r_symndx,
1350 						    local_syms,
1351 						    local_sections,
1352 						    h,
1353 						    &reloc_data);
1354 
1355 	  if (h == NULL)
1356 	    {
1357 	      create_got_dynrelocs_for_single_entry (
1358 		  got_entry_for_type (list,
1359 		      		arc_got_entry_type_for_reloc (howto)),
1360 		  output_bfd, info, NULL);
1361 	    }
1362 	}
1363 
1364       switch (r_type)
1365 	{
1366 	  case R_ARC_32:
1367 	  case R_ARC_32_ME:
1368 	  case R_ARC_PC32:
1369 	  case R_ARC_32_PCREL:
1370 	    if ((bfd_link_pic (info))
1371 		&& ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1372 		    || (h != NULL
1373 			&& h->dynindx != -1
1374 			&& (!info->symbolic || !h->def_regular))))
1375 	      {
1376 		Elf_Internal_Rela outrel;
1377 		bfd_byte *loc;
1378 		bfd_boolean skip = FALSE;
1379 		bfd_boolean relocate = FALSE;
1380 		asection *sreloc = _bfd_elf_get_dynamic_reloc_section
1381 				 (input_bfd, input_section,
1382 				  /*RELA*/ TRUE);
1383 
1384 		BFD_ASSERT (sreloc != NULL);
1385 
1386 		outrel.r_offset = _bfd_elf_section_offset (output_bfd,
1387 							   info,
1388 							   input_section,
1389 							   rel->r_offset);
1390 		if (outrel.r_offset == (bfd_vma) -1)
1391 		  skip = TRUE;
1392 
1393 		outrel.r_addend = rel->r_addend;
1394 		outrel.r_offset += (input_section->output_section->vma
1395 				    + input_section->output_offset);
1396 
1397 #define IS_ARC_PCREL_TYPE(TYPE) \
1398   (   (TYPE == R_ARC_PC32)      \
1399    || (TYPE == R_ARC_32_PCREL))
1400 
1401 		if (skip)
1402 		  {
1403 		    memset (&outrel, 0, sizeof outrel);
1404 		    relocate = FALSE;
1405 		  }
1406 		else if (h != NULL
1407 			 && h->dynindx != -1
1408 			 && ((IS_ARC_PCREL_TYPE (r_type))
1409 			 || !(bfd_link_executable (info)
1410 			      || SYMBOLIC_BIND (info, h))
1411 			 || ! h->def_regular))
1412 		  {
1413 		    BFD_ASSERT (h != NULL);
1414 		    if ((input_section->flags & SEC_ALLOC) != 0)
1415 		      relocate = FALSE;
1416 		    else
1417 		      relocate = TRUE;
1418 
1419 		    BFD_ASSERT (h->dynindx != -1);
1420 		    outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1421 		  }
1422 		else
1423 		  {
1424 		    /* Handle local symbols, they either do not have a
1425 		       global hash table entry (h == NULL), or are
1426 		       forced local due to a version script
1427 		       (h->forced_local), or the third condition is
1428 		       legacy, it appears to say something like, for
1429 		       links where we are pre-binding the symbols, or
1430 		       there's not an entry for this symbol in the
1431 		       dynamic symbol table, and it's a regular symbol
1432 		       not defined in a shared object, then treat the
1433 		       symbol as local, resolve it now.  */
1434 		    relocate = TRUE;
1435 		    /* outrel.r_addend = 0; */
1436 		    outrel.r_info = ELF32_R_INFO (0, R_ARC_RELATIVE);
1437 		  }
1438 
1439 		BFD_ASSERT (sreloc->contents != 0);
1440 
1441 		loc = sreloc->contents;
1442 		loc += sreloc->reloc_count * sizeof (Elf32_External_Rela);
1443 		sreloc->reloc_count += 1;
1444 
1445 		bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1446 
1447 		if (relocate == FALSE)
1448 		  continue;
1449 	      }
1450 	    break;
1451 	  default:
1452 	    break;
1453 	}
1454 
1455       if (is_reloc_SDA_relative (howto)
1456 	  && (reloc_data.sdata_begin_symbol_vma_set == FALSE))
1457 	{
1458 	  _bfd_error_handler
1459 	    ("Error: Linker symbol __SDATA_BEGIN__ not found");
1460 	  bfd_set_error (bfd_error_bad_value);
1461 	  return FALSE;
1462 	}
1463 
1464       DEBUG_ARC_RELOC (reloc_data);
1465 
1466       /* Make sure we have with a dynamic linker.  In case of GOT and PLT
1467 	 the sym_section should point to .got or .plt respectively.  */
1468       if ((is_reloc_for_GOT (howto) || is_reloc_for_PLT (howto))
1469 	  && reloc_data.sym_section == NULL)
1470 	{
1471 	  _bfd_error_handler
1472 	    (_("GOT and PLT relocations cannot be fixed with a non dynamic linker."));
1473 	  bfd_set_error (bfd_error_bad_value);
1474 	  return FALSE;
1475 	}
1476 
1477       msg = NULL;
1478       switch (arc_do_relocation (contents, reloc_data, info))
1479 	{
1480 	case bfd_reloc_ok:
1481 	  continue; /* The reloc processing loop.  */
1482 
1483 	case bfd_reloc_overflow:
1484 	  (*info->callbacks->reloc_overflow)
1485 	    (info, (h ? &h->root : NULL), reloc_data.symbol_name, howto->name, (bfd_vma) 0,
1486 	     input_bfd, input_section, rel->r_offset);
1487 	  break;
1488 
1489 	case bfd_reloc_undefined:
1490 	  (*info->callbacks->undefined_symbol)
1491 	    (info, reloc_data.symbol_name, input_bfd, input_section, rel->r_offset, TRUE);
1492 	  break;
1493 
1494 	case bfd_reloc_other:
1495 	  /* xgettext:c-format */
1496 	  msg = _("%B(%A): warning: unaligned access to symbol '%s' in the small data area");
1497 	  break;
1498 
1499 	case bfd_reloc_outofrange:
1500 	  /* xgettext:c-format */
1501 	  msg = _("%B(%A): internal error: out of range error");
1502 	  break;
1503 
1504 	case bfd_reloc_notsupported:
1505 	  /* xgettext:c-format */
1506 	  msg = _("%B(%A): internal error: unsupported relocation error");
1507 	  break;
1508 
1509 	case bfd_reloc_dangerous:
1510 	  /* xgettext:c-format */
1511 	  msg = _("%B(%A): internal error: dangerous relocation");
1512 	  break;
1513 
1514 	default:
1515 	  /* xgettext:c-format */
1516 	  msg = _("%B(%A): internal error: unknown error");
1517 	  break;
1518 	}
1519 
1520       if (msg)
1521 	_bfd_error_handler (msg, input_bfd, input_section, reloc_data.symbol_name);
1522       return FALSE;
1523     }
1524 
1525   return TRUE;
1526 }
1527 
1528 #define elf_arc_hash_table(p) \
1529     (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
1530   == ARC_ELF_DATA ? ((struct elf_arc_link_hash_table *) ((p)->hash)) : NULL)
1531 
1532 static bfd_boolean
1533 elf_arc_check_relocs (bfd *			 abfd,
1534 		      struct bfd_link_info *     info,
1535 		      asection *		 sec,
1536 		      const Elf_Internal_Rela *  relocs)
1537 {
1538   Elf_Internal_Shdr *		symtab_hdr;
1539   struct elf_link_hash_entry **	sym_hashes;
1540   const Elf_Internal_Rela *	rel;
1541   const Elf_Internal_Rela *	rel_end;
1542   bfd *				dynobj;
1543   asection *			sreloc = NULL;
1544 
1545   if (bfd_link_relocatable (info))
1546     return TRUE;
1547 
1548   dynobj = (elf_hash_table (info))->dynobj;
1549   symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1550   sym_hashes = elf_sym_hashes (abfd);
1551 
1552   rel_end = relocs + sec->reloc_count;
1553   for (rel = relocs; rel < rel_end; rel++)
1554     {
1555       enum elf_arc_reloc_type r_type;
1556       reloc_howto_type *howto;
1557       unsigned long   r_symndx;
1558       struct elf_link_hash_entry *h;
1559 
1560       r_type = ELF32_R_TYPE (rel->r_info);
1561 
1562       if (r_type >= (int) R_ARC_max)
1563 	{
1564 	  bfd_set_error (bfd_error_bad_value);
1565 	  return FALSE;
1566 	}
1567       howto = arc_elf_howto (r_type);
1568 
1569       if (dynobj == NULL
1570 	  && (is_reloc_for_GOT (howto) == TRUE
1571 	      || is_reloc_for_TLS (howto) == TRUE))
1572 	{
1573 	  dynobj = elf_hash_table (info)->dynobj = abfd;
1574 	  if (! _bfd_elf_create_got_section (abfd, info))
1575 	    return FALSE;
1576 	}
1577 
1578       /* Load symbol information.  */
1579       r_symndx = ELF32_R_SYM (rel->r_info);
1580       if (r_symndx < symtab_hdr->sh_info) /* Is a local symbol.  */
1581 	h = NULL;
1582       else /* Global one.  */
1583 	h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1584 
1585       switch (r_type)
1586 	{
1587 	  case R_ARC_32:
1588 	  case R_ARC_32_ME:
1589 	    /* During shared library creation, these relocs should not
1590 	       appear in a shared library (as memory will be read only
1591 	       and the dynamic linker can not resolve these.  However
1592 	       the error should not occur for e.g. debugging or
1593 	       non-readonly sections.  */
1594 	    if ((bfd_link_dll (info) && !bfd_link_pie (info))
1595 		&& (sec->flags & SEC_ALLOC) != 0
1596 		&& (sec->flags & SEC_READONLY) != 0
1597 		&& ((sec->flags & SEC_CODE) != 0
1598 		    || (sec->flags & SEC_DEBUGGING) != 0))
1599 	      {
1600 		const char *name;
1601 		if (h)
1602 		  name = h->root.root.string;
1603 		else
1604 		  /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);  */
1605 		  name = "UNKNOWN";
1606 		_bfd_error_handler
1607 		  /* xgettext:c-format */
1608 		  (_("\
1609 %B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
1610 		    abfd,
1611 		    arc_elf_howto (r_type)->name,
1612 		    name);
1613 		bfd_set_error (bfd_error_bad_value);
1614 		return FALSE;
1615 	      }
1616 
1617 	    /* In some cases we are not setting the 'non_got_ref'
1618 	       flag, even though the relocations don't require a GOT
1619 	       access.  We should extend the testing in this area to
1620 	       ensure that no significant cases are being missed.  */
1621 	    if (h)
1622 	      h->non_got_ref = 1;
1623 	    /* FALLTHROUGH */
1624 	  case R_ARC_PC32:
1625 	  case R_ARC_32_PCREL:
1626 	    if ((bfd_link_pic (info))
1627 		&& ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1628 		    || (h != NULL
1629 			&& (!info->symbolic || !h->def_regular))))
1630 	      {
1631 		if (sreloc == NULL)
1632 		  {
1633 		    sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
1634 								  2, abfd,
1635 								  /*rela*/
1636 								  TRUE);
1637 
1638 		    if (sreloc == NULL)
1639 		      return FALSE;
1640 		  }
1641 		sreloc->size += sizeof (Elf32_External_Rela);
1642 
1643 	      }
1644 	  default:
1645 	    break;
1646 	}
1647 
1648       if (is_reloc_for_PLT (howto) == TRUE)
1649 	{
1650 	  if (h == NULL)
1651 	    continue;
1652 	  else
1653 	    h->needs_plt = 1;
1654 	}
1655 
1656       /* Add info to the symbol got_entry_list.  */
1657       if (is_reloc_for_GOT (howto) == TRUE
1658 	  || is_reloc_for_TLS (howto) == TRUE)
1659 	{
1660 	  arc_fill_got_info_for_reloc (
1661 		  arc_got_entry_type_for_reloc (howto),
1662 		  get_got_entry_list_for_symbol (abfd, r_symndx, h),
1663 		  info,
1664 		  h);
1665 	}
1666     }
1667 
1668   return TRUE;
1669 }
1670 
1671 #define ELF_DYNAMIC_INTERPRETER  "/sbin/ld-uClibc.so"
1672 
1673 static struct plt_version_t *
1674 arc_get_plt_version (struct bfd_link_info *info)
1675 {
1676   int i;
1677 
1678   for (i = 0; i < 1; i++)
1679     {
1680       ARC_DEBUG ("%d: size1 = %d, size2 = %d\n", i,
1681 		 (int) plt_versions[i].entry_size,
1682 		 (int) plt_versions[i].elem_size);
1683     }
1684 
1685   if (bfd_get_mach (info->output_bfd) == bfd_mach_arc_arcv2)
1686     {
1687       if (bfd_link_pic (info))
1688 	return &(plt_versions[ELF_ARCV2_PIC]);
1689       else
1690 	return &(plt_versions[ELF_ARCV2_ABS]);
1691     }
1692   else
1693     {
1694       if (bfd_link_pic (info))
1695 	return &(plt_versions[ELF_ARC_PIC]);
1696       else
1697 	return &(plt_versions[ELF_ARC_ABS]);
1698     }
1699 }
1700 
1701 static bfd_vma
1702 add_symbol_to_plt (struct bfd_link_info *info)
1703 {
1704   struct elf_link_hash_table *htab = elf_hash_table (info);
1705   bfd_vma ret;
1706 
1707   struct plt_version_t *plt_data = arc_get_plt_version (info);
1708 
1709   /* If this is the first .plt entry, make room for the special first
1710      entry.  */
1711   if (htab->splt->size == 0)
1712     htab->splt->size += plt_data->entry_size;
1713 
1714   ret = htab->splt->size;
1715 
1716   htab->splt->size += plt_data->elem_size;
1717   ARC_DEBUG ("PLT_SIZE = %d\n", (int) htab->splt->size);
1718 
1719   htab->sgotplt->size += 4;
1720   htab->srelplt->size += sizeof (Elf32_External_Rela);
1721 
1722   return ret;
1723 }
1724 
1725 #define PLT_DO_RELOCS_FOR_ENTRY(ABFD, DS, RELOCS)	\
1726   plt_do_relocs_for_symbol (ABFD, DS, RELOCS, 0, 0)
1727 
1728 static void
1729 plt_do_relocs_for_symbol (bfd *abfd,
1730 			  struct elf_link_hash_table *htab,
1731 			  const struct plt_reloc *reloc,
1732 			  bfd_vma plt_offset,
1733 			  bfd_vma symbol_got_offset)
1734 {
1735   while (SYM_ONLY (reloc->symbol) != LAST_RELOC)
1736     {
1737       bfd_vma relocation = 0;
1738 
1739       switch (SYM_ONLY (reloc->symbol))
1740 	{
1741 	  case SGOT:
1742 		relocation
1743 		  = htab->sgotplt->output_section->vma
1744 		    + htab->sgotplt->output_offset + symbol_got_offset;
1745 		break;
1746 	}
1747       relocation += reloc->addend;
1748 
1749       if (IS_RELATIVE (reloc->symbol))
1750 	{
1751 	  bfd_vma reloc_offset = reloc->offset;
1752 	  reloc_offset -= (IS_INSN_32 (reloc->symbol)) ? 4 : 0;
1753 	  reloc_offset -= (IS_INSN_24 (reloc->symbol)) ? 2 : 0;
1754 
1755 	  relocation -= htab->splt->output_section->vma
1756 			 + htab->splt->output_offset
1757 			 + plt_offset + reloc_offset;
1758 	}
1759 
1760       /* TODO: being ME is not a property of the relocation but of the
1761 	 section of which is applying the relocation. */
1762       if (IS_MIDDLE_ENDIAN (reloc->symbol) && !bfd_big_endian (abfd))
1763 	{
1764 	  relocation
1765 	    = ((relocation & 0xffff0000) >> 16)
1766 	      | ((relocation & 0xffff) << 16);
1767 	}
1768 
1769       switch (reloc->size)
1770 	{
1771 	  case 32:
1772 	    bfd_put_32 (htab->splt->output_section->owner,
1773 			relocation,
1774 			htab->splt->contents + plt_offset + reloc->offset);
1775 	    break;
1776 	}
1777 
1778       reloc = &(reloc[1]); /* Jump to next relocation.  */
1779     }
1780 }
1781 
1782 static void
1783 relocate_plt_for_symbol (bfd *output_bfd,
1784 			 struct bfd_link_info *info,
1785 			 struct elf_link_hash_entry *h)
1786 {
1787   struct plt_version_t *plt_data = arc_get_plt_version (info);
1788   struct elf_link_hash_table *htab = elf_hash_table (info);
1789 
1790   bfd_vma plt_index = (h->plt.offset  - plt_data->entry_size)
1791 		      / plt_data->elem_size;
1792   bfd_vma got_offset = (plt_index + 3) * 4;
1793 
1794   ARC_DEBUG ("arc_info: PLT_OFFSET = %#lx, PLT_ENTRY_VMA = %#lx, \
1795 GOT_ENTRY_OFFSET = %#lx, GOT_ENTRY_VMA = %#lx, for symbol %s\n",
1796 	     (long) h->plt.offset,
1797 	     (long) (htab->splt->output_section->vma
1798 		     + htab->splt->output_offset
1799 		     + h->plt.offset),
1800 	     (long) got_offset,
1801 	     (long) (htab->sgotplt->output_section->vma
1802 		     + htab->sgotplt->output_offset
1803 		     + got_offset),
1804 	     h->root.root.string);
1805 
1806   {
1807     bfd_vma i = 0;
1808     uint16_t *ptr = (uint16_t *) plt_data->elem;
1809 
1810     for (i = 0; i < plt_data->elem_size/2; i++)
1811       {
1812 	uint16_t data = ptr[i];
1813 	bfd_put_16 (output_bfd,
1814 		    (bfd_vma) data,
1815 		    htab->splt->contents + h->plt.offset + (i*2));
1816       }
1817   }
1818 
1819   plt_do_relocs_for_symbol (output_bfd, htab,
1820 			    plt_data->elem_relocs,
1821 			    h->plt.offset,
1822 			    got_offset);
1823 
1824   /* Fill in the entry in the global offset table.  */
1825   bfd_put_32 (output_bfd,
1826 	      (bfd_vma) (htab->splt->output_section->vma
1827 			 + htab->splt->output_offset),
1828 	      htab->sgotplt->contents + got_offset);
1829 
1830   /* TODO: Fill in the entry in the .rela.plt section.  */
1831   {
1832     Elf_Internal_Rela rel;
1833     bfd_byte *loc;
1834 
1835     rel.r_offset = (htab->sgotplt->output_section->vma
1836 		    + htab->sgotplt->output_offset
1837 		    + got_offset);
1838     rel.r_addend = 0;
1839 
1840     BFD_ASSERT (h->dynindx != -1);
1841     rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_JMP_SLOT);
1842 
1843     loc = htab->srelplt->contents;
1844     loc += plt_index * sizeof (Elf32_External_Rela); /* relA */
1845     bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
1846   }
1847 }
1848 
1849 static void
1850 relocate_plt_for_entry (bfd *abfd,
1851 			struct bfd_link_info *info)
1852 {
1853   struct plt_version_t *plt_data = arc_get_plt_version (info);
1854   struct elf_link_hash_table *htab = elf_hash_table (info);
1855 
1856   {
1857     bfd_vma i = 0;
1858     uint16_t *ptr = (uint16_t *) plt_data->entry;
1859     for (i = 0; i < plt_data->entry_size/2; i++)
1860       {
1861 	uint16_t data = ptr[i];
1862 	bfd_put_16 (abfd,
1863 		    (bfd_vma) data,
1864 		    htab->splt->contents + (i*2));
1865       }
1866   }
1867   PLT_DO_RELOCS_FOR_ENTRY (abfd, htab, plt_data->entry_relocs);
1868 }
1869 
1870 /* Desc : Adjust a symbol defined by a dynamic object and referenced
1871    by a regular object.  The current definition is in some section of
1872    the dynamic object, but we're not including those sections.  We
1873    have to change the definition to something the rest of the link can
1874    understand.  */
1875 
1876 static bfd_boolean
1877 elf_arc_adjust_dynamic_symbol (struct bfd_link_info *info,
1878 			      struct elf_link_hash_entry *h)
1879 {
1880   asection *s;
1881   bfd *dynobj = (elf_hash_table (info))->dynobj;
1882   struct elf_link_hash_table *htab = elf_hash_table (info);
1883 
1884   if (h->type == STT_FUNC
1885       || h->type == STT_GNU_IFUNC
1886       || h->needs_plt == 1)
1887     {
1888       if (!bfd_link_pic (info) && !h->def_dynamic && !h->ref_dynamic)
1889 	{
1890 	  /* This case can occur if we saw a PLT32 reloc in an input
1891 	     file, but the symbol was never referred to by a dynamic
1892 	     object.  In such a case, we don't actually need to build
1893 	     a procedure linkage table, and we can just do a PC32
1894 	     reloc instead.  */
1895 	  BFD_ASSERT (h->needs_plt);
1896 	  return TRUE;
1897 	}
1898 
1899       /* Make sure this symbol is output as a dynamic symbol.  */
1900       if (h->dynindx == -1 && !h->forced_local
1901 	  && !bfd_elf_link_record_dynamic_symbol (info, h))
1902 	return FALSE;
1903 
1904       if (bfd_link_pic (info)
1905 	  || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
1906 	{
1907 	  bfd_vma loc = add_symbol_to_plt (info);
1908 
1909 	  if (bfd_link_executable (info) && !h->def_regular)
1910 	    {
1911 	      h->root.u.def.section = htab->splt;
1912 	      h->root.u.def.value = loc;
1913 	    }
1914 	  h->plt.offset = loc;
1915 	}
1916       else
1917 	{
1918 	  h->plt.offset = (bfd_vma) -1;
1919 	  h->needs_plt = 0;
1920 	}
1921       return TRUE;
1922     }
1923 
1924   /* If this is a weak symbol, and there is a real definition, the
1925      processor independent code will have arranged for us to see the
1926      real definition first, and we can just use the same value.  */
1927   if (h->u.weakdef != NULL)
1928     {
1929       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
1930 		  || h->u.weakdef->root.type == bfd_link_hash_defweak);
1931       h->root.u.def.section = h->u.weakdef->root.u.def.section;
1932       h->root.u.def.value = h->u.weakdef->root.u.def.value;
1933       return TRUE;
1934     }
1935 
1936   /* This is a reference to a symbol defined by a dynamic object which
1937      is not a function.  */
1938 
1939   /* If we are creating a shared library, we must presume that the
1940      only references to the symbol are via the global offset table.
1941      For such cases we need not do anything here; the relocations will
1942      be handled correctly by relocate_section.  */
1943   if (!bfd_link_executable (info))
1944     return TRUE;
1945 
1946   /* If there are no non-GOT references, we do not need a copy
1947      relocation.  */
1948   if (!h->non_got_ref)
1949     return TRUE;
1950 
1951   /* If -z nocopyreloc was given, we won't generate them either.  */
1952   if (info->nocopyreloc)
1953     {
1954       h->non_got_ref = 0;
1955       return TRUE;
1956     }
1957 
1958   /* We must allocate the symbol in our .dynbss section, which will
1959      become part of the .bss section of the executable.  There will be
1960      an entry for this symbol in the .dynsym section.  The dynamic
1961      object will contain position independent code, so all references
1962      from the dynamic object to this symbol will go through the global
1963      offset table.  The dynamic linker will use the .dynsym entry to
1964      determine the address it must put in the global offset table, so
1965      both the dynamic object and the regular object will refer to the
1966      same memory location for the variable.  */
1967 
1968   if (htab == NULL)
1969     return FALSE;
1970 
1971   /* We must generate a R_ARC_COPY reloc to tell the dynamic linker to
1972      copy the initial value out of the dynamic object and into the
1973      runtime process image.  We need to remember the offset into the
1974      .rela.bss section we are going to use.  */
1975   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
1976     {
1977       struct elf_arc_link_hash_table *arc_htab = elf_arc_hash_table (info);
1978 
1979       BFD_ASSERT (arc_htab->elf.srelbss != NULL);
1980       arc_htab->elf.srelbss->size += sizeof (Elf32_External_Rela);
1981       h->needs_copy = 1;
1982     }
1983 
1984   /* TODO: Move this also to arc_hash_table.  */
1985   s = bfd_get_section_by_name (dynobj, ".dynbss");
1986   BFD_ASSERT (s != NULL);
1987 
1988   return _bfd_elf_adjust_dynamic_copy (info, h, s);
1989 }
1990 
1991 /* Function :  elf_arc_finish_dynamic_symbol
1992    Brief    :  Finish up dynamic symbol handling.  We set the
1993 	     contents of various dynamic sections here.
1994    Args     :  output_bfd :
1995 	       info	  :
1996 	       h	  :
1997 	       sym	  :
1998    Returns  : True/False as the return status.  */
1999 
2000 static bfd_boolean
2001 elf_arc_finish_dynamic_symbol (bfd * output_bfd,
2002 			       struct bfd_link_info *info,
2003 			       struct elf_link_hash_entry *h,
2004 			       Elf_Internal_Sym * sym)
2005 {
2006   if (h->plt.offset != (bfd_vma) -1)
2007     {
2008       relocate_plt_for_symbol (output_bfd, info, h);
2009 
2010       if (!h->def_regular)
2011 	{
2012 	  /* Mark the symbol as undefined, rather than as defined in
2013 	     the .plt section.  Leave the value alone.  */
2014 	  sym->st_shndx = SHN_UNDEF;
2015 	}
2016     }
2017 
2018 
2019   /* This function traverses list of GOT entries and
2020      create respective dynamic relocs.  */
2021   /* TODO: Make function to get list and not access the list directly.  */
2022   /* TODO: Move function to relocate_section create this relocs eagerly.  */
2023   create_got_dynrelocs_for_got_info (&h->got.glist,
2024 				     output_bfd,
2025 				     info,
2026 				     h);
2027 
2028   if (h->needs_copy)
2029     {
2030       struct elf_arc_link_hash_table *arc_htab = elf_arc_hash_table (info);
2031 
2032       if (h->dynindx == -1
2033 	  || (h->root.type != bfd_link_hash_defined
2034 	      && h->root.type != bfd_link_hash_defweak)
2035 	  || arc_htab->elf.srelbss == NULL)
2036 	abort ();
2037 
2038       bfd_vma rel_offset = (h->root.u.def.value
2039 			    + h->root.u.def.section->output_section->vma
2040 			    + h->root.u.def.section->output_offset);
2041 
2042       bfd_byte * loc = arc_htab->elf.srelbss->contents
2043 	+ (arc_htab->elf.srelbss->reloc_count * sizeof (Elf32_External_Rela));
2044       arc_htab->elf.srelbss->reloc_count++;
2045 
2046       Elf_Internal_Rela rel;
2047       rel.r_addend = 0;
2048       rel.r_offset = rel_offset;
2049 
2050       BFD_ASSERT (h->dynindx != -1);
2051       rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_COPY);
2052 
2053       bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2054     }
2055 
2056   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
2057   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2058       || strcmp (h->root.root.string, "__DYNAMIC") == 0
2059       || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
2060     sym->st_shndx = SHN_ABS;
2061 
2062   return TRUE;
2063 }
2064 
2065 #define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION)		\
2066   case TAG:							\
2067   if (SYMBOL != NULL)						\
2068     h = elf_link_hash_lookup (elf_hash_table (info),		\
2069 			      SYMBOL, FALSE, FALSE, TRUE);	\
2070   else if (SECTION != NULL)					\
2071     s = bfd_get_linker_section (dynobj, SECTION);		\
2072   break;
2073 
2074 /* Function :  elf_arc_finish_dynamic_sections
2075    Brief    :  Finish up the dynamic sections handling.
2076    Args     :  output_bfd :
2077 	       info	  :
2078 	       h	  :
2079 	       sym	  :
2080    Returns  : True/False as the return status.  */
2081 
2082 static bfd_boolean
2083 elf_arc_finish_dynamic_sections (bfd * output_bfd,
2084 				 struct bfd_link_info *info)
2085 {
2086   struct elf_link_hash_table *htab = elf_hash_table (info);
2087   bfd *dynobj = (elf_hash_table (info))->dynobj;
2088   asection *sdyn = bfd_get_linker_section (dynobj, ".dynamic");
2089 
2090   if (sdyn)
2091     {
2092       Elf32_External_Dyn *dyncon, *dynconend;
2093 
2094       dyncon = (Elf32_External_Dyn *) sdyn->contents;
2095       dynconend
2096 	= (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
2097       for (; dyncon < dynconend; dyncon++)
2098 	{
2099 	  Elf_Internal_Dyn internal_dyn;
2100 	  bfd_boolean	  do_it = FALSE;
2101 
2102 	  struct elf_link_hash_entry *h = NULL;
2103 	  asection	 *s = NULL;
2104 
2105 	  bfd_elf32_swap_dyn_in (dynobj, dyncon, &internal_dyn);
2106 
2107 	  switch (internal_dyn.d_tag)
2108 	    {
2109 	      GET_SYMBOL_OR_SECTION (DT_INIT, info->init_function, NULL)
2110 	      GET_SYMBOL_OR_SECTION (DT_FINI, info->fini_function, NULL)
2111 	      GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt")
2112 	      GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt")
2113 	      GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt")
2114 	      GET_SYMBOL_OR_SECTION (DT_VERSYM, NULL, ".gnu.version")
2115 	      GET_SYMBOL_OR_SECTION (DT_VERDEF, NULL, ".gnu.version_d")
2116 	      GET_SYMBOL_OR_SECTION (DT_VERNEED, NULL, ".gnu.version_r")
2117 	      default:
2118 		break;
2119 	    }
2120 
2121 	  /* In case the dynamic symbols should be updated with a symbol.  */
2122 	  if (h != NULL
2123 	      && (h->root.type == bfd_link_hash_defined
2124 		  || h->root.type == bfd_link_hash_defweak))
2125 	    {
2126 	      asection	     *asec_ptr;
2127 
2128 	      internal_dyn.d_un.d_val = h->root.u.def.value;
2129 	      asec_ptr = h->root.u.def.section;
2130 	      if (asec_ptr->output_section != NULL)
2131 		{
2132 		  internal_dyn.d_un.d_val +=
2133 		    (asec_ptr->output_section->vma
2134 		     + asec_ptr->output_offset);
2135 		}
2136 	      else
2137 		{
2138 		  /* The symbol is imported from another shared
2139 		     library and does not apply to this one.  */
2140 		  internal_dyn.d_un.d_val = 0;
2141 		}
2142 	      do_it = TRUE;
2143 	    }
2144 	  else if (s != NULL) /* With a section information.  */
2145 	    {
2146 	      switch (internal_dyn.d_tag)
2147 		{
2148 		  case DT_PLTGOT:
2149 		  case DT_JMPREL:
2150 		  case DT_VERSYM:
2151 		  case DT_VERDEF:
2152 		  case DT_VERNEED:
2153 		    internal_dyn.d_un.d_ptr = (s->output_section->vma
2154 					       + s->output_offset);
2155 		    do_it = TRUE;
2156 		    break;
2157 
2158 		  case DT_PLTRELSZ:
2159 		    internal_dyn.d_un.d_val = s->size;
2160 		    do_it = TRUE;
2161 		    break;
2162 
2163 		  default:
2164 		    break;
2165 		}
2166 	    }
2167 
2168 	  if (do_it)
2169 	    bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon);
2170 	}
2171 
2172       if (htab->splt->size > 0)
2173 	{
2174 	  relocate_plt_for_entry (output_bfd, info);
2175 	}
2176 
2177       /* TODO: Validate this.  */
2178       if (htab->srelplt->output_section != bfd_abs_section_ptr)
2179 	elf_section_data (htab->srelplt->output_section)
2180 	  ->this_hdr.sh_entsize = 12;
2181     }
2182 
2183   /* Fill in the first three entries in the global offset table.  */
2184   if (htab->sgot)
2185     {
2186       struct elf_link_hash_entry *h;
2187       h = elf_link_hash_lookup (elf_hash_table (info), "_GLOBAL_OFFSET_TABLE_",
2188 				 FALSE, FALSE, TRUE);
2189 
2190 	if (h != NULL && h->root.type != bfd_link_hash_undefined
2191 	    && h->root.u.def.section != NULL)
2192 	{
2193 	  asection *sec = h->root.u.def.section;
2194 
2195 	  if (sdyn == NULL)
2196 	    bfd_put_32 (output_bfd, (bfd_vma) 0,
2197 			sec->contents);
2198 	  else
2199 	    bfd_put_32 (output_bfd,
2200 			sdyn->output_section->vma + sdyn->output_offset,
2201 			sec->contents);
2202 	  bfd_put_32 (output_bfd, (bfd_vma) 0, sec->contents + 4);
2203 	  bfd_put_32 (output_bfd, (bfd_vma) 0, sec->contents + 8);
2204 	}
2205     }
2206 
2207   return TRUE;
2208 }
2209 
2210 #define ADD_DYNAMIC_SYMBOL(NAME, TAG)					\
2211   h =  elf_link_hash_lookup (elf_hash_table (info),			\
2212 			     NAME, FALSE, FALSE, FALSE);		\
2213   if ((h != NULL && (h->ref_regular || h->def_regular)))		\
2214     if (! _bfd_elf_add_dynamic_entry (info, TAG, 0))			\
2215       return FALSE;
2216 
2217 /* Set the sizes of the dynamic sections.  */
2218 static bfd_boolean
2219 elf_arc_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2220 			       struct bfd_link_info *info)
2221 {
2222   bfd *dynobj;
2223   asection *s;
2224   bfd_boolean relocs_exist = FALSE;
2225   bfd_boolean reltext_exist = FALSE;
2226   struct elf_link_hash_table *htab = elf_hash_table (info);
2227 
2228   dynobj = htab->dynobj;
2229   BFD_ASSERT (dynobj != NULL);
2230 
2231   if (htab->dynamic_sections_created)
2232     {
2233       struct elf_link_hash_entry *h;
2234 
2235       /* Set the contents of the .interp section to the
2236 	 interpreter.  */
2237       if (bfd_link_executable (info) && !info->nointerp)
2238 	{
2239 	  s = bfd_get_section_by_name (dynobj, ".interp");
2240 	  BFD_ASSERT (s != NULL);
2241 	  s->size = sizeof (ELF_DYNAMIC_INTERPRETER);
2242 	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2243 	}
2244 
2245       /* Add some entries to the .dynamic section.  We fill in some of
2246 	 the values later, in elf_bfd_final_link, but we must add the
2247 	 entries now so that we know the final size of the .dynamic
2248 	 section.  Checking if the .init section is present.  We also
2249 	 create DT_INIT and DT_FINI entries if the init_str has been
2250 	 changed by the user.  */
2251       ADD_DYNAMIC_SYMBOL (info->init_function, DT_INIT);
2252       ADD_DYNAMIC_SYMBOL (info->fini_function, DT_FINI);
2253     }
2254   else
2255     {
2256       /* We may have created entries in the .rela.got section.
2257 	 However, if we are not creating the dynamic sections, we will
2258 	 not actually use these entries.  Reset the size of .rela.got,
2259 	 which will cause it to get stripped from the output file
2260 	 below.  */
2261       if (htab->srelgot != NULL)
2262 	htab->srelgot->size = 0;
2263     }
2264 
2265   for (s = dynobj->sections; s != NULL; s = s->next)
2266     {
2267       if ((s->flags & SEC_LINKER_CREATED) == 0)
2268 	continue;
2269 
2270       if (s == htab->splt
2271 	  || s == htab->sgot
2272 	  || s == htab->sgotplt
2273 	  || s == htab->sdynbss)
2274 	{
2275 	  /* Strip this section if we don't need it.  */
2276 	}
2277       else if (strncmp (s->name, ".rela", 5) == 0)
2278 	{
2279 	  if (s->size != 0 && s != htab->srelplt)
2280 	    {
2281 	      if (!reltext_exist)
2282 		{
2283 		  const char *name = s->name + 5;
2284 		  bfd *ibfd;
2285 		  for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next)
2286 		    if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour)
2287 		      {
2288 			asection *target = bfd_get_section_by_name (ibfd, name);
2289 			if (target != NULL
2290 			    && elf_section_data (target)->sreloc == s
2291 			    && ((target->output_section->flags
2292 				 & (SEC_READONLY | SEC_ALLOC))
2293 				== (SEC_READONLY | SEC_ALLOC)))
2294 			  {
2295 			    reltext_exist = TRUE;
2296 			    break;
2297 			  }
2298 		      }
2299 		}
2300 	      relocs_exist = TRUE;
2301 	    }
2302 
2303 	  /* We use the reloc_count field as a counter if we need to
2304 	     copy relocs into the output file.  */
2305 	  s->reloc_count = 0;
2306 	}
2307       else
2308 	{
2309 	  /* It's not one of our sections, so don't allocate space.  */
2310 	  continue;
2311 	}
2312 
2313       if (s->size == 0)
2314 	{
2315 	  s->flags |= SEC_EXCLUDE;
2316 	  continue;
2317 	}
2318 
2319       if ((s->flags & SEC_HAS_CONTENTS) == 0)
2320 	continue;
2321 
2322       /* Allocate memory for the section contents.  */
2323       s->contents = bfd_zalloc (dynobj, s->size);
2324       if (s->contents == NULL)
2325 	return FALSE;
2326     }
2327 
2328   if (htab->dynamic_sections_created)
2329     {
2330       /* TODO: Check if this is needed.  */
2331       if (!bfd_link_pic (info))
2332 	if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
2333 		return FALSE;
2334 
2335       if (htab->splt && (htab->splt->flags & SEC_EXCLUDE) == 0)
2336 	if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
2337 	    || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2338 	    || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2339 	    || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
2340 	  return FALSE;
2341 
2342       if (relocs_exist)
2343 	if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
2344 	    || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
2345 	    || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
2346 					    sizeof (Elf32_External_Rela)))
2347 	  return FALSE;
2348 
2349       if (reltext_exist)
2350 	if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
2351 	  return FALSE;
2352     }
2353 
2354   return TRUE;
2355 }
2356 
2357 
2358 /* Classify dynamic relocs such that -z combreloc can reorder and combine
2359    them.  */
2360 static enum elf_reloc_type_class
2361 elf32_arc_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
2362 			    const asection *rel_sec ATTRIBUTE_UNUSED,
2363 			    const Elf_Internal_Rela *rela)
2364 {
2365   switch ((int) ELF32_R_TYPE (rela->r_info))
2366     {
2367     case R_ARC_RELATIVE:
2368       return reloc_class_relative;
2369     case R_ARC_JMP_SLOT:
2370       return reloc_class_plt;
2371     case R_ARC_COPY:
2372       return reloc_class_copy;
2373     /* TODO: Needed in future to support ifunc.  */
2374     /*
2375     case R_ARC_IRELATIVE:
2376       return reloc_class_ifunc;
2377     */
2378     default:
2379       return reloc_class_normal;
2380     }
2381 }
2382 
2383 const struct elf_size_info arc_elf32_size_info =
2384 {
2385   sizeof (Elf32_External_Ehdr),
2386   sizeof (Elf32_External_Phdr),
2387   sizeof (Elf32_External_Shdr),
2388   sizeof (Elf32_External_Rel),
2389   sizeof (Elf32_External_Rela),
2390   sizeof (Elf32_External_Sym),
2391   sizeof (Elf32_External_Dyn),
2392   sizeof (Elf_External_Note),
2393   4,
2394   1,
2395   32, 2,
2396   ELFCLASS32, EV_CURRENT,
2397   bfd_elf32_write_out_phdrs,
2398   bfd_elf32_write_shdrs_and_ehdr,
2399   bfd_elf32_checksum_contents,
2400   bfd_elf32_write_relocs,
2401   bfd_elf32_swap_symbol_in,
2402   bfd_elf32_swap_symbol_out,
2403   bfd_elf32_slurp_reloc_table,
2404   bfd_elf32_slurp_symbol_table,
2405   bfd_elf32_swap_dyn_in,
2406   bfd_elf32_swap_dyn_out,
2407   bfd_elf32_swap_reloc_in,
2408   bfd_elf32_swap_reloc_out,
2409   bfd_elf32_swap_reloca_in,
2410   bfd_elf32_swap_reloca_out
2411 };
2412 
2413 #define elf_backend_size_info		arc_elf32_size_info
2414 
2415 /* Hook called by the linker routine which adds symbols from an object
2416    file.  */
2417 
2418 static bfd_boolean
2419 elf_arc_add_symbol_hook (bfd * abfd,
2420 			 struct bfd_link_info * info,
2421 			 Elf_Internal_Sym * sym,
2422 			 const char ** namep ATTRIBUTE_UNUSED,
2423 			 flagword * flagsp ATTRIBUTE_UNUSED,
2424 			 asection ** secp ATTRIBUTE_UNUSED,
2425 			 bfd_vma * valp ATTRIBUTE_UNUSED)
2426 {
2427   if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
2428       && (abfd->flags & DYNAMIC) == 0
2429       && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
2430     elf_tdata (info->output_bfd)->has_gnu_symbols |= elf_gnu_symbol_ifunc;
2431 
2432   return TRUE;
2433 }
2434 
2435 /* GDB expects general purpose registers to be in section .reg.  However Linux
2436    kernel doesn't create this section and instead writes registers to NOTE
2437    section.  It is up to the binutils to create a pseudo-section .reg from the
2438    contents of NOTE.  Also BFD will read pid and signal number from NOTE.  This
2439    function relies on offsets inside elf_prstatus structure in Linux to be
2440    stable.  */
2441 
2442 static bfd_boolean
2443 elf32_arc_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
2444 {
2445   int offset;
2446   size_t size;
2447 
2448   switch (note->descsz)
2449     {
2450     default:
2451       return FALSE;
2452 
2453     case 236: /* sizeof (struct elf_prstatus) on Linux/arc.  */
2454       /* pr_cursig */
2455       elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
2456       /* pr_pid */
2457       elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
2458       /* pr_regs */
2459       offset = 72;
2460       size = (40 * 4); /* There are 40 registers in user_regs_struct.  */
2461       break;
2462     }
2463   /* Make a ".reg/999" section.  */
2464   return _bfd_elfcore_make_pseudosection (abfd, ".reg", size,
2465 					  note->descpos + offset);
2466 }
2467 
2468 #define TARGET_LITTLE_SYM   arc_elf32_le_vec
2469 #define TARGET_LITTLE_NAME  "elf32-littlearc"
2470 #define TARGET_BIG_SYM	    arc_elf32_be_vec
2471 #define TARGET_BIG_NAME     "elf32-bigarc"
2472 #define ELF_ARCH	    bfd_arch_arc
2473 #define ELF_TARGET_ID	    ARC_ELF_DATA
2474 #define ELF_MACHINE_CODE    EM_ARC_COMPACT
2475 #define ELF_MACHINE_ALT1    EM_ARC_COMPACT2
2476 #define ELF_MAXPAGESIZE     0x2000
2477 
2478 #define bfd_elf32_bfd_link_hash_table_create	arc_elf_link_hash_table_create
2479 
2480 #define bfd_elf32_bfd_merge_private_bfd_data    arc_elf_merge_private_bfd_data
2481 #define bfd_elf32_bfd_reloc_type_lookup		arc_elf32_bfd_reloc_type_lookup
2482 #define bfd_elf32_bfd_set_private_flags		arc_elf_set_private_flags
2483 #define bfd_elf32_bfd_print_private_bfd_data    arc_elf_print_private_bfd_data
2484 #define bfd_elf32_bfd_copy_private_bfd_data     arc_elf_copy_private_bfd_data
2485 
2486 #define elf_info_to_howto_rel		     arc_info_to_howto_rel
2487 #define elf_backend_object_p		     arc_elf_object_p
2488 #define elf_backend_final_write_processing   arc_elf_final_write_processing
2489 
2490 #define elf_backend_relocate_section	     elf_arc_relocate_section
2491 #define elf_backend_check_relocs	     elf_arc_check_relocs
2492 #define elf_backend_create_dynamic_sections  _bfd_elf_create_dynamic_sections
2493 
2494 #define elf_backend_reloc_type_class		elf32_arc_reloc_type_class
2495 
2496 #define elf_backend_adjust_dynamic_symbol    elf_arc_adjust_dynamic_symbol
2497 #define elf_backend_finish_dynamic_symbol    elf_arc_finish_dynamic_symbol
2498 
2499 #define elf_backend_finish_dynamic_sections  elf_arc_finish_dynamic_sections
2500 #define elf_backend_size_dynamic_sections    elf_arc_size_dynamic_sections
2501 #define elf_backend_add_symbol_hook	     elf_arc_add_symbol_hook
2502 
2503 #define elf_backend_can_gc_sections	1
2504 #define elf_backend_want_got_plt	1
2505 #define elf_backend_plt_readonly	1
2506 #define elf_backend_rela_plts_and_copies_p 1
2507 #define elf_backend_want_plt_sym	0
2508 #define elf_backend_got_header_size	12
2509 #define elf_backend_dtrel_excludes_plt	1
2510 
2511 #define elf_backend_may_use_rel_p	0
2512 #define elf_backend_may_use_rela_p	1
2513 #define elf_backend_default_use_rela_p	1
2514 
2515 #define elf_backend_grok_prstatus elf32_arc_grok_prstatus
2516 
2517 #define elf_backend_default_execstack	0
2518 
2519 #include "elf32-target.h"
2520