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