Coverage Report

Created: 2023-06-29 07:05

/src/binutils-gdb/bfd/elf32-loongarch.c
Line
Count
Source (jump to first uncovered line)
1
#line 1 "elfnn-loongarch.c"
2
/* LoongArch-specific support for 32-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 32
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
               ELF32_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
elf32_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
elf32_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
elf32_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, ELF32_R_SYM (rel->r_info));
282
0
  void **slot;
283
284
0
  e.elf.indx = sec->id;
285
0
  e.elf.dynstr_index = ELF32_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 = ELF32_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
elf32_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, elf32_loongarch_local_htab_hash,
361
0
           elf32_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
      elf32_loongarch_link_hash_table_free (abfd);
366
0
      return NULL;
367
0
    }
368
0
  ret->elf.root.hash_table_free = elf32_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
elf32_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 = ELF32_R_SYM (rel->r_info);
634
0
      r_type = ELF32_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 = elf32_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_32.
844
       3. Under dll, R_LARCH_32 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 (Elf32_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 (Elf32_External_Rela);
1144
0
    }
1145
0
        else
1146
0
    {
1147
0
      if (SYMBOL_REFERENCES_LOCAL (info, h))
1148
0
        htab->elf.srelgot->size += sizeof (Elf32_External_Rela);
1149
0
      else
1150
0
        htab->elf.srelgot->size += 2 * sizeof (Elf32_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 (Elf32_External_Rela);
1164
0
    }
1165
0
        else
1166
0
    {
1167
0
      htab->elf.srelgot->size += sizeof (Elf32_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 (Elf32_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_DTPREL32
1194
   * R_LARCH_JUMP_SLOT
1195
   * R_LARCH_32.  */
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 (Elf32_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
elf32_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 bool
1543
elf32_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 elf32_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 (Elf32_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 (Elf32_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, elf32_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
     (void *) elf32_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 (Elf32_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 (ELF32_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
#define RELOCATE_CALC_PC32_HI20(relocation, pc)   \
2289
0
  ({              \
2290
0
    bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
2291
0
    pc = pc & (~(bfd_vma)0xfff);      \
2292
0
    if (__lo > 0x7ff)         \
2293
0
      {             \
2294
0
  relocation += 0x1000;       \
2295
0
      }            \
2296
0
    relocation &= ~(bfd_vma)0xfff;      \
2297
0
    relocation -= pc;         \
2298
0
  })
2299
2300
#define RELOCATE_CALC_PC64_HI32(relocation, pc)   \
2301
0
  ({              \
2302
0
    bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
2303
0
    if (__lo > 0x7ff)         \
2304
0
      {             \
2305
0
  relocation -= 0x100000000;          \
2306
0
      }              \
2307
0
    relocation -= (pc & ~(bfd_vma)0xffffffff);    \
2308
0
  })
2309
2310
static int
2311
loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
2312
        bfd *input_bfd, asection *input_section,
2313
        bfd_byte *contents, Elf_Internal_Rela *relocs,
2314
        Elf_Internal_Sym *local_syms,
2315
        asection **local_sections)
2316
0
{
2317
0
  Elf_Internal_Rela *rel;
2318
0
  Elf_Internal_Rela *relend;
2319
0
  bool fatal = false;
2320
0
  asection *sreloc = elf_section_data (input_section)->sreloc;
2321
0
  struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
2322
0
  Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd);
2323
0
  struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
2324
0
  bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd);
2325
0
  bool is_pic = bfd_link_pic (info);
2326
0
  bool is_dyn = elf_hash_table (info)->dynamic_sections_created;
2327
0
  asection *plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
2328
0
  asection *got = htab->elf.sgot;
2329
2330
0
  relend = relocs + input_section->reloc_count;
2331
0
  for (rel = relocs; rel < relend; rel++)
2332
0
    {
2333
0
      int r_type = ELF32_R_TYPE (rel->r_info);
2334
0
      unsigned long r_symndx = ELF32_R_SYM (rel->r_info);
2335
0
      bfd_vma pc = sec_addr (input_section) + rel->r_offset;
2336
0
      reloc_howto_type *howto = NULL;
2337
0
      asection *sec = NULL;
2338
0
      Elf_Internal_Sym *sym = NULL;
2339
0
      struct elf_link_hash_entry *h = NULL;
2340
0
      const char *name;
2341
0
      bfd_reloc_status_type r = bfd_reloc_ok;
2342
0
      bool is_ie, is_undefweak, unresolved_reloc, defined_local;
2343
0
      bool resolved_local, resolved_dynly, resolved_to_const;
2344
0
      char tls_type;
2345
0
      bfd_vma relocation, off, ie_off;
2346
0
      int i, j;
2347
2348
0
      howto = loongarch_elf_rtype_to_howto (input_bfd, r_type);
2349
0
      if (howto == NULL || r_type == R_LARCH_GNU_VTINHERIT
2350
0
    || r_type == R_LARCH_GNU_VTENTRY)
2351
0
  continue;
2352
2353
      /* This is a final link.  */
2354
0
      if (r_symndx < symtab_hdr->sh_info)
2355
0
  {
2356
0
    is_undefweak = false;
2357
0
    unresolved_reloc = false;
2358
0
    sym = local_syms + r_symndx;
2359
0
    sec = local_sections[r_symndx];
2360
0
    relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2361
2362
    /* Relocate against local STT_GNU_IFUNC symbol.  */
2363
0
    if (!bfd_link_relocatable (info)
2364
0
        && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
2365
0
      {
2366
0
        h = elf32_loongarch_get_local_sym_hash (htab, input_bfd, rel,
2367
0
                  false);
2368
0
        if (h == NULL)
2369
0
    abort ();
2370
2371
        /* Set STT_GNU_IFUNC symbol value.  */
2372
0
        h->root.u.def.value = sym->st_value;
2373
0
        h->root.u.def.section = sec;
2374
0
      }
2375
0
    defined_local = true;
2376
0
    resolved_local = true;
2377
0
    resolved_dynly = false;
2378
0
    resolved_to_const = false;
2379
2380
    /* Calc in funtion elf_link_input_bfd,
2381
     * if #define elf_backend_rela_normal to 1.  */
2382
0
    if (bfd_link_relocatable (info)
2383
0
        && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2384
0
      continue;
2385
0
  }
2386
0
      else
2387
0
  {
2388
0
    bool warned, ignored;
2389
2390
0
    RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2391
0
           r_symndx, symtab_hdr, sym_hashes,
2392
0
           h, sec, relocation,
2393
0
           unresolved_reloc, warned, ignored);
2394
    /* Here means symbol isn't local symbol only and 'h != NULL'.  */
2395
2396
    /* The 'unresolved_syms_in_objects' specify how to deal with undefined
2397
       symbol.  And 'dynamic_undefined_weak' specify what to do when
2398
       meeting undefweak.  */
2399
2400
0
    if ((is_undefweak = h->root.type == bfd_link_hash_undefweak))
2401
0
      {
2402
0
        defined_local = false;
2403
0
        resolved_local = false;
2404
0
        resolved_to_const = (!is_dyn || h->dynindx == -1
2405
0
           || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
2406
0
        resolved_dynly = !resolved_local && !resolved_to_const;
2407
0
      }
2408
0
    else if (warned)
2409
0
      {
2410
        /* Symbol undefined offen means failed already.  I don't know why
2411
     'warned' here but I guess it want to continue relocating as if
2412
     no error occures to find other errors as more as possible.  */
2413
2414
        /* To avoid generating warning messages about truncated
2415
     relocations, set the relocation's address to be the same as
2416
     the start of this section.  */
2417
0
        relocation = (input_section->output_section
2418
0
          ? input_section->output_section->vma
2419
0
          : 0);
2420
2421
0
        defined_local = relocation != 0;
2422
0
        resolved_local = defined_local;
2423
0
        resolved_to_const = !resolved_local;
2424
0
        resolved_dynly = false;
2425
0
      }
2426
0
    else
2427
0
      {
2428
0
        defined_local = !unresolved_reloc && !ignored;
2429
0
        resolved_local =
2430
0
    defined_local && SYMBOL_REFERENCES_LOCAL (info, h);
2431
0
        resolved_dynly = !resolved_local;
2432
0
        resolved_to_const = !resolved_local && !resolved_dynly;
2433
0
      }
2434
0
  }
2435
2436
0
      name = loongarch_sym_name (input_bfd, h, sym);
2437
2438
0
      if (sec != NULL && discarded_section (sec))
2439
0
  RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel,
2440
0
           1, relend, howto, 0, contents);
2441
2442
0
      if (bfd_link_relocatable (info))
2443
0
  continue;
2444
2445
      /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
2446
   from removed linkonce sections, or sections discarded by a linker
2447
   script.  Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const.  */
2448
0
      if (r_symndx == STN_UNDEF || bfd_is_abs_section (sec))
2449
0
  {
2450
0
    defined_local = false;
2451
0
    resolved_local = false;
2452
0
    resolved_dynly = false;
2453
0
    resolved_to_const = true;
2454
0
  }
2455
2456
      /* The ifunc reference generate plt.  */
2457
0
      if (h && h->type == STT_GNU_IFUNC && h->plt.offset != MINUS_ONE)
2458
0
  {
2459
0
    defined_local = true;
2460
0
    resolved_local = true;
2461
0
    resolved_dynly = false;
2462
0
    resolved_to_const = false;
2463
0
    relocation = sec_addr (plt) + h->plt.offset;
2464
0
  }
2465
2466
0
      unresolved_reloc = resolved_dynly;
2467
2468
0
      BFD_ASSERT (resolved_local + resolved_dynly + resolved_to_const == 1);
2469
2470
      /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));.  */
2471
2472
0
      BFD_ASSERT (!resolved_local || defined_local);
2473
2474
0
      is_ie = false;
2475
0
      switch (r_type)
2476
0
  {
2477
0
  case R_LARCH_MARK_PCREL:
2478
0
  case R_LARCH_MARK_LA:
2479
0
  case R_LARCH_NONE:
2480
0
    r = bfd_reloc_continue;
2481
0
    unresolved_reloc = false;
2482
0
    break;
2483
2484
0
  case R_LARCH_32:
2485
0
  case R_LARCH_64:
2486
0
    if (resolved_dynly || (is_pic && resolved_local))
2487
0
      {
2488
0
        Elf_Internal_Rela outrel;
2489
2490
        /* When generating a shared object, these relocations are copied
2491
     into the output file to be resolved at run time.  */
2492
2493
0
        outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2494
0
               input_section,
2495
0
               rel->r_offset);
2496
2497
0
        unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2498
0
          && (input_section->flags & SEC_ALLOC));
2499
2500
0
        outrel.r_offset += sec_addr (input_section);
2501
2502
        /* A pointer point to a ifunc symbol.  */
2503
0
        if (h && h->type == STT_GNU_IFUNC)
2504
0
    {
2505
0
      if (h->dynindx == -1)
2506
0
        {
2507
0
          outrel.r_info = ELF32_R_INFO (0, R_LARCH_IRELATIVE);
2508
0
          outrel.r_addend = (h->root.u.def.value
2509
0
          + h->root.u.def.section->output_section->vma
2510
0
          + h->root.u.def.section->output_offset);
2511
0
        }
2512
0
      else
2513
0
        {
2514
0
          outrel.r_info = ELF32_R_INFO (h->dynindx, R_LARCH_32);
2515
0
          outrel.r_addend = 0;
2516
0
        }
2517
2518
0
      if (SYMBOL_REFERENCES_LOCAL (info, h))
2519
0
        {
2520
2521
0
          if (htab->elf.splt != NULL)
2522
0
      sreloc = htab->elf.srelgot;
2523
0
          else
2524
0
      sreloc = htab->elf.irelplt;
2525
0
        }
2526
0
      else
2527
0
        {
2528
2529
0
          if (bfd_link_pic (info))
2530
0
      sreloc = htab->elf.irelifunc;
2531
0
          else if (htab->elf.splt != NULL)
2532
0
      sreloc = htab->elf.srelgot;
2533
0
          else
2534
0
      sreloc = htab->elf.irelplt;
2535
0
        }
2536
0
    }
2537
0
        else if (resolved_dynly)
2538
0
    {
2539
0
      if (h->dynindx == -1)
2540
0
        {
2541
0
          if (h->root.type == bfd_link_hash_undefined)
2542
0
      (*info->callbacks->undefined_symbol)
2543
0
        (info, name, input_bfd, input_section,
2544
0
         rel->r_offset, true);
2545
2546
0
          outrel.r_info = ELF32_R_INFO (0, r_type);
2547
0
        }
2548
0
      else
2549
0
        outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
2550
2551
0
      outrel.r_addend = rel->r_addend;
2552
0
    }
2553
0
        else
2554
0
    {
2555
0
      outrel.r_info = ELF32_R_INFO (0, R_LARCH_RELATIVE);
2556
0
      outrel.r_addend = relocation + rel->r_addend;
2557
0
    }
2558
2559
        /* No alloc space of func allocate_dynrelocs.  */
2560
0
        if (unresolved_reloc
2561
0
      && !(h && (h->is_weakalias || !h->dyn_relocs)))
2562
0
    loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2563
0
      }
2564
2565
0
    relocation += rel->r_addend;
2566
0
    break;
2567
2568
0
  case R_LARCH_ADD6:
2569
0
  case R_LARCH_ADD8:
2570
0
  case R_LARCH_ADD16:
2571
0
  case R_LARCH_ADD24:
2572
0
  case R_LARCH_ADD32:
2573
0
  case R_LARCH_ADD64:
2574
0
    {
2575
0
      bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
2576
0
           contents + rel->r_offset);
2577
0
      relocation = old_value + relocation + rel->r_addend;
2578
0
      break;
2579
0
    }
2580
2581
0
  case R_LARCH_SUB6:
2582
0
  case R_LARCH_SUB8:
2583
0
  case R_LARCH_SUB16:
2584
0
  case R_LARCH_SUB24:
2585
0
  case R_LARCH_SUB32:
2586
0
  case R_LARCH_SUB64:
2587
0
    {
2588
0
      bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
2589
0
            contents + rel->r_offset);
2590
0
      relocation = old_value - relocation - rel->r_addend;
2591
0
      break;
2592
0
    }
2593
2594
0
  case R_LARCH_ADD_ULEB128:
2595
0
  case R_LARCH_SUB_ULEB128:
2596
0
    {
2597
      /* Get the value and length of the uleb128 data.  */
2598
0
      unsigned int len = 0;
2599
0
      bfd_vma old_value = _bfd_read_unsigned_leb128 (input_bfd,
2600
0
            contents + rel->r_offset, &len);
2601
2602
0
      if (R_LARCH_ADD_ULEB128 == ELF32_R_TYPE (rel->r_info))
2603
0
        relocation = old_value + relocation + rel->r_addend;
2604
0
      else if (R_LARCH_SUB_ULEB128 == ELF32_R_TYPE (rel->r_info))
2605
0
        relocation = old_value - relocation - rel->r_addend;
2606
2607
0
      bfd_vma mask = (1 << (7 * len)) - 1;
2608
0
      relocation &= mask;
2609
0
      break;
2610
0
    }
2611
2612
0
  case R_LARCH_TLS_DTPREL32:
2613
0
  case R_LARCH_TLS_DTPREL64:
2614
0
    if (resolved_dynly)
2615
0
      {
2616
0
        Elf_Internal_Rela outrel;
2617
2618
0
        outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2619
0
               input_section,
2620
0
               rel->r_offset);
2621
0
        unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2622
0
          && (input_section->flags & SEC_ALLOC));
2623
0
        outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
2624
0
        outrel.r_offset += sec_addr (input_section);
2625
0
        outrel.r_addend = rel->r_addend;
2626
0
        if (unresolved_reloc)
2627
0
    loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2628
0
        break;
2629
0
      }
2630
2631
0
    if (resolved_to_const)
2632
0
      fatal = loongarch_reloc_is_fatal (info, input_bfd, input_section,
2633
0
                rel, howto,
2634
0
                bfd_reloc_notsupported,
2635
0
                is_undefweak, name,
2636
0
                "Internal:");
2637
0
    if (resolved_local)
2638
0
      {
2639
0
        if (!elf_hash_table (info)->tls_sec)
2640
0
    {
2641
0
    fatal = loongarch_reloc_is_fatal (info, input_bfd,
2642
0
        input_section, rel, howto, bfd_reloc_notsupported,
2643
0
        is_undefweak, name, "TLS section not be created");
2644
0
    }
2645
0
        else
2646
0
    relocation -= elf_hash_table (info)->tls_sec->vma;
2647
0
      }
2648
0
    else
2649
0
      {
2650
0
      fatal = loongarch_reloc_is_fatal (info, input_bfd,
2651
0
          input_section, rel, howto, bfd_reloc_undefined,
2652
0
          is_undefweak, name,
2653
0
          "TLS LE just can be resolved local only.");
2654
0
      }
2655
2656
0
    break;
2657
2658
0
  case R_LARCH_SOP_PUSH_TLS_TPREL:
2659
0
    if (resolved_local)
2660
0
      {
2661
0
        if (!elf_hash_table (info)->tls_sec)
2662
0
    fatal = (loongarch_reloc_is_fatal
2663
0
       (info, input_bfd, input_section, rel, howto,
2664
0
        bfd_reloc_notsupported, is_undefweak, name,
2665
0
        "TLS section not be created"));
2666
0
        else
2667
0
    relocation -= elf_hash_table (info)->tls_sec->vma;
2668
0
      }
2669
0
    else
2670
0
      fatal = (loongarch_reloc_is_fatal
2671
0
         (info, input_bfd, input_section, rel, howto,
2672
0
          bfd_reloc_undefined, is_undefweak, name,
2673
0
          "TLS LE just can be resolved local only."));
2674
0
    break;
2675
2676
0
  case R_LARCH_SOP_PUSH_ABSOLUTE:
2677
0
    if (is_undefweak)
2678
0
      {
2679
0
        if (resolved_dynly)
2680
0
    fatal = (loongarch_reloc_is_fatal
2681
0
       (info, input_bfd, input_section, rel, howto,
2682
0
        bfd_reloc_dangerous, is_undefweak, name,
2683
0
        "Someone require us to resolve undefweak "
2684
0
        "symbol dynamically.  \n"
2685
0
        "But this reloc can't be done.  "
2686
0
        "I think I can't throw error "
2687
0
        "for this\n"
2688
0
        "so I resolved it to 0.  "
2689
0
        "I suggest to re-compile with '-fpic'."));
2690
2691
0
        relocation = 0;
2692
0
        unresolved_reloc = false;
2693
0
        break;
2694
0
      }
2695
2696
0
    if (resolved_to_const)
2697
0
      {
2698
0
        relocation += rel->r_addend;
2699
0
        break;
2700
0
      }
2701
2702
0
    if (is_pic)
2703
0
      {
2704
0
        fatal = (loongarch_reloc_is_fatal
2705
0
           (info, input_bfd, input_section, rel, howto,
2706
0
      bfd_reloc_notsupported, is_undefweak, name,
2707
0
      "Under PIC we don't know load address.  Re-compile "
2708
0
      "with '-fpic'?"));
2709
0
        break;
2710
0
      }
2711
2712
0
    if (resolved_dynly)
2713
0
      {
2714
0
        if (!(plt && h && h->plt.offset != MINUS_ONE))
2715
0
    {
2716
0
      fatal = (loongarch_reloc_is_fatal
2717
0
         (info, input_bfd, input_section, rel, howto,
2718
0
          bfd_reloc_undefined, is_undefweak, name,
2719
0
          "Can't be resolved dynamically.  Try to re-compile "
2720
0
          "with '-fpic'?"));
2721
0
      break;
2722
0
    }
2723
2724
0
        if (rel->r_addend != 0)
2725
0
    {
2726
0
      fatal = (loongarch_reloc_is_fatal
2727
0
         (info, input_bfd, input_section, rel, howto,
2728
0
          bfd_reloc_notsupported, is_undefweak, name,
2729
0
          "Shouldn't be with r_addend."));
2730
0
      break;
2731
0
    }
2732
2733
0
        relocation = sec_addr (plt) + h->plt.offset;
2734
0
        unresolved_reloc = false;
2735
0
        break;
2736
0
      }
2737
2738
0
    if (resolved_local)
2739
0
      {
2740
0
        relocation += rel->r_addend;
2741
0
        break;
2742
0
      }
2743
2744
0
    break;
2745
2746
0
  case R_LARCH_SOP_PUSH_PCREL:
2747
0
  case R_LARCH_SOP_PUSH_PLT_PCREL:
2748
0
    unresolved_reloc = false;
2749
2750
0
    if (is_undefweak)
2751
0
      {
2752
0
        i = 0, j = 0;
2753
0
        relocation = 0;
2754
0
        if (resolved_dynly)
2755
0
    {
2756
0
      if (h && h->plt.offset != MINUS_ONE)
2757
0
        i = 1, j = 2;
2758
0
      else
2759
0
        fatal = (loongarch_reloc_is_fatal
2760
0
           (info, input_bfd, input_section, rel, howto,
2761
0
            bfd_reloc_dangerous, is_undefweak, name,
2762
0
            "Undefweak need to be resolved dynamically, "
2763
0
            "but PLT stub doesn't represent."));
2764
0
    }
2765
0
      }
2766
0
    else
2767
0
      {
2768
0
        if (!(defined_local || (h && h->plt.offset != MINUS_ONE)))
2769
0
    {
2770
0
      fatal = (loongarch_reloc_is_fatal
2771
0
         (info, input_bfd, input_section, rel, howto,
2772
0
          bfd_reloc_undefined, is_undefweak, name,
2773
0
          "PLT stub does not represent and "
2774
0
          "symbol not defined."));
2775
0
      break;
2776
0
    }
2777
2778
0
        if (resolved_local)
2779
0
    i = 0, j = 2;
2780
0
        else /* if (resolved_dynly) */
2781
0
    {
2782
0
      if (!(h && h->plt.offset != MINUS_ONE))
2783
0
        fatal = (loongarch_reloc_is_fatal
2784
0
           (info, input_bfd, input_section, rel, howto,
2785
0
            bfd_reloc_dangerous, is_undefweak, name,
2786
0
            "Internal: PLT stub doesn't represent.  "
2787
0
            "Resolve it with pcrel"));
2788
0
      i = 1, j = 3;
2789
0
    }
2790
0
      }
2791
2792
0
    for (; i < j; i++)
2793
0
      {
2794
0
        if ((i & 1) == 0 && defined_local)
2795
0
    {
2796
0
      relocation -= pc;
2797
0
      relocation += rel->r_addend;
2798
0
      break;
2799
0
    }
2800
2801
0
        if ((i & 1) && h && h->plt.offset != MINUS_ONE)
2802
0
    {
2803
0
      if (rel->r_addend != 0)
2804
0
        {
2805
0
          fatal = (loongarch_reloc_is_fatal
2806
0
             (info, input_bfd, input_section, rel, howto,
2807
0
        bfd_reloc_notsupported, is_undefweak, name,
2808
0
        "PLT shouldn't be with r_addend."));
2809
0
          break;
2810
0
        }
2811
0
      relocation = sec_addr (plt) + h->plt.offset - pc;
2812
0
      break;
2813
0
    }
2814
0
      }
2815
0
    break;
2816
2817
0
  case R_LARCH_SOP_PUSH_GPREL:
2818
0
    unresolved_reloc = false;
2819
2820
0
    if (rel->r_addend != 0)
2821
0
      {
2822
0
        fatal = (loongarch_reloc_is_fatal
2823
0
           (info, input_bfd, input_section, rel, howto,
2824
0
      bfd_reloc_notsupported, is_undefweak, name,
2825
0
      "Shouldn't be with r_addend."));
2826
0
        break;
2827
0
      }
2828
2829
0
    if (h != NULL)
2830
0
      {
2831
0
        off = h->got.offset & (~1);
2832
2833
0
        if (h->got.offset == MINUS_ONE && h->type != STT_GNU_IFUNC)
2834
0
    {
2835
0
      fatal = (loongarch_reloc_is_fatal
2836
0
         (info, input_bfd, input_section, rel, howto,
2837
0
          bfd_reloc_notsupported, is_undefweak, name,
2838
0
          "Internal: GOT entry doesn't represent."));
2839
0
      break;
2840
0
    }
2841
2842
        /* Hidden symbol not has .got entry, only .got.plt entry
2843
     so gprel is (plt - got).  */
2844
0
        if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
2845
0
    {
2846
0
      if (h->plt.offset == (bfd_vma) -1)
2847
0
        {
2848
0
          abort();
2849
0
        }
2850
2851
0
      bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE;
2852
0
      off = plt_index * GOT_ENTRY_SIZE;
2853
2854
0
      if (htab->elf.splt != NULL)
2855
0
        {
2856
          /* Section .plt header is 2 times of plt entry.  */
2857
0
          off = sec_addr (htab->elf.sgotplt) + off
2858
0
      - sec_addr (htab->elf.sgot);
2859
0
        }
2860
0
      else
2861
0
        {
2862
          /* Section iplt not has plt header.  */
2863
0
          off = sec_addr (htab->elf.igotplt) + off
2864
0
      - sec_addr (htab->elf.sgot);
2865
0
        }
2866
0
    }
2867
2868
0
        if ((h->got.offset & 1) == 0)
2869
0
    {
2870
0
      if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
2871
0
              bfd_link_pic (info), h)
2872
0
          && ((bfd_link_pic (info)
2873
0
         && SYMBOL_REFERENCES_LOCAL (info, h))))
2874
0
        {
2875
          /* This is actually a static link, or it is a
2876
       -Bsymbolic link and the symbol is defined
2877
       locally, or the symbol was forced to be local
2878
       because of a version file.  We must initialize
2879
       this entry in the global offset table.  Since the
2880
       offset must always be a multiple of the word size,
2881
       we use the least significant bit to record whether
2882
       we have initialized it already.
2883
2884
       When doing a dynamic link, we create a rela.got
2885
       relocation entry to initialize the value.  This
2886
       is done in the finish_dynamic_symbol routine.  */
2887
2888
0
          if (resolved_dynly)
2889
0
      {
2890
0
        fatal = (loongarch_reloc_is_fatal
2891
0
           (info, input_bfd, input_section, rel, howto,
2892
0
            bfd_reloc_dangerous, is_undefweak, name,
2893
0
            "Internal: here shouldn't dynamic."));
2894
0
      }
2895
2896
0
          if (!(defined_local || resolved_to_const))
2897
0
      {
2898
0
        fatal = (loongarch_reloc_is_fatal
2899
0
           (info, input_bfd, input_section, rel, howto,
2900
0
            bfd_reloc_undefined, is_undefweak, name,
2901
0
            "Internal: "));
2902
0
        break;
2903
0
      }
2904
2905
0
          asection *s;
2906
0
          Elf_Internal_Rela outrel;
2907
          /* We need to generate a R_LARCH_RELATIVE reloc
2908
       for the dynamic linker.  */
2909
0
          s = htab->elf.srelgot;
2910
0
          if (!s)
2911
0
      {
2912
0
        fatal = loongarch_reloc_is_fatal
2913
0
          (info, input_bfd,
2914
0
           input_section, rel, howto,
2915
0
           bfd_reloc_notsupported, is_undefweak, name,
2916
0
           "Internal: '.rel.got' not represent");
2917
0
        break;
2918
0
      }
2919
2920
0
          outrel.r_offset = sec_addr (got) + off;
2921
0
          outrel.r_info = ELF32_R_INFO (0, R_LARCH_RELATIVE);
2922
0
          outrel.r_addend = relocation; /* Link-time addr.  */
2923
0
          loongarch_elf_append_rela (output_bfd, s, &outrel);
2924
0
        }
2925
0
      bfd_put_32 (output_bfd, relocation, got->contents + off);
2926
0
      h->got.offset |= 1;
2927
0
    }
2928
0
      }
2929
0
    else
2930
0
      {
2931
0
        if (!local_got_offsets)
2932
0
    {
2933
0
      fatal = (loongarch_reloc_is_fatal
2934
0
         (info, input_bfd, input_section, rel, howto,
2935
0
          bfd_reloc_notsupported, is_undefweak, name,
2936
0
          "Internal: local got offsets not reporesent."));
2937
0
      break;
2938
0
    }
2939
2940
0
        off = local_got_offsets[r_symndx] & (~1);
2941
2942
0
        if (local_got_offsets[r_symndx] == MINUS_ONE)
2943
0
    {
2944
0
      fatal = (loongarch_reloc_is_fatal
2945
0
         (info, input_bfd, input_section, rel, howto,
2946
0
          bfd_reloc_notsupported, is_undefweak, name,
2947
0
          "Internal: GOT entry doesn't represent."));
2948
0
      break;
2949
0
    }
2950
2951
        /* The offset must always be a multiple of the word size.
2952
     So, we can use the least significant bit to record
2953
     whether we have already processed this entry.  */
2954
0
        if ((local_got_offsets[r_symndx] & 1) == 0)
2955
0
    {
2956
0
      if (is_pic)
2957
0
        {
2958
0
          asection *s;
2959
0
          Elf_Internal_Rela outrel;
2960
          /* We need to generate a R_LARCH_RELATIVE reloc
2961
       for the dynamic linker.  */
2962
0
          s = htab->elf.srelgot;
2963
0
          if (!s)
2964
0
      {
2965
0
        fatal = (loongarch_reloc_is_fatal
2966
0
           (info, input_bfd, input_section, rel, howto,
2967
0
            bfd_reloc_notsupported, is_undefweak, name,
2968
0
            "Internal: '.rel.got' not represent"));
2969
0
        break;
2970
0
      }
2971
2972
0
          outrel.r_offset = sec_addr (got) + off;
2973
0
          outrel.r_info = ELF32_R_INFO (0, R_LARCH_RELATIVE);
2974
0
          outrel.r_addend = relocation; /* Link-time addr.  */
2975
0
          loongarch_elf_append_rela (output_bfd, s, &outrel);
2976
0
        }
2977
2978
0
      bfd_put_32 (output_bfd, relocation, got->contents + off);
2979
0
      local_got_offsets[r_symndx] |= 1;
2980
0
    }
2981
0
      }
2982
0
    relocation = off;
2983
2984
0
    break;
2985
2986
0
  case R_LARCH_SOP_PUSH_TLS_GOT:
2987
0
  case R_LARCH_SOP_PUSH_TLS_GD:
2988
0
    {
2989
0
      unresolved_reloc = false;
2990
0
      if (r_type == R_LARCH_SOP_PUSH_TLS_GOT)
2991
0
        is_ie = true;
2992
2993
0
      bfd_vma got_off = 0;
2994
0
      if (h != NULL)
2995
0
        {
2996
0
    got_off = h->got.offset;
2997
0
    h->got.offset |= 1;
2998
0
        }
2999
0
      else
3000
0
        {
3001
0
    got_off = local_got_offsets[r_symndx];
3002
0
    local_got_offsets[r_symndx] |= 1;
3003
0
        }
3004
3005
0
      BFD_ASSERT (got_off != MINUS_ONE);
3006
3007
0
      ie_off = 0;
3008
0
      tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3009
0
      if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
3010
0
        ie_off = 2 * GOT_ENTRY_SIZE;
3011
3012
0
      if ((got_off & 1) == 0)
3013
0
        {
3014
0
    Elf_Internal_Rela rela;
3015
0
    asection *srel = htab->elf.srelgot;
3016
0
    bfd_vma tls_block_off = 0;
3017
3018
0
    if (SYMBOL_REFERENCES_LOCAL (info, h))
3019
0
      {
3020
0
        BFD_ASSERT (elf_hash_table (info)->tls_sec);
3021
0
        tls_block_off = relocation
3022
0
      - elf_hash_table (info)->tls_sec->vma;
3023
0
      }
3024
3025
0
    if (tls_type & GOT_TLS_GD)
3026
0
      {
3027
0
        rela.r_offset = sec_addr (got) + got_off;
3028
0
        rela.r_addend = 0;
3029
0
        if (SYMBOL_REFERENCES_LOCAL (info, h))
3030
0
          {
3031
      /* Local sym, used in exec, set module id 1.  */
3032
0
      if (bfd_link_executable (info))
3033
0
        bfd_put_32 (output_bfd, 1, got->contents + got_off);
3034
0
      else
3035
0
        {
3036
0
          rela.r_info = ELF32_R_INFO (0,
3037
0
              R_LARCH_TLS_DTPMOD32);
3038
0
          loongarch_elf_append_rela (output_bfd, srel, &rela);
3039
0
        }
3040
3041
0
      bfd_put_32 (output_bfd, tls_block_off,
3042
0
            got->contents + got_off + GOT_ENTRY_SIZE);
3043
0
          }
3044
        /* Dynamic resolved.  */
3045
0
        else
3046
0
          {
3047
      /* Dynamic relocate module id.  */
3048
0
      rela.r_info = ELF32_R_INFO (h->dynindx,
3049
0
                R_LARCH_TLS_DTPMOD32);
3050
0
      loongarch_elf_append_rela (output_bfd, srel, &rela);
3051
3052
      /* Dynamic relocate offset of block.  */
3053
0
      rela.r_offset += GOT_ENTRY_SIZE;
3054
0
      rela.r_info = ELF32_R_INFO (h->dynindx,
3055
0
                R_LARCH_TLS_DTPREL32);
3056
0
      loongarch_elf_append_rela (output_bfd, srel, &rela);
3057
0
          }
3058
0
      }
3059
0
    if (tls_type & GOT_TLS_IE)
3060
0
      {
3061
0
        rela.r_offset = sec_addr (got) + got_off + ie_off;
3062
0
        if (SYMBOL_REFERENCES_LOCAL (info, h))
3063
0
          {
3064
      /* Local sym, used in exec, set module id 1.  */
3065
0
      if (!bfd_link_executable (info))
3066
0
        {
3067
0
          rela.r_info = ELF32_R_INFO (0, R_LARCH_TLS_TPREL32);
3068
0
          rela.r_addend = tls_block_off;
3069
0
          loongarch_elf_append_rela (output_bfd, srel, &rela);
3070
0
        }
3071
3072
0
      bfd_put_32 (output_bfd, tls_block_off,
3073
0
            got->contents + got_off + ie_off);
3074
0
          }
3075
        /* Dynamic resolved.  */
3076
0
        else
3077
0
          {
3078
      /* Dynamic relocate offset of block.  */
3079
0
      rela.r_info = ELF32_R_INFO (h->dynindx,
3080
0
                R_LARCH_TLS_TPREL32);
3081
0
      rela.r_addend = 0;
3082
0
      loongarch_elf_append_rela (output_bfd, srel, &rela);
3083
0
          }
3084
0
      }
3085
0
        }
3086
3087
0
      relocation = (got_off & (~(bfd_vma)1)) + (is_ie ? ie_off : 0);
3088
0
    }
3089
0
    break;
3090
3091
  /* New reloc types.  */
3092
0
  case R_LARCH_B21:
3093
0
  case R_LARCH_B26:
3094
0
  case R_LARCH_B16:
3095
0
    unresolved_reloc = false;
3096
0
    if (is_undefweak)
3097
0
      {
3098
0
        relocation = 0;
3099
0
      }
3100
3101
0
    if (resolved_local)
3102
0
      {
3103
0
        relocation -= pc;
3104
0
        relocation += rel->r_addend;
3105
0
      }
3106
0
    else if (resolved_dynly)
3107
0
      {
3108
0
        BFD_ASSERT (h
3109
0
        && (h->plt.offset != MINUS_ONE
3110
0
            || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
3111
0
        && rel->r_addend == 0);
3112
0
        if (h && h->plt.offset == MINUS_ONE
3113
0
      && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
3114
0
    {
3115
0
      relocation -= pc;
3116
0
      relocation += rel->r_addend;
3117
0
    }
3118
0
        else
3119
0
    relocation = sec_addr (plt) + h->plt.offset - pc;
3120
0
      }
3121
3122
0
    break;
3123
3124
0
  case R_LARCH_ABS_HI20:
3125
0
  case R_LARCH_ABS_LO12:
3126
0
  case R_LARCH_ABS64_LO20:
3127
0
  case R_LARCH_ABS64_HI12:
3128
0
    BFD_ASSERT (!is_pic);
3129
3130
0
    if (is_undefweak)
3131
0
      {
3132
0
        BFD_ASSERT (resolved_dynly);
3133
0
        relocation = 0;
3134
0
        break;
3135
0
      }
3136
0
    else if (resolved_to_const || resolved_local)
3137
0
      {
3138
0
        relocation += rel->r_addend;
3139
0
      }
3140
0
    else if (resolved_dynly)
3141
0
      {
3142
0
        unresolved_reloc = false;
3143
0
        BFD_ASSERT ((plt && h && h->plt.offset != MINUS_ONE)
3144
0
        && rel->r_addend == 0);
3145
0
        relocation = sec_addr (plt) + h->plt.offset;
3146
0
      }
3147
3148
0
    break;
3149
3150
0
  case R_LARCH_PCREL20_S2:
3151
0
    unresolved_reloc = false;
3152
0
    if (h && h->plt.offset != MINUS_ONE)
3153
0
      relocation = sec_addr (plt) + h->plt.offset;
3154
0
    else
3155
0
      relocation += rel->r_addend;
3156
0
    relocation -= pc;
3157
0
    break;
3158
3159
0
  case R_LARCH_PCALA_HI20:
3160
0
    unresolved_reloc = false;
3161
0
    if (h && h->plt.offset != MINUS_ONE)
3162
0
      relocation = sec_addr (plt) + h->plt.offset;
3163
0
    else
3164
0
      relocation += rel->r_addend;
3165
3166
0
    RELOCATE_CALC_PC32_HI20 (relocation, pc);
3167
3168
0
    break;
3169
3170
0
  case R_LARCH_PCALA_LO12:
3171
    /* Not support if sym_addr in 2k page edge.
3172
       pcalau12i pc_hi20 (sym_addr)
3173
       ld.w/d pc_lo12 (sym_addr)
3174
       ld.w/d pc_lo12 (sym_addr + x)
3175
       ...
3176
       can not calc correct address
3177
       if sym_addr < 0x800 && sym_addr + x >= 0x800.  */
3178
3179
0
    if (h && h->plt.offset != MINUS_ONE)
3180
0
      relocation = sec_addr (plt) + h->plt.offset;
3181
0
    else
3182
0
      relocation += rel->r_addend;
3183
3184
    /* For 2G jump, generate pcalau12i, jirl.  */
3185
    /* If use jirl, turns to R_LARCH_B16.  */
3186
0
    uint32_t insn = bfd_get (32, input_bfd, contents + rel->r_offset);
3187
0
    if ((insn & 0x4c000000) == 0x4c000000)
3188
0
      {
3189
0
        relocation &= 0xfff;
3190
        /* Signed extend.  */
3191
0
        relocation = (relocation ^ 0x800) - 0x800;
3192
3193
0
        rel->r_info = ELF32_R_INFO (r_symndx, R_LARCH_B16);
3194
0
        howto = loongarch_elf_rtype_to_howto (input_bfd, R_LARCH_B16);
3195
0
      }
3196
0
    break;
3197
3198
0
  case R_LARCH_PCALA64_LO20:
3199
0
  case R_LARCH_PCALA64_HI12:
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_PC64_HI32 (relocation, pc);
3206
3207
0
    break;
3208
3209
0
  case R_LARCH_GOT_PC_HI20:
3210
0
  case R_LARCH_GOT_HI20:
3211
    /* Calc got offset.  */
3212
0
      {
3213
0
        unresolved_reloc = false;
3214
0
        BFD_ASSERT (rel->r_addend == 0);
3215
3216
0
        bfd_vma got_off = 0;
3217
0
        if (h != NULL)
3218
0
    {
3219
      /* GOT ref or ifunc.  */
3220
0
      BFD_ASSERT (h->got.offset != MINUS_ONE
3221
0
            || h->type == STT_GNU_IFUNC);
3222
3223
0
      got_off = h->got.offset  & (~(bfd_vma)1);
3224
      /* Hidden symbol not has got entry,
3225
       * only got.plt entry so it is (plt - got).  */
3226
0
      if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3227
0
        {
3228
0
          bfd_vma idx;
3229
0
          if (htab->elf.splt != NULL)
3230
0
      {
3231
0
        idx = (h->plt.offset - PLT_HEADER_SIZE)
3232
0
          / PLT_ENTRY_SIZE;
3233
0
        got_off = sec_addr (htab->elf.sgotplt)
3234
0
          + GOTPLT_HEADER_SIZE
3235
0
          + (idx * GOT_ENTRY_SIZE)
3236
0
          - sec_addr (htab->elf.sgot);
3237
0
      }
3238
0
          else
3239
0
      {
3240
0
        idx = h->plt.offset / PLT_ENTRY_SIZE;
3241
0
        got_off = sec_addr (htab->elf.sgotplt)
3242
0
          + (idx * GOT_ENTRY_SIZE)
3243
0
          - sec_addr (htab->elf.sgot);
3244
0
      }
3245
0
        }
3246
3247
0
      if ((h->got.offset & 1) == 0)
3248
0
        {
3249
          /* We need to generate a R_LARCH_RELATIVE reloc once
3250
           * in loongarch_elf_finish_dynamic_symbol or now,
3251
           * call finish_dyn && nopic
3252
           * or !call finish_dyn && pic.  */
3253
0
          if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
3254
0
                  bfd_link_pic (info),
3255
0
                  h)
3256
0
        && bfd_link_pic (info)
3257
0
        && SYMBOL_REFERENCES_LOCAL (info, h))
3258
0
      {
3259
0
        Elf_Internal_Rela rela;
3260
0
        rela.r_offset = sec_addr (got) + got_off;
3261
0
        rela.r_info = ELF32_R_INFO (0, R_LARCH_RELATIVE);
3262
0
        rela.r_addend = relocation;
3263
0
        loongarch_elf_append_rela (output_bfd,
3264
0
                 htab->elf.srelgot, &rela);
3265
0
      }
3266
0
          h->got.offset |= 1;
3267
0
          bfd_put_32 (output_bfd, relocation,
3268
0
          got->contents + got_off);
3269
0
        }
3270
0
    }
3271
0
        else
3272
0
    {
3273
0
      BFD_ASSERT (local_got_offsets
3274
0
            && local_got_offsets[r_symndx] != MINUS_ONE);
3275
3276
0
      got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
3277
0
      if ((local_got_offsets[r_symndx] & 1) == 0)
3278
0
        {
3279
0
          if (bfd_link_pic (info))
3280
0
      {
3281
0
        Elf_Internal_Rela rela;
3282
0
        rela.r_offset = sec_addr (got) + got_off;
3283
0
        rela.r_info = ELF32_R_INFO (0, R_LARCH_RELATIVE);
3284
0
        rela.r_addend = relocation;
3285
0
        loongarch_elf_append_rela (output_bfd,
3286
0
                 htab->elf.srelgot, &rela);
3287
0
      }
3288
0
          local_got_offsets[r_symndx] |= 1;
3289
0
        }
3290
0
      bfd_put_32 (output_bfd, relocation, got->contents + got_off);
3291
0
    }
3292
3293
0
        relocation = got_off + sec_addr (got);
3294
0
      }
3295
3296
0
    if (r_type == R_LARCH_GOT_PC_HI20)
3297
0
      RELOCATE_CALC_PC32_HI20 (relocation, pc);
3298
3299
0
    break;
3300
3301
0
  case R_LARCH_GOT_PC_LO12:
3302
0
  case R_LARCH_GOT64_PC_LO20:
3303
0
  case R_LARCH_GOT64_PC_HI12:
3304
0
  case R_LARCH_GOT_LO12:
3305
0
  case R_LARCH_GOT64_LO20:
3306
0
  case R_LARCH_GOT64_HI12:
3307
0
      {
3308
0
        unresolved_reloc = false;
3309
0
        bfd_vma got_off;
3310
0
        if (h)
3311
0
    got_off = h->got.offset & (~(bfd_vma)1);
3312
0
        else
3313
0
    got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
3314
3315
0
        if (h && h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3316
0
    {
3317
0
      bfd_vma idx;
3318
0
      if (htab->elf.splt != NULL)
3319
0
        idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
3320
0
      else
3321
0
        idx = h->plt.offset / PLT_ENTRY_SIZE;
3322
3323
0
      got_off = sec_addr (htab->elf.sgotplt)
3324
0
        + GOTPLT_HEADER_SIZE
3325
0
        + (idx * GOT_ENTRY_SIZE)
3326
0
        - sec_addr (htab->elf.sgot);
3327
0
    }
3328
3329
0
        relocation = got_off + sec_addr (got);
3330
0
      }
3331
3332
0
    if (r_type == R_LARCH_GOT64_PC_HI12
3333
0
        || r_type == R_LARCH_GOT64_PC_LO20)
3334
0
      RELOCATE_CALC_PC64_HI32 (relocation, pc);
3335
3336
0
    break;
3337
3338
0
  case R_LARCH_TLS_LE_HI20:
3339
0
  case R_LARCH_TLS_LE_LO12:
3340
0
  case R_LARCH_TLS_LE64_LO20:
3341
0
  case R_LARCH_TLS_LE64_HI12:
3342
0
    BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec);
3343
3344
0
    relocation -= elf_hash_table (info)->tls_sec->vma;
3345
0
    break;
3346
3347
  /* TLS IE LD/GD process separately is troublesome.
3348
     When a symbol is both ie and LD/GD, h->got.off |= 1
3349
     make only one type be relocated.  We must use
3350
     h->got.offset |= 1 and h->got.offset |= 2
3351
     diff IE and LD/GD.  And all (got_off & (~(bfd_vma)1))
3352
     (IE LD/GD and reusable GOT reloc) must change to
3353
     (got_off & (~(bfd_vma)3)), beause we use lowest 2 bits
3354
     as a tag.
3355
     Now, LD and GD is both GOT_TLS_GD type, LD seems to
3356
     can be omitted.  */
3357
0
  case R_LARCH_TLS_IE_PC_HI20:
3358
0
  case R_LARCH_TLS_IE_HI20:
3359
0
  case R_LARCH_TLS_LD_PC_HI20:
3360
0
  case R_LARCH_TLS_LD_HI20:
3361
0
  case R_LARCH_TLS_GD_PC_HI20:
3362
0
  case R_LARCH_TLS_GD_HI20:
3363
0
    BFD_ASSERT (rel->r_addend == 0);
3364
0
    unresolved_reloc = false;
3365
3366
0
    if (r_type == R_LARCH_TLS_IE_PC_HI20
3367
0
        || r_type == R_LARCH_TLS_IE_HI20)
3368
0
      is_ie = true;
3369
3370
0
    bfd_vma got_off = 0;
3371
0
    if (h != NULL)
3372
0
      {
3373
0
        got_off = h->got.offset;
3374
0
        h->got.offset |= 1;
3375
0
      }
3376
0
    else
3377
0
      {
3378
0
        got_off = local_got_offsets[r_symndx];
3379
0
        local_got_offsets[r_symndx] |= 1;
3380
0
      }
3381
3382
0
    BFD_ASSERT (got_off != MINUS_ONE);
3383
3384
0
    ie_off = 0;
3385
0
    tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3386
0
    if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
3387
0
      ie_off = 2 * GOT_ENTRY_SIZE;
3388
3389
0
    if ((got_off & 1) == 0)
3390
0
      {
3391
0
        Elf_Internal_Rela rela;
3392
0
        asection *relgot = htab->elf.srelgot;
3393
0
        bfd_vma tls_block_off = 0;
3394
3395
0
        if (SYMBOL_REFERENCES_LOCAL (info, h))
3396
0
    {
3397
0
      BFD_ASSERT (elf_hash_table (info)->tls_sec);
3398
0
      tls_block_off = relocation
3399
0
          - elf_hash_table (info)->tls_sec->vma;
3400
0
    }
3401
3402
0
        if (tls_type & GOT_TLS_GD)
3403
0
    {
3404
0
      rela.r_offset = sec_addr (got) + got_off;
3405
0
      rela.r_addend = 0;
3406
0
      if (SYMBOL_REFERENCES_LOCAL (info, h))
3407
0
        {
3408
          /* Local sym, used in exec, set module id 1.  */
3409
0
          if (bfd_link_executable (info))
3410
0
      bfd_put_32 (output_bfd, 1, got->contents + got_off);
3411
0
          else
3412
0
      {
3413
0
        rela.r_info = ELF32_R_INFO (0, R_LARCH_TLS_DTPMOD32);
3414
0
        loongarch_elf_append_rela (output_bfd, relgot, &rela);
3415
0
      }
3416
3417
0
          bfd_put_32 (output_bfd, tls_block_off,
3418
0
          got->contents + got_off + GOT_ENTRY_SIZE);
3419
0
        }
3420
      /* Dynamic resolved.  */
3421
0
      else
3422
0
        {
3423
          /* Dynamic relocate module id.  */
3424
0
          rela.r_info = ELF32_R_INFO (h->dynindx,
3425
0
              R_LARCH_TLS_DTPMOD32);
3426
0
          loongarch_elf_append_rela (output_bfd, relgot, &rela);
3427
3428
          /* Dynamic relocate offset of block.  */
3429
0
          rela.r_offset += GOT_ENTRY_SIZE;
3430
0
          rela.r_info = ELF32_R_INFO (h->dynindx,
3431
0
              R_LARCH_TLS_DTPREL32);
3432
0
          loongarch_elf_append_rela (output_bfd, relgot, &rela);
3433
0
        }
3434
0
    }
3435
0
        if (tls_type & GOT_TLS_IE)
3436
0
    {
3437
0
      rela.r_offset = sec_addr (got) + got_off + ie_off;
3438
0
      if (SYMBOL_REFERENCES_LOCAL (info, h))
3439
0
        {
3440
          /* Local sym, used in exec, set module id 1.  */
3441
0
          if (!bfd_link_executable (info))
3442
0
      {
3443
0
        rela.r_info = ELF32_R_INFO (0, R_LARCH_TLS_TPREL32);
3444
0
        rela.r_addend = tls_block_off;
3445
0
        loongarch_elf_append_rela (output_bfd, relgot, &rela);
3446
0
      }
3447
3448
0
          bfd_put_32 (output_bfd, tls_block_off,
3449
0
          got->contents + got_off + ie_off);
3450
0
        }
3451
      /* Dynamic resolved.  */
3452
0
      else
3453
0
        {
3454
          /* Dynamic relocate offset of block.  */
3455
0
          rela.r_info = ELF32_R_INFO (h->dynindx,
3456
0
              R_LARCH_TLS_TPREL32);
3457
0
          rela.r_addend = 0;
3458
0
          loongarch_elf_append_rela (output_bfd, relgot, &rela);
3459
0
        }
3460
0
    }
3461
0
      }
3462
0
    relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got)
3463
0
      + (is_ie ? ie_off : 0);
3464
3465
0
    if (r_type == R_LARCH_TLS_LD_PC_HI20
3466
0
        || r_type == R_LARCH_TLS_GD_PC_HI20
3467
0
        || r_type == R_LARCH_TLS_IE_PC_HI20)
3468
0
      RELOCATE_CALC_PC32_HI20 (relocation, pc);
3469
3470
0
    break;
3471
3472
0
  case R_LARCH_TLS_IE_PC_LO12:
3473
0
  case R_LARCH_TLS_IE64_PC_LO20:
3474
0
  case R_LARCH_TLS_IE64_PC_HI12:
3475
0
  case R_LARCH_TLS_IE_LO12:
3476
0
  case R_LARCH_TLS_IE64_LO20:
3477
0
  case R_LARCH_TLS_IE64_HI12:
3478
0
    unresolved_reloc = false;
3479
3480
0
    if (h)
3481
0
      relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)3));
3482
0
    else
3483
0
      relocation = sec_addr (got)
3484
0
        + (local_got_offsets[r_symndx] & (~(bfd_vma)3));
3485
3486
0
    tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3487
    /* Use both TLS_GD and TLS_IE.  */
3488
0
    if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
3489
0
      relocation += 2 * GOT_ENTRY_SIZE;
3490
3491
0
    if (r_type == R_LARCH_TLS_IE64_PC_LO20
3492
0
        || r_type == R_LARCH_TLS_IE64_PC_HI12)
3493
0
      RELOCATE_CALC_PC64_HI32 (relocation, pc);
3494
3495
0
    break;
3496
3497
0
  case R_LARCH_RELAX:
3498
0
  case R_LARCH_ALIGN:
3499
0
    r = bfd_reloc_continue;
3500
0
    unresolved_reloc = false;
3501
0
    break;
3502
3503
0
  default:
3504
0
    break;
3505
0
  }
3506
3507
0
      if (fatal)
3508
0
  break;
3509
3510
0
      do
3511
0
  {
3512
    /* 'unresolved_reloc' means we haven't done it yet.
3513
       We need help of dynamic linker to fix this memory location up.  */
3514
0
    if (!unresolved_reloc)
3515
0
      break;
3516
3517
0
    if (_bfd_elf_section_offset (output_bfd, info, input_section,
3518
0
               rel->r_offset) == MINUS_ONE)
3519
      /* WHY? May because it's invalid so skip checking.
3520
         But why dynamic reloc a invalid section?  */
3521
0
      break;
3522
3523
0
    if (input_section->output_section->flags & SEC_DEBUGGING)
3524
0
      {
3525
0
        fatal = (loongarch_reloc_is_fatal
3526
0
           (info, input_bfd, input_section, rel, howto,
3527
0
      bfd_reloc_dangerous, is_undefweak, name,
3528
0
      "Seems dynamic linker not process "
3529
0
      "sections 'SEC_DEBUGGING'."));
3530
0
      }
3531
0
    if (!is_dyn)
3532
0
      break;
3533
3534
0
    if ((info->flags & DF_TEXTREL) == 0)
3535
0
      if (input_section->output_section->flags & SEC_READONLY)
3536
0
        info->flags |= DF_TEXTREL;
3537
0
  }
3538
0
      while (0);
3539
3540
0
      if (fatal)
3541
0
  break;
3542
3543
0
      loongarch_record_one_reloc (input_bfd, input_section, r_type,
3544
0
          rel->r_offset, sym, h, rel->r_addend);
3545
3546
0
      if (r != bfd_reloc_continue)
3547
0
  r = perform_relocation (rel, input_section, howto, relocation,
3548
0
        input_bfd, contents);
3549
3550
0
      switch (r)
3551
0
  {
3552
0
  case bfd_reloc_dangerous:
3553
0
  case bfd_reloc_continue:
3554
0
  case bfd_reloc_ok:
3555
0
    continue;
3556
3557
0
  case bfd_reloc_overflow:
3558
    /* Overflow value can't be filled in.  */
3559
0
    loongarch_dump_reloc_record (info->callbacks->info);
3560
0
    info->callbacks->reloc_overflow
3561
0
      (info, h ? &h->root : NULL, name, howto->name, rel->r_addend,
3562
0
       input_bfd, input_section, rel->r_offset);
3563
0
    break;
3564
3565
0
  case bfd_reloc_outofrange:
3566
    /* Stack state incorrect.  */
3567
0
    loongarch_dump_reloc_record (info->callbacks->info);
3568
0
    info->callbacks->info
3569
0
      ("%X%H: Internal stack state is incorrect.\n"
3570
0
       "Want to push to full stack or pop from empty stack?\n",
3571
0
       input_bfd, input_section, rel->r_offset);
3572
0
    break;
3573
3574
0
  case bfd_reloc_notsupported:
3575
0
    info->callbacks->info ("%X%H: Unknown relocation type.\n", input_bfd,
3576
0
         input_section, rel->r_offset);
3577
0
    break;
3578
3579
0
  default:
3580
0
    info->callbacks->info ("%X%H: Internal: unknown error.\n", input_bfd,
3581
0
         input_section, rel->r_offset);
3582
0
    break;
3583
0
  }
3584
3585
0
      fatal = true;
3586
0
    }
3587
3588
0
  return !fatal;
3589
0
}
3590
3591
static bool
3592
loongarch_relax_delete_bytes (bfd *abfd,
3593
        asection *sec,
3594
        bfd_vma addr,
3595
        size_t count,
3596
        struct bfd_link_info *link_info)
3597
0
{
3598
0
  unsigned int i, symcount;
3599
0
  bfd_vma toaddr = sec->size;
3600
0
  struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd);
3601
0
  Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
3602
0
  unsigned int sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
3603
0
  struct bfd_elf_section_data *data = elf_section_data (sec);
3604
0
  bfd_byte *contents = data->this_hdr.contents;
3605
3606
  /* Actually delete the bytes.  */
3607
0
  sec->size -= count;
3608
0
  memmove (contents + addr, contents + addr + count, toaddr - addr - count);
3609
3610
  /* Adjust the location of all of the relocs.  Note that we need not
3611
     adjust the addends, since all PC-relative references must be against
3612
     symbols, which we will adjust below.  */
3613
0
  for (i = 0; i < sec->reloc_count; i++)
3614
0
    if (data->relocs[i].r_offset > addr && data->relocs[i].r_offset < toaddr)
3615
0
      data->relocs[i].r_offset -= count;
3616
3617
  /* Adjust the local symbols defined in this section.  */
3618
0
  for (i = 0; i < symtab_hdr->sh_info; i++)
3619
0
    {
3620
0
      Elf_Internal_Sym *sym = (Elf_Internal_Sym *) symtab_hdr->contents + i;
3621
0
      if (sym->st_shndx == sec_shndx)
3622
0
  {
3623
    /* If the symbol is in the range of memory we just moved, we
3624
       have to adjust its value.  */
3625
0
    if (sym->st_value > addr && sym->st_value <= toaddr)
3626
0
      sym->st_value -= count;
3627
3628
    /* If the symbol *spans* the bytes we just deleted (i.e. its
3629
       *end* is in the moved bytes but its *start* isn't), then we
3630
       must adjust its size.
3631
3632
       This test needs to use the original value of st_value, otherwise
3633
       we might accidentally decrease size when deleting bytes right
3634
       before the symbol.  But since deleted relocs can't span across
3635
       symbols, we can't have both a st_value and a st_size decrease,
3636
       so it is simpler to just use an else.  */
3637
0
    else if (sym->st_value <= addr
3638
0
       && sym->st_value + sym->st_size > addr
3639
0
       && sym->st_value + sym->st_size <= toaddr)
3640
0
      sym->st_size -= count;
3641
0
  }
3642
0
    }
3643
3644
  /* Now adjust the global symbols defined in this section.  */
3645
0
  symcount = ((symtab_hdr->sh_size / sizeof (Elf32_External_Sym))
3646
0
        - symtab_hdr->sh_info);
3647
3648
0
  for (i = 0; i < symcount; i++)
3649
0
    {
3650
0
      struct elf_link_hash_entry *sym_hash = sym_hashes[i];
3651
3652
      /* The '--wrap SYMBOL' option is causing a pain when the object file,
3653
   containing the definition of __wrap_SYMBOL, includes a direct
3654
   call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
3655
   the same symbol (which is __wrap_SYMBOL), but still exist as two
3656
   different symbols in 'sym_hashes', we don't want to adjust
3657
   the global symbol __wrap_SYMBOL twice.
3658
3659
   The same problem occurs with symbols that are versioned_hidden, as
3660
   foo becomes an alias for foo@BAR, and hence they need the same
3661
   treatment.  */
3662
0
      if (link_info->wrap_hash != NULL
3663
0
    || sym_hash->versioned != unversioned)
3664
0
  {
3665
0
    struct elf_link_hash_entry **cur_sym_hashes;
3666
3667
    /* Loop only over the symbols which have already been checked.  */
3668
0
    for (cur_sym_hashes = sym_hashes; cur_sym_hashes < &sym_hashes[i];
3669
0
         cur_sym_hashes++)
3670
0
      {
3671
        /* If the current symbol is identical to 'sym_hash', that means
3672
     the symbol was already adjusted (or at least checked).  */
3673
0
        if (*cur_sym_hashes == sym_hash)
3674
0
    break;
3675
0
      }
3676
    /* Don't adjust the symbol again.  */
3677
0
    if (cur_sym_hashes < &sym_hashes[i])
3678
0
      continue;
3679
0
  }
3680
3681
0
      if ((sym_hash->root.type == bfd_link_hash_defined
3682
0
     || sym_hash->root.type == bfd_link_hash_defweak)
3683
0
    && sym_hash->root.u.def.section == sec)
3684
0
  {
3685
    /* As above, adjust the value if needed.  */
3686
0
    if (sym_hash->root.u.def.value > addr
3687
0
        && sym_hash->root.u.def.value <= toaddr)
3688
0
      sym_hash->root.u.def.value -= count;
3689
3690
    /* As above, adjust the size if needed.  */
3691
0
    else if (sym_hash->root.u.def.value <= addr
3692
0
       && sym_hash->root.u.def.value + sym_hash->size > addr
3693
0
       && sym_hash->root.u.def.value + sym_hash->size <= toaddr)
3694
0
      sym_hash->size -= count;
3695
0
  }
3696
0
    }
3697
3698
0
  return true;
3699
0
}
3700
3701
/* Relax pcalau12i,addi.d => pcaddi.  */
3702
static bool
3703
loongarch_relax_pcala_addi (bfd *abfd, asection *sec,
3704
           Elf_Internal_Rela *rel_hi, bfd_vma symval)
3705
0
{
3706
0
  bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
3707
0
  Elf_Internal_Rela *rel_lo = rel_hi + 2;
3708
0
  uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
3709
0
  uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset);
3710
0
  uint32_t rd = pca & 0x1f;
3711
0
  bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
3712
0
  const uint32_t addi_d = 0x02c00000;
3713
0
  const uint32_t pcaddi = 0x18000000;
3714
3715
  /* Is pcalau12i + addi.d insns?  */
3716
0
  if ((ELF32_R_TYPE (rel_lo->r_info) != R_LARCH_PCALA_LO12)
3717
0
      || (ELF32_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
3718
0
      || (ELF32_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
3719
0
      || (rel_hi->r_offset + 4 != rel_lo->r_offset)
3720
0
      || ((add & addi_d) != addi_d)
3721
      /* Is pcalau12i $rd + addi.d $rd,$rd?  */
3722
0
      || ((add & 0x1f) != rd)
3723
0
      || (((add >> 5) & 0x1f) != rd)
3724
      /* Can be relaxed to pcaddi?  */
3725
0
      || (symval & 0x3) /* 4 bytes align.  */
3726
0
      || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000)
3727
0
      || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc))
3728
0
    return false;
3729
3730
0
  pca = pcaddi | rd;
3731
0
  bfd_put (32, abfd, pca, contents + rel_hi->r_offset);
3732
3733
  /* Adjust relocations.  */
3734
0
  rel_hi->r_info = ELF32_R_INFO (ELF32_R_SYM (rel_hi->r_info),
3735
0
         R_LARCH_PCREL20_S2);
3736
0
  rel_lo->r_info = ELF32_R_INFO (ELF32_R_SYM (rel_hi->r_info),
3737
0
         R_LARCH_DELETE);
3738
3739
0
  return true;
3740
0
}
3741
3742
/* Relax pcalau12i,ld.d => pcalau12i,addi.d.  */
3743
static bool
3744
loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
3745
    Elf_Internal_Rela *rel_hi)
3746
0
{
3747
0
  bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
3748
0
  Elf_Internal_Rela *rel_lo = rel_hi + 2;
3749
0
  uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
3750
0
  uint32_t ld = bfd_get (32, abfd, contents + rel_lo->r_offset);
3751
0
  uint32_t rd = pca & 0x1f;
3752
0
  const uint32_t ld_d = 0x28c00000;
3753
0
  uint32_t addi_d = 0x02c00000;
3754
3755
0
  if ((ELF32_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12)
3756
0
      || (ELF32_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
3757
0
      || (ELF32_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
3758
0
      || (rel_hi->r_offset + 4 != rel_lo->r_offset)
3759
0
      || ((ld & 0x1f) != rd)
3760
0
      || (((ld >> 5) & 0x1f) != rd)
3761
0
      || ((ld & ld_d) != ld_d))
3762
0
    return false;
3763
3764
0
  addi_d = addi_d | (rd << 5) | rd;
3765
0
  bfd_put (32, abfd, addi_d, contents + rel_lo->r_offset);
3766
3767
0
  rel_hi->r_info = ELF32_R_INFO (ELF32_R_SYM (rel_hi->r_info),
3768
0
         R_LARCH_PCALA_HI20);
3769
0
  rel_lo->r_info = ELF32_R_INFO (ELF32_R_SYM (rel_lo->r_info),
3770
0
         R_LARCH_PCALA_LO12);
3771
0
  return true;
3772
0
}
3773
3774
/* Called by after_allocation to set the information of data segment
3775
   before relaxing.  */
3776
3777
void
3778
bfd_elf32_loongarch_set_data_segment_info (struct bfd_link_info *info,
3779
             int *data_segment_phase)
3780
0
{
3781
0
  struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
3782
0
  htab->data_segment_phase = data_segment_phase;
3783
0
}
3784
3785
/* Implement R_LARCH_ALIGN by deleting excess alignment NOPs.
3786
   Once we've handled an R_LARCH_ALIGN, we can't relax anything else.  */
3787
static bool
3788
loongarch_relax_align (bfd *abfd, asection *sec,
3789
      asection *sym_sec,
3790
      struct bfd_link_info *link_info,
3791
      Elf_Internal_Rela *rel,
3792
      bfd_vma symval)
3793
0
{
3794
0
  bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
3795
0
  bfd_vma alignment = 1, pos;
3796
0
  while (alignment <= rel->r_addend)
3797
0
    alignment *= 2;
3798
3799
0
  symval -= rel->r_addend;
3800
0
  bfd_vma aligned_addr = ((symval - 1) & ~(alignment - 1)) + alignment;
3801
0
  bfd_vma nop_bytes = aligned_addr - symval;
3802
3803
  /* Once we've handled an R_LARCH_ALIGN, we can't relax anything else.  */
3804
0
  sec->sec_flg0 = true;
3805
3806
  /* Make sure there are enough NOPs to actually achieve the alignment.  */
3807
0
  if (rel->r_addend < nop_bytes)
3808
0
    {
3809
0
      _bfd_error_handler
3810
0
  (_("%pB(%pA+%#" PRIx64 "): %" PRId64 " bytes required for alignment "
3811
0
     "to %" PRId64 "-byte boundary, but only %" PRId64 " present"),
3812
0
   abfd, sym_sec, (uint64_t) rel->r_offset,
3813
0
   (int64_t) nop_bytes, (int64_t) alignment, (int64_t) rel->r_addend);
3814
0
      bfd_set_error (bfd_error_bad_value);
3815
0
      return false;
3816
0
    }
3817
3818
  /* Delete the reloc.  */
3819
0
  rel->r_info = ELF32_R_INFO (0, R_LARCH_NONE);
3820
3821
  /* If the number of NOPs is already correct, there's nothing to do.  */
3822
0
  if (nop_bytes == rel->r_addend)
3823
0
    return true;
3824
3825
  /* Write as many LOONGARCH NOPs as we need.  */
3826
0
  for (pos = 0; pos < (nop_bytes & -4); pos += 4)
3827
0
    bfd_putl32 (LARCH_NOP, contents + rel->r_offset + pos);
3828
3829
  /* Delete the excess NOPs.  */
3830
0
  return loongarch_relax_delete_bytes (abfd, sec, rel->r_offset + nop_bytes,
3831
0
           rel->r_addend - nop_bytes, link_info);
3832
0
}
3833
3834
static bool
3835
loongarch_elf_relax_section (bfd *abfd, asection *sec,
3836
             struct bfd_link_info *info,
3837
             bool *again)
3838
0
{
3839
0
  struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
3840
0
  Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd);
3841
0
  struct bfd_elf_section_data *data = elf_section_data (sec);
3842
0
  Elf_Internal_Rela *relocs;
3843
0
  *again = false;
3844
3845
0
  if (bfd_link_relocatable (info)
3846
0
      || sec->sec_flg0
3847
0
      || (sec->flags & SEC_RELOC) == 0
3848
0
      || sec->reloc_count == 0
3849
0
      || elf_seg_map (info->output_bfd) == NULL
3850
0
      || (info->disable_target_specific_optimizations
3851
0
    && info->relax_pass == 0)
3852
      /* The exp_seg_relro_adjust is enum phase_enum (0x4),
3853
   and defined in ld/ldexp.h.  */
3854
0
      || *(htab->data_segment_phase) == 4)
3855
0
    return true;
3856
3857
0
  if (data->relocs)
3858
0
    relocs = data->relocs;
3859
0
  else if (!(relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
3860
0
             info->keep_memory)))
3861
0
    return true;
3862
3863
0
  if (!data->this_hdr.contents
3864
0
      && !bfd_malloc_and_get_section (abfd, sec, &data->this_hdr.contents))
3865
0
    return true;
3866
3867
0
  if (symtab_hdr->sh_info != 0
3868
0
      && !symtab_hdr->contents
3869
0
      && !(symtab_hdr->contents =
3870
0
     (unsigned char *) bfd_elf_get_elf_syms (abfd, symtab_hdr,
3871
0
               symtab_hdr->sh_info,
3872
0
               0, NULL, NULL, NULL)))
3873
0
    return true;
3874
3875
0
      data->relocs = relocs;
3876
3877
0
  for (unsigned int i = 0; i < sec->reloc_count; i++)
3878
0
    {
3879
0
      Elf_Internal_Rela *rel = relocs + i;
3880
0
      asection *sym_sec;
3881
0
      bfd_vma symval;
3882
0
      unsigned long r_symndx = ELF32_R_SYM (rel->r_info);
3883
0
      bool local_got = false;
3884
0
      char symtype;
3885
0
      struct elf_link_hash_entry *h = NULL;
3886
3887
0
      if (r_symndx < symtab_hdr->sh_info)
3888
0
  {
3889
0
    Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents
3890
0
            + r_symndx;
3891
0
    if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
3892
0
      continue;
3893
3894
0
    if (sym->st_shndx == SHN_UNDEF)
3895
0
      {
3896
0
        sym_sec = sec;
3897
0
        symval = rel->r_offset;
3898
0
      }
3899
0
    else
3900
0
      {
3901
0
        sym_sec = elf_elfsections (abfd)[sym->st_shndx]->bfd_section;
3902
0
        symval = sym->st_value;
3903
0
      }
3904
0
    symtype = ELF_ST_TYPE (sym->st_info);
3905
0
  }
3906
0
      else
3907
0
  {
3908
0
    r_symndx = ELF32_R_SYM (rel->r_info) - symtab_hdr->sh_info;
3909
0
    h = elf_sym_hashes (abfd)[r_symndx];
3910
3911
0
    while (h->root.type == bfd_link_hash_indirect
3912
0
     || h->root.type == bfd_link_hash_warning)
3913
0
      h = (struct elf_link_hash_entry *) h->root.u.i.link;
3914
3915
    /* Disable the relaxation for ifunc.  */
3916
0
    if (h != NULL && h->type == STT_GNU_IFUNC)
3917
0
      continue;
3918
3919
0
    if ((h->root.type == bfd_link_hash_defined
3920
0
        || h->root.type == bfd_link_hash_defweak)
3921
0
       && h->root.u.def.section != NULL
3922
0
       && h->root.u.def.section->output_section != NULL)
3923
0
      {
3924
0
        symval = h->root.u.def.value;
3925
0
        sym_sec = h->root.u.def.section;
3926
0
      }
3927
0
    else
3928
0
      continue;
3929
3930
0
    if (h && bfd_link_executable (info)
3931
0
        && SYMBOL_REFERENCES_LOCAL (info, h))
3932
0
      local_got = true;
3933
0
    symtype = h->type;
3934
0
  }
3935
3936
0
      if (sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE
3937
0
     && (sym_sec->flags & SEC_MERGE))
3938
0
  {
3939
0
     if (symtype == STT_SECTION)
3940
0
       symval += rel->r_addend;
3941
3942
0
     symval = _bfd_merged_section_offset (abfd, &sym_sec,
3943
0
        elf_section_data (sym_sec)->sec_info,
3944
0
        symval);
3945
3946
0
     if (symtype != STT_SECTION)
3947
0
       symval += rel->r_addend;
3948
0
  }
3949
0
      else
3950
0
  symval += rel->r_addend;
3951
3952
0
      symval += sec_addr (sym_sec);
3953
3954
0
      switch (ELF32_R_TYPE (rel->r_info))
3955
0
  {
3956
0
  case R_LARCH_ALIGN:
3957
0
    if (2 == info->relax_pass)
3958
0
      loongarch_relax_align (abfd, sec, sym_sec, info, rel, symval);
3959
0
    break;
3960
0
  case R_LARCH_DELETE:
3961
0
    if (info->relax_pass == 1)
3962
0
      {
3963
0
        loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, info);
3964
0
        rel->r_info = ELF32_R_INFO (0, R_LARCH_NONE);
3965
0
      }
3966
0
    break;
3967
0
  case R_LARCH_PCALA_HI20:
3968
0
    if (info->relax_pass == 0)
3969
0
      {
3970
0
        if (i + 4 > sec->reloc_count)
3971
0
    break;
3972
0
        loongarch_relax_pcala_addi (abfd, sec, rel, symval);
3973
0
      }
3974
0
    break;
3975
0
  case R_LARCH_GOT_PC_HI20:
3976
0
    if (local_got)
3977
0
      {
3978
0
        if (i + 4 > sec->reloc_count)
3979
0
    break;
3980
0
        if (loongarch_relax_pcala_ld (abfd, sec, rel))
3981
0
    {
3982
0
      loongarch_relax_pcala_addi (abfd, sec, rel, symval);
3983
0
    }
3984
0
      }
3985
0
    break;
3986
0
  default:
3987
0
    break;
3988
0
  }
3989
0
    }
3990
3991
0
  return true;
3992
0
}
3993
3994
/* Finish up dynamic symbol handling.  We set the contents of various
3995
   dynamic sections here.  */
3996
3997
static bool
3998
loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
3999
             struct bfd_link_info *info,
4000
             struct elf_link_hash_entry *h,
4001
             Elf_Internal_Sym *sym)
4002
0
{
4003
0
  struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4004
0
  const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
4005
0
  asection *rela_dyn = bfd_get_section_by_name (output_bfd, ".rela.dyn");
4006
0
  struct bfd_link_order *lo = NULL;
4007
0
  Elf_Internal_Rela *slot = NULL, *last_slot = NULL;
4008
4009
0
  if (rela_dyn)
4010
0
    lo = rela_dyn->map_head.link_order;
4011
4012
0
  if (h->plt.offset != MINUS_ONE)
4013
0
    {
4014
0
      size_t i, plt_idx;
4015
0
      asection *plt, *gotplt, *relplt;
4016
0
      bfd_vma got_address;
4017
0
      uint32_t plt_entry[PLT_ENTRY_INSNS];
4018
0
      bfd_byte *loc;
4019
0
      Elf_Internal_Rela rela;
4020
0
      asection *rela_sec = NULL;
4021
4022
0
      if (htab->elf.splt)
4023
0
  {
4024
0
    BFD_ASSERT ((h->type == STT_GNU_IFUNC
4025
0
           && SYMBOL_REFERENCES_LOCAL (info, h))
4026
0
          || h->dynindx != -1);
4027
4028
0
    plt = htab->elf.splt;
4029
0
    gotplt = htab->elf.sgotplt;
4030
0
    if (h->type == STT_GNU_IFUNC && SYMBOL_REFERENCES_LOCAL (info, h))
4031
0
      relplt = htab->elf.srelgot;
4032
0
    else
4033
0
      relplt = htab->elf.srelplt;
4034
0
    plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
4035
0
    got_address =
4036
0
      sec_addr (gotplt) + GOTPLT_HEADER_SIZE + plt_idx * GOT_ENTRY_SIZE;
4037
0
  }
4038
0
      else /* if (htab->elf.iplt) */
4039
0
  {
4040
0
    BFD_ASSERT (h->type == STT_GNU_IFUNC
4041
0
          && SYMBOL_REFERENCES_LOCAL (info, h));
4042
4043
0
    plt = htab->elf.iplt;
4044
0
    gotplt = htab->elf.igotplt;
4045
0
    relplt = htab->elf.irelplt;
4046
0
    plt_idx = h->plt.offset / PLT_ENTRY_SIZE;
4047
0
    got_address = sec_addr (gotplt) + plt_idx * GOT_ENTRY_SIZE;
4048
0
  }
4049
4050
      /* Find out where the .plt entry should go.  */
4051
0
      loc = plt->contents + h->plt.offset;
4052
4053
      /* Fill in the PLT entry itself.  */
4054
0
      if (!loongarch_make_plt_entry (got_address,
4055
0
             sec_addr (plt) + h->plt.offset,
4056
0
             plt_entry))
4057
0
  return false;
4058
4059
0
      for (i = 0; i < PLT_ENTRY_INSNS; i++)
4060
0
  bfd_put_32 (output_bfd, plt_entry[i], loc + 4 * i);
4061
4062
      /* Fill in the initial value of the got.plt entry.  */
4063
0
      loc = gotplt->contents + (got_address - sec_addr (gotplt));
4064
0
      bfd_put_32 (output_bfd, sec_addr (plt), loc);
4065
4066
0
      rela.r_offset = got_address;
4067
4068
      /* TRUE if this is a PLT reference to a local IFUNC.  */
4069
0
      if (PLT_LOCAL_IFUNC_P (info, h)
4070
0
    && (relplt == htab->elf.srelgot
4071
0
        || relplt == htab->elf.irelplt))
4072
0
  {
4073
0
    rela.r_info = ELF32_R_INFO (0, R_LARCH_IRELATIVE);
4074
0
    rela.r_addend = (h->root.u.def.value
4075
0
             + h->root.u.def.section->output_section->vma
4076
0
             + h->root.u.def.section->output_offset);
4077
4078
    /* Find the space after dyn sort.  */
4079
0
    while (slot == last_slot || slot->r_offset != 0)
4080
0
      {
4081
0
        if (slot != last_slot)
4082
0
    {
4083
0
      slot++;
4084
0
      continue;
4085
0
    }
4086
4087
0
        BFD_ASSERT (lo != NULL);
4088
0
        rela_sec = lo->u.indirect.section;
4089
0
        lo = lo->next;
4090
4091
0
        slot = (Elf_Internal_Rela *)rela_sec->contents;
4092
0
        last_slot = (Elf_Internal_Rela *)(rela_sec->contents +
4093
0
            rela_sec->size);
4094
0
      }
4095
4096
0
    bed->s->swap_reloca_out (output_bfd, &rela, (bfd_byte *)slot);
4097
0
    rela_sec->reloc_count++;
4098
0
  }
4099
0
      else
4100
0
  {
4101
    /* Fill in the entry in the rela.plt section.  */
4102
0
    rela.r_info = ELF32_R_INFO (h->dynindx, R_LARCH_JUMP_SLOT);
4103
0
    rela.r_addend = 0;
4104
0
    loc = relplt->contents + plt_idx * sizeof (Elf32_External_Rela);
4105
0
    bed->s->swap_reloca_out (output_bfd, &rela, loc);
4106
0
  }
4107
4108
0
      if (!h->def_regular)
4109
0
  {
4110
    /* Mark the symbol as undefined, rather than as defined in
4111
       the .plt section.  Leave the value alone.  */
4112
0
    sym->st_shndx = SHN_UNDEF;
4113
    /* If the symbol is weak, we do need to clear the value.
4114
       Otherwise, the PLT entry would provide a definition for
4115
       the symbol even if the symbol wasn't defined anywhere,
4116
       and so the symbol would never be NULL.  */
4117
0
    if (!h->ref_regular_nonweak)
4118
0
      sym->st_value = 0;
4119
0
  }
4120
0
    }
4121
4122
0
  if (h->got.offset != MINUS_ONE
4123
      /* TLS got entry have been handled in elf_relocate_section.  */
4124
0
      && !(loongarch_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE))
4125
      /* Have allocated got entry but not allocated rela before.  */
4126
0
      && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
4127
0
    {
4128
0
      asection *sgot, *srela;
4129
0
      Elf_Internal_Rela rela;
4130
0
      bfd_vma off = h->got.offset & ~(bfd_vma)1;
4131
4132
      /* This symbol has an entry in the GOT.  Set it up.  */
4133
0
      sgot = htab->elf.sgot;
4134
0
      srela = htab->elf.srelgot;
4135
0
      BFD_ASSERT (sgot && srela);
4136
4137
0
      rela.r_offset = sec_addr (sgot) + off;
4138
4139
0
      if (h->def_regular
4140
0
    && h->type == STT_GNU_IFUNC)
4141
0
  {
4142
0
    if(h->plt.offset == MINUS_ONE)
4143
0
      {
4144
0
        if (htab->elf.splt == NULL)
4145
0
    srela = htab->elf.irelplt;
4146
4147
0
        if (SYMBOL_REFERENCES_LOCAL (info, h))
4148
0
    {
4149
0
      asection *sec = h->root.u.def.section;
4150
0
      rela.r_info = ELF32_R_INFO (0, R_LARCH_IRELATIVE);
4151
0
      rela.r_addend = h->root.u.def.value + sec->output_section->vma
4152
0
        + sec->output_offset;
4153
0
      bfd_put_32 (output_bfd, 0, sgot->contents + off);
4154
0
    }
4155
0
        else
4156
0
    {
4157
0
      BFD_ASSERT (h->dynindx != -1);
4158
0
      rela.r_info = ELF32_R_INFO (h->dynindx, R_LARCH_32);
4159
0
      rela.r_addend = 0;
4160
0
      bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + off);
4161
0
    }
4162
0
      }
4163
0
    else if(bfd_link_pic (info))
4164
0
      {
4165
0
        rela.r_info = ELF32_R_INFO (h->dynindx, R_LARCH_32);
4166
0
        rela.r_addend = 0;
4167
0
        bfd_put_32 (output_bfd, rela.r_addend, sgot->contents + off);
4168
0
      }
4169
0
    else
4170
0
      {
4171
0
        asection *plt;
4172
        /* For non-shared object, we can't use .got.plt, which
4173
     contains the real function address if we need pointer
4174
     equality.  We load the GOT entry with the PLT entry.  */
4175
0
        plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
4176
0
        bfd_put_32 (output_bfd,
4177
0
        (plt->output_section->vma
4178
0
         + plt->output_offset
4179
0
         + h->plt.offset),
4180
0
        sgot->contents + off);
4181
0
        return true;
4182
0
      }
4183
0
  }
4184
0
      else if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h))
4185
0
  {
4186
0
    asection *sec = h->root.u.def.section;
4187
0
    rela.r_info = ELF32_R_INFO (0, R_LARCH_RELATIVE);
4188
0
    rela.r_addend = (h->root.u.def.value + sec->output_section->vma
4189
0
         + sec->output_offset);
4190
0
  }
4191
0
      else
4192
0
  {
4193
0
    BFD_ASSERT (h->dynindx != -1);
4194
0
    rela.r_info = ELF32_R_INFO (h->dynindx, R_LARCH_32);
4195
0
    rela.r_addend = 0;
4196
0
  }
4197
4198
0
      loongarch_elf_append_rela (output_bfd, srela, &rela);
4199
0
    }
4200
4201
  /* Mark some specially defined symbols as absolute.  */
4202
0
  if (h == htab->elf.hdynamic || h == htab->elf.hgot || h == htab->elf.hplt)
4203
0
    sym->st_shndx = SHN_ABS;
4204
4205
0
  return true;
4206
0
}
4207
4208
/* Finish up the dynamic sections.  */
4209
4210
static bool
4211
loongarch_finish_dyn (bfd *output_bfd, struct bfd_link_info *info, bfd *dynobj,
4212
          asection *sdyn)
4213
0
{
4214
0
  struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4215
0
  const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
4216
0
  size_t dynsize = bed->s->sizeof_dyn, skipped_size = 0;
4217
0
  bfd_byte *dyncon, *dynconend;
4218
4219
0
  dynconend = sdyn->contents + sdyn->size;
4220
0
  for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize)
4221
0
    {
4222
0
      Elf_Internal_Dyn dyn;
4223
0
      asection *s;
4224
0
      int skipped = 0;
4225
4226
0
      bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
4227
4228
0
      switch (dyn.d_tag)
4229
0
  {
4230
0
  case DT_PLTGOT:
4231
0
    s = htab->elf.sgotplt;
4232
0
    dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4233
0
    break;
4234
0
  case DT_JMPREL:
4235
0
    s = htab->elf.srelplt;
4236
0
    dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4237
0
    break;
4238
0
  case DT_PLTRELSZ:
4239
0
    s = htab->elf.srelplt;
4240
0
    dyn.d_un.d_val = s->size;
4241
0
    break;
4242
0
  case DT_TEXTREL:
4243
0
    if ((info->flags & DF_TEXTREL) == 0)
4244
0
      skipped = 1;
4245
0
    break;
4246
0
  case DT_FLAGS:
4247
0
    if ((info->flags & DF_TEXTREL) == 0)
4248
0
      dyn.d_un.d_val &= ~DF_TEXTREL;
4249
0
    break;
4250
0
  }
4251
0
      if (skipped)
4252
0
  skipped_size += dynsize;
4253
0
      else
4254
0
  bed->s->swap_dyn_out (output_bfd, &dyn, dyncon - skipped_size);
4255
0
    }
4256
  /* Wipe out any trailing entries if we shifted down a dynamic tag.  */
4257
0
  memset (dyncon - skipped_size, 0, skipped_size);
4258
0
  return true;
4259
0
}
4260
4261
/* Finish up local dynamic symbol handling.  We set the contents of
4262
   various dynamic sections here.  */
4263
4264
static bool
4265
elf32_loongarch_finish_local_dynamic_symbol (void **slot, void *inf)
4266
0
{
4267
0
  struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
4268
0
  struct bfd_link_info *info = (struct bfd_link_info *) inf;
4269
4270
0
  return loongarch_elf_finish_dynamic_symbol (info->output_bfd, info, h, NULL);
4271
0
}
4272
4273
static bool
4274
loongarch_elf_finish_dynamic_sections (bfd *output_bfd,
4275
               struct bfd_link_info *info)
4276
0
{
4277
0
  bfd *dynobj;
4278
0
  asection *sdyn, *plt, *gotplt = NULL;
4279
0
  struct loongarch_elf_link_hash_table *htab;
4280
4281
0
  htab = loongarch_elf_hash_table (info);
4282
0
  BFD_ASSERT (htab);
4283
0
  dynobj = htab->elf.dynobj;
4284
0
  sdyn = bfd_get_linker_section (dynobj, ".dynamic");
4285
4286
0
  if (elf_hash_table (info)->dynamic_sections_created)
4287
0
    {
4288
0
      BFD_ASSERT (htab->elf.splt && sdyn);
4289
4290
0
      if (!loongarch_finish_dyn (output_bfd, info, dynobj, sdyn))
4291
0
  return false;
4292
0
    }
4293
4294
0
  plt = htab->elf.splt;
4295
0
  gotplt = htab->elf.sgotplt;
4296
4297
0
  if (plt && 0 < plt->size)
4298
0
    {
4299
0
      size_t i;
4300
0
      uint32_t plt_header[PLT_HEADER_INSNS];
4301
0
      if (!loongarch_make_plt_header (sec_addr (gotplt), sec_addr (plt),
4302
0
              plt_header))
4303
0
  return false;
4304
4305
0
      for (i = 0; i < PLT_HEADER_INSNS; i++)
4306
0
  bfd_put_32 (output_bfd, plt_header[i], plt->contents + 4 * i);
4307
4308
0
      elf_section_data (plt->output_section)->this_hdr.sh_entsize =
4309
0
  PLT_ENTRY_SIZE;
4310
0
    }
4311
4312
0
  if (htab->elf.sgotplt)
4313
0
    {
4314
0
      asection *output_section = htab->elf.sgotplt->output_section;
4315
4316
0
      if (bfd_is_abs_section (output_section))
4317
0
  {
4318
0
    _bfd_error_handler (_("discarded output section: `%pA'"),
4319
0
            htab->elf.sgotplt);
4320
0
    return false;
4321
0
  }
4322
4323
0
      if (0 < htab->elf.sgotplt->size)
4324
0
  {
4325
    /* Write the first two entries in .got.plt, needed for the dynamic
4326
       linker.  */
4327
0
    bfd_put_32 (output_bfd, MINUS_ONE, htab->elf.sgotplt->contents);
4328
4329
0
    bfd_put_32 (output_bfd, (bfd_vma) 0,
4330
0
          htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
4331
0
  }
4332
4333
0
      elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
4334
0
    }
4335
4336
0
  if (htab->elf.sgot)
4337
0
    {
4338
0
      asection *output_section = htab->elf.sgot->output_section;
4339
4340
0
      if (0 < htab->elf.sgot->size)
4341
0
  {
4342
    /* Set the first entry in the global offset table to the address of
4343
       the dynamic section.  */
4344
0
    bfd_vma val = sdyn ? sec_addr (sdyn) : 0;
4345
0
    bfd_put_32 (output_bfd, val, htab->elf.sgot->contents);
4346
0
  }
4347
4348
0
      elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
4349
0
    }
4350
4351
  /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
4352
0
  htab_traverse (htab->loc_hash_table,
4353
0
     (void *) elf32_loongarch_finish_local_dynamic_symbol, info);
4354
4355
0
  return true;
4356
0
}
4357
4358
/* Return address for Ith PLT stub in section PLT, for relocation REL
4359
   or (bfd_vma) -1 if it should not be included.  */
4360
4361
static bfd_vma
4362
loongarch_elf_plt_sym_val (bfd_vma i, const asection *plt,
4363
         const arelent *rel ATTRIBUTE_UNUSED)
4364
0
{
4365
0
  return plt->vma + PLT_HEADER_SIZE + i * PLT_ENTRY_SIZE;
4366
0
}
4367
4368
static enum elf_reloc_type_class
4369
loongarch_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
4370
          const asection *rel_sec ATTRIBUTE_UNUSED,
4371
          const Elf_Internal_Rela *rela)
4372
0
{
4373
0
  struct loongarch_elf_link_hash_table *htab;
4374
0
  htab = loongarch_elf_hash_table (info);
4375
4376
0
  if (htab->elf.dynsym != NULL && htab->elf.dynsym->contents != NULL)
4377
0
    {
4378
      /* Check relocation against STT_GNU_IFUNC symbol if there are
4379
   dynamic symbols.  */
4380
0
      bfd *abfd = info->output_bfd;
4381
0
      const struct elf_backend_data *bed = get_elf_backend_data (abfd);
4382
0
      unsigned long r_symndx = ELF32_R_SYM (rela->r_info);
4383
0
      if (r_symndx != STN_UNDEF)
4384
0
  {
4385
0
    Elf_Internal_Sym sym;
4386
0
    if (!bed->s->swap_symbol_in (abfd,
4387
0
               htab->elf.dynsym->contents
4388
0
               + r_symndx * bed->s->sizeof_sym,
4389
0
               0, &sym))
4390
0
      {
4391
        /* xgettext:c-format  */
4392
0
        _bfd_error_handler (_("%pB symbol number %lu references"
4393
0
            " nonexistent SHT_SYMTAB_SHNDX section"),
4394
0
          abfd, r_symndx);
4395
        /* Ideally an error class should be returned here.  */
4396
0
      }
4397
0
    else if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
4398
0
      return reloc_class_ifunc;
4399
0
  }
4400
0
    }
4401
4402
0
  switch (ELF32_R_TYPE (rela->r_info))
4403
0
    {
4404
0
    case R_LARCH_IRELATIVE:
4405
0
      return reloc_class_ifunc;
4406
0
    case R_LARCH_RELATIVE:
4407
0
      return reloc_class_relative;
4408
0
    case R_LARCH_JUMP_SLOT:
4409
0
      return reloc_class_plt;
4410
0
    case R_LARCH_COPY:
4411
0
      return reloc_class_copy;
4412
0
    default:
4413
0
      return reloc_class_normal;
4414
0
    }
4415
0
}
4416
4417
/* Copy the extra info we tack onto an elf_link_hash_entry.  */
4418
4419
static void
4420
loongarch_elf_copy_indirect_symbol (struct bfd_link_info *info,
4421
            struct elf_link_hash_entry *dir,
4422
            struct elf_link_hash_entry *ind)
4423
0
{
4424
0
  struct elf_link_hash_entry *edir, *eind;
4425
4426
0
  edir = dir;
4427
0
  eind = ind;
4428
4429
0
  if (eind->dyn_relocs != NULL)
4430
0
    {
4431
0
      if (edir->dyn_relocs != NULL)
4432
0
  {
4433
0
    struct elf_dyn_relocs **pp;
4434
0
    struct elf_dyn_relocs *p;
4435
4436
    /* Add reloc counts against the indirect sym to the direct sym
4437
       list.  Merge any entries against the same section.  */
4438
0
    for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
4439
0
      {
4440
0
        struct elf_dyn_relocs *q;
4441
4442
0
        for (q = edir->dyn_relocs; q != NULL; q = q->next)
4443
0
    if (q->sec == p->sec)
4444
0
      {
4445
0
        q->pc_count += p->pc_count;
4446
0
        q->count += p->count;
4447
0
        *pp = p->next;
4448
0
        break;
4449
0
      }
4450
0
        if (q == NULL)
4451
0
    pp = &p->next;
4452
0
      }
4453
0
    *pp = edir->dyn_relocs;
4454
0
  }
4455
4456
0
      edir->dyn_relocs = eind->dyn_relocs;
4457
0
      eind->dyn_relocs = NULL;
4458
0
    }
4459
4460
0
  if (ind->root.type == bfd_link_hash_indirect && dir->got.refcount < 0)
4461
0
    {
4462
0
      loongarch_elf_hash_entry(edir)->tls_type
4463
0
  = loongarch_elf_hash_entry(eind)->tls_type;
4464
0
      loongarch_elf_hash_entry(eind)->tls_type = GOT_UNKNOWN;
4465
0
    }
4466
0
  _bfd_elf_link_hash_copy_indirect (info, dir, ind);
4467
0
}
4468
4469
0
#define PRSTATUS_SIZE       0x1d8
4470
#define PRSTATUS_OFFSET_PR_CURSIG   0xc
4471
#define PRSTATUS_OFFSET_PR_PID      0x20
4472
0
#define ELF_GREGSET_T_SIZE      0x168
4473
0
#define PRSTATUS_OFFSET_PR_REG      0x70
4474
4475
/* Support for core dump NOTE sections.  */
4476
4477
static bool
4478
loongarch_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
4479
0
{
4480
0
  switch (note->descsz)
4481
0
    {
4482
0
    default:
4483
0
      return false;
4484
4485
    /* The sizeof (struct elf_prstatus) on Linux/LoongArch.  */
4486
0
    case PRSTATUS_SIZE:
4487
      /* pr_cursig  */
4488
0
      elf_tdata (abfd)->core->signal =
4489
0
  bfd_get_16 (abfd, note->descdata + PRSTATUS_OFFSET_PR_CURSIG);
4490
4491
      /* pr_pid  */
4492
0
      elf_tdata (abfd)->core->lwpid =
4493
0
  bfd_get_32 (abfd, note->descdata + PRSTATUS_OFFSET_PR_PID);
4494
0
      break;
4495
0
    }
4496
4497
  /* Make a ".reg/999" section.  */
4498
0
  return _bfd_elfcore_make_pseudosection (abfd, ".reg", ELF_GREGSET_T_SIZE,
4499
0
            note->descpos
4500
0
            + PRSTATUS_OFFSET_PR_REG);
4501
0
}
4502
4503
0
#define PRPSINFO_SIZE       0x88
4504
#define PRPSINFO_OFFSET_PR_PID      0x18
4505
0
#define PRPSINFO_OFFSET_PR_FNAME    0x28
4506
0
#define PRPSINFO_SIZEOF_PR_FNAME    0x10
4507
0
#define PRPSINFO_OFFSET_PR_PS_ARGS  0x38
4508
0
#define PRPSINFO_SIZEOF_PR_PS_ARGS  0x50
4509
4510
static bool
4511
loongarch_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
4512
0
{
4513
0
  switch (note->descsz)
4514
0
    {
4515
0
    default:
4516
0
      return false;
4517
4518
    /* The sizeof (prpsinfo_t) on Linux/LoongArch.  */
4519
0
    case PRPSINFO_SIZE:
4520
      /* pr_pid  */
4521
0
      elf_tdata (abfd)->core->pid =
4522
0
  bfd_get_32 (abfd, note->descdata + PRPSINFO_OFFSET_PR_PID);
4523
4524
      /* pr_fname  */
4525
0
      elf_tdata (abfd)->core->program =
4526
0
  _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_FNAME,
4527
0
            PRPSINFO_SIZEOF_PR_FNAME);
4528
4529
      /* pr_psargs  */
4530
0
      elf_tdata (abfd)->core->command =
4531
0
  _bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_PS_ARGS,
4532
0
            PRPSINFO_SIZEOF_PR_PS_ARGS);
4533
0
      break;
4534
0
    }
4535
4536
  /* Note that for some reason, a spurious space is tacked
4537
     onto the end of the args in some (at least one anyway)
4538
     implementations, so strip it off if it exists.  */
4539
4540
0
  {
4541
0
    char *command = elf_tdata (abfd)->core->command;
4542
0
    int n = strlen (command);
4543
4544
0
    if (0 < n && command[n - 1] == ' ')
4545
0
      command[n - 1] = '\0';
4546
0
  }
4547
4548
0
  return true;
4549
0
}
4550
4551
/* Set the right mach type.  */
4552
static bool
4553
loongarch_elf_object_p (bfd *abfd)
4554
4
{
4555
  /* There are only two mach types in LoongArch currently.  */
4556
4
  if (strcmp (abfd->xvec->name, "elf64-loongarch") == 0)
4557
0
    bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch64);
4558
4
  else
4559
4
    bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch32);
4560
4
  return true;
4561
4
}
4562
4563
static asection *
4564
loongarch_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info,
4565
          Elf_Internal_Rela *rel,
4566
          struct elf_link_hash_entry *h,
4567
          Elf_Internal_Sym *sym)
4568
0
{
4569
0
  if (h != NULL)
4570
0
    switch (ELF32_R_TYPE (rel->r_info))
4571
0
      {
4572
0
      case R_LARCH_GNU_VTINHERIT:
4573
0
      case R_LARCH_GNU_VTENTRY:
4574
0
  return NULL;
4575
0
      }
4576
4577
0
  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
4578
0
}
4579
4580
/* Return TRUE if symbol H should be hashed in the `.gnu.hash' section.  For
4581
   executable PLT slots where the executable never takes the address of those
4582
   functions, the function symbols are not added to the hash table.  */
4583
4584
static bool
4585
elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
4586
0
{
4587
0
  if (h->plt.offset != (bfd_vma) -1
4588
0
      && !h->def_regular
4589
0
      && !h->pointer_equality_needed)
4590
0
    return false;
4591
4592
0
  return _bfd_elf_hash_symbol (h);
4593
0
}
4594
4595
#define TARGET_LITTLE_SYM loongarch_elf32_vec
4596
#define TARGET_LITTLE_NAME "elf32-loongarch"
4597
#define ELF_ARCH bfd_arch_loongarch
4598
#define ELF_TARGET_ID LARCH_ELF_DATA
4599
#define ELF_MACHINE_CODE EM_LOONGARCH
4600
#define ELF_MAXPAGESIZE 0x4000
4601
#define bfd_elf32_bfd_reloc_type_lookup loongarch_reloc_type_lookup
4602
#define bfd_elf32_bfd_link_hash_table_create          \
4603
  loongarch_elf_link_hash_table_create
4604
#define bfd_elf32_bfd_reloc_name_lookup loongarch_reloc_name_lookup
4605
#define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto.  */
4606
#define elf_info_to_howto loongarch_info_to_howto_rela
4607
#define bfd_elf32_bfd_merge_private_bfd_data          \
4608
  elf32_loongarch_merge_private_bfd_data
4609
4610
#define elf_backend_reloc_type_class loongarch_reloc_type_class
4611
#define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol
4612
#define elf_backend_create_dynamic_sections          \
4613
  loongarch_elf_create_dynamic_sections
4614
#define elf_backend_check_relocs loongarch_elf_check_relocs
4615
#define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol
4616
#define elf_backend_size_dynamic_sections loongarch_elf_size_dynamic_sections
4617
#define elf_backend_relocate_section loongarch_elf_relocate_section
4618
#define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol
4619
#define elf_backend_finish_dynamic_sections          \
4620
  loongarch_elf_finish_dynamic_sections
4621
#define elf_backend_object_p loongarch_elf_object_p
4622
#define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook
4623
#define elf_backend_plt_sym_val loongarch_elf_plt_sym_val
4624
#define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
4625
#define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
4626
#define elf_backend_hash_symbol elf_loongarch64_hash_symbol
4627
#define bfd_elf32_bfd_relax_section loongarch_elf_relax_section
4628
4629
#include "elf32-target.h"