Coverage Report

Created: 2026-09-14 08:07

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