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