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