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