Coverage Report

Created: 2025-06-24 06:45

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