Coverage Report

Created: 2025-06-24 06:45

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