Call enqueue_pending_signal in linux_resume_one_lwp_throw
[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_byte * _loc;                                                    \
59                                                                         \
60     _loc = _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, _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   if ((elf_elfheader (abfd)->e_flags & EF_ARC_MACH) == EF_ARC_CPU_GENERIC)
692     elf_elfheader (abfd)->e_flags |= val;
693
694   elf_elfheader (abfd)->e_machine = emf;
695
696   /* Record whatever is the current syscall ABI version.  */
697   elf_elfheader (abfd)->e_flags |= E_ARC_OSABI_CURRENT;
698 }
699
700 #define BFD_DEBUG_PIC(...)
701
702 struct arc_relocation_data
703 {
704   bfd_vma         reloc_offset;
705   bfd_vma         reloc_addend;
706   bfd_vma         got_offset_value;
707
708   bfd_vma         sym_value;
709   asection *      sym_section;
710
711   reloc_howto_type *howto;
712
713   asection *      input_section;
714
715   bfd_vma         sdata_begin_symbol_vma;
716   bfd_boolean     sdata_begin_symbol_vma_set;
717   bfd_vma         got_symbol_vma;
718
719   bfd_boolean     should_relocate;
720 };
721
722 static void
723 debug_arc_reloc (struct arc_relocation_data reloc_data)
724 {
725   PR_DEBUG ("Reloc type=%s, should_relocate = %s\n",
726            reloc_data.howto->name,
727            reloc_data.should_relocate ? "true" : "false");
728   PR_DEBUG ("  offset = 0x%x, addend = 0x%x\n",
729            (unsigned int) reloc_data.reloc_offset,
730            (unsigned int) reloc_data.reloc_addend);
731   PR_DEBUG (" Symbol:\n");
732   PR_DEBUG ("  value = 0x%08x\n",
733            (unsigned int) reloc_data.sym_value);
734   if (reloc_data.sym_section != NULL)
735     {
736       PR_DEBUG ("IN IF\n");
737       PR_DEBUG (
738                "  section name = %s, output_offset 0x%08x",
739                reloc_data.sym_section->name,
740                (unsigned int) reloc_data.sym_section->output_offset);
741       if (reloc_data.sym_section->output_section != NULL)
742         {
743           PR_DEBUG (
744                    ", output_section->vma = 0x%08x",
745                    ((unsigned int) reloc_data.sym_section->output_section->vma));
746         }
747
748       PR_DEBUG ( "\n");
749     }
750   else
751     {
752       PR_DEBUG ( "  symbol section is NULL\n");
753     }
754
755   PR_DEBUG ( " Input_section:\n");
756   if (reloc_data.input_section != NULL)
757     {
758       PR_DEBUG (
759                "  section name = %s, output_offset 0x%08x, output_section->vma = 0x%08x\n",
760                reloc_data.input_section->name,
761                (unsigned int) reloc_data.input_section->output_offset,
762                (unsigned int) reloc_data.input_section->output_section->vma);
763       PR_DEBUG ( "  changed_address = 0x%08x\n",
764                (unsigned int) (reloc_data.input_section->output_section->vma +
765                reloc_data.input_section->output_offset +
766                reloc_data.reloc_offset));
767     }
768   else
769     {
770       PR_DEBUG ( "      input section is NULL\n");
771     }
772 }
773
774 static ATTRIBUTE_UNUSED bfd_vma
775 get_middle_endian_relocation (bfd_vma reloc)
776 {
777   bfd_vma ret = ((reloc & 0xffff0000) >> 16) |
778                 ((reloc & 0xffff) << 16);
779   return ret;
780 }
781
782 #define S (reloc_data.sym_value                                         \
783            + (reloc_data.sym_section->output_section != NULL ?          \
784               (reloc_data.sym_section->output_offset                    \
785                + reloc_data.sym_section->output_section->vma) : 0)      \
786            )
787 #define L (reloc_data.sym_value                                         \
788            + (reloc_data.sym_section->output_section != NULL ?          \
789               (reloc_data.sym_section->output_offset                    \
790               + reloc_data.sym_section->output_section->vma) : 0)       \
791           )
792 #define A (reloc_data.reloc_addend)
793 #define B (0)
794 #define G (reloc_data.got_offset_value)
795 #define GOT (reloc_data.got_symbol_vma)
796 #define GOT_BEGIN (htab->sgot->output_section->vma)
797
798 #define MES (0)
799         /* P: relative offset to PCL The offset should be to the
800           current location aligned to 32 bits.  */
801 #define P (                                                             \
802            (                                                            \
803             (reloc_data.input_section->output_section != NULL ?         \
804              reloc_data.input_section->output_section->vma : 0)         \
805             + reloc_data.input_section->output_offset                   \
806             + (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0))       \
807             ) & ~0x3)
808 #define PDATA ( \
809             (reloc_data.input_section->output_section->vma \
810              + reloc_data.input_section->output_offset \
811              + (reloc_data.reloc_offset) \
812             ))
813 #define SECTSTAR (reloc_data.input_section->output_offset)
814 #define SECTSTART (reloc_data.input_section->output_offset)
815 #define _SDA_BASE_ (reloc_data.sdata_begin_symbol_vma)
816 #define TLS_REL ((elf_hash_table (info))->tls_sec->output_section->vma)
817 #define _SDA_BASE_ (reloc_data.sdata_begin_symbol_vma)
818 #define TLS_TBSS (8)
819 #define TCB_SIZE (8)
820
821 #define NON_ME(VALUE) (reverse_me (reloc_data, VALUE))
822
823 #define none (0)
824
825 #define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA) \
826     {\
827       asection *sym_section = reloc_data.sym_section; \
828       asection *input_section = reloc_data.input_section; \
829       ARC_DEBUG ("FORMULA = " #FORMULA "\n"); \
830       ARC_DEBUG ("S = 0x%x\n", S); \
831       ARC_DEBUG ("A = 0x%x\n", A); \
832       ARC_DEBUG ("L = 0x%x\n", L); \
833       if (sym_section->output_section != NULL) \
834         { \
835           ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
836              sym_section->output_section->vma + sym_section->output_offset); \
837         } \
838       else \
839         { \
840           ARC_DEBUG ("symbol_section->vma = NULL\n"); \
841         } \
842       if (input_section->output_section != NULL) \
843         { \
844           ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
845              input_section->output_section->vma + input_section->output_offset); \
846         } \
847       else \
848         { \
849           ARC_DEBUG ("symbol_section->vma = NULL\n"); \
850         } \
851       ARC_DEBUG ("PCL = 0x%x\n", P); \
852       ARC_DEBUG ("P = 0x%x\n", P); \
853       ARC_DEBUG ("G = 0x%x\n", G); \
854       ARC_DEBUG ("SDA_OFFSET = 0x%x\n", _SDA_BASE_); \
855       ARC_DEBUG ("SDA_SET = %d\n", reloc_data.sdata_begin_symbol_vma_set); \
856       ARC_DEBUG ("GOT_OFFSET = 0x%x\n", GOT); \
857       ARC_DEBUG ("relocation = 0x%08x\n", relocation); \
858       ARC_DEBUG ("before = 0x%08x\n", (unsigned int) insn); \
859       ARC_DEBUG ("data   = 0x%08x (%u) (%d)\n", (unsigned int) relocation, (unsigned int) relocation, (int) relocation); \
860     }
861
862 #define PRINT_DEBUG_RELOC_INFO_AFTER \
863     { \
864       ARC_DEBUG ("after  = 0x%08x\n", (unsigned int) insn); \
865     }
866
867 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
868   case R_##TYPE: \
869     { \
870       bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
871       relocation = FORMULA  ; \
872       PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA) \
873       insn = RELOC_FUNCTION (insn, relocation); \
874       PRINT_DEBUG_RELOC_INFO_AFTER \
875     } \
876     break;
877
878 static bfd_vma
879 reverse_me (struct arc_relocation_data reloc_data, bfd_vma reloc)
880 {
881   if (reloc_data.input_section && reloc_data.input_section->flags & SEC_CODE)
882     return ((0x0000fffff & reloc) << 16) | ((0xffff0000 & reloc) >> 16);
883   else
884     return reloc;
885 }
886
887 static bfd_reloc_status_type
888 arc_do_relocation (bfd_byte * contents,
889                    struct arc_relocation_data reloc_data,
890                    struct bfd_link_info *info)
891 {
892   bfd_vma relocation = 0;
893   bfd_vma insn;
894   bfd_vma orig_insn ATTRIBUTE_UNUSED;
895   struct elf_link_hash_table *htab ATTRIBUTE_UNUSED = elf_hash_table (info);
896
897   if (reloc_data.should_relocate == FALSE)
898     return bfd_reloc_ok;
899
900   switch (reloc_data.howto->size)
901     {
902       case 2:
903         insn = arc_bfd_get_32 (reloc_data.input_section->owner,
904                                contents + reloc_data.reloc_offset,
905                                reloc_data.input_section);
906         break;
907       case 1:
908       case 0:
909         insn = arc_bfd_get_16 (reloc_data.input_section->owner,
910                                contents + reloc_data.reloc_offset,
911                                reloc_data.input_section);
912         break;
913       default:
914         insn = 0;
915         BFD_ASSERT (0);
916         break;
917     }
918
919   orig_insn = insn;
920
921   switch (reloc_data.howto->type)
922     {
923 #include "elf/arc-reloc.def"
924
925       default:
926         BFD_ASSERT (0);
927         break;
928     }
929
930   /* Check for relocation overflow.  */
931   if (reloc_data.howto->complain_on_overflow != complain_overflow_dont)
932     {
933       bfd_reloc_status_type flag;
934       flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
935                                  reloc_data.howto->bitsize,
936                                  reloc_data.howto->rightshift,
937                                  bfd_arch_bits_per_address (reloc_data.input_section->owner),
938                                  relocation);
939
940 #undef  DEBUG_ARC_RELOC
941 #define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
942       if (flag != bfd_reloc_ok)
943         {
944           PR_DEBUG ( "Relocation overflows !!!!\n");
945
946           DEBUG_ARC_RELOC (reloc_data);
947
948           PR_DEBUG (
949                   "Relocation value = signed -> %d, unsigned -> %u"
950                   ", hex -> (0x%08x)\n",
951                   (int) relocation,
952                   (unsigned int) relocation,
953                   (unsigned int) relocation);
954           return flag;
955         }
956     }
957 #undef  DEBUG_ARC_RELOC
958 #define DEBUG_ARC_RELOC(A)
959
960   switch (reloc_data.howto->size)
961     {
962       case 2:
963         arc_bfd_put_32 (reloc_data.input_section->owner, insn,
964                        contents + reloc_data.reloc_offset,
965                        reloc_data.input_section);
966         break;
967       case 1:
968       case 0:
969         arc_bfd_put_16 (reloc_data.input_section->owner, insn,
970                        contents + reloc_data.reloc_offset,
971                        reloc_data.input_section);
972         break;
973       default:
974         ARC_DEBUG ("size = %d\n", reloc_data.howto->size);
975         BFD_ASSERT (0);
976         break;
977     }
978
979   return bfd_reloc_ok;
980 }
981 #undef S
982 #undef A
983 #undef B
984 #undef G
985 #undef GOT
986 #undef L
987 #undef MES
988 #undef P
989 #undef SECTSTAR
990 #undef SECTSTART
991 #undef _SDA_BASE_
992 #undef none
993
994 #undef ARC_RELOC_HOWTO
995
996 static struct got_entry **
997 arc_get_local_got_ents (bfd * abfd)
998 {
999   static struct got_entry **local_got_ents = NULL;
1000
1001   if (local_got_ents == NULL)
1002     {
1003       size_t       size;
1004       Elf_Internal_Shdr *symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1005
1006       size = symtab_hdr->sh_info * sizeof (bfd_vma);
1007       local_got_ents = (struct got_entry **)
1008         bfd_alloc (abfd, sizeof(struct got_entry *) * size);
1009       if (local_got_ents == NULL)
1010         return FALSE;
1011
1012       memset (local_got_ents, 0, sizeof(struct got_entry *) * size);
1013       elf_local_got_ents (abfd) = local_got_ents;
1014     }
1015
1016   return local_got_ents;
1017 }
1018
1019 /* Relocate an arc ELF section.
1020    Function : elf_arc_relocate_section
1021    Brief    : Relocate an arc section, by handling all the relocations
1022              appearing in that section.
1023    Args     : output_bfd    : The bfd being written to.
1024               info          : Link information.
1025               input_bfd     : The input bfd.
1026               input_section : The section being relocated.
1027               contents      : contents of the section being relocated.
1028               relocs        : List of relocations in the section.
1029               local_syms    : is a pointer to the swapped in local symbols.
1030               local_section : is an array giving the section in the input file
1031                               corresponding to the st_shndx field of each
1032                               local symbol.  */
1033 static bfd_boolean
1034 elf_arc_relocate_section (bfd *            output_bfd,
1035                           struct bfd_link_info *  info,
1036                           bfd *            input_bfd,
1037                           asection *          input_section,
1038                           bfd_byte *          contents,
1039                           Elf_Internal_Rela *     relocs,
1040                           Elf_Internal_Sym *      local_syms,
1041                           asection **        local_sections)
1042 {
1043   Elf_Internal_Shdr *      symtab_hdr;
1044   struct elf_link_hash_entry ** sym_hashes;
1045   struct got_entry **      local_got_ents;
1046   Elf_Internal_Rela *      rel;
1047   Elf_Internal_Rela *      relend;
1048   struct elf_link_hash_table *htab = elf_hash_table (info);
1049
1050   symtab_hdr = &((elf_tdata (input_bfd))->symtab_hdr);
1051   sym_hashes = elf_sym_hashes (input_bfd);
1052
1053   rel = relocs;
1054   relend = relocs + input_section->reloc_count;
1055   for (; rel < relend; rel++)
1056     {
1057       enum elf_arc_reloc_type       r_type;
1058       reloc_howto_type *            howto;
1059       unsigned long              r_symndx;
1060       struct elf_link_hash_entry *  h;
1061       Elf_Internal_Sym *            sym;
1062       asection *                    sec;
1063       struct elf_link_hash_entry *h2;
1064
1065       struct arc_relocation_data reloc_data =
1066       {
1067         .reloc_offset = 0,
1068         .reloc_addend = 0,
1069         .got_offset_value = 0,
1070         .sym_value = 0, 
1071         .sym_section = NULL,
1072         .howto = NULL,
1073         .input_section = NULL,
1074         .sdata_begin_symbol_vma = 0,
1075         .sdata_begin_symbol_vma_set = FALSE,
1076         .got_symbol_vma = 0,
1077         .should_relocate = FALSE
1078       };
1079
1080       r_type = ELF32_R_TYPE (rel->r_info);
1081
1082       if (r_type >= (int) R_ARC_max)
1083         {
1084           bfd_set_error (bfd_error_bad_value);
1085           return FALSE;
1086         }
1087       howto = &elf_arc_howto_table[r_type];
1088
1089       r_symndx = ELF32_R_SYM (rel->r_info);
1090
1091       /* If we are generating another .o file and the symbol in not
1092          local, skip this relocation.  */
1093       if (bfd_link_relocatable (info))
1094         {
1095           /* This is a relocateable link.  We don't have to change
1096              anything, unless the reloc is against a section symbol,
1097              in which case we have to adjust according to where the
1098              section symbol winds up in the output section.  */
1099
1100           /* Checks if this is a local symbol and thus the reloc
1101              might (will??) be against a section symbol.  */
1102           if (r_symndx < symtab_hdr->sh_info)
1103             {
1104               sym = local_syms + r_symndx;
1105               if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1106                 {
1107                   sec = local_sections[r_symndx];
1108
1109                   /* for RELA relocs.Just adjust the addend
1110                      value in the relocation entry.  */
1111                   rel->r_addend += sec->output_offset + sym->st_value;
1112
1113                   BFD_DEBUG_PIC (
1114                     PR_DEBUG ("local symbols reloc "
1115                               "(section=%d %s) seen in %s\n",
1116                               r_symndx,
1117                               local_sections[r_symndx]->name,
1118                               __PRETTY_FUNCTION__)
1119                   );
1120                 }
1121             }
1122
1123           continue;
1124         }
1125
1126       h2 = elf_link_hash_lookup (elf_hash_table (info), "__SDATA_BEGIN__",
1127                                  FALSE, FALSE, TRUE);
1128
1129       if (reloc_data.sdata_begin_symbol_vma_set == FALSE
1130             && h2 != NULL && h2->root.type != bfd_link_hash_undefined
1131             && h2->root.u.def.section->output_section != NULL)
1132         /* TODO: Verify this condition.  */
1133         {
1134           reloc_data.sdata_begin_symbol_vma =
1135             (h2->root.u.def.value +
1136              h2->root.u.def.section->output_section->vma);
1137           reloc_data.sdata_begin_symbol_vma_set = TRUE;
1138         }
1139
1140       reloc_data.input_section = input_section;
1141       reloc_data.howto = howto;
1142       reloc_data.reloc_offset = rel->r_offset;
1143       reloc_data.reloc_addend = rel->r_addend;
1144
1145       /* This is a final link.  */
1146       h = NULL;
1147       sym = NULL;
1148       sec = NULL;
1149
1150       if (r_symndx < symtab_hdr->sh_info) /* A local symbol.  */
1151         {
1152           local_got_ents = arc_get_local_got_ents (output_bfd);
1153           struct got_entry *entry = local_got_ents[r_symndx];
1154
1155           sym = local_syms + r_symndx;
1156           sec = local_sections[r_symndx];
1157
1158           reloc_data.sym_value = sym->st_value;
1159           reloc_data.sym_section = sec;
1160
1161           /* Mergeable section handling.  */
1162           if ((sec->flags & SEC_MERGE)
1163               && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1164             {
1165               asection *msec;
1166               msec = sec;
1167               rel->r_addend = _bfd_elf_rel_local_sym (output_bfd, sym,
1168                                                       &msec, rel->r_addend);
1169               rel->r_addend -= (sec->output_section->vma
1170                                 + sec->output_offset
1171                                 + sym->st_value);
1172               rel->r_addend += msec->output_section->vma + msec->output_offset;
1173
1174               reloc_data.reloc_addend = rel->r_addend;
1175             }
1176
1177           if ((is_reloc_for_GOT (howto)
1178                || is_reloc_for_TLS (howto)) && entry != NULL)
1179             {
1180               if (is_reloc_for_TLS (howto))
1181                 while (entry->type == GOT_NORMAL && entry->next != NULL)
1182                   entry = entry->next;
1183
1184               if (is_reloc_for_GOT (howto))
1185                 while (entry->type != GOT_NORMAL && entry->next != NULL)
1186                   entry = entry->next;
1187
1188               if (entry->type == GOT_TLS_GD && entry->processed == FALSE)
1189                 {
1190                   bfd_vma sym_vma = sym->st_value
1191                                     + sec->output_section->vma
1192                                     + sec->output_offset;
1193
1194                   /* Create dynamic relocation for local sym.  */
1195                   ADD_RELA (output_bfd, got, entry->offset, 0,
1196                             R_ARC_TLS_DTPMOD, 0);
1197                   ADD_RELA (output_bfd, got, entry->offset+4, 0,
1198                             R_ARC_TLS_DTPOFF, 0);
1199
1200                   bfd_vma sec_vma = sec->output_section->vma
1201                                     + sec->output_offset;
1202                   bfd_put_32 (output_bfd, sym_vma - sec_vma,
1203                               htab->sgot->contents + entry->offset + 4);
1204
1205                   ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_GD value "
1206                          "= 0x%x @ 0x%x, for symbol %s\n",
1207                          sym_vma - sec_vma,
1208                          htab->sgot->contents + entry->offset + 4,
1209                          "(local)");
1210
1211                   entry->processed = TRUE;
1212                 }
1213               if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
1214                 {
1215                   bfd_vma sym_vma = sym->st_value
1216                                     + sec->output_section->vma
1217                                     + sec->output_offset;
1218                   bfd_vma sec_vma = htab->tls_sec->output_section->vma;
1219                   bfd_put_32 (output_bfd, sym_vma - sec_vma,
1220                               htab->sgot->contents + entry->offset);
1221                   /* TODO: Check if this type of relocs is the cause
1222                      for all the ARC_NONE dynamic relocs.  */
1223
1224                   ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_IE value = "
1225                          "0x%x @ 0x%x, for symbol %s\n",
1226                          sym_vma - sec_vma,
1227                          htab->sgot->contents + entry->offset,
1228                          "(local)");
1229
1230                   entry->processed = TRUE;
1231                 }
1232               if (entry->type == GOT_NORMAL && entry->processed == FALSE)
1233                 {
1234                   bfd_vma sec_vma = reloc_data.sym_section->output_section->vma
1235                                     + reloc_data.sym_section->output_offset;
1236
1237                   bfd_put_32 (output_bfd, reloc_data.sym_value + sec_vma,
1238                               htab->sgot->contents + entry->offset);
1239
1240                   ARC_DEBUG ("arc_info: PATCHED: 0x%08x @ 0x%08x for "
1241                          "sym %s in got offset 0x%x\n",
1242                          reloc_data.sym_value + sec_vma,
1243                          htab->sgot->output_section->vma
1244                          + htab->sgot->output_offset + entry->offset,
1245                          "(local)",
1246                          entry->offset);
1247                   entry->processed = TRUE;
1248                 }
1249
1250               reloc_data.got_offset_value = entry->offset;
1251               ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
1252                      "vma = 0x%x for symbol %s\n",
1253                      entry->type, entry->offset,
1254                      htab->sgot->output_section->vma
1255                      + htab->sgot->output_offset + entry->offset,
1256                      "(local)");
1257             }
1258
1259           BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1260           if (htab->sgot != NULL)
1261             reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1262                                         + htab->sgot->output_offset;
1263
1264           reloc_data.should_relocate = TRUE;
1265         }
1266       else /* Global symbol.  */
1267         {
1268           /* Get the symbol's entry in the symtab.  */
1269           h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1270
1271           while (h->root.type == bfd_link_hash_indirect
1272                  || h->root.type == bfd_link_hash_warning)
1273             h = (struct elf_link_hash_entry *) h->root.u.i.link;
1274
1275           BFD_ASSERT ((h->dynindx == -1) >= (h->forced_local != 0));
1276           /* If we have encountered a definition for this symbol.  */
1277           if (h->root.type == bfd_link_hash_defined
1278               || h->root.type == bfd_link_hash_defweak)
1279             {
1280               reloc_data.sym_value = h->root.u.def.value;
1281               reloc_data.sym_section = h->root.u.def.section;
1282
1283               reloc_data.should_relocate = TRUE;
1284
1285               if (is_reloc_for_GOT (howto) && !bfd_link_pic (info))
1286                 {
1287                   /* TODO: Change it to use arc_do_relocation with
1288                     ARC_32 reloc.  Try to use ADD_RELA macro.  */
1289                   bfd_vma relocation =
1290                     reloc_data.sym_value + reloc_data.reloc_addend
1291                     + (reloc_data.sym_section->output_section != NULL ?
1292                         (reloc_data.sym_section->output_offset
1293                          + reloc_data.sym_section->output_section->vma)
1294                       : 0);
1295
1296                   BFD_ASSERT (h->got.glist);
1297                   bfd_vma got_offset = h->got.glist->offset;
1298                   bfd_put_32 (output_bfd, relocation,
1299                               htab->sgot->contents + got_offset);
1300                 }
1301               if (is_reloc_for_PLT (howto) && 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                 }
1307             }
1308           else if (h->root.type == bfd_link_hash_undefweak)
1309             {
1310               /* Is weak symbol and has no definition.  */
1311               if (is_reloc_for_GOT (howto))
1312                 {
1313                   reloc_data.sym_value = h->root.u.def.value;
1314                   reloc_data.sym_section = htab->sgot;
1315                   reloc_data.should_relocate = TRUE;
1316                 }
1317               else if (is_reloc_for_PLT (howto)
1318                        && h->plt.offset != (bfd_vma) -1)
1319                 {
1320                   /* TODO: This is repeated up here.  */
1321                   reloc_data.sym_value = h->plt.offset;
1322                   reloc_data.sym_section = htab->splt;
1323                   reloc_data.should_relocate = TRUE;
1324                 }
1325               else
1326                 continue;
1327             }
1328           else
1329             {
1330               if (is_reloc_for_GOT (howto))
1331                 {
1332                   reloc_data.sym_value = h->root.u.def.value;
1333                   reloc_data.sym_section = htab->sgot;
1334
1335                   reloc_data.should_relocate = TRUE;
1336                 }
1337               else if (is_reloc_for_PLT (howto))
1338                 {
1339                   /* Fail if it is linking for PIE and the symbol is
1340                      undefined.  */
1341                   if (bfd_link_executable (info)
1342                       && !(*info->callbacks->undefined_symbol)
1343                         (info, h->root.root.string, input_bfd, input_section,
1344                          rel->r_offset, TRUE))
1345                     {
1346                       return FALSE;
1347                     }
1348                   reloc_data.sym_value = h->plt.offset;
1349                   reloc_data.sym_section = htab->splt;
1350
1351                   reloc_data.should_relocate = TRUE;
1352                 }
1353               else if (!bfd_link_pic (info)
1354                        && !(*info->callbacks->undefined_symbol)
1355                        (info, h->root.root.string, input_bfd, input_section,
1356                         rel->r_offset, TRUE))
1357                 {
1358                   return FALSE;
1359                 }
1360             }
1361
1362           if (h->got.glist != NULL)
1363             {
1364               struct got_entry *entry = h->got.glist;
1365
1366               if (is_reloc_for_GOT (howto) || is_reloc_for_TLS (howto))
1367                 {
1368                   if (! elf_hash_table (info)->dynamic_sections_created
1369                       || (bfd_link_pic (info)
1370                           && SYMBOL_REFERENCES_LOCAL (info, h)))
1371                     {
1372                       reloc_data.sym_value = h->root.u.def.value;
1373                       reloc_data.sym_section = h->root.u.def.section;
1374
1375                       if (is_reloc_for_TLS (howto))
1376                         while (entry->type == GOT_NORMAL && entry->next != NULL)
1377                           entry = entry->next;
1378
1379                       if (entry->processed == FALSE
1380                           && (entry->type == GOT_TLS_GD
1381                               || entry->type == GOT_TLS_IE))
1382                         {
1383                           bfd_vma sym_value = h->root.u.def.value
1384                             + h->root.u.def.section->output_section->vma
1385                             + h->root.u.def.section->output_offset;
1386
1387                           bfd_vma sec_vma =
1388                             elf_hash_table (info)->tls_sec->output_section->vma;
1389
1390                           bfd_put_32 (output_bfd,
1391                                       sym_value - sec_vma,
1392                                       htab->sgot->contents + entry->offset
1393                                       + (entry->existing_entries == MOD_AND_OFF ? 4 : 0));
1394
1395                           ARC_DEBUG ("arc_info: FIXED -> %s value = 0x%x "
1396                                      "@ 0x%x, for symbol %s\n",
1397                                      (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
1398                                       "GOT_TLS_IE"),
1399                                      sym_value - sec_vma,
1400                                      htab->sgot->contents + entry->offset
1401                                      + (entry->existing_entries == MOD_AND_OFF ? 4 : 0),
1402                                      h->root.root.string);
1403
1404                           entry->processed = TRUE;
1405                         }
1406
1407                       if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
1408                         {
1409                           bfd_vma sec_vma = htab->tls_sec->output_section->vma;
1410                           bfd_put_32 (output_bfd,
1411                                       reloc_data.sym_value - sec_vma,
1412                                       htab->sgot->contents + entry->offset);
1413                         }
1414
1415                       if (entry->type == GOT_NORMAL && entry->processed == FALSE)
1416                         {
1417                           bfd_vma sec_vma =
1418                             reloc_data.sym_section->output_section->vma
1419                             + reloc_data.sym_section->output_offset;
1420
1421                           if (h->root.type != bfd_link_hash_undefweak)
1422                             {
1423                               bfd_put_32 (output_bfd,
1424                                           reloc_data.sym_value + sec_vma,
1425                                           htab->sgot->contents + entry->offset);
1426
1427                               ARC_DEBUG ("arc_info: PATCHED: 0x%08x "
1428                                          "@ 0x%08x for sym %s in got offset 0x%x\n",
1429                                          reloc_data.sym_value + sec_vma,
1430                                          htab->sgot->output_section->vma
1431                                          + htab->sgot->output_offset + entry->offset,
1432                                          h->root.root.string,
1433                                          entry->offset);
1434                             }
1435                           else
1436                             {
1437                               ARC_DEBUG ("arc_info: PATCHED: NOT_PATCHED "
1438                                          "@ 0x%08x for sym %s in got offset 0x%x "
1439                                          "(is undefweak)\n",
1440                                          htab->sgot->output_section->vma
1441                                          + htab->sgot->output_offset + entry->offset,
1442                                          h->root.root.string,
1443                                          entry->offset);
1444                             }
1445
1446                           entry->processed = TRUE;
1447                         }
1448                     }
1449                 }
1450
1451               reloc_data.got_offset_value = entry->offset;
1452
1453               ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
1454                          "vma = 0x%x for symbol %s\n",
1455                          entry->type, entry->offset,
1456                          htab->sgot->output_section->vma
1457                          + htab->sgot->output_offset + entry->offset,
1458                          h->root.root.string);
1459             }
1460
1461           BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1462           if (htab->sgot != NULL)
1463             reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1464                                         + htab->sgot->output_offset;
1465         }
1466
1467       switch (r_type)
1468         {
1469           case R_ARC_32:
1470           case R_ARC_32_ME:
1471           case R_ARC_PC32:
1472           case R_ARC_32_PCREL:
1473             if (bfd_link_pic (info) && !bfd_link_pie (info)
1474                 && ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1475                     || (h != NULL
1476                         && h->dynindx != -1
1477                         && (!info->symbolic || !h->def_regular))))
1478               {
1479                 Elf_Internal_Rela outrel;
1480                 bfd_byte *loc;
1481                 bfd_boolean skip = FALSE;
1482                 bfd_boolean relocate = FALSE;
1483                 asection *sreloc = _bfd_elf_get_dynamic_reloc_section
1484                                  (input_bfd, input_section,
1485                                   /*RELA*/ TRUE);
1486
1487                 BFD_ASSERT (sreloc != NULL);
1488
1489                 outrel.r_offset = _bfd_elf_section_offset (output_bfd,
1490                                                            info,
1491                                                            input_section,
1492                                                            rel->r_offset);
1493                 if (outrel.r_offset == (bfd_vma) -1)
1494                   skip = TRUE;
1495
1496                 outrel.r_addend = rel->r_addend;
1497                 outrel.r_offset += (input_section->output_section->vma
1498                                     + input_section->output_offset);
1499
1500                 if (skip)
1501                   {
1502                     memset (&outrel, 0, sizeof outrel);
1503                     relocate = FALSE;
1504                   }
1505                 else if (r_type == R_ARC_PC32
1506                          || r_type == R_ARC_32_PCREL)
1507                   {
1508                     BFD_ASSERT (h != NULL && h->dynindx != -1);
1509                     if ((input_section->flags & SEC_ALLOC) != 0)
1510                       relocate = FALSE;
1511                     else
1512                       relocate = TRUE;
1513                     outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1514                   }
1515                 else
1516                   {
1517                     /* Handle local symbols, they either do not have a
1518                        global hash table entry (h == NULL), or are
1519                        forced local due to a version script
1520                        (h->forced_local), or the third condition is
1521                        legacy, it appears to say something like, for
1522                        links where we are pre-binding the symbols, or
1523                        there's not an entry for this symbol in the
1524                        dynamic symbol table, and it's a regular symbol
1525                        not defined in a shared object, then treat the
1526                        symbol as local, resolve it now.  */
1527                     if (h == NULL
1528                         || ((info->symbolic || h->dynindx == -1)
1529                             && h->def_regular)
1530                         || h->forced_local)
1531                       {
1532                         relocate = TRUE;
1533                         /* outrel.r_addend = 0; */
1534                         outrel.r_info = ELF32_R_INFO (0, R_ARC_RELATIVE);
1535                       }
1536                     else
1537                       {
1538                         BFD_ASSERT (h->dynindx != -1);
1539
1540                         /* This type of dynamic relocation cannot be created
1541                            for code sections.  */
1542                         BFD_ASSERT ((input_section->flags & SEC_CODE) == 0);
1543
1544                         if ((input_section->flags & SEC_ALLOC) != 0)
1545                           relocate = FALSE;
1546                         else
1547                           relocate = TRUE;
1548                         outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_32);
1549                       }
1550                   }
1551
1552                 BFD_ASSERT (sreloc->contents != 0);
1553
1554                 loc = sreloc->contents;
1555                 loc += sreloc->reloc_count * sizeof (Elf32_External_Rela);
1556                 sreloc->reloc_count += 1;
1557
1558                 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1559
1560                 if (relocate == FALSE)
1561                   continue;
1562               }
1563             break;
1564           default:
1565             break;
1566         }
1567
1568       if (is_reloc_SDA_relative (howto)
1569           && (reloc_data.sdata_begin_symbol_vma_set == FALSE))
1570         {
1571           (*_bfd_error_handler)
1572               ("Error: Linker symbol __SDATA_BEGIN__ not found");
1573           bfd_set_error (bfd_error_bad_value);
1574           return FALSE;
1575         }
1576
1577       DEBUG_ARC_RELOC (reloc_data);
1578
1579       if (arc_do_relocation (contents, reloc_data, info) != bfd_reloc_ok)
1580         return FALSE;
1581     }
1582
1583   return TRUE;
1584 }
1585
1586 static struct dynamic_sections
1587 arc_create_dynamic_sections (bfd * abfd, struct bfd_link_info *info)
1588 {
1589   struct elf_link_hash_table *htab;
1590   bfd    *dynobj;
1591   struct dynamic_sections ds =
1592     {
1593       .initialized = FALSE,
1594       .sgot = NULL,
1595       .srelgot = NULL,
1596       .sgotplt = NULL,
1597       .srelgotplt = NULL,
1598       .sdyn = NULL,
1599       .splt = NULL,
1600       .srelplt = NULL
1601     };
1602
1603   htab = elf_hash_table (info);
1604   BFD_ASSERT (htab);
1605
1606   /* Create dynamic sections for relocatable executables so that we
1607      can copy relocations.  */
1608   if (! htab->dynamic_sections_created && bfd_link_pic (info))
1609     {
1610       if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
1611         BFD_ASSERT (0);
1612     }
1613
1614   dynobj = (elf_hash_table (info))->dynobj;
1615
1616   if (dynobj)
1617     {
1618       ds.sgot = htab->sgot;
1619       ds.srelgot = htab->srelgot;
1620
1621       ds.sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
1622       ds.srelgotplt = ds.srelplt;
1623
1624       ds.splt = bfd_get_section_by_name (dynobj, ".plt");
1625       ds.srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
1626     }
1627
1628   if (htab->dynamic_sections_created)
1629     {
1630       ds.sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
1631     }
1632
1633   ds.initialized = TRUE;
1634
1635   return ds;
1636 }
1637
1638 #define ADD_SYMBOL_REF_SEC_AND_RELOC(SECNAME, COND_FOR_RELOC, H)        \
1639   htab->s##SECNAME->size;                                               \
1640   {                                                                     \
1641     if (COND_FOR_RELOC)                                                 \
1642       {                                                                 \
1643         htab->srel##SECNAME->size += sizeof (Elf32_External_Rela);      \
1644           ARC_DEBUG ("arc_info: Added reloc space in "                  \
1645                      #SECNAME " section at " __FILE__                   \
1646                      ":%d for symbol\n",                                \
1647                      __LINE__, name_for_global_symbol (H));             \
1648       }                                                                 \
1649     if (H)                                                              \
1650       if (h->dynindx == -1 && !h->forced_local)                         \
1651         if (! bfd_elf_link_record_dynamic_symbol (info, H))             \
1652           return FALSE;                                                 \
1653      htab->s##SECNAME->size += 4;                       \
1654    }
1655
1656 static bfd_boolean
1657 elf_arc_check_relocs (bfd *                      abfd,
1658                       struct bfd_link_info *     info,
1659                       asection *                 sec,
1660                       const Elf_Internal_Rela *  relocs)
1661 {
1662   Elf_Internal_Shdr *           symtab_hdr;
1663   struct elf_link_hash_entry ** sym_hashes;
1664   struct got_entry **           local_got_ents;
1665   const Elf_Internal_Rela *     rel;
1666   const Elf_Internal_Rela *     rel_end;
1667   bfd *                         dynobj;
1668   asection *                    sreloc = NULL;
1669   struct elf_link_hash_table *  htab = elf_hash_table (info);
1670
1671   if (bfd_link_relocatable (info))
1672     return TRUE;
1673
1674   dynobj = (elf_hash_table (info))->dynobj;
1675   symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1676   sym_hashes = elf_sym_hashes (abfd);
1677   local_got_ents = arc_get_local_got_ents (abfd);
1678
1679   rel_end = relocs + sec->reloc_count;
1680   for (rel = relocs; rel < rel_end; rel++)
1681     {
1682       enum elf_arc_reloc_type r_type;
1683       reloc_howto_type *howto;
1684       unsigned long   r_symndx;
1685       struct elf_link_hash_entry *h;
1686
1687       r_type = ELF32_R_TYPE (rel->r_info);
1688
1689       if (r_type >= (int) R_ARC_max)
1690         {
1691           bfd_set_error (bfd_error_bad_value);
1692           return FALSE;
1693         }
1694       howto = &elf_arc_howto_table[r_type];
1695
1696       if (dynobj == NULL
1697           && (is_reloc_for_GOT (howto) == TRUE
1698               || is_reloc_for_TLS (howto) == TRUE))
1699         {
1700           dynobj = elf_hash_table (info)->dynobj = abfd;
1701           if (! _bfd_elf_create_got_section (abfd, info))
1702             return FALSE;
1703         }
1704
1705       /* Load symbol information.  */
1706       r_symndx = ELF32_R_SYM (rel->r_info);
1707       if (r_symndx < symtab_hdr->sh_info) /* Is a local symbol.  */
1708         h = NULL;
1709       else /* Global one.  */
1710         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1711
1712       switch (r_type)
1713         {
1714           case R_ARC_32:
1715           case R_ARC_32_ME:
1716             /* During shared library creation, these relocs should not
1717                appear in a shared library (as memory will be read only
1718                and the dynamic linker can not resolve these.  However
1719                the error should not occur for e.g. debugging or
1720                non-readonly sections.  */
1721             if (bfd_link_dll (info) && !bfd_link_pie (info)
1722                 && (sec->flags & SEC_ALLOC) != 0
1723                 && (sec->flags & SEC_READONLY) != 0)
1724               {
1725                 const char *name;
1726                 if (h)
1727                   name = h->root.root.string;
1728                 else
1729                   /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);  */
1730                   name = "UNKNOWN";
1731                 (*_bfd_error_handler)
1732                   (_("\
1733 %B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
1734                     abfd,
1735                     arc_elf_howto (r_type)->name,
1736                     name);
1737                 bfd_set_error (bfd_error_bad_value);
1738                 return FALSE;
1739               }
1740
1741             /* In some cases we are not setting the 'non_got_ref'
1742                flag, even though the relocations don't require a GOT
1743                access.  We should extend the testing in this area to
1744                ensure that no significant cases are being missed.  */
1745             if (h)
1746               h->non_got_ref = 1;
1747             /* FALLTHROUGH */
1748           case R_ARC_PC32:
1749           case R_ARC_32_PCREL:
1750             if (bfd_link_pic (info) && !bfd_link_pie (info)
1751                 && ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1752                     || (h != NULL
1753                         && h->dynindx != -1
1754                         && (!info->symbolic || !h->def_regular))))
1755               {
1756                 if (sreloc == NULL)
1757                   {
1758                     sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
1759                                                                   2, abfd,
1760                                                                   /*rela*/
1761                                                                   TRUE);
1762
1763                     if (sreloc == NULL)
1764                       return FALSE;
1765                   }
1766                 sreloc->size += sizeof (Elf32_External_Rela);
1767
1768               }
1769           default:
1770             break;
1771         }
1772
1773       if (is_reloc_for_PLT (howto) == TRUE)
1774         {
1775           if (h == NULL)
1776             continue;
1777           else
1778             h->needs_plt = 1;
1779         }
1780
1781       if (is_reloc_for_GOT (howto) == TRUE)
1782         {
1783           if (h == NULL)
1784             {
1785               /* Local symbol.  */
1786               if (local_got_ents[r_symndx] == NULL)
1787                 {
1788                   bfd_vma offset =
1789                     ADD_SYMBOL_REF_SEC_AND_RELOC (got,
1790                                                   bfd_link_pic (info),
1791                                                   NULL);
1792                   new_got_entry_to_list (&(local_got_ents[r_symndx]),
1793                                          GOT_NORMAL, offset, NONE);
1794                 }
1795             }
1796           else
1797             {
1798               /* Global symbol.  */
1799               h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1800               if (h->got.glist == NULL)
1801                 {
1802                   bfd_vma offset =
1803                     ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1804                   new_got_entry_to_list (&h->got.glist,
1805                                          GOT_NORMAL, offset, NONE);
1806                 }
1807             }
1808         }
1809
1810       if (is_reloc_for_TLS (howto) == TRUE)
1811         {
1812           enum tls_type_e type = GOT_UNKNOWN;
1813
1814           switch (r_type)
1815             {
1816               case R_ARC_TLS_GD_GOT:
1817                 type = GOT_TLS_GD;
1818                 break;
1819               case R_ARC_TLS_IE_GOT:
1820                 type = GOT_TLS_IE;
1821                 break;
1822               default:
1823                 break;
1824             }
1825
1826           struct got_entry **list = NULL;
1827           if (h != NULL)
1828             list = &(h->got.glist);
1829           else
1830             list = &(local_got_ents[r_symndx]);
1831
1832           if (type != GOT_UNKNOWN && !symbol_has_entry_of_type (*list, type))
1833             {
1834               enum tls_got_entries entries = NONE;
1835               bfd_vma offset =
1836                 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1837
1838               if (type == GOT_TLS_GD)
1839                 {
1840                   bfd_vma ATTRIBUTE_UNUSED notneeded =
1841                     ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1842                   entries = MOD_AND_OFF;
1843                 }
1844
1845               if (entries == NONE)
1846                 entries = OFF;
1847
1848               new_got_entry_to_list (list, type, offset, entries);
1849             }
1850         }
1851     }
1852
1853   return TRUE;
1854 }
1855
1856 #define ELF_DYNAMIC_INTERPRETER  "/sbin/ld-uClibc.so"
1857
1858 static struct plt_version_t *
1859 arc_get_plt_version (struct bfd_link_info *info)
1860 {
1861   int i;
1862
1863   for (i = 0; i < 1; i++)
1864     {
1865       ARC_DEBUG ("%d: size1 = %d, size2 = %d\n", i,
1866                  plt_versions[i].entry_size,
1867                  plt_versions[i].elem_size);
1868     }
1869
1870   if (bfd_get_mach (info->output_bfd) == bfd_mach_arc_arcv2)
1871     {
1872       if (bfd_link_pic (info))
1873         return &(plt_versions[ELF_ARCV2_PIC]);
1874       else
1875         return &(plt_versions[ELF_ARCV2_ABS]);
1876     }
1877   else
1878     {
1879       if (bfd_link_pic (info))
1880         return &(plt_versions[ELF_ARC_PIC]);
1881       else
1882         return &(plt_versions[ELF_ARC_ABS]);
1883     }
1884 }
1885
1886 static bfd_vma
1887 add_symbol_to_plt (struct bfd_link_info *info)
1888 {
1889   struct elf_link_hash_table *htab = elf_hash_table (info);
1890   bfd_vma ret;
1891
1892   struct plt_version_t *plt_data = arc_get_plt_version (info);
1893
1894   /* If this is the first .plt entry, make room for the special first
1895      entry.  */
1896   if (htab->splt->size == 0)
1897     htab->splt->size += plt_data->entry_size;
1898
1899   ret = htab->splt->size;
1900
1901   htab->splt->size += plt_data->elem_size;
1902   ARC_DEBUG ("PLT_SIZE = %d\n", htab->splt->size);
1903
1904   htab->sgotplt->size += 4;
1905   htab->srelplt->size += sizeof (Elf32_External_Rela);
1906
1907   return ret;
1908 }
1909
1910 #define PLT_DO_RELOCS_FOR_ENTRY(ABFD, DS, RELOCS)       \
1911   plt_do_relocs_for_symbol (ABFD, DS, RELOCS, 0, 0)
1912
1913 static void
1914 plt_do_relocs_for_symbol (bfd *abfd,
1915                           struct elf_link_hash_table *htab,
1916                           const struct plt_reloc *reloc,
1917                           bfd_vma plt_offset,
1918                           bfd_vma symbol_got_offset)
1919 {
1920   while (SYM_ONLY (reloc->symbol) != LAST_RELOC)
1921     {
1922       bfd_vma relocation = 0;
1923
1924       switch (SYM_ONLY (reloc->symbol))
1925         {
1926           case SGOT:
1927                 relocation =
1928                     htab->sgotplt->output_section->vma +
1929                     htab->sgotplt->output_offset + symbol_got_offset;
1930                 break;
1931         }
1932       relocation += reloc->addend;
1933
1934       if (IS_RELATIVE (reloc->symbol))
1935         {
1936           bfd_vma reloc_offset = reloc->offset;
1937           reloc_offset -= (IS_INSN_32 (reloc->symbol)) ? 4 : 0;
1938           reloc_offset -= (IS_INSN_24 (reloc->symbol)) ? 2 : 0;
1939
1940           relocation -= htab->splt->output_section->vma
1941                          + htab->splt->output_offset
1942                          + plt_offset + reloc_offset;
1943         }
1944
1945       /* TODO: being ME is not a property of the relocation but of the
1946          section of which is applying the relocation. */
1947       if (IS_MIDDLE_ENDIAN (reloc->symbol) || bfd_big_endian (abfd))
1948         {
1949           relocation =
1950               ((relocation & 0xffff0000) >> 16) |
1951               ((relocation & 0xffff) << 16);
1952         }
1953
1954       switch (reloc->size)
1955         {
1956           case 32:
1957             bfd_put_32 (htab->splt->output_section->owner,
1958                         relocation,
1959                         htab->splt->contents + plt_offset + reloc->offset);
1960             break;
1961         }
1962
1963       reloc = &(reloc[1]); /* Jump to next relocation.  */
1964     }
1965 }
1966
1967 static void
1968 relocate_plt_for_symbol (bfd *output_bfd,
1969                          struct bfd_link_info *info,
1970                          struct elf_link_hash_entry *h)
1971 {
1972   struct plt_version_t *plt_data = arc_get_plt_version (info);
1973   struct elf_link_hash_table *htab = elf_hash_table (info);
1974
1975   bfd_vma plt_index = (h->plt.offset  - plt_data->entry_size)
1976                       / plt_data->elem_size;
1977   bfd_vma got_offset = (plt_index + 3) * 4;
1978
1979   ARC_DEBUG ("arc_info: PLT_OFFSET = 0x%x, PLT_ENTRY_VMA = 0x%x, \
1980 GOT_ENTRY_OFFSET = 0x%x, GOT_ENTRY_VMA = 0x%x, for symbol %s\n",
1981              h->plt.offset,
1982              htab->splt->output_section->vma
1983              + htab->splt->output_offset
1984              + h->plt.offset,
1985              got_offset,
1986              htab->sgotplt->output_section->vma
1987              + htab->sgotplt->output_offset
1988              + got_offset,
1989              h->root.root.string);
1990
1991   memcpy (htab->splt->contents + h->plt.offset,
1992           plt_data->elem,
1993           plt_data->elem_size);
1994   plt_do_relocs_for_symbol (output_bfd, htab,
1995                             plt_data->elem_relocs,
1996                             h->plt.offset,
1997                             got_offset);
1998
1999   /* Fill in the entry in the global offset table.  */
2000   bfd_put_32 (output_bfd,
2001               (bfd_vma) (htab->splt->output_section->vma
2002                          + htab->splt->output_offset),
2003               htab->sgotplt->contents + got_offset);
2004
2005   /* TODO: Fill in the entry in the .rela.plt section.  */
2006   {
2007     Elf_Internal_Rela rel;
2008     bfd_byte *loc;
2009
2010     rel.r_offset = (htab->sgotplt->output_section->vma
2011                     + htab->sgotplt->output_offset
2012                     + got_offset);
2013     rel.r_addend = 0;
2014     rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_JMP_SLOT);
2015
2016     loc = htab->srelplt->contents;
2017     loc += plt_index * sizeof (Elf32_External_Rela); /* relA */
2018     bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2019   }
2020 }
2021
2022 static void
2023 relocate_plt_for_entry (bfd *abfd,
2024                         struct bfd_link_info *info)
2025 {
2026   struct plt_version_t *plt_data = arc_get_plt_version (info);
2027   struct elf_link_hash_table *htab = elf_hash_table (info);
2028
2029   memcpy (htab->splt->contents, plt_data->entry,
2030           plt_data->entry_size);
2031   PLT_DO_RELOCS_FOR_ENTRY (abfd, htab, plt_data->entry_relocs);
2032 }
2033
2034 /* Desc : Adjust a symbol defined by a dynamic object and referenced
2035    by a regular object.  The current definition is in some section of
2036    the dynamic object, but we're not including those sections.  We
2037    have to change the definition to something the rest of the link can
2038    understand.  */
2039
2040 static bfd_boolean
2041 elf_arc_adjust_dynamic_symbol (struct bfd_link_info *info,
2042                               struct elf_link_hash_entry *h)
2043 {
2044   asection *s;
2045   unsigned int power_of_two;
2046   bfd *dynobj = (elf_hash_table (info))->dynobj;
2047   struct elf_link_hash_table *htab = elf_hash_table (info);
2048
2049   if (h->type == STT_FUNC
2050       || h->type == STT_GNU_IFUNC
2051       || h->needs_plt == 1)
2052     {
2053       if (!bfd_link_pic (info) && !h->def_dynamic && !h->ref_dynamic)
2054         {
2055           /* This case can occur if we saw a PLT32 reloc in an input
2056              file, but the symbol was never referred to by a dynamic
2057              object.  In such a case, we don't actually need to build
2058              a procedure linkage table, and we can just do a PC32
2059              reloc instead.  */
2060           BFD_ASSERT (h->needs_plt);
2061           return TRUE;
2062         }
2063
2064       /* Make sure this symbol is output as a dynamic symbol.  */
2065       if (h->dynindx == -1 && !h->forced_local
2066           && !bfd_elf_link_record_dynamic_symbol (info, h))
2067         return FALSE;
2068
2069       if (bfd_link_pic (info)
2070           || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
2071         {
2072           bfd_vma loc = add_symbol_to_plt (info);
2073
2074           if (!bfd_link_pic (info) && !h->def_regular)
2075             {
2076               h->root.u.def.section = htab->splt;
2077               h->root.u.def.value = loc;
2078             }
2079           h->plt.offset = loc;
2080         }
2081       else
2082         {
2083           h->plt.offset = (bfd_vma) -1;
2084           h->needs_plt = 0;
2085         }
2086       return TRUE;
2087     }
2088
2089   /* If this is a weak symbol, and there is a real definition, the
2090      processor independent code will have arranged for us to see the
2091      real definition first, and we can just use the same value.  */
2092   if (h->u.weakdef != NULL)
2093     {
2094       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2095                   || h->u.weakdef->root.type == bfd_link_hash_defweak);
2096       h->root.u.def.section = h->u.weakdef->root.u.def.section;
2097       h->root.u.def.value = h->u.weakdef->root.u.def.value;
2098       return TRUE;
2099     }
2100
2101   /* If there are no non-GOT references, we do not need a copy
2102      relocation.  */
2103   if (!h->non_got_ref)
2104     return TRUE;
2105
2106   /* This is a reference to a symbol defined by a dynamic object which
2107      is not a function.  */
2108
2109   /* If we are creating a shared library, we must presume that the
2110      only references to the symbol are via the global offset table.
2111      For such cases we need not do anything here; the relocations will
2112      be handled correctly by relocate_section.  */
2113   if (bfd_link_pic (info))
2114     return TRUE;
2115
2116   /* We must allocate the symbol in our .dynbss section, which will
2117      become part of the .bss section of the executable.  There will be
2118      an entry for this symbol in the .dynsym section.  The dynamic
2119      object will contain position independent code, so all references
2120      from the dynamic object to this symbol will go through the global
2121      offset table.  The dynamic linker will use the .dynsym entry to
2122      determine the address it must put in the global offset table, so
2123      both the dynamic object and the regular object will refer to the
2124      same memory location for the variable.  */
2125
2126   s = bfd_get_section_by_name (dynobj, ".dynbss");
2127   BFD_ASSERT (s != NULL);
2128
2129   /* We must generate a R_ARC_COPY reloc to tell the dynamic linker to
2130      copy the initial value out of the dynamic object and into the
2131      runtime process image.  We need to remember the offset into the
2132      .rela.bss section we are going to use.  */
2133   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2134     {
2135       asection *srel;
2136
2137       srel = bfd_get_section_by_name (dynobj, ".rela.bss");
2138       BFD_ASSERT (srel != NULL);
2139       srel->size += sizeof (Elf32_External_Rela);
2140       h->needs_copy = 1;
2141     }
2142
2143   /* We need to figure out the alignment required for this symbol.  I
2144      have no idea how ELF linkers handle this.  */
2145   power_of_two = bfd_log2 (h->size);
2146   if (power_of_two > 3)
2147     power_of_two = 3;
2148
2149   /* Apply the required alignment.  */
2150   s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
2151   if (power_of_two > bfd_get_section_alignment (dynobj, s))
2152     {
2153       if (! bfd_set_section_alignment (dynobj, s, power_of_two))
2154         return FALSE;
2155     }
2156
2157   /* Define the symbol as being at this point in the section.  */
2158   h->root.u.def.section = s;
2159   h->root.u.def.value = s->size;
2160
2161   /* Increment the section size to make room for the symbol.  */
2162   s->size += h->size;
2163
2164   return TRUE;
2165 }
2166
2167 /* Function :  elf_arc_finish_dynamic_symbol
2168    Brief    :  Finish up dynamic symbol handling.  We set the
2169              contents of various dynamic sections here.
2170    Args     :  output_bfd :
2171                info       :
2172                h          :
2173                sym        :
2174    Returns  : True/False as the return status.  */
2175
2176 static bfd_boolean
2177 elf_arc_finish_dynamic_symbol (bfd * output_bfd,
2178                                struct bfd_link_info *info,
2179                                struct elf_link_hash_entry *h,
2180                                Elf_Internal_Sym * sym)
2181 {
2182   if (h->plt.offset != (bfd_vma) -1)
2183     {
2184       relocate_plt_for_symbol (output_bfd, info, h);
2185
2186       if (!h->def_regular)
2187         {
2188           /* Mark the symbol as undefined, rather than as defined in
2189              the .plt section.  Leave the value alone.  */
2190           sym->st_shndx = SHN_UNDEF;
2191         }
2192     }
2193
2194   if (h->got.glist != NULL)
2195     {
2196       struct got_entry *list = h->got.glist;
2197
2198       /* Traverse the list of got entries for this symbol.  */
2199       while (list)
2200         {
2201           bfd_vma got_offset = h->got.glist->offset;
2202
2203           if (list->type == GOT_NORMAL
2204               && list->created_dyn_relocation == FALSE)
2205             {
2206               if (bfd_link_pic (info)
2207                   && (info->symbolic || h->dynindx == -1)
2208                   && h->def_regular)
2209                 {
2210                   ADD_RELA (output_bfd, got, got_offset, 0, R_ARC_RELATIVE, 0);
2211                 }
2212               else
2213                 {
2214                   ADD_RELA (output_bfd, got, got_offset, h->dynindx,
2215                           R_ARC_GLOB_DAT, 0);
2216                 }
2217               list->created_dyn_relocation = TRUE;
2218             }
2219           else if (list->existing_entries != NONE)
2220             {
2221               struct elf_link_hash_table *htab = elf_hash_table (info);
2222               enum tls_got_entries e = list->existing_entries;
2223
2224               BFD_ASSERT (list->type != GOT_TLS_GD
2225                           || list->existing_entries == MOD_AND_OFF);
2226
2227               bfd_vma dynindx = h->dynindx == -1 ? 0 : h->dynindx;
2228               if (e == MOD_AND_OFF || e == MOD)
2229                 {
2230                   ADD_RELA (output_bfd, got, got_offset, dynindx,
2231                             R_ARC_TLS_DTPMOD, 0);
2232                   ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2233 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2234                              list->type,
2235                              got_offset,
2236                              htab->sgot->output_section->vma
2237                              + htab->sgot->output_offset + got_offset,
2238                              dynindx, 0);
2239                 }
2240               if (e == MOD_AND_OFF || e == OFF)
2241                 {
2242                   bfd_vma addend = 0;
2243                   if (list->type == GOT_TLS_IE)
2244                     addend = bfd_get_32 (output_bfd,
2245                                          htab->sgot->contents + got_offset);
2246
2247                   ADD_RELA (output_bfd, got,
2248                             got_offset + (e == MOD_AND_OFF ? 4 : 0),
2249                             dynindx,
2250                             (list->type == GOT_TLS_IE ?
2251                              R_ARC_TLS_TPOFF : R_ARC_TLS_DTPOFF),
2252                             addend);
2253
2254                   ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2255 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2256                              list->type,
2257                              got_offset,
2258                              htab->sgot->output_section->vma
2259                              + htab->sgot->output_offset + got_offset,
2260                              dynindx, addend);
2261                 }
2262             }
2263
2264           list = list->next;
2265         }
2266
2267       h->got.glist = NULL;
2268     }
2269
2270   if (h->needs_copy)
2271     {
2272       bfd_vma rel_offset = (h->root.u.def.value
2273                             + h->root.u.def.section->output_section->vma
2274                             + h->root.u.def.section->output_offset);
2275
2276       asection *srelbss =
2277         bfd_get_section_by_name (h->root.u.def.section->owner,
2278                                  ".rela.bss");
2279
2280       bfd_byte * loc = srelbss->contents
2281         + (srelbss->reloc_count * sizeof (Elf32_External_Rela));
2282       srelbss->reloc_count++;
2283
2284       Elf_Internal_Rela rel;
2285       rel.r_addend = 0;
2286       rel.r_offset = rel_offset;
2287       rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_COPY);
2288
2289       bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2290     }
2291
2292   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
2293   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2294       || strcmp (h->root.root.string, "__DYNAMIC") == 0
2295       || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
2296     sym->st_shndx = SHN_ABS;
2297
2298   return TRUE;
2299 }
2300
2301 #define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION, ASSERT)     \
2302   case TAG:                                                     \
2303   if (SYMBOL != NULL)                                           \
2304     {                                                           \
2305       h = elf_link_hash_lookup (elf_hash_table (info),          \
2306                                 SYMBOL, FALSE, FALSE, TRUE);    \
2307     }                                                           \
2308   else if (SECTION != NULL)                                     \
2309     {                                                           \
2310       s = bfd_get_section_by_name (output_bfd, SECTION);        \
2311       BFD_ASSERT (s != NULL || !ASSERT);                        \
2312       do_it = TRUE;                                             \
2313     }                                                           \
2314   break;
2315
2316 /* Function :  elf_arc_finish_dynamic_sections
2317    Brief    :  Finish up the dynamic sections handling.
2318    Args     :  output_bfd :
2319                info       :
2320                h          :
2321                sym        :
2322    Returns  : True/False as the return status.  */
2323
2324 static bfd_boolean
2325 elf_arc_finish_dynamic_sections (bfd * output_bfd,
2326                                  struct bfd_link_info *info)
2327 {
2328   struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
2329   struct elf_link_hash_table *htab = elf_hash_table (info);
2330   bfd *dynobj = (elf_hash_table (info))->dynobj;
2331
2332   if (ds.sdyn)
2333     {
2334       Elf32_External_Dyn *dyncon, *dynconend;
2335
2336       dyncon = (Elf32_External_Dyn *) ds.sdyn->contents;
2337       dynconend =
2338         (Elf32_External_Dyn *) (ds.sdyn->contents + ds.sdyn->size);
2339       for (; dyncon < dynconend; dyncon++)
2340         {
2341           Elf_Internal_Dyn internal_dyn;
2342           bfd_boolean     do_it = FALSE;
2343
2344           struct elf_link_hash_entry *h = NULL;
2345           asection       *s = NULL;
2346
2347           bfd_elf32_swap_dyn_in (dynobj, dyncon, &internal_dyn);
2348
2349           switch (internal_dyn.d_tag)
2350             {
2351               GET_SYMBOL_OR_SECTION (DT_INIT, "_init", NULL, TRUE)
2352               GET_SYMBOL_OR_SECTION (DT_FINI, "_fini", NULL, TRUE)
2353               GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt", TRUE)
2354               GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt", TRUE)
2355               GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt", TRUE)
2356               GET_SYMBOL_OR_SECTION (DT_RELASZ, NULL, ".rela.plt", FALSE)
2357               GET_SYMBOL_OR_SECTION (DT_VERSYM, NULL, ".gnu.version", TRUE)
2358               GET_SYMBOL_OR_SECTION (DT_VERDEF, NULL, ".gnu.version_d", TRUE)
2359               GET_SYMBOL_OR_SECTION (DT_VERNEED, NULL, ".gnu.version_r", TRUE)
2360               default:
2361                 break;
2362             }
2363
2364           /* In case the dynamic symbols should be updated with a symbol.  */
2365           if (h != NULL
2366               && (h->root.type == bfd_link_hash_defined
2367                   || h->root.type == bfd_link_hash_defweak))
2368             {
2369               asection       *asec_ptr;
2370
2371               internal_dyn.d_un.d_val = h->root.u.def.value;
2372               asec_ptr = h->root.u.def.section;
2373               if (asec_ptr->output_section != NULL)
2374                 {
2375                   internal_dyn.d_un.d_val +=
2376                     (asec_ptr->output_section->vma +
2377                      asec_ptr->output_offset);
2378                 }
2379               else
2380                 {
2381                   /* The symbol is imported from another shared
2382                      library and does not apply to this one.  */
2383                   internal_dyn.d_un.d_val = 0;
2384                 }
2385               do_it = TRUE;
2386             }
2387           else if (s != NULL) /* With a section information.  */
2388             {
2389               switch (internal_dyn.d_tag)
2390                 {
2391                   case DT_PLTGOT:
2392                   case DT_JMPREL:
2393                   case DT_VERSYM:
2394                   case DT_VERDEF:
2395                   case DT_VERNEED:
2396                     internal_dyn.d_un.d_ptr = s->vma;
2397                     do_it = TRUE;
2398                     break;
2399
2400                   case DT_PLTRELSZ:
2401                     internal_dyn.d_un.d_val = s->size;
2402                     do_it = TRUE;
2403                     break;
2404
2405                   case DT_RELASZ:
2406                     if (s != NULL)
2407                       internal_dyn.d_un.d_val -= s->size;
2408                     do_it = TRUE;
2409                     break;
2410
2411                   default:
2412                     break;
2413                 }
2414             }
2415
2416           if (do_it == TRUE)
2417             bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon);
2418         }
2419
2420       if (htab->splt->size > 0)
2421         {
2422           relocate_plt_for_entry (output_bfd, info);
2423         }
2424
2425       /* TODO: Validate this.  */
2426       elf_section_data (htab->srelplt->output_section)->this_hdr.sh_entsize
2427         = 0xc;
2428     }
2429
2430   /* Fill in the first three entries in the global offset table.  */
2431   if (htab->sgot)
2432     {
2433       if (htab->sgot->size > 0 || htab->sgotplt->size > 0)
2434         {
2435           if (ds.sdyn == NULL)
2436             bfd_put_32 (output_bfd, (bfd_vma) 0,
2437                         htab->sgotplt->contents);
2438           else
2439             bfd_put_32 (output_bfd,
2440                         ds.sdyn->output_section->vma + ds.sdyn->output_offset,
2441                         htab->sgotplt->contents);
2442           bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 4);
2443           bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 8);
2444         }
2445     }
2446
2447   return TRUE;
2448 }
2449
2450 #define ADD_DYNAMIC_SYMBOL(NAME, TAG)                                   \
2451   h =  elf_link_hash_lookup (elf_hash_table (info),                     \
2452                              NAME, FALSE, FALSE, FALSE);                \
2453   if ((h != NULL && (h->ref_regular || h->def_regular)))                \
2454     if (! _bfd_elf_add_dynamic_entry (info, TAG, 0))                    \
2455       return FALSE;
2456
2457 /* Set the sizes of the dynamic sections.  */
2458 static bfd_boolean
2459 elf_arc_size_dynamic_sections (bfd * output_bfd,
2460                                struct bfd_link_info *info)
2461 {
2462   bfd *    dynobj;
2463   asection *      s;
2464   bfd_boolean     relocs_exist = FALSE;
2465   bfd_boolean     reltext_exist = FALSE;
2466   struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
2467   struct elf_link_hash_table *htab = elf_hash_table (info);
2468
2469   dynobj = (elf_hash_table (info))->dynobj;
2470   BFD_ASSERT (dynobj != NULL);
2471
2472   if ((elf_hash_table (info))->dynamic_sections_created)
2473     {
2474       struct elf_link_hash_entry *h;
2475
2476       /* Set the contents of the .interp section to the
2477          interpreter.  */
2478       if (!bfd_link_pic (info))
2479         {
2480           s = bfd_get_section_by_name (dynobj, ".interp");
2481           BFD_ASSERT (s != NULL);
2482           s->size = sizeof (ELF_DYNAMIC_INTERPRETER);
2483           s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2484         }
2485
2486       /* Add some entries to the .dynamic section.  We fill in some of
2487          the values later, in elf_bfd_final_link, but we must add the
2488          entries now so that we know the final size of the .dynamic
2489          section.  Checking if the .init section is present.  We also
2490          create DT_INIT and DT_FINI entries if the init_str has been
2491          changed by the user.  */
2492       ADD_DYNAMIC_SYMBOL ("init", DT_INIT);
2493       ADD_DYNAMIC_SYMBOL ("fini", DT_FINI);
2494     }
2495   else
2496     {
2497       /* We may have created entries in the .rela.got section.
2498          However, if we are not creating the dynamic sections, we will
2499          not actually use these entries.  Reset the size of .rela.got,
2500          which will cause it to get stripped from the output file
2501          below.  */
2502       if (htab->srelgot != NULL)
2503         htab->srelgot->size = 0;
2504     }
2505
2506   if (htab->splt != NULL && htab->splt->size == 0)
2507     htab->splt->flags |= SEC_EXCLUDE;
2508   for (s = dynobj->sections; s != NULL; s = s->next)
2509     {
2510       if ((s->flags & SEC_LINKER_CREATED) == 0)
2511         continue;
2512
2513       if (strncmp (s->name, ".rela", 5) == 0)
2514         {
2515           if (s->size == 0)
2516             {
2517               s->flags |= SEC_EXCLUDE;
2518             }
2519           else
2520             {
2521               if (strcmp (s->name, ".rela.plt") != 0)
2522                 {
2523                   const char *outname =
2524                     bfd_get_section_name (output_bfd,
2525                                           htab->srelplt->output_section);
2526
2527                   asection *target = bfd_get_section_by_name (output_bfd,
2528                                                               outname + 4);
2529
2530                   relocs_exist = TRUE;
2531                   if (target != NULL && target->size != 0
2532                       && (target->flags & SEC_READONLY) != 0
2533                       && (target->flags & SEC_ALLOC) != 0)
2534                     reltext_exist = TRUE;
2535                 }
2536             }
2537
2538           /* We use the reloc_count field as a counter if we need to
2539              copy relocs into the output file.  */
2540           s->reloc_count = 0;
2541         }
2542
2543       if (strcmp (s->name, ".dynamic") == 0)
2544         continue;
2545
2546       if (s->size != 0)
2547         s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2548
2549       if (s->contents == NULL && s->size != 0)
2550         return FALSE;
2551     }
2552
2553   if (ds.sdyn)
2554     {
2555       /* TODO: Check if this is needed.  */
2556       if (!bfd_link_pic (info))
2557         if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
2558                 return FALSE;
2559
2560       if (htab->splt && (htab->splt->flags & SEC_EXCLUDE) == 0)
2561         if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
2562             || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2563             || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2564             || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0)
2565            )
2566           return FALSE;
2567
2568       if (relocs_exist == TRUE)
2569         if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
2570             || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
2571             || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
2572                                             sizeof (Elf32_External_Rela))
2573            )
2574           return FALSE;
2575
2576       if (reltext_exist == TRUE)
2577         if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
2578           return FALSE;
2579     }
2580
2581   return TRUE;
2582 }
2583
2584 const struct elf_size_info arc_elf32_size_info =
2585 {
2586   sizeof (Elf32_External_Ehdr),
2587   sizeof (Elf32_External_Phdr),
2588   sizeof (Elf32_External_Shdr),
2589   sizeof (Elf32_External_Rel),
2590   sizeof (Elf32_External_Rela),
2591   sizeof (Elf32_External_Sym),
2592   sizeof (Elf32_External_Dyn),
2593   sizeof (Elf_External_Note),
2594   4,
2595   1,
2596   32, 2,
2597   ELFCLASS32, EV_CURRENT,
2598   bfd_elf32_write_out_phdrs,
2599   bfd_elf32_write_shdrs_and_ehdr,
2600   bfd_elf32_checksum_contents,
2601   bfd_elf32_write_relocs,
2602   bfd_elf32_swap_symbol_in,
2603   bfd_elf32_swap_symbol_out,
2604   bfd_elf32_slurp_reloc_table,
2605   bfd_elf32_slurp_symbol_table,
2606   bfd_elf32_swap_dyn_in,
2607   bfd_elf32_swap_dyn_out,
2608   bfd_elf32_swap_reloc_in,
2609   bfd_elf32_swap_reloc_out,
2610   bfd_elf32_swap_reloca_in,
2611   bfd_elf32_swap_reloca_out
2612 };
2613
2614 #define elf_backend_size_info           arc_elf32_size_info
2615
2616 static struct bfd_link_hash_table *
2617 arc_elf_link_hash_table_create (bfd *abfd)
2618 {
2619   struct elf_link_hash_table *htab;
2620
2621   htab = bfd_zmalloc (sizeof (*htab));
2622   if (htab == NULL)
2623     return NULL;
2624
2625   if (!_bfd_elf_link_hash_table_init (htab, abfd,
2626                                       _bfd_elf_link_hash_newfunc,
2627                                       sizeof (struct elf_link_hash_entry),
2628                                       GENERIC_ELF_DATA))
2629     {
2630       free (htab);
2631       return NULL;
2632     }
2633
2634   htab->init_got_refcount.refcount = 0;
2635   htab->init_got_refcount.glist = NULL;
2636   htab->init_got_offset.offset = 0;
2637   htab->init_got_offset.glist = NULL;
2638   return (struct bfd_link_hash_table *) htab;
2639 }
2640
2641 /* Hook called by the linker routine which adds symbols from an object
2642    file.  */
2643
2644 static bfd_boolean
2645 elf_arc_add_symbol_hook (bfd * abfd,
2646                          struct bfd_link_info * info,
2647                          Elf_Internal_Sym * sym,
2648                          const char ** namep ATTRIBUTE_UNUSED,
2649                          flagword * flagsp ATTRIBUTE_UNUSED,
2650                          asection ** secp ATTRIBUTE_UNUSED,
2651                          bfd_vma * valp ATTRIBUTE_UNUSED)
2652 {
2653   if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
2654        || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
2655       && (abfd->flags & DYNAMIC) == 0
2656       && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
2657     elf_tdata (info->output_bfd)->has_gnu_symbols = elf_gnu_symbol_any;
2658
2659   return TRUE;
2660 }
2661
2662 #define TARGET_LITTLE_SYM   arc_elf32_le_vec
2663 #define TARGET_LITTLE_NAME  "elf32-littlearc"
2664 #define TARGET_BIG_SYM      arc_elf32_be_vec
2665 #define TARGET_BIG_NAME     "elf32-bigarc"
2666 #define ELF_ARCH            bfd_arch_arc
2667 #define ELF_MACHINE_CODE    EM_ARC_COMPACT
2668 #define ELF_MACHINE_ALT1    EM_ARC_COMPACT2
2669 #define ELF_MAXPAGESIZE     0x2000
2670
2671 #define bfd_elf32_bfd_link_hash_table_create    arc_elf_link_hash_table_create
2672
2673 #define bfd_elf32_bfd_merge_private_bfd_data    arc_elf_merge_private_bfd_data
2674 #define bfd_elf32_bfd_reloc_type_lookup         arc_elf32_bfd_reloc_type_lookup
2675 #define bfd_elf32_bfd_set_private_flags         arc_elf_set_private_flags
2676 #define bfd_elf32_bfd_print_private_bfd_data    arc_elf_print_private_bfd_data
2677 #define bfd_elf32_bfd_copy_private_bfd_data     arc_elf_copy_private_bfd_data
2678
2679 #define elf_info_to_howto_rel                arc_info_to_howto_rel
2680 #define elf_backend_object_p                 arc_elf_object_p
2681 #define elf_backend_final_write_processing   arc_elf_final_write_processing
2682
2683 #define elf_backend_relocate_section         elf_arc_relocate_section
2684 #define elf_backend_check_relocs             elf_arc_check_relocs
2685 #define elf_backend_create_dynamic_sections  _bfd_elf_create_dynamic_sections
2686
2687 #define elf_backend_adjust_dynamic_symbol    elf_arc_adjust_dynamic_symbol
2688 #define elf_backend_finish_dynamic_symbol    elf_arc_finish_dynamic_symbol
2689
2690 #define elf_backend_finish_dynamic_sections  elf_arc_finish_dynamic_sections
2691 #define elf_backend_size_dynamic_sections    elf_arc_size_dynamic_sections
2692 #define elf_backend_add_symbol_hook          elf_arc_add_symbol_hook
2693
2694 #define elf_backend_can_gc_sections     1
2695 #define elf_backend_want_got_plt        1
2696 #define elf_backend_plt_readonly        1
2697 #define elf_backend_rela_plts_and_copies_p 1
2698 #define elf_backend_want_plt_sym        0
2699 #define elf_backend_got_header_size     12
2700
2701 #define elf_backend_may_use_rel_p       0
2702 #define elf_backend_may_use_rela_p      1
2703 #define elf_backend_default_use_rela_p  1
2704
2705 #include "elf32-target.h"