Coverage Report

Created: 2025-07-08 11:15

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