Coverage Report

Created: 2026-07-12 09:22

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