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