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