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