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