Coverage Report

Created: 2026-07-25 10:20

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