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