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