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