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