Coverage Report

Created: 2026-05-11 07:54

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