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