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