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