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