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