Coverage Report

Created: 2026-05-11 07:54

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