Coverage Report

Created: 2024-05-21 06:29

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