Coverage Report

Created: 2023-08-28 06:25

/src/binutils-gdb/bfd/elf64-loongarch.c
Line
Count
Source (jump to first uncovered line)
1
#line 1 "elfnn-loongarch.c"
2
/* LoongArch-specific support for 64-bit ELF.
3
   Copyright (C) 2021-2023 Free Software Foundation, Inc.
4
   Contributed by Loongson Ltd.
5
6
   This file is part of BFD, the Binary File Descriptor library.
7
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
18
   You should have received a copy of the GNU General Public License
19
   along with this program; see the file COPYING3.  If not,
20
   see <http://www.gnu.org/licenses/>.  */
21
22
#include "ansidecl.h"
23
#include "sysdep.h"
24
#include "bfd.h"
25
#include "libbfd.h"
26
0
#define ARCH_SIZE 64
27
#include "elf-bfd.h"
28
#include "objalloc.h"
29
#include "elf/loongarch.h"
30
#include "elfxx-loongarch.h"
31
#include "opcode/loongarch.h"
32
33
static bool
34
loongarch_info_to_howto_rela (bfd *abfd, arelent *cache_ptr,
35
            Elf_Internal_Rela *dst)
36
0
{
37
0
  cache_ptr->howto = loongarch_elf_rtype_to_howto (abfd,
38
0
               ELF64_R_TYPE (dst->r_info));
39
0
  return cache_ptr->howto != NULL;
40
0
}
41
42
/* LoongArch ELF linker hash entry.  */
43
struct loongarch_elf_link_hash_entry
44
{
45
  struct elf_link_hash_entry elf;
46
47
0
#define GOT_UNKNOWN 0
48
0
#define GOT_NORMAL  1
49
0
#define GOT_TLS_GD  2
50
0
#define GOT_TLS_IE  4
51
0
#define GOT_TLS_LE  8
52
  char tls_type;
53
};
54
55
#define loongarch_elf_hash_entry(ent) \
56
0
  ((struct loongarch_elf_link_hash_entry *) (ent))
57
58
struct _bfd_loongarch_elf_obj_tdata
59
{
60
  struct elf_obj_tdata root;
61
62
  /* The tls_type for each local got entry.  */
63
  char *local_got_tls_type;
64
};
65
66
#define _bfd_loongarch_elf_tdata(abfd)  \
67
0
  ((struct _bfd_loongarch_elf_obj_tdata *) (abfd)->tdata.any)
68
69
#define _bfd_loongarch_elf_local_got_tls_type(abfd) \
70
0
  (_bfd_loongarch_elf_tdata (abfd)->local_got_tls_type)
71
72
#define _bfd_loongarch_elf_tls_type(abfd, h, symndx)      \
73
0
  (*((h) != NULL              \
74
0
     ? &loongarch_elf_hash_entry (h)->tls_type        \
75
0
     : &_bfd_loongarch_elf_local_got_tls_type (abfd)[symndx]))
76
77
#define is_loongarch_elf(bfd)           \
78
0
  (bfd_get_flavour (bfd) == bfd_target_elf_flavour      \
79
0
   && elf_tdata (bfd) != NULL            \
80
0
   && elf_object_id (bfd) == LARCH_ELF_DATA)
81
82
struct loongarch_elf_link_hash_table
83
{
84
  struct elf_link_hash_table elf;
85
86
  /* Short-cuts to get to dynamic linker sections.  */
87
  asection *sdyntdata;
88
89
  /* Small local sym to section mapping cache.  */
90
  struct sym_cache sym_cache;
91
92
  /* Used by local STT_GNU_IFUNC symbols.  */
93
  htab_t loc_hash_table;
94
  void *loc_hash_memory;
95
96
  /* The max alignment of output sections.  */
97
  bfd_vma max_alignment;
98
99
  /* The data segment phase, don't relax the section
100
     when it is exp_seg_relro_adjust.  */
101
  int *data_segment_phase;
102
};
103
104
/* Get the LoongArch ELF linker hash table from a link_info structure.  */
105
#define loongarch_elf_hash_table(p)         \
106
0
  (elf_hash_table_id (elf_hash_table (p)) == LARCH_ELF_DATA    \
107
0
   ? ((struct loongarch_elf_link_hash_table *) ((p)->hash))    \
108
0
   : NULL)
109
110
0
#define MINUS_ONE ((bfd_vma) 0 - 1)
111
112
0
#define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset)
113
114
0
#define LARCH_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3)
115
0
#define LARCH_ELF_WORD_BYTES (1 << LARCH_ELF_LOG_WORD_BYTES)
116
117
0
#define PLT_HEADER_INSNS 8
118
0
#define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
119
120
0
#define PLT_ENTRY_INSNS 4
121
0
#define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
122
123
0
#define GOT_ENTRY_SIZE (LARCH_ELF_WORD_BYTES)
124
125
0
#define GOTPLT_HEADER_SIZE (GOT_ENTRY_SIZE * 2)
126
127
#define elf_backend_want_got_plt 1
128
129
#define elf_backend_plt_readonly 1
130
131
#define elf_backend_want_plt_sym 1
132
#define elf_backend_plt_alignment 4
133
#define elf_backend_can_gc_sections 1
134
#define elf_backend_can_refcount 1
135
#define elf_backend_want_got_sym 1
136
137
#define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1)
138
139
#define elf_backend_want_dynrelro 1
140
#define elf_backend_rela_normal 1
141
#define elf_backend_default_execstack 0
142
143
/* Generate a PLT header.  */
144
145
static bool
146
loongarch_make_plt_header (bfd_vma got_plt_addr, bfd_vma plt_header_addr,
147
         uint32_t *entry)
148
0
{
149
0
  bfd_vma pcrel = got_plt_addr - plt_header_addr;
150
0
  bfd_vma hi, lo;
151
152
0
  if (pcrel + 0x80000800 > 0xffffffff)
153
0
    {
154
0
      _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
155
0
      bfd_set_error (bfd_error_bad_value);
156
0
      return false;
157
0
    }
158
0
  hi = ((pcrel + 0x800) >> 12) & 0xfffff;
159
0
  lo = pcrel & 0xfff;
160
161
  /* pcaddu12i  $t2, %hi(%pcrel(.got.plt))
162
     sub.[wd]   $t1, $t1, $t3
163
     ld.[wd]    $t3, $t2, %lo(%pcrel(.got.plt)) # _dl_runtime_resolve
164
     addi.[wd]  $t1, $t1, -(PLT_HEADER_SIZE + 12)
165
     addi.[wd]  $t0, $t2, %lo(%pcrel(.got.plt))
166
     srli.[wd]  $t1, $t1, log2(16 / GOT_ENTRY_SIZE)
167
     ld.[wd]    $t0, $t0, GOT_ENTRY_SIZE
168
     jirl   $r0, $t3, 0 */
169
170
0
  if (GOT_ENTRY_SIZE == 8)
171
0
    {
172
0
      entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
173
0
      entry[1] = 0x0011bdad;
174
0
      entry[2] = 0x28c001cf | (lo & 0xfff) << 10;
175
0
      entry[3] = 0x02c001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
176
0
      entry[4] = 0x02c001cc | (lo & 0xfff) << 10;
177
0
      entry[5] = 0x004501ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
178
0
      entry[6] = 0x28c0018c | GOT_ENTRY_SIZE << 10;
179
0
      entry[7] = 0x4c0001e0;
180
0
    }
181
0
  else
182
0
    {
183
0
      entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
184
0
      entry[1] = 0x00113dad;
185
0
      entry[2] = 0x288001cf | (lo & 0xfff) << 10;
186
0
      entry[3] = 0x028001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
187
0
      entry[4] = 0x028001cc | (lo & 0xfff) << 10;
188
0
      entry[5] = 0x004481ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
189
0
      entry[6] = 0x2880018c | GOT_ENTRY_SIZE << 10;
190
0
      entry[7] = 0x4c0001e0;
191
0
    }
192
0
  return true;
193
0
}
194
195
/* Generate a PLT entry.  */
196
197
static bool
198
loongarch_make_plt_entry (bfd_vma got_plt_entry_addr, bfd_vma plt_entry_addr,
199
        uint32_t *entry)
200
0
{
201
0
  bfd_vma pcrel = got_plt_entry_addr - plt_entry_addr;
202
0
  bfd_vma hi, lo;
203
204
0
  if (pcrel + 0x80000800 > 0xffffffff)
205
0
    {
206
0
      _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
207
0
      bfd_set_error (bfd_error_bad_value);
208
0
      return false;
209
0
    }
210
0
  hi = ((pcrel + 0x800) >> 12) & 0xfffff;
211
0
  lo = pcrel & 0xfff;
212
213
0
  entry[0] = 0x1c00000f | (hi & 0xfffff) << 5;
214
0
  entry[1] = ((GOT_ENTRY_SIZE == 8 ? 0x28c001ef : 0x288001ef)
215
0
        | (lo & 0xfff) << 10);
216
0
  entry[2] = 0x4c0001ed;  /* jirl $r13, $15, 0 */
217
0
  entry[3] = 0x03400000;  /* nop */
218
219
0
  return true;
220
0
}
221
222
/* Create an entry in an LoongArch ELF linker hash table.  */
223
224
static struct bfd_hash_entry *
225
link_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
226
       const char *string)
227
0
{
228
0
  struct loongarch_elf_link_hash_entry *eh;
229
230
  /* Allocate the structure if it has not already been allocated by a
231
     subclass.  */
232
0
  if (entry == NULL)
233
0
    {
234
0
      entry = bfd_hash_allocate (table, sizeof (*eh));
235
0
      if (entry == NULL)
236
0
  return entry;
237
0
    }
238
239
  /* Call the allocation method of the superclass.  */
240
0
  entry = _bfd_elf_link_hash_newfunc (entry, table, string);
241
0
  if (entry != NULL)
242
0
    {
243
0
      eh = (struct loongarch_elf_link_hash_entry *) entry;
244
0
      eh->tls_type = GOT_UNKNOWN;
245
0
    }
246
247
0
  return entry;
248
0
}
249
250
/* Compute a hash of a local hash entry.  We use elf_link_hash_entry
251
  for local symbol so that we can handle local STT_GNU_IFUNC symbols
252
  as global symbol.  We reuse indx and dynstr_index for local symbol
253
  hash since they aren't used by global symbols in this backend.  */
254
255
static hashval_t
256
elf64_loongarch_local_htab_hash (const void *ptr)
257
0
{
258
0
  struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) ptr;
259
0
  return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
260
0
}
261
262
/* Compare local hash entries.  */
263
264
static int
265
elf64_loongarch_local_htab_eq (const void *ptr1, const void *ptr2)
266
0
{
267
0
  struct elf_link_hash_entry *h1 = (struct elf_link_hash_entry *) ptr1;
268
0
  struct elf_link_hash_entry *h2 = (struct elf_link_hash_entry *) ptr2;
269
270
0
  return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
271
0
}
272
273
/* Find and/or create a hash entry for local symbol.  */
274
static struct elf_link_hash_entry *
275
elf64_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table *htab,
276
            bfd *abfd, const Elf_Internal_Rela *rel,
277
            bool create)
278
0
{
279
0
  struct loongarch_elf_link_hash_entry e, *ret;
280
0
  asection *sec = abfd->sections;
281
0
  hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id, ELF64_R_SYM (rel->r_info));
282
0
  void **slot;
283
284
0
  e.elf.indx = sec->id;
285
0
  e.elf.dynstr_index = ELF64_R_SYM (rel->r_info);
286
0
  slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
287
0
           create ? INSERT : NO_INSERT);
288
289
0
  if (!slot)
290
0
    return NULL;
291
292
0
  if (*slot)
293
0
    {
294
0
      ret = (struct loongarch_elf_link_hash_entry *) *slot;
295
0
      return &ret->elf;
296
0
    }
297
298
0
  ret = ((struct loongarch_elf_link_hash_entry *)
299
0
   objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
300
0
       sizeof (struct loongarch_elf_link_hash_entry)));
301
0
  if (ret)
302
0
    {
303
0
      memset (ret, 0, sizeof (*ret));
304
0
      ret->elf.indx = sec->id;
305
0
      ret->elf.pointer_equality_needed = 0;
306
0
      ret->elf.dynstr_index = ELF64_R_SYM (rel->r_info);
307
0
      ret->elf.dynindx = -1;
308
0
      ret->elf.needs_plt = 0;
309
0
      ret->elf.plt.refcount = -1;
310
0
      ret->elf.got.refcount = -1;
311
0
      ret->elf.def_dynamic = 0;
312
0
      ret->elf.def_regular = 1;
313
0
      ret->elf.ref_dynamic = 0; /* This should be always 0 for local.  */
314
0
      ret->elf.ref_regular = 0;
315
0
      ret->elf.forced_local = 1;
316
0
      ret->elf.root.type = bfd_link_hash_defined;
317
0
      *slot = ret;
318
0
    }
319
0
  return &ret->elf;
320
0
}
321
322
/* Destroy an LoongArch elf linker hash table.  */
323
324
static void
325
elf64_loongarch_link_hash_table_free (bfd *obfd)
326
0
{
327
0
  struct loongarch_elf_link_hash_table *ret;
328
0
  ret = (struct loongarch_elf_link_hash_table *) obfd->link.hash;
329
330
0
  if (ret->loc_hash_table)
331
0
    htab_delete (ret->loc_hash_table);
332
0
  if (ret->loc_hash_memory)
333
0
    objalloc_free ((struct objalloc *) ret->loc_hash_memory);
334
335
0
  _bfd_elf_link_hash_table_free (obfd);
336
0
}
337
338
/* Create a LoongArch ELF linker hash table.  */
339
340
static struct bfd_link_hash_table *
341
loongarch_elf_link_hash_table_create (bfd *abfd)
342
0
{
343
0
  struct loongarch_elf_link_hash_table *ret;
344
0
  bfd_size_type amt = sizeof (struct loongarch_elf_link_hash_table);
345
346
0
  ret = (struct loongarch_elf_link_hash_table *) bfd_zmalloc (amt);
347
0
  if (ret == NULL)
348
0
    return NULL;
349
350
0
  if (!_bfd_elf_link_hash_table_init
351
0
      (&ret->elf, abfd, link_hash_newfunc,
352
0
       sizeof (struct loongarch_elf_link_hash_entry), LARCH_ELF_DATA))
353
0
    {
354
0
      free (ret);
355
0
      return NULL;
356
0
    }
357
358
0
  ret->max_alignment = MINUS_ONE;
359
360
0
  ret->loc_hash_table = htab_try_create (1024, elf64_loongarch_local_htab_hash,
361
0
           elf64_loongarch_local_htab_eq, NULL);
362
0
  ret->loc_hash_memory = objalloc_create ();
363
0
  if (!ret->loc_hash_table || !ret->loc_hash_memory)
364
0
    {
365
0
      elf64_loongarch_link_hash_table_free (abfd);
366
0
      return NULL;
367
0
    }
368
0
  ret->elf.root.hash_table_free = elf64_loongarch_link_hash_table_free;
369
370
0
  return &ret->elf.root;
371
0
}
372
373
/* Merge backend specific data from an object file to the output
374
   object file when linking.  */
375
376
static bool
377
elf64_loongarch_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
378
0
{
379
0
  bfd *obfd = info->output_bfd;
380
0
  flagword in_flags = elf_elfheader (ibfd)->e_flags;
381
0
  flagword out_flags = elf_elfheader (obfd)->e_flags;
382
383
0
  if (!is_loongarch_elf (ibfd) || !is_loongarch_elf (obfd))
384
0
    return true;
385
386
0
  if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
387
0
    {
388
0
      _bfd_error_handler (_("%pB: ABI is incompatible with that of "
389
0
          "the selected emulation:\n"
390
0
          "  target emulation `%s' does not match `%s'"),
391
0
        ibfd, bfd_get_target (ibfd), bfd_get_target (obfd));
392
0
      return false;
393
0
    }
394
395
0
  if (!_bfd_elf_merge_object_attributes (ibfd, info))
396
0
    return false;
397
398
  /* If the input BFD is not a dynamic object and it does not contain any
399
     non-data sections, do not account its ABI.  For example, various
400
     packages produces such data-only relocatable objects with
401
     `ld -r -b binary` or `objcopy`, and these objects have zero e_flags.
402
     But they are compatible with all ABIs.  */
403
0
  if (!(ibfd->flags & DYNAMIC))
404
0
    {
405
0
      asection *sec;
406
0
      bool have_code_sections = false;
407
0
      for (sec = ibfd->sections; sec != NULL; sec = sec->next)
408
0
  if ((bfd_section_flags (sec)
409
0
       & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
410
0
      == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
411
0
    {
412
0
      have_code_sections = true;
413
0
      break;
414
0
    }
415
0
      if (!have_code_sections)
416
0
  return true;
417
0
    }
418
419
0
  if (!elf_flags_init (obfd))
420
0
    {
421
0
      elf_flags_init (obfd) = true;
422
0
      elf_elfheader (obfd)->e_flags = in_flags;
423
0
      return true;
424
0
    }
425
0
  else if (out_flags != in_flags)
426
0
    {
427
0
      if ((EF_LOONGARCH_IS_OBJ_V0 (out_flags)
428
0
     && EF_LOONGARCH_IS_OBJ_V1 (in_flags))
429
0
    || (EF_LOONGARCH_IS_OBJ_V0 (in_flags)
430
0
        && EF_LOONGARCH_IS_OBJ_V1 (out_flags)))
431
0
  {
432
0
    elf_elfheader (obfd)->e_flags |= EF_LOONGARCH_OBJABI_V1;
433
0
    out_flags = elf_elfheader (obfd)->e_flags;
434
0
    in_flags = out_flags;
435
0
  }
436
0
    }
437
438
  /* Disallow linking different ABIs.  */
439
  /* Only check relocation version.
440
     The obj_v0 is compatible with obj_v1.  */
441
0
  if (EF_LOONGARCH_ABI(out_flags ^ in_flags) & EF_LOONGARCH_ABI_MASK)
442
0
    {
443
0
      _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd);
444
0
      goto fail;
445
0
    }
446
447
0
  return true;
448
449
0
 fail:
450
0
  bfd_set_error (bfd_error_bad_value);
451
0
  return false;
452
0
}
453
454
/* Create the .got section.  */
455
456
static bool
457
loongarch_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
458
0
{
459
0
  flagword flags;
460
0
  char *name;
461
0
  asection *s, *s_got;
462
0
  struct elf_link_hash_entry *h;
463
0
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
464
0
  struct elf_link_hash_table *htab = elf_hash_table (info);
465
466
  /* This function may be called more than once.  */
467
0
  if (htab->sgot != NULL)
468
0
    return true;
469
470
0
  flags = bed->dynamic_sec_flags;
471
0
  name = bed->rela_plts_and_copies_p ? ".rela.got" : ".rel.got";
472
0
  s = bfd_make_section_anyway_with_flags (abfd, name, flags | SEC_READONLY);
473
474
0
  if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
475
0
    return false;
476
0
  htab->srelgot = s;
477
478
0
  s = s_got = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
479
0
  if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
480
0
    return false;
481
0
  htab->sgot = s;
482
483
  /* The first bit of the global offset table is the header.  */
484
0
  s->size += bed->got_header_size;
485
486
0
  if (bed->want_got_plt)
487
0
    {
488
0
      s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
489
0
      if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
490
0
  return false;
491
0
      htab->sgotplt = s;
492
493
      /* Reserve room for the header.  */
494
0
      s->size = GOTPLT_HEADER_SIZE;
495
0
    }
496
497
0
  if (bed->want_got_sym)
498
0
    {
499
      /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
500
   section.  We don't do this in the linker script because we don't want
501
   to define the symbol if we are not creating a global offset table.  */
502
0
      h = _bfd_elf_define_linkage_sym (abfd, info, s_got,
503
0
               "_GLOBAL_OFFSET_TABLE_");
504
0
      elf_hash_table (info)->hgot = h;
505
0
      if (h == NULL)
506
0
  return false;
507
0
    }
508
0
  return true;
509
0
}
510
511
/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
512
   .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
513
   hash table.  */
514
515
static bool
516
loongarch_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
517
0
{
518
0
  struct loongarch_elf_link_hash_table *htab;
519
520
0
  htab = loongarch_elf_hash_table (info);
521
0
  BFD_ASSERT (htab != NULL);
522
523
0
  if (!loongarch_elf_create_got_section (dynobj, info))
524
0
    return false;
525
526
0
  if (!_bfd_elf_create_dynamic_sections (dynobj, info))
527
0
    return false;
528
529
0
  if (!bfd_link_pic (info))
530
0
    htab->sdyntdata
531
0
      = bfd_make_section_anyway_with_flags (dynobj, ".tdata.dyn",
532
0
              SEC_ALLOC | SEC_THREAD_LOCAL);
533
534
0
  if (!htab->elf.splt || !htab->elf.srelplt || !htab->elf.sdynbss
535
0
      || (!bfd_link_pic (info) && (!htab->elf.srelbss || !htab->sdyntdata)))
536
0
    abort ();
537
538
0
  return true;
539
0
}
540
541
static bool
542
loongarch_elf_record_tls_and_got_reference (bfd *abfd,
543
              struct bfd_link_info *info,
544
              struct elf_link_hash_entry *h,
545
              unsigned long symndx,
546
              char tls_type)
547
0
{
548
0
  struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
549
0
  Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
550
551
  /* This is a global offset table entry for a local symbol.  */
552
0
  if (elf_local_got_refcounts (abfd) == NULL)
553
0
    {
554
0
      bfd_size_type size =
555
0
  symtab_hdr->sh_info * (sizeof (bfd_vma) + sizeof (tls_type));
556
0
      if (!(elf_local_got_refcounts (abfd) = bfd_zalloc (abfd, size)))
557
0
  return false;
558
0
      _bfd_loongarch_elf_local_got_tls_type (abfd) =
559
0
  (char *) (elf_local_got_refcounts (abfd) + symtab_hdr->sh_info);
560
0
    }
561
562
0
  switch (tls_type)
563
0
    {
564
0
    case GOT_NORMAL:
565
0
    case GOT_TLS_GD:
566
0
    case GOT_TLS_IE:
567
      /* Need GOT.  */
568
0
      if (htab->elf.sgot == NULL
569
0
    && !loongarch_elf_create_got_section (htab->elf.dynobj, info))
570
0
  return false;
571
0
      if (h)
572
0
  {
573
0
    if (h->got.refcount < 0)
574
0
      h->got.refcount = 0;
575
0
    h->got.refcount++;
576
0
  }
577
0
      else
578
0
  elf_local_got_refcounts (abfd)[symndx]++;
579
0
      break;
580
0
    case GOT_TLS_LE:
581
      /* No need for GOT.  */
582
0
      break;
583
0
    default:
584
0
      _bfd_error_handler (_("Internal error: unreachable."));
585
0
      return false;
586
0
    }
587
588
0
  char *new_tls_type = &_bfd_loongarch_elf_tls_type (abfd, h, symndx);
589
0
  *new_tls_type |= tls_type;
590
0
  if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL))
591
0
    {
592
0
      _bfd_error_handler (_("%pB: `%s' accessed both as normal and "
593
0
          "thread local symbol"),
594
0
        abfd,
595
0
        h ? h->root.root.string : "<local>");
596
0
      return false;
597
0
    }
598
599
0
  return true;
600
0
}
601
602
/* Look through the relocs for a section during the first phase, and
603
   allocate space in the global offset table or procedure linkage
604
   table.  */
605
606
static bool
607
loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
608
          asection *sec, const Elf_Internal_Rela *relocs)
609
0
{
610
0
  struct loongarch_elf_link_hash_table *htab;
611
0
  Elf_Internal_Shdr *symtab_hdr;
612
0
  struct elf_link_hash_entry **sym_hashes;
613
0
  const Elf_Internal_Rela *rel;
614
0
  asection *sreloc = NULL;
615
616
0
  if (bfd_link_relocatable (info))
617
0
    return true;
618
619
0
  htab = loongarch_elf_hash_table (info);
620
0
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
621
0
  sym_hashes = elf_sym_hashes (abfd);
622
623
0
  if (htab->elf.dynobj == NULL)
624
0
    htab->elf.dynobj = abfd;
625
626
0
  for (rel = relocs; rel < relocs + sec->reloc_count; rel++)
627
0
    {
628
0
      unsigned int r_type;
629
0
      unsigned int r_symndx;
630
0
      struct elf_link_hash_entry *h;
631
0
      Elf_Internal_Sym *isym = NULL;
632
633
0
      r_symndx = ELF64_R_SYM (rel->r_info);
634
0
      r_type = ELF64_R_TYPE (rel->r_info);
635
636
0
      if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
637
0
  {
638
0
    _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd, r_symndx);
639
0
    return false;
640
0
  }
641
642
0
      if (r_symndx < symtab_hdr->sh_info)
643
0
  {
644
    /* A local symbol.  */
645
0
    isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, r_symndx);
646
0
    if (isym == NULL)
647
0
      return false;
648
649
0
    if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
650
0
      {
651
0
        h = elf64_loongarch_get_local_sym_hash (htab, abfd, rel, true);
652
0
        if (h == NULL)
653
0
    return false;
654
655
0
        h->type = STT_GNU_IFUNC;
656
0
        h->ref_regular = 1;
657
0
      }
658
0
    else
659
0
      h = NULL;
660
0
  }
661
0
      else
662
0
  {
663
0
    h = sym_hashes[r_symndx - symtab_hdr->sh_info];
664
0
    while (h->root.type == bfd_link_hash_indirect
665
0
     || h->root.type == bfd_link_hash_warning)
666
0
      h = (struct elf_link_hash_entry *) h->root.u.i.link;
667
0
  }
668
669
      /* It is referenced by a non-shared object.  */
670
0
      if (h != NULL)
671
0
  h->ref_regular = 1;
672
673
0
      if (h && h->type == STT_GNU_IFUNC)
674
0
  {
675
0
    if (htab->elf.dynobj == NULL)
676
0
      htab->elf.dynobj = abfd;
677
678
    /* Create 'irelifunc' in PIC object.  */
679
0
    if (bfd_link_pic (info)
680
0
        && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
681
0
      return false;
682
    /* If '.plt' not represent, create '.iplt' to deal with ifunc.  */
683
0
    else if (!htab->elf.splt
684
0
       && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
685
0
      return false;
686
    /* Create the ifunc sections, iplt and ipltgot, for static
687
       executables.  */
688
0
    if ((r_type == R_LARCH_64 || r_type == R_LARCH_32)
689
0
        && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
690
0
      return false;
691
692
0
    if (h->plt.refcount < 0)
693
0
      h->plt.refcount = 0;
694
0
    h->plt.refcount++;
695
0
    h->needs_plt = 1;
696
697
0
    elf_tdata (info->output_bfd)->has_gnu_osabi |= elf_gnu_osabi_ifunc;
698
0
  }
699
700
0
      int need_dynreloc = 0;
701
0
      int only_need_pcrel = 0;
702
703
0
      switch (r_type)
704
0
  {
705
0
  case R_LARCH_GOT_PC_HI20:
706
0
  case R_LARCH_GOT_HI20:
707
0
  case R_LARCH_SOP_PUSH_GPREL:
708
    /* For la.global.  */
709
0
    if (h)
710
0
      h->pointer_equality_needed = 1;
711
0
    if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
712
0
                 r_symndx,
713
0
                 GOT_NORMAL))
714
0
      return false;
715
0
    break;
716
717
0
  case R_LARCH_TLS_LD_PC_HI20:
718
0
  case R_LARCH_TLS_LD_HI20:
719
0
  case R_LARCH_TLS_GD_PC_HI20:
720
0
  case R_LARCH_TLS_GD_HI20:
721
0
  case R_LARCH_SOP_PUSH_TLS_GD:
722
0
    if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
723
0
                 r_symndx,
724
0
                 GOT_TLS_GD))
725
0
      return false;
726
0
    break;
727
728
0
  case R_LARCH_TLS_IE_PC_HI20:
729
0
  case R_LARCH_TLS_IE_HI20:
730
0
  case R_LARCH_SOP_PUSH_TLS_GOT:
731
0
    if (bfd_link_pic (info))
732
      /* May fail for lazy-bind.  */
733
0
      info->flags |= DF_STATIC_TLS;
734
735
0
    if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
736
0
                 r_symndx,
737
0
                 GOT_TLS_IE))
738
0
      return false;
739
0
    break;
740
741
0
  case R_LARCH_TLS_LE_HI20:
742
0
  case R_LARCH_SOP_PUSH_TLS_TPREL:
743
0
    if (!bfd_link_executable (info))
744
0
      return false;
745
746
0
    info->flags |= DF_STATIC_TLS;
747
748
0
    if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
749
0
                 r_symndx,
750
0
                 GOT_TLS_LE))
751
0
      return false;
752
0
    break;
753
754
0
  case R_LARCH_ABS_HI20:
755
0
  case R_LARCH_SOP_PUSH_ABSOLUTE:
756
0
    if (h != NULL)
757
      /* If this reloc is in a read-only section, we might
758
         need a copy reloc.  We can't check reliably at this
759
         stage whether the section is read-only, as input
760
         sections have not yet been mapped to output sections.
761
         Tentatively set the flag for now, and correct in
762
         adjust_dynamic_symbol.  */
763
0
      h->non_got_ref = 1;
764
0
    break;
765
766
0
  case R_LARCH_PCALA_HI20:
767
0
    if (h != NULL)
768
0
      {
769
        /* For pcalau12i + jirl.  */
770
0
        h->needs_plt = 1;
771
0
        if (h->plt.refcount < 0)
772
0
    h->plt.refcount = 0;
773
0
        h->plt.refcount++;
774
775
0
        h->non_got_ref = 1;
776
0
        h->pointer_equality_needed = 1;
777
0
      }
778
779
0
    break;
780
781
0
  case R_LARCH_B16:
782
0
  case R_LARCH_B21:
783
0
  case R_LARCH_B26:
784
0
    if (h != NULL)
785
0
      {
786
0
        h->needs_plt = 1;
787
0
        if (!bfd_link_pic (info))
788
0
    h->non_got_ref = 1;
789
790
        /* We try to create PLT stub for all non-local function.  */
791
0
        if (h->plt.refcount < 0)
792
0
    h->plt.refcount = 0;
793
0
        h->plt.refcount++;
794
0
      }
795
796
0
    break;
797
798
0
  case R_LARCH_SOP_PUSH_PCREL:
799
0
    if (h != NULL)
800
0
      {
801
0
        if (!bfd_link_pic (info))
802
0
    h->non_got_ref = 1;
803
804
        /* We try to create PLT stub for all non-local function.  */
805
0
        if (h->plt.refcount < 0)
806
0
    h->plt.refcount = 0;
807
0
        h->plt.refcount++;
808
0
        h->pointer_equality_needed = 1;
809
0
      }
810
811
0
    break;
812
813
0
  case R_LARCH_SOP_PUSH_PLT_PCREL:
814
    /* This symbol requires a procedure linkage table entry.  We
815
       actually build the entry in adjust_dynamic_symbol,
816
       because this might be a case of linking PIC code without
817
       linking in any dynamic objects, in which case we don't
818
       need to generate a procedure linkage table after all.  */
819
0
    if (h != NULL)
820
0
      {
821
0
        h->needs_plt = 1;
822
0
        if (h->plt.refcount < 0)
823
0
    h->plt.refcount = 0;
824
0
        h->plt.refcount++;
825
0
      }
826
0
    break;
827
828
0
  case R_LARCH_TLS_DTPREL32:
829
0
  case R_LARCH_TLS_DTPREL64:
830
0
    need_dynreloc = 1;
831
0
    only_need_pcrel = 1;
832
0
    break;
833
834
0
  case R_LARCH_JUMP_SLOT:
835
0
  case R_LARCH_32:
836
0
  case R_LARCH_64:
837
838
0
    need_dynreloc = 1;
839
840
    /* If resolved symbol is defined in this object,
841
       1. Under pie, the symbol is known.  We convert it
842
       into R_LARCH_RELATIVE and need load-addr still.
843
       2. Under pde, the symbol is known and we can discard R_LARCH_64.
844
       3. Under dll, R_LARCH_64 can't be changed normally, since
845
       its defination could be covered by the one in executable.
846
       For symbolic, we convert it into R_LARCH_RELATIVE.
847
       Thus, only under pde, it needs pcrel only.  We discard it.  */
848
0
    only_need_pcrel = bfd_link_pde (info);
849
850
0
    if (h != NULL
851
0
        && (!bfd_link_pic (info)
852
0
      || h->type == STT_GNU_IFUNC))
853
0
      {
854
        /* This reloc might not bind locally.  */
855
0
        h->non_got_ref = 1;
856
0
        h->pointer_equality_needed = 1;
857
858
0
        if (!h->def_regular
859
0
      || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
860
0
    {
861
      /* We may need a .plt entry if the symbol is a function
862
         defined in a shared lib or is a function referenced
863
         from the code or read-only section.  */
864
0
      h->plt.refcount += 1;
865
0
    }
866
0
      }
867
0
    break;
868
869
0
  case R_LARCH_GNU_VTINHERIT:
870
0
    if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
871
0
      return false;
872
0
    break;
873
874
0
  case R_LARCH_GNU_VTENTRY:
875
0
    if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
876
0
      return false;
877
0
    break;
878
879
0
  default:
880
0
    break;
881
0
  }
882
883
      /* Record some info for sizing and allocating dynamic entry.  */
884
0
      if (need_dynreloc && (sec->flags & SEC_ALLOC))
885
0
  {
886
    /* When creating a shared object, we must copy these
887
       relocs into the output file.  We create a reloc
888
       section in dynobj and make room for the reloc.  */
889
0
    struct elf_dyn_relocs *p;
890
0
    struct elf_dyn_relocs **head;
891
892
0
    if (sreloc == NULL)
893
0
      {
894
0
        sreloc
895
0
    = _bfd_elf_make_dynamic_reloc_section (sec, htab->elf.dynobj,
896
0
                   LARCH_ELF_LOG_WORD_BYTES,
897
0
                   abfd, /*rela?*/ true);
898
0
        if (sreloc == NULL)
899
0
    return false;
900
0
      }
901
902
    /* If this is a global symbol, we count the number of
903
       relocations we need for this symbol.  */
904
0
    if (h != NULL)
905
0
      head = &h->dyn_relocs;
906
0
    else
907
0
      {
908
        /* Track dynamic relocs needed for local syms too.
909
     We really need local syms available to do this
910
     easily.  Oh well.  */
911
912
0
        asection *s;
913
0
        void *vpp;
914
915
0
        s = bfd_section_from_elf_index (abfd, isym->st_shndx);
916
0
        if (s == NULL)
917
0
    s = sec;
918
919
0
        vpp = &elf_section_data (s)->local_dynrel;
920
0
        head = (struct elf_dyn_relocs **) vpp;
921
0
      }
922
923
0
    p = *head;
924
0
    if (p == NULL || p->sec != sec)
925
0
      {
926
0
        bfd_size_type amt = sizeof *p;
927
0
        p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj, amt);
928
0
        if (p == NULL)
929
0
    return false;
930
0
        p->next = *head;
931
0
        *head = p;
932
0
        p->sec = sec;
933
0
        p->count = 0;
934
0
        p->pc_count = 0;
935
0
      }
936
937
0
    p->count++;
938
0
    p->pc_count += only_need_pcrel;
939
0
  }
940
0
    }
941
942
0
  return true;
943
0
}
944
945
/* Find dynamic relocs for H that apply to read-only sections.  */
946
947
static asection *
948
readonly_dynrelocs (struct elf_link_hash_entry *h)
949
0
{
950
0
  struct elf_dyn_relocs *p;
951
952
0
  for (p = h->dyn_relocs; p != NULL; p = p->next)
953
0
    {
954
0
      asection *s = p->sec->output_section;
955
956
0
      if (s != NULL && (s->flags & SEC_READONLY) != 0)
957
0
  return p->sec;
958
0
    }
959
0
  return NULL;
960
0
}
961
962
/* Adjust a symbol defined by a dynamic object and referenced by a
963
   regular object.  The current definition is in some section of the
964
   dynamic object, but we're not including those sections.  We have to
965
   change the definition to something the rest of the link can
966
   understand.  */
967
static bool
968
loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
969
             struct elf_link_hash_entry *h)
970
0
{
971
0
  struct loongarch_elf_link_hash_table *htab;
972
0
  bfd *dynobj;
973
974
0
  htab = loongarch_elf_hash_table (info);
975
0
  BFD_ASSERT (htab != NULL);
976
977
0
  dynobj = htab->elf.dynobj;
978
979
  /* Make sure we know what is going on here.  */
980
0
  BFD_ASSERT (dynobj != NULL
981
0
        && (h->needs_plt
982
0
      || h->type == STT_GNU_IFUNC
983
0
      || h->is_weakalias
984
0
      || (h->def_dynamic
985
0
          && h->ref_regular
986
0
          && !h->def_regular)));
987
988
  /* If this is a function, put it in the procedure linkage table.  We
989
     will fill in the contents of the procedure linkage table later
990
     (although we could actually do it here).  */
991
0
  if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt)
992
0
    {
993
0
      if (h->plt.refcount <= 0
994
0
    || (h->type != STT_GNU_IFUNC
995
0
        && (SYMBOL_REFERENCES_LOCAL (info, h)
996
0
      || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
997
0
          && h->root.type == bfd_link_hash_undefweak))))
998
0
  {
999
    /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc
1000
       in an input file, but the symbol was never referred to by a
1001
       dynamic object, or if all references were garbage collected.
1002
       In such a case, we don't actually need to build a PLT entry.  */
1003
0
    h->plt.offset = MINUS_ONE;
1004
0
    h->needs_plt = 0;
1005
0
  }
1006
1007
0
      return true;
1008
0
    }
1009
0
  else
1010
0
    h->plt.offset = MINUS_ONE;
1011
1012
  /* If this is a weak symbol, and there is a real definition, the
1013
     processor independent code will have arranged for us to see the
1014
     real definition first, and we can just use the same value.  */
1015
0
  if (h->is_weakalias)
1016
0
    {
1017
0
      struct elf_link_hash_entry *def = weakdef (h);
1018
0
      BFD_ASSERT (def->root.type == bfd_link_hash_defined);
1019
0
      h->root.u.def.section = def->root.u.def.section;
1020
0
      h->root.u.def.value = def->root.u.def.value;
1021
0
      return true;
1022
0
    }
1023
1024
  /* R_LARCH_COPY is not adept glibc, not to generate.  */
1025
  /* Can not print anything, because make check ld.  */
1026
0
  return true;
1027
0
}
1028
1029
/* Allocate space in .plt, .got and associated reloc sections for
1030
   dynamic relocs.  */
1031
1032
static bool
1033
allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
1034
0
{
1035
0
  struct bfd_link_info *info;
1036
0
  struct loongarch_elf_link_hash_table *htab;
1037
0
  struct elf_dyn_relocs *p;
1038
1039
0
  if (h->root.type == bfd_link_hash_indirect)
1040
0
    return true;
1041
1042
0
  if (h->type == STT_GNU_IFUNC
1043
0
      && h->def_regular)
1044
0
    return true;
1045
1046
0
  info = (struct bfd_link_info *) inf;
1047
0
  htab = loongarch_elf_hash_table (info);
1048
0
  bool dyn = htab->elf.dynamic_sections_created;
1049
0
  BFD_ASSERT (htab != NULL);
1050
1051
0
  do
1052
0
    {
1053
0
      asection *plt, *gotplt, *relplt;
1054
1055
0
      if (!h->needs_plt)
1056
0
  break;
1057
1058
0
      h->needs_plt = 0;
1059
1060
0
      if (htab->elf.splt)
1061
0
  {
1062
0
    if (h->dynindx == -1 && !h->forced_local && dyn
1063
0
        && h->root.type == bfd_link_hash_undefweak)
1064
0
      {
1065
0
        if (!bfd_elf_link_record_dynamic_symbol (info, h))
1066
0
    return false;
1067
0
      }
1068
1069
0
    if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h)
1070
0
        && h->type != STT_GNU_IFUNC)
1071
0
      break;
1072
1073
0
    plt = htab->elf.splt;
1074
0
    gotplt = htab->elf.sgotplt;
1075
0
    relplt = htab->elf.srelplt;
1076
0
  }
1077
0
      else if (htab->elf.iplt)
1078
0
  {
1079
    /* .iplt only for IFUNC.  */
1080
0
    if (h->type != STT_GNU_IFUNC)
1081
0
      break;
1082
1083
0
    plt = htab->elf.iplt;
1084
0
    gotplt = htab->elf.igotplt;
1085
0
    relplt = htab->elf.irelplt;
1086
0
  }
1087
0
      else
1088
0
  break;
1089
1090
0
      if (plt->size == 0)
1091
0
  plt->size = PLT_HEADER_SIZE;
1092
1093
0
      h->plt.offset = plt->size;
1094
0
      plt->size += PLT_ENTRY_SIZE;
1095
0
      gotplt->size += GOT_ENTRY_SIZE;
1096
0
      relplt->size += sizeof (Elf64_External_Rela);
1097
1098
      /* If this symbol is not defined in a regular file, and we are
1099
   not generating a shared library, then set the symbol to this
1100
   location in the .plt.  This is required to make function
1101
   pointers compare as equal between the normal executable and
1102
   the shared library.  */
1103
0
      if (!bfd_link_pic (info)
1104
0
    && !h->def_regular)
1105
0
  {
1106
0
    h->root.u.def.section = plt;
1107
0
    h->root.u.def.value = h->plt.offset;
1108
0
  }
1109
1110
0
      h->needs_plt = 1;
1111
0
    }
1112
0
  while (0);
1113
1114
0
  if (!h->needs_plt)
1115
0
    h->plt.offset = MINUS_ONE;
1116
1117
0
  if (0 < h->got.refcount)
1118
0
    {
1119
0
      asection *s;
1120
0
      int tls_type = loongarch_elf_hash_entry (h)->tls_type;
1121
1122
      /* Make sure this symbol is output as a dynamic symbol.
1123
   Undefined weak syms won't yet be marked as dynamic.  */
1124
0
      if (h->dynindx == -1 && !h->forced_local && dyn
1125
0
    && h->root.type == bfd_link_hash_undefweak)
1126
0
  {
1127
0
    if (!bfd_elf_link_record_dynamic_symbol (info, h))
1128
0
      return false;
1129
0
  }
1130
1131
0
      s = htab->elf.sgot;
1132
0
      h->got.offset = s->size;
1133
0
      if (tls_type & (GOT_TLS_GD | GOT_TLS_IE))
1134
0
  {
1135
    /* TLS_GD needs two dynamic relocs and two GOT slots.  */
1136
0
    if (tls_type & GOT_TLS_GD)
1137
0
      {
1138
0
        s->size += 2 * GOT_ENTRY_SIZE;
1139
0
        if (bfd_link_executable (info))
1140
0
    {
1141
      /* Link exe and not defined local.  */
1142
0
      if (!SYMBOL_REFERENCES_LOCAL (info, h))
1143
0
        htab->elf.srelgot->size += 2 * sizeof (Elf64_External_Rela);
1144
0
    }
1145
0
        else
1146
0
    {
1147
0
      if (SYMBOL_REFERENCES_LOCAL (info, h))
1148
0
        htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
1149
0
      else
1150
0
        htab->elf.srelgot->size += 2 * sizeof (Elf64_External_Rela);
1151
0
    }
1152
0
      }
1153
1154
    /* TLS_IE needs one dynamic reloc and one GOT slot.  */
1155
0
    if (tls_type & GOT_TLS_IE)
1156
0
      {
1157
0
        s->size += GOT_ENTRY_SIZE;
1158
1159
0
        if (bfd_link_executable (info))
1160
0
    {
1161
      /* Link exe and not defined local.  */
1162
0
      if (!SYMBOL_REFERENCES_LOCAL (info, h))
1163
0
        htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
1164
0
    }
1165
0
        else
1166
0
    {
1167
0
      htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
1168
0
    }
1169
0
      }
1170
0
  }
1171
0
      else
1172
0
  {
1173
0
    s->size += GOT_ENTRY_SIZE;
1174
0
    if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1175
0
         || h->root.type != bfd_link_hash_undefweak)
1176
0
        && (bfd_link_pic (info)
1177
0
      || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info),
1178
0
                  h))
1179
0
        && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
1180
        /* Undefined weak symbol in static PIE resolves to 0 without
1181
     any dynamic relocations.  */
1182
0
      htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
1183
0
  }
1184
0
    }
1185
0
  else
1186
0
    h->got.offset = MINUS_ONE;
1187
1188
0
  if (h->dyn_relocs == NULL)
1189
0
    return true;
1190
1191
  /* Extra dynamic relocate,
1192
   * R_LARCH_64
1193
   * R_LARCH_TLS_DTPREL64
1194
   * R_LARCH_JUMP_SLOT
1195
   * R_LARCH_64.  */
1196
1197
0
  if (SYMBOL_CALLS_LOCAL (info, h))
1198
0
    {
1199
0
      struct elf_dyn_relocs **pp;
1200
1201
0
      for (pp = &h->dyn_relocs; (p = *pp) != NULL;)
1202
0
  {
1203
0
    p->count -= p->pc_count;
1204
0
    p->pc_count = 0;
1205
0
    if (p->count == 0)
1206
0
      *pp = p->next;
1207
0
    else
1208
0
      pp = &p->next;
1209
0
  }
1210
0
    }
1211
1212
0
  if (h->root.type == bfd_link_hash_undefweak)
1213
0
    {
1214
0
      if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)
1215
0
    || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1216
0
    || (!bfd_link_pic (info) && h->non_got_ref))
1217
0
  h->dyn_relocs = NULL;
1218
0
      else if (h->dynindx == -1 && !h->forced_local)
1219
0
  {
1220
    /* Make sure this symbol is output as a dynamic symbol.
1221
       Undefined weak syms won't yet be marked as dynamic.  */
1222
0
    if (!bfd_elf_link_record_dynamic_symbol (info, h))
1223
0
      return false;
1224
1225
0
    if (h->dynindx == -1)
1226
0
      h->dyn_relocs = NULL;
1227
0
  }
1228
0
    }
1229
1230
0
  for (p = h->dyn_relocs; p != NULL; p = p->next)
1231
0
    {
1232
0
      asection *sreloc = elf_section_data (p->sec)->sreloc;
1233
0
      sreloc->size += p->count * sizeof (Elf64_External_Rela);
1234
0
    }
1235
1236
0
  return true;
1237
0
}
1238
1239
/* A modified version of _bfd_elf_allocate_ifunc_dyn_relocs.
1240
   For local def and ref ifunc,
1241
   dynamic relocations are stored in
1242
   1.  rela.srelgot section in dynamic object (dll or exec).
1243
   2.  rela.irelplt section in static executable.
1244
   Unlike _bfd_elf_allocate_ifunc_dyn_relocs, rela.srelgot is used
1245
   instead of rela.srelplt.  Glibc ELF loader will not support
1246
   R_LARCH_IRELATIVE relocation in rela.plt.  */
1247
1248
static bool
1249
local_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
1250
            struct elf_link_hash_entry *h,
1251
            struct elf_dyn_relocs **head,
1252
            unsigned int plt_entry_size,
1253
            unsigned int plt_header_size,
1254
            unsigned int got_entry_size,
1255
            bool avoid_plt)
1256
0
{
1257
0
  asection *plt, *gotplt, *relplt;
1258
0
  struct elf_dyn_relocs *p;
1259
0
  unsigned int sizeof_reloc;
1260
0
  const struct elf_backend_data *bed;
1261
0
  struct elf_link_hash_table *htab;
1262
  /* If AVOID_PLT is TRUE, don't use PLT if possible.  */
1263
0
  bool use_plt = !avoid_plt || h->plt.refcount > 0;
1264
0
  bool need_dynreloc = !use_plt || bfd_link_pic (info);
1265
1266
  /* When a PIC object references a STT_GNU_IFUNC symbol defined
1267
     in executable or it isn't referenced via PLT, the address of
1268
     the resolved function may be used.  But in non-PIC executable,
1269
     the address of its plt slot may be used.  Pointer equality may
1270
     not work correctly.  PIE or non-PLT reference should be used if
1271
     pointer equality is required here.
1272
1273
     If STT_GNU_IFUNC symbol is defined in position-dependent executable,
1274
     backend should change it to the normal function and set its address
1275
     to its PLT entry which should be resolved by R_*_IRELATIVE at
1276
     run-time.  All external references should be resolved to its PLT in
1277
     executable.  */
1278
0
  if (!need_dynreloc
1279
0
      && !(bfd_link_pde (info) && h->def_regular)
1280
0
      && (h->dynindx != -1
1281
0
    || info->export_dynamic)
1282
0
      && h->pointer_equality_needed)
1283
0
    {
1284
0
      info->callbacks->einfo
1285
  /* xgettext:c-format.  */
1286
0
  (_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer "
1287
0
     "equality in `%pB' can not be used when making an "
1288
0
     "executable; recompile with -fPIE and relink with -pie\n"),
1289
0
   h->root.root.string,
1290
0
   h->root.u.def.section->owner);
1291
0
      bfd_set_error (bfd_error_bad_value);
1292
0
      return false;
1293
0
    }
1294
1295
0
  htab = elf_hash_table (info);
1296
1297
  /* When the symbol is marked with regular reference, if PLT isn't used
1298
     or we are building a PIC object, we must keep dynamic relocation
1299
     if there is non-GOT reference and use PLT if there is PC-relative
1300
     reference.  */
1301
0
  if (need_dynreloc && h->ref_regular)
1302
0
    {
1303
0
      bool keep = false;
1304
0
      for (p = *head; p != NULL; p = p->next)
1305
0
  if (p->count)
1306
0
    {
1307
0
      h->non_got_ref = 1;
1308
      /* Need dynamic relocations for non-GOT reference.  */
1309
0
      keep = true;
1310
0
      if (p->pc_count)
1311
0
        {
1312
    /* Must use PLT for PC-relative reference.  */
1313
0
    use_plt = true;
1314
0
    need_dynreloc = bfd_link_pic (info);
1315
0
    break;
1316
0
        }
1317
0
    }
1318
0
      if (keep)
1319
0
  goto keep;
1320
0
    }
1321
1322
  /* Support garbage collection against STT_GNU_IFUNC symbols.  */
1323
0
  if (h->plt.refcount <= 0 && h->got.refcount <= 0)
1324
0
    {
1325
0
      h->got = htab->init_got_offset;
1326
0
      h->plt = htab->init_plt_offset;
1327
0
      *head = NULL;
1328
0
      return true;
1329
0
    }
1330
1331
  /* Return and discard space for dynamic relocations against it if
1332
     it is never referenced.  */
1333
0
  if (!h->ref_regular)
1334
0
    {
1335
0
      if (h->plt.refcount > 0
1336
0
    || h->got.refcount > 0)
1337
0
  abort ();
1338
0
      h->got = htab->init_got_offset;
1339
0
      h->plt = htab->init_plt_offset;
1340
0
      *head = NULL;
1341
0
      return true;
1342
0
    }
1343
1344
0
 keep:
1345
0
  bed = get_elf_backend_data (info->output_bfd);
1346
0
  if (bed->rela_plts_and_copies_p)
1347
0
    sizeof_reloc = bed->s->sizeof_rela;
1348
0
  else
1349
0
    sizeof_reloc = bed->s->sizeof_rel;
1350
1351
  /* When building a static executable, use iplt, igot.plt and
1352
     rela.iplt sections for STT_GNU_IFUNC symbols.  */
1353
0
  if (htab->splt != NULL)
1354
0
    {
1355
0
      plt = htab->splt;
1356
0
      gotplt = htab->sgotplt;
1357
      /* Change dynamic info of ifunc gotplt from srelplt to srelgot.  */
1358
0
      relplt = htab->srelgot;
1359
1360
      /* If this is the first plt entry and PLT is used, make room for
1361
   the special first entry.  */
1362
0
      if (plt->size == 0 && use_plt)
1363
0
  plt->size += plt_header_size;
1364
0
    }
1365
0
  else
1366
0
    {
1367
0
      plt = htab->iplt;
1368
0
      gotplt = htab->igotplt;
1369
0
      relplt = htab->irelplt;
1370
0
    }
1371
1372
0
  if (use_plt)
1373
0
    {
1374
      /* Don't update value of STT_GNU_IFUNC symbol to PLT.  We need
1375
   the original value for R_*_IRELATIVE.  */
1376
0
      h->plt.offset = plt->size;
1377
1378
      /* Make room for this entry in the plt/iplt section.  */
1379
0
      plt->size += plt_entry_size;
1380
1381
      /* We also need to make an entry in the got.plt/got.iplt section,
1382
   which will be placed in the got section by the linker script.  */
1383
0
      gotplt->size += got_entry_size;
1384
0
    }
1385
1386
  /* We also need to make an entry in the rela.plt/.rela.iplt
1387
     section for GOTPLT relocation if PLT is used.  */
1388
0
  if (use_plt)
1389
0
    {
1390
0
      relplt->size += sizeof_reloc;
1391
0
      relplt->reloc_count++;
1392
0
    }
1393
1394
  /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
1395
     there is a non-GOT reference in a PIC object or PLT isn't used.  */
1396
0
  if (!need_dynreloc || !h->non_got_ref)
1397
0
    *head = NULL;
1398
1399
  /* Finally, allocate space.  */
1400
0
  p = *head;
1401
0
  if (p != NULL)
1402
0
    {
1403
0
      bfd_size_type count = 0;
1404
0
      do
1405
0
  {
1406
0
    count += p->count;
1407
0
    p = p->next;
1408
0
  }
1409
0
      while (p != NULL);
1410
1411
0
      htab->ifunc_resolvers = count != 0;
1412
1413
      /* Dynamic relocations are stored in
1414
   1.  rela.srelgot section in PIC object.
1415
   2.  rela.srelgot section in dynamic executable.
1416
   3.  rela.irelplt section in static executable.  */
1417
0
      if (htab->splt != NULL)
1418
0
  htab->srelgot->size += count * sizeof_reloc;
1419
0
      else
1420
0
  {
1421
0
    relplt->size += count * sizeof_reloc;
1422
0
    relplt->reloc_count += count;
1423
0
  }
1424
0
    }
1425
1426
  /* For STT_GNU_IFUNC symbol, got.plt has the real function address
1427
     and got has the PLT entry adddress.  We will load the GOT entry
1428
     with the PLT entry in finish_dynamic_symbol if it is used.  For
1429
     branch, it uses got.plt.  For symbol value, if PLT is used,
1430
     1.  Use got.plt in a PIC object if it is forced local or not
1431
     dynamic.
1432
     2.  Use got.plt in a non-PIC object if pointer equality isn't
1433
     needed.
1434
     3.  Use got.plt in PIE.
1435
     4.  Use got.plt if got isn't used.
1436
     5.  Otherwise use got so that it can be shared among different
1437
     objects at run-time.
1438
     If PLT isn't used, always use got for symbol value.
1439
     We only need to relocate got entry in PIC object or in dynamic
1440
     executable without PLT.  */
1441
0
  if (use_plt
1442
0
      && (h->got.refcount <= 0
1443
0
    || (bfd_link_pic (info)
1444
0
        && (h->dynindx == -1
1445
0
      || h->forced_local))
1446
0
    || (
1447
0
        !h->pointer_equality_needed)
1448
0
    || htab->sgot == NULL))
1449
0
    {
1450
      /* Use got.plt.  */
1451
0
      h->got.offset = (bfd_vma) -1;
1452
0
    }
1453
0
  else
1454
0
    {
1455
0
      if (!use_plt)
1456
0
  {
1457
    /* PLT isn't used.  */
1458
0
    h->plt.offset = (bfd_vma) -1;
1459
0
  }
1460
0
      if (h->got.refcount <= 0)
1461
0
  {
1462
    /* GOT isn't need when there are only relocations for static
1463
       pointers.  */
1464
0
    h->got.offset = (bfd_vma) -1;
1465
0
  }
1466
0
      else
1467
0
  {
1468
0
    h->got.offset = htab->sgot->size;
1469
0
    htab->sgot->size += got_entry_size;
1470
    /* Need to relocate the GOT entry in a PIC object or PLT isn't
1471
       used.  Otherwise, the GOT entry will be filled with the PLT
1472
       entry and dynamic GOT relocation isn't needed.  */
1473
0
    if (need_dynreloc)
1474
0
      {
1475
        /* For non-static executable, dynamic GOT relocation is in
1476
     rela.got section, but for static executable, it is
1477
     in rela.iplt section.  */
1478
0
        if (htab->splt != NULL)
1479
0
    htab->srelgot->size += sizeof_reloc;
1480
0
        else
1481
0
    {
1482
0
      relplt->size += sizeof_reloc;
1483
0
      relplt->reloc_count++;
1484
0
    }
1485
0
      }
1486
0
  }
1487
0
    }
1488
1489
0
  return true;
1490
0
}
1491
1492
/* Allocate space in .plt, .got and associated reloc sections for
1493
   ifunc dynamic relocs.  */
1494
1495
static bool
1496
elf64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf)
1497
0
{
1498
0
  struct bfd_link_info *info;
1499
  /* An example of a bfd_link_hash_indirect symbol is versioned
1500
     symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
1501
     -> __gxx_personality_v0(bfd_link_hash_defined)
1502
1503
     There is no need to process bfd_link_hash_indirect symbols here
1504
     because we will also be presented with the concrete instance of
1505
     the symbol and loongarch_elf_copy_indirect_symbol () will have been
1506
     called to copy all relevant data from the generic to the concrete
1507
     symbol instance.  */
1508
0
  if (h->root.type == bfd_link_hash_indirect)
1509
0
    return true;
1510
1511
0
  if (h->root.type == bfd_link_hash_warning)
1512
0
    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1513
1514
0
  info = (struct bfd_link_info *) inf;
1515
1516
  /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1517
     here if it is defined and referenced in a non-shared object.  */
1518
0
  if (h->type == STT_GNU_IFUNC && h->def_regular)
1519
0
    {
1520
0
      if (SYMBOL_REFERENCES_LOCAL (info, h))
1521
0
  return local_allocate_ifunc_dyn_relocs (info, h,
1522
0
            &h->dyn_relocs,
1523
0
            PLT_ENTRY_SIZE,
1524
0
            PLT_HEADER_SIZE,
1525
0
            GOT_ENTRY_SIZE,
1526
0
            false);
1527
0
      else
1528
0
  return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
1529
0
               &h->dyn_relocs,
1530
0
               PLT_ENTRY_SIZE,
1531
0
               PLT_HEADER_SIZE,
1532
0
               GOT_ENTRY_SIZE,
1533
0
               false);
1534
0
    }
1535
1536
0
  return true;
1537
0
}
1538
1539
/* Allocate space in .plt, .got and associated reloc sections for
1540
   ifunc dynamic relocs.  */
1541
1542
static int
1543
elf64_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
1544
0
{
1545
0
  struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
1546
1547
0
  if (h->type != STT_GNU_IFUNC
1548
0
      || !h->def_regular
1549
0
      || !h->ref_regular
1550
0
      || !h->forced_local
1551
0
      || h->root.type != bfd_link_hash_defined)
1552
0
    abort ();
1553
1554
0
  return elf64_allocate_ifunc_dynrelocs (h, inf);
1555
0
}
1556
1557
/* Set DF_TEXTREL if we find any dynamic relocs that apply to
1558
   read-only sections.  */
1559
1560
static bool
1561
maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
1562
0
{
1563
0
  asection *sec;
1564
1565
0
  if (h->root.type == bfd_link_hash_indirect)
1566
0
    return true;
1567
1568
0
  sec = readonly_dynrelocs (h);
1569
0
  if (sec != NULL)
1570
0
    {
1571
0
      struct bfd_link_info *info = (struct bfd_link_info *) info_p;
1572
1573
0
      info->flags |= DF_TEXTREL;
1574
0
      info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' in "
1575
0
        "read-only section `%pA'\n"),
1576
0
            sec->owner, h->root.root.string, sec);
1577
1578
      /* Not an error, just cut short the traversal.  */
1579
0
      return false;
1580
0
    }
1581
0
  return true;
1582
0
}
1583
1584
static bool
1585
loongarch_elf_size_dynamic_sections (bfd *output_bfd,
1586
             struct bfd_link_info *info)
1587
0
{
1588
0
  struct loongarch_elf_link_hash_table *htab;
1589
0
  bfd *dynobj;
1590
0
  asection *s;
1591
0
  bfd *ibfd;
1592
1593
0
  htab = loongarch_elf_hash_table (info);
1594
0
  BFD_ASSERT (htab != NULL);
1595
0
  dynobj = htab->elf.dynobj;
1596
0
  BFD_ASSERT (dynobj != NULL);
1597
1598
0
  if (htab->elf.dynamic_sections_created)
1599
0
    {
1600
      /* Set the contents of the .interp section to the interpreter.  */
1601
0
      if (bfd_link_executable (info) && !info->nointerp)
1602
0
  {
1603
0
    const char *interpreter;
1604
0
    s = bfd_get_linker_section (dynobj, ".interp");
1605
0
    BFD_ASSERT (s != NULL);
1606
1607
0
    if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS32)
1608
0
      interpreter = "/lib32/ld.so.1";
1609
0
    else if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS64)
1610
0
      interpreter = "/lib64/ld.so.1";
1611
0
    else
1612
0
      interpreter = "/lib/ld.so.1";
1613
1614
0
    s->contents = (unsigned char *) interpreter;
1615
0
    s->size = strlen (interpreter) + 1;
1616
0
  }
1617
0
    }
1618
1619
  /* Set up .got offsets for local syms, and space for local dynamic
1620
     relocs.  */
1621
0
  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
1622
0
    {
1623
0
      bfd_signed_vma *local_got;
1624
0
      bfd_signed_vma *end_local_got;
1625
0
      char *local_tls_type;
1626
0
      bfd_size_type locsymcount;
1627
0
      Elf_Internal_Shdr *symtab_hdr;
1628
0
      asection *srel;
1629
1630
0
      if (!is_loongarch_elf (ibfd))
1631
0
  continue;
1632
1633
0
      for (s = ibfd->sections; s != NULL; s = s->next)
1634
0
  {
1635
0
    struct elf_dyn_relocs *p;
1636
1637
0
    for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
1638
0
      {
1639
0
        p->count -= p->pc_count;
1640
0
        if (!bfd_is_abs_section (p->sec)
1641
0
      && bfd_is_abs_section (p->sec->output_section))
1642
0
    {
1643
      /* Input section has been discarded, either because
1644
         it is a copy of a linkonce section or due to
1645
         linker script /DISCARD/, so we'll be discarding
1646
         the relocs too.  */
1647
0
    }
1648
0
        else if (0 < p->count)
1649
0
    {
1650
0
      srel = elf_section_data (p->sec)->sreloc;
1651
0
      srel->size += p->count * sizeof (Elf64_External_Rela);
1652
0
      if ((p->sec->output_section->flags & SEC_READONLY) != 0)
1653
0
        info->flags |= DF_TEXTREL;
1654
0
    }
1655
0
      }
1656
0
  }
1657
1658
0
      local_got = elf_local_got_refcounts (ibfd);
1659
0
      if (!local_got)
1660
0
  continue;
1661
1662
0
      symtab_hdr = &elf_symtab_hdr (ibfd);
1663
0
      locsymcount = symtab_hdr->sh_info;
1664
0
      end_local_got = local_got + locsymcount;
1665
0
      local_tls_type = _bfd_loongarch_elf_local_got_tls_type (ibfd);
1666
0
      s = htab->elf.sgot;
1667
0
      srel = htab->elf.srelgot;
1668
0
      for (; local_got < end_local_got; ++local_got, ++local_tls_type)
1669
0
  {
1670
0
    if (0 < *local_got)
1671
0
      {
1672
0
        *local_got = s->size;
1673
1674
        /* TLS gd use two got.  */
1675
0
        if (*local_tls_type & GOT_TLS_GD)
1676
0
    s->size += GOT_ENTRY_SIZE * 2;
1677
0
        else
1678
    /* Normal got, tls ie/ld use one got.  */
1679
0
    s->size += GOT_ENTRY_SIZE;
1680
1681
0
        if (bfd_link_executable (info)
1682
0
      && (*local_tls_type & (GOT_TLS_GD| GOT_TLS_IE)))
1683
0
    ;/* Do nothing.  */
1684
0
        else
1685
0
    {
1686
0
      srel->size += sizeof (Elf64_External_Rela);
1687
0
    }
1688
0
      }
1689
0
    else
1690
0
      *local_got = MINUS_ONE;
1691
0
  }
1692
0
    }
1693
1694
  /* Allocate global sym .plt and .got entries, and space for global
1695
     sym dynamic relocs.  */
1696
0
  elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
1697
1698
  /* Allocate global ifunc sym .plt and .got entries, and space for global
1699
     ifunc sym dynamic relocs.  */
1700
0
  elf_link_hash_traverse (&htab->elf, elf64_allocate_ifunc_dynrelocs, info);
1701
1702
  /* Allocate .plt and .got entries, and space for local ifunc symbols.  */
1703
0
  htab_traverse (htab->loc_hash_table,
1704
0
     elf64_allocate_local_ifunc_dynrelocs, info);
1705
1706
  /* Don't allocate .got.plt section if there are no PLT.  */
1707
0
  if (htab->elf.sgotplt && htab->elf.sgotplt->size == GOTPLT_HEADER_SIZE
1708
0
      && (htab->elf.splt == NULL || htab->elf.splt->size == 0))
1709
0
    htab->elf.sgotplt->size = 0;
1710
1711
  /* The check_relocs and adjust_dynamic_symbol entry points have
1712
     determined the sizes of the various dynamic sections.  Allocate
1713
     memory for them.  */
1714
0
  for (s = dynobj->sections; s != NULL; s = s->next)
1715
0
    {
1716
0
      if ((s->flags & SEC_LINKER_CREATED) == 0)
1717
0
  continue;
1718
1719
0
      if (s == htab->elf.splt || s == htab->elf.iplt || s == htab->elf.sgot
1720
0
    || s == htab->elf.sgotplt || s == htab->elf.igotplt
1721
0
    || s == htab->elf.sdynbss || s == htab->elf.sdynrelro)
1722
0
  {
1723
    /* Strip this section if we don't need it; see the
1724
       comment below.  */
1725
0
  }
1726
0
      else if (strncmp (s->name, ".rela", 5) == 0)
1727
0
  {
1728
0
    if (s->size != 0)
1729
0
      {
1730
        /* We use the reloc_count field as a counter if we need
1731
     to copy relocs into the output file.  */
1732
0
        s->reloc_count = 0;
1733
0
      }
1734
0
  }
1735
0
      else
1736
0
  {
1737
    /* It's not one of our sections.  */
1738
0
    continue;
1739
0
  }
1740
1741
0
      if (s->size == 0)
1742
0
  {
1743
    /* If we don't need this section, strip it from the
1744
       output file.  This is mostly to handle .rela.bss and
1745
       .rela.plt.  We must create both sections in
1746
       create_dynamic_sections, because they must be created
1747
       before the linker maps input sections to output
1748
       sections.  The linker does that before
1749
       adjust_dynamic_symbol is called, and it is that
1750
       function which decides whether anything needs to go
1751
       into these sections.  */
1752
0
    s->flags |= SEC_EXCLUDE;
1753
0
    continue;
1754
0
  }
1755
1756
0
      if ((s->flags & SEC_HAS_CONTENTS) == 0)
1757
0
  continue;
1758
1759
      /* Allocate memory for the section contents.  Zero the memory
1760
   for the benefit of .rela.plt, which has 4 unused entries
1761
   at the beginning, and we don't want garbage.  */
1762
0
      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
1763
0
      if (s->contents == NULL)
1764
0
  return false;
1765
0
    }
1766
1767
0
  if (elf_hash_table (info)->dynamic_sections_created)
1768
0
    {
1769
      /* Add some entries to the .dynamic section.  We fill in the
1770
   values later, in loongarch_elf_finish_dynamic_sections, but we
1771
   must add the entries now so that we get the correct size for
1772
   the .dynamic section.  The DT_DEBUG entry is filled in by the
1773
   dynamic linker and used by the debugger.  */
1774
0
#define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL)
1775
1776
0
      if (bfd_link_executable (info))
1777
0
  {
1778
0
    if (!add_dynamic_entry (DT_DEBUG, 0))
1779
0
      return false;
1780
0
  }
1781
1782
0
      if (htab->elf.srelplt->size != 0)
1783
0
  {
1784
0
    if (!add_dynamic_entry (DT_PLTGOT, 0)
1785
0
        || !add_dynamic_entry (DT_PLTRELSZ, 0)
1786
0
        || !add_dynamic_entry (DT_PLTREL, DT_RELA)
1787
0
        || !add_dynamic_entry (DT_JMPREL, 0))
1788
0
      return false;
1789
0
  }
1790
1791
0
      if (!add_dynamic_entry (DT_RELA, 0)
1792
0
    || !add_dynamic_entry (DT_RELASZ, 0)
1793
0
    || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
1794
0
  return false;
1795
1796
      /* If any dynamic relocs apply to a read-only section,
1797
   then we need a DT_TEXTREL entry.  */
1798
0
      if ((info->flags & DF_TEXTREL) == 0)
1799
0
  elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
1800
1801
0
      if (info->flags & DF_TEXTREL)
1802
0
  {
1803
0
    if (!add_dynamic_entry (DT_TEXTREL, 0))
1804
0
      return false;
1805
    /* Clear the DF_TEXTREL flag.  It will be set again if we
1806
       write out an actual text relocation; we may not, because
1807
       at this point we do not know whether e.g.  any .eh_frame
1808
       absolute relocations have been converted to PC-relative.  */
1809
0
    info->flags &= ~DF_TEXTREL;
1810
0
  }
1811
0
    }
1812
0
#undef add_dynamic_entry
1813
1814
0
  return true;
1815
0
}
1816
1817
0
#define LARCH_LD_STACK_DEPTH 16
1818
static int64_t larch_opc_stack[LARCH_LD_STACK_DEPTH];
1819
static size_t larch_stack_top = 0;
1820
1821
static bfd_reloc_status_type
1822
loongarch_push (int64_t val)
1823
0
{
1824
0
  if (LARCH_LD_STACK_DEPTH <= larch_stack_top)
1825
0
    return bfd_reloc_outofrange;
1826
0
  larch_opc_stack[larch_stack_top++] = val;
1827
0
  return bfd_reloc_ok;
1828
0
}
1829
1830
static bfd_reloc_status_type
1831
loongarch_pop (int64_t *val)
1832
0
{
1833
0
  if (larch_stack_top == 0)
1834
0
    return bfd_reloc_outofrange;
1835
0
  BFD_ASSERT (val);
1836
0
  *val = larch_opc_stack[--larch_stack_top];
1837
0
  return bfd_reloc_ok;
1838
0
}
1839
1840
static bfd_reloc_status_type
1841
loongarch_top (int64_t *val)
1842
0
{
1843
0
  if (larch_stack_top == 0)
1844
0
    return bfd_reloc_outofrange;
1845
0
  BFD_ASSERT (val);
1846
0
  *val = larch_opc_stack[larch_stack_top - 1];
1847
0
  return bfd_reloc_ok;
1848
0
}
1849
1850
static void
1851
loongarch_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
1852
0
{
1853
0
  BFD_ASSERT (s && s->contents);
1854
0
  const struct elf_backend_data *bed;
1855
0
  bfd_byte *loc;
1856
1857
0
  bed = get_elf_backend_data (abfd);
1858
0
  if (!(s->size > s->reloc_count * bed->s->sizeof_rela))
1859
0
    BFD_ASSERT (s->size > s->reloc_count * bed->s->sizeof_rela);
1860
0
  loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela);
1861
0
  bed->s->swap_reloca_out (abfd, rel, loc);
1862
0
}
1863
1864
/* Check rel->r_offset in range of contents.  */
1865
static bfd_reloc_status_type
1866
loongarch_check_offset (const Elf_Internal_Rela *rel,
1867
      const asection *input_section)
1868
0
{
1869
0
  if (0 == strcmp(input_section->name, ".text")
1870
0
      && rel->r_offset > input_section->size)
1871
0
    return bfd_reloc_overflow;
1872
1873
0
  return bfd_reloc_ok;
1874
0
}
1875
1876
#define LARCH_RELOC_PERFORM_3OP(op1, op2, op3)        \
1877
0
  ({                  \
1878
0
    bfd_reloc_status_type ret = loongarch_pop (&op2); \
1879
0
    if (ret == bfd_reloc_ok)           \
1880
0
      {                 \
1881
0
  ret = loongarch_pop (&op1);         \
1882
0
  if (ret == bfd_reloc_ok)         \
1883
0
    ret = loongarch_push (op3);         \
1884
0
      }                 \
1885
0
    ret;                \
1886
0
   })
1887
1888
static bfd_reloc_status_type
1889
loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela *rel,
1890
          const asection *input_section ATTRIBUTE_UNUSED,
1891
          reloc_howto_type *howto, bfd *input_bfd,
1892
          bfd_byte *contents, bfd_vma reloc_val)
1893
0
{
1894
0
  int bits = bfd_get_reloc_size (howto) * 8;
1895
0
  uint32_t insn = bfd_get (bits, input_bfd, contents + rel->r_offset);
1896
1897
0
  if (!loongarch_adjust_reloc_bitsfield (input_bfd, howto, &reloc_val))
1898
0
    return bfd_reloc_overflow;
1899
1900
0
  insn = (insn & (uint32_t)howto->src_mask)
1901
0
    | ((insn & (~(uint32_t)howto->dst_mask)) | reloc_val);
1902
1903
0
  bfd_put (bits, input_bfd, insn, contents + rel->r_offset);
1904
1905
0
  return bfd_reloc_ok;
1906
0
}
1907
1908
static bfd_reloc_status_type
1909
perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
1910
        reloc_howto_type *howto, bfd_vma value,
1911
        bfd *input_bfd, bfd_byte *contents)
1912
0
{
1913
0
  int64_t opr1, opr2, opr3;
1914
0
  bfd_reloc_status_type r = bfd_reloc_ok;
1915
0
  int bits = bfd_get_reloc_size (howto) * 8;
1916
1917
0
  switch (ELF64_R_TYPE (rel->r_info))
1918
0
    {
1919
0
    case R_LARCH_SOP_PUSH_PCREL:
1920
0
    case R_LARCH_SOP_PUSH_ABSOLUTE:
1921
0
    case R_LARCH_SOP_PUSH_GPREL:
1922
0
    case R_LARCH_SOP_PUSH_TLS_TPREL:
1923
0
    case R_LARCH_SOP_PUSH_TLS_GOT:
1924
0
    case R_LARCH_SOP_PUSH_TLS_GD:
1925
0
    case R_LARCH_SOP_PUSH_PLT_PCREL:
1926
0
      r = loongarch_push (value);
1927
0
      break;
1928
1929
0
    case R_LARCH_SOP_PUSH_DUP:
1930
0
      r = loongarch_pop (&opr1);
1931
0
      if (r == bfd_reloc_ok)
1932
0
  {
1933
0
    r = loongarch_push (opr1);
1934
0
    if (r == bfd_reloc_ok)
1935
0
      r = loongarch_push (opr1);
1936
0
  }
1937
0
      break;
1938
1939
0
    case R_LARCH_SOP_ASSERT:
1940
0
      r = loongarch_pop (&opr1);
1941
0
      if (r != bfd_reloc_ok || !opr1)
1942
0
  r = bfd_reloc_notsupported;
1943
0
      break;
1944
1945
0
    case R_LARCH_SOP_NOT:
1946
0
      r = loongarch_pop (&opr1);
1947
0
      if (r == bfd_reloc_ok)
1948
0
  r = loongarch_push (!opr1);
1949
0
      break;
1950
1951
0
    case R_LARCH_SOP_SUB:
1952
0
      r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 - opr2);
1953
0
      break;
1954
1955
0
    case R_LARCH_SOP_SL:
1956
0
      r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 << opr2);
1957
0
      break;
1958
1959
0
    case R_LARCH_SOP_SR:
1960
0
      r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 >> opr2);
1961
0
      break;
1962
1963
0
    case R_LARCH_SOP_AND:
1964
0
      r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 & opr2);
1965
0
      break;
1966
1967
0
    case R_LARCH_SOP_ADD:
1968
0
      r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 + opr2);
1969
0
      break;
1970
1971
0
    case R_LARCH_SOP_IF_ELSE:
1972
0
      r = loongarch_pop (&opr3);
1973
0
      if (r == bfd_reloc_ok)
1974
0
  {
1975
0
    r = loongarch_pop (&opr2);
1976
0
    if (r == bfd_reloc_ok)
1977
0
      {
1978
0
        r = loongarch_pop (&opr1);
1979
0
        if (r == bfd_reloc_ok)
1980
0
    r = loongarch_push (opr1 ? opr2 : opr3);
1981
0
      }
1982
0
  }
1983
0
      break;
1984
1985
0
    case R_LARCH_SOP_POP_32_S_10_5:
1986
0
    case R_LARCH_SOP_POP_32_S_10_12:
1987
0
    case R_LARCH_SOP_POP_32_S_10_16:
1988
0
    case R_LARCH_SOP_POP_32_S_10_16_S2:
1989
0
    case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
1990
0
    case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
1991
0
    case R_LARCH_SOP_POP_32_S_5_20:
1992
0
    case R_LARCH_SOP_POP_32_U_10_12:
1993
0
    case R_LARCH_SOP_POP_32_U:
1994
0
      r = loongarch_pop (&opr1);
1995
0
      if (r != bfd_reloc_ok)
1996
0
  break;
1997
0
      r = loongarch_check_offset (rel, input_section);
1998
0
      if (r != bfd_reloc_ok)
1999
0
  break;
2000
2001
0
      r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
2002
0
              howto, input_bfd,
2003
0
              contents, (bfd_vma)opr1);
2004
0
      break;
2005
2006
0
    case R_LARCH_TLS_DTPREL32:
2007
0
    case R_LARCH_32:
2008
0
    case R_LARCH_TLS_DTPREL64:
2009
0
    case R_LARCH_64:
2010
0
      r = loongarch_check_offset (rel, input_section);
2011
0
      if (r != bfd_reloc_ok)
2012
0
  break;
2013
2014
0
      bfd_put (bits, input_bfd, value, contents + rel->r_offset);
2015
0
      break;
2016
2017
    /* LoongArch only has add/sub reloc pair, not has set/sub reloc pair.
2018
       Because set/sub reloc pair not support multi-thread. While add/sub
2019
       reloc pair process order not affect the final result.
2020
2021
       For add/sub reloc, the original value will be involved in the
2022
       calculation. In order not to add/sub extra value, we write 0 to symbol
2023
       address at assembly time.
2024
2025
       add/sub reloc bits determined by the value after symbol subtraction,
2026
       not symbol value.
2027
2028
       add/sub reloc save part of the symbol value, so we only need to
2029
       save howto->dst_mask bits.  */
2030
0
    case R_LARCH_ADD6:
2031
0
    case R_LARCH_SUB6:
2032
0
      {
2033
0
  bfd_vma word = bfd_get (howto->bitsize, input_bfd,
2034
0
        contents + rel->r_offset);
2035
0
  word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
2036
0
  bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2037
0
  r = bfd_reloc_ok;
2038
0
  break;
2039
0
      }
2040
2041
    /* Not need to read the original value, just write the new value.  */
2042
0
    case R_LARCH_ADD8:
2043
0
    case R_LARCH_ADD16:
2044
0
    case R_LARCH_ADD24:
2045
0
    case R_LARCH_ADD32:
2046
0
    case R_LARCH_ADD64:
2047
0
    case R_LARCH_SUB8:
2048
0
    case R_LARCH_SUB16:
2049
0
    case R_LARCH_SUB24:
2050
0
    case R_LARCH_SUB32:
2051
0
    case R_LARCH_SUB64:
2052
0
      {
2053
  /* Because add/sub reloc is processed separately,
2054
     so the high bits is invalid.  */
2055
0
  bfd_vma word = value & howto->dst_mask;
2056
0
  bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2057
0
  r = bfd_reloc_ok;
2058
0
  break;
2059
0
      }
2060
2061
0
    case R_LARCH_ADD_ULEB128:
2062
0
    case R_LARCH_SUB_ULEB128:
2063
0
      {
2064
0
  unsigned int len = 0;
2065
  /* Before write uleb128, first read it to get it's length.  */
2066
0
  _bfd_read_unsigned_leb128 (input_bfd, contents + rel->r_offset, &len);
2067
0
  loongarch_write_unsigned_leb128 (contents + rel->r_offset, len, value);
2068
0
  r = bfd_reloc_ok;
2069
0
  break;
2070
0
      }
2071
2072
    /* For eh_frame and debug info.  */
2073
0
    case R_LARCH_32_PCREL:
2074
0
    case R_LARCH_64_PCREL:
2075
0
      {
2076
0
  value -= sec_addr (input_section) + rel->r_offset;
2077
0
  value += rel->r_addend;
2078
0
  bfd_vma word = bfd_get (howto->bitsize, input_bfd,
2079
0
        contents + rel->r_offset);
2080
0
  word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
2081
0
  bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2082
0
  r = bfd_reloc_ok;
2083
0
  break;
2084
0
      }
2085
2086
    /* New reloc type.
2087
       R_LARCH_B16 ~ R_LARCH_TLS_GD_HI20.  */
2088
0
    case R_LARCH_B16:
2089
0
    case R_LARCH_B21:
2090
0
    case R_LARCH_B26:
2091
0
    case R_LARCH_ABS_HI20:
2092
0
    case R_LARCH_ABS_LO12:
2093
0
    case R_LARCH_ABS64_LO20:
2094
0
    case R_LARCH_ABS64_HI12:
2095
0
    case R_LARCH_PCALA_HI20:
2096
0
    case R_LARCH_PCALA_LO12:
2097
0
    case R_LARCH_PCALA64_LO20:
2098
0
    case R_LARCH_PCALA64_HI12:
2099
0
    case R_LARCH_GOT_PC_HI20:
2100
0
    case R_LARCH_GOT_PC_LO12:
2101
0
    case R_LARCH_GOT64_PC_LO20:
2102
0
    case R_LARCH_GOT64_PC_HI12:
2103
0
    case R_LARCH_GOT_HI20:
2104
0
    case R_LARCH_GOT_LO12:
2105
0
    case R_LARCH_GOT64_LO20:
2106
0
    case R_LARCH_GOT64_HI12:
2107
0
    case R_LARCH_TLS_LE_HI20:
2108
0
    case R_LARCH_TLS_LE_LO12:
2109
0
    case R_LARCH_TLS_LE64_LO20:
2110
0
    case R_LARCH_TLS_LE64_HI12:
2111
0
    case R_LARCH_TLS_IE_PC_HI20:
2112
0
    case R_LARCH_TLS_IE_PC_LO12:
2113
0
    case R_LARCH_TLS_IE64_PC_LO20:
2114
0
    case R_LARCH_TLS_IE64_PC_HI12:
2115
0
    case R_LARCH_TLS_IE_HI20:
2116
0
    case R_LARCH_TLS_IE_LO12:
2117
0
    case R_LARCH_TLS_IE64_LO20:
2118
0
    case R_LARCH_TLS_IE64_HI12:
2119
0
    case R_LARCH_TLS_LD_PC_HI20:
2120
0
    case R_LARCH_TLS_LD_HI20:
2121
0
    case R_LARCH_TLS_GD_PC_HI20:
2122
0
    case R_LARCH_TLS_GD_HI20:
2123
0
    case R_LARCH_PCREL20_S2:
2124
0
      r = loongarch_check_offset (rel, input_section);
2125
0
      if (r != bfd_reloc_ok)
2126
0
  break;
2127
2128
0
      r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
2129
0
              howto, input_bfd,
2130
0
              contents, value);
2131
0
      break;
2132
2133
0
    case R_LARCH_RELAX:
2134
0
      break;
2135
2136
0
    default:
2137
0
      r = bfd_reloc_notsupported;
2138
0
    }
2139
0
  return r;
2140
0
}
2141
2142
0
#define LARCH_RECENT_RELOC_QUEUE_LENGTH 72
2143
static struct
2144
{
2145
  bfd *bfd;
2146
  asection *section;
2147
  bfd_vma r_offset;
2148
  int r_type;
2149
  bfd_vma relocation;
2150
  Elf_Internal_Sym *sym;
2151
  struct elf_link_hash_entry *h;
2152
  bfd_vma addend;
2153
  int64_t top_then;
2154
} larch_reloc_queue[LARCH_RECENT_RELOC_QUEUE_LENGTH];
2155
static size_t larch_reloc_queue_head = 0;
2156
static size_t larch_reloc_queue_tail = 0;
2157
2158
static const char *
2159
loongarch_sym_name (bfd *input_bfd, struct elf_link_hash_entry *h,
2160
        Elf_Internal_Sym *sym)
2161
0
{
2162
0
  const char *ret = NULL;
2163
0
  if (sym)
2164
0
    ret = bfd_elf_string_from_elf_section (input_bfd,
2165
0
             elf_symtab_hdr (input_bfd).sh_link,
2166
0
             sym->st_name);
2167
0
  else if (h)
2168
0
    ret = h->root.root.string;
2169
2170
0
  if (ret == NULL || *ret == '\0')
2171
0
    ret = "<nameless>";
2172
0
  return ret;
2173
0
}
2174
2175
static void
2176
loongarch_record_one_reloc (bfd *abfd, asection *section, int r_type,
2177
          bfd_vma r_offset, Elf_Internal_Sym *sym,
2178
          struct elf_link_hash_entry *h, bfd_vma addend)
2179
0
{
2180
0
  if ((larch_reloc_queue_head == 0
2181
0
       && larch_reloc_queue_tail == LARCH_RECENT_RELOC_QUEUE_LENGTH - 1)
2182
0
      || larch_reloc_queue_head == larch_reloc_queue_tail + 1)
2183
0
    larch_reloc_queue_head =
2184
0
      (larch_reloc_queue_head + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2185
0
  larch_reloc_queue[larch_reloc_queue_tail].bfd = abfd;
2186
0
  larch_reloc_queue[larch_reloc_queue_tail].section = section;
2187
0
  larch_reloc_queue[larch_reloc_queue_tail].r_offset = r_offset;
2188
0
  larch_reloc_queue[larch_reloc_queue_tail].r_type = r_type;
2189
0
  larch_reloc_queue[larch_reloc_queue_tail].sym = sym;
2190
0
  larch_reloc_queue[larch_reloc_queue_tail].h = h;
2191
0
  larch_reloc_queue[larch_reloc_queue_tail].addend = addend;
2192
0
  loongarch_top (&larch_reloc_queue[larch_reloc_queue_tail].top_then);
2193
0
  larch_reloc_queue_tail =
2194
0
    (larch_reloc_queue_tail + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2195
0
}
2196
2197
static void
2198
loongarch_dump_reloc_record (void (*p) (const char *fmt, ...))
2199
0
{
2200
0
  size_t i = larch_reloc_queue_head;
2201
0
  bfd *a_bfd = NULL;
2202
0
  asection *section = NULL;
2203
0
  bfd_vma r_offset = 0;
2204
0
  int inited = 0;
2205
0
  p ("Dump relocate record:\n");
2206
0
  p ("stack top\t\trelocation name\t\tsymbol");
2207
0
  while (i != larch_reloc_queue_tail)
2208
0
    {
2209
0
      if (a_bfd != larch_reloc_queue[i].bfd
2210
0
    || section != larch_reloc_queue[i].section
2211
0
    || r_offset != larch_reloc_queue[i].r_offset)
2212
0
  {
2213
0
    a_bfd = larch_reloc_queue[i].bfd;
2214
0
    section = larch_reloc_queue[i].section;
2215
0
    r_offset = larch_reloc_queue[i].r_offset;
2216
0
    p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue[i].bfd,
2217
0
       larch_reloc_queue[i].section, larch_reloc_queue[i].r_offset);
2218
0
  }
2219
2220
0
      if (!inited)
2221
0
  inited = 1, p ("...\n");
2222
2223
0
      reloc_howto_type *howto =
2224
0
  loongarch_elf_rtype_to_howto (larch_reloc_queue[i].bfd,
2225
0
              larch_reloc_queue[i].r_type);
2226
0
      p ("0x%V %s\t`%s'", (bfd_vma) larch_reloc_queue[i].top_then,
2227
0
   howto ? howto->name : "<unknown reloc>",
2228
0
   loongarch_sym_name (larch_reloc_queue[i].bfd, larch_reloc_queue[i].h,
2229
0
           larch_reloc_queue[i].sym));
2230
2231
0
      long addend = larch_reloc_queue[i].addend;
2232
0
      if (addend < 0)
2233
0
  p (" - %ld", -addend);
2234
0
      else if (0 < addend)
2235
0
  p (" + %ld(0x%v)", addend, larch_reloc_queue[i].addend);
2236
2237
0
      p ("\n");
2238
0
      i = (i + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2239
0
    }
2240
0
  p ("\n"
2241
0
     "-- Record dump end --\n\n");
2242
0
}
2243
2244
static bool
2245
loongarch_reloc_is_fatal (struct bfd_link_info *info,
2246
        bfd *input_bfd,
2247
        asection *input_section,
2248
        Elf_Internal_Rela *rel,
2249
        reloc_howto_type *howto,
2250
        bfd_reloc_status_type rtype,
2251
        bool is_undefweak,
2252
        const char *name,
2253
        const char *msg)
2254
0
{
2255
0
  bool fatal = true;
2256
0
  switch (rtype)
2257
0
    {
2258
      /* 'dangerous' means we do it but can't promise it's ok
2259
   'unsupport' means out of ability of relocation type
2260
   'undefined' means we can't deal with the undefined symbol.  */
2261
0
    case bfd_reloc_undefined:
2262
0
      info->callbacks->undefined_symbol (info, name, input_bfd, input_section,
2263
0
           rel->r_offset, true);
2264
0
      info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2265
0
           input_bfd, input_section, rel->r_offset,
2266
0
           howto->name,
2267
0
           is_undefweak ? "[undefweak] " : "", name, msg);
2268
0
      break;
2269
0
    case bfd_reloc_dangerous:
2270
0
      info->callbacks->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n",
2271
0
           input_bfd, input_section, rel->r_offset,
2272
0
           howto->name,
2273
0
           is_undefweak ? "[undefweak] " : "", name, msg);
2274
0
      fatal = false;
2275
0
      break;
2276
0
    case bfd_reloc_notsupported:
2277
0
      info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2278
0
           input_bfd, input_section, rel->r_offset,
2279
0
           howto->name,
2280
0
           is_undefweak ? "[undefweak] " : "", name, msg);
2281
0
      break;
2282
0
    default:
2283
0
      break;
2284
0
    }
2285
0
  return fatal;
2286
0
}
2287
2288
/* If lo12 immediate > 0x7ff, because sign-extend caused by addi.d/ld.d,
2289
   hi20 immediate need to add 0x1.
2290
   For example: pc 0x120000000, symbol 0x120000812
2291
   lo12 immediate is 0x812, 0x120000812 & 0xfff = 0x812
2292
   hi20 immediate is 1, because lo12 imm > 0x7ff, symbol need to add 0x1000
2293
   (((0x120000812 + 0x1000) & ~0xfff) - (0x120000000 & ~0xfff)) >> 12 = 0x1
2294
2295
   At run:
2296
   pcalau12i $t0, hi20 (0x1)
2297
      $t0 = 0x120000000 + (0x1 << 12) = 0x120001000
2298
   addi.d $t0, $t0, lo12 (0x812)
2299
      $t0 = 0x120001000 + 0xfffffffffffff812 (-(0x1000 - 0x812) = -0x7ee)
2300
    = 0x120001000 - 0x7ee (0x1000 - 0x7ee = 0x812)
2301
    = 0x120000812
2302
    Without hi20 add 0x1000, the result 0x120000000 - 0x7ee = 0x11ffff812 is
2303
    error.
2304
    0x1000 + sign-extend-to64(0x8xx) = 0x8xx.  */
2305
#define RELOCATE_CALC_PC32_HI20(relocation, pc)   \
2306
0
  ({              \
2307
0
    bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
2308
0
    relocation = (relocation & ~(bfd_vma)0xfff)   \
2309
0
      - (pc & ~(bfd_vma)0xfff);   \
2310
0
    if (__lo > 0x7ff)         \
2311
0
  relocation += 0x1000;       \
2312
0
  })
2313
2314
/* For example: pc is 0x11000010000100, symbol is 0x1812348ffff812
2315
   offset = (0x1812348ffff812 & ~0xfff) - (0x11000010000100 & ~0xfff)
2316
    = 0x712347ffff000
2317
   lo12: 0x1812348ffff812 & 0xfff = 0x812
2318
   hi20: 0x7ffff + 0x1(lo12 > 0x7ff) = 0x80000
2319
   lo20: 0x71234 - 0x1(lo12 > 0x7ff) + 0x1(hi20 > 0x7ffff)
2320
   hi12: 0x0
2321
2322
   pcalau12i $t1, hi20 (0x80000)
2323
      $t1 = 0x11000010000100 + sign-extend(0x80000 << 12)
2324
    = 0x11000010000100 + 0xffffffff80000000
2325
    = 0x10ffff90000000
2326
   addi.d $t0, $zero, lo12 (0x812)
2327
      $t0 = 0xfffffffffffff812 (if lo12 > 0x7ff, because sign-extend,
2328
      lo20 need to sub 0x1)
2329
   lu32i.d $t0, lo12 (0x71234)
2330
      $t0 = {0x71234, 0xfffff812}
2331
    = 0x71234fffff812
2332
   lu52i.d $t0, hi12 (0x0)
2333
      $t0 = {0x0, 0x71234fffff812}
2334
    = 0x71234fffff812
2335
   add.d $t1, $t1, $t0
2336
      $t1 = 0x10ffff90000000 + 0x71234fffff812
2337
    = 0x1812348ffff812.  */
2338
#define RELOCATE_CALC_PC64_HI32(relocation, pc)   \
2339
0
  ({              \
2340
0
    bfd_vma __lo = (relocation & (bfd_vma)0xfff); \
2341
0
    relocation = (relocation & ~(bfd_vma)0xfff)   \
2342
0
      - (pc & ~(bfd_vma)0xfff);   \
2343
0
    if (__lo > 0x7ff)         \
2344
0
  relocation += (0x1000 - 0x100000000);   \
2345
0
    if (relocation & 0x80000000)     \
2346
0
      relocation += 0x100000000;     \
2347
0
  })
2348
2349
static int
2350
loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
2351
        bfd *input_bfd, asection *input_section,
2352
        bfd_byte *contents, Elf_Internal_Rela *relocs,
2353
        Elf_Internal_Sym *local_syms,
2354
        asection **local_sections)
2355
0
{
2356
0
  Elf_Internal_Rela *rel;
2357
0
  Elf_Internal_Rela *relend;
2358
0
  bool fatal = false;
2359
0
  asection *sreloc = elf_section_data (input_section)->sreloc;
2360
0
  struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
2361
0
  Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd);
2362
0
  struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
2363
0
  bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd);
2364
0
  bool is_pic = bfd_link_pic (info);
2365
0
  bool is_dyn = elf_hash_table (info)->dynamic_sections_created;
2366
0
  asection *plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
2367
0
  asection *got = htab->elf.sgot;
2368
2369
0
  relend = relocs + input_section->reloc_count;
2370
0
  for (rel = relocs; rel < relend; rel++)
2371
0
    {
2372
0
      int r_type = ELF64_R_TYPE (rel->r_info);
2373
0
      unsigned long r_symndx = ELF64_R_SYM (rel->r_info);
2374
0
      bfd_vma pc = sec_addr (input_section) + rel->r_offset;
2375
0
      reloc_howto_type *howto = NULL;
2376
0
      asection *sec = NULL;
2377
0
      Elf_Internal_Sym *sym = NULL;
2378
0
      struct elf_link_hash_entry *h = NULL;
2379
0
      const char *name;
2380
0
      bfd_reloc_status_type r = bfd_reloc_ok;
2381
0
      bool is_ie, is_undefweak, unresolved_reloc, defined_local;
2382
0
      bool resolved_local, resolved_dynly, resolved_to_const;
2383
0
      char tls_type;
2384
0
      bfd_vma relocation, off, ie_off;
2385
0
      int i, j;
2386
2387
0
      howto = loongarch_elf_rtype_to_howto (input_bfd, r_type);
2388
0
      if (howto == NULL || r_type == R_LARCH_GNU_VTINHERIT
2389
0
    || r_type == R_LARCH_GNU_VTENTRY)
2390
0
  continue;
2391
2392
      /* This is a final link.  */
2393
0
      if (r_symndx < symtab_hdr->sh_info)
2394
0
  {
2395
0
    is_undefweak = false;
2396
0
    unresolved_reloc = false;
2397
0
    sym = local_syms + r_symndx;
2398
0
    sec = local_sections[r_symndx];
2399
0
    relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2400
2401
    /* Relocate against local STT_GNU_IFUNC symbol.  */
2402
0
    if (!bfd_link_relocatable (info)
2403
0
        && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
2404
0
      {
2405
0
        h = elf64_loongarch_get_local_sym_hash (htab, input_bfd, rel,
2406
0
                  false);
2407
0
        if (h == NULL)
2408
0
    abort ();
2409
2410
        /* Set STT_GNU_IFUNC symbol value.  */
2411
0
        h->root.u.def.value = sym->st_value;
2412
0
        h->root.u.def.section = sec;
2413
0
      }
2414
0
    defined_local = true;
2415
0
    resolved_local = true;
2416
0
    resolved_dynly = false;
2417
0
    resolved_to_const = false;
2418
2419
    /* Calc in funtion elf_link_input_bfd,
2420
     * if #define elf_backend_rela_normal to 1.  */
2421
0
    if (bfd_link_relocatable (info)
2422
0
        && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2423
0
      continue;
2424
0
  }
2425
0
      else
2426
0
  {
2427
0
    bool warned, ignored;
2428
2429
0
    RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2430
0
           r_symndx, symtab_hdr, sym_hashes,
2431
0
           h, sec, relocation,
2432
0
           unresolved_reloc, warned, ignored);
2433
    /* Here means symbol isn't local symbol only and 'h != NULL'.  */
2434
2435
    /* The 'unresolved_syms_in_objects' specify how to deal with undefined
2436
       symbol.  And 'dynamic_undefined_weak' specify what to do when
2437
       meeting undefweak.  */
2438
2439
0
    if ((is_undefweak = h->root.type == bfd_link_hash_undefweak))
2440
0
      {
2441
0
        defined_local = false;
2442
0
        resolved_local = false;
2443
0
        resolved_to_const = (!is_dyn || h->dynindx == -1
2444
0
           || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
2445
0
        resolved_dynly = !resolved_local && !resolved_to_const;
2446
0
      }
2447
0
    else if (warned)
2448
0
      {
2449
        /* Symbol undefined offen means failed already.  I don't know why
2450
     'warned' here but I guess it want to continue relocating as if
2451
     no error occures to find other errors as more as possible.  */
2452
2453
        /* To avoid generating warning messages about truncated
2454
     relocations, set the relocation's address to be the same as
2455
     the start of this section.  */
2456
0
        relocation = (input_section->output_section
2457
0
          ? input_section->output_section->vma
2458
0
          : 0);
2459
2460
0
        defined_local = relocation != 0;
2461
0
        resolved_local = defined_local;
2462
0
        resolved_to_const = !resolved_local;
2463
0
        resolved_dynly = false;
2464
0
      }
2465
0
    else
2466
0
      {
2467
0
        defined_local = !unresolved_reloc && !ignored;
2468
0
        resolved_local =
2469
0
    defined_local && SYMBOL_REFERENCES_LOCAL (info, h);
2470
0
        resolved_dynly = !resolved_local;
2471
0
        resolved_to_const = !resolved_local && !resolved_dynly;
2472
0
      }
2473
0
  }
2474
2475
0
      name = loongarch_sym_name (input_bfd, h, sym);
2476
2477
0
      if (sec != NULL && discarded_section (sec))
2478
0
  RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel,
2479
0
           1, relend, howto, 0, contents);
2480
2481
0
      if (bfd_link_relocatable (info))
2482
0
  continue;
2483
2484
      /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
2485
   from removed linkonce sections, or sections discarded by a linker
2486
   script.  Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const.  */
2487
0
      if (r_symndx == STN_UNDEF || bfd_is_abs_section (sec))
2488
0
  {
2489
0
    defined_local = false;
2490
0
    resolved_local = false;
2491
0
    resolved_dynly = false;
2492
0
    resolved_to_const = true;
2493
0
  }
2494
2495
      /* The ifunc reference generate plt.  */
2496
0
      if (h && h->type == STT_GNU_IFUNC && h->plt.offset != MINUS_ONE)
2497
0
  {
2498
0
    defined_local = true;
2499
0
    resolved_local = true;
2500
0
    resolved_dynly = false;
2501
0
    resolved_to_const = false;
2502
0
    relocation = sec_addr (plt) + h->plt.offset;
2503
0
  }
2504
2505
0
      unresolved_reloc = resolved_dynly;
2506
2507
0
      BFD_ASSERT (resolved_local + resolved_dynly + resolved_to_const == 1);
2508
2509
      /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));.  */
2510
2511
0
      BFD_ASSERT (!resolved_local || defined_local);
2512
2513
0
      is_ie = false;
2514
0
      switch (r_type)
2515
0
  {
2516
0
  case R_LARCH_MARK_PCREL:
2517
0
  case R_LARCH_MARK_LA:
2518
0
  case R_LARCH_NONE:
2519
0
    r = bfd_reloc_continue;
2520
0
    unresolved_reloc = false;
2521
0
    break;
2522
2523
0
  case R_LARCH_32:
2524
0
  case R_LARCH_64:
2525
0
    if (resolved_dynly || (is_pic && resolved_local))
2526
0
      {
2527
0
        Elf_Internal_Rela outrel;
2528
2529
        /* When generating a shared object, these relocations are copied
2530
     into the output file to be resolved at run time.  */
2531
2532
0
        outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2533
0
               input_section,
2534
0
               rel->r_offset);
2535
2536
0
        unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2537
0
          && (input_section->flags & SEC_ALLOC));
2538
2539
0
        outrel.r_offset += sec_addr (input_section);
2540
2541
        /* A pointer point to a ifunc symbol.  */
2542
0
        if (h && h->type == STT_GNU_IFUNC)
2543
0
    {
2544
0
      if (h->dynindx == -1)
2545
0
        {
2546
0
          outrel.r_info = ELF64_R_INFO (0, R_LARCH_IRELATIVE);
2547
0
          outrel.r_addend = (h->root.u.def.value
2548
0
          + h->root.u.def.section->output_section->vma
2549
0
          + h->root.u.def.section->output_offset);
2550
0
        }
2551
0
      else
2552
0
        {
2553
0
          outrel.r_info = ELF64_R_INFO (h->dynindx, R_LARCH_64);
2554
0
          outrel.r_addend = 0;
2555
0
        }
2556
2557
0
      if (SYMBOL_REFERENCES_LOCAL (info, h))
2558
0
        {
2559
2560
0
          if (htab->elf.splt != NULL)
2561
0
      sreloc = htab->elf.srelgot;
2562
0
          else
2563
0
      sreloc = htab->elf.irelplt;
2564
0
        }
2565
0
      else
2566
0
        {
2567
2568
0
          if (bfd_link_pic (info))
2569
0
      sreloc = htab->elf.irelifunc;
2570
0
          else if (htab->elf.splt != NULL)
2571
0
      sreloc = htab->elf.srelgot;
2572
0
          else
2573
0
      sreloc = htab->elf.irelplt;
2574
0
        }
2575
0
    }
2576
0
        else if (resolved_dynly)
2577
0
    {
2578
0
      if (h->dynindx == -1)
2579
0
        {
2580
0
          if (h->root.type == bfd_link_hash_undefined)
2581
0
      (*info->callbacks->undefined_symbol)
2582
0
        (info, name, input_bfd, input_section,
2583
0
         rel->r_offset, true);
2584
2585
0
          outrel.r_info = ELF64_R_INFO (0, r_type);
2586
0
        }
2587
0
      else
2588
0
        outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
2589
2590
0
      outrel.r_addend = rel->r_addend;
2591
0
    }
2592
0
        else
2593
0
    {
2594
0
      outrel.r_info = ELF64_R_INFO (0, R_LARCH_RELATIVE);
2595
0
      outrel.r_addend = relocation + rel->r_addend;
2596
0
    }
2597
2598
        /* No alloc space of func allocate_dynrelocs.  */
2599
0
        if (unresolved_reloc
2600
0
      && !(h && (h->is_weakalias || !h->dyn_relocs)))
2601
0
    loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2602
0
      }
2603
2604
0
    relocation += rel->r_addend;
2605
0
    break;
2606
2607
0
  case R_LARCH_ADD6:
2608
0
  case R_LARCH_ADD8:
2609
0
  case R_LARCH_ADD16:
2610
0
  case R_LARCH_ADD24:
2611
0
  case R_LARCH_ADD32:
2612
0
  case R_LARCH_ADD64:
2613
0
    {
2614
0
      bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
2615
0
           contents + rel->r_offset);
2616
0
      relocation = old_value + relocation + rel->r_addend;
2617
0
      break;
2618
0
    }
2619
2620
0
  case R_LARCH_SUB6:
2621
0
  case R_LARCH_SUB8:
2622
0
  case R_LARCH_SUB16:
2623
0
  case R_LARCH_SUB24:
2624
0
  case R_LARCH_SUB32:
2625
0
  case R_LARCH_SUB64:
2626
0
    {
2627
0
      bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
2628
0
            contents + rel->r_offset);
2629
0
      relocation = old_value - relocation - rel->r_addend;
2630
0
      break;
2631
0
    }
2632
2633
0
  case R_LARCH_ADD_ULEB128:
2634
0
  case R_LARCH_SUB_ULEB128:
2635
0
    {
2636
      /* Get the value and length of the uleb128 data.  */
2637
0
      unsigned int len = 0;
2638
0
      bfd_vma old_value = _bfd_read_unsigned_leb128 (input_bfd,
2639
0
            contents + rel->r_offset, &len);
2640
2641
0
      if (R_LARCH_ADD_ULEB128 == ELF64_R_TYPE (rel->r_info))
2642
0
        relocation = old_value + relocation + rel->r_addend;
2643
0
      else if (R_LARCH_SUB_ULEB128 == ELF64_R_TYPE (rel->r_info))
2644
0
        relocation = old_value - relocation - rel->r_addend;
2645
2646
0
      bfd_vma mask = (1 << (7 * len)) - 1;
2647
0
      relocation &= mask;
2648
0
      break;
2649
0
    }
2650
2651
0
  case R_LARCH_TLS_DTPREL32:
2652
0
  case R_LARCH_TLS_DTPREL64:
2653
0
    if (resolved_dynly)
2654
0
      {
2655
0
        Elf_Internal_Rela outrel;
2656
2657
0
        outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2658
0
               input_section,
2659
0
               rel->r_offset);
2660
0
        unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2661
0
          && (input_section->flags & SEC_ALLOC));
2662
0
        outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
2663
0
        outrel.r_offset += sec_addr (input_section);
2664
0
        outrel.r_addend = rel->r_addend;
2665
0
        if (unresolved_reloc)
2666
0
    loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2667
0
        break;
2668
0
      }
2669
2670
0
    if (resolved_to_const)
2671
0
      fatal = loongarch_reloc_is_fatal (info, input_bfd, input_section,
2672
0
                rel, howto,
2673
0
                bfd_reloc_notsupported,
2674
0
                is_undefweak, name,
2675
0
                "Internal:");
2676
0
    if (resolved_local)
2677
0
      {
2678
0
        if (!elf_hash_table (info)->tls_sec)
2679
0
    {
2680
0
    fatal = loongarch_reloc_is_fatal (info, input_bfd,
2681
0
        input_section, rel, howto, bfd_reloc_notsupported,
2682
0
        is_undefweak, name, "TLS section not be created");
2683
0
    }
2684
0
        else
2685
0
    relocation -= elf_hash_table (info)->tls_sec->vma;
2686
0
      }
2687
0
    else
2688
0
      {
2689
0
      fatal = loongarch_reloc_is_fatal (info, input_bfd,
2690
0
          input_section, rel, howto, bfd_reloc_undefined,
2691
0
          is_undefweak, name,
2692
0
          "TLS LE just can be resolved local only.");
2693
0
      }
2694
2695
0
    break;
2696
2697
0
  case R_LARCH_SOP_PUSH_TLS_TPREL:
2698
0
    if (resolved_local)
2699
0
      {
2700
0
        if (!elf_hash_table (info)->tls_sec)
2701
0
    fatal = (loongarch_reloc_is_fatal
2702
0
       (info, input_bfd, input_section, rel, howto,
2703
0
        bfd_reloc_notsupported, is_undefweak, name,
2704
0
        "TLS section not be created"));
2705
0
        else
2706
0
    relocation -= elf_hash_table (info)->tls_sec->vma;
2707
0
      }
2708
0
    else
2709
0
      fatal = (loongarch_reloc_is_fatal
2710
0
         (info, input_bfd, input_section, rel, howto,
2711
0
          bfd_reloc_undefined, is_undefweak, name,
2712
0
          "TLS LE just can be resolved local only."));
2713
0
    break;
2714
2715
0
  case R_LARCH_SOP_PUSH_ABSOLUTE:
2716
0
    if (is_undefweak)
2717
0
      {
2718
0
        if (resolved_dynly)
2719
0
    fatal = (loongarch_reloc_is_fatal
2720
0
       (info, input_bfd, input_section, rel, howto,
2721
0
        bfd_reloc_dangerous, is_undefweak, name,
2722
0
        "Someone require us to resolve undefweak "
2723
0
        "symbol dynamically.  \n"
2724
0
        "But this reloc can't be done.  "
2725
0
        "I think I can't throw error "
2726
0
        "for this\n"
2727
0
        "so I resolved it to 0.  "
2728
0
        "I suggest to re-compile with '-fpic'."));
2729
2730
0
        relocation = 0;
2731
0
        unresolved_reloc = false;
2732
0
        break;
2733
0
      }
2734
2735
0
    if (resolved_to_const)
2736
0
      {
2737
0
        relocation += rel->r_addend;
2738
0
        break;
2739
0
      }
2740
2741
0
    if (is_pic)
2742
0
      {
2743
0
        fatal = (loongarch_reloc_is_fatal
2744
0
           (info, input_bfd, input_section, rel, howto,
2745
0
      bfd_reloc_notsupported, is_undefweak, name,
2746
0
      "Under PIC we don't know load address.  Re-compile "
2747
0
      "with '-fpic'?"));
2748
0
        break;
2749
0
      }
2750
2751
0
    if (resolved_dynly)
2752
0
      {
2753
0
        if (!(plt && h && h->plt.offset != MINUS_ONE))
2754
0
    {
2755
0
      fatal = (loongarch_reloc_is_fatal
2756
0
         (info, input_bfd, input_section, rel, howto,
2757
0
          bfd_reloc_undefined, is_undefweak, name,
2758
0
          "Can't be resolved dynamically.  Try to re-compile "
2759
0
          "with '-fpic'?"));
2760
0
      break;
2761
0
    }
2762
2763
0
        if (rel->r_addend != 0)
2764
0
    {
2765
0
      fatal = (loongarch_reloc_is_fatal
2766
0
         (info, input_bfd, input_section, rel, howto,
2767
0
          bfd_reloc_notsupported, is_undefweak, name,
2768
0
          "Shouldn't be with r_addend."));
2769
0
      break;
2770
0
    }
2771
2772
0
        relocation = sec_addr (plt) + h->plt.offset;
2773
0
        unresolved_reloc = false;
2774
0
        break;
2775
0
      }
2776
2777
0
    if (resolved_local)
2778
0
      {
2779
0
        relocation += rel->r_addend;
2780
0
        break;
2781
0
      }
2782
2783
0
    break;
2784
2785
0
  case R_LARCH_SOP_PUSH_PCREL:
2786
0
  case R_LARCH_SOP_PUSH_PLT_PCREL:
2787
0
    unresolved_reloc = false;
2788
2789
0
    if (is_undefweak)
2790
0
      {
2791
0
        i = 0, j = 0;
2792
0
        relocation = 0;
2793
0
        if (resolved_dynly)
2794
0
    {
2795
0
      if (h && h->plt.offset != MINUS_ONE)
2796
0
        i = 1, j = 2;
2797
0
      else
2798
0
        fatal = (loongarch_reloc_is_fatal
2799
0
           (info, input_bfd, input_section, rel, howto,
2800
0
            bfd_reloc_dangerous, is_undefweak, name,
2801
0
            "Undefweak need to be resolved dynamically, "
2802
0
            "but PLT stub doesn't represent."));
2803
0
    }
2804
0
      }
2805
0
    else
2806
0
      {
2807
0
        if (!(defined_local || (h && h->plt.offset != MINUS_ONE)))
2808
0
    {
2809
0
      fatal = (loongarch_reloc_is_fatal
2810
0
         (info, input_bfd, input_section, rel, howto,
2811
0
          bfd_reloc_undefined, is_undefweak, name,
2812
0
          "PLT stub does not represent and "
2813
0
          "symbol not defined."));
2814
0
      break;
2815
0
    }
2816
2817
0
        if (resolved_local)
2818
0
    i = 0, j = 2;
2819
0
        else /* if (resolved_dynly) */
2820
0
    {
2821
0
      if (!(h && h->plt.offset != MINUS_ONE))
2822
0
        fatal = (loongarch_reloc_is_fatal
2823
0
           (info, input_bfd, input_section, rel, howto,
2824
0
            bfd_reloc_dangerous, is_undefweak, name,
2825
0
            "Internal: PLT stub doesn't represent.  "
2826
0
            "Resolve it with pcrel"));
2827
0
      i = 1, j = 3;
2828
0
    }
2829
0
      }
2830
2831
0
    for (; i < j; i++)
2832
0
      {
2833
0
        if ((i & 1) == 0 && defined_local)
2834
0
    {
2835
0
      relocation -= pc;
2836
0
      relocation += rel->r_addend;
2837
0
      break;
2838
0
    }
2839
2840
0
        if ((i & 1) && h && h->plt.offset != MINUS_ONE)
2841
0
    {
2842
0
      if (rel->r_addend != 0)
2843
0
        {
2844
0
          fatal = (loongarch_reloc_is_fatal
2845
0
             (info, input_bfd, input_section, rel, howto,
2846
0
        bfd_reloc_notsupported, is_undefweak, name,
2847
0
        "PLT shouldn't be with r_addend."));
2848
0
          break;
2849
0
        }
2850
0
      relocation = sec_addr (plt) + h->plt.offset - pc;
2851
0
      break;
2852
0
    }
2853
0
      }
2854
0
    break;
2855
2856
0
  case R_LARCH_SOP_PUSH_GPREL:
2857
0
    unresolved_reloc = false;
2858
2859
0
    if (rel->r_addend != 0)
2860
0
      {
2861
0
        fatal = (loongarch_reloc_is_fatal
2862
0
           (info, input_bfd, input_section, rel, howto,
2863
0
      bfd_reloc_notsupported, is_undefweak, name,
2864
0
      "Shouldn't be with r_addend."));
2865
0
        break;
2866
0
      }
2867
2868
0
    if (h != NULL)
2869
0
      {
2870
0
        off = h->got.offset & (~1);
2871
2872
0
        if (h->got.offset == MINUS_ONE && h->type != STT_GNU_IFUNC)
2873
0
    {
2874
0
      fatal = (loongarch_reloc_is_fatal
2875
0
         (info, input_bfd, input_section, rel, howto,
2876
0
          bfd_reloc_notsupported, is_undefweak, name,
2877
0
          "Internal: GOT entry doesn't represent."));
2878
0
      break;
2879
0
    }
2880
2881
        /* Hidden symbol not has .got entry, only .got.plt entry
2882
     so gprel is (plt - got).  */
2883
0
        if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
2884
0
    {
2885
0
      if (h->plt.offset == (bfd_vma) -1)
2886
0
        {
2887
0
          abort();
2888
0
        }
2889
2890
0
      bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE;
2891
0
      off = plt_index * GOT_ENTRY_SIZE;
2892
2893
0
      if (htab->elf.splt != NULL)
2894
0
        {
2895
          /* Section .plt header is 2 times of plt entry.  */
2896
0
          off = sec_addr (htab->elf.sgotplt) + off
2897
0
      - sec_addr (htab->elf.sgot);
2898
0
        }
2899
0
      else
2900
0
        {
2901
          /* Section iplt not has plt header.  */
2902
0
          off = sec_addr (htab->elf.igotplt) + off
2903
0
      - sec_addr (htab->elf.sgot);
2904
0
        }
2905
0
    }
2906
2907
0
        if ((h->got.offset & 1) == 0)
2908
0
    {
2909
0
      if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
2910
0
              bfd_link_pic (info), h)
2911
0
          && ((bfd_link_pic (info)
2912
0
         && SYMBOL_REFERENCES_LOCAL (info, h))))
2913
0
        {
2914
          /* This is actually a static link, or it is a
2915
       -Bsymbolic link and the symbol is defined
2916
       locally, or the symbol was forced to be local
2917
       because of a version file.  We must initialize
2918
       this entry in the global offset table.  Since the
2919
       offset must always be a multiple of the word size,
2920
       we use the least significant bit to record whether
2921
       we have initialized it already.
2922
2923
       When doing a dynamic link, we create a rela.got
2924
       relocation entry to initialize the value.  This
2925
       is done in the finish_dynamic_symbol routine.  */
2926
2927
0
          if (resolved_dynly)
2928
0
      {
2929
0
        fatal = (loongarch_reloc_is_fatal
2930
0
           (info, input_bfd, input_section, rel, howto,
2931
0
            bfd_reloc_dangerous, is_undefweak, name,
2932
0
            "Internal: here shouldn't dynamic."));
2933
0
      }
2934
2935
0
          if (!(defined_local || resolved_to_const))
2936
0
      {
2937
0
        fatal = (loongarch_reloc_is_fatal
2938
0
           (info, input_bfd, input_section, rel, howto,
2939
0
            bfd_reloc_undefined, is_undefweak, name,
2940
0
            "Internal: "));
2941
0
        break;
2942
0
      }
2943
2944
0
          asection *s;
2945
0
          Elf_Internal_Rela outrel;
2946
          /* We need to generate a R_LARCH_RELATIVE reloc
2947
       for the dynamic linker.  */
2948
0
          s = htab->elf.srelgot;
2949
0
          if (!s)
2950
0
      {
2951
0
        fatal = loongarch_reloc_is_fatal
2952
0
          (info, input_bfd,
2953
0
           input_section, rel, howto,
2954
0
           bfd_reloc_notsupported, is_undefweak, name,
2955
0
           "Internal: '.rel.got' not represent");
2956
0
        break;
2957
0
      }
2958
2959
0
          outrel.r_offset = sec_addr (got) + off;
2960
0
          outrel.r_info = ELF64_R_INFO (0, R_LARCH_RELATIVE);
2961
0
          outrel.r_addend = relocation; /* Link-time addr.  */
2962
0
          loongarch_elf_append_rela (output_bfd, s, &outrel);
2963
0
        }
2964
0
      bfd_put_64 (output_bfd, relocation, got->contents + off);
2965
0
      h->got.offset |= 1;
2966
0
    }
2967
0
      }
2968
0
    else
2969
0
      {
2970
0
        if (!local_got_offsets)
2971
0
    {
2972
0
      fatal = (loongarch_reloc_is_fatal
2973
0
         (info, input_bfd, input_section, rel, howto,
2974
0
          bfd_reloc_notsupported, is_undefweak, name,
2975
0
          "Internal: local got offsets not reporesent."));
2976
0
      break;
2977
0
    }
2978
2979
0
        off = local_got_offsets[r_symndx] & (~1);
2980
2981
0
        if (local_got_offsets[r_symndx] == MINUS_ONE)
2982
0
    {
2983
0
      fatal = (loongarch_reloc_is_fatal
2984
0
         (info, input_bfd, input_section, rel, howto,
2985
0
          bfd_reloc_notsupported, is_undefweak, name,
2986
0
          "Internal: GOT entry doesn't represent."));
2987
0
      break;
2988
0
    }
2989
2990
        /* The offset must always be a multiple of the word size.
2991
     So, we can use the least significant bit to record
2992
     whether we have already processed this entry.  */
2993
0
        if ((local_got_offsets[r_symndx] & 1) == 0)
2994
0
    {
2995
0
      if (is_pic)
2996
0
        {
2997
0
          asection *s;
2998
0
          Elf_Internal_Rela outrel;
2999
          /* We need to generate a R_LARCH_RELATIVE reloc
3000
       for the dynamic linker.  */
3001
0
          s = htab->elf.srelgot;
3002
0
          if (!s)
3003
0
      {
3004
0
        fatal = (loongarch_reloc_is_fatal
3005
0
           (info, input_bfd, input_section, rel, howto,
3006
0
            bfd_reloc_notsupported, is_undefweak, name,
3007
0
            "Internal: '.rel.got' not represent"));
3008
0
        break;
3009
0
      }
3010
3011
0
          outrel.r_offset = sec_addr (got) + off;
3012
0
          outrel.r_info = ELF64_R_INFO (0, R_LARCH_RELATIVE);
3013
0
          outrel.r_addend = relocation; /* Link-time addr.  */
3014
0
          loongarch_elf_append_rela (output_bfd, s, &outrel);
3015
0
        }
3016
3017
0
      bfd_put_64 (output_bfd, relocation, got->contents + off);
3018
0
      local_got_offsets[r_symndx] |= 1;
3019
0
    }
3020
0
      }
3021
0
    relocation = off;
3022
3023
0
    break;
3024
3025
0
  case R_LARCH_SOP_PUSH_TLS_GOT:
3026
0
  case R_LARCH_SOP_PUSH_TLS_GD:
3027
0
    {
3028
0
      unresolved_reloc = false;
3029
0
      if (r_type == R_LARCH_SOP_PUSH_TLS_GOT)
3030
0
        is_ie = true;
3031
3032
0
      bfd_vma got_off = 0;
3033
0
      if (h != NULL)
3034
0
        {
3035
0
    got_off = h->got.offset;
3036
0
    h->got.offset |= 1;
3037
0
        }
3038
0
      else
3039
0
        {
3040
0
    got_off = local_got_offsets[r_symndx];
3041
0
    local_got_offsets[r_symndx] |= 1;
3042
0
        }
3043
3044
0
      BFD_ASSERT (got_off != MINUS_ONE);
3045
3046
0
      ie_off = 0;
3047
0
      tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3048
0
      if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
3049
0
        ie_off = 2 * GOT_ENTRY_SIZE;
3050
3051
0
      if ((got_off & 1) == 0)
3052
0
        {
3053
0
    Elf_Internal_Rela rela;
3054
0
    asection *srel = htab->elf.srelgot;
3055
0
    bfd_vma tls_block_off = 0;
3056
3057
0
    if (SYMBOL_REFERENCES_LOCAL (info, h))
3058
0
      {
3059
0
        BFD_ASSERT (elf_hash_table (info)->tls_sec);
3060
0
        tls_block_off = relocation
3061
0
      - elf_hash_table (info)->tls_sec->vma;
3062
0
      }
3063
3064
0
    if (tls_type & GOT_TLS_GD)
3065
0
      {
3066
0
        rela.r_offset = sec_addr (got) + got_off;
3067
0
        rela.r_addend = 0;
3068
0
        if (SYMBOL_REFERENCES_LOCAL (info, h))
3069
0
          {
3070
      /* Local sym, used in exec, set module id 1.  */
3071
0
      if (bfd_link_executable (info))
3072
0
        bfd_put_64 (output_bfd, 1, got->contents + got_off);
3073
0
      else
3074
0
        {
3075
0
          rela.r_info = ELF64_R_INFO (0,
3076
0
              R_LARCH_TLS_DTPMOD64);
3077
0
          loongarch_elf_append_rela (output_bfd, srel, &rela);
3078
0
        }
3079
3080
0
      bfd_put_64 (output_bfd, tls_block_off,
3081
0
            got->contents + got_off + GOT_ENTRY_SIZE);
3082
0
          }
3083
        /* Dynamic resolved.  */
3084
0
        else
3085
0
          {
3086
      /* Dynamic relocate module id.  */
3087
0
      rela.r_info = ELF64_R_INFO (h->dynindx,
3088
0
                R_LARCH_TLS_DTPMOD64);
3089
0
      loongarch_elf_append_rela (output_bfd, srel, &rela);
3090
3091
      /* Dynamic relocate offset of block.  */
3092
0
      rela.r_offset += GOT_ENTRY_SIZE;
3093
0
      rela.r_info = ELF64_R_INFO (h->dynindx,
3094
0
                R_LARCH_TLS_DTPREL64);
3095
0
      loongarch_elf_append_rela (output_bfd, srel, &rela);
3096
0
          }
3097
0
      }
3098
0
    if (tls_type & GOT_TLS_IE)
3099
0
      {
3100
0
        rela.r_offset = sec_addr (got) + got_off + ie_off;
3101
0
        if (SYMBOL_REFERENCES_LOCAL (info, h))
3102
0
          {
3103
      /* Local sym, used in exec, set module id 1.  */
3104
0
      if (!bfd_link_executable (info))
3105
0
        {
3106
0
          rela.r_info = ELF64_R_INFO (0, R_LARCH_TLS_TPREL64);
3107
0
          rela.r_addend = tls_block_off;
3108
0
          loongarch_elf_append_rela (output_bfd, srel, &rela);
3109
0
        }
3110
3111
0
      bfd_put_64 (output_bfd, tls_block_off,
3112
0
            got->contents + got_off + ie_off);
3113
0
          }
3114
        /* Dynamic resolved.  */
3115
0
        else
3116
0
          {
3117
      /* Dynamic relocate offset of block.  */
3118
0
      rela.r_info = ELF64_R_INFO (h->dynindx,
3119
0
                R_LARCH_TLS_TPREL64);
3120
0
      rela.r_addend = 0;
3121
0
      loongarch_elf_append_rela (output_bfd, srel, &rela);
3122
0
          }
3123
0
      }
3124
0
        }
3125
3126
0
      relocation = (got_off & (~(bfd_vma)1)) + (is_ie ? ie_off : 0);
3127
0
    }
3128
0
    break;
3129
3130
  /* New reloc types.  */
3131
0
  case R_LARCH_B21:
3132
0
  case R_LARCH_B26:
3133
0
  case R_LARCH_B16:
3134
0
    unresolved_reloc = false;
3135
0
    if (is_undefweak)
3136
0
      {
3137
0
        relocation = 0;
3138
0
      }
3139
3140
0
    if (resolved_local)
3141
0
      {
3142
0
        relocation -= pc;
3143
0
        relocation += rel->r_addend;
3144
0
      }
3145
0
    else if (resolved_dynly)
3146
0
      {
3147
0
        BFD_ASSERT (h
3148
0
        && (h->plt.offset != MINUS_ONE
3149
0
            || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
3150
0
        && rel->r_addend == 0);
3151
0
        if (h && h->plt.offset == MINUS_ONE
3152
0
      && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
3153
0
    {
3154
0
      relocation -= pc;
3155
0
      relocation += rel->r_addend;
3156
0
    }
3157
0
        else
3158
0
    relocation = sec_addr (plt) + h->plt.offset - pc;
3159
0
      }
3160
3161
0
    break;
3162
3163
0
  case R_LARCH_ABS_HI20:
3164
0
  case R_LARCH_ABS_LO12:
3165
0
  case R_LARCH_ABS64_LO20:
3166
0
  case R_LARCH_ABS64_HI12:
3167
0
    BFD_ASSERT (!is_pic);
3168
3169
0
    if (is_undefweak)
3170
0
      {
3171
0
        BFD_ASSERT (resolved_dynly);
3172
0
        relocation = 0;
3173
0
        break;
3174
0
      }
3175
0
    else if (resolved_to_const || resolved_local)
3176
0
      {
3177
0
        relocation += rel->r_addend;
3178
0
      }
3179
0
    else if (resolved_dynly)
3180
0
      {
3181
0
        unresolved_reloc = false;
3182
0
        BFD_ASSERT ((plt && h && h->plt.offset != MINUS_ONE)
3183
0
        && rel->r_addend == 0);
3184
0
        relocation = sec_addr (plt) + h->plt.offset;
3185
0
      }
3186
3187
0
    break;
3188
3189
0
  case R_LARCH_PCREL20_S2:
3190
0
    unresolved_reloc = false;
3191
0
    if (h && h->plt.offset != MINUS_ONE)
3192
0
      relocation = sec_addr (plt) + h->plt.offset;
3193
0
    else
3194
0
      relocation += rel->r_addend;
3195
0
    relocation -= pc;
3196
0
    break;
3197
3198
0
  case R_LARCH_PCALA_HI20:
3199
0
    unresolved_reloc = false;
3200
0
    if (h && h->plt.offset != MINUS_ONE)
3201
0
      relocation = sec_addr (plt) + h->plt.offset;
3202
0
    else
3203
0
      relocation += rel->r_addend;
3204
3205
0
    RELOCATE_CALC_PC32_HI20 (relocation, pc);
3206
3207
0
    break;
3208
3209
0
  case R_LARCH_PCALA_LO12:
3210
    /* Not support if sym_addr in 2k page edge.
3211
       pcalau12i pc_hi20 (sym_addr)
3212
       ld.w/d pc_lo12 (sym_addr)
3213
       ld.w/d pc_lo12 (sym_addr + x)
3214
       ...
3215
       can not calc correct address
3216
       if sym_addr < 0x800 && sym_addr + x >= 0x800.  */
3217
3218
0
    if (h && h->plt.offset != MINUS_ONE)
3219
0
      relocation = sec_addr (plt) + h->plt.offset;
3220
0
    else
3221
0
      relocation += rel->r_addend;
3222
3223
    /* For 2G jump, generate pcalau12i, jirl.  */
3224
    /* If use jirl, turns to R_LARCH_B16.  */
3225
0
    uint32_t insn = bfd_get (32, input_bfd, contents + rel->r_offset);
3226
0
    if ((insn & 0x4c000000) == 0x4c000000)
3227
0
      {
3228
0
        relocation &= 0xfff;
3229
        /* Signed extend.  */
3230
0
        relocation = (relocation ^ 0x800) - 0x800;
3231
3232
0
        rel->r_info = ELF64_R_INFO (r_symndx, R_LARCH_B16);
3233
0
        howto = loongarch_elf_rtype_to_howto (input_bfd, R_LARCH_B16);
3234
0
      }
3235
0
    break;
3236
3237
0
  case R_LARCH_PCALA64_LO20:
3238
0
  case R_LARCH_PCALA64_HI12:
3239
0
    if (h && h->plt.offset != MINUS_ONE)
3240
0
      relocation = sec_addr (plt) + h->plt.offset;
3241
0
    else
3242
0
      relocation += rel->r_addend;
3243
3244
0
    RELOCATE_CALC_PC64_HI32 (relocation, pc);
3245
3246
0
    break;
3247
3248
0
  case R_LARCH_GOT_PC_HI20:
3249
0
  case R_LARCH_GOT_HI20:
3250
    /* Calc got offset.  */
3251
0
      {
3252
0
        unresolved_reloc = false;
3253
0
        BFD_ASSERT (rel->r_addend == 0);
3254
3255
0
        bfd_vma got_off = 0;
3256
0
        if (h != NULL)
3257
0
    {
3258
      /* GOT ref or ifunc.  */
3259
0
      BFD_ASSERT (h->got.offset != MINUS_ONE
3260
0
            || h->type == STT_GNU_IFUNC);
3261
3262
0
      got_off = h->got.offset  & (~(bfd_vma)1);
3263
      /* Hidden symbol not has got entry,
3264
       * only got.plt entry so it is (plt - got).  */
3265
0
      if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3266
0
        {
3267
0
          bfd_vma idx;
3268
0
          if (htab->elf.splt != NULL)
3269
0
      {
3270
0
        idx = (h->plt.offset - PLT_HEADER_SIZE)
3271
0
          / PLT_ENTRY_SIZE;
3272
0
        got_off = sec_addr (htab->elf.sgotplt)
3273
0
          + GOTPLT_HEADER_SIZE
3274
0
          + (idx * GOT_ENTRY_SIZE)
3275
0
          - sec_addr (htab->elf.sgot);
3276
0
      }
3277
0
          else
3278
0
      {
3279
0
        idx = h->plt.offset / PLT_ENTRY_SIZE;
3280
0
        got_off = sec_addr (htab->elf.sgotplt)
3281
0
          + (idx * GOT_ENTRY_SIZE)
3282
0
          - sec_addr (htab->elf.sgot);
3283
0
      }
3284
0
        }
3285
3286
0
      if ((h->got.offset & 1) == 0)
3287
0
        {
3288
          /* We need to generate a R_LARCH_RELATIVE reloc once
3289
           * in loongarch_elf_finish_dynamic_symbol or now,
3290
           * call finish_dyn && nopic
3291
           * or !call finish_dyn && pic.  */
3292
0
          if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
3293
0
                  bfd_link_pic (info),
3294
0
                  h)
3295
0
        && bfd_link_pic (info)
3296
0
        && SYMBOL_REFERENCES_LOCAL (info, h))
3297
0
      {
3298
0
        Elf_Internal_Rela rela;
3299
0
        rela.r_offset = sec_addr (got) + got_off;
3300
0
        rela.r_info = ELF64_R_INFO (0, R_LARCH_RELATIVE);
3301
0
        rela.r_addend = relocation;
3302
0
        loongarch_elf_append_rela (output_bfd,
3303
0
                 htab->elf.srelgot, &rela);
3304
0
      }
3305
0
          h->got.offset |= 1;
3306
0
          bfd_put_64 (output_bfd, relocation,
3307
0
          got->contents + got_off);
3308
0
        }
3309
0
    }
3310
0
        else
3311
0
    {
3312
0
      BFD_ASSERT (local_got_offsets
3313
0
            && local_got_offsets[r_symndx] != MINUS_ONE);
3314
3315
0
      got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
3316
0
      if ((local_got_offsets[r_symndx] & 1) == 0)
3317
0
        {
3318
0
          if (bfd_link_pic (info))
3319
0
      {
3320
0
        Elf_Internal_Rela rela;
3321
0
        rela.r_offset = sec_addr (got) + got_off;
3322
0
        rela.r_info = ELF64_R_INFO (0, R_LARCH_RELATIVE);
3323
0
        rela.r_addend = relocation;
3324
0
        loongarch_elf_append_rela (output_bfd,
3325
0
                 htab->elf.srelgot, &rela);
3326
0
      }
3327
0
          local_got_offsets[r_symndx] |= 1;
3328
0
        }
3329
0
      bfd_put_64 (output_bfd, relocation, got->contents + got_off);
3330
0
    }
3331
3332
0
        relocation = got_off + sec_addr (got);
3333
0
      }
3334
3335
0
    if (r_type == R_LARCH_GOT_PC_HI20)
3336
0
      RELOCATE_CALC_PC32_HI20 (relocation, pc);
3337
3338
0
    break;
3339
3340
0
  case R_LARCH_GOT_PC_LO12:
3341
0
  case R_LARCH_GOT64_PC_LO20:
3342
0
  case R_LARCH_GOT64_PC_HI12:
3343
0
  case R_LARCH_GOT_LO12:
3344
0
  case R_LARCH_GOT64_LO20:
3345
0
  case R_LARCH_GOT64_HI12:
3346
0
      {
3347
0
        unresolved_reloc = false;
3348
0
        bfd_vma got_off;
3349
0
        if (h)
3350
0
    got_off = h->got.offset & (~(bfd_vma)1);
3351
0
        else
3352
0
    got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
3353
3354
0
        if (h && h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3355
0
    {
3356
0
      bfd_vma idx;
3357
0
      if (htab->elf.splt != NULL)
3358
0
        idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
3359
0
      else
3360
0
        idx = h->plt.offset / PLT_ENTRY_SIZE;
3361
3362
0
      got_off = sec_addr (htab->elf.sgotplt)
3363
0
        + GOTPLT_HEADER_SIZE
3364
0
        + (idx * GOT_ENTRY_SIZE)
3365
0
        - sec_addr (htab->elf.sgot);
3366
0
    }
3367
3368
0
        relocation = got_off + sec_addr (got);
3369
0
      }
3370
3371
0
    if (r_type == R_LARCH_GOT64_PC_HI12
3372
0
        || r_type == R_LARCH_GOT64_PC_LO20)
3373
0
      RELOCATE_CALC_PC64_HI32 (relocation, pc);
3374
3375
0
    break;
3376
3377
0
  case R_LARCH_TLS_LE_HI20:
3378
0
  case R_LARCH_TLS_LE_LO12:
3379
0
  case R_LARCH_TLS_LE64_LO20:
3380
0
  case R_LARCH_TLS_LE64_HI12:
3381
0
    BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec);
3382
3383
0
    relocation -= elf_hash_table (info)->tls_sec->vma;
3384
0
    break;
3385
3386
  /* TLS IE LD/GD process separately is troublesome.
3387
     When a symbol is both ie and LD/GD, h->got.off |= 1
3388
     make only one type be relocated.  We must use
3389
     h->got.offset |= 1 and h->got.offset |= 2
3390
     diff IE and LD/GD.  And all (got_off & (~(bfd_vma)1))
3391
     (IE LD/GD and reusable GOT reloc) must change to
3392
     (got_off & (~(bfd_vma)3)), beause we use lowest 2 bits
3393
     as a tag.
3394
     Now, LD and GD is both GOT_TLS_GD type, LD seems to
3395
     can be omitted.  */
3396
0
  case R_LARCH_TLS_IE_PC_HI20:
3397
0
  case R_LARCH_TLS_IE_HI20:
3398
0
  case R_LARCH_TLS_LD_PC_HI20:
3399
0
  case R_LARCH_TLS_LD_HI20:
3400
0
  case R_LARCH_TLS_GD_PC_HI20:
3401
0
  case R_LARCH_TLS_GD_HI20:
3402
0
    BFD_ASSERT (rel->r_addend == 0);
3403
0
    unresolved_reloc = false;
3404
3405
0
    if (r_type == R_LARCH_TLS_IE_PC_HI20
3406
0
        || r_type == R_LARCH_TLS_IE_HI20)
3407
0
      is_ie = true;
3408
3409
0
    bfd_vma got_off = 0;
3410
0
    if (h != NULL)
3411
0
      {
3412
0
        got_off = h->got.offset;
3413
0
        h->got.offset |= 1;
3414
0
      }
3415
0
    else
3416
0
      {
3417
0
        got_off = local_got_offsets[r_symndx];
3418
0
        local_got_offsets[r_symndx] |= 1;
3419
0
      }
3420
3421
0
    BFD_ASSERT (got_off != MINUS_ONE);
3422
3423
0
    ie_off = 0;
3424
0
    tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3425
0
    if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
3426
0
      ie_off = 2 * GOT_ENTRY_SIZE;
3427
3428
0
    if ((got_off & 1) == 0)
3429
0
      {
3430
0
        Elf_Internal_Rela rela;
3431
0
        asection *relgot = htab->elf.srelgot;
3432
0
        bfd_vma tls_block_off = 0;
3433
3434
0
        if (SYMBOL_REFERENCES_LOCAL (info, h))
3435
0
    {
3436
0
      BFD_ASSERT (elf_hash_table (info)->tls_sec);
3437
0
      tls_block_off = relocation
3438
0
          - elf_hash_table (info)->tls_sec->vma;
3439
0
    }
3440
3441
0
        if (tls_type & GOT_TLS_GD)
3442
0
    {
3443
0
      rela.r_offset = sec_addr (got) + got_off;
3444
0
      rela.r_addend = 0;
3445
0
      if (SYMBOL_REFERENCES_LOCAL (info, h))
3446
0
        {
3447
          /* Local sym, used in exec, set module id 1.  */
3448
0
          if (bfd_link_executable (info))
3449
0
      bfd_put_64 (output_bfd, 1, got->contents + got_off);
3450
0
          else
3451
0
      {
3452
0
        rela.r_info = ELF64_R_INFO (0, R_LARCH_TLS_DTPMOD64);
3453
0
        loongarch_elf_append_rela (output_bfd, relgot, &rela);
3454
0
      }
3455
3456
0
          bfd_put_64 (output_bfd, tls_block_off,
3457
0
          got->contents + got_off + GOT_ENTRY_SIZE);
3458
0
        }
3459
      /* Dynamic resolved.  */
3460
0
      else
3461
0
        {
3462
          /* Dynamic relocate module id.  */
3463
0
          rela.r_info = ELF64_R_INFO (h->dynindx,
3464
0
              R_LARCH_TLS_DTPMOD64);
3465
0
          loongarch_elf_append_rela (output_bfd, relgot, &rela);
3466
3467
          /* Dynamic relocate offset of block.  */
3468
0
          rela.r_offset += GOT_ENTRY_SIZE;
3469
0
          rela.r_info = ELF64_R_INFO (h->dynindx,
3470
0
              R_LARCH_TLS_DTPREL64);
3471
0
          loongarch_elf_append_rela (output_bfd, relgot, &rela);
3472
0
        }
3473
0
    }
3474
0
        if (tls_type & GOT_TLS_IE)
3475
0
    {
3476
0
      rela.r_offset = sec_addr (got) + got_off + ie_off;
3477
0
      if (SYMBOL_REFERENCES_LOCAL (info, h))
3478
0
        {
3479
          /* Local sym, used in exec, set module id 1.  */
3480
0
          if (!bfd_link_executable (info))
3481
0
      {
3482
0
        rela.r_info = ELF64_R_INFO (0, R_LARCH_TLS_TPREL64);
3483
0
        rela.r_addend = tls_block_off;
3484
0
        loongarch_elf_append_rela (output_bfd, relgot, &rela);
3485
0
      }
3486
3487
0
          bfd_put_64 (output_bfd, tls_block_off,
3488
0
          got->contents + got_off + ie_off);
3489
0
        }
3490
      /* Dynamic resolved.  */
3491
0
      else
3492
0
        {
3493
          /* Dynamic relocate offset of block.  */
3494
0
          rela.r_info = ELF64_R_INFO (h->dynindx,
3495
0
              R_LARCH_TLS_TPREL64);
3496
0
          rela.r_addend = 0;
3497
0
          loongarch_elf_append_rela (output_bfd, relgot, &rela);
3498
0
        }
3499
0
    }
3500
0
      }
3501
0
    relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got)
3502
0
      + (is_ie ? ie_off : 0);
3503
3504
0
    if (r_type == R_LARCH_TLS_LD_PC_HI20
3505
0
        || r_type == R_LARCH_TLS_GD_PC_HI20
3506
0
        || r_type == R_LARCH_TLS_IE_PC_HI20)
3507
0
      RELOCATE_CALC_PC32_HI20 (relocation, pc);
3508
3509
0
    break;
3510
3511
0
  case R_LARCH_TLS_IE_PC_LO12:
3512
0
  case R_LARCH_TLS_IE64_PC_LO20:
3513
0
  case R_LARCH_TLS_IE64_PC_HI12:
3514
0
  case R_LARCH_TLS_IE_LO12:
3515
0
  case R_LARCH_TLS_IE64_LO20:
3516
0
  case R_LARCH_TLS_IE64_HI12:
3517
0
    unresolved_reloc = false;
3518
3519
0
    if (h)
3520
0
      relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)3));
3521
0
    else
3522
0
      relocation = sec_addr (got)
3523
0
        + (local_got_offsets[r_symndx] & (~(bfd_vma)3));
3524
3525
0
    tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3526
    /* Use both TLS_GD and TLS_IE.  */
3527
0
    if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
3528
0
      relocation += 2 * GOT_ENTRY_SIZE;
3529
3530
0
    if (r_type == R_LARCH_TLS_IE64_PC_LO20
3531
0
        || r_type == R_LARCH_TLS_IE64_PC_HI12)
3532
0
      RELOCATE_CALC_PC64_HI32 (relocation, pc);
3533
3534
0
    break;
3535
3536
0
  case R_LARCH_RELAX:
3537
0
  case R_LARCH_ALIGN:
3538
0
    r = bfd_reloc_continue;
3539
0
    unresolved_reloc = false;
3540
0
    break;
3541
3542
0
  default:
3543
0
    break;
3544
0
  }
3545
3546
0
      if (fatal)
3547
0
  break;
3548
3549
0
      do
3550
0
  {
3551
    /* 'unresolved_reloc' means we haven't done it yet.
3552
       We need help of dynamic linker to fix this memory location up.  */
3553
0
    if (!unresolved_reloc)
3554
0
      break;
3555
3556
0
    if (_bfd_elf_section_offset (output_bfd, info, input_section,
3557
0
               rel->r_offset) == MINUS_ONE)
3558
      /* WHY? May because it's invalid so skip checking.
3559
         But why dynamic reloc a invalid section?  */
3560
0
      break;
3561
3562
0
    if (input_section->output_section->flags & SEC_DEBUGGING)
3563
0
      {
3564
0
        fatal = (loongarch_reloc_is_fatal
3565
0
           (info, input_bfd, input_section, rel, howto,
3566
0
      bfd_reloc_dangerous, is_undefweak, name,
3567
0
      "Seems dynamic linker not process "
3568
0
      "sections 'SEC_DEBUGGING'."));
3569
0
      }
3570
0
    if (!is_dyn)
3571
0
      break;
3572
3573
0
    if ((info->flags & DF_TEXTREL) == 0)
3574
0
      if (input_section->output_section->flags & SEC_READONLY)
3575
0
        info->flags |= DF_TEXTREL;
3576
0
  }
3577
0
      while (0);
3578
3579
0
      if (fatal)
3580
0
  break;
3581
3582
0
      loongarch_record_one_reloc (input_bfd, input_section, r_type,
3583
0
          rel->r_offset, sym, h, rel->r_addend);
3584
3585
0
      if (r != bfd_reloc_continue)
3586
0
  r = perform_relocation (rel, input_section, howto, relocation,
3587
0
        input_bfd, contents);
3588
3589
0
      switch (r)
3590
0
  {
3591
0
  case bfd_reloc_dangerous:
3592
0
  case bfd_reloc_continue:
3593
0
  case bfd_reloc_ok:
3594
0
    continue;
3595
3596
0
  case bfd_reloc_overflow:
3597
    /* Overflow value can't be filled in.  */
3598
0
    loongarch_dump_reloc_record (info->callbacks->info);
3599
0
    info->callbacks->reloc_overflow
3600
0
      (info, h ? &h->root : NULL, name, howto->name, rel->r_addend,
3601
0
       input_bfd, input_section, rel->r_offset);
3602
0
    break;
3603
3604
0
  case bfd_reloc_outofrange:
3605
    /* Stack state incorrect.  */
3606
0
    loongarch_dump_reloc_record (info->callbacks->info);
3607
0
    info->callbacks->info
3608
0
      ("%X%H: Internal stack state is incorrect.\n"
3609
0
       "Want to push to full stack or pop from empty stack?\n",
3610
0
       input_bfd, input_section, rel->r_offset);
3611
0
    break;
3612
3613
0
  case bfd_reloc_notsupported:
3614
0
    info->callbacks->info ("%X%H: Unknown relocation type.\n", input_bfd,
3615
0
         input_section, rel->r_offset);
3616
0
    break;
3617
3618
0
  default:
3619
0
    info->callbacks->info ("%X%H: Internal: unknown error.\n", input_bfd,
3620
0
         input_section, rel->r_offset);
3621
0
    break;
3622
0
  }
3623
3624
0
      fatal = true;
3625
0
    }
3626
3627
0
  return !fatal;
3628
0
}
3629
3630
static bool
3631
loongarch_relax_delete_bytes (bfd *abfd,
3632
        asection *sec,
3633
        bfd_vma addr,
3634
        size_t count,
3635
        struct bfd_link_info *link_info)
3636
0
{
3637
0
  unsigned int i, symcount;
3638
0
  bfd_vma toaddr = sec->size;
3639
0
  struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd);
3640
0
  Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
3641
0
  unsigned int sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
3642
0
  struct bfd_elf_section_data *data = elf_section_data (sec);
3643
0
  bfd_byte *contents = data->this_hdr.contents;
3644
3645
  /* Actually delete the bytes.  */
3646
0
  sec->size -= count;
3647
0
  memmove (contents + addr, contents + addr + count, toaddr - addr - count);
3648
3649
  /* Adjust the location of all of the relocs.  Note that we need not
3650
     adjust the addends, since all PC-relative references must be against
3651
     symbols, which we will adjust below.  */
3652
0
  for (i = 0; i < sec->reloc_count; i++)
3653
0
    if (data->relocs[i].r_offset > addr && data->relocs[i].r_offset < toaddr)
3654
0
      data->relocs[i].r_offset -= count;
3655
3656
  /* Adjust the local symbols defined in this section.  */
3657
0
  for (i = 0; i < symtab_hdr->sh_info; i++)
3658
0
    {
3659
0
      Elf_Internal_Sym *sym = (Elf_Internal_Sym *) symtab_hdr->contents + i;
3660
0
      if (sym->st_shndx == sec_shndx)
3661
0
  {
3662
    /* If the symbol is in the range of memory we just moved, we
3663
       have to adjust its value.  */
3664
0
    if (sym->st_value > addr && sym->st_value <= toaddr)
3665
0
      sym->st_value -= count;
3666
3667
    /* If the symbol *spans* the bytes we just deleted (i.e. its
3668
       *end* is in the moved bytes but its *start* isn't), then we
3669
       must adjust its size.
3670
3671
       This test needs to use the original value of st_value, otherwise
3672
       we might accidentally decrease size when deleting bytes right
3673
       before the symbol.  But since deleted relocs can't span across
3674
       symbols, we can't have both a st_value and a st_size decrease,
3675
       so it is simpler to just use an else.  */
3676
0
    else if (sym->st_value <= addr
3677
0
       && sym->st_value + sym->st_size > addr
3678
0
       && sym->st_value + sym->st_size <= toaddr)
3679
0
      sym->st_size -= count;
3680
0
  }
3681
0
    }
3682
3683
  /* Now adjust the global symbols defined in this section.  */
3684
0
  symcount = ((symtab_hdr->sh_size / sizeof (Elf64_External_Sym))
3685
0
        - symtab_hdr->sh_info);
3686
3687
0
  for (i = 0; i < symcount; i++)
3688
0
    {
3689
0
      struct elf_link_hash_entry *sym_hash = sym_hashes[i];
3690
3691
      /* The '--wrap SYMBOL' option is causing a pain when the object file,
3692
   containing the definition of __wrap_SYMBOL, includes a direct
3693
   call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
3694
   the same symbol (which is __wrap_SYMBOL), but still exist as two
3695
   different symbols in 'sym_hashes', we don't want to adjust
3696
   the global symbol __wrap_SYMBOL twice.
3697
3698
   The same problem occurs with symbols that are versioned_hidden, as
3699
   foo becomes an alias for foo@BAR, and hence they need the same
3700
   treatment.  */
3701
0
      if (link_info->wrap_hash != NULL
3702
0
    || sym_hash->versioned != unversioned)
3703
0
  {
3704
0
    struct elf_link_hash_entry **cur_sym_hashes;
3705
3706
    /* Loop only over the symbols which have already been checked.  */
3707
0
    for (cur_sym_hashes = sym_hashes; cur_sym_hashes < &sym_hashes[i];
3708
0
         cur_sym_hashes++)
3709
0
      {
3710
        /* If the current symbol is identical to 'sym_hash', that means
3711
     the symbol was already adjusted (or at least checked).  */
3712
0
        if (*cur_sym_hashes == sym_hash)
3713
0
    break;
3714
0
      }
3715
    /* Don't adjust the symbol again.  */
3716
0
    if (cur_sym_hashes < &sym_hashes[i])
3717
0
      continue;
3718
0
  }
3719
3720
0
      if ((sym_hash->root.type == bfd_link_hash_defined
3721
0
     || sym_hash->root.type == bfd_link_hash_defweak)
3722
0
    && sym_hash->root.u.def.section == sec)
3723
0
  {
3724
    /* As above, adjust the value if needed.  */
3725
0
    if (sym_hash->root.u.def.value > addr
3726
0
        && sym_hash->root.u.def.value <= toaddr)
3727
0
      sym_hash->root.u.def.value -= count;
3728
3729
    /* As above, adjust the size if needed.  */
3730
0
    else if (sym_hash->root.u.def.value <= addr
3731
0
       && sym_hash->root.u.def.value + sym_hash->size > addr
3732
0
       && sym_hash->root.u.def.value + sym_hash->size <= toaddr)
3733
0
      sym_hash->size -= count;
3734
0
  }
3735
0
    }
3736
3737
0
  return true;
3738
0
}
3739
3740
/* Relax pcalau12i,addi.d => pcaddi.  */
3741
static bool
3742
loongarch_relax_pcala_addi (bfd *abfd, asection *sec,
3743
           Elf_Internal_Rela *rel_hi, bfd_vma symval)
3744
0
{
3745
0
  bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
3746
0
  Elf_Internal_Rela *rel_lo = rel_hi + 2;
3747
0
  uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
3748
0
  uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset);
3749
0
  uint32_t rd = pca & 0x1f;
3750
0
  bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
3751
0
  const uint32_t addi_d = 0x02c00000;
3752
0
  const uint32_t pcaddi = 0x18000000;
3753
3754
  /* Is pcalau12i + addi.d insns?  */
3755
0
  if ((ELF64_R_TYPE (rel_lo->r_info) != R_LARCH_PCALA_LO12)
3756
0
      || (ELF64_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
3757
0
      || (ELF64_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
3758
0
      || (rel_hi->r_offset + 4 != rel_lo->r_offset)
3759
0
      || ((add & addi_d) != addi_d)
3760
      /* Is pcalau12i $rd + addi.d $rd,$rd?  */
3761
0
      || ((add & 0x1f) != rd)
3762
0
      || (((add >> 5) & 0x1f) != rd)
3763
      /* Can be relaxed to pcaddi?  */
3764
0
      || (symval & 0x3) /* 4 bytes align.  */
3765
0
      || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000)
3766
0
      || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc))
3767
0
    return false;
3768
3769
0
  pca = pcaddi | rd;
3770
0
  bfd_put (32, abfd, pca, contents + rel_hi->r_offset);
3771
3772
  /* Adjust relocations.  */
3773
0
  rel_hi->r_info = ELF64_R_INFO (ELF64_R_SYM (rel_hi->r_info),
3774
0
         R_LARCH_PCREL20_S2);
3775
0
  rel_lo->r_info = ELF64_R_INFO (ELF64_R_SYM (rel_hi->r_info),
3776
0
         R_LARCH_DELETE);
3777
3778
0
  return true;
3779
0
}
3780
3781
/* Relax pcalau12i,ld.d => pcalau12i,addi.d.  */
3782
static bool
3783
loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
3784
    Elf_Internal_Rela *rel_hi)
3785
0
{
3786
0
  bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
3787
0
  Elf_Internal_Rela *rel_lo = rel_hi + 2;
3788
0
  uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
3789
0
  uint32_t ld = bfd_get (32, abfd, contents + rel_lo->r_offset);
3790
0
  uint32_t rd = pca & 0x1f;
3791
0
  const uint32_t ld_d = 0x28c00000;
3792
0
  uint32_t addi_d = 0x02c00000;
3793
3794
0
  if ((ELF64_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12)
3795
0
      || (ELF64_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
3796
0
      || (ELF64_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
3797
0
      || (rel_hi->r_offset + 4 != rel_lo->r_offset)
3798
0
      || ((ld & 0x1f) != rd)
3799
0
      || (((ld >> 5) & 0x1f) != rd)
3800
0
      || ((ld & ld_d) != ld_d))
3801
0
    return false;
3802
3803
0
  addi_d = addi_d | (rd << 5) | rd;
3804
0
  bfd_put (32, abfd, addi_d, contents + rel_lo->r_offset);
3805
3806
0
  rel_hi->r_info = ELF64_R_INFO (ELF64_R_SYM (rel_hi->r_info),
3807
0
         R_LARCH_PCALA_HI20);
3808
0
  rel_lo->r_info = ELF64_R_INFO (ELF64_R_SYM (rel_lo->r_info),
3809
0
         R_LARCH_PCALA_LO12);
3810
0
  return true;
3811
0
}
3812
3813
/* Called by after_allocation to set the information of data segment
3814
   before relaxing.  */
3815
3816
void
3817
bfd_elf64_loongarch_set_data_segment_info (struct bfd_link_info *info,
3818
             int *data_segment_phase)
3819
0
{
3820
0
  struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
3821
0
  htab->data_segment_phase = data_segment_phase;
3822
0
}
3823
3824
/* Implement R_LARCH_ALIGN by deleting excess alignment NOPs.
3825
   Once we've handled an R_LARCH_ALIGN, we can't relax anything else.  */
3826
static bool
3827
loongarch_relax_align (bfd *abfd, asection *sec,
3828
      asection *sym_sec,
3829
      struct bfd_link_info *link_info,
3830
      Elf_Internal_Rela *rel,
3831
      bfd_vma symval)
3832
0
{
3833
0
  bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
3834
0
  bfd_vma alignment = 1, pos;
3835
0
  while (alignment <= rel->r_addend)
3836
0
    alignment *= 2;
3837
3838
0
  symval -= rel->r_addend;
3839
0
  bfd_vma aligned_addr = ((symval - 1) & ~(alignment - 1)) + alignment;
3840
0
  bfd_vma nop_bytes = aligned_addr - symval;
3841
3842
  /* Once we've handled an R_LARCH_ALIGN, we can't relax anything else.  */
3843
0
  sec->sec_flg0 = true;
3844
3845
  /* Make sure there are enough NOPs to actually achieve the alignment.  */
3846
0
  if (rel->r_addend < nop_bytes)
3847
0
    {
3848
0
      _bfd_error_handler
3849
0
  (_("%pB(%pA+%#" PRIx64 "): %" PRId64 " bytes required for alignment "
3850
0
     "to %" PRId64 "-byte boundary, but only %" PRId64 " present"),
3851
0
   abfd, sym_sec, (uint64_t) rel->r_offset,
3852
0
   (int64_t) nop_bytes, (int64_t) alignment, (int64_t) rel->r_addend);
3853
0
      bfd_set_error (bfd_error_bad_value);
3854
0
      return false;
3855
0
    }
3856
3857
  /* Delete the reloc.  */
3858
0
  rel->r_info = ELF64_R_INFO (0, R_LARCH_NONE);
3859
3860
  /* If the number of NOPs is already correct, there's nothing to do.  */
3861
0
  if (nop_bytes == rel->r_addend)
3862
0
    return true;
3863
3864
  /* Write as many LOONGARCH NOPs as we need.  */
3865
0
  for (pos = 0; pos < (nop_bytes & -4); pos += 4)
3866
0
    bfd_putl32 (LARCH_NOP, contents + rel->r_offset + pos);
3867
3868
  /* Delete the excess NOPs.  */
3869
0
  return loongarch_relax_delete_bytes (abfd, sec, rel->r_offset + nop_bytes,
3870
0
           rel->r_addend - nop_bytes, link_info);
3871
0
}
3872
3873
static bool
3874
loongarch_elf_relax_section (bfd *abfd, asection *sec,
3875
             struct bfd_link_info *info,
3876
             bool *again)
3877
0
{
3878
0
  struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
3879
0
  Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd);
3880
0
  struct bfd_elf_section_data *data = elf_section_data (sec);
3881
0
  Elf_Internal_Rela *relocs;
3882
0
  *again = false;
3883
3884
0
  if (bfd_link_relocatable (info)
3885
0
      || sec->sec_flg0
3886
0
      || (sec->flags & SEC_RELOC) == 0
3887
0
      || sec->reloc_count == 0
3888
0
      || elf_seg_map (info->output_bfd) == NULL
3889
0
      || (info->disable_target_specific_optimizations
3890
0
    && info->relax_pass == 0)
3891
      /* The exp_seg_relro_adjust is enum phase_enum (0x4),
3892
   and defined in ld/ldexp.h.  */
3893
0
      || *(htab->data_segment_phase) == 4)
3894
0
    return true;
3895
3896
0
  if (data->relocs)
3897
0
    relocs = data->relocs;
3898
0
  else if (!(relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
3899
0
             info->keep_memory)))
3900
0
    return true;
3901
3902
0
  if (!data->this_hdr.contents
3903
0
      && !bfd_malloc_and_get_section (abfd, sec, &data->this_hdr.contents))
3904
0
    return true;
3905
3906
0
  if (symtab_hdr->sh_info != 0
3907
0
      && !symtab_hdr->contents
3908
0
      && !(symtab_hdr->contents =
3909
0
     (unsigned char *) bfd_elf_get_elf_syms (abfd, symtab_hdr,
3910
0
               symtab_hdr->sh_info,
3911
0
               0, NULL, NULL, NULL)))
3912
0
    return true;
3913
3914
0
      data->relocs = relocs;
3915
3916
0
  for (unsigned int i = 0; i < sec->reloc_count; i++)
3917
0
    {
3918
0
      Elf_Internal_Rela *rel = relocs + i;
3919
0
      asection *sym_sec;
3920
0
      bfd_vma symval;
3921
0
      unsigned long r_symndx = ELF64_R_SYM (rel->r_info);
3922
0
      bool local_got = false;
3923
0
      char symtype;
3924
0
      struct elf_link_hash_entry *h = NULL;
3925
3926
0
      if (r_symndx < symtab_hdr->sh_info)
3927
0
  {
3928
0
    Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents
3929
0
            + r_symndx;
3930
0
    if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
3931
0
      continue;
3932
3933
0
    if (sym->st_shndx == SHN_UNDEF)
3934
0
      {
3935
0
        sym_sec = sec;
3936
0
        symval = rel->r_offset;
3937
0
      }
3938
0
    else
3939
0
      {
3940
0
        sym_sec = elf_elfsections (abfd)[sym->st_shndx]->bfd_section;
3941
0
        symval = sym->st_value;
3942
0
      }
3943
0
    symtype = ELF_ST_TYPE (sym->st_info);
3944
0
  }
3945
0
      else
3946
0
  {
3947
0
    r_symndx = ELF64_R_SYM (rel->r_info) - symtab_hdr->sh_info;
3948
0
    h = elf_sym_hashes (abfd)[r_symndx];
3949
3950
0
    while (h->root.type == bfd_link_hash_indirect
3951
0
     || h->root.type == bfd_link_hash_warning)
3952
0
      h = (struct elf_link_hash_entry *) h->root.u.i.link;
3953
3954
    /* Disable the relaxation for ifunc.  */
3955
0
    if (h != NULL && h->type == STT_GNU_IFUNC)
3956
0
      continue;
3957
3958
0
    if ((h->root.type == bfd_link_hash_defined
3959
0
        || h->root.type == bfd_link_hash_defweak)
3960
0
       && h->root.u.def.section != NULL
3961
0
       && h->root.u.def.section->output_section != NULL)
3962
0
      {
3963
0
        symval = h->root.u.def.value;
3964
0
        sym_sec = h->root.u.def.section;
3965
0
      }
3966
0
    else
3967
0
      continue;
3968
3969
0
    if (h && bfd_link_executable (info)
3970
0
        && SYMBOL_REFERENCES_LOCAL (info, h))
3971
0
      local_got = true;
3972
0
    symtype = h->type;
3973
0
  }
3974
3975
0
      if (sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE
3976
0
     && (sym_sec->flags & SEC_MERGE))
3977
0
  {
3978
0
     if (symtype == STT_SECTION)
3979
0
       symval += rel->r_addend;
3980
3981
0
     symval = _bfd_merged_section_offset (abfd, &sym_sec,
3982
0
        elf_section_data (sym_sec)->sec_info,
3983
0
        symval);
3984
3985
0
     if (symtype != STT_SECTION)
3986
0
       symval += rel->r_addend;
3987
0
  }
3988
0
      else
3989
0
  symval += rel->r_addend;
3990
3991
0
      symval += sec_addr (sym_sec);
3992
3993
0
      switch (ELF64_R_TYPE (rel->r_info))
3994
0
  {
3995
0
  case R_LARCH_ALIGN:
3996
0
    if (2 == info->relax_pass)
3997
0
      loongarch_relax_align (abfd, sec, sym_sec, info, rel, symval);
3998
0
    break;
3999
0
  case R_LARCH_DELETE:
4000
0
    if (info->relax_pass == 1)
4001
0
      {
4002
0
        loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, info);
4003
0
        rel->r_info = ELF64_R_INFO (0, R_LARCH_NONE);
4004
0
      }
4005
0
    break;
4006
0
  case R_LARCH_PCALA_HI20:
4007
0
    if (info->relax_pass == 0)
4008
0
      {
4009
0
        if (i + 4 > sec->reloc_count)
4010
0
    break;
4011
0
        loongarch_relax_pcala_addi (abfd, sec, rel, symval);
4012
0
      }
4013
0
    break;
4014
0
  case R_LARCH_GOT_PC_HI20:
4015
0
    if (local_got)
4016
0
      {
4017
0
        if (i + 4 > sec->reloc_count)
4018
0
    break;
4019
0
        if (loongarch_relax_pcala_ld (abfd, sec, rel))
4020
0
    {
4021
0
      loongarch_relax_pcala_addi (abfd, sec, rel, symval);
4022
0
    }
4023
0
      }
4024
0
    break;
4025
0
  default:
4026
0
    break;
4027
0
  }
4028
0
    }
4029
4030
0
  return true;
4031
0
}
4032
4033
/* Finish up dynamic symbol handling.  We set the contents of various
4034
   dynamic sections here.  */
4035
4036
static bool
4037
loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
4038
             struct bfd_link_info *info,
4039
             struct elf_link_hash_entry *h,
4040
             Elf_Internal_Sym *sym)
4041
0
{
4042
0
  struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4043
0
  const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
4044
4045
0
  if (h->plt.offset != MINUS_ONE)
4046
0
    {
4047
0
      size_t i, plt_idx;
4048
0
      asection *plt, *gotplt, *relplt;
4049
0
      bfd_vma got_address;
4050
0
      uint32_t plt_entry[PLT_ENTRY_INSNS];
4051
0
      bfd_byte *loc;
4052
0
      Elf_Internal_Rela rela;
4053
4054
0
      if (htab->elf.splt)
4055
0
  {
4056
0
    BFD_ASSERT ((h->type == STT_GNU_IFUNC
4057
0
           && SYMBOL_REFERENCES_LOCAL (info, h))
4058
0
          || h->dynindx != -1);
4059
4060
0
    plt = htab->elf.splt;
4061
0
    gotplt = htab->elf.sgotplt;
4062
0
    if (h->type == STT_GNU_IFUNC && SYMBOL_REFERENCES_LOCAL (info, h))
4063
0
      relplt = htab->elf.srelgot;
4064
0
    else
4065
0
      relplt = htab->elf.srelplt;
4066
0
    plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
4067
0
    got_address =
4068
0
      sec_addr (gotplt) + GOTPLT_HEADER_SIZE + plt_idx * GOT_ENTRY_SIZE;
4069
0
  }
4070
0
      else /* if (htab->elf.iplt) */
4071
0
  {
4072
0
    BFD_ASSERT (h->type == STT_GNU_IFUNC
4073
0
          && SYMBOL_REFERENCES_LOCAL (info, h));
4074
4075
0
    plt = htab->elf.iplt;
4076
0
    gotplt = htab->elf.igotplt;
4077
0
    relplt = htab->elf.irelplt;
4078
0
    plt_idx = h->plt.offset / PLT_ENTRY_SIZE;
4079
0
    got_address = sec_addr (gotplt) + plt_idx * GOT_ENTRY_SIZE;
4080
0
  }
4081
4082
      /* Find out where the .plt entry should go.  */
4083
0
      loc = plt->contents + h->plt.offset;
4084
4085
      /* Fill in the PLT entry itself.  */
4086
0
      if (!loongarch_make_plt_entry (got_address,
4087
0
             sec_addr (plt) + h->plt.offset,
4088
0
             plt_entry))
4089
0
  return false;
4090
4091
0
      for (i = 0; i < PLT_ENTRY_INSNS; i++)
4092
0
  bfd_put_32 (output_bfd, plt_entry[i], loc + 4 * i);
4093
4094
      /* Fill in the initial value of the got.plt entry.  */
4095
0
      loc = gotplt->contents + (got_address - sec_addr (gotplt));
4096
0
      bfd_put_64 (output_bfd, sec_addr (plt), loc);
4097
4098
0
      rela.r_offset = got_address;
4099
4100
      /* TRUE if this is a PLT reference to a local IFUNC.  */
4101
0
      if (PLT_LOCAL_IFUNC_P (info, h)
4102
0
    && (relplt == htab->elf.srelgot
4103
0
        || relplt == htab->elf.irelplt))
4104
0
  {
4105
0
    rela.r_info = ELF64_R_INFO (0, R_LARCH_IRELATIVE);
4106
0
    rela.r_addend = (h->root.u.def.value
4107
0
             + h->root.u.def.section->output_section->vma
4108
0
             + h->root.u.def.section->output_offset);
4109
4110
0
    loongarch_elf_append_rela (output_bfd, relplt, &rela);
4111
0
  }
4112
0
      else
4113
0
  {
4114
    /* Fill in the entry in the rela.plt section.  */
4115
0
    rela.r_info = ELF64_R_INFO (h->dynindx, R_LARCH_JUMP_SLOT);
4116
0
    rela.r_addend = 0;
4117
0
    loc = relplt->contents + plt_idx * sizeof (Elf64_External_Rela);
4118
0
    bed->s->swap_reloca_out (output_bfd, &rela, loc);
4119
0
  }
4120
4121
0
      if (!h->def_regular)
4122
0
  {
4123
    /* Mark the symbol as undefined, rather than as defined in
4124
       the .plt section.  Leave the value alone.  */
4125
0
    sym->st_shndx = SHN_UNDEF;
4126
    /* If the symbol is weak, we do need to clear the value.
4127
       Otherwise, the PLT entry would provide a definition for
4128
       the symbol even if the symbol wasn't defined anywhere,
4129
       and so the symbol would never be NULL.  */
4130
0
    if (!h->ref_regular_nonweak)
4131
0
      sym->st_value = 0;
4132
0
  }
4133
0
    }
4134
4135
0
  if (h->got.offset != MINUS_ONE
4136
      /* TLS got entry have been handled in elf_relocate_section.  */
4137
0
      && !(loongarch_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE))
4138
      /* Have allocated got entry but not allocated rela before.  */
4139
0
      && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
4140
0
    {
4141
0
      asection *sgot, *srela;
4142
0
      Elf_Internal_Rela rela;
4143
0
      bfd_vma off = h->got.offset & ~(bfd_vma)1;
4144
4145
      /* This symbol has an entry in the GOT.  Set it up.  */
4146
0
      sgot = htab->elf.sgot;
4147
0
      srela = htab->elf.srelgot;
4148
0
      BFD_ASSERT (sgot && srela);
4149
4150
0
      rela.r_offset = sec_addr (sgot) + off;
4151
4152
0
      if (h->def_regular
4153
0
    && h->type == STT_GNU_IFUNC)
4154
0
  {
4155
0
    if(h->plt.offset == MINUS_ONE)
4156
0
      {
4157
0
        if (htab->elf.splt == NULL)
4158
0
    srela = htab->elf.irelplt;
4159
4160
0
        if (SYMBOL_REFERENCES_LOCAL (info, h))
4161
0
    {
4162
0
      asection *sec = h->root.u.def.section;
4163
0
      rela.r_info = ELF64_R_INFO (0, R_LARCH_IRELATIVE);
4164
0
      rela.r_addend = h->root.u.def.value + sec->output_section->vma
4165
0
        + sec->output_offset;
4166
0
      bfd_put_64 (output_bfd, 0, sgot->contents + off);
4167
0
    }
4168
0
        else
4169
0
    {
4170
0
      BFD_ASSERT (h->dynindx != -1);
4171
0
      rela.r_info = ELF64_R_INFO (h->dynindx, R_LARCH_64);
4172
0
      rela.r_addend = 0;
4173
0
      bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + off);
4174
0
    }
4175
0
      }
4176
0
    else if(bfd_link_pic (info))
4177
0
      {
4178
0
        rela.r_info = ELF64_R_INFO (h->dynindx, R_LARCH_64);
4179
0
        rela.r_addend = 0;
4180
0
        bfd_put_64 (output_bfd, rela.r_addend, sgot->contents + off);
4181
0
      }
4182
0
    else
4183
0
      {
4184
0
        asection *plt;
4185
        /* For non-shared object, we can't use .got.plt, which
4186
     contains the real function address if we need pointer
4187
     equality.  We load the GOT entry with the PLT entry.  */
4188
0
        plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
4189
0
        bfd_put_64 (output_bfd,
4190
0
        (plt->output_section->vma
4191
0
         + plt->output_offset
4192
0
         + h->plt.offset),
4193
0
        sgot->contents + off);
4194
0
        return true;
4195
0
      }
4196
0
  }
4197
0
      else if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h))
4198
0
  {
4199
0
    asection *sec = h->root.u.def.section;
4200
0
    rela.r_info = ELF64_R_INFO (0, R_LARCH_RELATIVE);
4201
0
    rela.r_addend = (h->root.u.def.value + sec->output_section->vma
4202
0
         + sec->output_offset);
4203
0
  }
4204
0
      else
4205
0
  {
4206
0
    BFD_ASSERT (h->dynindx != -1);
4207
0
    rela.r_info = ELF64_R_INFO (h->dynindx, R_LARCH_64);
4208
0
    rela.r_addend = 0;
4209
0
  }
4210
4211
0
      loongarch_elf_append_rela (output_bfd, srela, &rela);
4212
0
    }
4213
4214
  /* Mark some specially defined symbols as absolute.  */
4215
0
  if (h == htab->elf.hdynamic || h == htab->elf.hgot || h == htab->elf.hplt)
4216
0
    sym->st_shndx = SHN_ABS;
4217
4218
0
  return true;
4219
0
}
4220
4221
/* Finish up the dynamic sections.  */
4222
4223
static bool
4224
loongarch_finish_dyn (bfd *output_bfd, struct bfd_link_info *info, bfd *dynobj,
4225
          asection *sdyn)
4226
0
{
4227
0
  struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4228
0
  const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
4229
0
  size_t dynsize = bed->s->sizeof_dyn, skipped_size = 0;
4230
0
  bfd_byte *dyncon, *dynconend;
4231
4232
0
  dynconend = sdyn->contents + sdyn->size;
4233
0
  for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize)
4234
0
    {
4235
0
      Elf_Internal_Dyn dyn;
4236
0
      asection *s;
4237
0
      int skipped = 0;
4238
4239
0
      bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
4240
4241
0
      switch (dyn.d_tag)
4242
0
  {
4243
0
  case DT_PLTGOT:
4244
0
    s = htab->elf.sgotplt;
4245
0
    dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4246
0
    break;
4247
0
  case DT_JMPREL:
4248
0
    s = htab->elf.srelplt;
4249
0
    dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4250
0
    break;
4251
0
  case DT_PLTRELSZ:
4252
0
    s = htab->elf.srelplt;
4253
0
    dyn.d_un.d_val = s->size;
4254
0
    break;
4255
0
  case DT_TEXTREL:
4256
0
    if ((info->flags & DF_TEXTREL) == 0)
4257
0
      skipped = 1;
4258
0
    break;
4259
0
  case DT_FLAGS:
4260
0
    if ((info->flags & DF_TEXTREL) == 0)
4261
0
      dyn.d_un.d_val &= ~DF_TEXTREL;
4262
0
    break;
4263
0
  }
4264
0
      if (skipped)
4265
0
  skipped_size += dynsize;
4266
0
      else
4267
0
  bed->s->swap_dyn_out (output_bfd, &dyn, dyncon - skipped_size);
4268
0
    }
4269
  /* Wipe out any trailing entries if we shifted down a dynamic tag.  */
4270
0
  memset (dyncon - skipped_size, 0, skipped_size);
4271
0
  return true;
4272
0
}
4273
4274
/* Finish up local dynamic symbol handling.  We set the contents of
4275
   various dynamic sections here.  */
4276
4277
static int
4278
elf64_loongarch_finish_local_dynamic_symbol (void **slot, void *inf)
4279
0
{
4280
0
  struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
4281
0
  struct bfd_link_info *info = (struct bfd_link_info *) inf;
4282
4283
0
  return loongarch_elf_finish_dynamic_symbol (info->output_bfd, info, h, NULL);
4284
0
}
4285
4286
/* Value of struct elf_backend_data->elf_backend_output_arch_local_syms,
4287
   this function is called before elf_link_sort_relocs.
4288
   So relocation R_LARCH_IRELATIVE for local ifunc can be append to
4289
   .rela.dyn (.rela.got) by loongarch_elf_append_rela.  */
4290
4291
static bool
4292
elf_loongarch_output_arch_local_syms
4293
  (bfd *output_bfd ATTRIBUTE_UNUSED,
4294
   struct bfd_link_info *info,
4295
   void *flaginfo ATTRIBUTE_UNUSED,
4296
   int (*func) (void *, const char *,
4297
    Elf_Internal_Sym *,
4298
    asection *,
4299
    struct elf_link_hash_entry *) ATTRIBUTE_UNUSED)
4300
0
{
4301
0
  struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4302
0
  if (htab == NULL)
4303
0
    return false;
4304
4305
  /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
4306
0
  htab_traverse (htab->loc_hash_table,
4307
0
     elf64_loongarch_finish_local_dynamic_symbol,
4308
0
     info);
4309
4310
0
  return true;
4311
0
}
4312
4313
static bool
4314
loongarch_elf_finish_dynamic_sections (bfd *output_bfd,
4315
               struct bfd_link_info *info)
4316
0
{
4317
0
  bfd *dynobj;
4318
0
  asection *sdyn, *plt, *gotplt = NULL;
4319
0
  struct loongarch_elf_link_hash_table *htab;
4320
4321
0
  htab = loongarch_elf_hash_table (info);
4322
0
  BFD_ASSERT (htab);
4323
0
  dynobj = htab->elf.dynobj;
4324
0
  sdyn = bfd_get_linker_section (dynobj, ".dynamic");
4325
4326
0
  if (elf_hash_table (info)->dynamic_sections_created)
4327
0
    {
4328
0
      BFD_ASSERT (htab->elf.splt && sdyn);
4329
4330
0
      if (!loongarch_finish_dyn (output_bfd, info, dynobj, sdyn))
4331
0
  return false;
4332
0
    }
4333
4334
0
  plt = htab->elf.splt;
4335
0
  gotplt = htab->elf.sgotplt;
4336
4337
0
  if (plt && 0 < plt->size)
4338
0
    {
4339
0
      size_t i;
4340
0
      uint32_t plt_header[PLT_HEADER_INSNS];
4341
0
      if (!loongarch_make_plt_header (sec_addr (gotplt), sec_addr (plt),
4342
0
              plt_header))
4343
0
  return false;
4344
4345
0
      for (i = 0; i < PLT_HEADER_INSNS; i++)
4346
0
  bfd_put_32 (output_bfd, plt_header[i], plt->contents + 4 * i);
4347
4348
0
      elf_section_data (plt->output_section)->this_hdr.sh_entsize =
4349
0
  PLT_ENTRY_SIZE;
4350
0
    }
4351
4352
0
  if (htab->elf.sgotplt)
4353
0
    {
4354
0
      asection *output_section = htab->elf.sgotplt->output_section;
4355
4356
0
      if (bfd_is_abs_section (output_section))
4357
0
  {
4358
0
    _bfd_error_handler (_("discarded output section: `%pA'"),
4359
0
            htab->elf.sgotplt);
4360
0
    return false;
4361
0
  }
4362
4363
0
      if (0 < htab->elf.sgotplt->size)
4364
0
  {
4365
    /* Write the first two entries in .got.plt, needed for the dynamic
4366
       linker.  */
4367
0
    bfd_put_64 (output_bfd, MINUS_ONE, htab->elf.sgotplt->contents);
4368
4369
0
    bfd_put_64 (output_bfd, (bfd_vma) 0,
4370
0
          htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
4371
0
  }
4372
4373
0
      elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
4374
0
    }
4375
4376
0
  if (htab->elf.sgot)
4377
0
    {
4378
0
      asection *output_section = htab->elf.sgot->output_section;
4379
4380
0
      if (0 < htab->elf.sgot->size)
4381
0
  {
4382
    /* Set the first entry in the global offset table to the address of
4383
       the dynamic section.  */
4384
0
    bfd_vma val = sdyn ? sec_addr (sdyn) : 0;
4385
0
    bfd_put_64 (output_bfd, val, htab->elf.sgot->contents);
4386
0
  }
4387
4388
0
      elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
4389
0
    }
4390
4391
0
  return true;
4392
0
}
4393
4394
/* Return address for Ith PLT stub in section PLT, for relocation REL
4395
   or (bfd_vma) -1 if it should not be included.  */
4396
4397
static bfd_vma
4398
loongarch_elf_plt_sym_val (bfd_vma i, const asection *plt,
4399
         const arelent *rel ATTRIBUTE_UNUSED)
4400
0
{
4401
0
  return plt->vma + PLT_HEADER_SIZE + i * PLT_ENTRY_SIZE;
4402
0
}
4403
4404
static enum elf_reloc_type_class
4405
loongarch_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
4406
          const asection *rel_sec ATTRIBUTE_UNUSED,
4407
          const Elf_Internal_Rela *rela)
4408
0
{
4409
0
  struct loongarch_elf_link_hash_table *htab;
4410
0
  htab = loongarch_elf_hash_table (info);
4411
4412
0
  if (htab->elf.dynsym != NULL && htab->elf.dynsym->contents != NULL)
4413
0
    {
4414
      /* Check relocation against STT_GNU_IFUNC symbol if there are
4415
   dynamic symbols.  */
4416
0
      bfd *abfd = info->output_bfd;
4417
0
      const struct elf_backend_data *bed = get_elf_backend_data (abfd);
4418
0
      unsigned long r_symndx = ELF64_R_SYM (rela->r_info);
4419
0
      if (r_symndx != STN_UNDEF)
4420
0
  {
4421
0
    Elf_Internal_Sym sym;
4422
0
    if (!bed->s->swap_symbol_in (abfd,
4423
0
               htab->elf.dynsym->contents
4424
0
               + r_symndx * bed->s->sizeof_sym,
4425
0
               0, &sym))
4426
0
      {
4427
        /* xgettext:c-format  */
4428
0
        _bfd_error_handler (_("%pB symbol number %lu references"
4429
0
            " nonexistent SHT_SYMTAB_SHNDX section"),
4430
0
          abfd, r_symndx);
4431
        /* Ideally an error class should be returned here.  */
4432
0
      }
4433
0
    else if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
4434
0
      return reloc_class_ifunc;
4435
0
  }
4436
0
    }
4437
4438
0
  switch (ELF64_R_TYPE (rela->r_info))
4439
0
    {
4440
0
    case R_LARCH_IRELATIVE:
4441
0
      return reloc_class_ifunc;
4442
0
    case R_LARCH_RELATIVE:
4443
0
      return reloc_class_relative;
4444
0
    case R_LARCH_JUMP_SLOT:
4445
0
      return reloc_class_plt;
4446
0
    case R_LARCH_COPY:
4447
0
      return reloc_class_copy;
4448
0
    default:
4449
0
      return reloc_class_normal;
4450
0
    }
4451
0
}
4452
4453
/* Copy the extra info we tack onto an elf_link_hash_entry.  */
4454
4455
static void
4456
loongarch_elf_copy_indirect_symbol (struct bfd_link_info *info,
4457
            struct elf_link_hash_entry *dir,
4458
            struct elf_link_hash_entry *ind)
4459
0
{
4460
0
  struct elf_link_hash_entry *edir, *eind;
4461
4462
0
  edir = dir;
4463
0
  eind = ind;
4464
4465
0
  if (eind->dyn_relocs != NULL)
4466
0
    {
4467
0
      if (edir->dyn_relocs != NULL)
4468
0
  {
4469
0
    struct elf_dyn_relocs **pp;
4470
0
    struct elf_dyn_relocs *p;
4471
4472
    /* Add reloc counts against the indirect sym to the direct sym
4473
       list.  Merge any entries against the same section.  */
4474
0
    for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
4475
0
      {
4476
0
        struct elf_dyn_relocs *q;
4477
4478
0
        for (q = edir->dyn_relocs; q != NULL; q = q->next)
4479
0
    if (q->sec == p->sec)
4480
0
      {
4481
0
        q->pc_count += p->pc_count;
4482
0
        q->count += p->count;
4483
0
        *pp = p->next;
4484
0
        break;
4485
0
      }
4486
0
        if (q == NULL)
4487
0
    pp = &p->next;
4488
0
      }
4489
0
    *pp = edir->dyn_relocs;
4490
0
  }
4491
4492
0
      edir->dyn_relocs = eind->dyn_relocs;
4493
0
      eind->dyn_relocs = NULL;
4494
0
    }
4495
4496
0
  if (ind->root.type == bfd_link_hash_indirect && dir->got.refcount < 0)
4497
0
    {
4498
0
      loongarch_elf_hash_entry(edir)->tls_type
4499
0
  = loongarch_elf_hash_entry(eind)->tls_type;
4500
0
      loongarch_elf_hash_entry(eind)->tls_type = GOT_UNKNOWN;
4501
0
    }
4502
0
  _bfd_elf_link_hash_copy_indirect (info, dir, ind);
4503
0
}
4504
4505
0
#define PRSTATUS_SIZE       0x1d8
4506
#define PRSTATUS_OFFSET_PR_CURSIG   0xc
4507
#define PRSTATUS_OFFSET_PR_PID      0x20
4508
0
#define ELF_GREGSET_T_SIZE      0x168
4509
0
#define PRSTATUS_OFFSET_PR_REG      0x70
4510
4511
/* Support for core dump NOTE sections.  */
4512
4513
static bool
4514
loongarch_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
4515
0
{
4516
0
  switch (note->descsz)
4517
0
    {
4518
0
    default:
4519
0
      return false;
4520
4521
    /* The sizeof (struct elf_prstatus) on Linux/LoongArch.  */
4522
0
    case PRSTATUS_SIZE:
4523
      /* pr_cursig  */
4524
0
      elf_tdata (abfd)->core->signal =
4525
0
  bfd_get_16 (abfd, note->descdata + PRSTATUS_OFFSET_PR_CURSIG);
4526
4527
      /* pr_pid  */
4528
0
      elf_tdata (abfd)->core->lwpid =
4529
0
  bfd_get_32 (abfd, note->descdata + PRSTATUS_OFFSET_PR_PID);
4530
0
      break;
4531
0
    }
4532
4533
  /* Make a ".reg/999" section.  */
4534
0
  return _bfd_elfcore_make_pseudosection (abfd, ".reg", ELF_GREGSET_T_SIZE,
4535
0
            note->descpos
4536
0
            + PRSTATUS_OFFSET_PR_REG);
4537
0
}
4538
4539
0
#define PRPSINFO_SIZE       0x88
4540
#define PRPSINFO_OFFSET_PR_PID      0x18
4541
0
#define PRPSINFO_OFFSET_PR_FNAME    0x28
4542
0
#define PRPSINFO_SIZEOF_PR_FNAME    0x10
4543
0
#define PRPSINFO_OFFSET_PR_PS_ARGS  0x38
4544
0
#define PRPSINFO_SIZEOF_PR_PS_ARGS  0x50
4545
4546
static bool
4547
loongarch_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
4548
0
{
4549
0
  switch (note->descsz)
4550
0
    {
4551
0
    default:
4552
0
      return false;
4553
4554
    /* The sizeof (prpsinfo_t) on Linux/LoongArch.  */
4555
0
    case PRPSINFO_SIZE:
4556
      /* pr_pid  */
4557
0
      elf_tdata (abfd)->core->pid =
4558
0
  bfd_get_32 (abfd, note->descdata + PRPSINFO_OFFSET_PR_PID);
4559
4560
      /* pr_fname  */
4561
0
      elf_tdata (abfd)->core->program =
4562
0
  _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_FNAME,
4563
0
            PRPSINFO_SIZEOF_PR_FNAME);
4564
4565
      /* pr_psargs  */
4566
0
      elf_tdata (abfd)->core->command =
4567
0
  _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_PS_ARGS,
4568
0
            PRPSINFO_SIZEOF_PR_PS_ARGS);
4569
0
      break;
4570
0
    }
4571
4572
  /* Note that for some reason, a spurious space is tacked
4573
     onto the end of the args in some (at least one anyway)
4574
     implementations, so strip it off if it exists.  */
4575
4576
0
  {
4577
0
    char *command = elf_tdata (abfd)->core->command;
4578
0
    int n = strlen (command);
4579
4580
0
    if (0 < n && command[n - 1] == ' ')
4581
0
      command[n - 1] = '\0';
4582
0
  }
4583
4584
0
  return true;
4585
0
}
4586
4587
/* Set the right mach type.  */
4588
static bool
4589
loongarch_elf_object_p (bfd *abfd)
4590
4
{
4591
  /* There are only two mach types in LoongArch currently.  */
4592
4
  if (strcmp (abfd->xvec->name, "elf64-loongarch") == 0)
4593
4
    bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch64);
4594
0
  else
4595
0
    bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch32);
4596
4
  return true;
4597
4
}
4598
4599
static asection *
4600
loongarch_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info,
4601
          Elf_Internal_Rela *rel,
4602
          struct elf_link_hash_entry *h,
4603
          Elf_Internal_Sym *sym)
4604
0
{
4605
0
  if (h != NULL)
4606
0
    switch (ELF64_R_TYPE (rel->r_info))
4607
0
      {
4608
0
      case R_LARCH_GNU_VTINHERIT:
4609
0
      case R_LARCH_GNU_VTENTRY:
4610
0
  return NULL;
4611
0
      }
4612
4613
0
  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
4614
0
}
4615
4616
/* Return TRUE if symbol H should be hashed in the `.gnu.hash' section.  For
4617
   executable PLT slots where the executable never takes the address of those
4618
   functions, the function symbols are not added to the hash table.  */
4619
4620
static bool
4621
elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
4622
0
{
4623
0
  if (h->plt.offset != (bfd_vma) -1
4624
0
      && !h->def_regular
4625
0
      && !h->pointer_equality_needed)
4626
0
    return false;
4627
4628
0
  return _bfd_elf_hash_symbol (h);
4629
0
}
4630
4631
#define TARGET_LITTLE_SYM loongarch_elf64_vec
4632
#define TARGET_LITTLE_NAME "elf64-loongarch"
4633
#define ELF_ARCH bfd_arch_loongarch
4634
#define ELF_TARGET_ID LARCH_ELF_DATA
4635
#define ELF_MACHINE_CODE EM_LOONGARCH
4636
#define ELF_MAXPAGESIZE 0x4000
4637
#define bfd_elf64_bfd_reloc_type_lookup loongarch_reloc_type_lookup
4638
#define bfd_elf64_bfd_link_hash_table_create          \
4639
  loongarch_elf_link_hash_table_create
4640
#define bfd_elf64_bfd_reloc_name_lookup loongarch_reloc_name_lookup
4641
#define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto.  */
4642
#define elf_info_to_howto loongarch_info_to_howto_rela
4643
#define bfd_elf64_bfd_merge_private_bfd_data          \
4644
  elf64_loongarch_merge_private_bfd_data
4645
4646
#define elf_backend_reloc_type_class loongarch_reloc_type_class
4647
#define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol
4648
#define elf_backend_create_dynamic_sections          \
4649
  loongarch_elf_create_dynamic_sections
4650
#define elf_backend_check_relocs loongarch_elf_check_relocs
4651
#define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol
4652
#define elf_backend_size_dynamic_sections loongarch_elf_size_dynamic_sections
4653
#define elf_backend_relocate_section loongarch_elf_relocate_section
4654
#define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol
4655
#define elf_backend_output_arch_local_syms \
4656
  elf_loongarch_output_arch_local_syms
4657
#define elf_backend_finish_dynamic_sections          \
4658
  loongarch_elf_finish_dynamic_sections
4659
#define elf_backend_object_p loongarch_elf_object_p
4660
#define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook
4661
#define elf_backend_plt_sym_val loongarch_elf_plt_sym_val
4662
#define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
4663
#define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
4664
#define elf_backend_hash_symbol elf_loongarch64_hash_symbol
4665
#define bfd_elf64_bfd_relax_section loongarch_elf_relax_section
4666
4667
#include "elf64-target.h"