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