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