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