]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/elf32-arc.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / bfd / elf32-arc.c
CommitLineData
252b5132 1/* ARC-specific support for 32-bit ELF
6f2750fe 2 Copyright (C) 1994-2016 Free Software Foundation, Inc.
886a2506 3 Contributed by Cupertino Miranda (cmiranda@synopsys.com).
252b5132 4
0d2bcfaf 5 This file is part of BFD, the Binary File Descriptor library.
252b5132 6
0d2bcfaf
NC
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
cd123cb7 9 the Free Software Foundation; either version 3 of the License, or
0d2bcfaf 10 (at your option) any later version.
252b5132 11
0d2bcfaf
NC
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
252b5132 16
0d2bcfaf
NC
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
47b0e7ad
NC
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
252b5132 21
252b5132 22#include "sysdep.h"
3db64b00 23#include "bfd.h"
252b5132
RH
24#include "libbfd.h"
25#include "elf-bfd.h"
26#include "elf/arc.h"
ea04a8f6 27#include "libiberty.h"
886a2506 28#include "opcode/arc-func.h"
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 }
34e967a5 691
886a2506 692 elf_elfheader (abfd)->e_flags &= ~EF_ARC_MACH;
252b5132 693 elf_elfheader (abfd)->e_flags |= val;
886a2506 694 elf_elfheader (abfd)->e_machine = emf;
886a2506
NC
695 /* Record whatever is the current syscall ABI version. */
696 elf_elfheader (abfd)->e_flags |= E_ARC_OSABI_CURRENT;
252b5132
RH
697}
698
886a2506
NC
699#define BFD_DEBUG_PIC(...)
700
701struct arc_relocation_data
702{
703 bfd_vma reloc_offset;
704 bfd_vma reloc_addend;
705 bfd_vma got_offset_value;
706
707 bfd_vma sym_value;
708 asection * sym_section;
709
710 reloc_howto_type *howto;
711
712 asection * input_section;
713
714 bfd_vma sdata_begin_symbol_vma;
715 bfd_boolean sdata_begin_symbol_vma_set;
716 bfd_vma got_symbol_vma;
717
718 bfd_boolean should_relocate;
719};
720
721static void
722debug_arc_reloc (struct arc_relocation_data reloc_data)
723{
34e967a5 724 PR_DEBUG ("Reloc type=%s, should_relocate = %s\n",
886a2506
NC
725 reloc_data.howto->name,
726 reloc_data.should_relocate ? "true" : "false");
34e967a5 727 PR_DEBUG (" offset = 0x%x, addend = 0x%x\n",
886a2506
NC
728 (unsigned int) reloc_data.reloc_offset,
729 (unsigned int) reloc_data.reloc_addend);
34e967a5
MC
730 PR_DEBUG (" Symbol:\n");
731 PR_DEBUG (" value = 0x%08x\n",
886a2506
NC
732 (unsigned int) reloc_data.sym_value);
733 if (reloc_data.sym_section != NULL)
734 {
34e967a5
MC
735 PR_DEBUG ("IN IF\n");
736 PR_DEBUG (
737 " section name = %s, output_offset 0x%08x",
886a2506 738 reloc_data.sym_section->name,
34e967a5
MC
739 (unsigned int) reloc_data.sym_section->output_offset);
740 if (reloc_data.sym_section->output_section != NULL)
741 {
742 PR_DEBUG (
743 ", output_section->vma = 0x%08x",
744 ((unsigned int) reloc_data.sym_section->output_section->vma));
745 }
746
747 PR_DEBUG ( "\n");
886a2506
NC
748 }
749 else
34e967a5
MC
750 {
751 PR_DEBUG ( " symbol section is NULL\n");
752 }
886a2506 753
34e967a5 754 PR_DEBUG ( " Input_section:\n");
886a2506
NC
755 if (reloc_data.input_section != NULL)
756 {
34e967a5 757 PR_DEBUG (
886a2506
NC
758 " section name = %s, output_offset 0x%08x, output_section->vma = 0x%08x\n",
759 reloc_data.input_section->name,
760 (unsigned int) reloc_data.input_section->output_offset,
761 (unsigned int) reloc_data.input_section->output_section->vma);
34e967a5 762 PR_DEBUG ( " changed_address = 0x%08x\n",
886a2506
NC
763 (unsigned int) (reloc_data.input_section->output_section->vma +
764 reloc_data.input_section->output_offset +
765 reloc_data.reloc_offset));
766 }
767 else
34e967a5
MC
768 {
769 PR_DEBUG ( " input section is NULL\n");
770 }
886a2506
NC
771}
772
6f4b1afc
CM
773static ATTRIBUTE_UNUSED bfd_vma
774get_middle_endian_relocation (bfd_vma reloc)
775{
34e967a5
MC
776 bfd_vma ret = ((reloc & 0xffff0000) >> 16) |
777 ((reloc & 0xffff) << 16);
6f4b1afc
CM
778 return ret;
779}
780
34e967a5
MC
781#define S (reloc_data.sym_value \
782 + (reloc_data.sym_section->output_section != NULL ? \
783 (reloc_data.sym_section->output_offset \
784 + reloc_data.sym_section->output_section->vma) : 0) \
785 )
786#define L (reloc_data.sym_value \
787 + (reloc_data.sym_section->output_section != NULL ? \
788 (reloc_data.sym_section->output_offset \
789 + reloc_data.sym_section->output_section->vma) : 0) \
790 )
886a2506
NC
791#define A (reloc_data.reloc_addend)
792#define B (0)
793#define G (reloc_data.got_offset_value)
34e967a5
MC
794#define GOT (reloc_data.got_symbol_vma)
795#define GOT_BEGIN (htab->sgot->output_section->vma)
796
886a2506 797#define MES (0)
34e967a5
MC
798 /* P: relative offset to PCL The offset should be to the
799 current location aligned to 32 bits. */
800#define P ( \
801 ( \
802 (reloc_data.input_section->output_section != NULL ? \
803 reloc_data.input_section->output_section->vma : 0) \
804 + reloc_data.input_section->output_offset \
805 + (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0)) \
886a2506 806 ) & ~0x3)
6f4b1afc
CM
807#define PDATA ( \
808 (reloc_data.input_section->output_section->vma \
809 + reloc_data.input_section->output_offset \
810 + (reloc_data.reloc_offset) \
34e967a5 811 ))
886a2506
NC
812#define SECTSTAR (reloc_data.input_section->output_offset)
813#define SECTSTART (reloc_data.input_section->output_offset)
814#define _SDA_BASE_ (reloc_data.sdata_begin_symbol_vma)
34e967a5
MC
815#define TLS_REL ((elf_hash_table (info))->tls_sec->output_section->vma)
816#define _SDA_BASE_ (reloc_data.sdata_begin_symbol_vma)
817#define TLS_TBSS (8)
818#define TCB_SIZE (8)
819
820#define NON_ME(VALUE) (reverse_me (reloc_data, VALUE))
886a2506
NC
821
822#define none (0)
823
34e967a5
MC
824#define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA) \
825 {\
826 asection *sym_section = reloc_data.sym_section; \
827 asection *input_section = reloc_data.input_section; \
828 ARC_DEBUG ("FORMULA = " #FORMULA "\n"); \
829 ARC_DEBUG ("S = 0x%x\n", S); \
830 ARC_DEBUG ("A = 0x%x\n", A); \
831 ARC_DEBUG ("L = 0x%x\n", L); \
832 if (sym_section->output_section != NULL) \
833 { \
834 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
835 sym_section->output_section->vma + sym_section->output_offset); \
836 } \
837 else \
838 { \
839 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
840 } \
841 if (input_section->output_section != NULL) \
842 { \
843 ARC_DEBUG ("symbol_section->vma = 0x%x\n", \
844 input_section->output_section->vma + input_section->output_offset); \
845 } \
846 else \
847 { \
848 ARC_DEBUG ("symbol_section->vma = NULL\n"); \
849 } \
850 ARC_DEBUG ("PCL = 0x%x\n", P); \
851 ARC_DEBUG ("P = 0x%x\n", P); \
852 ARC_DEBUG ("G = 0x%x\n", G); \
853 ARC_DEBUG ("SDA_OFFSET = 0x%x\n", _SDA_BASE_); \
854 ARC_DEBUG ("SDA_SET = %d\n", reloc_data.sdata_begin_symbol_vma_set); \
855 ARC_DEBUG ("GOT_OFFSET = 0x%x\n", GOT); \
856 ARC_DEBUG ("relocation = 0x%08x\n", relocation); \
857 ARC_DEBUG ("before = 0x%08x\n", (unsigned int) insn); \
858 ARC_DEBUG ("data = 0x%08x (%u) (%d)\n", (unsigned int) relocation, (unsigned int) relocation, (int) relocation); \
859 }
860
861#define PRINT_DEBUG_RELOC_INFO_AFTER \
862 { \
863 ARC_DEBUG ("after = 0x%08x\n", (unsigned int) insn); \
864 }
865
886a2506
NC
866#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
867 case R_##TYPE: \
868 { \
869 bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
870 relocation = FORMULA ; \
34e967a5 871 PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA) \
886a2506 872 insn = RELOC_FUNCTION (insn, relocation); \
34e967a5 873 PRINT_DEBUG_RELOC_INFO_AFTER \
886a2506
NC
874 } \
875 break;
876
34e967a5
MC
877static bfd_vma
878reverse_me (struct arc_relocation_data reloc_data, bfd_vma reloc)
879{
880 if (reloc_data.input_section && reloc_data.input_section->flags & SEC_CODE)
881 return ((0x0000fffff & reloc) << 16) | ((0xffff0000 & reloc) >> 16);
882 else
883 return reloc;
884}
885
886a2506 886static bfd_reloc_status_type
34e967a5
MC
887arc_do_relocation (bfd_byte * contents,
888 struct arc_relocation_data reloc_data,
889 struct bfd_link_info *info)
886a2506
NC
890{
891 bfd_vma relocation = 0;
892 bfd_vma insn;
893 bfd_vma orig_insn ATTRIBUTE_UNUSED;
34e967a5 894 struct elf_link_hash_table *htab ATTRIBUTE_UNUSED = elf_hash_table (info);
886a2506
NC
895
896 if (reloc_data.should_relocate == FALSE)
34e967a5 897 return bfd_reloc_ok;
886a2506
NC
898
899 switch (reloc_data.howto->size)
900 {
901 case 2:
902 insn = arc_bfd_get_32 (reloc_data.input_section->owner,
903 contents + reloc_data.reloc_offset,
904 reloc_data.input_section);
905 break;
906 case 1:
907 case 0:
908 insn = arc_bfd_get_16 (reloc_data.input_section->owner,
909 contents + reloc_data.reloc_offset,
910 reloc_data.input_section);
911 break;
912 default:
913 insn = 0;
914 BFD_ASSERT (0);
915 break;
916 }
917
918 orig_insn = insn;
919
920 switch (reloc_data.howto->type)
921 {
34e967a5 922#include "elf/arc-reloc.def"
886a2506
NC
923
924 default:
925 BFD_ASSERT (0);
926 break;
927 }
928
929 /* Check for relocation overflow. */
930 if (reloc_data.howto->complain_on_overflow != complain_overflow_dont)
931 {
932 bfd_reloc_status_type flag;
933 flag = bfd_check_overflow (reloc_data.howto->complain_on_overflow,
934 reloc_data.howto->bitsize,
935 reloc_data.howto->rightshift,
936 bfd_arch_bits_per_address (reloc_data.input_section->owner),
937 relocation);
938
34e967a5 939#undef DEBUG_ARC_RELOC
886a2506
NC
940#define DEBUG_ARC_RELOC(A) debug_arc_reloc (A)
941 if (flag != bfd_reloc_ok)
942 {
34e967a5 943 PR_DEBUG ( "Relocation overflows !!!!\n");
886a2506
NC
944
945 DEBUG_ARC_RELOC (reloc_data);
946
34e967a5
MC
947 PR_DEBUG (
948 "Relocation value = signed -> %d, unsigned -> %u"
949 ", hex -> (0x%08x)\n",
886a2506
NC
950 (int) relocation,
951 (unsigned int) relocation,
952 (unsigned int) relocation);
953 return flag;
954 }
955 }
34e967a5 956#undef DEBUG_ARC_RELOC
886a2506
NC
957#define DEBUG_ARC_RELOC(A)
958
959 switch (reloc_data.howto->size)
960 {
961 case 2:
962 arc_bfd_put_32 (reloc_data.input_section->owner, insn,
963 contents + reloc_data.reloc_offset,
964 reloc_data.input_section);
965 break;
966 case 1:
967 case 0:
968 arc_bfd_put_16 (reloc_data.input_section->owner, insn,
969 contents + reloc_data.reloc_offset,
970 reloc_data.input_section);
971 break;
972 default:
973 ARC_DEBUG ("size = %d\n", reloc_data.howto->size);
974 BFD_ASSERT (0);
975 break;
976 }
977
978 return bfd_reloc_ok;
979}
980#undef S
981#undef A
982#undef B
983#undef G
984#undef GOT
985#undef L
986#undef MES
987#undef P
988#undef SECTSTAR
989#undef SECTSTART
990#undef _SDA_BASE_
991#undef none
992
993#undef ARC_RELOC_HOWTO
994
34e967a5
MC
995static struct got_entry **
996arc_get_local_got_ents (bfd * abfd)
886a2506 997{
34e967a5 998 static struct got_entry **local_got_ents = NULL;
886a2506 999
34e967a5 1000 if (local_got_ents == NULL)
886a2506
NC
1001 {
1002 size_t size;
886a2506
NC
1003 Elf_Internal_Shdr *symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1004
1005 size = symtab_hdr->sh_info * sizeof (bfd_vma);
34e967a5
MC
1006 local_got_ents = (struct got_entry **)
1007 bfd_alloc (abfd, sizeof(struct got_entry *) * size);
1008 if (local_got_ents == NULL)
886a2506 1009 return FALSE;
34e967a5
MC
1010
1011 memset (local_got_ents, 0, sizeof(struct got_entry *) * size);
1012 elf_local_got_ents (abfd) = local_got_ents;
886a2506
NC
1013 }
1014
34e967a5 1015 return local_got_ents;
886a2506
NC
1016}
1017
886a2506
NC
1018/* Relocate an arc ELF section.
1019 Function : elf_arc_relocate_section
1020 Brief : Relocate an arc section, by handling all the relocations
34e967a5 1021 appearing in that section.
886a2506 1022 Args : output_bfd : The bfd being written to.
34e967a5
MC
1023 info : Link information.
1024 input_bfd : The input bfd.
1025 input_section : The section being relocated.
1026 contents : contents of the section being relocated.
1027 relocs : List of relocations in the section.
1028 local_syms : is a pointer to the swapped in local symbols.
1029 local_section : is an array giving the section in the input file
1030 corresponding to the st_shndx field of each
1031 local symbol. */
886a2506 1032static bfd_boolean
34e967a5 1033elf_arc_relocate_section (bfd * output_bfd,
886a2506 1034 struct bfd_link_info * info,
34e967a5
MC
1035 bfd * input_bfd,
1036 asection * input_section,
1037 bfd_byte * contents,
886a2506
NC
1038 Elf_Internal_Rela * relocs,
1039 Elf_Internal_Sym * local_syms,
34e967a5 1040 asection ** local_sections)
886a2506 1041{
34e967a5 1042 Elf_Internal_Shdr * symtab_hdr;
886a2506 1043 struct elf_link_hash_entry ** sym_hashes;
34e967a5
MC
1044 struct got_entry ** local_got_ents;
1045 Elf_Internal_Rela * rel;
1046 Elf_Internal_Rela * relend;
1047 struct elf_link_hash_table *htab = elf_hash_table (info);
886a2506
NC
1048
1049 symtab_hdr = &((elf_tdata (input_bfd))->symtab_hdr);
1050 sym_hashes = elf_sym_hashes (input_bfd);
1051
1052 rel = relocs;
1053 relend = relocs + input_section->reloc_count;
1054 for (; rel < relend; rel++)
1055 {
1056 enum elf_arc_reloc_type r_type;
34e967a5
MC
1057 reloc_howto_type * howto;
1058 unsigned long r_symndx;
886a2506 1059 struct elf_link_hash_entry * h;
34e967a5
MC
1060 Elf_Internal_Sym * sym;
1061 asection * sec;
1062 struct elf_link_hash_entry *h2;
886a2506
NC
1063
1064 struct arc_relocation_data reloc_data =
1065 {
34e967a5
MC
1066 .reloc_offset = 0,
1067 .reloc_addend = 0,
1068 .got_offset_value = 0,
1069 .sym_value = 0,
1070 .sym_section = NULL,
1071 .howto = NULL,
1072 .input_section = NULL,
1073 .sdata_begin_symbol_vma = 0,
1074 .sdata_begin_symbol_vma_set = FALSE,
1075 .got_symbol_vma = 0,
1076 .should_relocate = FALSE
886a2506
NC
1077 };
1078
34e967a5
MC
1079 r_type = ELF32_R_TYPE (rel->r_info);
1080
1081 if (r_type >= (int) R_ARC_max)
1082 {
1083 bfd_set_error (bfd_error_bad_value);
1084 return FALSE;
1085 }
1086 howto = &elf_arc_howto_table[r_type];
1087
1088 r_symndx = ELF32_R_SYM (rel->r_info);
1089
1090 /* If we are generating another .o file and the symbol in not
1091 local, skip this relocation. */
1092 if (bfd_link_relocatable (info))
1093 {
1094 /* This is a relocateable link. We don't have to change
1095 anything, unless the reloc is against a section symbol,
1096 in which case we have to adjust according to where the
1097 section symbol winds up in the output section. */
1098
1099 /* Checks if this is a local symbol and thus the reloc
1100 might (will??) be against a section symbol. */
1101 if (r_symndx < symtab_hdr->sh_info)
1102 {
1103 sym = local_syms + r_symndx;
1104 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1105 {
1106 sec = local_sections[r_symndx];
1107
1108 /* for RELA relocs.Just adjust the addend
1109 value in the relocation entry. */
1110 rel->r_addend += sec->output_offset + sym->st_value;
1111
1112 BFD_DEBUG_PIC (
1113 PR_DEBUG ("local symbols reloc "
1114 "(section=%d %s) seen in %s\n",
1115 r_symndx,
1116 local_sections[r_symndx]->name,
1117 __PRETTY_FUNCTION__)
1118 );
1119 }
1120 }
1121
1122 continue;
1123 }
886a2506
NC
1124
1125 h2 = elf_link_hash_lookup (elf_hash_table (info), "__SDATA_BEGIN__",
1126 FALSE, FALSE, TRUE);
1127
1128 if (reloc_data.sdata_begin_symbol_vma_set == FALSE
34e967a5
MC
1129 && h2 != NULL && h2->root.type != bfd_link_hash_undefined
1130 && h2->root.u.def.section->output_section != NULL)
1131 /* TODO: Verify this condition. */
886a2506
NC
1132 {
1133 reloc_data.sdata_begin_symbol_vma =
1134 (h2->root.u.def.value +
1135 h2->root.u.def.section->output_section->vma);
1136 reloc_data.sdata_begin_symbol_vma_set = TRUE;
1137 }
1138
886a2506
NC
1139 reloc_data.input_section = input_section;
1140 reloc_data.howto = howto;
1141 reloc_data.reloc_offset = rel->r_offset;
1142 reloc_data.reloc_addend = rel->r_addend;
1143
886a2506
NC
1144 /* This is a final link. */
1145 h = NULL;
1146 sym = NULL;
1147 sec = NULL;
1148
1149 if (r_symndx < symtab_hdr->sh_info) /* A local symbol. */
1150 {
34e967a5
MC
1151 local_got_ents = arc_get_local_got_ents (output_bfd);
1152 struct got_entry *entry = local_got_ents[r_symndx];
1153
886a2506
NC
1154 sym = local_syms + r_symndx;
1155 sec = local_sections[r_symndx];
1156
1157 reloc_data.sym_value = sym->st_value;
1158 reloc_data.sym_section = sec;
1159
34e967a5
MC
1160 if ((is_reloc_for_GOT (howto)
1161 || is_reloc_for_TLS (howto)) && entry != NULL)
1162 {
1163 if (is_reloc_for_TLS (howto))
1164 while (entry->type == GOT_NORMAL && entry->next != NULL)
1165 entry = entry->next;
1166
1167 if (is_reloc_for_GOT (howto))
1168 while (entry->type != GOT_NORMAL && entry->next != NULL)
1169 entry = entry->next;
1170
1171 if (entry->type == GOT_TLS_GD && entry->processed == FALSE)
1172 {
1173 bfd_vma sym_vma = sym->st_value
1174 + sec->output_section->vma
1175 + sec->output_offset;
1176
1177 /* Create dynamic relocation for local sym. */
1178 ADD_RELA (output_bfd, got, entry->offset, 0,
1179 R_ARC_TLS_DTPMOD, 0);
1180 ADD_RELA (output_bfd, got, entry->offset+4, 0,
1181 R_ARC_TLS_DTPOFF, 0);
1182
1183 bfd_vma sec_vma = sec->output_section->vma
1184 + sec->output_offset;
1185 bfd_put_32 (output_bfd, sym_vma - sec_vma,
1186 htab->sgot->contents + entry->offset + 4);
1187
1188 ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_GD value "
1189 "= 0x%x @ 0x%x, for symbol %s\n",
1190 sym_vma - sec_vma,
1191 htab->sgot->contents + entry->offset + 4,
1192 "(local)");
1193
1194 entry->processed = TRUE;
1195 }
1196 if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
1197 {
1198 bfd_vma sym_vma = sym->st_value
1199 + sec->output_section->vma
1200 + sec->output_offset;
1201 bfd_vma sec_vma = htab->tls_sec->output_section->vma;
1202 bfd_put_32 (output_bfd, sym_vma - sec_vma,
1203 htab->sgot->contents + entry->offset);
1204 /* TODO: Check if this type of relocs is the cause
1205 for all the ARC_NONE dynamic relocs. */
1206
1207 ARC_DEBUG ("arc_info: FIXED -> GOT_TLS_IE value = "
1208 "0x%x @ 0x%x, for symbol %s\n",
1209 sym_vma - sec_vma,
1210 htab->sgot->contents + entry->offset,
1211 "(local)");
1212
1213 entry->processed = TRUE;
1214 }
1215 if (entry->type == GOT_NORMAL && entry->processed == FALSE)
1216 {
1217 bfd_vma sec_vma = reloc_data.sym_section->output_section->vma
1218 + reloc_data.sym_section->output_offset;
1219
1220 bfd_put_32 (output_bfd, reloc_data.sym_value + sec_vma,
1221 htab->sgot->contents + entry->offset);
1222
1223 ARC_DEBUG ("arc_info: PATCHED: 0x%08x @ 0x%08x for "
1224 "sym %s in got offset 0x%x\n",
1225 reloc_data.sym_value + sec_vma,
1226 htab->sgot->output_section->vma
1227 + htab->sgot->output_offset + entry->offset,
1228 "(local)",
1229 entry->offset);
1230 entry->processed = TRUE;
1231 }
1232
1233 reloc_data.got_offset_value = entry->offset;
1234 ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
1235 "vma = 0x%x for symbol %s\n",
1236 entry->type, entry->offset,
1237 htab->sgot->output_section->vma
1238 + htab->sgot->output_offset + entry->offset,
1239 "(local)");
1240 }
1241
1242 BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1243 if (htab->sgot != NULL)
1244 reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1245 + htab->sgot->output_offset;
886a2506
NC
1246
1247 reloc_data.should_relocate = TRUE;
1248 }
1249 else /* Global symbol. */
1250 {
1251 /* Get the symbol's entry in the symtab. */
1252 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1253
1254 while (h->root.type == bfd_link_hash_indirect
1255 || h->root.type == bfd_link_hash_warning)
1256 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1257
1258 BFD_ASSERT ((h->dynindx == -1) >= (h->forced_local != 0));
1259 /* If we have encountered a definition for this symbol. */
1260 if (h->root.type == bfd_link_hash_defined
1261 || h->root.type == bfd_link_hash_defweak)
1262 {
1263 reloc_data.sym_value = h->root.u.def.value;
1264 reloc_data.sym_section = h->root.u.def.section;
1265
1266 reloc_data.should_relocate = TRUE;
1267
34e967a5 1268 if (is_reloc_for_GOT (howto) && !bfd_link_pic (info))
886a2506 1269 {
34e967a5
MC
1270 /* TODO: Change it to use arc_do_relocation with
1271 ARC_32 reloc. Try to use ADD_RELA macro. */
886a2506
NC
1272 bfd_vma relocation =
1273 reloc_data.sym_value + reloc_data.reloc_addend
34e967a5
MC
1274 + (reloc_data.sym_section->output_section != NULL ?
1275 (reloc_data.sym_section->output_offset
1276 + reloc_data.sym_section->output_section->vma)
1277 : 0);
1278
1279 BFD_ASSERT (h->got.glist);
1280 bfd_vma got_offset = h->got.glist->offset;
1281 bfd_put_32 (output_bfd, relocation,
1282 htab->sgot->contents + got_offset);
1283 }
1284 if (is_reloc_for_PLT (howto) && h->plt.offset != (bfd_vma) -1)
1285 {
1286 /* TODO: This is repeated up here. */
1287 reloc_data.sym_value = h->plt.offset;
1288 reloc_data.sym_section = htab->splt;
886a2506
NC
1289 }
1290 }
1291 else if (h->root.type == bfd_link_hash_undefweak)
1292 {
1293 /* Is weak symbol and has no definition. */
34e967a5
MC
1294 if (is_reloc_for_GOT (howto))
1295 {
1296 reloc_data.sym_value = h->root.u.def.value;
1297 reloc_data.sym_section = htab->sgot;
1298 reloc_data.should_relocate = TRUE;
1299 }
1300 else if (is_reloc_for_PLT (howto)
1301 && 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;
1306 reloc_data.should_relocate = TRUE;
1307 }
1308 else
1309 continue;
886a2506
NC
1310 }
1311 else
1312 {
1313 if (is_reloc_for_GOT (howto))
1314 {
886a2506 1315 reloc_data.sym_value = h->root.u.def.value;
34e967a5 1316 reloc_data.sym_section = htab->sgot;
886a2506
NC
1317
1318 reloc_data.should_relocate = TRUE;
1319 }
1320 else if (is_reloc_for_PLT (howto))
1321 {
886a2506 1322 reloc_data.sym_value = h->plt.offset;
34e967a5 1323 reloc_data.sym_section = htab->splt;
886a2506
NC
1324
1325 reloc_data.should_relocate = TRUE;
1326 }
1327 else if (!(*info->callbacks->undefined_symbol)
1328 (info, h->root.root.string, input_bfd, input_section,
1329 rel->r_offset,!bfd_link_pic (info)))
1330 {
1331 return FALSE;
1332 }
1333 }
1334
34e967a5
MC
1335 if (h->got.glist != NULL)
1336 {
1337 struct got_entry *entry = h->got.glist;
1338
1339 if (is_reloc_for_GOT (howto) || is_reloc_for_TLS (howto))
1340 {
1341 if (! elf_hash_table (info)->dynamic_sections_created
1342 || (bfd_link_pic (info)
1343 && SYMBOL_REFERENCES_LOCAL (info, h)))
1344 {
1345 reloc_data.sym_value = h->root.u.def.value;
1346 reloc_data.sym_section = h->root.u.def.section;
1347
1348 if (is_reloc_for_TLS (howto))
1349 while (entry->type == GOT_NORMAL && entry->next != NULL)
1350 entry = entry->next;
1351
1352 if (entry->processed == FALSE
1353 && (entry->type == GOT_TLS_GD
1354 || entry->type == GOT_TLS_IE))
1355 {
1356 bfd_vma sym_value = h->root.u.def.value
1357 + h->root.u.def.section->output_section->vma
1358 + h->root.u.def.section->output_offset;
1359
1360 bfd_vma sec_vma =
1361 elf_hash_table (info)->tls_sec->output_section->vma;
1362
1363 bfd_put_32 (output_bfd,
1364 sym_value - sec_vma,
1365 htab->sgot->contents + entry->offset
1366 + (entry->existing_entries == MOD_AND_OFF ? 4 : 0));
1367
1368 ARC_DEBUG ("arc_info: FIXED -> %s value = 0x%x "
1369 "@ 0x%x, for symbol %s\n",
1370 (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
1371 "GOT_TLS_IE"),
1372 sym_value - sec_vma,
1373 htab->sgot->contents + entry->offset
1374 + (entry->existing_entries == MOD_AND_OFF ? 4 : 0),
1375 h->root.root.string);
1376
1377 entry->processed = TRUE;
1378 }
1379
1380 if (entry->type == GOT_TLS_IE && entry->processed == FALSE)
1381 {
1382 bfd_vma sec_vma = htab->tls_sec->output_section->vma;
1383 bfd_put_32 (output_bfd,
1384 reloc_data.sym_value - sec_vma,
1385 htab->sgot->contents + entry->offset);
1386 }
1387
1388 if (entry->type == GOT_NORMAL && entry->processed == FALSE)
1389 {
1390 bfd_vma sec_vma =
1391 reloc_data.sym_section->output_section->vma
1392 + reloc_data.sym_section->output_offset;
1393
1394 if (h->root.type != bfd_link_hash_undefweak)
1395 {
1396 bfd_put_32 (output_bfd,
1397 reloc_data.sym_value + sec_vma,
1398 htab->sgot->contents + entry->offset);
1399
1400 ARC_DEBUG ("arc_info: PATCHED: 0x%08x "
1401 "@ 0x%08x for sym %s in got offset 0x%x\n",
1402 reloc_data.sym_value + sec_vma,
1403 htab->sgot->output_section->vma
1404 + htab->sgot->output_offset + entry->offset,
1405 h->root.root.string,
1406 entry->offset);
1407 }
1408 else
1409 {
1410 ARC_DEBUG ("arc_info: PATCHED: NOT_PATCHED "
1411 "@ 0x%08x for sym %s in got offset 0x%x "
1412 "(is undefweak)\n",
1413 htab->sgot->output_section->vma
1414 + htab->sgot->output_offset + entry->offset,
1415 h->root.root.string,
1416 entry->offset);
1417 }
1418
1419 entry->processed = TRUE;
1420 }
1421 }
1422 }
1423
1424 reloc_data.got_offset_value = entry->offset;
1425
1426 ARC_DEBUG ("arc_info: GOT_ENTRY = %d, offset = 0x%x, "
1427 "vma = 0x%x for symbol %s\n",
1428 entry->type, entry->offset,
1429 htab->sgot->output_section->vma
1430 + htab->sgot->output_offset + entry->offset,
1431 h->root.root.string);
1432 }
1433
1434 BFD_ASSERT (htab->sgot != NULL || !is_reloc_for_GOT (howto));
1435 if (htab->sgot != NULL)
1436 reloc_data.got_symbol_vma = htab->sgot->output_section->vma
1437 + htab->sgot->output_offset;
886a2506
NC
1438 }
1439
34e967a5
MC
1440 switch (r_type)
1441 {
1442 case R_ARC_32:
1443 case R_ARC_32_ME:
1444 case R_ARC_PC32:
1445 case R_ARC_32_PCREL:
1446 if (bfd_link_pic (info)
1447 && ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1448 || (h != NULL
1449 && h->dynindx != -1
1450 && (!info->symbolic || !h->def_regular))))
1451 {
1452 Elf_Internal_Rela outrel;
1453 bfd_byte *loc;
1454 bfd_boolean skip = FALSE;
1455 bfd_boolean relocate = FALSE;
1456 asection *sreloc = _bfd_elf_get_dynamic_reloc_section
1457 (input_bfd, input_section,
1458 /*RELA*/ TRUE);
1459
1460 BFD_ASSERT (sreloc != NULL);
1461
1462 outrel.r_offset = _bfd_elf_section_offset (output_bfd,
1463 info,
1464 input_section,
1465 rel->r_offset);
1466 if (outrel.r_offset == (bfd_vma) -1)
1467 skip = TRUE;
1468
1469 outrel.r_addend = rel->r_addend;
1470 outrel.r_offset += (input_section->output_section->vma
1471 + input_section->output_offset);
1472
1473 if (skip)
1474 {
1475 memset (&outrel, 0, sizeof outrel);
1476 relocate = FALSE;
1477 }
1478 else if (r_type == R_ARC_PC32
1479 || r_type == R_ARC_32_PCREL)
1480 {
1481 BFD_ASSERT (h != NULL && h->dynindx != -1);
1482 if ((input_section->flags & SEC_ALLOC) != 0)
1483 relocate = FALSE;
1484 else
1485 relocate = TRUE;
1486 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1487 }
1488 else
1489 {
1490 /* Handle local symbols, they either do not have a
1491 global hash table entry (h == NULL), or are
1492 forced local due to a version script
1493 (h->forced_local), or the third condition is
1494 legacy, it appears to say something like, for
1495 links where we are pre-binding the symbols, or
1496 there's not an entry for this symbol in the
1497 dynamic symbol table, and it's a regular symbol
1498 not defined in a shared object, then treat the
1499 symbol as local, resolve it now. */
1500 if (h == NULL
1501 || ((info->symbolic || h->dynindx == -1)
1502 && h->def_regular)
1503 || h->forced_local)
1504 {
1505 relocate = TRUE;
1506 /* outrel.r_addend = 0; */
1507 outrel.r_info = ELF32_R_INFO (0, R_ARC_RELATIVE);
1508 }
1509 else
1510 {
1511 BFD_ASSERT (h->dynindx != -1);
1512 if ((input_section->flags & SEC_ALLOC) != 0)
1513 relocate = FALSE;
1514 else
1515 relocate = TRUE;
1516 outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_32);
1517 }
1518 }
1519
1520 BFD_ASSERT (sreloc->contents != 0);
1521
1522 loc = sreloc->contents;
1523 loc += sreloc->reloc_count * sizeof (Elf32_External_Rela);
1524 sreloc->reloc_count += 1;
1525
1526 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1527
1528 if (relocate == FALSE)
1529 continue;
1530 }
1531 break;
1532 default:
1533 break;
1534 }
1535
1536 if (is_reloc_SDA_relative (howto)
1537 && (reloc_data.sdata_begin_symbol_vma_set == FALSE))
886a2506
NC
1538 {
1539 (*_bfd_error_handler)
1540 ("Error: Linker symbol __SDATA_BEGIN__ not found");
1541 bfd_set_error (bfd_error_bad_value);
1542 return FALSE;
1543 }
1544
1545 DEBUG_ARC_RELOC (reloc_data);
34e967a5
MC
1546
1547 if (arc_do_relocation (contents, reloc_data, info) != bfd_reloc_ok)
886a2506
NC
1548 return FALSE;
1549 }
1550
1551 return TRUE;
1552}
1553
1554static struct dynamic_sections
1555arc_create_dynamic_sections (bfd * abfd, struct bfd_link_info *info)
1556{
34e967a5
MC
1557 struct elf_link_hash_table *htab;
1558 bfd *dynobj;
886a2506 1559 struct dynamic_sections ds =
886a2506 1560 {
34e967a5
MC
1561 .initialized = FALSE,
1562 .sgot = NULL,
1563 .srelgot = NULL,
1564 .sgotplt = NULL,
1565 .srelgotplt = NULL,
1566 .sdyn = NULL,
1567 .splt = NULL,
1568 .srelplt = NULL
1569 };
1570
1571 htab = elf_hash_table (info);
1572 BFD_ASSERT (htab);
1573
1574 /* Create dynamic sections for relocatable executables so that we
1575 can copy relocations. */
1576 if (! htab->dynamic_sections_created && bfd_link_pic (info))
1577 {
1578 if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
1579 BFD_ASSERT (0);
886a2506 1580 }
886a2506 1581
34e967a5 1582 dynobj = (elf_hash_table (info))->dynobj;
886a2506 1583
34e967a5 1584 if (dynobj)
886a2506 1585 {
34e967a5
MC
1586 ds.sgot = htab->sgot;
1587 ds.srelgot = htab->srelgot;
886a2506 1588
34e967a5
MC
1589 ds.sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
1590 ds.srelgotplt = ds.srelplt;
886a2506 1591
34e967a5
MC
1592 ds.splt = bfd_get_section_by_name (dynobj, ".plt");
1593 ds.srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
1594 }
1595
1596 if (htab->dynamic_sections_created)
1597 {
1598 ds.sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
1599 }
886a2506
NC
1600
1601 ds.initialized = TRUE;
1602
1603 return ds;
1604}
1605
34e967a5
MC
1606#define ADD_SYMBOL_REF_SEC_AND_RELOC(SECNAME, COND_FOR_RELOC, H) \
1607 htab->s##SECNAME->size; \
1608 { \
1609 if (COND_FOR_RELOC) \
1610 { \
1611 htab->srel##SECNAME->size += sizeof (Elf32_External_Rela); \
1612 ARC_DEBUG ("arc_info: Added reloc space in " \
1613 #SECNAME " section at " __FILE__ \
1614 ":%d for symbol\n", \
1615 __LINE__, name_for_global_symbol (H)); \
1616 } \
1617 if (H) \
1618 if (h->dynindx == -1 && !h->forced_local) \
1619 if (! bfd_elf_link_record_dynamic_symbol (info, H)) \
1620 return FALSE; \
1621 htab->s##SECNAME->size += 4; \
1622 }
886a2506
NC
1623
1624static bfd_boolean
34e967a5 1625elf_arc_check_relocs (bfd * abfd,
886a2506 1626 struct bfd_link_info * info,
34e967a5 1627 asection * sec,
886a2506
NC
1628 const Elf_Internal_Rela * relocs)
1629{
34e967a5
MC
1630 Elf_Internal_Shdr * symtab_hdr;
1631 struct elf_link_hash_entry ** sym_hashes;
1632 struct got_entry ** local_got_ents;
1633 const Elf_Internal_Rela * rel;
1634 const Elf_Internal_Rela * rel_end;
1635 bfd * dynobj;
1636 asection * sreloc = NULL;
1637 struct elf_link_hash_table * htab = elf_hash_table (info);
1638
1639 if (bfd_link_relocatable (info))
1640 return TRUE;
886a2506
NC
1641
1642 dynobj = (elf_hash_table (info))->dynobj;
1643 symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
1644 sym_hashes = elf_sym_hashes (abfd);
34e967a5 1645 local_got_ents = arc_get_local_got_ents (abfd);
886a2506
NC
1646
1647 rel_end = relocs + sec->reloc_count;
1648 for (rel = relocs; rel < rel_end; rel++)
1649 {
1650 enum elf_arc_reloc_type r_type;
1651 reloc_howto_type *howto;
1652 unsigned long r_symndx;
1653 struct elf_link_hash_entry *h;
1654
1655 r_type = ELF32_R_TYPE (rel->r_info);
1656
1657 if (r_type >= (int) R_ARC_max)
1658 {
1659 bfd_set_error (bfd_error_bad_value);
1660 return FALSE;
1661 }
34e967a5
MC
1662 howto = &elf_arc_howto_table[r_type];
1663
1664 if (dynobj == NULL
1665 && (is_reloc_for_GOT (howto) == TRUE
1666 || is_reloc_for_TLS (howto) == TRUE))
1667 {
1668 dynobj = elf_hash_table (info)->dynobj = abfd;
1669 if (! _bfd_elf_create_got_section (abfd, info))
1670 return FALSE;
1671 }
886a2506
NC
1672
1673 /* Load symbol information. */
1674 r_symndx = ELF32_R_SYM (rel->r_info);
1675 if (r_symndx < symtab_hdr->sh_info) /* Is a local symbol. */
1676 h = NULL;
1677 else /* Global one. */
1678 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1679
34e967a5
MC
1680 switch (r_type)
1681 {
1682 case R_ARC_32:
1683 case R_ARC_32_ME:
1684 /* During shared library creation, these relocs should not
1685 appear in a shared library (as memory will be read only
1686 and the dynamic linker can not resolve these. However
1687 the error should not occur for e.g. debugging or
1688 non-readonly sections. */
1689 if (bfd_link_dll (info) && !bfd_link_pie (info)
1690 && (sec->flags & SEC_ALLOC) != 0
1691 && (sec->flags & SEC_READONLY) != 0)
1692 {
1693 const char *name;
1694 if (h)
1695 name = h->root.root.string;
1696 else
1697 /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); */
1698 name = "UNKNOWN";
1699 (*_bfd_error_handler)
1700 (_("\
1701%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
1702 abfd,
1703 arc_elf_howto (r_type)->name,
1704 name);
1705 bfd_set_error (bfd_error_bad_value);
1706 return FALSE;
1707 }
1708
1709 /* In some cases we are not setting the 'non_got_ref'
1710 flag, even though the relocations don't require a GOT
1711 access. We should extend the testing in this area to
1712 ensure that no significant cases are being missed. */
1713 if (h)
1714 h->non_got_ref = 1;
1715 /* FALLTHROUGH */
1716 case R_ARC_PC32:
1717 case R_ARC_32_PCREL:
1718 if (bfd_link_pic (info)
1719 && ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
1720 || (h != NULL
1721 && h->dynindx != -1
1722 && (!info->symbolic || !h->def_regular))))
1723 {
1724 if (sreloc == NULL)
1725 {
1726 sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
1727 2, abfd,
1728 /*rela*/
1729 TRUE);
1730
1731 if (sreloc == NULL)
1732 return FALSE;
1733 }
1734 sreloc->size += sizeof (Elf32_External_Rela);
1735
1736 }
1737 default:
1738 break;
1739 }
1740
886a2506
NC
1741 if (is_reloc_for_PLT (howto) == TRUE)
1742 {
1743 if (h == NULL)
1744 continue;
1745 else
1746 h->needs_plt = 1;
1747 }
1748
1749 if (is_reloc_for_GOT (howto) == TRUE)
1750 {
1751 if (h == NULL)
1752 {
1753 /* Local symbol. */
34e967a5
MC
1754 if (local_got_ents[r_symndx] == NULL)
1755 {
1756 bfd_vma offset =
1757 ADD_SYMBOL_REF_SEC_AND_RELOC (got,
1758 bfd_link_pic (info),
1759 NULL);
1760 new_got_entry_to_list (&(local_got_ents[r_symndx]),
1761 GOT_NORMAL, offset, NONE);
1762 }
886a2506
NC
1763 }
1764 else
1765 {
1766 /* Global symbol. */
1767 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
34e967a5
MC
1768 if (h->got.glist == NULL)
1769 {
1770 bfd_vma offset =
1771 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1772 new_got_entry_to_list (&h->got.glist,
1773 GOT_NORMAL, offset, NONE);
1774 }
886a2506
NC
1775 }
1776 }
886a2506 1777
34e967a5
MC
1778 if (is_reloc_for_TLS (howto) == TRUE)
1779 {
1780 enum tls_type_e type = GOT_UNKNOWN;
886a2506 1781
34e967a5
MC
1782 switch (r_type)
1783 {
1784 case R_ARC_TLS_GD_GOT:
1785 type = GOT_TLS_GD;
1786 break;
1787 case R_ARC_TLS_IE_GOT:
1788 type = GOT_TLS_IE;
1789 break;
1790 default:
1791 break;
1792 }
886a2506 1793
34e967a5
MC
1794 struct got_entry **list = NULL;
1795 if (h != NULL)
1796 list = &(h->got.glist);
1797 else
1798 list = &(local_got_ents[r_symndx]);
886a2506 1799
34e967a5
MC
1800 if (type != GOT_UNKNOWN && !symbol_has_entry_of_type (*list, type))
1801 {
1802 enum tls_got_entries entries = NONE;
1803 bfd_vma offset =
1804 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
886a2506 1805
34e967a5
MC
1806 if (type == GOT_TLS_GD)
1807 {
1808 bfd_vma ATTRIBUTE_UNUSED notneeded =
1809 ADD_SYMBOL_REF_SEC_AND_RELOC (got, TRUE, h);
1810 entries = MOD_AND_OFF;
1811 }
886a2506 1812
34e967a5
MC
1813 if (entries == NONE)
1814 entries = OFF;
886a2506 1815
34e967a5
MC
1816 new_got_entry_to_list (list, type, offset, entries);
1817 }
1818 }
1819 }
886a2506 1820
34e967a5
MC
1821 return TRUE;
1822}
886a2506 1823
34e967a5 1824#define ELF_DYNAMIC_INTERPRETER "/sbin/ld-uClibc.so"
886a2506 1825
34e967a5
MC
1826static struct plt_version_t *
1827arc_get_plt_version (struct bfd_link_info *info)
886a2506 1828{
34e967a5 1829 int i;
886a2506 1830
34e967a5
MC
1831 for (i = 0; i < 1; i++)
1832 {
1833 ARC_DEBUG ("%d: size1 = %d, size2 = %d\n", i,
1834 plt_versions[i].entry_size,
1835 plt_versions[i].elem_size);
1836 }
886a2506 1837
34e967a5 1838 if (bfd_get_mach (info->output_bfd) == bfd_mach_arc_arcv2)
886a2506 1839 {
34e967a5
MC
1840 if (bfd_link_pic (info))
1841 return &(plt_versions[ELF_ARCV2_PIC]);
1842 else
1843 return &(plt_versions[ELF_ARCV2_ABS]);
1844 }
1845 else
886a2506 1846 {
34e967a5
MC
1847 if (bfd_link_pic (info))
1848 return &(plt_versions[ELF_ARC_PIC]);
1849 else
1850 return &(plt_versions[ELF_ARC_ABS]);
886a2506 1851 }
886a2506
NC
1852}
1853
1854static bfd_vma
1855add_symbol_to_plt (struct bfd_link_info *info)
1856{
34e967a5 1857 struct elf_link_hash_table *htab = elf_hash_table (info);
886a2506
NC
1858 bfd_vma ret;
1859
34e967a5 1860 struct plt_version_t *plt_data = arc_get_plt_version (info);
886a2506 1861
34e967a5
MC
1862 /* If this is the first .plt entry, make room for the special first
1863 entry. */
1864 if (htab->splt->size == 0)
1865 htab->splt->size += plt_data->entry_size;
886a2506 1866
34e967a5
MC
1867 ret = htab->splt->size;
1868
1869 htab->splt->size += plt_data->elem_size;
1870 ARC_DEBUG ("PLT_SIZE = %d\n", htab->splt->size);
1871
1872 htab->sgotplt->size += 4;
1873 htab->srelplt->size += sizeof (Elf32_External_Rela);
886a2506
NC
1874
1875 return ret;
1876}
1877
34e967a5
MC
1878#define PLT_DO_RELOCS_FOR_ENTRY(ABFD, DS, RELOCS) \
1879 plt_do_relocs_for_symbol (ABFD, DS, RELOCS, 0, 0)
886a2506
NC
1880
1881static void
34e967a5
MC
1882plt_do_relocs_for_symbol (bfd *abfd,
1883 struct elf_link_hash_table *htab,
1884 const struct plt_reloc *reloc,
886a2506
NC
1885 bfd_vma plt_offset,
1886 bfd_vma symbol_got_offset)
1887{
1888 while (SYM_ONLY (reloc->symbol) != LAST_RELOC)
1889 {
1890 bfd_vma relocation = 0;
1891
1892 switch (SYM_ONLY (reloc->symbol))
1893 {
1894 case SGOT:
1895 relocation =
34e967a5
MC
1896 htab->sgotplt->output_section->vma +
1897 htab->sgotplt->output_offset + symbol_got_offset;
886a2506
NC
1898 break;
1899 }
1900 relocation += reloc->addend;
1901
34e967a5
MC
1902 if (IS_RELATIVE (reloc->symbol))
1903 {
1904 bfd_vma reloc_offset = reloc->offset;
1905 reloc_offset -= (IS_INSN_32 (reloc->symbol)) ? 4 : 0;
1906 reloc_offset -= (IS_INSN_24 (reloc->symbol)) ? 2 : 0;
886a2506 1907
34e967a5
MC
1908 relocation -= htab->splt->output_section->vma
1909 + htab->splt->output_offset
1910 + plt_offset + reloc_offset;
1911 }
1912
1913 /* TODO: being ME is not a property of the relocation but of the
1914 section of which is applying the relocation. */
1915 if (IS_MIDDLE_ENDIAN (reloc->symbol) || bfd_big_endian (abfd))
886a2506
NC
1916 {
1917 relocation =
1918 ((relocation & 0xffff0000) >> 16) |
1919 ((relocation & 0xffff) << 16);
1920 }
1921
1922 switch (reloc->size)
1923 {
1924 case 32:
34e967a5 1925 bfd_put_32 (htab->splt->output_section->owner,
886a2506 1926 relocation,
34e967a5 1927 htab->splt->contents + plt_offset + reloc->offset);
886a2506
NC
1928 break;
1929 }
1930
34e967a5 1931 reloc = &(reloc[1]); /* Jump to next relocation. */
886a2506
NC
1932 }
1933}
1934
1935static void
34e967a5
MC
1936relocate_plt_for_symbol (bfd *output_bfd,
1937 struct bfd_link_info *info,
886a2506
NC
1938 struct elf_link_hash_entry *h)
1939{
34e967a5
MC
1940 struct plt_version_t *plt_data = arc_get_plt_version (info);
1941 struct elf_link_hash_table *htab = elf_hash_table (info);
886a2506 1942
34e967a5
MC
1943 bfd_vma plt_index = (h->plt.offset - plt_data->entry_size)
1944 / plt_data->elem_size;
886a2506
NC
1945 bfd_vma got_offset = (plt_index + 3) * 4;
1946
34e967a5
MC
1947 ARC_DEBUG ("arc_info: PLT_OFFSET = 0x%x, PLT_ENTRY_VMA = 0x%x, \
1948GOT_ENTRY_OFFSET = 0x%x, GOT_ENTRY_VMA = 0x%x, for symbol %s\n",
1949 h->plt.offset,
1950 htab->splt->output_section->vma
1951 + htab->splt->output_offset
1952 + h->plt.offset,
1953 got_offset,
1954 htab->sgotplt->output_section->vma
1955 + htab->sgotplt->output_offset
1956 + got_offset,
1957 h->root.root.string);
1958
1959 memcpy (htab->splt->contents + h->plt.offset,
1960 plt_data->elem,
1961 plt_data->elem_size);
1962 plt_do_relocs_for_symbol (output_bfd, htab,
1963 plt_data->elem_relocs,
1964 h->plt.offset,
886a2506 1965 got_offset);
34e967a5
MC
1966
1967 /* Fill in the entry in the global offset table. */
1968 bfd_put_32 (output_bfd,
1969 (bfd_vma) (htab->splt->output_section->vma
1970 + htab->splt->output_offset),
1971 htab->sgotplt->contents + got_offset);
1972
1973 /* TODO: Fill in the entry in the .rela.plt section. */
1974 {
1975 Elf_Internal_Rela rel;
1976 bfd_byte *loc;
1977
1978 rel.r_offset = (htab->sgotplt->output_section->vma
1979 + htab->sgotplt->output_offset
1980 + got_offset);
1981 rel.r_addend = 0;
1982 rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_JMP_SLOT);
1983
1984 loc = htab->srelplt->contents;
1985 loc += plt_index * sizeof (Elf32_External_Rela); /* relA */
1986 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
1987 }
886a2506
NC
1988}
1989
1990static void
34e967a5
MC
1991relocate_plt_for_entry (bfd *abfd,
1992 struct bfd_link_info *info)
886a2506 1993{
34e967a5
MC
1994 struct plt_version_t *plt_data = arc_get_plt_version (info);
1995 struct elf_link_hash_table *htab = elf_hash_table (info);
886a2506 1996
34e967a5
MC
1997 memcpy (htab->splt->contents, plt_data->entry,
1998 plt_data->entry_size);
1999 PLT_DO_RELOCS_FOR_ENTRY (abfd, htab, plt_data->entry_relocs);
886a2506
NC
2000}
2001
34e967a5
MC
2002/* Desc : Adjust a symbol defined by a dynamic object and referenced
2003 by a regular object. The current definition is in some section of
2004 the dynamic object, but we're not including those sections. We
2005 have to change the definition to something the rest of the link can
886a2506
NC
2006 understand. */
2007
2008static bfd_boolean
2009elf_arc_adjust_dynamic_symbol (struct bfd_link_info *info,
2010 struct elf_link_hash_entry *h)
2011{
34e967a5
MC
2012 asection *s;
2013 unsigned int power_of_two;
886a2506 2014 bfd *dynobj = (elf_hash_table (info))->dynobj;
34e967a5 2015 struct elf_link_hash_table *htab = elf_hash_table (info);
886a2506 2016
34e967a5
MC
2017 if (h->type == STT_FUNC
2018 || h->type == STT_GNU_IFUNC
2019 || h->needs_plt == 1)
886a2506
NC
2020 {
2021 if (!bfd_link_pic (info) && !h->def_dynamic && !h->ref_dynamic)
2022 {
2023 /* This case can occur if we saw a PLT32 reloc in an input
2024 file, but the symbol was never referred to by a dynamic
2025 object. In such a case, we don't actually need to build
2026 a procedure linkage table, and we can just do a PC32
2027 reloc instead. */
2028 BFD_ASSERT (h->needs_plt);
2029 return TRUE;
2030 }
2031
2032 /* Make sure this symbol is output as a dynamic symbol. */
2033 if (h->dynindx == -1 && !h->forced_local
2034 && !bfd_elf_link_record_dynamic_symbol (info, h))
2035 return FALSE;
2036
34e967a5
MC
2037 if (bfd_link_pic (info)
2038 || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
886a2506
NC
2039 {
2040 bfd_vma loc = add_symbol_to_plt (info);
2041
2042 if (!bfd_link_pic (info) && !h->def_regular)
2043 {
34e967a5 2044 h->root.u.def.section = htab->splt;
886a2506
NC
2045 h->root.u.def.value = loc;
2046 }
2047 h->plt.offset = loc;
2048 }
34e967a5
MC
2049 else
2050 {
2051 h->plt.offset = (bfd_vma) -1;
2052 h->needs_plt = 0;
2053 }
2054 return TRUE;
886a2506 2055 }
34e967a5
MC
2056
2057 /* If this is a weak symbol, and there is a real definition, the
2058 processor independent code will have arranged for us to see the
2059 real definition first, and we can just use the same value. */
2060 if (h->u.weakdef != NULL)
886a2506 2061 {
34e967a5
MC
2062 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2063 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2064 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2065 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2066 return TRUE;
886a2506
NC
2067 }
2068
34e967a5
MC
2069 /* If there are no non-GOT references, we do not need a copy
2070 relocation. */
2071 if (!h->non_got_ref)
2072 return TRUE;
2073
2074 /* This is a reference to a symbol defined by a dynamic object which
2075 is not a function. */
2076
2077 /* If we are creating a shared library, we must presume that the
2078 only references to the symbol are via the global offset table.
2079 For such cases we need not do anything here; the relocations will
2080 be handled correctly by relocate_section. */
2081 if (bfd_link_pic (info))
2082 return TRUE;
2083
2084 /* We must allocate the symbol in our .dynbss section, which will
2085 become part of the .bss section of the executable. There will be
2086 an entry for this symbol in the .dynsym section. The dynamic
2087 object will contain position independent code, so all references
2088 from the dynamic object to this symbol will go through the global
2089 offset table. The dynamic linker will use the .dynsym entry to
2090 determine the address it must put in the global offset table, so
2091 both the dynamic object and the regular object will refer to the
2092 same memory location for the variable. */
2093
2094 s = bfd_get_section_by_name (dynobj, ".dynbss");
2095 BFD_ASSERT (s != NULL);
2096
2097 /* We must generate a R_ARC_COPY reloc to tell the dynamic linker to
2098 copy the initial value out of the dynamic object and into the
2099 runtime process image. We need to remember the offset into the
2100 .rela.bss section we are going to use. */
2101 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2102 {
2103 asection *srel;
2104
2105 srel = bfd_get_section_by_name (dynobj, ".rela.bss");
2106 BFD_ASSERT (srel != NULL);
2107 srel->size += sizeof (Elf32_External_Rela);
2108 h->needs_copy = 1;
2109 }
2110
2111 /* We need to figure out the alignment required for this symbol. I
2112 have no idea how ELF linkers handle this. */
2113 power_of_two = bfd_log2 (h->size);
2114 if (power_of_two > 3)
2115 power_of_two = 3;
886a2506 2116
34e967a5
MC
2117 /* Apply the required alignment. */
2118 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
2119 if (power_of_two > bfd_get_section_alignment (dynobj, s))
2120 {
2121 if (! bfd_set_section_alignment (dynobj, s, power_of_two))
2122 return FALSE;
2123 }
2124
2125 /* Define the symbol as being at this point in the section. */
2126 h->root.u.def.section = s;
2127 h->root.u.def.value = s->size;
2128
2129 /* Increment the section size to make room for the symbol. */
2130 s->size += h->size;
2131
2132 return TRUE;
886a2506
NC
2133}
2134
2135/* Function : elf_arc_finish_dynamic_symbol
2136 Brief : Finish up dynamic symbol handling. We set the
34e967a5 2137 contents of various dynamic sections here.
886a2506 2138 Args : output_bfd :
34e967a5
MC
2139 info :
2140 h :
2141 sym :
886a2506 2142 Returns : True/False as the return status. */
34e967a5 2143
886a2506
NC
2144static bfd_boolean
2145elf_arc_finish_dynamic_symbol (bfd * output_bfd,
2146 struct bfd_link_info *info,
2147 struct elf_link_hash_entry *h,
2148 Elf_Internal_Sym * sym)
2149{
34e967a5 2150 if (h->plt.offset != (bfd_vma) -1)
886a2506 2151 {
34e967a5
MC
2152 relocate_plt_for_symbol (output_bfd, info, h);
2153
2154 if (!h->def_regular)
886a2506 2155 {
34e967a5
MC
2156 /* Mark the symbol as undefined, rather than as defined in
2157 the .plt section. Leave the value alone. */
2158 sym->st_shndx = SHN_UNDEF;
886a2506 2159 }
34e967a5
MC
2160 }
2161
2162 if (h->got.glist != NULL)
2163 {
2164 struct got_entry *list = h->got.glist;
2165
2166 /* Traverse the list of got entries for this symbol. */
2167 while (list)
886a2506 2168 {
34e967a5
MC
2169 bfd_vma got_offset = h->got.glist->offset;
2170
2171 if (list->type == GOT_NORMAL
2172 && list->created_dyn_relocation == FALSE)
2173 {
2174 if (bfd_link_pic (info)
2175 && (info->symbolic || h->dynindx == -1)
2176 && h->def_regular)
2177 {
2178 ADD_RELA (output_bfd, got, got_offset, 0, R_ARC_RELATIVE, 0);
2179 }
2180 else
2181 {
2182 ADD_RELA (output_bfd, got, got_offset, h->dynindx,
2183 R_ARC_GLOB_DAT, 0);
2184 }
2185 list->created_dyn_relocation = TRUE;
2186 }
2187 else if (list->existing_entries != NONE)
2188 {
2189 struct elf_link_hash_table *htab = elf_hash_table (info);
2190 enum tls_got_entries e = list->existing_entries;
2191
2192 BFD_ASSERT (list->type != GOT_TLS_GD
2193 || list->existing_entries == MOD_AND_OFF);
2194
840855c5 2195 bfd_vma dynindx = h->dynindx == -1 ? 0 : h->dynindx;
34e967a5
MC
2196 if (e == MOD_AND_OFF || e == MOD)
2197 {
840855c5 2198 ADD_RELA (output_bfd, got, got_offset, dynindx,
34e967a5
MC
2199 R_ARC_TLS_DTPMOD, 0);
2200 ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2201GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2202 list->type,
2203 got_offset,
2204 htab->sgot->output_section->vma
2205 + htab->sgot->output_offset + got_offset,
840855c5 2206 dynindx, 0);
34e967a5
MC
2207 }
2208 if (e == MOD_AND_OFF || e == OFF)
2209 {
2210 bfd_vma addend = 0;
2211 if (list->type == GOT_TLS_IE)
2212 addend = bfd_get_32 (output_bfd,
2213 htab->sgot->contents + got_offset);
2214
2215 ADD_RELA (output_bfd, got,
2216 got_offset + (e == MOD_AND_OFF ? 4 : 0),
840855c5 2217 dynindx,
34e967a5
MC
2218 (list->type == GOT_TLS_IE ?
2219 R_ARC_TLS_TPOFF : R_ARC_TLS_DTPOFF),
2220 addend);
2221
2222 ARC_DEBUG ("arc_info: TLS_DYNRELOC: type = %d, \
2223GOT_OFFSET = 0x%x, GOT_VMA = 0x%x, INDEX = %d, ADDEND = 0x%x\n",
2224 list->type,
2225 got_offset,
2226 htab->sgot->output_section->vma
2227 + htab->sgot->output_offset + got_offset,
840855c5 2228 dynindx, addend);
34e967a5
MC
2229 }
2230 }
2231
2232 list = list->next;
886a2506 2233 }
34e967a5
MC
2234
2235 h->got.glist = NULL;
2236 }
2237
2238 if (h->needs_copy)
2239 {
2240 bfd_vma rel_offset = (h->root.u.def.value
2241 + h->root.u.def.section->output_section->vma
2242 + h->root.u.def.section->output_offset);
2243
2244 asection *srelbss =
2245 bfd_get_section_by_name (h->root.u.def.section->owner,
2246 ".rela.bss");
2247
23a42089
NC
2248 bfd_byte * loc = srelbss->contents
2249 + (srelbss->reloc_count * sizeof (Elf32_External_Rela));
34e967a5
MC
2250 srelbss->reloc_count++;
2251
2252 Elf_Internal_Rela rel;
2253 rel.r_addend = 0;
2254 rel.r_offset = rel_offset;
2255 rel.r_info = ELF32_R_INFO (h->dynindx, R_ARC_COPY);
2256
23a42089 2257 bfd_elf32_swap_reloca_out (output_bfd, &rel, loc);
886a2506
NC
2258 }
2259
2260 /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */
2261 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2262 || strcmp (h->root.root.string, "__DYNAMIC") == 0
2263 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
2264 sym->st_shndx = SHN_ABS;
2265
2266 return TRUE;
2267}
2268
34e967a5
MC
2269#define GET_SYMBOL_OR_SECTION(TAG, SYMBOL, SECTION, ASSERT) \
2270 case TAG: \
2271 if (SYMBOL != NULL) \
2272 { \
2273 h = elf_link_hash_lookup (elf_hash_table (info), \
2274 SYMBOL, FALSE, FALSE, TRUE); \
2275 } \
2276 else if (SECTION != NULL) \
2277 { \
2278 s = bfd_get_section_by_name (output_bfd, SECTION); \
2279 BFD_ASSERT (s != NULL || !ASSERT); \
2280 do_it = TRUE; \
2281 } \
2282 break;
886a2506
NC
2283
2284/* Function : elf_arc_finish_dynamic_sections
2285 Brief : Finish up the dynamic sections handling.
2286 Args : output_bfd :
34e967a5
MC
2287 info :
2288 h :
2289 sym :
886a2506 2290 Returns : True/False as the return status. */
34e967a5 2291
886a2506 2292static bfd_boolean
34e967a5
MC
2293elf_arc_finish_dynamic_sections (bfd * output_bfd,
2294 struct bfd_link_info *info)
886a2506
NC
2295{
2296 struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
34e967a5 2297 struct elf_link_hash_table *htab = elf_hash_table (info);
886a2506
NC
2298 bfd *dynobj = (elf_hash_table (info))->dynobj;
2299
2300 if (ds.sdyn)
2301 {
2302 Elf32_External_Dyn *dyncon, *dynconend;
2303
2304 dyncon = (Elf32_External_Dyn *) ds.sdyn->contents;
2305 dynconend =
34e967a5 2306 (Elf32_External_Dyn *) (ds.sdyn->contents + ds.sdyn->size);
886a2506
NC
2307 for (; dyncon < dynconend; dyncon++)
2308 {
2309 Elf_Internal_Dyn internal_dyn;
2310 bfd_boolean do_it = FALSE;
2311
2312 struct elf_link_hash_entry *h = NULL;
2313 asection *s = NULL;
2314
2315 bfd_elf32_swap_dyn_in (dynobj, dyncon, &internal_dyn);
2316
2317 switch (internal_dyn.d_tag)
2318 {
34e967a5
MC
2319 GET_SYMBOL_OR_SECTION (DT_INIT, "_init", NULL, TRUE)
2320 GET_SYMBOL_OR_SECTION (DT_FINI, "_fini", NULL, TRUE)
2321 GET_SYMBOL_OR_SECTION (DT_PLTGOT, NULL, ".plt", TRUE)
2322 GET_SYMBOL_OR_SECTION (DT_JMPREL, NULL, ".rela.plt", TRUE)
2323 GET_SYMBOL_OR_SECTION (DT_PLTRELSZ, NULL, ".rela.plt", TRUE)
2324 GET_SYMBOL_OR_SECTION (DT_RELASZ, NULL, ".rela.plt", FALSE)
2325 GET_SYMBOL_OR_SECTION (DT_VERSYM, NULL, ".gnu.version", TRUE)
2326 GET_SYMBOL_OR_SECTION (DT_VERDEF, NULL, ".gnu.version_d", TRUE)
2327 GET_SYMBOL_OR_SECTION (DT_VERNEED, NULL, ".gnu.version_r", TRUE)
886a2506
NC
2328 default:
2329 break;
2330 }
2331
34e967a5 2332 /* In case the dynamic symbols should be updated with a symbol. */
886a2506
NC
2333 if (h != NULL
2334 && (h->root.type == bfd_link_hash_defined
34e967a5 2335 || h->root.type == bfd_link_hash_defweak))
886a2506
NC
2336 {
2337 asection *asec_ptr;
2338
2339 internal_dyn.d_un.d_val = h->root.u.def.value;
2340 asec_ptr = h->root.u.def.section;
2341 if (asec_ptr->output_section != NULL)
2342 {
2343 internal_dyn.d_un.d_val +=
2344 (asec_ptr->output_section->vma +
2345 asec_ptr->output_offset);
2346 }
2347 else
2348 {
34e967a5
MC
2349 /* The symbol is imported from another shared
2350 library and does not apply to this one. */
886a2506
NC
2351 internal_dyn.d_un.d_val = 0;
2352 }
2353 do_it = TRUE;
2354 }
2355 else if (s != NULL) /* With a section information. */
2356 {
2357 switch (internal_dyn.d_tag)
2358 {
2359 case DT_PLTGOT:
2360 case DT_JMPREL:
34e967a5
MC
2361 case DT_VERSYM:
2362 case DT_VERDEF:
2363 case DT_VERNEED:
886a2506
NC
2364 internal_dyn.d_un.d_ptr = s->vma;
2365 do_it = TRUE;
2366 break;
2367
2368 case DT_PLTRELSZ:
2369 internal_dyn.d_un.d_val = s->size;
2370 do_it = TRUE;
2371 break;
2372
2373 case DT_RELASZ:
34e967a5
MC
2374 if (s != NULL)
2375 internal_dyn.d_un.d_val -= s->size;
886a2506
NC
2376 do_it = TRUE;
2377 break;
2378
2379 default:
2380 break;
2381 }
2382 }
2383
2384 if (do_it == TRUE)
2385 bfd_elf32_swap_dyn_out (output_bfd, &internal_dyn, dyncon);
2386 }
2387
34e967a5 2388 if (htab->splt->size > 0)
886a2506 2389 {
34e967a5 2390 relocate_plt_for_entry (output_bfd, info);
886a2506
NC
2391 }
2392
34e967a5
MC
2393 /* TODO: Validate this. */
2394 elf_section_data (htab->srelplt->output_section)->this_hdr.sh_entsize
2395 = 0xc;
886a2506
NC
2396 }
2397
2398 /* Fill in the first three entries in the global offset table. */
34e967a5 2399 if (htab->sgot)
886a2506 2400 {
34e967a5 2401 if (htab->sgot->size > 0 || htab->sgotplt->size > 0)
886a2506
NC
2402 {
2403 if (ds.sdyn == NULL)
2404 bfd_put_32 (output_bfd, (bfd_vma) 0,
34e967a5 2405 htab->sgotplt->contents);
886a2506
NC
2406 else
2407 bfd_put_32 (output_bfd,
2408 ds.sdyn->output_section->vma + ds.sdyn->output_offset,
34e967a5
MC
2409 htab->sgotplt->contents);
2410 bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 4);
2411 bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 8);
886a2506
NC
2412 }
2413 }
2414
886a2506
NC
2415 return TRUE;
2416}
2417
34e967a5
MC
2418#define ADD_DYNAMIC_SYMBOL(NAME, TAG) \
2419 h = elf_link_hash_lookup (elf_hash_table (info), \
2420 NAME, FALSE, FALSE, FALSE); \
2421 if ((h != NULL && (h->ref_regular || h->def_regular))) \
2422 if (! _bfd_elf_add_dynamic_entry (info, TAG, 0)) \
886a2506
NC
2423 return FALSE;
2424
2425/* Set the sizes of the dynamic sections. */
2426static bfd_boolean
34e967a5
MC
2427elf_arc_size_dynamic_sections (bfd * output_bfd,
2428 struct bfd_link_info *info)
886a2506 2429{
34e967a5 2430 bfd * dynobj;
886a2506 2431 asection * s;
34e967a5
MC
2432 bfd_boolean relocs_exist = FALSE;
2433 bfd_boolean reltext_exist = FALSE;
886a2506 2434 struct dynamic_sections ds = arc_create_dynamic_sections (output_bfd, info);
34e967a5 2435 struct elf_link_hash_table *htab = elf_hash_table (info);
886a2506
NC
2436
2437 dynobj = (elf_hash_table (info))->dynobj;
2438 BFD_ASSERT (dynobj != NULL);
2439
2440 if ((elf_hash_table (info))->dynamic_sections_created)
2441 {
2442 struct elf_link_hash_entry *h;
2443
34e967a5
MC
2444 /* Set the contents of the .interp section to the
2445 interpreter. */
886a2506
NC
2446 if (!bfd_link_pic (info))
2447 {
2448 s = bfd_get_section_by_name (dynobj, ".interp");
2449 BFD_ASSERT (s != NULL);
34e967a5 2450 s->size = sizeof (ELF_DYNAMIC_INTERPRETER);
886a2506
NC
2451 s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
2452 }
2453
34e967a5
MC
2454 /* Add some entries to the .dynamic section. We fill in some of
2455 the values later, in elf_bfd_final_link, but we must add the
2456 entries now so that we know the final size of the .dynamic
2457 section. Checking if the .init section is present. We also
2458 create DT_INIT and DT_FINI entries if the init_str has been
2459 changed by the user. */
886a2506
NC
2460 ADD_DYNAMIC_SYMBOL ("init", DT_INIT);
2461 ADD_DYNAMIC_SYMBOL ("fini", DT_FINI);
2462 }
2463 else
2464 {
34e967a5
MC
2465 /* We may have created entries in the .rela.got section.
2466 However, if we are not creating the dynamic sections, we will
2467 not actually use these entries. Reset the size of .rela.got,
2468 which will cause it to get stripped from the output file
2469 below. */
2470 if (htab->srelgot != NULL)
2471 htab->srelgot->size = 0;
886a2506
NC
2472 }
2473
34e967a5
MC
2474 if (htab->splt != NULL && htab->splt->size == 0)
2475 htab->splt->flags |= SEC_EXCLUDE;
886a2506
NC
2476 for (s = dynobj->sections; s != NULL; s = s->next)
2477 {
34e967a5 2478 if ((s->flags & SEC_LINKER_CREATED) == 0)
886a2506
NC
2479 continue;
2480
34e967a5 2481 if (strncmp (s->name, ".rela", 5) == 0)
886a2506 2482 {
34e967a5
MC
2483 if (s->size == 0)
2484 {
2485 s->flags |= SEC_EXCLUDE;
2486 }
2487 else
2488 {
2489 if (strcmp (s->name, ".rela.plt") != 0)
2490 {
2491 const char *outname =
2492 bfd_get_section_name (output_bfd,
2493 htab->srelplt->output_section);
2494
2495 asection *target = bfd_get_section_by_name (output_bfd,
2496 outname + 4);
2497
2498 relocs_exist = TRUE;
2499 if (target != NULL && target->size != 0
2500 && (target->flags & SEC_READONLY) != 0
2501 && (target->flags & SEC_ALLOC) != 0)
2502 reltext_exist = TRUE;
2503 }
2504 }
886a2506 2505
34e967a5
MC
2506 /* We use the reloc_count field as a counter if we need to
2507 copy relocs into the output file. */
2508 s->reloc_count = 0;
886a2506 2509 }
34e967a5
MC
2510
2511 if (strcmp (s->name, ".dynamic") == 0)
2512 continue;
2513
2514 if (s->size != 0)
2515 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2516
2517 if (s->contents == NULL && s->size != 0)
2518 return FALSE;
886a2506
NC
2519 }
2520
2521 if (ds.sdyn)
2522 {
34e967a5
MC
2523 /* TODO: Check if this is needed. */
2524 if (!bfd_link_pic (info))
2525 if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
2526 return FALSE;
2527
2528 if (htab->splt && (htab->splt->flags & SEC_EXCLUDE) == 0)
886a2506
NC
2529 if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
2530 || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
2531 || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
2532 || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0)
2533 )
2534 return FALSE;
2535
2536 if (relocs_exist == TRUE)
2537 if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
2538 || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
2539 || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
2540 sizeof (Elf32_External_Rela))
2541 )
2542 return FALSE;
2543
2544 if (reltext_exist == TRUE)
2545 if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
2546 return FALSE;
2547 }
2548
2549 return TRUE;
2550}
2551
34e967a5
MC
2552const struct elf_size_info arc_elf32_size_info =
2553{
2554 sizeof (Elf32_External_Ehdr),
2555 sizeof (Elf32_External_Phdr),
2556 sizeof (Elf32_External_Shdr),
2557 sizeof (Elf32_External_Rel),
2558 sizeof (Elf32_External_Rela),
2559 sizeof (Elf32_External_Sym),
2560 sizeof (Elf32_External_Dyn),
2561 sizeof (Elf_External_Note),
2562 4,
2563 1,
2564 32, 2,
2565 ELFCLASS32, EV_CURRENT,
2566 bfd_elf32_write_out_phdrs,
2567 bfd_elf32_write_shdrs_and_ehdr,
2568 bfd_elf32_checksum_contents,
2569 bfd_elf32_write_relocs,
2570 bfd_elf32_swap_symbol_in,
2571 bfd_elf32_swap_symbol_out,
2572 bfd_elf32_slurp_reloc_table,
2573 bfd_elf32_slurp_symbol_table,
2574 bfd_elf32_swap_dyn_in,
2575 bfd_elf32_swap_dyn_out,
2576 bfd_elf32_swap_reloc_in,
2577 bfd_elf32_swap_reloc_out,
2578 bfd_elf32_swap_reloca_in,
2579 bfd_elf32_swap_reloca_out
2580};
2581
2582#define elf_backend_size_info arc_elf32_size_info
2583
2584static struct bfd_link_hash_table *
2585arc_elf_link_hash_table_create (bfd *abfd)
2586{
2587 struct elf_link_hash_table *htab;
2588
2589 htab = bfd_zmalloc (sizeof (*htab));
2590 if (htab == NULL)
2591 return NULL;
2592
2593 if (!_bfd_elf_link_hash_table_init (htab, abfd,
2594 _bfd_elf_link_hash_newfunc,
2595 sizeof (struct elf_link_hash_entry),
2596 GENERIC_ELF_DATA))
2597 {
2598 free (htab);
2599 return NULL;
2600 }
2601
2602 htab->init_got_refcount.refcount = 0;
2603 htab->init_got_refcount.glist = NULL;
2604 htab->init_got_offset.offset = 0;
2605 htab->init_got_offset.glist = NULL;
2606 return (struct bfd_link_hash_table *) htab;
2607}
2608
2609/* Hook called by the linker routine which adds symbols from an object
2610 file. */
2611
2612static bfd_boolean
2613elf_arc_add_symbol_hook (bfd * abfd,
2614 struct bfd_link_info * info,
2615 Elf_Internal_Sym * sym,
2616 const char ** namep ATTRIBUTE_UNUSED,
2617 flagword * flagsp ATTRIBUTE_UNUSED,
2618 asection ** secp ATTRIBUTE_UNUSED,
2619 bfd_vma * valp ATTRIBUTE_UNUSED)
2620{
2621 if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
2622 || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
2623 && (abfd->flags & DYNAMIC) == 0
2624 && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
2625 elf_tdata (info->output_bfd)->has_gnu_symbols = elf_gnu_symbol_any;
2626
2627 return TRUE;
2628}
886a2506 2629
6d00b590 2630#define TARGET_LITTLE_SYM arc_elf32_le_vec
47b0e7ad 2631#define TARGET_LITTLE_NAME "elf32-littlearc"
886a2506
NC
2632#define TARGET_BIG_SYM arc_elf32_be_vec
2633#define TARGET_BIG_NAME "elf32-bigarc"
2634#define ELF_ARCH bfd_arch_arc
2635#define ELF_MACHINE_CODE EM_ARC_COMPACT
2636#define ELF_MACHINE_ALT1 EM_ARC_COMPACT2
2637#define ELF_MAXPAGESIZE 0x2000
2638
34e967a5
MC
2639#define bfd_elf32_bfd_link_hash_table_create arc_elf_link_hash_table_create
2640
2641#define bfd_elf32_bfd_merge_private_bfd_data arc_elf_merge_private_bfd_data
2642#define bfd_elf32_bfd_reloc_type_lookup arc_elf32_bfd_reloc_type_lookup
2643#define bfd_elf32_bfd_set_private_flags arc_elf_set_private_flags
2644#define bfd_elf32_bfd_print_private_bfd_data arc_elf_print_private_bfd_data
2645#define bfd_elf32_bfd_copy_private_bfd_data arc_elf_copy_private_bfd_data
2646
886a2506
NC
2647#define elf_info_to_howto_rel arc_info_to_howto_rel
2648#define elf_backend_object_p arc_elf_object_p
2649#define elf_backend_final_write_processing arc_elf_final_write_processing
2650
2651#define elf_backend_relocate_section elf_arc_relocate_section
2652#define elf_backend_check_relocs elf_arc_check_relocs
2653#define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
2654
2655#define elf_backend_adjust_dynamic_symbol elf_arc_adjust_dynamic_symbol
2656#define elf_backend_finish_dynamic_symbol elf_arc_finish_dynamic_symbol
2657
2658#define elf_backend_finish_dynamic_sections elf_arc_finish_dynamic_sections
2659#define elf_backend_size_dynamic_sections elf_arc_size_dynamic_sections
34e967a5 2660#define elf_backend_add_symbol_hook elf_arc_add_symbol_hook
886a2506
NC
2661
2662#define elf_backend_can_gc_sections 1
2663#define elf_backend_want_got_plt 1
2664#define elf_backend_plt_readonly 1
34e967a5 2665#define elf_backend_rela_plts_and_copies_p 1
886a2506
NC
2666#define elf_backend_want_plt_sym 0
2667#define elf_backend_got_header_size 12
2668
2669#define elf_backend_may_use_rel_p 0
2670#define elf_backend_may_use_rela_p 1
2671#define elf_backend_default_use_rela_p 1
252b5132
RH
2672
2673#include "elf32-target.h"