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