elf_backend_dtrel_excludes_plt
[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, struct bfd_link_info *info)
546 {
547   bfd *obfd = info->output_bfd;
548   unsigned short mach_ibfd;
549   static unsigned short mach_obfd = EM_NONE;
550   flagword out_flags;
551   flagword in_flags;
552   asection *sec;
553
554    /* Check if we have the same endianess.  */
555   if (! _bfd_generic_verify_endian_match (ibfd, info))
556     return FALSE;
557
558   /* Collect ELF flags.  */
559   in_flags = elf_elfheader (ibfd)->e_flags & EF_ARC_MACH_MSK;
560   out_flags = elf_elfheader (obfd)->e_flags & EF_ARC_MACH_MSK;
561
562   if (!elf_flags_init (obfd)) /* First call, no flags set.  */
563     {
564       elf_flags_init (obfd) = TRUE;
565       out_flags = in_flags;
566     }
567
568   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
569       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
570     return TRUE;
571
572   /* Check to see if the input BFD actually contains any sections.  Do
573      not short-circuit dynamic objects; their section list may be
574      emptied by elf_link_add_object_symbols.  */
575   if (!(ibfd->flags & DYNAMIC))
576     {
577       bfd_boolean null_input_bfd = TRUE;
578       bfd_boolean only_data_sections = TRUE;
579
580       for (sec = ibfd->sections; sec != NULL; sec = sec->next)
581         {
582           if ((bfd_get_section_flags (ibfd, sec)
583                & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
584               == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
585             only_data_sections = FALSE;
586
587           null_input_bfd = FALSE;
588         }
589
590       if (null_input_bfd || only_data_sections)
591         return TRUE;
592     }
593
594   /* Complain about various flag/architecture mismatches.  */
595   mach_ibfd = elf_elfheader (ibfd)->e_machine;
596   if (mach_obfd == EM_NONE)
597     {
598       mach_obfd = mach_ibfd;
599     }
600   else
601     {
602       if (mach_ibfd != mach_obfd)
603         {
604           /* xgettext:c-format */
605           _bfd_error_handler (_("ERROR: Attempting to link %B "
606                                 "with a binary %s of different architecture"),
607                               ibfd, bfd_get_filename (obfd));
608           return FALSE;
609         }
610       else if (in_flags != out_flags)
611         {
612           /* Warn if different flags.  */
613           _bfd_error_handler
614             /* xgettext:c-format */
615             (_("%s: uses different e_flags (0x%lx) fields than "
616                "previous modules (0x%lx)"),
617              bfd_get_filename (ibfd), (long)in_flags, (long)out_flags);
618           if (in_flags && out_flags)
619             return FALSE;
620           /* MWDT doesnt set the eflags hence make sure we choose the
621              eflags set by gcc.  */
622           in_flags = in_flags > out_flags ? in_flags : out_flags;
623         }
624     }
625
626   /* Update the flags.  */
627   elf_elfheader (obfd)->e_flags = in_flags;
628
629   if (bfd_get_mach (obfd) < bfd_get_mach (ibfd))
630     {
631       return bfd_set_arch_mach (obfd, bfd_arch_arc, bfd_get_mach (ibfd));
632     }
633
634   return TRUE;
635 }
636
637 /* Set the right machine number for an ARC ELF file.  */
638 static bfd_boolean
639 arc_elf_object_p (bfd * abfd)
640 {
641   /* Make sure this is initialised, or you'll have the potential of passing
642      garbage---or misleading values---into the call to
643      bfd_default_set_arch_mach ().  */
644   int             mach = bfd_mach_arc_arc700;
645   unsigned long   arch = elf_elfheader (abfd)->e_flags & EF_ARC_MACH_MSK;
646   unsigned        e_machine = elf_elfheader (abfd)->e_machine;
647
648   if (e_machine == EM_ARC_COMPACT || e_machine == EM_ARC_COMPACT2)
649     {
650       switch (arch)
651         {
652           case E_ARC_MACH_ARC600:
653             mach = bfd_mach_arc_arc600;
654             break;
655           case E_ARC_MACH_ARC601:
656             mach = bfd_mach_arc_arc601;
657             break;
658           case E_ARC_MACH_ARC700:
659             mach = bfd_mach_arc_arc700;
660             break;
661           case EF_ARC_CPU_ARCV2HS:
662           case EF_ARC_CPU_ARCV2EM:
663             mach = bfd_mach_arc_arcv2;
664             break;
665           default:
666             mach = (e_machine == EM_ARC_COMPACT)
667               ? bfd_mach_arc_arc700 : bfd_mach_arc_arcv2;
668             break;
669         }
670     }
671   else
672     {
673       if (e_machine == EM_ARC)
674         {
675           _bfd_error_handler
676             (_("Error: The ARC4 architecture is no longer supported.\n"));
677           return FALSE;
678         }
679       else
680         {
681           _bfd_error_handler
682             (_("Warning: unset or old architecture flags. \n"
683                "               Use default machine.\n"));
684         }
685     }
686
687   return bfd_default_set_arch_mach (abfd, bfd_arch_arc, mach);
688 }
689
690 /* The final processing done just before writing out an ARC ELF object file.
691    This gets the ARC architecture right based on the machine number.  */
692
693 static void
694 arc_elf_final_write_processing (bfd * abfd,
695                                 bfd_boolean linker ATTRIBUTE_UNUSED)
696 {
697   unsigned long emf;
698
699   switch (bfd_get_mach (abfd))
700     {
701     case bfd_mach_arc_arc600:
702       emf = EM_ARC_COMPACT;
703       break;
704     case bfd_mach_arc_arc601:
705       emf = EM_ARC_COMPACT;
706       break;
707     case bfd_mach_arc_arc700:
708       emf = EM_ARC_COMPACT;
709       break;
710     case bfd_mach_arc_arcv2:
711       emf = EM_ARC_COMPACT2;
712       break;
713     default:
714       goto DO_NOTHING;
715     }
716
717   elf_elfheader (abfd)->e_machine = emf;
718
719   /* Record whatever is the current syscall ABI version.  */
720   elf_elfheader (abfd)->e_flags |= E_ARC_OSABI_CURRENT;
721
722 DO_NOTHING:
723   return;
724 }
725
726 #ifdef ARC_ENABLE_DEBUG
727 #define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
728
729 static void
730 debug_arc_reloc (struct arc_relocation_data reloc_data)
731 {
732   ARC_DEBUG ("Reloc type=%s, should_relocate = %s\n",
733              reloc_data.howto->name,
734              reloc_data.should_relocate ? "true" : "false");
735   ARC_DEBUG ("  offset = 0x%x, addend = 0x%x\n",
736              (unsigned int) reloc_data.reloc_offset,
737              (unsigned int) reloc_data.reloc_addend);
738   ARC_DEBUG (" Symbol:\n");
739   ARC_DEBUG ("  value = 0x%08x\n",
740              (unsigned int) reloc_data.sym_value);
741   if (reloc_data.sym_section != NULL)
742     {
743       ARC_DEBUG (" Symbol Section:\n");
744       ARC_DEBUG ("  section name = %s, output_offset 0x%08x",
745                  reloc_data.sym_section->name,
746                  (unsigned int) reloc_data.sym_section->output_offset);
747       if (reloc_data.sym_section->output_section != NULL)
748         ARC_DEBUG (", output_section->vma = 0x%08x",
749                    ((unsigned int) reloc_data.sym_section->output_section->vma));
750       ARC_DEBUG ("\n");
751       if (reloc_data.sym_section->owner && reloc_data.sym_section->owner->filename)
752         ARC_DEBUG ("  file: %s\n", reloc_data.sym_section->owner->filename);
753     }
754   else
755     {
756       ARC_DEBUG ("  symbol section is NULL\n");
757     }
758
759   ARC_DEBUG (" Input_section:\n");
760   if (reloc_data.input_section != NULL)
761     {
762       ARC_DEBUG ("  section name = %s, output_offset 0x%08x, output_section->vma = 0x%08x\n",
763                  reloc_data.input_section->name,
764                  (unsigned int) reloc_data.input_section->output_offset,
765                  (unsigned int) reloc_data.input_section->output_section->vma);
766       ARC_DEBUG ("  changed_address = 0x%08x\n",
767                  (unsigned int) (reloc_data.input_section->output_section->vma
768                                  + reloc_data.input_section->output_offset
769                                  + reloc_data.reloc_offset));
770       ARC_DEBUG ("  file: %s\n", reloc_data.input_section->owner->filename);
771     }
772   else
773     {
774       ARC_DEBUG ("      input section is NULL\n");
775     }
776 }
777 #else
778 #define DEBUG_ARC_RELOC(A)
779 #endif /* ARC_ENABLE_DEBUG */
780
781 static bfd_vma
782 middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
783 {
784   if (do_it)
785     {
786       insn
787         = ((insn & 0xffff0000) >> 16)
788           | ((insn & 0xffff) << 16);
789     }
790   return insn;
791 }
792
793 /* This function is called for relocations that are otherwise marked as NOT
794    requiring overflow checks.  In here we perform non-standard checks of
795    the relocation value.  */
796
797 static inline bfd_reloc_status_type
798 arc_special_overflow_checks (const struct arc_relocation_data reloc_data,
799                              bfd_signed_vma relocation,
800                              struct bfd_link_info *info ATTRIBUTE_UNUSED)
801 {
802   switch (reloc_data.howto->type)
803     {
804     case R_ARC_NPS_CMEM16:
805       if (((relocation >> 16) & 0xffff) != NPS_CMEM_HIGH_VALUE)
806         {
807           if (reloc_data.reloc_addend == 0)
808             _bfd_error_handler
809               /* xgettext:c-format */
810               (_("%B(%A+0x%lx): CMEM relocation to `%s' is invalid, "
811                  "16 MSB should be 0x%04x (value is 0x%lx)"),
812                reloc_data.input_section->owner,
813                reloc_data.input_section,
814                reloc_data.reloc_offset,
815                reloc_data.symbol_name,
816                NPS_CMEM_HIGH_VALUE,
817                (relocation));
818           else
819             _bfd_error_handler
820               /* xgettext:c-format */
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           /* xgettext:c-format */
1534           msg = _("%B(%A): warning: unaligned access to symbol '%s' in the small data area");
1535           break;
1536
1537         case bfd_reloc_outofrange:
1538           /* xgettext:c-format */
1539           msg = _("%B(%A): internal error: out of range error");
1540           break;
1541
1542         case bfd_reloc_notsupported:
1543           /* xgettext:c-format */
1544           msg = _("%B(%A): internal error: unsupported relocation error");
1545           break;
1546
1547         case bfd_reloc_dangerous:
1548           /* xgettext:c-format */
1549           msg = _("%B(%A): internal error: dangerous relocation");
1550           break;
1551
1552         default:
1553           /* xgettext:c-format */
1554           msg = _("%B(%A): internal error: unknown error");
1555           break;
1556         }
1557
1558       if (msg)
1559         _bfd_error_handler (msg, input_bfd, input_section, reloc_data.symbol_name);
1560       return FALSE;
1561     }
1562
1563   return TRUE;
1564 }
1565
1566 #define elf_arc_hash_table(p) \
1567     (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
1568   == ARC_ELF_DATA ? ((struct elf_arc_link_hash_table *) ((p)->hash)) : NULL)
1569
1570 /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
1571    .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
1572    hash table.  */
1573
1574 static bfd_boolean
1575 arc_elf_create_dynamic_sections (bfd *dynobj,
1576                                     struct bfd_link_info *info)
1577 {
1578   struct elf_arc_link_hash_table *htab;
1579
1580   if (!_bfd_elf_create_dynamic_sections (dynobj, info))
1581     return FALSE;
1582
1583   htab = elf_arc_hash_table (info);
1584   if (htab == NULL)
1585     return FALSE;
1586
1587   if (bfd_link_executable (info))
1588     {
1589       /* Always allow copy relocs for building executables.  */
1590       asection *s = bfd_get_linker_section (dynobj, ".rela.bss");
1591       if (s == NULL)
1592         {
1593           const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
1594           s = bfd_make_section_anyway_with_flags (dynobj,
1595                                                   ".rela.bss",
1596                                                   (bed->dynamic_sec_flags
1597                                                    | SEC_READONLY));
1598           if (s == NULL
1599               || ! bfd_set_section_alignment (dynobj, s,
1600                                               bed->s->log_file_align))
1601             return FALSE;
1602         }
1603       htab->srelbss = s;
1604     }
1605
1606   return TRUE;
1607 }
1608
1609 static struct dynamic_sections
1610 arc_create_dynamic_sections (bfd * abfd, struct bfd_link_info *info)
1611 {
1612   struct elf_link_hash_table *htab;
1613   bfd    *dynobj;
1614   struct dynamic_sections ds =
1615     {
1616       .initialized = FALSE,
1617       .sgot = NULL,
1618       .srelgot = NULL,
1619       .sgotplt = NULL,
1620       .srelgotplt = NULL,
1621       .sdyn = NULL,
1622       .splt = NULL,
1623       .srelplt = NULL
1624     };
1625
1626   htab = elf_hash_table (info);
1627   BFD_ASSERT (htab);
1628
1629   /* Create dynamic sections for relocatable executables so that we
1630      can copy relocations.  */
1631   if (! htab->dynamic_sections_created && bfd_link_pic (info))
1632     {
1633       if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
1634         BFD_ASSERT (0);
1635     }
1636
1637   dynobj = (elf_hash_table (info))->dynobj;
1638
1639   if (dynobj)
1640     {
1641       ds.sgot = htab->sgot;
1642       ds.srelgot = htab->srelgot;
1643
1644       ds.sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
1645       ds.srelgotplt = ds.srelplt;
1646
1647       ds.splt = bfd_get_section_by_name (dynobj, ".plt");
1648       ds.srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
1649     }
1650
1651   if (htab->dynamic_sections_created)
1652     {
1653       ds.sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
1654     }
1655
1656   ds.initialized = TRUE;
1657
1658   return ds;
1659 }
1660
1661 static bfd_boolean
1662 elf_arc_check_relocs (bfd *                      abfd,
1663                       struct bfd_link_info *     info,
1664                       asection *                 sec,
1665                       const Elf_Internal_Rela *  relocs)
1666 {
1667   Elf_Internal_Shdr *           symtab_hdr;
1668   struct elf_link_hash_entry ** sym_hashes;
1669   const Elf_Internal_Rela *     rel;
1670   const Elf_Internal_Rela *     rel_end;
1671   bfd *                         dynobj;
1672   asection *                    sreloc = NULL;
1673
1674   if (bfd_link_relocatable (info))
1675     return TRUE;
1676
1677   dynobj = (elf_hash_table (info))->dynobj;
1678   symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1679   sym_hashes = elf_sym_hashes (abfd);
1680
1681   rel_end = relocs + sec->reloc_count;
1682   for (rel = relocs; rel < rel_end; rel++)
1683     {
1684       enum elf_arc_reloc_type r_type;
1685       reloc_howto_type *howto;
1686       unsigned long   r_symndx;
1687       struct elf_link_hash_entry *h;
1688
1689       r_type = ELF32_R_TYPE (rel->r_info);
1690
1691       if (r_type >= (int) R_ARC_max)
1692         {
1693           bfd_set_error (bfd_error_bad_value);
1694           return FALSE;
1695         }
1696       howto = arc_elf_howto (r_type);
1697
1698       if (dynobj == NULL
1699           && (is_reloc_for_GOT (howto) == TRUE
1700               || is_reloc_for_TLS (howto) == TRUE))
1701         {
1702           dynobj = elf_hash_table (info)->dynobj = abfd;
1703           if (! _bfd_elf_create_got_section (abfd, info))
1704             return FALSE;
1705         }
1706
1707       /* Load symbol information.  */
1708       r_symndx = ELF32_R_SYM (rel->r_info);
1709       if (r_symndx < symtab_hdr->sh_info) /* Is a local symbol.  */
1710         h = NULL;
1711       else /* Global one.  */
1712         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1713
1714       switch (r_type)
1715         {
1716           case R_ARC_32:
1717           case R_ARC_32_ME:
1718             /* During shared library creation, these relocs should not
1719                appear in a shared library (as memory will be read only
1720                and the dynamic linker can not resolve these.  However
1721                the error should not occur for e.g. debugging or
1722                non-readonly sections.  */
1723             if ((bfd_link_dll (info) && !bfd_link_pie (info))
1724                 && (sec->flags & SEC_ALLOC) != 0
1725                 && (sec->flags & SEC_READONLY) != 0
1726                 && ((sec->flags & SEC_CODE) != 0
1727                     || (sec->flags & SEC_DEBUGGING) != 0))
1728               {
1729                 const char *name;
1730                 if (h)
1731                   name = h->root.root.string;
1732                 else
1733                   /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);  */
1734                   name = "UNKNOWN";
1735                 _bfd_error_handler
1736                   /* xgettext:c-format */
1737                   (_("\
1738 %B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
1739                     abfd,
1740                     arc_elf_howto (r_type)->name,
1741                     name);
1742                 bfd_set_error (bfd_error_bad_value);
1743                 return FALSE;
1744               }
1745
1746             /* In some cases we are not setting the 'non_got_ref'
1747                flag, even though the relocations don't require a GOT
1748                access.  We should extend the testing in this area to
1749                ensure that no significant cases are being missed.  */
1750             if (h)
1751               h->non_got_ref = 1;
1752             /* FALLTHROUGH */
1753           case R_ARC_PC32:
1754           case R_ARC_32_PCREL:
1755             if ((bfd_link_pic (info))
1756                 && ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1757                     || (h != NULL
1758                         && (!info->symbolic || !h->def_regular))))
1759               {
1760                 if (sreloc == NULL)
1761                   {
1762                     sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
1763                                                                   2, abfd,
1764                                                                   /*rela*/
1765                                                                   TRUE);
1766
1767                     if (sreloc == NULL)
1768                       return FALSE;
1769                   }
1770                 sreloc->size += sizeof (Elf32_External_Rela);
1771
1772               }
1773           default:
1774             break;
1775         }
1776
1777       if (is_reloc_for_PLT (howto) == TRUE)
1778         {
1779           if (h == NULL)
1780             continue;
1781           else
1782             h->needs_plt = 1;
1783         }
1784
1785       /* Add info to the symbol got_entry_list.  */
1786       if (is_reloc_for_GOT (howto) == TRUE
1787           || is_reloc_for_TLS (howto) == TRUE)
1788         {
1789           arc_fill_got_info_for_reloc (
1790                   arc_got_entry_type_for_reloc (howto),
1791                   get_got_entry_list_for_symbol (abfd, r_symndx, h),
1792                   info,
1793                   h);
1794         }
1795     }
1796
1797   return TRUE;
1798 }
1799
1800 #define ELF_DYNAMIC_INTERPRETER  "/sbin/ld-uClibc.so"
1801
1802 static struct plt_version_t *
1803 arc_get_plt_version (struct bfd_link_info *info)
1804 {
1805   int i;
1806
1807   for (i = 0; i < 1; i++)
1808     {
1809       ARC_DEBUG ("%d: size1 = %d, size2 = %d\n", i,
1810                  (int) plt_versions[i].entry_size,
1811                  (int) plt_versions[i].elem_size);
1812     }
1813
1814   if (bfd_get_mach (info->output_bfd) == bfd_mach_arc_arcv2)
1815     {
1816       if (bfd_link_pic (info))
1817         return &(plt_versions[ELF_ARCV2_PIC]);
1818       else
1819         return &(plt_versions[ELF_ARCV2_ABS]);
1820     }
1821   else
1822     {
1823       if (bfd_link_pic (info))
1824         return &(plt_versions[ELF_ARC_PIC]);
1825       else
1826         return &(plt_versions[ELF_ARC_ABS]);
1827     }
1828 }
1829
1830 static bfd_vma
1831 add_symbol_to_plt (struct bfd_link_info *info)
1832 {
1833   struct elf_link_hash_table *htab = elf_hash_table (info);
1834   bfd_vma ret;
1835
1836   struct plt_version_t *plt_data = arc_get_plt_version (info);
1837
1838   /* If this is the first .plt entry, make room for the special first
1839      entry.  */
1840   if (htab->splt->size == 0)
1841     htab->splt->size += plt_data->entry_size;
1842
1843   ret = htab->splt->size;
1844
1845   htab->splt->size += plt_data->elem_size;
1846   ARC_DEBUG ("PLT_SIZE = %d\n", (int) htab->splt->size);
1847
1848   htab->sgotplt->size += 4;
1849   htab->srelplt->size += sizeof (Elf32_External_Rela);
1850
1851   return ret;
1852 }
1853
1854 #define PLT_DO_RELOCS_FOR_ENTRY(ABFD, DS, RELOCS)       \
1855   plt_do_relocs_for_symbol (ABFD, DS, RELOCS, 0, 0)
1856
1857 static void
1858 plt_do_relocs_for_symbol (bfd *abfd,
1859                           struct elf_link_hash_table *htab,
1860                           const struct plt_reloc *reloc,
1861                           bfd_vma plt_offset,
1862                           bfd_vma symbol_got_offset)
1863 {
1864   while (SYM_ONLY (reloc->symbol) != LAST_RELOC)
1865     {
1866       bfd_vma relocation = 0;
1867
1868       switch (SYM_ONLY (reloc->symbol))
1869         {
1870           case SGOT:
1871                 relocation
1872                   = htab->sgotplt->output_section->vma
1873                     + htab->sgotplt->output_offset + symbol_got_offset;
1874                 break;
1875         }
1876       relocation += reloc->addend;
1877
1878       if (IS_RELATIVE (reloc->symbol))
1879         {
1880           bfd_vma reloc_offset = reloc->offset;
1881           reloc_offset -= (IS_INSN_32 (reloc->symbol)) ? 4 : 0;
1882           reloc_offset -= (IS_INSN_24 (reloc->symbol)) ? 2 : 0;
1883
1884           relocation -= htab->splt->output_section->vma
1885                          + htab->splt->output_offset
1886                          + plt_offset + reloc_offset;
1887         }
1888
1889       /* TODO: being ME is not a property of the relocation but of the
1890          section of which is applying the relocation. */
1891       if (IS_MIDDLE_ENDIAN (reloc->symbol) && !bfd_big_endian (abfd))
1892         {
1893           relocation
1894             = ((relocation & 0xffff0000) >> 16)
1895               | ((relocation & 0xffff) << 16);
1896         }
1897
1898       switch (reloc->size)
1899         {
1900           case 32:
1901             bfd_put_32 (htab->splt->output_section->owner,
1902                         relocation,
1903                         htab->splt->contents + plt_offset + reloc->offset);
1904             break;
1905         }
1906
1907       reloc = &(reloc[1]); /* Jump to next relocation.  */
1908     }
1909 }
1910
1911 static void
1912 relocate_plt_for_symbol (bfd *output_bfd,
1913                          struct bfd_link_info *info,
1914                          struct elf_link_hash_entry *h)
1915 {
1916   struct plt_version_t *plt_data = arc_get_plt_version (info);
1917   struct elf_link_hash_table *htab = elf_hash_table (info);
1918
1919   bfd_vma plt_index = (h->plt.offset  - plt_data->entry_size)
1920                       / plt_data->elem_size;
1921   bfd_vma got_offset = (plt_index + 3) * 4;
1922
1923   ARC_DEBUG ("arc_info: PLT_OFFSET = %#lx, PLT_ENTRY_VMA = %#lx, \
1924 GOT_ENTRY_OFFSET = %#lx, GOT_ENTRY_VMA = %#lx, for symbol %s\n",
1925              (long) h->plt.offset,
1926              (long) (htab->splt->output_section->vma
1927                      + htab->splt->output_offset
1928                      + h->plt.offset),
1929              (long) got_offset,
1930              (long) (htab->sgotplt->output_section->vma
1931                      + htab->sgotplt->output_offset
1932                      + got_offset),
1933              h->root.root.string);
1934
1935   {
1936     bfd_vma i = 0;
1937     uint16_t *ptr = (uint16_t *) plt_data->elem;
1938
1939     for (i = 0; i < plt_data->elem_size/2; i++)
1940       {
1941         uint16_t data = ptr[i];
1942         bfd_put_16 (output_bfd,
1943                     (bfd_vma) data,
1944                     htab->splt->contents + h->plt.offset + (i*2));
1945       }
1946   }
1947
1948   plt_do_relocs_for_symbol (output_bfd, htab,
1949                             plt_data->elem_relocs,
1950                             h->plt.offset,
1951                             got_offset);
1952
1953   /* Fill in the entry in the global offset table.  */
1954   bfd_put_32 (output_bfd,
1955               (bfd_vma) (htab->splt->output_section->vma
1956                          + htab->splt->output_offset),
1957               htab->sgotplt->contents + got_offset);
1958
1959   /* TODO: Fill in the entry in the .rela.plt section.  */
1960   {
1961     Elf_Internal_Rela rel;
1962     bfd_byte *loc;
1963
1964     rel.r_offset = (htab->sgotplt->output_section->vma
1965                     + htab->sgotplt->output_offset
1966                     + got_offset);
1967     rel.r_addend = 0;
1968
1969     BFD_ASSERT (h->dynindx != -1);
1970     rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_JMP_SLOT);
1971
1972     loc = htab->srelplt->contents;
1973     loc += plt_index * sizeof (Elf32_External_Rela); /* relA */
1974     bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
1975   }
1976 }
1977
1978 static void
1979 relocate_plt_for_entry (bfd *abfd,
1980                         struct bfd_link_info *info)
1981 {
1982   struct plt_version_t *plt_data = arc_get_plt_version (info);
1983   struct elf_link_hash_table *htab = elf_hash_table (info);
1984
1985   {
1986     bfd_vma i = 0;
1987     uint16_t *ptr = (uint16_t *) plt_data->entry;
1988     for (i = 0; i < plt_data->entry_size/2; i++)
1989       {
1990         uint16_t data = ptr[i];
1991         bfd_put_16 (abfd,
1992                     (bfd_vma) data,
1993                     htab->splt->contents + (i*2));
1994       }
1995   }
1996   PLT_DO_RELOCS_FOR_ENTRY (abfd, htab, plt_data->entry_relocs);
1997 }
1998
1999 /* Desc : Adjust a symbol defined by a dynamic object and referenced
2000    by a regular object.  The current definition is in some section of
2001    the dynamic object, but we're not including those sections.  We
2002    have to change the definition to something the rest of the link can
2003    understand.  */
2004
2005 static bfd_boolean
2006 elf_arc_adjust_dynamic_symbol (struct bfd_link_info *info,
2007                               struct elf_link_hash_entry *h)
2008 {
2009   asection *s;
2010   bfd *dynobj = (elf_hash_table (info))->dynobj;
2011   struct elf_link_hash_table *htab = elf_hash_table (info);
2012
2013   if (h->type == STT_FUNC
2014       || h->type == STT_GNU_IFUNC
2015       || h->needs_plt == 1)
2016     {
2017       if (!bfd_link_pic (info) && !h->def_dynamic && !h->ref_dynamic)
2018         {
2019           /* This case can occur if we saw a PLT32 reloc in an input
2020              file, but the symbol was never referred to by a dynamic
2021              object.  In such a case, we don't actually need to build
2022              a procedure linkage table, and we can just do a PC32
2023              reloc instead.  */
2024           BFD_ASSERT (h->needs_plt);
2025           return TRUE;
2026         }
2027
2028       /* Make sure this symbol is output as a dynamic symbol.  */
2029       if (h->dynindx == -1 && !h->forced_local
2030           && !bfd_elf_link_record_dynamic_symbol (info, h))
2031         return FALSE;
2032
2033       if (bfd_link_pic (info)
2034           || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
2035         {
2036           bfd_vma loc = add_symbol_to_plt (info);
2037
2038           if (bfd_link_executable (info) && !h->def_regular)
2039             {
2040               h->root.u.def.section = htab->splt;
2041               h->root.u.def.value = loc;
2042             }
2043           h->plt.offset = loc;
2044         }
2045       else
2046         {
2047           h->plt.offset = (bfd_vma) -1;
2048           h->needs_plt = 0;
2049         }
2050       return TRUE;
2051     }
2052
2053   /* If this is a weak symbol, and there is a real definition, the
2054      processor independent code will have arranged for us to see the
2055      real definition first, and we can just use the same value.  */
2056   if (h->u.weakdef != NULL)
2057     {
2058       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2059                   || h->u.weakdef->root.type == bfd_link_hash_defweak);
2060       h->root.u.def.section = h->u.weakdef->root.u.def.section;
2061       h->root.u.def.value = h->u.weakdef->root.u.def.value;
2062       return TRUE;
2063     }
2064
2065   /* This is a reference to a symbol defined by a dynamic object which
2066      is not a function.  */
2067
2068   /* If we are creating a shared library, we must presume that the
2069      only references to the symbol are via the global offset table.
2070      For such cases we need not do anything here; the relocations will
2071      be handled correctly by relocate_section.  */
2072   if (!bfd_link_executable (info))
2073     return TRUE;
2074
2075   /* If there are no non-GOT references, we do not need a copy
2076      relocation.  */
2077   if (!h->non_got_ref)
2078     return TRUE;
2079
2080   /* If -z nocopyreloc was given, we won't generate them either.  */
2081   if (info->nocopyreloc)
2082     {
2083       h->non_got_ref = 0;
2084       return TRUE;
2085     }
2086
2087   /* We must allocate the symbol in our .dynbss section, which will
2088      become part of the .bss section of the executable.  There will be
2089      an entry for this symbol in the .dynsym section.  The dynamic
2090      object will contain position independent code, so all references
2091      from the dynamic object to this symbol will go through the global
2092      offset table.  The dynamic linker will use the .dynsym entry to
2093      determine the address it must put in the global offset table, so
2094      both the dynamic object and the regular object will refer to the
2095      same memory location for the variable.  */
2096
2097   if (htab == NULL)
2098     return FALSE;
2099
2100   /* We must generate a R_ARC_COPY reloc to tell the dynamic linker to
2101      copy the initial value out of the dynamic object and into the
2102      runtime process image.  We need to remember the offset into the
2103      .rela.bss section we are going to use.  */
2104   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2105     {
2106       struct elf_arc_link_hash_table *arc_htab = elf_arc_hash_table (info);
2107
2108       BFD_ASSERT (arc_htab->srelbss != NULL);
2109       arc_htab->srelbss->size += sizeof (Elf32_External_Rela);
2110       h->needs_copy = 1;
2111     }
2112
2113   /* TODO: Move this also to arc_hash_table.  */
2114   s = bfd_get_section_by_name (dynobj, ".dynbss");
2115   BFD_ASSERT (s != NULL);
2116
2117   return _bfd_elf_adjust_dynamic_copy (info, h, s);
2118 }
2119
2120 /* Function :  elf_arc_finish_dynamic_symbol
2121    Brief    :  Finish up dynamic symbol handling.  We set the
2122              contents of various dynamic sections here.
2123    Args     :  output_bfd :
2124                info       :
2125                h          :
2126                sym        :
2127    Returns  : True/False as the return status.  */
2128
2129 static bfd_boolean
2130 elf_arc_finish_dynamic_symbol (bfd * output_bfd,
2131                                struct bfd_link_info *info,
2132                                struct elf_link_hash_entry *h,
2133                                Elf_Internal_Sym * sym)
2134 {
2135   if (h->plt.offset != (bfd_vma) -1)
2136     {
2137       relocate_plt_for_symbol (output_bfd, info, h);
2138
2139       if (!h->def_regular)
2140         {
2141           /* Mark the symbol as undefined, rather than as defined in
2142              the .plt section.  Leave the value alone.  */
2143           sym->st_shndx = SHN_UNDEF;
2144         }
2145     }
2146
2147
2148   /* This function traverses list of GOT entries and
2149      create respective dynamic relocs.  */
2150   /* TODO: Make function to get list and not access the list directly.  */
2151   /* TODO: Move function to relocate_section create this relocs eagerly.  */
2152   create_got_dynrelocs_for_got_info (&h->got.glist,
2153                                      output_bfd,
2154                                      info,
2155                                      h);
2156
2157   if (h->needs_copy)
2158     {
2159       struct elf_arc_link_hash_table *arc_htab = elf_arc_hash_table (info);
2160
2161       if (h->dynindx == -1
2162           || (h->root.type != bfd_link_hash_defined
2163               && h->root.type != bfd_link_hash_defweak)
2164           || arc_htab->srelbss == NULL)
2165         abort ();
2166
2167       bfd_vma rel_offset = (h->root.u.def.value
2168                             + h->root.u.def.section->output_section->vma
2169                             + h->root.u.def.section->output_offset);
2170
2171       bfd_byte * loc = arc_htab->srelbss->contents
2172         + (arc_htab->srelbss->reloc_count * sizeof (Elf32_External_Rela));
2173       arc_htab->srelbss->reloc_count++;
2174
2175       Elf_Internal_Rela rel;
2176       rel.r_addend = 0;
2177       rel.r_offset = rel_offset;
2178
2179       BFD_ASSERT (h->dynindx != -1);
2180       rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_COPY);
2181
2182       bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2183     }
2184
2185   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
2186   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2187       || strcmp (h->root.root.string, "__DYNAMIC") == 0
2188       || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
2189     sym->st_shndx = SHN_ABS;
2190
2191   return TRUE;
2192 }
2193
2194 #define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION)             \
2195   case TAG:                                                     \
2196   if (SYMBOL != NULL)                                           \
2197     h = elf_link_hash_lookup (elf_hash_table (info),            \
2198                               SYMBOL, FALSE, FALSE, TRUE);      \
2199   else if (SECTION != NULL)                                     \
2200     s = bfd_get_linker_section (dynobj, SECTION);               \
2201   break;
2202
2203 /* Function :  elf_arc_finish_dynamic_sections
2204    Brief    :  Finish up the dynamic sections handling.
2205    Args     :  output_bfd :
2206                info       :
2207                h          :
2208                sym        :
2209    Returns  : True/False as the return status.  */
2210
2211 static bfd_boolean
2212 elf_arc_finish_dynamic_sections (bfd * output_bfd,
2213                                  struct bfd_link_info *info)
2214 {
2215   struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
2216   struct elf_link_hash_table *htab = elf_hash_table (info);
2217   bfd *dynobj = (elf_hash_table (info))->dynobj;
2218
2219   if (ds.sdyn)
2220     {
2221       Elf32_External_Dyn *dyncon, *dynconend;
2222
2223       dyncon = (Elf32_External_Dyn *) ds.sdyn->contents;
2224       dynconend
2225         = (Elf32_External_Dyn *) (ds.sdyn->contents + ds.sdyn->size);
2226       for (; dyncon < dynconend; dyncon++)
2227         {
2228           Elf_Internal_Dyn internal_dyn;
2229           bfd_boolean     do_it = FALSE;
2230
2231           struct elf_link_hash_entry *h = NULL;
2232           asection       *s = NULL;
2233
2234           bfd_elf32_swap_dyn_in (dynobj, dyncon, &internal_dyn);
2235
2236           switch (internal_dyn.d_tag)
2237             {
2238               GET_SYMBOL_OR_SECTION (DT_INIT, info->init_function, NULL)
2239               GET_SYMBOL_OR_SECTION (DT_FINI, info->fini_function, NULL)
2240               GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt")
2241               GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt")
2242               GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt")
2243               GET_SYMBOL_OR_SECTION (DT_VERSYM, NULL, ".gnu.version")
2244               GET_SYMBOL_OR_SECTION (DT_VERDEF, NULL, ".gnu.version_d")
2245               GET_SYMBOL_OR_SECTION (DT_VERNEED, NULL, ".gnu.version_r")
2246               default:
2247                 break;
2248             }
2249
2250           /* In case the dynamic symbols should be updated with a symbol.  */
2251           if (h != NULL
2252               && (h->root.type == bfd_link_hash_defined
2253                   || h->root.type == bfd_link_hash_defweak))
2254             {
2255               asection       *asec_ptr;
2256
2257               internal_dyn.d_un.d_val = h->root.u.def.value;
2258               asec_ptr = h->root.u.def.section;
2259               if (asec_ptr->output_section != NULL)
2260                 {
2261                   internal_dyn.d_un.d_val +=
2262                     (asec_ptr->output_section->vma
2263                      + asec_ptr->output_offset);
2264                 }
2265               else
2266                 {
2267                   /* The symbol is imported from another shared
2268                      library and does not apply to this one.  */
2269                   internal_dyn.d_un.d_val = 0;
2270                 }
2271               do_it = TRUE;
2272             }
2273           else if (s != NULL) /* With a section information.  */
2274             {
2275               switch (internal_dyn.d_tag)
2276                 {
2277                   case DT_PLTGOT:
2278                   case DT_JMPREL:
2279                   case DT_VERSYM:
2280                   case DT_VERDEF:
2281                   case DT_VERNEED:
2282                     internal_dyn.d_un.d_ptr = (s->output_section->vma
2283                                                + s->output_offset);
2284                     do_it = TRUE;
2285                     break;
2286
2287                   case DT_PLTRELSZ:
2288                     internal_dyn.d_un.d_val = s->size;
2289                     do_it = TRUE;
2290                     break;
2291
2292                   default:
2293                     break;
2294                 }
2295             }
2296
2297           if (do_it)
2298             bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon);
2299         }
2300
2301       if (htab->splt->size > 0)
2302         {
2303           relocate_plt_for_entry (output_bfd, info);
2304         }
2305
2306       /* TODO: Validate this.  */
2307       elf_section_data (htab->srelplt->output_section)->this_hdr.sh_entsize
2308         = 0xc;
2309     }
2310
2311   /* Fill in the first three entries in the global offset table.  */
2312   if (htab->sgot)
2313     {
2314       struct elf_link_hash_entry *h;
2315       h = elf_link_hash_lookup (elf_hash_table (info), "_GLOBAL_OFFSET_TABLE_",
2316                                  FALSE, FALSE, TRUE);
2317
2318         if (h != NULL && h->root.type != bfd_link_hash_undefined
2319             && h->root.u.def.section != NULL)
2320         {
2321           asection *sec = h->root.u.def.section;
2322
2323           if (ds.sdyn == NULL)
2324             bfd_put_32 (output_bfd, (bfd_vma) 0,
2325                         sec->contents);
2326           else
2327             bfd_put_32 (output_bfd,
2328                         ds.sdyn->output_section->vma + ds.sdyn->output_offset,
2329                         sec->contents);
2330           bfd_put_32 (output_bfd, (bfd_vma) 0, sec->contents + 4);
2331           bfd_put_32 (output_bfd, (bfd_vma) 0, sec->contents + 8);
2332         }
2333     }
2334
2335   return TRUE;
2336 }
2337
2338 #define ADD_DYNAMIC_SYMBOL(NAME, TAG)                                   \
2339   h =  elf_link_hash_lookup (elf_hash_table (info),                     \
2340                              NAME, FALSE, FALSE, FALSE);                \
2341   if ((h != NULL && (h->ref_regular || h->def_regular)))                \
2342     if (! _bfd_elf_add_dynamic_entry (info, TAG, 0))                    \
2343       return FALSE;
2344
2345 /* Set the sizes of the dynamic sections.  */
2346 static bfd_boolean
2347 elf_arc_size_dynamic_sections (bfd * output_bfd,
2348                                struct bfd_link_info *info)
2349 {
2350   bfd *    dynobj;
2351   asection *      s;
2352   bfd_boolean     relocs_exist = FALSE;
2353   bfd_boolean     reltext_exist = FALSE;
2354   struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
2355   struct elf_link_hash_table *htab = elf_hash_table (info);
2356
2357   dynobj = (elf_hash_table (info))->dynobj;
2358   BFD_ASSERT (dynobj != NULL);
2359
2360   if ((elf_hash_table (info))->dynamic_sections_created)
2361     {
2362       struct elf_link_hash_entry *h;
2363
2364       /* Set the contents of the .interp section to the
2365          interpreter.  */
2366       if (!bfd_link_pic (info))
2367         {
2368           s = bfd_get_section_by_name (dynobj, ".interp");
2369           BFD_ASSERT (s != NULL);
2370           s->size = sizeof (ELF_DYNAMIC_INTERPRETER);
2371           s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2372         }
2373
2374       /* Add some entries to the .dynamic section.  We fill in some of
2375          the values later, in elf_bfd_final_link, but we must add the
2376          entries now so that we know the final size of the .dynamic
2377          section.  Checking if the .init section is present.  We also
2378          create DT_INIT and DT_FINI entries if the init_str has been
2379          changed by the user.  */
2380       ADD_DYNAMIC_SYMBOL (info->init_function, DT_INIT);
2381       ADD_DYNAMIC_SYMBOL (info->fini_function, DT_FINI);
2382     }
2383   else
2384     {
2385       /* We may have created entries in the .rela.got section.
2386          However, if we are not creating the dynamic sections, we will
2387          not actually use these entries.  Reset the size of .rela.got,
2388          which will cause it to get stripped from the output file
2389          below.  */
2390       if (htab->srelgot != NULL)
2391         htab->srelgot->size = 0;
2392     }
2393
2394   if (htab->splt != NULL && htab->splt->size == 0)
2395     htab->splt->flags |= SEC_EXCLUDE;
2396   for (s = dynobj->sections; s != NULL; s = s->next)
2397     {
2398       if ((s->flags & SEC_LINKER_CREATED) == 0)
2399         continue;
2400
2401       if (strncmp (s->name, ".rela", 5) == 0)
2402         {
2403           if (s->size == 0)
2404             {
2405               s->flags |= SEC_EXCLUDE;
2406             }
2407           else
2408             {
2409               if (strcmp (s->name, ".rela.plt") != 0)
2410                 {
2411                   const char *outname =
2412                     bfd_get_section_name (output_bfd,
2413                                           htab->srelplt->output_section);
2414
2415                   asection *target = bfd_get_section_by_name (output_bfd,
2416                                                               outname + 4);
2417
2418                   relocs_exist = TRUE;
2419                   if (target != NULL && target->size != 0
2420                       && (target->flags & SEC_READONLY) != 0
2421                       && (target->flags & SEC_ALLOC) != 0)
2422                     reltext_exist = TRUE;
2423                 }
2424             }
2425
2426           /* We use the reloc_count field as a counter if we need to
2427              copy relocs into the output file.  */
2428           s->reloc_count = 0;
2429         }
2430
2431       if (strcmp (s->name, ".dynamic") == 0)
2432         continue;
2433
2434       if (s->size != 0)
2435         s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2436
2437       if (s->contents == NULL && s->size != 0)
2438         return FALSE;
2439     }
2440
2441   if (ds.sdyn)
2442     {
2443       /* TODO: Check if this is needed.  */
2444       if (!bfd_link_pic (info))
2445         if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
2446                 return FALSE;
2447
2448       if (htab->splt && (htab->splt->flags & SEC_EXCLUDE) == 0)
2449         if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
2450             || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2451             || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2452             || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0)
2453            )
2454           return FALSE;
2455
2456       if (relocs_exist == TRUE)
2457         if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
2458             || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
2459             || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
2460                                             sizeof (Elf32_External_Rela))
2461            )
2462           return FALSE;
2463
2464       if (reltext_exist == TRUE)
2465         if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
2466           return FALSE;
2467     }
2468
2469   return TRUE;
2470 }
2471
2472
2473 /* Classify dynamic relocs such that -z combreloc can reorder and combine
2474    them.  */
2475 static enum elf_reloc_type_class
2476 elf32_arc_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
2477                             const asection *rel_sec ATTRIBUTE_UNUSED,
2478                             const Elf_Internal_Rela *rela)
2479 {
2480   switch ((int) ELF32_R_TYPE (rela->r_info))
2481     {
2482     case R_ARC_RELATIVE:
2483       return reloc_class_relative;
2484     case R_ARC_JMP_SLOT:
2485       return reloc_class_plt;
2486     case R_ARC_COPY:
2487       return reloc_class_copy;
2488     /* TODO: Needed in future to support ifunc.  */
2489     /*
2490     case R_ARC_IRELATIVE:
2491       return reloc_class_ifunc;
2492     */
2493     default:
2494       return reloc_class_normal;
2495     }
2496 }
2497
2498 const struct elf_size_info arc_elf32_size_info =
2499 {
2500   sizeof (Elf32_External_Ehdr),
2501   sizeof (Elf32_External_Phdr),
2502   sizeof (Elf32_External_Shdr),
2503   sizeof (Elf32_External_Rel),
2504   sizeof (Elf32_External_Rela),
2505   sizeof (Elf32_External_Sym),
2506   sizeof (Elf32_External_Dyn),
2507   sizeof (Elf_External_Note),
2508   4,
2509   1,
2510   32, 2,
2511   ELFCLASS32, EV_CURRENT,
2512   bfd_elf32_write_out_phdrs,
2513   bfd_elf32_write_shdrs_and_ehdr,
2514   bfd_elf32_checksum_contents,
2515   bfd_elf32_write_relocs,
2516   bfd_elf32_swap_symbol_in,
2517   bfd_elf32_swap_symbol_out,
2518   bfd_elf32_slurp_reloc_table,
2519   bfd_elf32_slurp_symbol_table,
2520   bfd_elf32_swap_dyn_in,
2521   bfd_elf32_swap_dyn_out,
2522   bfd_elf32_swap_reloc_in,
2523   bfd_elf32_swap_reloc_out,
2524   bfd_elf32_swap_reloca_in,
2525   bfd_elf32_swap_reloca_out
2526 };
2527
2528 #define elf_backend_size_info           arc_elf32_size_info
2529
2530 /* Hook called by the linker routine which adds symbols from an object
2531    file.  */
2532
2533 static bfd_boolean
2534 elf_arc_add_symbol_hook (bfd * abfd,
2535                          struct bfd_link_info * info,
2536                          Elf_Internal_Sym * sym,
2537                          const char ** namep ATTRIBUTE_UNUSED,
2538                          flagword * flagsp ATTRIBUTE_UNUSED,
2539                          asection ** secp ATTRIBUTE_UNUSED,
2540                          bfd_vma * valp ATTRIBUTE_UNUSED)
2541 {
2542   if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
2543       && (abfd->flags & DYNAMIC) == 0
2544       && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
2545     elf_tdata (info->output_bfd)->has_gnu_symbols |= elf_gnu_symbol_ifunc;
2546
2547   return TRUE;
2548 }
2549
2550 /* GDB expects general purpose registers to be in section .reg.  However Linux
2551    kernel doesn't create this section and instead writes registers to NOTE
2552    section.  It is up to the binutils to create a pseudo-section .reg from the
2553    contents of NOTE.  Also BFD will read pid and signal number from NOTE.  This
2554    function relies on offsets inside elf_prstatus structure in Linux to be
2555    stable.  */
2556
2557 static bfd_boolean
2558 elf32_arc_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
2559 {
2560   int offset;
2561   size_t size;
2562
2563   switch (note->descsz)
2564     {
2565     default:
2566       return FALSE;
2567
2568     case 236: /* sizeof (struct elf_prstatus) on Linux/arc.  */
2569       /* pr_cursig */
2570       elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
2571       /* pr_pid */
2572       elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
2573       /* pr_regs */
2574       offset = 72;
2575       size = (40 * 4); /* There are 40 registers in user_regs_struct.  */
2576       break;
2577     }
2578   /* Make a ".reg/999" section.  */
2579   return _bfd_elfcore_make_pseudosection (abfd, ".reg", size,
2580                                           note->descpos + offset);
2581 }
2582
2583 #define TARGET_LITTLE_SYM   arc_elf32_le_vec
2584 #define TARGET_LITTLE_NAME  "elf32-littlearc"
2585 #define TARGET_BIG_SYM      arc_elf32_be_vec
2586 #define TARGET_BIG_NAME     "elf32-bigarc"
2587 #define ELF_ARCH            bfd_arch_arc
2588 #define ELF_TARGET_ID       ARC_ELF_DATA
2589 #define ELF_MACHINE_CODE    EM_ARC_COMPACT
2590 #define ELF_MACHINE_ALT1    EM_ARC_COMPACT2
2591 #define ELF_MAXPAGESIZE     0x2000
2592
2593 #define bfd_elf32_bfd_link_hash_table_create    arc_elf_link_hash_table_create
2594
2595 #define bfd_elf32_bfd_merge_private_bfd_data    arc_elf_merge_private_bfd_data
2596 #define bfd_elf32_bfd_reloc_type_lookup         arc_elf32_bfd_reloc_type_lookup
2597 #define bfd_elf32_bfd_set_private_flags         arc_elf_set_private_flags
2598 #define bfd_elf32_bfd_print_private_bfd_data    arc_elf_print_private_bfd_data
2599 #define bfd_elf32_bfd_copy_private_bfd_data     arc_elf_copy_private_bfd_data
2600
2601 #define elf_info_to_howto_rel                arc_info_to_howto_rel
2602 #define elf_backend_object_p                 arc_elf_object_p
2603 #define elf_backend_final_write_processing   arc_elf_final_write_processing
2604
2605 #define elf_backend_relocate_section         elf_arc_relocate_section
2606 #define elf_backend_check_relocs             elf_arc_check_relocs
2607 #define elf_backend_create_dynamic_sections  arc_elf_create_dynamic_sections
2608
2609 #define elf_backend_reloc_type_class            elf32_arc_reloc_type_class
2610
2611 #define elf_backend_adjust_dynamic_symbol    elf_arc_adjust_dynamic_symbol
2612 #define elf_backend_finish_dynamic_symbol    elf_arc_finish_dynamic_symbol
2613
2614 #define elf_backend_finish_dynamic_sections  elf_arc_finish_dynamic_sections
2615 #define elf_backend_size_dynamic_sections    elf_arc_size_dynamic_sections
2616 #define elf_backend_add_symbol_hook          elf_arc_add_symbol_hook
2617
2618 #define elf_backend_can_gc_sections     1
2619 #define elf_backend_want_got_plt        1
2620 #define elf_backend_plt_readonly        1
2621 #define elf_backend_rela_plts_and_copies_p 1
2622 #define elf_backend_want_plt_sym        0
2623 #define elf_backend_got_header_size     12
2624 #define elf_backend_dtrel_excludes_plt  1
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"