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