Coverage Report

Created: 2026-03-10 08:46

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