[ARC] Fix to pass ld-elf-ehdr_start-shared.
[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   NONE = 0,
131   MOD,
132   OFF,
133   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 == 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 == 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, 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, 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 = 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 = MOD_AND_OFF;
1859                 }
1860
1861               if (entries == NONE)
1862                 entries = 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   memcpy (htab->splt->contents + h->plt.offset,
2008           plt_data->elem,
2009           plt_data->elem_size);
2010   plt_do_relocs_for_symbol (output_bfd, htab,
2011                             plt_data->elem_relocs,
2012                             h->plt.offset,
2013                             got_offset);
2014
2015   /* Fill in the entry in the global offset table.  */
2016   bfd_put_32 (output_bfd,
2017               (bfd_vma) (htab->splt->output_section->vma
2018                          + htab->splt->output_offset),
2019               htab->sgotplt->contents + got_offset);
2020
2021   /* TODO: Fill in the entry in the .rela.plt section.  */
2022   {
2023     Elf_Internal_Rela rel;
2024     bfd_byte *loc;
2025
2026     rel.r_offset = (htab->sgotplt->output_section->vma
2027                     + htab->sgotplt->output_offset
2028                     + got_offset);
2029     rel.r_addend = 0;
2030
2031     BFD_ASSERT (h->dynindx != -1);
2032     rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_JMP_SLOT);
2033
2034     loc = htab->srelplt->contents;
2035     loc += plt_index * sizeof (Elf32_External_Rela); /* relA */
2036     bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2037   }
2038 }
2039
2040 static void
2041 relocate_plt_for_entry (bfd *abfd,
2042                         struct bfd_link_info *info)
2043 {
2044   struct plt_version_t *plt_data = arc_get_plt_version (info);
2045   struct elf_link_hash_table *htab = elf_hash_table (info);
2046
2047   memcpy (htab->splt->contents, plt_data->entry,
2048           plt_data->entry_size);
2049   PLT_DO_RELOCS_FOR_ENTRY (abfd, htab, plt_data->entry_relocs);
2050 }
2051
2052 /* Desc : Adjust a symbol defined by a dynamic object and referenced
2053    by a regular object.  The current definition is in some section of
2054    the dynamic object, but we're not including those sections.  We
2055    have to change the definition to something the rest of the link can
2056    understand.  */
2057
2058 static bfd_boolean
2059 elf_arc_adjust_dynamic_symbol (struct bfd_link_info *info,
2060                               struct elf_link_hash_entry *h)
2061 {
2062   asection *s;
2063   unsigned int power_of_two;
2064   bfd *dynobj = (elf_hash_table (info))->dynobj;
2065   struct elf_link_hash_table *htab = elf_hash_table (info);
2066
2067   if (h->type == STT_FUNC
2068       || h->type == STT_GNU_IFUNC
2069       || h->needs_plt == 1)
2070     {
2071       if (!bfd_link_pic (info) && !h->def_dynamic && !h->ref_dynamic)
2072         {
2073           /* This case can occur if we saw a PLT32 reloc in an input
2074              file, but the symbol was never referred to by a dynamic
2075              object.  In such a case, we don't actually need to build
2076              a procedure linkage table, and we can just do a PC32
2077              reloc instead.  */
2078           BFD_ASSERT (h->needs_plt);
2079           return TRUE;
2080         }
2081
2082       /* Make sure this symbol is output as a dynamic symbol.  */
2083       if (h->dynindx == -1 && !h->forced_local
2084           && !bfd_elf_link_record_dynamic_symbol (info, h))
2085         return FALSE;
2086
2087       if (bfd_link_pic (info)
2088           || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
2089         {
2090           bfd_vma loc = add_symbol_to_plt (info);
2091
2092           if (!bfd_link_pic (info) && !h->def_regular)
2093             {
2094               h->root.u.def.section = htab->splt;
2095               h->root.u.def.value = loc;
2096             }
2097           h->plt.offset = loc;
2098         }
2099       else
2100         {
2101           h->plt.offset = (bfd_vma) -1;
2102           h->needs_plt = 0;
2103         }
2104       return TRUE;
2105     }
2106
2107   /* If this is a weak symbol, and there is a real definition, the
2108      processor independent code will have arranged for us to see the
2109      real definition first, and we can just use the same value.  */
2110   if (h->u.weakdef != NULL)
2111     {
2112       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2113                   || h->u.weakdef->root.type == bfd_link_hash_defweak);
2114       h->root.u.def.section = h->u.weakdef->root.u.def.section;
2115       h->root.u.def.value = h->u.weakdef->root.u.def.value;
2116       return TRUE;
2117     }
2118
2119   /* If there are no non-GOT references, we do not need a copy
2120      relocation.  */
2121   if (!h->non_got_ref)
2122     return TRUE;
2123
2124   /* This is a reference to a symbol defined by a dynamic object which
2125      is not a function.  */
2126
2127   /* If we are creating a shared library, we must presume that the
2128      only references to the symbol are via the global offset table.
2129      For such cases we need not do anything here; the relocations will
2130      be handled correctly by relocate_section.  */
2131   if (bfd_link_pic (info))
2132     return TRUE;
2133
2134   /* We must allocate the symbol in our .dynbss section, which will
2135      become part of the .bss section of the executable.  There will be
2136      an entry for this symbol in the .dynsym section.  The dynamic
2137      object will contain position independent code, so all references
2138      from the dynamic object to this symbol will go through the global
2139      offset table.  The dynamic linker will use the .dynsym entry to
2140      determine the address it must put in the global offset table, so
2141      both the dynamic object and the regular object will refer to the
2142      same memory location for the variable.  */
2143
2144   s = bfd_get_section_by_name (dynobj, ".dynbss");
2145   BFD_ASSERT (s != NULL);
2146
2147   /* We must generate a R_ARC_COPY reloc to tell the dynamic linker to
2148      copy the initial value out of the dynamic object and into the
2149      runtime process image.  We need to remember the offset into the
2150      .rela.bss section we are going to use.  */
2151   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2152     {
2153       asection *srel;
2154
2155       srel = bfd_get_section_by_name (dynobj, ".rela.bss");
2156       BFD_ASSERT (srel != NULL);
2157       srel->size += sizeof (Elf32_External_Rela);
2158       h->needs_copy = 1;
2159     }
2160
2161   /* We need to figure out the alignment required for this symbol.  I
2162      have no idea how ELF linkers handle this.  */
2163   power_of_two = bfd_log2 (h->size);
2164   if (power_of_two > 3)
2165     power_of_two = 3;
2166
2167   /* Apply the required alignment.  */
2168   s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
2169   if (power_of_two > bfd_get_section_alignment (dynobj, s))
2170     {
2171       if (! bfd_set_section_alignment (dynobj, s, power_of_two))
2172         return FALSE;
2173     }
2174
2175   /* Define the symbol as being at this point in the section.  */
2176   h->root.u.def.section = s;
2177   h->root.u.def.value = s->size;
2178
2179   /* Increment the section size to make room for the symbol.  */
2180   s->size += h->size;
2181
2182   return TRUE;
2183 }
2184
2185 /* Function :  elf_arc_finish_dynamic_symbol
2186    Brief    :  Finish up dynamic symbol handling.  We set the
2187              contents of various dynamic sections here.
2188    Args     :  output_bfd :
2189                info       :
2190                h          :
2191                sym        :
2192    Returns  : True/False as the return status.  */
2193
2194 static bfd_boolean
2195 elf_arc_finish_dynamic_symbol (bfd * output_bfd,
2196                                struct bfd_link_info *info,
2197                                struct elf_link_hash_entry *h,
2198                                Elf_Internal_Sym * sym)
2199 {
2200   if (h->plt.offset != (bfd_vma) -1)
2201     {
2202       relocate_plt_for_symbol (output_bfd, info, h);
2203
2204       if (!h->def_regular)
2205         {
2206           /* Mark the symbol as undefined, rather than as defined in
2207              the .plt section.  Leave the value alone.  */
2208           sym->st_shndx = SHN_UNDEF;
2209         }
2210     }
2211
2212   if (h->got.glist != NULL)
2213     {
2214       struct got_entry *list = h->got.glist;
2215
2216       /* Traverse the list of got entries for this symbol.  */
2217       while (list)
2218         {
2219           bfd_vma got_offset = h->got.glist->offset;
2220
2221           if (list->type == GOT_NORMAL
2222               && list->created_dyn_relocation == FALSE)
2223             {
2224               if (bfd_link_pic (info)
2225                   && (info->symbolic || h->dynindx == -1)
2226                   && h->def_regular)
2227                 {
2228                   ADD_RELA (output_bfd, got, got_offset, 0, R_ARC_RELATIVE, 0);
2229                 }
2230               /* Do not fully understand the side effects of this condition.
2231                  The relocation space might still being reserved.  Perhaps
2232                  I should clear its value.  */
2233               else if (h->dynindx != -1)
2234                 {
2235                   ADD_RELA (output_bfd, got, got_offset, h->dynindx,
2236                           R_ARC_GLOB_DAT, 0);
2237                 }
2238               list->created_dyn_relocation = TRUE;
2239             }
2240           else if (list->existing_entries != NONE)
2241             {
2242               struct elf_link_hash_table *htab = elf_hash_table (info);
2243               enum tls_got_entries e = list->existing_entries;
2244
2245               BFD_ASSERT (list->type != GOT_TLS_GD
2246                           || list->existing_entries == MOD_AND_OFF);
2247
2248               bfd_vma dynindx = h->dynindx == -1 ? 0 : h->dynindx;
2249               if (e == MOD_AND_OFF || e == MOD)
2250                 {
2251                   ADD_RELA (output_bfd, got, got_offset, dynindx,
2252                             R_ARC_TLS_DTPMOD, 0);
2253                   ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2254 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2255                              list->type,
2256                              got_offset,
2257                              htab->sgot->output_section->vma
2258                              + htab->sgot->output_offset + got_offset,
2259                              dynindx, 0);
2260                 }
2261               if (e == MOD_AND_OFF || e == OFF)
2262                 {
2263                   bfd_vma addend = 0;
2264                   if (list->type == GOT_TLS_IE)
2265                     addend = bfd_get_32 (output_bfd,
2266                                          htab->sgot->contents + got_offset);
2267
2268                   ADD_RELA (output_bfd, got,
2269                             got_offset + (e == MOD_AND_OFF ? 4 : 0),
2270                             dynindx,
2271                             (list->type == GOT_TLS_IE ?
2272                              R_ARC_TLS_TPOFF : R_ARC_TLS_DTPOFF),
2273                             addend);
2274
2275                   ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2276 GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2277                              list->type,
2278                              got_offset,
2279                              htab->sgot->output_section->vma
2280                              + htab->sgot->output_offset + got_offset,
2281                              dynindx, addend);
2282                 }
2283             }
2284
2285           list = list->next;
2286         }
2287
2288       h->got.glist = NULL;
2289     }
2290
2291   if (h->needs_copy)
2292     {
2293       bfd_vma rel_offset = (h->root.u.def.value
2294                             + h->root.u.def.section->output_section->vma
2295                             + h->root.u.def.section->output_offset);
2296
2297       asection *srelbss =
2298         bfd_get_section_by_name (h->root.u.def.section->owner,
2299                                  ".rela.bss");
2300
2301       bfd_byte * loc = srelbss->contents
2302         + (srelbss->reloc_count * sizeof (Elf32_External_Rela));
2303       srelbss->reloc_count++;
2304
2305       Elf_Internal_Rela rel;
2306       rel.r_addend = 0;
2307       rel.r_offset = rel_offset;
2308
2309       BFD_ASSERT (h->dynindx != -1);
2310       rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_COPY);
2311
2312       bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
2313     }
2314
2315   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
2316   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2317       || strcmp (h->root.root.string, "__DYNAMIC") == 0
2318       || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
2319     sym->st_shndx = SHN_ABS;
2320
2321   return TRUE;
2322 }
2323
2324 #define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION, ASSERT)     \
2325   case TAG:                                                     \
2326   if (SYMBOL != NULL)                                           \
2327     {                                                           \
2328       h = elf_link_hash_lookup (elf_hash_table (info),          \
2329                                 SYMBOL, FALSE, FALSE, TRUE);    \
2330     }                                                           \
2331   else if (SECTION != NULL)                                     \
2332     {                                                           \
2333       s = bfd_get_section_by_name (output_bfd, SECTION);        \
2334       BFD_ASSERT (s != NULL || !ASSERT);                        \
2335       do_it = TRUE;                                             \
2336     }                                                           \
2337   break;
2338
2339 /* Function :  elf_arc_finish_dynamic_sections
2340    Brief    :  Finish up the dynamic sections handling.
2341    Args     :  output_bfd :
2342                info       :
2343                h          :
2344                sym        :
2345    Returns  : True/False as the return status.  */
2346
2347 static bfd_boolean
2348 elf_arc_finish_dynamic_sections (bfd * output_bfd,
2349                                  struct bfd_link_info *info)
2350 {
2351   struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
2352   struct elf_link_hash_table *htab = elf_hash_table (info);
2353   bfd *dynobj = (elf_hash_table (info))->dynobj;
2354
2355   if (ds.sdyn)
2356     {
2357       Elf32_External_Dyn *dyncon, *dynconend;
2358
2359       dyncon = (Elf32_External_Dyn *) ds.sdyn->contents;
2360       dynconend =
2361         (Elf32_External_Dyn *) (ds.sdyn->contents + ds.sdyn->size);
2362       for (; dyncon < dynconend; dyncon++)
2363         {
2364           Elf_Internal_Dyn internal_dyn;
2365           bfd_boolean     do_it = FALSE;
2366
2367           struct elf_link_hash_entry *h = NULL;
2368           asection       *s = NULL;
2369
2370           bfd_elf32_swap_dyn_in (dynobj, dyncon, &internal_dyn);
2371
2372           switch (internal_dyn.d_tag)
2373             {
2374               GET_SYMBOL_OR_SECTION (DT_INIT, "_init", NULL, TRUE)
2375               GET_SYMBOL_OR_SECTION (DT_FINI, "_fini", NULL, TRUE)
2376               GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt", TRUE)
2377               GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt", TRUE)
2378               GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt", TRUE)
2379               GET_SYMBOL_OR_SECTION (DT_RELASZ, NULL, ".rela.plt", FALSE)
2380               GET_SYMBOL_OR_SECTION (DT_VERSYM, NULL, ".gnu.version", TRUE)
2381               GET_SYMBOL_OR_SECTION (DT_VERDEF, NULL, ".gnu.version_d", TRUE)
2382               GET_SYMBOL_OR_SECTION (DT_VERNEED, NULL, ".gnu.version_r", TRUE)
2383               default:
2384                 break;
2385             }
2386
2387           /* In case the dynamic symbols should be updated with a symbol.  */
2388           if (h != NULL
2389               && (h->root.type == bfd_link_hash_defined
2390                   || h->root.type == bfd_link_hash_defweak))
2391             {
2392               asection       *asec_ptr;
2393
2394               internal_dyn.d_un.d_val = h->root.u.def.value;
2395               asec_ptr = h->root.u.def.section;
2396               if (asec_ptr->output_section != NULL)
2397                 {
2398                   internal_dyn.d_un.d_val +=
2399                     (asec_ptr->output_section->vma +
2400                      asec_ptr->output_offset);
2401                 }
2402               else
2403                 {
2404                   /* The symbol is imported from another shared
2405                      library and does not apply to this one.  */
2406                   internal_dyn.d_un.d_val = 0;
2407                 }
2408               do_it = TRUE;
2409             }
2410           else if (s != NULL) /* With a section information.  */
2411             {
2412               switch (internal_dyn.d_tag)
2413                 {
2414                   case DT_PLTGOT:
2415                   case DT_JMPREL:
2416                   case DT_VERSYM:
2417                   case DT_VERDEF:
2418                   case DT_VERNEED:
2419                     internal_dyn.d_un.d_ptr = s->vma;
2420                     do_it = TRUE;
2421                     break;
2422
2423                   case DT_PLTRELSZ:
2424                     internal_dyn.d_un.d_val = s->size;
2425                     do_it = TRUE;
2426                     break;
2427
2428                   case DT_RELASZ:
2429                     if (s != NULL)
2430                       internal_dyn.d_un.d_val -= s->size;
2431                     do_it = TRUE;
2432                     break;
2433
2434                   default:
2435                     break;
2436                 }
2437             }
2438
2439           if (do_it == TRUE)
2440             bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon);
2441         }
2442
2443       if (htab->splt->size > 0)
2444         {
2445           relocate_plt_for_entry (output_bfd, info);
2446         }
2447
2448       /* TODO: Validate this.  */
2449       elf_section_data (htab->srelplt->output_section)->this_hdr.sh_entsize
2450         = 0xc;
2451     }
2452
2453   /* Fill in the first three entries in the global offset table.  */
2454   if (htab->sgot)
2455     {
2456       if (htab->sgot->size > 0 || htab->sgotplt->size > 0)
2457         {
2458           if (ds.sdyn == NULL)
2459             bfd_put_32 (output_bfd, (bfd_vma) 0,
2460                         htab->sgotplt->contents);
2461           else
2462             bfd_put_32 (output_bfd,
2463                         ds.sdyn->output_section->vma + ds.sdyn->output_offset,
2464                         htab->sgotplt->contents);
2465           bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 4);
2466           bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 8);
2467         }
2468     }
2469
2470   return TRUE;
2471 }
2472
2473 #define ADD_DYNAMIC_SYMBOL(NAME, TAG)                                   \
2474   h =  elf_link_hash_lookup (elf_hash_table (info),                     \
2475                              NAME, FALSE, FALSE, FALSE);                \
2476   if ((h != NULL && (h->ref_regular || h->def_regular)))                \
2477     if (! _bfd_elf_add_dynamic_entry (info, TAG, 0))                    \
2478       return FALSE;
2479
2480 /* Set the sizes of the dynamic sections.  */
2481 static bfd_boolean
2482 elf_arc_size_dynamic_sections (bfd * output_bfd,
2483                                struct bfd_link_info *info)
2484 {
2485   bfd *    dynobj;
2486   asection *      s;
2487   bfd_boolean     relocs_exist = FALSE;
2488   bfd_boolean     reltext_exist = FALSE;
2489   struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
2490   struct elf_link_hash_table *htab = elf_hash_table (info);
2491
2492   dynobj = (elf_hash_table (info))->dynobj;
2493   BFD_ASSERT (dynobj != NULL);
2494
2495   if ((elf_hash_table (info))->dynamic_sections_created)
2496     {
2497       struct elf_link_hash_entry *h;
2498
2499       /* Set the contents of the .interp section to the
2500          interpreter.  */
2501       if (!bfd_link_pic (info))
2502         {
2503           s = bfd_get_section_by_name (dynobj, ".interp");
2504           BFD_ASSERT (s != NULL);
2505           s->size = sizeof (ELF_DYNAMIC_INTERPRETER);
2506           s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2507         }
2508
2509       /* Add some entries to the .dynamic section.  We fill in some of
2510          the values later, in elf_bfd_final_link, but we must add the
2511          entries now so that we know the final size of the .dynamic
2512          section.  Checking if the .init section is present.  We also
2513          create DT_INIT and DT_FINI entries if the init_str has been
2514          changed by the user.  */
2515       ADD_DYNAMIC_SYMBOL ("init", DT_INIT);
2516       ADD_DYNAMIC_SYMBOL ("fini", DT_FINI);
2517     }
2518   else
2519     {
2520       /* We may have created entries in the .rela.got section.
2521          However, if we are not creating the dynamic sections, we will
2522          not actually use these entries.  Reset the size of .rela.got,
2523          which will cause it to get stripped from the output file
2524          below.  */
2525       if (htab->srelgot != NULL)
2526         htab->srelgot->size = 0;
2527     }
2528
2529   if (htab->splt != NULL && htab->splt->size == 0)
2530     htab->splt->flags |= SEC_EXCLUDE;
2531   for (s = dynobj->sections; s != NULL; s = s->next)
2532     {
2533       if ((s->flags & SEC_LINKER_CREATED) == 0)
2534         continue;
2535
2536       if (strncmp (s->name, ".rela", 5) == 0)
2537         {
2538           if (s->size == 0)
2539             {
2540               s->flags |= SEC_EXCLUDE;
2541             }
2542           else
2543             {
2544               if (strcmp (s->name, ".rela.plt") != 0)
2545                 {
2546                   const char *outname =
2547                     bfd_get_section_name (output_bfd,
2548                                           htab->srelplt->output_section);
2549
2550                   asection *target = bfd_get_section_by_name (output_bfd,
2551                                                               outname + 4);
2552
2553                   relocs_exist = TRUE;
2554                   if (target != NULL && target->size != 0
2555                       && (target->flags & SEC_READONLY) != 0
2556                       && (target->flags & SEC_ALLOC) != 0)
2557                     reltext_exist = TRUE;
2558                 }
2559             }
2560
2561           /* We use the reloc_count field as a counter if we need to
2562              copy relocs into the output file.  */
2563           s->reloc_count = 0;
2564         }
2565
2566       if (strcmp (s->name, ".dynamic") == 0)
2567         continue;
2568
2569       if (s->size != 0)
2570         s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2571
2572       if (s->contents == NULL && s->size != 0)
2573         return FALSE;
2574     }
2575
2576   if (ds.sdyn)
2577     {
2578       /* TODO: Check if this is needed.  */
2579       if (!bfd_link_pic (info))
2580         if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
2581                 return FALSE;
2582
2583       if (htab->splt && (htab->splt->flags & SEC_EXCLUDE) == 0)
2584         if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
2585             || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2586             || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2587             || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0)
2588            )
2589           return FALSE;
2590
2591       if (relocs_exist == TRUE)
2592         if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
2593             || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
2594             || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
2595                                             sizeof (Elf32_External_Rela))
2596            )
2597           return FALSE;
2598
2599       if (reltext_exist == TRUE)
2600         if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
2601           return FALSE;
2602     }
2603
2604   return TRUE;
2605 }
2606
2607 const struct elf_size_info arc_elf32_size_info =
2608 {
2609   sizeof (Elf32_External_Ehdr),
2610   sizeof (Elf32_External_Phdr),
2611   sizeof (Elf32_External_Shdr),
2612   sizeof (Elf32_External_Rel),
2613   sizeof (Elf32_External_Rela),
2614   sizeof (Elf32_External_Sym),
2615   sizeof (Elf32_External_Dyn),
2616   sizeof (Elf_External_Note),
2617   4,
2618   1,
2619   32, 2,
2620   ELFCLASS32, EV_CURRENT,
2621   bfd_elf32_write_out_phdrs,
2622   bfd_elf32_write_shdrs_and_ehdr,
2623   bfd_elf32_checksum_contents,
2624   bfd_elf32_write_relocs,
2625   bfd_elf32_swap_symbol_in,
2626   bfd_elf32_swap_symbol_out,
2627   bfd_elf32_slurp_reloc_table,
2628   bfd_elf32_slurp_symbol_table,
2629   bfd_elf32_swap_dyn_in,
2630   bfd_elf32_swap_dyn_out,
2631   bfd_elf32_swap_reloc_in,
2632   bfd_elf32_swap_reloc_out,
2633   bfd_elf32_swap_reloca_in,
2634   bfd_elf32_swap_reloca_out
2635 };
2636
2637 #define elf_backend_size_info           arc_elf32_size_info
2638
2639 static struct bfd_link_hash_table *
2640 arc_elf_link_hash_table_create (bfd *abfd)
2641 {
2642   struct elf_link_hash_table *htab;
2643
2644   htab = bfd_zmalloc (sizeof (*htab));
2645   if (htab == NULL)
2646     return NULL;
2647
2648   if (!_bfd_elf_link_hash_table_init (htab, abfd,
2649                                       _bfd_elf_link_hash_newfunc,
2650                                       sizeof (struct elf_link_hash_entry),
2651                                       GENERIC_ELF_DATA))
2652     {
2653       free (htab);
2654       return NULL;
2655     }
2656
2657   htab->init_got_refcount.refcount = 0;
2658   htab->init_got_refcount.glist = NULL;
2659   htab->init_got_offset.offset = 0;
2660   htab->init_got_offset.glist = NULL;
2661   return (struct bfd_link_hash_table *) htab;
2662 }
2663
2664 /* Hook called by the linker routine which adds symbols from an object
2665    file.  */
2666
2667 static bfd_boolean
2668 elf_arc_add_symbol_hook (bfd * abfd,
2669                          struct bfd_link_info * info,
2670                          Elf_Internal_Sym * sym,
2671                          const char ** namep ATTRIBUTE_UNUSED,
2672                          flagword * flagsp ATTRIBUTE_UNUSED,
2673                          asection ** secp ATTRIBUTE_UNUSED,
2674                          bfd_vma * valp ATTRIBUTE_UNUSED)
2675 {
2676   if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
2677        || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
2678       && (abfd->flags & DYNAMIC) == 0
2679       && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
2680     elf_tdata (info->output_bfd)->has_gnu_symbols = elf_gnu_symbol_any;
2681
2682   return TRUE;
2683 }
2684
2685 #define TARGET_LITTLE_SYM   arc_elf32_le_vec
2686 #define TARGET_LITTLE_NAME  "elf32-littlearc"
2687 #define TARGET_BIG_SYM      arc_elf32_be_vec
2688 #define TARGET_BIG_NAME     "elf32-bigarc"
2689 #define ELF_ARCH            bfd_arch_arc
2690 #define ELF_MACHINE_CODE    EM_ARC_COMPACT
2691 #define ELF_MACHINE_ALT1    EM_ARC_COMPACT2
2692 #define ELF_MAXPAGESIZE     0x2000
2693
2694 #define bfd_elf32_bfd_link_hash_table_create    arc_elf_link_hash_table_create
2695
2696 #define bfd_elf32_bfd_merge_private_bfd_data    arc_elf_merge_private_bfd_data
2697 #define bfd_elf32_bfd_reloc_type_lookup         arc_elf32_bfd_reloc_type_lookup
2698 #define bfd_elf32_bfd_set_private_flags         arc_elf_set_private_flags
2699 #define bfd_elf32_bfd_print_private_bfd_data    arc_elf_print_private_bfd_data
2700 #define bfd_elf32_bfd_copy_private_bfd_data     arc_elf_copy_private_bfd_data
2701
2702 #define elf_info_to_howto_rel                arc_info_to_howto_rel
2703 #define elf_backend_object_p                 arc_elf_object_p
2704 #define elf_backend_final_write_processing   arc_elf_final_write_processing
2705
2706 #define elf_backend_relocate_section         elf_arc_relocate_section
2707 #define elf_backend_check_relocs             elf_arc_check_relocs
2708 #define elf_backend_create_dynamic_sections  _bfd_elf_create_dynamic_sections
2709
2710 #define elf_backend_adjust_dynamic_symbol    elf_arc_adjust_dynamic_symbol
2711 #define elf_backend_finish_dynamic_symbol    elf_arc_finish_dynamic_symbol
2712
2713 #define elf_backend_finish_dynamic_sections  elf_arc_finish_dynamic_sections
2714 #define elf_backend_size_dynamic_sections    elf_arc_size_dynamic_sections
2715 #define elf_backend_add_symbol_hook          elf_arc_add_symbol_hook
2716
2717 #define elf_backend_can_gc_sections     1
2718 #define elf_backend_want_got_plt        1
2719 #define elf_backend_plt_readonly        1
2720 #define elf_backend_rela_plts_and_copies_p 1
2721 #define elf_backend_want_plt_sym        0
2722 #define elf_backend_got_header_size     12
2723
2724 #define elf_backend_may_use_rel_p       0
2725 #define elf_backend_may_use_rela_p      1
2726 #define elf_backend_default_use_rela_p  1
2727
2728 #include "elf32-target.h"