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