1/* LoongArch-specific support for NN-bit ELF.
2   Copyright (C) 2021-2022 Free Software Foundation, Inc.
3   Contributed by Loongson Ltd.
4
5   This file is part of BFD, the Binary File Descriptor library.
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 3 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program; see the file COPYING3.  If not,
19   see <http://www.gnu.org/licenses/>.  */
20
21#include "ansidecl.h"
22#include "sysdep.h"
23#include "bfd.h"
24#include "libbfd.h"
25#define ARCH_SIZE NN
26#include "elf-bfd.h"
27#include "objalloc.h"
28#include "elf/loongarch.h"
29#include "elfxx-loongarch.h"
30
31static bool
32loongarch_info_to_howto_rela (bfd *abfd, arelent *cache_ptr,
33			      Elf_Internal_Rela *dst)
34{
35  cache_ptr->howto = loongarch_elf_rtype_to_howto (abfd,
36						   ELFNN_R_TYPE (dst->r_info));
37  return cache_ptr->howto != NULL;
38}
39
40/* LoongArch ELF linker hash entry.  */
41struct loongarch_elf_link_hash_entry
42{
43  struct elf_link_hash_entry elf;
44
45#define GOT_UNKNOWN 0
46#define GOT_NORMAL  1
47#define GOT_TLS_GD  2
48#define GOT_TLS_IE  4
49#define GOT_TLS_LE  8
50  char tls_type;
51};
52
53#define loongarch_elf_hash_entry(ent)	\
54  ((struct loongarch_elf_link_hash_entry *) (ent))
55
56struct _bfd_loongarch_elf_obj_tdata
57{
58  struct elf_obj_tdata root;
59
60  /* The tls_type for each local got entry.  */
61  char *local_got_tls_type;
62};
63
64#define _bfd_loongarch_elf_tdata(abfd)	\
65  ((struct _bfd_loongarch_elf_obj_tdata *) (abfd)->tdata.any)
66
67#define _bfd_loongarch_elf_local_got_tls_type(abfd)	\
68  (_bfd_loongarch_elf_tdata (abfd)->local_got_tls_type)
69
70#define _bfd_loongarch_elf_tls_type(abfd, h, symndx)			\
71  (*((h) != NULL							\
72     ? &loongarch_elf_hash_entry (h)->tls_type				\
73     : &_bfd_loongarch_elf_local_got_tls_type (abfd)[symndx]))
74
75#define is_loongarch_elf(bfd)						\
76  (bfd_get_flavour (bfd) == bfd_target_elf_flavour			\
77   && elf_tdata (bfd) != NULL						\
78   && elf_object_id (bfd) == LARCH_ELF_DATA)
79
80struct loongarch_elf_link_hash_table
81{
82  struct elf_link_hash_table elf;
83
84  /* Short-cuts to get to dynamic linker sections.  */
85  asection *sdyntdata;
86
87  /* Small local sym to section mapping cache.  */
88  struct sym_cache sym_cache;
89
90  /* Used by local STT_GNU_IFUNC symbols.  */
91  htab_t loc_hash_table;
92  void *loc_hash_memory;
93
94  /* The max alignment of output sections.  */
95  bfd_vma max_alignment;
96};
97
98/* Get the LoongArch ELF linker hash table from a link_info structure.  */
99#define loongarch_elf_hash_table(p)					\
100  (elf_hash_table_id (elf_hash_table (p)) == LARCH_ELF_DATA		\
101   ? ((struct loongarch_elf_link_hash_table *) ((p)->hash))		\
102   : NULL)
103
104#define MINUS_ONE ((bfd_vma) 0 - 1)
105
106#define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset)
107
108#define LARCH_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3)
109#define LARCH_ELF_WORD_BYTES (1 << LARCH_ELF_LOG_WORD_BYTES)
110
111#define PLT_HEADER_INSNS 8
112#define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
113
114#define PLT_ENTRY_INSNS 4
115#define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
116
117#define GOT_ENTRY_SIZE (LARCH_ELF_WORD_BYTES)
118
119#define GOTPLT_HEADER_SIZE (GOT_ENTRY_SIZE * 2)
120
121#define elf_backend_want_got_plt 1
122
123#define elf_backend_plt_readonly 1
124
125#define elf_backend_want_plt_sym 1
126#define elf_backend_plt_alignment 4
127#define elf_backend_can_gc_sections 1
128#define elf_backend_can_refcount 1
129#define elf_backend_want_got_sym 1
130
131#define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1)
132
133#define elf_backend_want_dynrelro 1
134#define elf_backend_rela_normal 1
135#define elf_backend_default_execstack 0
136
137/* Generate a PLT header.  */
138
139static bool
140loongarch_make_plt_header (bfd_vma got_plt_addr, bfd_vma plt_header_addr,
141			   uint32_t *entry)
142{
143  bfd_vma pcrel = got_plt_addr - plt_header_addr;
144  bfd_vma hi, lo;
145
146  if (pcrel + 0x80000800 > 0xffffffff)
147    {
148      _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
149      bfd_set_error (bfd_error_bad_value);
150      return false;
151    }
152  hi = ((pcrel + 0x800) >> 12) & 0xfffff;
153  lo = pcrel & 0xfff;
154
155  /* pcaddu12i  $t2, %hi(%pcrel(.got.plt))
156     sub.[wd]   $t1, $t1, $t3
157     ld.[wd]    $t3, $t2, %lo(%pcrel(.got.plt)) # _dl_runtime_resolve
158     addi.[wd]  $t1, $t1, -(PLT_HEADER_SIZE + 12)
159     addi.[wd]  $t0, $t2, %lo(%pcrel(.got.plt))
160     srli.[wd]  $t1, $t1, log2(16 / GOT_ENTRY_SIZE)
161     ld.[wd]    $t0, $t0, GOT_ENTRY_SIZE
162     jirl   $r0, $t3, 0 */
163
164  if (GOT_ENTRY_SIZE == 8)
165    {
166      entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
167      entry[1] = 0x0011bdad;
168      entry[2] = 0x28c001cf | (lo & 0xfff) << 10;
169      entry[3] = 0x02c001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
170      entry[4] = 0x02c001cc | (lo & 0xfff) << 10;
171      entry[5] = 0x004501ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
172      entry[6] = 0x28c0018c | GOT_ENTRY_SIZE << 10;
173      entry[7] = 0x4c0001e0;
174    }
175  else
176    {
177      entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
178      entry[1] = 0x00113dad;
179      entry[2] = 0x288001cf | (lo & 0xfff) << 10;
180      entry[3] = 0x028001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
181      entry[4] = 0x028001cc | (lo & 0xfff) << 10;
182      entry[5] = 0x004481ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
183      entry[6] = 0x2880018c | GOT_ENTRY_SIZE << 10;
184      entry[7] = 0x4c0001e0;
185    }
186  return true;
187}
188
189/* Generate a PLT entry.  */
190
191static bool
192loongarch_make_plt_entry (bfd_vma got_plt_entry_addr, bfd_vma plt_entry_addr,
193			  uint32_t *entry)
194{
195  bfd_vma pcrel = got_plt_entry_addr - plt_entry_addr;
196  bfd_vma hi, lo;
197
198  if (pcrel + 0x80000800 > 0xffffffff)
199    {
200      _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
201      bfd_set_error (bfd_error_bad_value);
202      return false;
203    }
204  hi = ((pcrel + 0x800) >> 12) & 0xfffff;
205  lo = pcrel & 0xfff;
206
207  entry[0] = 0x1c00000f | (hi & 0xfffff) << 5;
208  entry[1] = ((GOT_ENTRY_SIZE == 8 ? 0x28c001ef : 0x288001ef)
209	      | (lo & 0xfff) << 10);
210  entry[2] = 0x4c0001ed;	/* jirl $r13, $15, 0 */
211  entry[3] = 0x03400000;	/* nop */
212
213  return true;
214}
215
216/* Create an entry in an LoongArch ELF linker hash table.  */
217
218static struct bfd_hash_entry *
219link_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
220		   const char *string)
221{
222  struct loongarch_elf_link_hash_entry *eh;
223
224  /* Allocate the structure if it has not already been allocated by a
225     subclass.  */
226  if (entry == NULL)
227    {
228      entry = bfd_hash_allocate (table, sizeof (*eh));
229      if (entry == NULL)
230	return entry;
231    }
232
233  /* Call the allocation method of the superclass.  */
234  entry = _bfd_elf_link_hash_newfunc (entry, table, string);
235  if (entry != NULL)
236    {
237      eh = (struct loongarch_elf_link_hash_entry *) entry;
238      eh->tls_type = GOT_UNKNOWN;
239    }
240
241  return entry;
242}
243
244/* Compute a hash of a local hash entry.  We use elf_link_hash_entry
245  for local symbol so that we can handle local STT_GNU_IFUNC symbols
246  as global symbol.  We reuse indx and dynstr_index for local symbol
247  hash since they aren't used by global symbols in this backend.  */
248
249static hashval_t
250elfNN_loongarch_local_htab_hash (const void *ptr)
251{
252  struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) ptr;
253  return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
254}
255
256/* Compare local hash entries.  */
257
258static int
259elfNN_loongarch_local_htab_eq (const void *ptr1, const void *ptr2)
260{
261  struct elf_link_hash_entry *h1 = (struct elf_link_hash_entry *) ptr1;
262  struct elf_link_hash_entry *h2 = (struct elf_link_hash_entry *) ptr2;
263
264  return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
265}
266
267/* Find and/or create a hash entry for local symbol.  */
268static struct elf_link_hash_entry *
269elfNN_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table *htab,
270				    bfd *abfd, const Elf_Internal_Rela *rel,
271				    bool create)
272{
273  struct loongarch_elf_link_hash_entry e, *ret;
274  asection *sec = abfd->sections;
275  hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id, ELFNN_R_SYM (rel->r_info));
276  void **slot;
277
278  e.elf.indx = sec->id;
279  e.elf.dynstr_index = ELFNN_R_SYM (rel->r_info);
280  slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
281				   create ? INSERT : NO_INSERT);
282
283  if (!slot)
284    return NULL;
285
286  if (*slot)
287    {
288      ret = (struct loongarch_elf_link_hash_entry *) *slot;
289      return &ret->elf;
290    }
291
292  ret = ((struct loongarch_elf_link_hash_entry *)
293	 objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
294			 sizeof (struct loongarch_elf_link_hash_entry)));
295  if (ret)
296    {
297      memset (ret, 0, sizeof (*ret));
298      ret->elf.indx = sec->id;
299      ret->elf.pointer_equality_needed = 0;
300      ret->elf.dynstr_index = ELFNN_R_SYM (rel->r_info);
301      ret->elf.dynindx = -1;
302      ret->elf.needs_plt = 0;
303      ret->elf.plt.refcount = -1;
304      ret->elf.got.refcount = -1;
305      ret->elf.def_dynamic = 0;
306      ret->elf.def_regular = 1;
307      ret->elf.ref_dynamic = 0; /* This should be always 0 for local.  */
308      ret->elf.ref_regular = 0;
309      ret->elf.forced_local = 1;
310      ret->elf.root.type = bfd_link_hash_defined;
311      *slot = ret;
312    }
313  return &ret->elf;
314}
315
316/* Destroy an LoongArch elf linker hash table.  */
317
318static void
319elfNN_loongarch_link_hash_table_free (bfd *obfd)
320{
321  struct loongarch_elf_link_hash_table *ret;
322  ret = (struct loongarch_elf_link_hash_table *) obfd->link.hash;
323
324  if (ret->loc_hash_table)
325    htab_delete (ret->loc_hash_table);
326  if (ret->loc_hash_memory)
327    objalloc_free ((struct objalloc *) ret->loc_hash_memory);
328
329  _bfd_elf_link_hash_table_free (obfd);
330}
331
332/* Create a LoongArch ELF linker hash table.  */
333
334static struct bfd_link_hash_table *
335loongarch_elf_link_hash_table_create (bfd *abfd)
336{
337  struct loongarch_elf_link_hash_table *ret;
338  bfd_size_type amt = sizeof (struct loongarch_elf_link_hash_table);
339
340  ret = (struct loongarch_elf_link_hash_table *) bfd_zmalloc (amt);
341  if (ret == NULL)
342    return NULL;
343
344  if (!_bfd_elf_link_hash_table_init
345      (&ret->elf, abfd, link_hash_newfunc,
346       sizeof (struct loongarch_elf_link_hash_entry), LARCH_ELF_DATA))
347    {
348      free (ret);
349      return NULL;
350    }
351
352  ret->max_alignment = MINUS_ONE;
353
354  ret->loc_hash_table = htab_try_create (1024, elfNN_loongarch_local_htab_hash,
355					 elfNN_loongarch_local_htab_eq, NULL);
356  ret->loc_hash_memory = objalloc_create ();
357  if (!ret->loc_hash_table || !ret->loc_hash_memory)
358    {
359      elfNN_loongarch_link_hash_table_free (abfd);
360      return NULL;
361    }
362  ret->elf.root.hash_table_free = elfNN_loongarch_link_hash_table_free;
363
364  return &ret->elf.root;
365}
366
367/* Merge backend specific data from an object file to the output
368   object file when linking.  */
369
370static bool
371elfNN_loongarch_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
372{
373  bfd *obfd = info->output_bfd;
374  flagword in_flags = elf_elfheader (ibfd)->e_flags;
375  flagword out_flags = elf_elfheader (obfd)->e_flags;
376
377  if (!is_loongarch_elf (ibfd) || !is_loongarch_elf (obfd))
378    return true;
379
380  if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
381    {
382      _bfd_error_handler (_("%pB: ABI is incompatible with that of "
383			    "the selected emulation:\n"
384			    "  target emulation `%s' does not match `%s'"),
385			  ibfd, bfd_get_target (ibfd), bfd_get_target (obfd));
386      return false;
387    }
388
389  if (!_bfd_elf_merge_object_attributes (ibfd, info))
390    return false;
391
392  /* If the input BFD is not a dynamic object and it does not contain any
393     non-data sections, do not account its ABI.  For example, various
394     packages produces such data-only relocatable objects with
395     `ld -r -b binary` or `objcopy`, and these objects have zero e_flags.
396     But they are compatible with all ABIs.  */
397  if (!(ibfd->flags & DYNAMIC))
398    {
399      asection *sec;
400      bool have_code_sections = false;
401      for (sec = ibfd->sections; sec != NULL; sec = sec->next)
402	if ((bfd_section_flags (sec)
403	     & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
404	    == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
405	  {
406	    have_code_sections = true;
407	    break;
408	  }
409      if (!have_code_sections)
410	return true;
411    }
412
413  if (!elf_flags_init (obfd))
414    {
415      elf_flags_init (obfd) = true;
416      elf_elfheader (obfd)->e_flags = in_flags;
417      return true;
418    }
419  else if (out_flags != in_flags)
420    {
421      if ((EF_LOONGARCH_IS_OBJ_V0 (out_flags)
422	   && EF_LOONGARCH_IS_OBJ_V1 (in_flags))
423	  || (EF_LOONGARCH_IS_OBJ_V0 (in_flags)
424	      && EF_LOONGARCH_IS_OBJ_V1 (out_flags)))
425	{
426	  elf_elfheader (obfd)->e_flags |= EF_LOONGARCH_OBJABI_V1;
427	  out_flags = elf_elfheader (obfd)->e_flags;
428	  in_flags = out_flags;
429	}
430    }
431
432  /* Disallow linking different ABIs.  */
433  /* Only check relocation version.
434     The obj_v0 is compatible with obj_v1.  */
435  if (EF_LOONGARCH_ABI(out_flags ^ in_flags) & EF_LOONGARCH_ABI_MASK)
436    {
437      _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd);
438      goto fail;
439    }
440
441  return true;
442
443 fail:
444  bfd_set_error (bfd_error_bad_value);
445  return false;
446}
447
448/* Create the .got section.  */
449
450static bool
451loongarch_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
452{
453  flagword flags;
454  char *name;
455  asection *s, *s_got;
456  struct elf_link_hash_entry *h;
457  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
458  struct elf_link_hash_table *htab = elf_hash_table (info);
459
460  /* This function may be called more than once.  */
461  if (htab->sgot != NULL)
462    return true;
463
464  flags = bed->dynamic_sec_flags;
465  name = bed->rela_plts_and_copies_p ? ".rela.got" : ".rel.got";
466  s = bfd_make_section_anyway_with_flags (abfd, name, flags | SEC_READONLY);
467
468  if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
469    return false;
470  htab->srelgot = s;
471
472  s = s_got = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
473  if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
474    return false;
475  htab->sgot = s;
476
477  /* The first bit of the global offset table is the header.  */
478  s->size += bed->got_header_size;
479
480  if (bed->want_got_plt)
481    {
482      s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
483      if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
484	return false;
485      htab->sgotplt = s;
486
487      /* Reserve room for the header.  */
488      s->size = GOTPLT_HEADER_SIZE;
489    }
490
491  if (bed->want_got_sym)
492    {
493      /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
494	 section.  We don't do this in the linker script because we don't want
495	 to define the symbol if we are not creating a global offset table.  */
496      h = _bfd_elf_define_linkage_sym (abfd, info, s_got,
497				       "_GLOBAL_OFFSET_TABLE_");
498      elf_hash_table (info)->hgot = h;
499      if (h == NULL)
500	return false;
501    }
502  return true;
503}
504
505/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
506   .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
507   hash table.  */
508
509static bool
510loongarch_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
511{
512  struct loongarch_elf_link_hash_table *htab;
513
514  htab = loongarch_elf_hash_table (info);
515  BFD_ASSERT (htab != NULL);
516
517  if (!loongarch_elf_create_got_section (dynobj, info))
518    return false;
519
520  if (!_bfd_elf_create_dynamic_sections (dynobj, info))
521    return false;
522
523  if (!bfd_link_pic (info))
524    htab->sdyntdata
525      = bfd_make_section_anyway_with_flags (dynobj, ".tdata.dyn",
526					    SEC_ALLOC | SEC_THREAD_LOCAL);
527
528  if (!htab->elf.splt || !htab->elf.srelplt || !htab->elf.sdynbss
529      || (!bfd_link_pic (info) && (!htab->elf.srelbss || !htab->sdyntdata)))
530    abort ();
531
532  return true;
533}
534
535static bool
536loongarch_elf_record_tls_and_got_reference (bfd *abfd,
537					    struct bfd_link_info *info,
538					    struct elf_link_hash_entry *h,
539					    unsigned long symndx,
540					    char tls_type)
541{
542  struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
543  Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
544
545  /* This is a global offset table entry for a local symbol.  */
546  if (elf_local_got_refcounts (abfd) == NULL)
547    {
548      bfd_size_type size =
549	symtab_hdr->sh_info * (sizeof (bfd_vma) + sizeof (tls_type));
550      if (!(elf_local_got_refcounts (abfd) = bfd_zalloc (abfd, size)))
551	return false;
552      _bfd_loongarch_elf_local_got_tls_type (abfd) =
553	(char *) (elf_local_got_refcounts (abfd) + symtab_hdr->sh_info);
554    }
555
556  switch (tls_type)
557    {
558    case GOT_NORMAL:
559    case GOT_TLS_GD:
560    case GOT_TLS_IE:
561      /* Need GOT.  */
562      if (htab->elf.sgot == NULL
563	  && !loongarch_elf_create_got_section (htab->elf.dynobj, info))
564	return false;
565      if (h)
566	{
567	  if (h->got.refcount < 0)
568	    h->got.refcount = 0;
569	  h->got.refcount++;
570	}
571      else
572	elf_local_got_refcounts (abfd)[symndx]++;
573      break;
574    case GOT_TLS_LE:
575      /* No need for GOT.  */
576      break;
577    default:
578      _bfd_error_handler (_("Internal error: unreachable."));
579      return false;
580    }
581
582  char *new_tls_type = &_bfd_loongarch_elf_tls_type (abfd, h, symndx);
583  *new_tls_type |= tls_type;
584  if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL))
585    {
586      _bfd_error_handler (_("%pB: `%s' accessed both as normal and "
587			    "thread local symbol"),
588			  abfd,
589			  h ? h->root.root.string : "<local>");
590      return false;
591    }
592
593  return true;
594}
595
596/* Look through the relocs for a section during the first phase, and
597   allocate space in the global offset table or procedure linkage
598   table.  */
599
600static bool
601loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
602			    asection *sec, const Elf_Internal_Rela *relocs)
603{
604  struct loongarch_elf_link_hash_table *htab;
605  Elf_Internal_Shdr *symtab_hdr;
606  struct elf_link_hash_entry **sym_hashes;
607  const Elf_Internal_Rela *rel;
608  asection *sreloc = NULL;
609
610  if (bfd_link_relocatable (info))
611    return true;
612
613  htab = loongarch_elf_hash_table (info);
614  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
615  sym_hashes = elf_sym_hashes (abfd);
616
617  if (htab->elf.dynobj == NULL)
618    htab->elf.dynobj = abfd;
619
620  for (rel = relocs; rel < relocs + sec->reloc_count; rel++)
621    {
622      unsigned int r_type;
623      unsigned int r_symndx;
624      struct elf_link_hash_entry *h;
625      Elf_Internal_Sym *isym = NULL;
626
627      r_symndx = ELFNN_R_SYM (rel->r_info);
628      r_type = ELFNN_R_TYPE (rel->r_info);
629
630      if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
631	{
632	  _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd, r_symndx);
633	  return false;
634	}
635
636      if (r_symndx < symtab_hdr->sh_info)
637	{
638	  /* A local symbol.  */
639	  isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, r_symndx);
640	  if (isym == NULL)
641	    return false;
642
643	  if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
644	    {
645	      h = elfNN_loongarch_get_local_sym_hash (htab, abfd, rel, true);
646	      if (h == NULL)
647		return false;
648
649	      h->type = STT_GNU_IFUNC;
650	      h->ref_regular = 1;
651	    }
652	  else
653	    h = NULL;
654	}
655      else
656	{
657	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
658	  while (h->root.type == bfd_link_hash_indirect
659		 || h->root.type == bfd_link_hash_warning)
660	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
661	}
662
663      /* It is referenced by a non-shared object.  */
664      if (h != NULL)
665	h->ref_regular = 1;
666
667      if (h && h->type == STT_GNU_IFUNC)
668	{
669	  if (htab->elf.dynobj == NULL)
670	    htab->elf.dynobj = abfd;
671
672	  /* Create 'irelifunc' in PIC object.  */
673	  if (bfd_link_pic (info)
674	      && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
675	    return false;
676	  /* If '.plt' not represent, create '.iplt' to deal with ifunc.  */
677	  else if (!htab->elf.splt
678		   && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
679	    return false;
680	  /* Create the ifunc sections, iplt and ipltgot, for static
681	     executables.  */
682	  if ((r_type == R_LARCH_64 || r_type == R_LARCH_32)
683	      && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
684	    return false;
685
686	  if (h->plt.refcount < 0)
687	    h->plt.refcount = 0;
688	  h->plt.refcount++;
689	  h->needs_plt = 1;
690
691	  elf_tdata (info->output_bfd)->has_gnu_osabi |= elf_gnu_osabi_ifunc;
692	}
693
694      int need_dynreloc = 0;
695      int only_need_pcrel = 0;
696
697      switch (r_type)
698	{
699	case R_LARCH_GOT_PC_HI20:
700	case R_LARCH_GOT_HI20:
701	case R_LARCH_SOP_PUSH_GPREL:
702	  /* For la.global.  */
703	  if (h)
704	    h->pointer_equality_needed = 1;
705	  if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
706							   r_symndx,
707							   GOT_NORMAL))
708	    return false;
709	  break;
710
711	case R_LARCH_TLS_LD_PC_HI20:
712	case R_LARCH_TLS_LD_HI20:
713	case R_LARCH_TLS_GD_PC_HI20:
714	case R_LARCH_TLS_GD_HI20:
715	case R_LARCH_SOP_PUSH_TLS_GD:
716	  if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
717							   r_symndx,
718							   GOT_TLS_GD))
719	    return false;
720	  break;
721
722	case R_LARCH_TLS_IE_PC_HI20:
723	case R_LARCH_TLS_IE_HI20:
724	case R_LARCH_SOP_PUSH_TLS_GOT:
725	  if (bfd_link_pic (info))
726	    /* May fail for lazy-bind.  */
727	    info->flags |= DF_STATIC_TLS;
728
729	  if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
730							   r_symndx,
731							   GOT_TLS_IE))
732	    return false;
733	  break;
734
735	case R_LARCH_TLS_LE_HI20:
736	case R_LARCH_SOP_PUSH_TLS_TPREL:
737	  if (!bfd_link_executable (info))
738	    return false;
739
740	  info->flags |= DF_STATIC_TLS;
741
742	  if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
743							   r_symndx,
744							   GOT_TLS_LE))
745	    return false;
746	  break;
747
748	case R_LARCH_ABS_HI20:
749	case R_LARCH_SOP_PUSH_ABSOLUTE:
750	  if (h != NULL)
751	    /* If this reloc is in a read-only section, we might
752	       need a copy reloc.  We can't check reliably at this
753	       stage whether the section is read-only, as input
754	       sections have not yet been mapped to output sections.
755	       Tentatively set the flag for now, and correct in
756	       adjust_dynamic_symbol.  */
757	    h->non_got_ref = 1;
758	  break;
759
760	case R_LARCH_PCALA_HI20:
761	  if (h != NULL)
762	    {
763	      /* For pcalau12i + jirl.  */
764	      h->needs_plt = 1;
765	      if (h->plt.refcount < 0)
766		h->plt.refcount = 0;
767	      h->plt.refcount++;
768
769	      h->non_got_ref = 1;
770	      h->pointer_equality_needed = 1;
771	    }
772
773	  break;
774
775	case R_LARCH_B21:
776	case R_LARCH_B16:
777	case R_LARCH_B26:
778	  if (h != NULL)
779	    {
780	      h->needs_plt = 1;
781	      if (!bfd_link_pic (info))
782		h->non_got_ref = 1;
783
784	      /* We try to create PLT stub for all non-local function.  */
785	      if (h->plt.refcount < 0)
786		h->plt.refcount = 0;
787	      h->plt.refcount++;
788	    }
789
790	  break;
791
792	case R_LARCH_SOP_PUSH_PCREL:
793	  if (h != NULL)
794	    {
795	      if (!bfd_link_pic (info))
796		h->non_got_ref = 1;
797
798	      /* We try to create PLT stub for all non-local function.  */
799	      if (h->plt.refcount < 0)
800		h->plt.refcount = 0;
801	      h->plt.refcount++;
802	      h->pointer_equality_needed = 1;
803	    }
804
805	  break;
806
807	case R_LARCH_SOP_PUSH_PLT_PCREL:
808	  /* This symbol requires a procedure linkage table entry.  We
809	     actually build the entry in adjust_dynamic_symbol,
810	     because this might be a case of linking PIC code without
811	     linking in any dynamic objects, in which case we don't
812	     need to generate a procedure linkage table after all.  */
813	  if (h != NULL)
814	    {
815	      h->needs_plt = 1;
816	      if (h->plt.refcount < 0)
817		h->plt.refcount = 0;
818	      h->plt.refcount++;
819	    }
820	  break;
821
822	case R_LARCH_TLS_DTPREL32:
823	case R_LARCH_TLS_DTPREL64:
824	  need_dynreloc = 1;
825	  only_need_pcrel = 1;
826	  break;
827
828	case R_LARCH_JUMP_SLOT:
829	case R_LARCH_32:
830	case R_LARCH_64:
831
832	  need_dynreloc = 1;
833
834	  /* If resolved symbol is defined in this object,
835	     1. Under pie, the symbol is known.  We convert it
836	     into R_LARCH_RELATIVE and need load-addr still.
837	     2. Under pde, the symbol is known and we can discard R_LARCH_NN.
838	     3. Under dll, R_LARCH_NN can't be changed normally, since
839	     its defination could be covered by the one in executable.
840	     For symbolic, we convert it into R_LARCH_RELATIVE.
841	     Thus, only under pde, it needs pcrel only.  We discard it.  */
842	  only_need_pcrel = bfd_link_pde (info);
843
844	  if (h != NULL
845	      && (!bfd_link_pic (info)
846		  || h->type == STT_GNU_IFUNC))
847	    {
848	      /* This reloc might not bind locally.  */
849	      h->non_got_ref = 1;
850	      h->pointer_equality_needed = 1;
851
852	      if (!h->def_regular
853		  || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
854		{
855		  /* We may need a .plt entry if the symbol is a function
856		     defined in a shared lib or is a function referenced
857		     from the code or read-only section.  */
858		  h->plt.refcount += 1;
859		}
860	    }
861	  break;
862
863	case R_LARCH_GNU_VTINHERIT:
864	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
865	    return false;
866	  break;
867
868	case R_LARCH_GNU_VTENTRY:
869	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
870	    return false;
871	  break;
872
873	default:
874	  break;
875	}
876
877      /* Record some info for sizing and allocating dynamic entry.  */
878      if (need_dynreloc && (sec->flags & SEC_ALLOC))
879	{
880	  /* When creating a shared object, we must copy these
881	     relocs into the output file.  We create a reloc
882	     section in dynobj and make room for the reloc.  */
883	  struct elf_dyn_relocs *p;
884	  struct elf_dyn_relocs **head;
885
886	  if (sreloc == NULL)
887	    {
888	      sreloc
889		= _bfd_elf_make_dynamic_reloc_section (sec, htab->elf.dynobj,
890						       LARCH_ELF_LOG_WORD_BYTES,
891						       abfd, /*rela?*/ true);
892	      if (sreloc == NULL)
893		return false;
894	    }
895
896	  /* If this is a global symbol, we count the number of
897	     relocations we need for this symbol.  */
898	  if (h != NULL)
899	    head = &h->dyn_relocs;
900	  else
901	    {
902	      /* Track dynamic relocs needed for local syms too.
903		 We really need local syms available to do this
904		 easily.  Oh well.  */
905
906	      asection *s;
907	      void *vpp;
908
909	      s = bfd_section_from_elf_index (abfd, isym->st_shndx);
910	      if (s == NULL)
911		s = sec;
912
913	      vpp = &elf_section_data (s)->local_dynrel;
914	      head = (struct elf_dyn_relocs **) vpp;
915	    }
916
917	  p = *head;
918	  if (p == NULL || p->sec != sec)
919	    {
920	      bfd_size_type amt = sizeof *p;
921	      p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj, amt);
922	      if (p == NULL)
923		return false;
924	      p->next = *head;
925	      *head = p;
926	      p->sec = sec;
927	      p->count = 0;
928	      p->pc_count = 0;
929	    }
930
931	  p->count++;
932	  p->pc_count += only_need_pcrel;
933	}
934    }
935
936  return true;
937}
938
939/* Find dynamic relocs for H that apply to read-only sections.  */
940
941static asection *
942readonly_dynrelocs (struct elf_link_hash_entry *h)
943{
944  struct elf_dyn_relocs *p;
945
946  for (p = h->dyn_relocs; p != NULL; p = p->next)
947    {
948      asection *s = p->sec->output_section;
949
950      if (s != NULL && (s->flags & SEC_READONLY) != 0)
951	return p->sec;
952    }
953  return NULL;
954}
955
956/* Adjust a symbol defined by a dynamic object and referenced by a
957   regular object.  The current definition is in some section of the
958   dynamic object, but we're not including those sections.  We have to
959   change the definition to something the rest of the link can
960   understand.  */
961static bool
962loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
963				     struct elf_link_hash_entry *h)
964{
965  struct loongarch_elf_link_hash_table *htab;
966  bfd *dynobj;
967
968  htab = loongarch_elf_hash_table (info);
969  BFD_ASSERT (htab != NULL);
970
971  dynobj = htab->elf.dynobj;
972
973  /* Make sure we know what is going on here.  */
974  BFD_ASSERT (dynobj != NULL
975	      && (h->needs_plt || h->type == STT_GNU_IFUNC || h->is_weakalias
976		  || (h->def_dynamic && h->ref_regular && !h->def_regular)));
977
978  /* If this is a function, put it in the procedure linkage table.  We
979     will fill in the contents of the procedure linkage table later
980     (although we could actually do it here).  */
981  if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt)
982    {
983      if (h->plt.refcount < 0
984	  || (h->type != STT_GNU_IFUNC
985	      && (SYMBOL_REFERENCES_LOCAL (info, h)
986		  || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
987		      && h->root.type == bfd_link_hash_undefweak))))
988	{
989	  /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc
990	     in an input file, but the symbol was never referred to by a
991	     dynamic object, or if all references were garbage collected.
992	     In such a case, we don't actually need to build a PLT entry.  */
993	  h->plt.offset = MINUS_ONE;
994	  h->needs_plt = 0;
995	}
996      else
997	h->needs_plt = 1;
998
999      return true;
1000    }
1001  else
1002    h->plt.offset = MINUS_ONE;
1003
1004  /* If this is a weak symbol, and there is a real definition, the
1005     processor independent code will have arranged for us to see the
1006     real definition first, and we can just use the same value.  */
1007  if (h->is_weakalias)
1008    {
1009      struct elf_link_hash_entry *def = weakdef (h);
1010      BFD_ASSERT (def->root.type == bfd_link_hash_defined);
1011      h->root.u.def.section = def->root.u.def.section;
1012      h->root.u.def.value = def->root.u.def.value;
1013      return true;
1014    }
1015
1016  /* R_LARCH_COPY is not adept glibc, not to generate.  */
1017  /* Can not print anything, because make check ld.  */
1018  return true;
1019}
1020
1021/* Allocate space in .plt, .got and associated reloc sections for
1022   dynamic relocs.  */
1023
1024static bool
1025allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
1026{
1027  struct bfd_link_info *info;
1028  struct loongarch_elf_link_hash_table *htab;
1029  struct elf_dyn_relocs *p;
1030
1031  if (h->root.type == bfd_link_hash_indirect)
1032    return true;
1033
1034  if (h->type == STT_GNU_IFUNC
1035      && h->def_regular)
1036    return true;
1037
1038  info = (struct bfd_link_info *) inf;
1039  htab = loongarch_elf_hash_table (info);
1040  bool dyn = htab->elf.dynamic_sections_created;
1041  BFD_ASSERT (htab != NULL);
1042
1043  do
1044    {
1045      asection *plt, *gotplt, *relplt;
1046
1047      if (!h->needs_plt)
1048	break;
1049
1050      h->needs_plt = 0;
1051
1052      if (htab->elf.splt)
1053	{
1054	  if (h->dynindx == -1 && !h->forced_local && dyn
1055	      && h->root.type == bfd_link_hash_undefweak)
1056	    {
1057	      if (!bfd_elf_link_record_dynamic_symbol (info, h))
1058		return false;
1059	    }
1060
1061	  if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h)
1062	      && h->type != STT_GNU_IFUNC)
1063	    break;
1064
1065	  plt = htab->elf.splt;
1066	  gotplt = htab->elf.sgotplt;
1067	  relplt = htab->elf.srelplt;
1068	}
1069      else if (htab->elf.iplt)
1070	{
1071	  /* .iplt only for IFUNC.  */
1072	  if (h->type != STT_GNU_IFUNC)
1073	    break;
1074
1075	  plt = htab->elf.iplt;
1076	  gotplt = htab->elf.igotplt;
1077	  relplt = htab->elf.irelplt;
1078	}
1079      else
1080	break;
1081
1082      if (plt->size == 0)
1083	plt->size = PLT_HEADER_SIZE;
1084
1085      h->plt.offset = plt->size;
1086      plt->size += PLT_ENTRY_SIZE;
1087      gotplt->size += GOT_ENTRY_SIZE;
1088      relplt->size += sizeof (ElfNN_External_Rela);
1089
1090      /* If this symbol is not defined in a regular file, and we are
1091	 not generating a shared library, then set the symbol to this
1092	 location in the .plt.  This is required to make function
1093	 pointers compare as equal between the normal executable and
1094	 the shared library.  */
1095      if (!bfd_link_pic (info)
1096	  && !h->def_regular)
1097	{
1098	  h->root.u.def.section = plt;
1099	  h->root.u.def.value = h->plt.offset;
1100	}
1101
1102      h->needs_plt = 1;
1103    }
1104  while (0);
1105
1106  if (!h->needs_plt)
1107    h->plt.offset = MINUS_ONE;
1108
1109  if (0 < h->got.refcount)
1110    {
1111      asection *s;
1112      int tls_type = loongarch_elf_hash_entry (h)->tls_type;
1113
1114      /* Make sure this symbol is output as a dynamic symbol.
1115	 Undefined weak syms won't yet be marked as dynamic.  */
1116      if (h->dynindx == -1 && !h->forced_local && dyn
1117	  && h->root.type == bfd_link_hash_undefweak)
1118	{
1119	  if (!bfd_elf_link_record_dynamic_symbol (info, h))
1120	    return false;
1121	}
1122
1123      s = htab->elf.sgot;
1124      h->got.offset = s->size;
1125      if (tls_type & (GOT_TLS_GD | GOT_TLS_IE))
1126	{
1127	  /* TLS_GD needs two dynamic relocs and two GOT slots.  */
1128	  if (tls_type & GOT_TLS_GD)
1129	    {
1130	      s->size += 2 * GOT_ENTRY_SIZE;
1131	      if (bfd_link_executable (info))
1132		{
1133		  /* Link exe and not defined local.  */
1134		  if (!SYMBOL_REFERENCES_LOCAL (info, h))
1135		    htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
1136		}
1137	      else
1138		{
1139		  if (SYMBOL_REFERENCES_LOCAL (info, h))
1140		    htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1141		  else
1142		    htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
1143		}
1144	    }
1145
1146	  /* TLS_IE needs one dynamic reloc and one GOT slot.  */
1147	  if (tls_type & GOT_TLS_IE)
1148	    {
1149	      s->size += GOT_ENTRY_SIZE;
1150
1151	      if (bfd_link_executable (info))
1152		{
1153		  /* Link exe and not defined local.  */
1154		  if (!SYMBOL_REFERENCES_LOCAL (info, h))
1155		    htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1156		}
1157	      else
1158		{
1159		  htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1160		}
1161	    }
1162	}
1163      else
1164	{
1165	  s->size += GOT_ENTRY_SIZE;
1166	  if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1167	       || h->root.type != bfd_link_hash_undefweak)
1168	      && (bfd_link_pic (info)
1169		  || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info),
1170						      h))
1171	      && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
1172	      /* Undefined weak symbol in static PIE resolves to 0 without
1173		 any dynamic relocations.  */
1174	    htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1175	}
1176    }
1177  else
1178    h->got.offset = MINUS_ONE;
1179
1180  if (h->dyn_relocs == NULL)
1181    return true;
1182
1183  /* Extra dynamic relocate,
1184   * R_LARCH_64
1185   * R_LARCH_TLS_DTPRELNN
1186   * R_LARCH_JUMP_SLOT
1187   * R_LARCH_NN.  */
1188
1189  if (SYMBOL_CALLS_LOCAL (info, h))
1190    {
1191      struct elf_dyn_relocs **pp;
1192
1193      for (pp = &h->dyn_relocs; (p = *pp) != NULL;)
1194	{
1195	  p->count -= p->pc_count;
1196	  p->pc_count = 0;
1197	  if (p->count == 0)
1198	    *pp = p->next;
1199	  else
1200	    pp = &p->next;
1201	}
1202    }
1203
1204  if (h->root.type == bfd_link_hash_undefweak)
1205    {
1206      if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)
1207	  || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1208	  || (!bfd_link_pic (info) && h->non_got_ref))
1209	h->dyn_relocs = NULL;
1210      else if (h->dynindx == -1 && !h->forced_local)
1211	{
1212	  /* Make sure this symbol is output as a dynamic symbol.
1213	     Undefined weak syms won't yet be marked as dynamic.  */
1214	  if (!bfd_elf_link_record_dynamic_symbol (info, h))
1215	    return false;
1216
1217	  if (h->dynindx == -1)
1218	    h->dyn_relocs = NULL;
1219	}
1220    }
1221
1222  for (p = h->dyn_relocs; p != NULL; p = p->next)
1223    {
1224      asection *sreloc = elf_section_data (p->sec)->sreloc;
1225      sreloc->size += p->count * sizeof (ElfNN_External_Rela);
1226    }
1227
1228  return true;
1229}
1230
1231/* A modified version of _bfd_elf_allocate_ifunc_dyn_relocs.
1232   For local def and ref ifunc,
1233   dynamic relocations are stored in
1234   1.  rela.srelgot section in dynamic object (dll or exec).
1235   2.  rela.irelplt section in static executable.
1236   Unlike _bfd_elf_allocate_ifunc_dyn_relocs, rela.srelgot is used
1237   instead of rela.srelplt.  Glibc ELF loader will not support
1238   R_LARCH_IRELATIVE relocation in rela.plt.  */
1239
1240static bool
1241local_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
1242				    struct elf_link_hash_entry *h,
1243				    struct elf_dyn_relocs **head,
1244				    unsigned int plt_entry_size,
1245				    unsigned int plt_header_size,
1246				    unsigned int got_entry_size,
1247				    bool avoid_plt)
1248{
1249  asection *plt, *gotplt, *relplt;
1250  struct elf_dyn_relocs *p;
1251  unsigned int sizeof_reloc;
1252  const struct elf_backend_data *bed;
1253  struct elf_link_hash_table *htab;
1254  /* If AVOID_PLT is TRUE, don't use PLT if possible.  */
1255  bool use_plt = !avoid_plt || h->plt.refcount > 0;
1256  bool need_dynreloc = !use_plt || bfd_link_pic (info);
1257
1258  /* When a PIC object references a STT_GNU_IFUNC symbol defined
1259     in executable or it isn't referenced via PLT, the address of
1260     the resolved function may be used.  But in non-PIC executable,
1261     the address of its plt slot may be used.  Pointer equality may
1262     not work correctly.  PIE or non-PLT reference should be used if
1263     pointer equality is required here.
1264
1265     If STT_GNU_IFUNC symbol is defined in position-dependent executable,
1266     backend should change it to the normal function and set its address
1267     to its PLT entry which should be resolved by R_*_IRELATIVE at
1268     run-time.  All external references should be resolved to its PLT in
1269     executable.  */
1270  if (!need_dynreloc
1271      && !(bfd_link_pde (info) && h->def_regular)
1272      && (h->dynindx != -1
1273	  || info->export_dynamic)
1274      && h->pointer_equality_needed)
1275    {
1276      info->callbacks->einfo
1277	/* xgettext:c-format.  */
1278	(_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer "
1279	   "equality in `%pB' can not be used when making an "
1280	   "executable; recompile with -fPIE and relink with -pie\n"),
1281	 h->root.root.string,
1282	 h->root.u.def.section->owner);
1283      bfd_set_error (bfd_error_bad_value);
1284      return false;
1285    }
1286
1287  htab = elf_hash_table (info);
1288
1289  /* When the symbol is marked with regular reference, if PLT isn't used
1290     or we are building a PIC object, we must keep dynamic relocation
1291     if there is non-GOT reference and use PLT if there is PC-relative
1292     reference.  */
1293  if (need_dynreloc && h->ref_regular)
1294    {
1295      bool keep = false;
1296      for (p = *head; p != NULL; p = p->next)
1297	if (p->count)
1298	  {
1299	    h->non_got_ref = 1;
1300	    /* Need dynamic relocations for non-GOT reference.  */
1301	    keep = true;
1302	    if (p->pc_count)
1303	      {
1304		/* Must use PLT for PC-relative reference.  */
1305		use_plt = true;
1306		need_dynreloc = bfd_link_pic (info);
1307		break;
1308	      }
1309	  }
1310      if (keep)
1311	goto keep;
1312    }
1313
1314  /* Support garbage collection against STT_GNU_IFUNC symbols.  */
1315  if (h->plt.refcount <= 0 && h->got.refcount <= 0)
1316    {
1317      h->got = htab->init_got_offset;
1318      h->plt = htab->init_plt_offset;
1319      *head = NULL;
1320      return true;
1321    }
1322
1323  /* Return and discard space for dynamic relocations against it if
1324     it is never referenced.  */
1325  if (!h->ref_regular)
1326    {
1327      if (h->plt.refcount > 0
1328	  || h->got.refcount > 0)
1329	abort ();
1330      h->got = htab->init_got_offset;
1331      h->plt = htab->init_plt_offset;
1332      *head = NULL;
1333      return true;
1334    }
1335
1336 keep:
1337  bed = get_elf_backend_data (info->output_bfd);
1338  if (bed->rela_plts_and_copies_p)
1339    sizeof_reloc = bed->s->sizeof_rela;
1340  else
1341    sizeof_reloc = bed->s->sizeof_rel;
1342
1343  /* When building a static executable, use iplt, igot.plt and
1344     rela.iplt sections for STT_GNU_IFUNC symbols.  */
1345  if (htab->splt != NULL)
1346    {
1347      plt = htab->splt;
1348      gotplt = htab->sgotplt;
1349      /* Change dynamic info of ifunc gotplt from srelplt to srelgot.  */
1350      relplt = htab->srelgot;
1351
1352      /* If this is the first plt entry and PLT is used, make room for
1353	 the special first entry.  */
1354      if (plt->size == 0 && use_plt)
1355	plt->size += plt_header_size;
1356    }
1357  else
1358    {
1359      plt = htab->iplt;
1360      gotplt = htab->igotplt;
1361      relplt = htab->irelplt;
1362    }
1363
1364  if (use_plt)
1365    {
1366      /* Don't update value of STT_GNU_IFUNC symbol to PLT.  We need
1367	 the original value for R_*_IRELATIVE.  */
1368      h->plt.offset = plt->size;
1369
1370      /* Make room for this entry in the plt/iplt section.  */
1371      plt->size += plt_entry_size;
1372
1373      /* We also need to make an entry in the got.plt/got.iplt section,
1374	 which will be placed in the got section by the linker script.  */
1375      gotplt->size += got_entry_size;
1376    }
1377
1378  /* We also need to make an entry in the rela.plt/.rela.iplt
1379     section for GOTPLT relocation if PLT is used.  */
1380  if (use_plt)
1381    {
1382      relplt->size += sizeof_reloc;
1383      relplt->reloc_count++;
1384    }
1385
1386  /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
1387     there is a non-GOT reference in a PIC object or PLT isn't used.  */
1388  if (!need_dynreloc || !h->non_got_ref)
1389    *head = NULL;
1390
1391  /* Finally, allocate space.  */
1392  p = *head;
1393  if (p != NULL)
1394    {
1395      bfd_size_type count = 0;
1396      do
1397	{
1398	  count += p->count;
1399	  p = p->next;
1400	}
1401      while (p != NULL);
1402
1403      htab->ifunc_resolvers = count != 0;
1404
1405      /* Dynamic relocations are stored in
1406	 1.  rela.srelgot section in PIC object.
1407	 2.  rela.srelgot section in dynamic executable.
1408	 3.  rela.irelplt section in static executable.  */
1409      if (htab->splt != NULL)
1410	htab->srelgot->size += count * sizeof_reloc;
1411      else
1412	{
1413	  relplt->size += count * sizeof_reloc;
1414	  relplt->reloc_count += count;
1415	}
1416    }
1417
1418  /* For STT_GNU_IFUNC symbol, got.plt has the real function address
1419     and got has the PLT entry adddress.  We will load the GOT entry
1420     with the PLT entry in finish_dynamic_symbol if it is used.  For
1421     branch, it uses got.plt.  For symbol value, if PLT is used,
1422     1.  Use got.plt in a PIC object if it is forced local or not
1423     dynamic.
1424     2.  Use got.plt in a non-PIC object if pointer equality isn't
1425     needed.
1426     3.  Use got.plt in PIE.
1427     4.  Use got.plt if got isn't used.
1428     5.  Otherwise use got so that it can be shared among different
1429     objects at run-time.
1430     If PLT isn't used, always use got for symbol value.
1431     We only need to relocate got entry in PIC object or in dynamic
1432     executable without PLT.  */
1433  if (use_plt
1434      && (h->got.refcount <= 0
1435	  || (bfd_link_pic (info)
1436	      && (h->dynindx == -1
1437		  || h->forced_local))
1438	  || (
1439	      !h->pointer_equality_needed)
1440	  || htab->sgot == NULL))
1441    {
1442      /* Use got.plt.  */
1443      h->got.offset = (bfd_vma) -1;
1444    }
1445  else
1446    {
1447      if (!use_plt)
1448	{
1449	  /* PLT isn't used.  */
1450	  h->plt.offset = (bfd_vma) -1;
1451	}
1452      if (h->got.refcount <= 0)
1453	{
1454	  /* GOT isn't need when there are only relocations for static
1455	     pointers.  */
1456	  h->got.offset = (bfd_vma) -1;
1457	}
1458      else
1459	{
1460	  h->got.offset = htab->sgot->size;
1461	  htab->sgot->size += got_entry_size;
1462	  /* Need to relocate the GOT entry in a PIC object or PLT isn't
1463	     used.  Otherwise, the GOT entry will be filled with the PLT
1464	     entry and dynamic GOT relocation isn't needed.  */
1465	  if (need_dynreloc)
1466	    {
1467	      /* For non-static executable, dynamic GOT relocation is in
1468		 rela.got section, but for static executable, it is
1469		 in rela.iplt section.  */
1470	      if (htab->splt != NULL)
1471		htab->srelgot->size += sizeof_reloc;
1472	      else
1473		{
1474		  relplt->size += sizeof_reloc;
1475		  relplt->reloc_count++;
1476		}
1477	    }
1478	}
1479    }
1480
1481  return true;
1482}
1483
1484/* Allocate space in .plt, .got and associated reloc sections for
1485   ifunc dynamic relocs.  */
1486
1487static bool
1488elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf)
1489{
1490  struct bfd_link_info *info;
1491  /* An example of a bfd_link_hash_indirect symbol is versioned
1492     symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
1493     -> __gxx_personality_v0(bfd_link_hash_defined)
1494
1495     There is no need to process bfd_link_hash_indirect symbols here
1496     because we will also be presented with the concrete instance of
1497     the symbol and loongarch_elf_copy_indirect_symbol () will have been
1498     called to copy all relevant data from the generic to the concrete
1499     symbol instance.  */
1500  if (h->root.type == bfd_link_hash_indirect)
1501    return true;
1502
1503  if (h->root.type == bfd_link_hash_warning)
1504    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1505
1506  info = (struct bfd_link_info *) inf;
1507
1508  /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1509     here if it is defined and referenced in a non-shared object.  */
1510  if (h->type == STT_GNU_IFUNC && h->def_regular)
1511    {
1512      if (SYMBOL_REFERENCES_LOCAL (info, h))
1513	return local_allocate_ifunc_dyn_relocs (info, h,
1514						&h->dyn_relocs,
1515						PLT_ENTRY_SIZE,
1516						PLT_HEADER_SIZE,
1517						GOT_ENTRY_SIZE,
1518						false);
1519      else
1520	return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
1521						   &h->dyn_relocs,
1522						   PLT_ENTRY_SIZE,
1523						   PLT_HEADER_SIZE,
1524						   GOT_ENTRY_SIZE,
1525						   false);
1526    }
1527
1528  return true;
1529}
1530
1531/* Allocate space in .plt, .got and associated reloc sections for
1532   ifunc dynamic relocs.  */
1533
1534static bool
1535elfNN_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
1536{
1537  struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
1538
1539  if (h->type != STT_GNU_IFUNC
1540      || !h->def_regular
1541      || !h->ref_regular
1542      || !h->forced_local
1543      || h->root.type != bfd_link_hash_defined)
1544    abort ();
1545
1546  return elfNN_allocate_ifunc_dynrelocs (h, inf);
1547}
1548
1549/* Set DF_TEXTREL if we find any dynamic relocs that apply to
1550   read-only sections.  */
1551
1552static bool
1553maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
1554{
1555  asection *sec;
1556
1557  if (h->root.type == bfd_link_hash_indirect)
1558    return true;
1559
1560  sec = readonly_dynrelocs (h);
1561  if (sec != NULL)
1562    {
1563      struct bfd_link_info *info = (struct bfd_link_info *) info_p;
1564
1565      info->flags |= DF_TEXTREL;
1566      info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' in "
1567				"read-only section `%pA'\n"),
1568			      sec->owner, h->root.root.string, sec);
1569
1570      /* Not an error, just cut short the traversal.  */
1571      return false;
1572    }
1573  return true;
1574}
1575
1576static bool
1577loongarch_elf_size_dynamic_sections (bfd *output_bfd,
1578				     struct bfd_link_info *info)
1579{
1580  struct loongarch_elf_link_hash_table *htab;
1581  bfd *dynobj;
1582  asection *s;
1583  bfd *ibfd;
1584
1585  htab = loongarch_elf_hash_table (info);
1586  BFD_ASSERT (htab != NULL);
1587  dynobj = htab->elf.dynobj;
1588  BFD_ASSERT (dynobj != NULL);
1589
1590  if (htab->elf.dynamic_sections_created)
1591    {
1592      /* Set the contents of the .interp section to the interpreter.  */
1593      if (bfd_link_executable (info) && !info->nointerp)
1594	{
1595	  const char *interpreter;
1596	  s = bfd_get_linker_section (dynobj, ".interp");
1597	  BFD_ASSERT (s != NULL);
1598
1599	  if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS32)
1600	    interpreter = "/lib32/ld.so.1";
1601	  else if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS64)
1602	    interpreter = "/lib64/ld.so.1";
1603	  else
1604	    interpreter = "/lib/ld.so.1";
1605
1606	  s->contents = (unsigned char *) interpreter;
1607	  s->size = strlen (interpreter) + 1;
1608	}
1609    }
1610
1611  /* Set up .got offsets for local syms, and space for local dynamic
1612     relocs.  */
1613  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
1614    {
1615      bfd_signed_vma *local_got;
1616      bfd_signed_vma *end_local_got;
1617      char *local_tls_type;
1618      bfd_size_type locsymcount;
1619      Elf_Internal_Shdr *symtab_hdr;
1620      asection *srel;
1621
1622      if (!is_loongarch_elf (ibfd))
1623	continue;
1624
1625      for (s = ibfd->sections; s != NULL; s = s->next)
1626	{
1627	  struct elf_dyn_relocs *p;
1628
1629	  for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
1630	    {
1631	      p->count -= p->pc_count;
1632	      if (!bfd_is_abs_section (p->sec)
1633		  && bfd_is_abs_section (p->sec->output_section))
1634		{
1635		  /* Input section has been discarded, either because
1636		     it is a copy of a linkonce section or due to
1637		     linker script /DISCARD/, so we'll be discarding
1638		     the relocs too.  */
1639		}
1640	      else if (0 < p->count)
1641		{
1642		  srel = elf_section_data (p->sec)->sreloc;
1643		  srel->size += p->count * sizeof (ElfNN_External_Rela);
1644		  if ((p->sec->output_section->flags & SEC_READONLY) != 0)
1645		    info->flags |= DF_TEXTREL;
1646		}
1647	    }
1648	}
1649
1650      local_got = elf_local_got_refcounts (ibfd);
1651      if (!local_got)
1652	continue;
1653
1654      symtab_hdr = &elf_symtab_hdr (ibfd);
1655      locsymcount = symtab_hdr->sh_info;
1656      end_local_got = local_got + locsymcount;
1657      local_tls_type = _bfd_loongarch_elf_local_got_tls_type (ibfd);
1658      s = htab->elf.sgot;
1659      srel = htab->elf.srelgot;
1660      for (; local_got < end_local_got; ++local_got, ++local_tls_type)
1661	{
1662	  if (0 < *local_got)
1663	    {
1664	      *local_got = s->size;
1665
1666	      /* TLS gd use two got.  */
1667	      if (*local_tls_type & GOT_TLS_GD)
1668		s->size += GOT_ENTRY_SIZE * 2;
1669	      else
1670		/* Normal got, tls ie/ld use one got.  */
1671		s->size += GOT_ENTRY_SIZE;
1672
1673	      if (bfd_link_executable (info)
1674		  && (*local_tls_type & (GOT_TLS_GD| GOT_TLS_IE)))
1675		;/* Do nothing.  */
1676	      else
1677		{
1678		  srel->size += sizeof (ElfNN_External_Rela);
1679		}
1680	    }
1681	  else
1682	    *local_got = MINUS_ONE;
1683	}
1684    }
1685
1686  /* Allocate global sym .plt and .got entries, and space for global
1687     sym dynamic relocs.  */
1688  elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
1689
1690  /* Allocate global ifunc sym .plt and .got entries, and space for global
1691     ifunc sym dynamic relocs.  */
1692  elf_link_hash_traverse (&htab->elf, elfNN_allocate_ifunc_dynrelocs, info);
1693
1694  /* Allocate .plt and .got entries, and space for local ifunc symbols.  */
1695  htab_traverse (htab->loc_hash_table,
1696		 (void *) elfNN_allocate_local_ifunc_dynrelocs, info);
1697
1698  /* Don't allocate .got.plt section if there are no PLT.  */
1699  if (htab->elf.sgotplt && htab->elf.sgotplt->size == GOTPLT_HEADER_SIZE
1700      && (htab->elf.splt == NULL || htab->elf.splt->size == 0))
1701    htab->elf.sgotplt->size = 0;
1702
1703  /* The check_relocs and adjust_dynamic_symbol entry points have
1704     determined the sizes of the various dynamic sections.  Allocate
1705     memory for them.  */
1706  for (s = dynobj->sections; s != NULL; s = s->next)
1707    {
1708      if ((s->flags & SEC_LINKER_CREATED) == 0)
1709	continue;
1710
1711      if (s == htab->elf.splt || s == htab->elf.iplt || s == htab->elf.sgot
1712	  || s == htab->elf.sgotplt || s == htab->elf.igotplt
1713	  || s == htab->elf.sdynbss || s == htab->elf.sdynrelro)
1714	{
1715	  /* Strip this section if we don't need it; see the
1716	     comment below.  */
1717	}
1718      else if (strncmp (s->name, ".rela", 5) == 0)
1719	{
1720	  if (s->size != 0)
1721	    {
1722	      /* We use the reloc_count field as a counter if we need
1723		 to copy relocs into the output file.  */
1724	      s->reloc_count = 0;
1725	    }
1726	}
1727      else
1728	{
1729	  /* It's not one of our sections.  */
1730	  continue;
1731	}
1732
1733      if (s->size == 0)
1734	{
1735	  /* If we don't need this section, strip it from the
1736	     output file.  This is mostly to handle .rela.bss and
1737	     .rela.plt.  We must create both sections in
1738	     create_dynamic_sections, because they must be created
1739	     before the linker maps input sections to output
1740	     sections.  The linker does that before
1741	     adjust_dynamic_symbol is called, and it is that
1742	     function which decides whether anything needs to go
1743	     into these sections.  */
1744	  s->flags |= SEC_EXCLUDE;
1745	  continue;
1746	}
1747
1748      if ((s->flags & SEC_HAS_CONTENTS) == 0)
1749	continue;
1750
1751      /* Allocate memory for the section contents.  Zero the memory
1752	 for the benefit of .rela.plt, which has 4 unused entries
1753	 at the beginning, and we don't want garbage.  */
1754      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
1755      if (s->contents == NULL)
1756	return false;
1757    }
1758
1759  if (elf_hash_table (info)->dynamic_sections_created)
1760    {
1761      /* Add some entries to the .dynamic section.  We fill in the
1762	 values later, in loongarch_elf_finish_dynamic_sections, but we
1763	 must add the entries now so that we get the correct size for
1764	 the .dynamic section.  The DT_DEBUG entry is filled in by the
1765	 dynamic linker and used by the debugger.  */
1766#define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL)
1767
1768      if (bfd_link_executable (info))
1769	{
1770	  if (!add_dynamic_entry (DT_DEBUG, 0))
1771	    return false;
1772	}
1773
1774      if (htab->elf.srelplt->size != 0)
1775	{
1776	  if (!add_dynamic_entry (DT_PLTGOT, 0)
1777	      || !add_dynamic_entry (DT_PLTRELSZ, 0)
1778	      || !add_dynamic_entry (DT_PLTREL, DT_RELA)
1779	      || !add_dynamic_entry (DT_JMPREL, 0))
1780	    return false;
1781	}
1782
1783      if (!add_dynamic_entry (DT_RELA, 0)
1784	  || !add_dynamic_entry (DT_RELASZ, 0)
1785	  || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
1786	return false;
1787
1788      /* If any dynamic relocs apply to a read-only section,
1789	 then we need a DT_TEXTREL entry.  */
1790      if ((info->flags & DF_TEXTREL) == 0)
1791	elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
1792
1793      if (info->flags & DF_TEXTREL)
1794	{
1795	  if (!add_dynamic_entry (DT_TEXTREL, 0))
1796	    return false;
1797	  /* Clear the DF_TEXTREL flag.  It will be set again if we
1798	     write out an actual text relocation; we may not, because
1799	     at this point we do not know whether e.g.  any .eh_frame
1800	     absolute relocations have been converted to PC-relative.  */
1801	  info->flags &= ~DF_TEXTREL;
1802	}
1803    }
1804#undef add_dynamic_entry
1805
1806  return true;
1807}
1808
1809#define LARCH_LD_STACK_DEPTH 16
1810static int64_t larch_opc_stack[LARCH_LD_STACK_DEPTH];
1811static size_t larch_stack_top = 0;
1812
1813static bfd_reloc_status_type
1814loongarch_push (int64_t val)
1815{
1816  if (LARCH_LD_STACK_DEPTH <= larch_stack_top)
1817    return bfd_reloc_outofrange;
1818  larch_opc_stack[larch_stack_top++] = val;
1819  return bfd_reloc_ok;
1820}
1821
1822static bfd_reloc_status_type
1823loongarch_pop (int64_t *val)
1824{
1825  if (larch_stack_top == 0)
1826    return bfd_reloc_outofrange;
1827  BFD_ASSERT (val);
1828  *val = larch_opc_stack[--larch_stack_top];
1829  return bfd_reloc_ok;
1830}
1831
1832static bfd_reloc_status_type
1833loongarch_top (int64_t *val)
1834{
1835  if (larch_stack_top == 0)
1836    return bfd_reloc_outofrange;
1837  BFD_ASSERT (val);
1838  *val = larch_opc_stack[larch_stack_top - 1];
1839  return bfd_reloc_ok;
1840}
1841
1842static void
1843loongarch_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
1844{
1845  BFD_ASSERT (s && s->contents);
1846  const struct elf_backend_data *bed;
1847  bfd_byte *loc;
1848
1849  bed = get_elf_backend_data (abfd);
1850  if (!(s->size > s->reloc_count * bed->s->sizeof_rela))
1851    BFD_ASSERT (s->size > s->reloc_count * bed->s->sizeof_rela);
1852  loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela);
1853  bed->s->swap_reloca_out (abfd, rel, loc);
1854}
1855
1856/* Check rel->r_offset in range of contents.  */
1857static bfd_reloc_status_type
1858loongarch_check_offset (const Elf_Internal_Rela *rel,
1859			const asection *input_section)
1860{
1861  if (0 == strcmp(input_section->name, ".text")
1862      && rel->r_offset > input_section->size)
1863    return bfd_reloc_overflow;
1864
1865  return bfd_reloc_ok;
1866}
1867
1868#define LARCH_RELOC_PERFORM_3OP(op1, op2, op3)	      \
1869  ({						      \
1870    bfd_reloc_status_type ret = loongarch_pop (&op2); \
1871    if (ret == bfd_reloc_ok)			      \
1872      {						      \
1873	ret = loongarch_pop (&op1);		      \
1874	if (ret == bfd_reloc_ok)		      \
1875	  ret = loongarch_push (op3);		      \
1876      }						      \
1877    ret;					      \
1878   })
1879
1880static bfd_reloc_status_type
1881loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela *rel,
1882				  const asection *input_section ATTRIBUTE_UNUSED,
1883				  reloc_howto_type *howto, bfd *input_bfd,
1884				  bfd_byte *contents, bfd_vma reloc_val)
1885{
1886  int bits = bfd_get_reloc_size (howto) * 8;
1887  uint32_t insn = bfd_get (bits, input_bfd, contents + rel->r_offset);
1888
1889  if (!loongarch_adjust_reloc_bitsfield(howto, &reloc_val))
1890    return bfd_reloc_overflow;
1891
1892  insn = (insn & (uint32_t)howto->src_mask)
1893    | ((insn & (~(uint32_t)howto->dst_mask)) | reloc_val);
1894
1895  bfd_put (bits, input_bfd, insn, contents + rel->r_offset);
1896
1897  return bfd_reloc_ok;
1898}
1899
1900static bfd_reloc_status_type
1901perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
1902		    reloc_howto_type *howto, bfd_vma value,
1903		    bfd *input_bfd, bfd_byte *contents)
1904{
1905  int64_t opr1, opr2, opr3;
1906  bfd_reloc_status_type r = bfd_reloc_ok;
1907  int bits = bfd_get_reloc_size (howto) * 8;
1908
1909  switch (ELFNN_R_TYPE (rel->r_info))
1910    {
1911    case R_LARCH_SOP_PUSH_PCREL:
1912    case R_LARCH_SOP_PUSH_ABSOLUTE:
1913    case R_LARCH_SOP_PUSH_GPREL:
1914    case R_LARCH_SOP_PUSH_TLS_TPREL:
1915    case R_LARCH_SOP_PUSH_TLS_GOT:
1916    case R_LARCH_SOP_PUSH_TLS_GD:
1917    case R_LARCH_SOP_PUSH_PLT_PCREL:
1918      r = loongarch_push (value);
1919      break;
1920
1921    case R_LARCH_SOP_PUSH_DUP:
1922      r = loongarch_pop (&opr1);
1923      if (r == bfd_reloc_ok)
1924	{
1925	  r = loongarch_push (opr1);
1926	  if (r == bfd_reloc_ok)
1927	    r = loongarch_push (opr1);
1928	}
1929      break;
1930
1931    case R_LARCH_SOP_ASSERT:
1932      r = loongarch_pop (&opr1);
1933      if (r != bfd_reloc_ok || !opr1)
1934	r = bfd_reloc_notsupported;
1935      break;
1936
1937    case R_LARCH_SOP_NOT:
1938      r = loongarch_pop (&opr1);
1939      if (r == bfd_reloc_ok)
1940	r = loongarch_push (!opr1);
1941      break;
1942
1943    case R_LARCH_SOP_SUB:
1944      r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 - opr2);
1945      break;
1946
1947    case R_LARCH_SOP_SL:
1948      r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 << opr2);
1949      break;
1950
1951    case R_LARCH_SOP_SR:
1952      r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 >> opr2);
1953      break;
1954
1955    case R_LARCH_SOP_AND:
1956      r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 & opr2);
1957      break;
1958
1959    case R_LARCH_SOP_ADD:
1960      r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 + opr2);
1961      break;
1962
1963    case R_LARCH_SOP_IF_ELSE:
1964      r = loongarch_pop (&opr3);
1965      if (r == bfd_reloc_ok)
1966	{
1967	  r = loongarch_pop (&opr2);
1968	  if (r == bfd_reloc_ok)
1969	    {
1970	      r = loongarch_pop (&opr1);
1971	      if (r == bfd_reloc_ok)
1972		r = loongarch_push (opr1 ? opr2 : opr3);
1973	    }
1974	}
1975      break;
1976
1977    case R_LARCH_SOP_POP_32_S_10_5:
1978    case R_LARCH_SOP_POP_32_S_10_12:
1979    case R_LARCH_SOP_POP_32_S_10_16:
1980    case R_LARCH_SOP_POP_32_S_10_16_S2:
1981    case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
1982    case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
1983    case R_LARCH_SOP_POP_32_S_5_20:
1984    case R_LARCH_SOP_POP_32_U_10_12:
1985    case R_LARCH_SOP_POP_32_U:
1986      r = loongarch_pop (&opr1);
1987      if (r != bfd_reloc_ok)
1988	break;
1989      r = loongarch_check_offset (rel, input_section);
1990      if (r != bfd_reloc_ok)
1991	break;
1992
1993      r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
1994					    howto, input_bfd,
1995					    contents, (bfd_vma)opr1);
1996      break;
1997
1998    case R_LARCH_TLS_DTPREL32:
1999    case R_LARCH_32:
2000    case R_LARCH_TLS_DTPREL64:
2001    case R_LARCH_64:
2002      r = loongarch_check_offset (rel, input_section);
2003      if (r != bfd_reloc_ok)
2004	break;
2005
2006      bfd_put (bits, input_bfd, value, contents + rel->r_offset);
2007      break;
2008
2009    case R_LARCH_ADD8:
2010    case R_LARCH_ADD16:
2011    case R_LARCH_ADD24:
2012    case R_LARCH_ADD32:
2013    case R_LARCH_ADD64:
2014      r = loongarch_check_offset (rel, input_section);
2015      if (r != bfd_reloc_ok)
2016	break;
2017
2018      opr1 = bfd_get (bits, input_bfd, contents + rel->r_offset);
2019      bfd_put (bits, input_bfd, opr1 + value, contents + rel->r_offset);
2020      break;
2021
2022    case R_LARCH_SUB8:
2023    case R_LARCH_SUB16:
2024    case R_LARCH_SUB24:
2025    case R_LARCH_SUB32:
2026    case R_LARCH_SUB64:
2027      r = loongarch_check_offset (rel, input_section);
2028      if (r != bfd_reloc_ok)
2029	break;
2030
2031      opr1 = bfd_get (bits, input_bfd, contents + rel->r_offset);
2032      bfd_put (bits, input_bfd, opr1 - value, contents + rel->r_offset);
2033      break;
2034
2035    /* For eh_frame and debug info.  */
2036    case R_LARCH_32_PCREL:
2037      value -= sec_addr (input_section) + rel->r_offset;
2038      value += rel->r_addend;
2039      bfd_vma word = bfd_get (howto->bitsize, input_bfd,
2040			      contents + rel->r_offset);
2041      word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
2042      bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2043      r = bfd_reloc_ok;
2044      break;
2045
2046    /* New reloc type.
2047       R_LARCH_B16 ~ R_LARCH_TLS_GD_HI20.  */
2048    case R_LARCH_B16:
2049    case R_LARCH_B21:
2050    case R_LARCH_B26:
2051    case R_LARCH_ABS_HI20:
2052    case R_LARCH_ABS_LO12:
2053    case R_LARCH_ABS64_LO20:
2054    case R_LARCH_ABS64_HI12:
2055    case R_LARCH_PCALA_HI20:
2056    case R_LARCH_PCALA_LO12:
2057    case R_LARCH_PCALA64_LO20:
2058    case R_LARCH_PCALA64_HI12:
2059    case R_LARCH_GOT_PC_HI20:
2060    case R_LARCH_GOT_PC_LO12:
2061    case R_LARCH_GOT64_PC_LO20:
2062    case R_LARCH_GOT64_PC_HI12:
2063    case R_LARCH_GOT_HI20:
2064    case R_LARCH_GOT_LO12:
2065    case R_LARCH_GOT64_LO20:
2066    case R_LARCH_GOT64_HI12:
2067    case R_LARCH_TLS_LE_HI20:
2068    case R_LARCH_TLS_LE_LO12:
2069    case R_LARCH_TLS_LE64_LO20:
2070    case R_LARCH_TLS_LE64_HI12:
2071    case R_LARCH_TLS_IE_PC_HI20:
2072    case R_LARCH_TLS_IE_PC_LO12:
2073    case R_LARCH_TLS_IE64_PC_LO20:
2074    case R_LARCH_TLS_IE64_PC_HI12:
2075    case R_LARCH_TLS_IE_HI20:
2076    case R_LARCH_TLS_IE_LO12:
2077    case R_LARCH_TLS_IE64_LO20:
2078    case R_LARCH_TLS_IE64_HI12:
2079    case R_LARCH_TLS_LD_PC_HI20:
2080    case R_LARCH_TLS_LD_HI20:
2081    case R_LARCH_TLS_GD_PC_HI20:
2082    case R_LARCH_TLS_GD_HI20:
2083      r = loongarch_check_offset (rel, input_section);
2084      if (r != bfd_reloc_ok)
2085	break;
2086
2087      r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
2088					    howto, input_bfd,
2089					    contents, value);
2090      break;
2091
2092    case R_LARCH_RELAX:
2093      break;
2094
2095    default:
2096      r = bfd_reloc_notsupported;
2097    }
2098  return r;
2099}
2100
2101#define LARCH_RECENT_RELOC_QUEUE_LENGTH 72
2102static struct
2103{
2104  bfd *bfd;
2105  asection *section;
2106  bfd_vma r_offset;
2107  int r_type;
2108  bfd_vma relocation;
2109  Elf_Internal_Sym *sym;
2110  struct elf_link_hash_entry *h;
2111  bfd_vma addend;
2112  int64_t top_then;
2113} larch_reloc_queue[LARCH_RECENT_RELOC_QUEUE_LENGTH];
2114static size_t larch_reloc_queue_head = 0;
2115static size_t larch_reloc_queue_tail = 0;
2116
2117static const char *
2118loongarch_sym_name (bfd *input_bfd, struct elf_link_hash_entry *h,
2119		    Elf_Internal_Sym *sym)
2120{
2121  const char *ret = NULL;
2122  if (sym)
2123    ret = bfd_elf_string_from_elf_section (input_bfd,
2124					   elf_symtab_hdr (input_bfd).sh_link,
2125					   sym->st_name);
2126  else if (h)
2127    ret = h->root.root.string;
2128
2129  if (ret == NULL || *ret == '\0')
2130    ret = "<nameless>";
2131  return ret;
2132}
2133
2134static void
2135loongarch_record_one_reloc (bfd *abfd, asection *section, int r_type,
2136			    bfd_vma r_offset, Elf_Internal_Sym *sym,
2137			    struct elf_link_hash_entry *h, bfd_vma addend)
2138{
2139  if ((larch_reloc_queue_head == 0
2140       && larch_reloc_queue_tail == LARCH_RECENT_RELOC_QUEUE_LENGTH - 1)
2141      || larch_reloc_queue_head == larch_reloc_queue_tail + 1)
2142    larch_reloc_queue_head =
2143      (larch_reloc_queue_head + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2144  larch_reloc_queue[larch_reloc_queue_tail].bfd = abfd;
2145  larch_reloc_queue[larch_reloc_queue_tail].section = section;
2146  larch_reloc_queue[larch_reloc_queue_tail].r_offset = r_offset;
2147  larch_reloc_queue[larch_reloc_queue_tail].r_type = r_type;
2148  larch_reloc_queue[larch_reloc_queue_tail].sym = sym;
2149  larch_reloc_queue[larch_reloc_queue_tail].h = h;
2150  larch_reloc_queue[larch_reloc_queue_tail].addend = addend;
2151  loongarch_top (&larch_reloc_queue[larch_reloc_queue_tail].top_then);
2152  larch_reloc_queue_tail =
2153    (larch_reloc_queue_tail + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2154}
2155
2156static void
2157loongarch_dump_reloc_record (void (*p) (const char *fmt, ...))
2158{
2159  size_t i = larch_reloc_queue_head;
2160  bfd *a_bfd = NULL;
2161  asection *section = NULL;
2162  bfd_vma r_offset = 0;
2163  int inited = 0;
2164  p ("Dump relocate record:\n");
2165  p ("stack top\t\trelocation name\t\tsymbol");
2166  while (i != larch_reloc_queue_tail)
2167    {
2168      if (a_bfd != larch_reloc_queue[i].bfd
2169	  || section != larch_reloc_queue[i].section
2170	  || r_offset != larch_reloc_queue[i].r_offset)
2171	{
2172	  a_bfd = larch_reloc_queue[i].bfd;
2173	  section = larch_reloc_queue[i].section;
2174	  r_offset = larch_reloc_queue[i].r_offset;
2175	  p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue[i].bfd,
2176	     larch_reloc_queue[i].section, larch_reloc_queue[i].r_offset);
2177	}
2178
2179      if (!inited)
2180	inited = 1, p ("...\n");
2181
2182      reloc_howto_type *howto =
2183	loongarch_elf_rtype_to_howto (larch_reloc_queue[i].bfd,
2184				      larch_reloc_queue[i].r_type);
2185      p ("0x%V %s\t`%s'", (bfd_vma) larch_reloc_queue[i].top_then,
2186	 howto ? howto->name : "<unknown reloc>",
2187	 loongarch_sym_name (larch_reloc_queue[i].bfd, larch_reloc_queue[i].h,
2188			     larch_reloc_queue[i].sym));
2189
2190      long addend = larch_reloc_queue[i].addend;
2191      if (addend < 0)
2192	p (" - %ld", -addend);
2193      else if (0 < addend)
2194	p (" + %ld(0x%v)", addend, larch_reloc_queue[i].addend);
2195
2196      p ("\n");
2197      i = (i + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2198    }
2199  p ("\n"
2200     "-- Record dump end --\n\n");
2201}
2202
2203static bool
2204loongarch_reloc_is_fatal (struct bfd_link_info *info,
2205			  bfd *input_bfd,
2206			  asection *input_section,
2207			  Elf_Internal_Rela *rel,
2208			  reloc_howto_type *howto,
2209			  bfd_reloc_status_type rtype,
2210			  bool is_undefweak,
2211			  const char *name,
2212			  const char *msg)
2213{
2214  bool fatal = true;
2215  switch (rtype)
2216    {
2217      /* 'dangerous' means we do it but can't promise it's ok
2218	 'unsupport' means out of ability of relocation type
2219	 'undefined' means we can't deal with the undefined symbol.  */
2220    case bfd_reloc_undefined:
2221      info->callbacks->undefined_symbol (info, name, input_bfd, input_section,
2222					 rel->r_offset, true);
2223      info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2224			     input_bfd, input_section, rel->r_offset,
2225			     howto->name,
2226			     is_undefweak ? "[undefweak] " : "", name, msg);
2227      break;
2228    case bfd_reloc_dangerous:
2229      info->callbacks->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n",
2230			     input_bfd, input_section, rel->r_offset,
2231			     howto->name,
2232			     is_undefweak ? "[undefweak] " : "", name, msg);
2233      fatal = false;
2234      break;
2235    case bfd_reloc_notsupported:
2236      info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2237			     input_bfd, input_section, rel->r_offset,
2238			     howto->name,
2239			     is_undefweak ? "[undefweak] " : "", name, msg);
2240      break;
2241    default:
2242      break;
2243    }
2244  return fatal;
2245}
2246
2247#define RELOCATE_CALC_PC32_HI20(relocation, pc) 	\
2248  ({							\
2249    bfd_vma lo = (relocation) & ((bfd_vma)0xfff);	\
2250    pc = pc & (~(bfd_vma)0xfff);			\
2251    if (lo > 0x7ff)					\
2252      {							\
2253	relocation += 0x1000;				\
2254      } 						\
2255    relocation &= ~(bfd_vma)0xfff;			\
2256    relocation -= pc;					\
2257  })
2258
2259#define RELOCATE_CALC_PC64_HI32(relocation, pc)  	\
2260  ({							\
2261    bfd_vma lo = (relocation) & ((bfd_vma)0xfff);	\
2262    if (lo > 0x7ff)					\
2263      { 						\
2264	relocation -= 0x100000000;      		\
2265      }  						\
2266    relocation -= (pc & ~(bfd_vma)0xffffffff);  	\
2267  })
2268
2269static int
2270loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
2271				bfd *input_bfd, asection *input_section,
2272				bfd_byte *contents, Elf_Internal_Rela *relocs,
2273				Elf_Internal_Sym *local_syms,
2274				asection **local_sections)
2275{
2276  Elf_Internal_Rela *rel;
2277  Elf_Internal_Rela *relend;
2278  bool fatal = false;
2279  asection *sreloc = elf_section_data (input_section)->sreloc;
2280  struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
2281  Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd);
2282  struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
2283  bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd);
2284  bool is_pic = bfd_link_pic (info);
2285  bool is_dyn = elf_hash_table (info)->dynamic_sections_created;
2286  asection *plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
2287  asection *got = htab->elf.sgot;
2288
2289  relend = relocs + input_section->reloc_count;
2290  for (rel = relocs; rel < relend; rel++)
2291    {
2292      int r_type = ELFNN_R_TYPE (rel->r_info);
2293      unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
2294      bfd_vma pc = sec_addr (input_section) + rel->r_offset;
2295      reloc_howto_type *howto = NULL;
2296      asection *sec = NULL;
2297      Elf_Internal_Sym *sym = NULL;
2298      struct elf_link_hash_entry *h = NULL;
2299      const char *name;
2300      bfd_reloc_status_type r = bfd_reloc_ok;
2301      bool is_ie, is_undefweak, unresolved_reloc, defined_local;
2302      bool resolved_local, resolved_dynly, resolved_to_const;
2303      char tls_type;
2304      bfd_vma relocation, off, ie_off;
2305      int i, j;
2306
2307      howto = loongarch_elf_rtype_to_howto (input_bfd, r_type);
2308      if (howto == NULL || r_type == R_LARCH_GNU_VTINHERIT
2309	  || r_type == R_LARCH_GNU_VTENTRY)
2310	continue;
2311
2312      /* This is a final link.  */
2313      if (r_symndx < symtab_hdr->sh_info)
2314	{
2315	  is_undefweak = false;
2316	  unresolved_reloc = false;
2317	  sym = local_syms + r_symndx;
2318	  sec = local_sections[r_symndx];
2319	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2320
2321	  /* Relocate against local STT_GNU_IFUNC symbol.  */
2322	  if (!bfd_link_relocatable (info)
2323	      && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
2324	    {
2325	      h = elfNN_loongarch_get_local_sym_hash (htab, input_bfd, rel,
2326						      false);
2327	      if (h == NULL)
2328		abort ();
2329
2330	      /* Set STT_GNU_IFUNC symbol value.  */
2331	      h->root.u.def.value = sym->st_value;
2332	      h->root.u.def.section = sec;
2333	    }
2334	  defined_local = true;
2335	  resolved_local = true;
2336	  resolved_dynly = false;
2337	  resolved_to_const = false;
2338
2339	  /* Calc in funtion elf_link_input_bfd,
2340	   * if #define elf_backend_rela_normal to 1.  */
2341	  if (bfd_link_relocatable (info)
2342	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2343	    continue;
2344	}
2345      else
2346	{
2347	  bool warned, ignored;
2348
2349	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2350				   r_symndx, symtab_hdr, sym_hashes,
2351				   h, sec, relocation,
2352				   unresolved_reloc, warned, ignored);
2353	  /* Here means symbol isn't local symbol only and 'h != NULL'.  */
2354
2355	  /* The 'unresolved_syms_in_objects' specify how to deal with undefined
2356	     symbol.  And 'dynamic_undefined_weak' specify what to do when
2357	     meeting undefweak.  */
2358
2359	  if ((is_undefweak = h->root.type == bfd_link_hash_undefweak))
2360	    {
2361	      defined_local = false;
2362	      resolved_local = false;
2363	      resolved_to_const = (!is_dyn || h->dynindx == -1
2364				   || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
2365	      resolved_dynly = !resolved_local && !resolved_to_const;
2366	    }
2367	  else if (warned)
2368	    {
2369	      /* Symbol undefined offen means failed already.  I don't know why
2370		 'warned' here but I guess it want to continue relocating as if
2371		 no error occures to find other errors as more as possible.  */
2372
2373	      /* To avoid generating warning messages about truncated
2374		 relocations, set the relocation's address to be the same as
2375		 the start of this section.  */
2376	      relocation = (input_section->output_section
2377			    ? input_section->output_section->vma
2378			    : 0);
2379
2380	      defined_local = relocation != 0;
2381	      resolved_local = defined_local;
2382	      resolved_to_const = !resolved_local;
2383	      resolved_dynly = false;
2384	    }
2385	  else
2386	    {
2387	      defined_local = !unresolved_reloc && !ignored;
2388	      resolved_local =
2389		defined_local && SYMBOL_REFERENCES_LOCAL (info, h);
2390	      resolved_dynly = !resolved_local;
2391	      resolved_to_const = !resolved_local && !resolved_dynly;
2392	    }
2393	}
2394
2395      name = loongarch_sym_name (input_bfd, h, sym);
2396
2397      if (sec != NULL && discarded_section (sec))
2398	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel,
2399					 1, relend, howto, 0, contents);
2400
2401      if (bfd_link_relocatable (info))
2402	continue;
2403
2404      /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
2405	 from removed linkonce sections, or sections discarded by a linker
2406	 script.  Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const.  */
2407      if (r_symndx == STN_UNDEF || bfd_is_abs_section (sec))
2408	{
2409	  defined_local = false;
2410	  resolved_local = false;
2411	  resolved_dynly = false;
2412	  resolved_to_const = true;
2413	}
2414
2415      /* The ifunc reference generate plt.  */
2416      if (h && h->type == STT_GNU_IFUNC && h->plt.offset != MINUS_ONE)
2417	{
2418	  defined_local = true;
2419	  resolved_local = true;
2420	  resolved_dynly = false;
2421	  resolved_to_const = false;
2422	  relocation = sec_addr (plt) + h->plt.offset;
2423	}
2424
2425      unresolved_reloc = resolved_dynly;
2426
2427      BFD_ASSERT (resolved_local + resolved_dynly + resolved_to_const == 1);
2428
2429      /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));.  */
2430
2431      BFD_ASSERT (!resolved_local || defined_local);
2432
2433      is_ie = false;
2434      switch (r_type)
2435	{
2436	case R_LARCH_MARK_PCREL:
2437	case R_LARCH_MARK_LA:
2438	case R_LARCH_NONE:
2439	  r = bfd_reloc_continue;
2440	  unresolved_reloc = false;
2441	  break;
2442
2443	case R_LARCH_32:
2444	case R_LARCH_64:
2445	  if (resolved_dynly || (is_pic && resolved_local))
2446	    {
2447	      Elf_Internal_Rela outrel;
2448
2449	      /* When generating a shared object, these relocations are copied
2450		 into the output file to be resolved at run time.  */
2451
2452	      outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2453							 input_section,
2454							 rel->r_offset);
2455
2456	      unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2457				  && (input_section->flags & SEC_ALLOC));
2458
2459	      outrel.r_offset += sec_addr (input_section);
2460
2461	      /* A pointer point to a ifunc symbol.  */
2462	      if (h && h->type == STT_GNU_IFUNC)
2463		{
2464		  if (h->dynindx == -1)
2465		    {
2466		      outrel.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
2467		      outrel.r_addend = (h->root.u.def.value
2468				  + h->root.u.def.section->output_section->vma
2469				  + h->root.u.def.section->output_offset);
2470		    }
2471		  else
2472		    {
2473		      outrel.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
2474		      outrel.r_addend = 0;
2475		    }
2476
2477		  if (SYMBOL_REFERENCES_LOCAL (info, h))
2478		    {
2479
2480		      if (htab->elf.splt != NULL)
2481			sreloc = htab->elf.srelgot;
2482		      else
2483			sreloc = htab->elf.irelplt;
2484		    }
2485		  else
2486		    {
2487
2488		      if (bfd_link_pic (info))
2489			sreloc = htab->elf.irelifunc;
2490		      else if (htab->elf.splt != NULL)
2491			sreloc = htab->elf.srelgot;
2492		      else
2493			sreloc = htab->elf.irelplt;
2494		    }
2495		}
2496	      else if (resolved_dynly)
2497		{
2498		  if (h->dynindx == -1)
2499		    {
2500		      if (h->root.type == bfd_link_hash_undefined)
2501			(*info->callbacks->undefined_symbol)
2502			  (info, name, input_bfd, input_section,
2503			   rel->r_offset, true);
2504
2505		      outrel.r_info = ELFNN_R_INFO (0, r_type);
2506		    }
2507		  else
2508		    outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
2509
2510		  outrel.r_addend = rel->r_addend;
2511		}
2512	      else
2513		{
2514		  outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
2515		  outrel.r_addend = relocation + rel->r_addend;
2516		}
2517
2518	      /* No alloc space of func allocate_dynrelocs.  */
2519	      if (unresolved_reloc
2520		  && !(h && (h->is_weakalias || !h->dyn_relocs)))
2521		loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2522	    }
2523
2524	  relocation += rel->r_addend;
2525	  break;
2526
2527	case R_LARCH_ADD8:
2528	case R_LARCH_ADD16:
2529	case R_LARCH_ADD24:
2530	case R_LARCH_ADD32:
2531	case R_LARCH_ADD64:
2532	case R_LARCH_SUB8:
2533	case R_LARCH_SUB16:
2534	case R_LARCH_SUB24:
2535	case R_LARCH_SUB32:
2536	case R_LARCH_SUB64:
2537	  if (resolved_dynly)
2538	    fatal = (loongarch_reloc_is_fatal
2539		     (info, input_bfd, input_section, rel, howto,
2540		      bfd_reloc_undefined, is_undefweak, name,
2541		      "Can't be resolved dynamically.  "
2542		      "If this procedure is hand-written assembly,\n"
2543		      "there must be something like '.dword sym1 - sym2' "
2544		      "to generate these relocs\n"
2545		      "and we can't get known link-time address of "
2546		      "these symbols."));
2547	  else
2548	    relocation += rel->r_addend;
2549	  break;
2550
2551	case R_LARCH_TLS_DTPREL32:
2552	case R_LARCH_TLS_DTPREL64:
2553	  if (resolved_dynly)
2554	    {
2555	      Elf_Internal_Rela outrel;
2556
2557	      outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2558							 input_section,
2559							 rel->r_offset);
2560	      unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2561				  && (input_section->flags & SEC_ALLOC));
2562	      outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
2563	      outrel.r_offset += sec_addr (input_section);
2564	      outrel.r_addend = rel->r_addend;
2565	      if (unresolved_reloc)
2566		loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2567	      break;
2568	    }
2569
2570	  if (resolved_to_const)
2571	    fatal = loongarch_reloc_is_fatal (info, input_bfd, input_section,
2572					      rel, howto,
2573					      bfd_reloc_notsupported,
2574					      is_undefweak, name,
2575					      "Internal:");
2576	  if (resolved_local)
2577	    {
2578	      if (!elf_hash_table (info)->tls_sec)
2579		{
2580		fatal = loongarch_reloc_is_fatal (info, input_bfd,
2581			  input_section, rel, howto, bfd_reloc_notsupported,
2582			  is_undefweak, name, "TLS section not be created");
2583		}
2584	      else
2585		relocation -= elf_hash_table (info)->tls_sec->vma;
2586	    }
2587	  else
2588	    {
2589	    fatal = loongarch_reloc_is_fatal (info, input_bfd,
2590		      input_section, rel, howto, bfd_reloc_undefined,
2591		      is_undefweak, name,
2592		      "TLS LE just can be resolved local only.");
2593	    }
2594
2595	  break;
2596
2597	case R_LARCH_SOP_PUSH_TLS_TPREL:
2598	  if (resolved_local)
2599	    {
2600	      if (!elf_hash_table (info)->tls_sec)
2601		fatal = (loongarch_reloc_is_fatal
2602			 (info, input_bfd, input_section, rel, howto,
2603			  bfd_reloc_notsupported, is_undefweak, name,
2604			  "TLS section not be created"));
2605	      else
2606		relocation -= elf_hash_table (info)->tls_sec->vma;
2607	    }
2608	  else
2609	    fatal = (loongarch_reloc_is_fatal
2610		     (info, input_bfd, input_section, rel, howto,
2611		      bfd_reloc_undefined, is_undefweak, name,
2612		      "TLS LE just can be resolved local only."));
2613	  break;
2614
2615	case R_LARCH_SOP_PUSH_ABSOLUTE:
2616	  if (is_undefweak)
2617	    {
2618	      if (resolved_dynly)
2619		fatal = (loongarch_reloc_is_fatal
2620			 (info, input_bfd, input_section, rel, howto,
2621			  bfd_reloc_dangerous, is_undefweak, name,
2622			  "Someone require us to resolve undefweak "
2623			  "symbol dynamically.  \n"
2624			  "But this reloc can't be done.  "
2625			  "I think I can't throw error "
2626			  "for this\n"
2627			  "so I resolved it to 0.  "
2628			  "I suggest to re-compile with '-fpic'."));
2629
2630	      relocation = 0;
2631	      unresolved_reloc = false;
2632	      break;
2633	    }
2634
2635	  if (resolved_to_const)
2636	    {
2637	      relocation += rel->r_addend;
2638	      break;
2639	    }
2640
2641	  if (is_pic)
2642	    {
2643	      fatal = (loongarch_reloc_is_fatal
2644		       (info, input_bfd, input_section, rel, howto,
2645			bfd_reloc_notsupported, is_undefweak, name,
2646			"Under PIC we don't know load address.  Re-compile "
2647			"with '-fpic'?"));
2648	      break;
2649	    }
2650
2651	  if (resolved_dynly)
2652	    {
2653	      if (!(plt && h && h->plt.offset != MINUS_ONE))
2654		{
2655		  fatal = (loongarch_reloc_is_fatal
2656			   (info, input_bfd, input_section, rel, howto,
2657			    bfd_reloc_undefined, is_undefweak, name,
2658			    "Can't be resolved dynamically.  Try to re-compile "
2659			    "with '-fpic'?"));
2660		  break;
2661		}
2662
2663	      if (rel->r_addend != 0)
2664		{
2665		  fatal = (loongarch_reloc_is_fatal
2666			   (info, input_bfd, input_section, rel, howto,
2667			    bfd_reloc_notsupported, is_undefweak, name,
2668			    "Shouldn't be with r_addend."));
2669		  break;
2670		}
2671
2672	      relocation = sec_addr (plt) + h->plt.offset;
2673	      unresolved_reloc = false;
2674	      break;
2675	    }
2676
2677	  if (resolved_local)
2678	    {
2679	      relocation += rel->r_addend;
2680	      break;
2681	    }
2682
2683	  break;
2684
2685	case R_LARCH_SOP_PUSH_PCREL:
2686	case R_LARCH_SOP_PUSH_PLT_PCREL:
2687	  unresolved_reloc = false;
2688
2689	  if (is_undefweak)
2690	    {
2691	      i = 0, j = 0;
2692	      relocation = 0;
2693	      if (resolved_dynly)
2694		{
2695		  if (h && h->plt.offset != MINUS_ONE)
2696		    i = 1, j = 2;
2697		  else
2698		    fatal = (loongarch_reloc_is_fatal
2699			     (info, input_bfd, input_section, rel, howto,
2700			      bfd_reloc_dangerous, is_undefweak, name,
2701			      "Undefweak need to be resolved dynamically, "
2702			      "but PLT stub doesn't represent."));
2703		}
2704	    }
2705	  else
2706	    {
2707	      if (!(defined_local || (h && h->plt.offset != MINUS_ONE)))
2708		{
2709		  fatal = (loongarch_reloc_is_fatal
2710			   (info, input_bfd, input_section, rel, howto,
2711			    bfd_reloc_undefined, is_undefweak, name,
2712			    "PLT stub does not represent and "
2713			    "symbol not defined."));
2714		  break;
2715		}
2716
2717	      if (resolved_local)
2718		i = 0, j = 2;
2719	      else /* if (resolved_dynly) */
2720		{
2721		  if (!(h && h->plt.offset != MINUS_ONE))
2722		    fatal = (loongarch_reloc_is_fatal
2723			     (info, input_bfd, input_section, rel, howto,
2724			      bfd_reloc_dangerous, is_undefweak, name,
2725			      "Internal: PLT stub doesn't represent.  "
2726			      "Resolve it with pcrel"));
2727		  i = 1, j = 3;
2728		}
2729	    }
2730
2731	  for (; i < j; i++)
2732	    {
2733	      if ((i & 1) == 0 && defined_local)
2734		{
2735		  relocation -= pc;
2736		  relocation += rel->r_addend;
2737		  break;
2738		}
2739
2740	      if ((i & 1) && h && h->plt.offset != MINUS_ONE)
2741		{
2742		  if (rel->r_addend != 0)
2743		    {
2744		      fatal = (loongarch_reloc_is_fatal
2745			       (info, input_bfd, input_section, rel, howto,
2746				bfd_reloc_notsupported, is_undefweak, name,
2747				"PLT shouldn't be with r_addend."));
2748		      break;
2749		    }
2750		  relocation = sec_addr (plt) + h->plt.offset - pc;
2751		  break;
2752		}
2753	    }
2754	  break;
2755
2756	case R_LARCH_SOP_PUSH_GPREL:
2757	  unresolved_reloc = false;
2758
2759	  if (rel->r_addend != 0)
2760	    {
2761	      fatal = (loongarch_reloc_is_fatal
2762		       (info, input_bfd, input_section, rel, howto,
2763			bfd_reloc_notsupported, is_undefweak, name,
2764			"Shouldn't be with r_addend."));
2765	      break;
2766	    }
2767
2768	  if (h != NULL)
2769	    {
2770	      off = h->got.offset & (~1);
2771
2772	      if (h->got.offset == MINUS_ONE && h->type != STT_GNU_IFUNC)
2773		{
2774		  fatal = (loongarch_reloc_is_fatal
2775			   (info, input_bfd, input_section, rel, howto,
2776			    bfd_reloc_notsupported, is_undefweak, name,
2777			    "Internal: GOT entry doesn't represent."));
2778		  break;
2779		}
2780
2781	      /* Hidden symbol not has .got entry, only .got.plt entry
2782		 so gprel is (plt - got).  */
2783	      if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
2784		{
2785		  if (h->plt.offset == (bfd_vma) -1)
2786		    {
2787		      abort();
2788		    }
2789
2790		  bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE;
2791		  off = plt_index * GOT_ENTRY_SIZE;
2792
2793		  if (htab->elf.splt != NULL)
2794		    {
2795		      /* Section .plt header is 2 times of plt entry.  */
2796		      off = sec_addr (htab->elf.sgotplt) + off
2797			- sec_addr (htab->elf.sgot);
2798		    }
2799		  else
2800		    {
2801		      /* Section iplt not has plt header.  */
2802		      off = sec_addr (htab->elf.igotplt) + off
2803			- sec_addr (htab->elf.sgot);
2804		    }
2805		}
2806
2807	      if ((h->got.offset & 1) == 0)
2808		{
2809		  if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
2810							bfd_link_pic (info), h)
2811		      && ((bfd_link_pic (info)
2812			   && SYMBOL_REFERENCES_LOCAL (info, h))))
2813		    {
2814		      /* This is actually a static link, or it is a
2815			 -Bsymbolic link and the symbol is defined
2816			 locally, or the symbol was forced to be local
2817			 because of a version file.  We must initialize
2818			 this entry in the global offset table.  Since the
2819			 offset must always be a multiple of the word size,
2820			 we use the least significant bit to record whether
2821			 we have initialized it already.
2822
2823			 When doing a dynamic link, we create a rela.got
2824			 relocation entry to initialize the value.  This
2825			 is done in the finish_dynamic_symbol routine.  */
2826
2827		      if (resolved_dynly)
2828			{
2829			  fatal = (loongarch_reloc_is_fatal
2830				   (info, input_bfd, input_section, rel, howto,
2831				    bfd_reloc_dangerous, is_undefweak, name,
2832				    "Internal: here shouldn't dynamic."));
2833			}
2834
2835		      if (!(defined_local || resolved_to_const))
2836			{
2837			  fatal = (loongarch_reloc_is_fatal
2838				   (info, input_bfd, input_section, rel, howto,
2839				    bfd_reloc_undefined, is_undefweak, name,
2840				    "Internal: "));
2841			  break;
2842			}
2843
2844		      asection *s;
2845		      Elf_Internal_Rela outrel;
2846		      /* We need to generate a R_LARCH_RELATIVE reloc
2847			 for the dynamic linker.  */
2848		      s = htab->elf.srelgot;
2849		      if (!s)
2850			{
2851			  fatal = loongarch_reloc_is_fatal
2852			    (info, input_bfd,
2853			     input_section, rel, howto,
2854			     bfd_reloc_notsupported, is_undefweak, name,
2855			     "Internal: '.rel.got' not represent");
2856			  break;
2857			}
2858
2859		      outrel.r_offset = sec_addr (got) + off;
2860		      outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
2861		      outrel.r_addend = relocation; /* Link-time addr.  */
2862		      loongarch_elf_append_rela (output_bfd, s, &outrel);
2863		    }
2864		  bfd_put_NN (output_bfd, relocation, got->contents + off);
2865		  h->got.offset |= 1;
2866		}
2867	    }
2868	  else
2869	    {
2870	      if (!local_got_offsets)
2871		{
2872		  fatal = (loongarch_reloc_is_fatal
2873			   (info, input_bfd, input_section, rel, howto,
2874			    bfd_reloc_notsupported, is_undefweak, name,
2875			    "Internal: local got offsets not reporesent."));
2876		  break;
2877		}
2878
2879	      off = local_got_offsets[r_symndx] & (~1);
2880
2881	      if (local_got_offsets[r_symndx] == MINUS_ONE)
2882		{
2883		  fatal = (loongarch_reloc_is_fatal
2884			   (info, input_bfd, input_section, rel, howto,
2885			    bfd_reloc_notsupported, is_undefweak, name,
2886			    "Internal: GOT entry doesn't represent."));
2887		  break;
2888		}
2889
2890	      /* The offset must always be a multiple of the word size.
2891		 So, we can use the least significant bit to record
2892		 whether we have already processed this entry.  */
2893	      if ((local_got_offsets[r_symndx] & 1) == 0)
2894		{
2895		  if (is_pic)
2896		    {
2897		      asection *s;
2898		      Elf_Internal_Rela outrel;
2899		      /* We need to generate a R_LARCH_RELATIVE reloc
2900			 for the dynamic linker.  */
2901		      s = htab->elf.srelgot;
2902		      if (!s)
2903			{
2904			  fatal = (loongarch_reloc_is_fatal
2905				   (info, input_bfd, input_section, rel, howto,
2906				    bfd_reloc_notsupported, is_undefweak, name,
2907				    "Internal: '.rel.got' not represent"));
2908			  break;
2909			}
2910
2911		      outrel.r_offset = sec_addr (got) + off;
2912		      outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
2913		      outrel.r_addend = relocation; /* Link-time addr.  */
2914		      loongarch_elf_append_rela (output_bfd, s, &outrel);
2915		    }
2916
2917		  bfd_put_NN (output_bfd, relocation, got->contents + off);
2918		  local_got_offsets[r_symndx] |= 1;
2919		}
2920	    }
2921	  relocation = off;
2922
2923	  break;
2924
2925	case R_LARCH_SOP_PUSH_TLS_GOT:
2926	case R_LARCH_SOP_PUSH_TLS_GD:
2927	  {
2928	    unresolved_reloc = false;
2929	    if (r_type == R_LARCH_SOP_PUSH_TLS_GOT)
2930	      is_ie = true;
2931
2932	    bfd_vma got_off = 0;
2933	    if (h != NULL)
2934	      {
2935		got_off = h->got.offset;
2936		h->got.offset |= 1;
2937	      }
2938	    else
2939	      {
2940		got_off = local_got_offsets[r_symndx];
2941		local_got_offsets[r_symndx] |= 1;
2942	      }
2943
2944	    BFD_ASSERT (got_off != MINUS_ONE);
2945
2946	    ie_off = 0;
2947	    tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
2948	    if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
2949	      ie_off = 2 * GOT_ENTRY_SIZE;
2950
2951	    if ((got_off & 1) == 0)
2952	      {
2953		Elf_Internal_Rela rela;
2954		asection *srel = htab->elf.srelgot;
2955		bfd_vma tls_block_off = 0;
2956
2957		if (SYMBOL_REFERENCES_LOCAL (info, h))
2958		  {
2959		    BFD_ASSERT (elf_hash_table (info)->tls_sec);
2960		    tls_block_off = relocation
2961			- elf_hash_table (info)->tls_sec->vma;
2962		  }
2963
2964		if (tls_type & GOT_TLS_GD)
2965		  {
2966		    rela.r_offset = sec_addr (got) + got_off;
2967		    rela.r_addend = 0;
2968		    if (SYMBOL_REFERENCES_LOCAL (info, h))
2969		      {
2970			/* Local sym, used in exec, set module id 1.  */
2971			if (bfd_link_executable (info))
2972			  bfd_put_NN (output_bfd, 1, got->contents + got_off);
2973			else
2974			  {
2975			    rela.r_info = ELFNN_R_INFO (0,
2976							R_LARCH_TLS_DTPMODNN);
2977			    loongarch_elf_append_rela (output_bfd, srel, &rela);
2978			  }
2979
2980			bfd_put_NN (output_bfd, tls_block_off,
2981				    got->contents + got_off + GOT_ENTRY_SIZE);
2982		      }
2983		    /* Dynamic resolved.  */
2984		    else
2985		      {
2986			/* Dynamic relocate module id.  */
2987			rela.r_info = ELFNN_R_INFO (h->dynindx,
2988						    R_LARCH_TLS_DTPMODNN);
2989			loongarch_elf_append_rela (output_bfd, srel, &rela);
2990
2991			/* Dynamic relocate offset of block.  */
2992			rela.r_offset += GOT_ENTRY_SIZE;
2993			rela.r_info = ELFNN_R_INFO (h->dynindx,
2994						    R_LARCH_TLS_DTPRELNN);
2995			loongarch_elf_append_rela (output_bfd, srel, &rela);
2996		      }
2997		  }
2998		if (tls_type & GOT_TLS_IE)
2999		  {
3000		    rela.r_offset = sec_addr (got) + got_off + ie_off;
3001		    if (SYMBOL_REFERENCES_LOCAL (info, h))
3002		      {
3003			/* Local sym, used in exec, set module id 1.  */
3004			if (!bfd_link_executable (info))
3005			  {
3006			    rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
3007			    rela.r_addend = tls_block_off;
3008			    loongarch_elf_append_rela (output_bfd, srel, &rela);
3009			  }
3010
3011			bfd_put_NN (output_bfd, tls_block_off,
3012				    got->contents + got_off + ie_off);
3013		      }
3014		    /* Dynamic resolved.  */
3015		    else
3016		      {
3017			/* Dynamic relocate offset of block.  */
3018			rela.r_info = ELFNN_R_INFO (h->dynindx,
3019						    R_LARCH_TLS_TPRELNN);
3020			rela.r_addend = 0;
3021			loongarch_elf_append_rela (output_bfd, srel, &rela);
3022		      }
3023		  }
3024	      }
3025
3026	    relocation = (got_off & (~(bfd_vma)1)) + (is_ie ? ie_off : 0);
3027	  }
3028	  break;
3029
3030	/* New reloc types.  */
3031	case R_LARCH_B21:
3032	case R_LARCH_B26:
3033	case R_LARCH_B16:
3034	  unresolved_reloc = false;
3035	  if (is_undefweak)
3036	    {
3037	      relocation = 0;
3038	    }
3039
3040	  if (resolved_local)
3041	    {
3042	      relocation -= pc;
3043	      relocation += rel->r_addend;
3044	    }
3045	  else if (resolved_dynly)
3046	    {
3047	      BFD_ASSERT (h
3048			  && (h->plt.offset != MINUS_ONE
3049			      || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
3050			  && rel->r_addend == 0);
3051	      if (h && h->plt.offset == MINUS_ONE
3052		  && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
3053		{
3054		  relocation -= pc;
3055		  relocation += rel->r_addend;
3056		}
3057	      else
3058		relocation = sec_addr (plt) + h->plt.offset - pc;
3059	    }
3060
3061	  break;
3062
3063	case R_LARCH_ABS_HI20:
3064	case R_LARCH_ABS_LO12:
3065	case R_LARCH_ABS64_LO20:
3066	case R_LARCH_ABS64_HI12:
3067	  BFD_ASSERT (!is_pic);
3068
3069	  if (is_undefweak)
3070	    {
3071	      BFD_ASSERT (resolved_dynly);
3072	      relocation = 0;
3073	      break;
3074	    }
3075	  else if (resolved_to_const || resolved_local)
3076	    {
3077	      relocation += rel->r_addend;
3078	    }
3079	  else if (resolved_dynly)
3080	    {
3081	      unresolved_reloc = false;
3082	      BFD_ASSERT ((plt && h && h->plt.offset != MINUS_ONE)
3083			  && rel->r_addend == 0);
3084	      relocation = sec_addr (plt) + h->plt.offset;
3085	    }
3086
3087	  break;
3088
3089	case R_LARCH_PCALA_HI20:
3090	  unresolved_reloc = false;
3091	  if (h && h->plt.offset != MINUS_ONE)
3092	    relocation = sec_addr (plt) + h->plt.offset;
3093	  else
3094	    relocation += rel->r_addend;
3095
3096	  RELOCATE_CALC_PC32_HI20 (relocation, pc);
3097
3098	  break;
3099
3100	case R_LARCH_PCALA_LO12:
3101	  /* Not support if sym_addr in 2k page edge.
3102	     pcalau12i pc_hi20 (sym_addr)
3103	     ld.w/d pc_lo12 (sym_addr)
3104	     ld.w/d pc_lo12 (sym_addr + x)
3105	     ...
3106	     can not calc correct address
3107	     if sym_addr < 0x800 && sym_addr + x >= 0x800.  */
3108
3109	  if (h && h->plt.offset != MINUS_ONE)
3110	    relocation = sec_addr (plt) + h->plt.offset;
3111	  else
3112	    relocation += rel->r_addend;
3113
3114	  relocation &= 0xfff;
3115	  /* Signed extend.  */
3116	  relocation = (relocation ^ 0x800) - 0x800;
3117
3118	  /* For 2G jump, generate pcalau12i, jirl.  */
3119	  /* If use jirl, turns to R_LARCH_B16.  */
3120	  uint32_t insn = bfd_get (32, input_bfd, contents + rel->r_offset);
3121	  if ((insn & 0x4c000000) == 0x4c000000)
3122	    {
3123	      rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_B16);
3124	      howto = loongarch_elf_rtype_to_howto (input_bfd, R_LARCH_B16);
3125	    }
3126	  break;
3127
3128	case R_LARCH_PCALA64_LO20:
3129	case R_LARCH_PCALA64_HI12:
3130	  if (h && h->plt.offset != MINUS_ONE)
3131	    relocation = sec_addr (plt) + h->plt.offset;
3132	  else
3133	    relocation += rel->r_addend;
3134
3135	  RELOCATE_CALC_PC64_HI32 (relocation, pc);
3136
3137	  break;
3138
3139	case R_LARCH_GOT_PC_HI20:
3140	case R_LARCH_GOT_HI20:
3141	  /* Calc got offset.  */
3142	    {
3143	      unresolved_reloc = false;
3144	      BFD_ASSERT (rel->r_addend == 0);
3145
3146	      bfd_vma got_off = 0;
3147	      if (h != NULL)
3148		{
3149		  /* GOT ref or ifunc.  */
3150		  BFD_ASSERT (h->got.offset != MINUS_ONE
3151			      || h->type == STT_GNU_IFUNC);
3152
3153		  got_off = h->got.offset  & (~(bfd_vma)1);
3154		  /* Hidden symbol not has got entry,
3155		   * only got.plt entry so it is (plt - got).  */
3156		  if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3157		    {
3158		      bfd_vma idx;
3159		      if (htab->elf.splt != NULL)
3160			{
3161			  idx = (h->plt.offset - PLT_HEADER_SIZE)
3162			    / PLT_ENTRY_SIZE;
3163			  got_off = sec_addr (htab->elf.sgotplt)
3164			    + GOTPLT_HEADER_SIZE
3165			    + (idx * GOT_ENTRY_SIZE)
3166			    - sec_addr (htab->elf.sgot);
3167			}
3168		      else
3169			{
3170			  idx = h->plt.offset / PLT_ENTRY_SIZE;
3171			  got_off = sec_addr (htab->elf.sgotplt)
3172			    + (idx * GOT_ENTRY_SIZE)
3173			    - sec_addr (htab->elf.sgot);
3174			}
3175		    }
3176
3177		  if ((h->got.offset & 1) == 0)
3178		    {
3179		      /* We need to generate a R_LARCH_RELATIVE reloc once
3180		       * in loongarch_elf_finish_dynamic_symbol or now,
3181		       * call finish_dyn && nopic
3182		       * or !call finish_dyn && pic.  */
3183		      if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
3184							    bfd_link_pic (info),
3185							    h)
3186			  && bfd_link_pic (info)
3187			  && SYMBOL_REFERENCES_LOCAL (info, h))
3188			{
3189			  Elf_Internal_Rela rela;
3190			  rela.r_offset = sec_addr (got) + got_off;
3191			  rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3192			  rela.r_addend = relocation;
3193			  loongarch_elf_append_rela (output_bfd,
3194						     htab->elf.srelgot, &rela);
3195			}
3196		      h->got.offset |= 1;
3197		      bfd_put_NN (output_bfd, relocation,
3198				  got->contents + got_off);
3199		    }
3200		}
3201	      else
3202		{
3203		  BFD_ASSERT (local_got_offsets
3204			      && local_got_offsets[r_symndx] != MINUS_ONE);
3205
3206		  got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
3207		  if ((local_got_offsets[r_symndx] & 1) == 0)
3208		    {
3209		      if (bfd_link_pic (info))
3210			{
3211			  Elf_Internal_Rela rela;
3212			  rela.r_offset = sec_addr (got) + got_off;
3213			  rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3214			  rela.r_addend = relocation;
3215			  loongarch_elf_append_rela (output_bfd,
3216						     htab->elf.srelgot, &rela);
3217			}
3218		      local_got_offsets[r_symndx] |= 1;
3219		    }
3220		  bfd_put_NN (output_bfd, relocation, got->contents + got_off);
3221		}
3222
3223	      relocation = got_off + sec_addr (got);
3224	    }
3225
3226	  if (r_type == R_LARCH_GOT_PC_HI20)
3227	    RELOCATE_CALC_PC32_HI20 (relocation, pc);
3228
3229	  break;
3230
3231	case R_LARCH_GOT_PC_LO12:
3232	case R_LARCH_GOT64_PC_LO20:
3233	case R_LARCH_GOT64_PC_HI12:
3234	case R_LARCH_GOT_LO12:
3235	case R_LARCH_GOT64_LO20:
3236	case R_LARCH_GOT64_HI12:
3237	    {
3238	      unresolved_reloc = false;
3239	      bfd_vma got_off;
3240	      if (h)
3241		got_off = h->got.offset & (~(bfd_vma)1);
3242	      else
3243		got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
3244
3245	      if (h && h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3246		{
3247		  bfd_vma idx;
3248		  if (htab->elf.splt != NULL)
3249		    idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
3250		  else
3251		    idx = h->plt.offset / PLT_ENTRY_SIZE;
3252
3253		  got_off = sec_addr (htab->elf.sgotplt)
3254		    + GOTPLT_HEADER_SIZE
3255		    + (idx * GOT_ENTRY_SIZE)
3256		    - sec_addr (htab->elf.sgot);
3257		}
3258	      relocation = got_off + sec_addr (got);
3259	    }
3260
3261	  if (r_type == R_LARCH_GOT_PC_LO12)
3262	    relocation &= (bfd_vma)0xfff;
3263	  else if (r_type == R_LARCH_GOT64_PC_LO20
3264		   || r_type == R_LARCH_GOT64_PC_HI12)
3265	    RELOCATE_CALC_PC64_HI32 (relocation, pc);
3266
3267	  break;
3268
3269	case R_LARCH_TLS_LE_HI20:
3270	case R_LARCH_TLS_LE_LO12:
3271	case R_LARCH_TLS_LE64_LO20:
3272	case R_LARCH_TLS_LE64_HI12:
3273	  BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec);
3274
3275	  relocation -= elf_hash_table (info)->tls_sec->vma;
3276	  break;
3277
3278	/* TLS IE LD/GD process separately is troublesome.
3279	   When a symbol is both ie and LD/GD, h->got.off |= 1
3280	   make only one type be relocated.  We must use
3281	   h->got.offset |= 1 and h->got.offset |= 2
3282	   diff IE and LD/GD.  And all (got_off & (~(bfd_vma)1))
3283	   (IE LD/GD and reusable GOT reloc) must change to
3284	   (got_off & (~(bfd_vma)3)), beause we use lowest 2 bits
3285	   as a tag.
3286	   Now, LD and GD is both GOT_TLS_GD type, LD seems to
3287	   can be omitted.  */
3288	case R_LARCH_TLS_IE_PC_HI20:
3289	case R_LARCH_TLS_IE_HI20:
3290	case R_LARCH_TLS_LD_PC_HI20:
3291	case R_LARCH_TLS_LD_HI20:
3292	case R_LARCH_TLS_GD_PC_HI20:
3293	case R_LARCH_TLS_GD_HI20:
3294	  BFD_ASSERT (rel->r_addend == 0);
3295	  unresolved_reloc = false;
3296
3297	  if (r_type == R_LARCH_TLS_IE_PC_HI20
3298	      || r_type == R_LARCH_TLS_IE_HI20)
3299	    is_ie = true;
3300
3301	  bfd_vma got_off = 0;
3302	  if (h != NULL)
3303	    {
3304	      got_off = h->got.offset;
3305	      h->got.offset |= 1;
3306	    }
3307	  else
3308	    {
3309	      got_off = local_got_offsets[r_symndx];
3310	      local_got_offsets[r_symndx] |= 1;
3311	    }
3312
3313	  BFD_ASSERT (got_off != MINUS_ONE);
3314
3315	  ie_off = 0;
3316	  tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3317	  if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
3318	    ie_off = 2 * GOT_ENTRY_SIZE;
3319
3320	  if ((got_off & 1) == 0)
3321	    {
3322	      Elf_Internal_Rela rela;
3323	      asection *relgot = htab->elf.srelgot;
3324	      bfd_vma tls_block_off = 0;
3325
3326	      if (SYMBOL_REFERENCES_LOCAL (info, h))
3327		{
3328		  BFD_ASSERT (elf_hash_table (info)->tls_sec);
3329		  tls_block_off = relocation
3330		      - elf_hash_table (info)->tls_sec->vma;
3331		}
3332
3333	      if (tls_type & GOT_TLS_GD)
3334		{
3335		  rela.r_offset = sec_addr (got) + got_off;
3336		  rela.r_addend = 0;
3337		  if (SYMBOL_REFERENCES_LOCAL (info, h))
3338		    {
3339		      /* Local sym, used in exec, set module id 1.  */
3340		      if (bfd_link_executable (info))
3341			bfd_put_NN (output_bfd, 1, got->contents + got_off);
3342		      else
3343			{
3344			  rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_DTPMODNN);
3345			  loongarch_elf_append_rela (output_bfd, relgot, &rela);
3346			}
3347
3348		      bfd_put_NN (output_bfd, tls_block_off,
3349				  got->contents + got_off + GOT_ENTRY_SIZE);
3350		    }
3351		  /* Dynamic resolved.  */
3352		  else
3353		    {
3354		      /* Dynamic relocate module id.  */
3355		      rela.r_info = ELFNN_R_INFO (h->dynindx,
3356						  R_LARCH_TLS_DTPMODNN);
3357		      loongarch_elf_append_rela (output_bfd, relgot, &rela);
3358
3359		      /* Dynamic relocate offset of block.  */
3360		      rela.r_offset += GOT_ENTRY_SIZE;
3361		      rela.r_info = ELFNN_R_INFO (h->dynindx,
3362						  R_LARCH_TLS_DTPRELNN);
3363		      loongarch_elf_append_rela (output_bfd, relgot, &rela);
3364		    }
3365		}
3366	      if (tls_type & GOT_TLS_IE)
3367		{
3368		  rela.r_offset = sec_addr (got) + got_off + ie_off;
3369		  if (SYMBOL_REFERENCES_LOCAL (info, h))
3370		    {
3371		      /* Local sym, used in exec, set module id 1.  */
3372		      if (!bfd_link_executable (info))
3373			{
3374			  rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
3375			  rela.r_addend = tls_block_off;
3376			  loongarch_elf_append_rela (output_bfd, relgot, &rela);
3377			}
3378
3379		      bfd_put_NN (output_bfd, tls_block_off,
3380				  got->contents + got_off + ie_off);
3381		    }
3382		  /* Dynamic resolved.  */
3383		  else
3384		    {
3385		      /* Dynamic relocate offset of block.  */
3386		      rela.r_info = ELFNN_R_INFO (h->dynindx,
3387						  R_LARCH_TLS_TPRELNN);
3388		      rela.r_addend = 0;
3389		      loongarch_elf_append_rela (output_bfd, relgot, &rela);
3390		    }
3391		}
3392	    }
3393	  relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got)
3394			+ (is_ie ? ie_off : 0);
3395
3396	  if (r_type == R_LARCH_TLS_LD_PC_HI20
3397	      || r_type == R_LARCH_TLS_GD_PC_HI20
3398	      || r_type == R_LARCH_TLS_IE_PC_HI20)
3399	    RELOCATE_CALC_PC32_HI20 (relocation, pc);
3400
3401	  break;
3402
3403	case R_LARCH_TLS_IE_PC_LO12:
3404	case R_LARCH_TLS_IE64_PC_LO20:
3405	case R_LARCH_TLS_IE64_PC_HI12:
3406	case R_LARCH_TLS_IE_LO12:
3407	case R_LARCH_TLS_IE64_LO20:
3408	case R_LARCH_TLS_IE64_HI12:
3409	  unresolved_reloc = false;
3410
3411	  if (h)
3412	    relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)3));
3413	  else
3414	    relocation = sec_addr (got)
3415	      + (local_got_offsets[r_symndx] & (~(bfd_vma)3));
3416
3417	  tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3418	  /* Use both TLS_GD and TLS_IE.  */
3419	  if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
3420	    relocation += 2 * GOT_ENTRY_SIZE;
3421
3422	  if (r_type == R_LARCH_TLS_IE_PC_LO12)
3423	    relocation &= (bfd_vma)0xfff;
3424	  else if (r_type == R_LARCH_TLS_IE64_PC_LO20
3425		   || r_type == R_LARCH_TLS_IE64_PC_HI12)
3426	    RELOCATE_CALC_PC64_HI32 (relocation, pc);
3427
3428	  break;
3429
3430	case R_LARCH_RELAX:
3431	  break;
3432
3433	default:
3434	  break;
3435	}
3436
3437      if (fatal)
3438	break;
3439
3440      do
3441	{
3442	  /* 'unresolved_reloc' means we haven't done it yet.
3443	     We need help of dynamic linker to fix this memory location up.  */
3444	  if (!unresolved_reloc)
3445	    break;
3446
3447	  if (_bfd_elf_section_offset (output_bfd, info, input_section,
3448				       rel->r_offset) == MINUS_ONE)
3449	    /* WHY? May because it's invalid so skip checking.
3450	       But why dynamic reloc a invalid section?  */
3451	    break;
3452
3453	  if (input_section->output_section->flags & SEC_DEBUGGING)
3454	    {
3455	      fatal = (loongarch_reloc_is_fatal
3456		       (info, input_bfd, input_section, rel, howto,
3457			bfd_reloc_dangerous, is_undefweak, name,
3458			"Seems dynamic linker not process "
3459			"sections 'SEC_DEBUGGING'."));
3460	    }
3461	  if (!is_dyn)
3462	    break;
3463
3464	  if ((info->flags & DF_TEXTREL) == 0)
3465	    if (input_section->output_section->flags & SEC_READONLY)
3466	      info->flags |= DF_TEXTREL;
3467	}
3468      while (0);
3469
3470      if (fatal)
3471	break;
3472
3473      loongarch_record_one_reloc (input_bfd, input_section, r_type,
3474				  rel->r_offset, sym, h, rel->r_addend);
3475
3476      if (r != bfd_reloc_continue)
3477	r = perform_relocation (rel, input_section, howto, relocation,
3478				input_bfd, contents);
3479
3480      switch (r)
3481	{
3482	case bfd_reloc_dangerous:
3483	case bfd_reloc_continue:
3484	case bfd_reloc_ok:
3485	  continue;
3486
3487	case bfd_reloc_overflow:
3488	  /* Overflow value can't be filled in.  */
3489	  loongarch_dump_reloc_record (info->callbacks->info);
3490	  info->callbacks->reloc_overflow
3491	    (info, h ? &h->root : NULL, name, howto->name, rel->r_addend,
3492	     input_bfd, input_section, rel->r_offset);
3493	  break;
3494
3495	case bfd_reloc_outofrange:
3496	  /* Stack state incorrect.  */
3497	  loongarch_dump_reloc_record (info->callbacks->info);
3498	  info->callbacks->info
3499	    ("%X%H: Internal stack state is incorrect.\n"
3500	     "Want to push to full stack or pop from empty stack?\n",
3501	     input_bfd, input_section, rel->r_offset);
3502	  break;
3503
3504	case bfd_reloc_notsupported:
3505	  info->callbacks->info ("%X%H: Unknown relocation type.\n", input_bfd,
3506				 input_section, rel->r_offset);
3507	  break;
3508
3509	default:
3510	  info->callbacks->info ("%X%H: Internal: unknown error.\n", input_bfd,
3511				 input_section, rel->r_offset);
3512	  break;
3513	}
3514
3515      fatal = true;
3516    }
3517
3518  return !fatal;
3519}
3520
3521/* Finish up dynamic symbol handling.  We set the contents of various
3522   dynamic sections here.  */
3523
3524static bool
3525loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
3526				     struct bfd_link_info *info,
3527				     struct elf_link_hash_entry *h,
3528				     Elf_Internal_Sym *sym)
3529{
3530  struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
3531  const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
3532  asection *rela_dyn = bfd_get_section_by_name (output_bfd, ".rela.dyn");
3533  struct bfd_link_order *lo = NULL;
3534  Elf_Internal_Rela *slot = NULL, *last_slot = NULL;
3535
3536  if (rela_dyn)
3537    lo = rela_dyn->map_head.link_order;
3538
3539  if (h->plt.offset != MINUS_ONE)
3540    {
3541      size_t i, plt_idx;
3542      asection *plt, *gotplt, *relplt;
3543      bfd_vma got_address;
3544      uint32_t plt_entry[PLT_ENTRY_INSNS];
3545      bfd_byte *loc;
3546      Elf_Internal_Rela rela;
3547      asection *rela_sec = NULL;
3548
3549      if (htab->elf.splt)
3550	{
3551	  BFD_ASSERT ((h->type == STT_GNU_IFUNC
3552		       && SYMBOL_REFERENCES_LOCAL (info, h))
3553		      || h->dynindx != -1);
3554
3555	  plt = htab->elf.splt;
3556	  gotplt = htab->elf.sgotplt;
3557	  if (h->type == STT_GNU_IFUNC && SYMBOL_REFERENCES_LOCAL (info, h))
3558	    relplt = htab->elf.srelgot;
3559	  else
3560	    relplt = htab->elf.srelplt;
3561	  plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
3562	  got_address =
3563	    sec_addr (gotplt) + GOTPLT_HEADER_SIZE + plt_idx * GOT_ENTRY_SIZE;
3564	}
3565      else /* if (htab->elf.iplt) */
3566	{
3567	  BFD_ASSERT (h->type == STT_GNU_IFUNC
3568		      && SYMBOL_REFERENCES_LOCAL (info, h));
3569
3570	  plt = htab->elf.iplt;
3571	  gotplt = htab->elf.igotplt;
3572	  relplt = htab->elf.irelplt;
3573	  plt_idx = h->plt.offset / PLT_ENTRY_SIZE;
3574	  got_address = sec_addr (gotplt) + plt_idx * GOT_ENTRY_SIZE;
3575	}
3576
3577      /* Find out where the .plt entry should go.  */
3578      loc = plt->contents + h->plt.offset;
3579
3580      /* Fill in the PLT entry itself.  */
3581      if (!loongarch_make_plt_entry (got_address,
3582				     sec_addr (plt) + h->plt.offset,
3583				     plt_entry))
3584	return false;
3585
3586      for (i = 0; i < PLT_ENTRY_INSNS; i++)
3587	bfd_put_32 (output_bfd, plt_entry[i], loc + 4 * i);
3588
3589      /* Fill in the initial value of the got.plt entry.  */
3590      loc = gotplt->contents + (got_address - sec_addr (gotplt));
3591      bfd_put_NN (output_bfd, sec_addr (plt), loc);
3592
3593      rela.r_offset = got_address;
3594
3595      /* TRUE if this is a PLT reference to a local IFUNC.  */
3596      if (PLT_LOCAL_IFUNC_P (info, h)
3597	  && (relplt == htab->elf.srelgot
3598	      || relplt == htab->elf.irelplt))
3599	{
3600	  rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
3601	  rela.r_addend = (h->root.u.def.value
3602			       + h->root.u.def.section->output_section->vma
3603			       + h->root.u.def.section->output_offset);
3604
3605	  /* Find the space after dyn sort.  */
3606	  while (slot == last_slot || slot->r_offset != 0)
3607	    {
3608	      if (slot != last_slot)
3609		{
3610		  slot++;
3611		  continue;
3612		}
3613
3614	      BFD_ASSERT (lo != NULL);
3615	      rela_sec = lo->u.indirect.section;
3616	      lo = lo->next;
3617
3618	      slot = (Elf_Internal_Rela *)rela_sec->contents;
3619	      last_slot = (Elf_Internal_Rela *)(rela_sec->contents +
3620						rela_sec->size);
3621	    }
3622
3623	  bed->s->swap_reloca_out (output_bfd, &rela, (bfd_byte *)slot);
3624	  rela_sec->reloc_count++;
3625	}
3626      else
3627	{
3628	  /* Fill in the entry in the rela.plt section.  */
3629	  rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_JUMP_SLOT);
3630	  rela.r_addend = 0;
3631	  loc = relplt->contents + plt_idx * sizeof (ElfNN_External_Rela);
3632	  bed->s->swap_reloca_out (output_bfd, &rela, loc);
3633	}
3634
3635      if (!h->def_regular)
3636	{
3637	  /* Mark the symbol as undefined, rather than as defined in
3638	     the .plt section.  Leave the value alone.  */
3639	  sym->st_shndx = SHN_UNDEF;
3640	  /* If the symbol is weak, we do need to clear the value.
3641	     Otherwise, the PLT entry would provide a definition for
3642	     the symbol even if the symbol wasn't defined anywhere,
3643	     and so the symbol would never be NULL.  */
3644	  if (!h->ref_regular_nonweak)
3645	    sym->st_value = 0;
3646	}
3647    }
3648
3649  if (h->got.offset != MINUS_ONE
3650      /* TLS got entry have been handled in elf_relocate_section.  */
3651      && !(loongarch_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE))
3652      /* Have allocated got entry but not allocated rela before.  */
3653      && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
3654    {
3655      asection *sgot, *srela;
3656      Elf_Internal_Rela rela;
3657      bfd_vma off = h->got.offset & ~(bfd_vma)1;
3658
3659      /* This symbol has an entry in the GOT.  Set it up.  */
3660      sgot = htab->elf.sgot;
3661      srela = htab->elf.srelgot;
3662      BFD_ASSERT (sgot && srela);
3663
3664      rela.r_offset = sec_addr (sgot) + off;
3665
3666      if (h->def_regular
3667	  && h->type == STT_GNU_IFUNC)
3668	{
3669	  if(h->plt.offset == MINUS_ONE)
3670	    {
3671	      if (htab->elf.splt == NULL)
3672		srela = htab->elf.irelplt;
3673
3674	      if (SYMBOL_REFERENCES_LOCAL (info, h))
3675		{
3676		  asection *sec = h->root.u.def.section;
3677		  rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
3678		  rela.r_addend = h->root.u.def.value + sec->output_section->vma
3679		    + sec->output_offset;
3680		  bfd_put_NN (output_bfd, 0, sgot->contents + off);
3681		}
3682	      else
3683		{
3684		  BFD_ASSERT (h->dynindx != -1);
3685		  rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
3686		  rela.r_addend = 0;
3687		  bfd_put_NN (output_bfd, (bfd_vma) 0, sgot->contents + off);
3688		}
3689	    }
3690	  else if(bfd_link_pic (info))
3691	    {
3692	      rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
3693	      rela.r_addend = 0;
3694	      bfd_put_NN (output_bfd, rela.r_addend, sgot->contents + off);
3695	    }
3696	  else
3697	    {
3698	      asection *plt;
3699	      /* For non-shared object, we can't use .got.plt, which
3700		 contains the real function address if we need pointer
3701		 equality.  We load the GOT entry with the PLT entry.  */
3702	      plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
3703	      bfd_put_NN (output_bfd,
3704			  (plt->output_section->vma
3705			   + plt->output_offset
3706			   + h->plt.offset),
3707			  sgot->contents + off);
3708	      return true;
3709	    }
3710	}
3711      else if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h))
3712	{
3713	  asection *sec = h->root.u.def.section;
3714	  rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3715	  rela.r_addend = (h->root.u.def.value + sec->output_section->vma
3716			   + sec->output_offset);
3717	}
3718      else
3719	{
3720	  BFD_ASSERT (h->dynindx != -1);
3721	  rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
3722	  rela.r_addend = 0;
3723	}
3724
3725      loongarch_elf_append_rela (output_bfd, srela, &rela);
3726    }
3727
3728  /* Mark some specially defined symbols as absolute.  */
3729  if (h == htab->elf.hdynamic || h == htab->elf.hgot || h == htab->elf.hplt)
3730    sym->st_shndx = SHN_ABS;
3731
3732  return true;
3733}
3734
3735/* Finish up the dynamic sections.  */
3736
3737static bool
3738loongarch_finish_dyn (bfd *output_bfd, struct bfd_link_info *info, bfd *dynobj,
3739		      asection *sdyn)
3740{
3741  struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
3742  const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
3743  size_t dynsize = bed->s->sizeof_dyn, skipped_size = 0;
3744  bfd_byte *dyncon, *dynconend;
3745
3746  dynconend = sdyn->contents + sdyn->size;
3747  for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize)
3748    {
3749      Elf_Internal_Dyn dyn;
3750      asection *s;
3751      int skipped = 0;
3752
3753      bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
3754
3755      switch (dyn.d_tag)
3756	{
3757	case DT_PLTGOT:
3758	  s = htab->elf.sgotplt;
3759	  dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
3760	  break;
3761	case DT_JMPREL:
3762	  s = htab->elf.srelplt;
3763	  dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
3764	  break;
3765	case DT_PLTRELSZ:
3766	  s = htab->elf.srelplt;
3767	  dyn.d_un.d_val = s->size;
3768	  break;
3769	case DT_TEXTREL:
3770	  if ((info->flags & DF_TEXTREL) == 0)
3771	    skipped = 1;
3772	  break;
3773	case DT_FLAGS:
3774	  if ((info->flags & DF_TEXTREL) == 0)
3775	    dyn.d_un.d_val &= ~DF_TEXTREL;
3776	  break;
3777	}
3778      if (skipped)
3779	skipped_size += dynsize;
3780      else
3781	bed->s->swap_dyn_out (output_bfd, &dyn, dyncon - skipped_size);
3782    }
3783  /* Wipe out any trailing entries if we shifted down a dynamic tag.  */
3784  memset (dyncon - skipped_size, 0, skipped_size);
3785  return true;
3786}
3787
3788/* Finish up local dynamic symbol handling.  We set the contents of
3789   various dynamic sections here.  */
3790
3791static bool
3792elfNN_loongarch_finish_local_dynamic_symbol (void **slot, void *inf)
3793{
3794  struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
3795  struct bfd_link_info *info = (struct bfd_link_info *) inf;
3796
3797  return loongarch_elf_finish_dynamic_symbol (info->output_bfd, info, h, NULL);
3798}
3799
3800static bool
3801loongarch_elf_finish_dynamic_sections (bfd *output_bfd,
3802				       struct bfd_link_info *info)
3803{
3804  bfd *dynobj;
3805  asection *sdyn, *plt, *gotplt = NULL;
3806  struct loongarch_elf_link_hash_table *htab;
3807
3808  htab = loongarch_elf_hash_table (info);
3809  BFD_ASSERT (htab);
3810  dynobj = htab->elf.dynobj;
3811  sdyn = bfd_get_linker_section (dynobj, ".dynamic");
3812
3813  if (elf_hash_table (info)->dynamic_sections_created)
3814    {
3815      BFD_ASSERT (htab->elf.splt && sdyn);
3816
3817      if (!loongarch_finish_dyn (output_bfd, info, dynobj, sdyn))
3818	return false;
3819    }
3820
3821  plt = htab->elf.splt;
3822  gotplt = htab->elf.sgotplt;
3823
3824  if (plt && 0 < plt->size)
3825    {
3826      size_t i;
3827      uint32_t plt_header[PLT_HEADER_INSNS];
3828      if (!loongarch_make_plt_header (sec_addr (gotplt), sec_addr (plt),
3829				      plt_header))
3830	return false;
3831
3832      for (i = 0; i < PLT_HEADER_INSNS; i++)
3833	bfd_put_32 (output_bfd, plt_header[i], plt->contents + 4 * i);
3834
3835      elf_section_data (plt->output_section)->this_hdr.sh_entsize =
3836	PLT_ENTRY_SIZE;
3837    }
3838
3839  if (htab->elf.sgotplt)
3840    {
3841      asection *output_section = htab->elf.sgotplt->output_section;
3842
3843      if (bfd_is_abs_section (output_section))
3844	{
3845	  _bfd_error_handler (_("discarded output section: `%pA'"),
3846			      htab->elf.sgotplt);
3847	  return false;
3848	}
3849
3850      if (0 < htab->elf.sgotplt->size)
3851	{
3852	  /* Write the first two entries in .got.plt, needed for the dynamic
3853	     linker.  */
3854	  bfd_put_NN (output_bfd, MINUS_ONE, htab->elf.sgotplt->contents);
3855
3856	  bfd_put_NN (output_bfd, (bfd_vma) 0,
3857		      htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
3858	}
3859
3860      elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
3861    }
3862
3863  if (htab->elf.sgot)
3864    {
3865      asection *output_section = htab->elf.sgot->output_section;
3866
3867      if (0 < htab->elf.sgot->size)
3868	{
3869	  /* Set the first entry in the global offset table to the address of
3870	     the dynamic section.  */
3871	  bfd_vma val = sdyn ? sec_addr (sdyn) : 0;
3872	  bfd_put_NN (output_bfd, val, htab->elf.sgot->contents);
3873	}
3874
3875      elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
3876    }
3877
3878  /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
3879  htab_traverse (htab->loc_hash_table,
3880		 (void *) elfNN_loongarch_finish_local_dynamic_symbol, info);
3881
3882  return true;
3883}
3884
3885/* Return address for Ith PLT stub in section PLT, for relocation REL
3886   or (bfd_vma) -1 if it should not be included.  */
3887
3888static bfd_vma
3889loongarch_elf_plt_sym_val (bfd_vma i, const asection *plt,
3890			   const arelent *rel ATTRIBUTE_UNUSED)
3891{
3892  return plt->vma + PLT_HEADER_SIZE + i * PLT_ENTRY_SIZE;
3893}
3894
3895static enum elf_reloc_type_class
3896loongarch_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
3897			    const asection *rel_sec ATTRIBUTE_UNUSED,
3898			    const Elf_Internal_Rela *rela)
3899{
3900  struct loongarch_elf_link_hash_table *htab;
3901  htab = loongarch_elf_hash_table (info);
3902
3903  if (htab->elf.dynsym != NULL && htab->elf.dynsym->contents != NULL)
3904    {
3905      /* Check relocation against STT_GNU_IFUNC symbol if there are
3906	 dynamic symbols.  */
3907      bfd *abfd = info->output_bfd;
3908      const struct elf_backend_data *bed = get_elf_backend_data (abfd);
3909      unsigned long r_symndx = ELFNN_R_SYM (rela->r_info);
3910      if (r_symndx != STN_UNDEF)
3911	{
3912	  Elf_Internal_Sym sym;
3913	  if (!bed->s->swap_symbol_in (abfd,
3914				       htab->elf.dynsym->contents
3915				       + r_symndx * bed->s->sizeof_sym,
3916				       0, &sym))
3917	    {
3918	      /* xgettext:c-format  */
3919	      _bfd_error_handler (_("%pB symbol number %lu references"
3920				    " nonexistent SHT_SYMTAB_SHNDX section"),
3921				  abfd, r_symndx);
3922	      /* Ideally an error class should be returned here.  */
3923	    }
3924	  else if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
3925	    return reloc_class_ifunc;
3926	}
3927    }
3928
3929  switch (ELFNN_R_TYPE (rela->r_info))
3930    {
3931    case R_LARCH_IRELATIVE:
3932      return reloc_class_ifunc;
3933    case R_LARCH_RELATIVE:
3934      return reloc_class_relative;
3935    case R_LARCH_JUMP_SLOT:
3936      return reloc_class_plt;
3937    case R_LARCH_COPY:
3938      return reloc_class_copy;
3939    default:
3940      return reloc_class_normal;
3941    }
3942}
3943
3944/* Copy the extra info we tack onto an elf_link_hash_entry.  */
3945
3946static void
3947loongarch_elf_copy_indirect_symbol (struct bfd_link_info *info,
3948				    struct elf_link_hash_entry *dir,
3949				    struct elf_link_hash_entry *ind)
3950{
3951  struct elf_link_hash_entry *edir, *eind;
3952
3953  edir = dir;
3954  eind = ind;
3955
3956  if (eind->dyn_relocs != NULL)
3957    {
3958      if (edir->dyn_relocs != NULL)
3959	{
3960	  struct elf_dyn_relocs **pp;
3961	  struct elf_dyn_relocs *p;
3962
3963	  /* Add reloc counts against the indirect sym to the direct sym
3964	     list.  Merge any entries against the same section.  */
3965	  for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
3966	    {
3967	      struct elf_dyn_relocs *q;
3968
3969	      for (q = edir->dyn_relocs; q != NULL; q = q->next)
3970		if (q->sec == p->sec)
3971		  {
3972		    q->pc_count += p->pc_count;
3973		    q->count += p->count;
3974		    *pp = p->next;
3975		    break;
3976		  }
3977	      if (q == NULL)
3978		pp = &p->next;
3979	    }
3980	  *pp = edir->dyn_relocs;
3981	}
3982
3983      edir->dyn_relocs = eind->dyn_relocs;
3984      eind->dyn_relocs = NULL;
3985    }
3986
3987  if (ind->root.type == bfd_link_hash_indirect && dir->got.refcount < 0)
3988    {
3989      loongarch_elf_hash_entry(edir)->tls_type
3990	= loongarch_elf_hash_entry(eind)->tls_type;
3991      loongarch_elf_hash_entry(eind)->tls_type = GOT_UNKNOWN;
3992    }
3993  _bfd_elf_link_hash_copy_indirect (info, dir, ind);
3994}
3995
3996#define PRSTATUS_SIZE		    0x1d8
3997#define PRSTATUS_OFFSET_PR_CURSIG   0xc
3998#define PRSTATUS_OFFSET_PR_PID	    0x20
3999#define ELF_GREGSET_T_SIZE	    0x168
4000#define PRSTATUS_OFFSET_PR_REG	    0x70
4001
4002/* Support for core dump NOTE sections.  */
4003
4004static bool
4005loongarch_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
4006{
4007  switch (note->descsz)
4008    {
4009    default:
4010      return false;
4011
4012    /* The sizeof (struct elf_prstatus) on Linux/LoongArch.  */
4013    case PRSTATUS_SIZE:
4014      /* pr_cursig  */
4015      elf_tdata (abfd)->core->signal =
4016	bfd_get_16 (abfd, note->descdata + PRSTATUS_OFFSET_PR_CURSIG);
4017
4018      /* pr_pid  */
4019      elf_tdata (abfd)->core->lwpid =
4020	bfd_get_32 (abfd, note->descdata + PRSTATUS_OFFSET_PR_PID);
4021      break;
4022    }
4023
4024  /* Make a ".reg/999" section.  */
4025  return _bfd_elfcore_make_pseudosection (abfd, ".reg", ELF_GREGSET_T_SIZE,
4026					  note->descpos
4027					  + PRSTATUS_OFFSET_PR_REG);
4028}
4029
4030#define PRPSINFO_SIZE		    0x88
4031#define PRPSINFO_OFFSET_PR_PID	    0x18
4032#define PRPSINFO_OFFSET_PR_FNAME    0x28
4033#define PRPSINFO_SIZEOF_PR_FNAME    0x10
4034#define PRPSINFO_OFFSET_PR_PS_ARGS  0x38
4035#define PRPSINFO_SIZEOF_PR_PS_ARGS  0x50
4036
4037static bool
4038loongarch_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
4039{
4040  switch (note->descsz)
4041    {
4042    default:
4043      return false;
4044
4045    /* The sizeof (prpsinfo_t) on Linux/LoongArch.  */
4046    case PRPSINFO_SIZE:
4047      /* pr_pid  */
4048      elf_tdata (abfd)->core->pid =
4049	bfd_get_32 (abfd, note->descdata + PRPSINFO_OFFSET_PR_PID);
4050
4051      /* pr_fname  */
4052      elf_tdata (abfd)->core->program =
4053	_bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_FNAME,
4054			      PRPSINFO_SIZEOF_PR_FNAME);
4055
4056      /* pr_psargs  */
4057      elf_tdata (abfd)->core->command =
4058	_bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_PS_ARGS,
4059			      PRPSINFO_SIZEOF_PR_PS_ARGS);
4060      break;
4061    }
4062
4063  /* Note that for some reason, a spurious space is tacked
4064     onto the end of the args in some (at least one anyway)
4065     implementations, so strip it off if it exists.  */
4066
4067  {
4068    char *command = elf_tdata (abfd)->core->command;
4069    int n = strlen (command);
4070
4071    if (0 < n && command[n - 1] == ' ')
4072      command[n - 1] = '\0';
4073  }
4074
4075  return true;
4076}
4077
4078/* Set the right mach type.  */
4079static bool
4080loongarch_elf_object_p (bfd *abfd)
4081{
4082  /* There are only two mach types in LoongArch currently.  */
4083  if (strcmp (abfd->xvec->name, "elf64-loongarch") == 0)
4084    bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch64);
4085  else
4086    bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch32);
4087  return true;
4088}
4089
4090static asection *
4091loongarch_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info,
4092			    Elf_Internal_Rela *rel,
4093			    struct elf_link_hash_entry *h,
4094			    Elf_Internal_Sym *sym)
4095{
4096  if (h != NULL)
4097    switch (ELFNN_R_TYPE (rel->r_info))
4098      {
4099      case R_LARCH_GNU_VTINHERIT:
4100      case R_LARCH_GNU_VTENTRY:
4101	return NULL;
4102      }
4103
4104  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
4105}
4106
4107/* Return TRUE if symbol H should be hashed in the `.gnu.hash' section.  For
4108   executable PLT slots where the executable never takes the address of those
4109   functions, the function symbols are not added to the hash table.  */
4110
4111static bool
4112elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
4113{
4114  if (h->plt.offset != (bfd_vma) -1
4115      && !h->def_regular
4116      && !h->pointer_equality_needed)
4117    return false;
4118
4119  return _bfd_elf_hash_symbol (h);
4120}
4121
4122#define TARGET_LITTLE_SYM loongarch_elfNN_vec
4123#define TARGET_LITTLE_NAME "elfNN-loongarch"
4124#define ELF_ARCH bfd_arch_loongarch
4125#define ELF_TARGET_ID LARCH_ELF_DATA
4126#define ELF_MACHINE_CODE EM_LOONGARCH
4127#define ELF_MAXPAGESIZE 0x4000
4128#define bfd_elfNN_bfd_reloc_type_lookup loongarch_reloc_type_lookup
4129#define bfd_elfNN_bfd_link_hash_table_create				  \
4130  loongarch_elf_link_hash_table_create
4131#define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup
4132#define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto.  */
4133#define elf_info_to_howto loongarch_info_to_howto_rela
4134#define bfd_elfNN_bfd_merge_private_bfd_data				  \
4135  elfNN_loongarch_merge_private_bfd_data
4136
4137#define elf_backend_reloc_type_class loongarch_reloc_type_class
4138#define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol
4139#define elf_backend_create_dynamic_sections				   \
4140  loongarch_elf_create_dynamic_sections
4141#define elf_backend_check_relocs loongarch_elf_check_relocs
4142#define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol
4143#define elf_backend_size_dynamic_sections loongarch_elf_size_dynamic_sections
4144#define elf_backend_relocate_section loongarch_elf_relocate_section
4145#define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol
4146#define elf_backend_finish_dynamic_sections				   \
4147  loongarch_elf_finish_dynamic_sections
4148#define elf_backend_object_p loongarch_elf_object_p
4149#define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook
4150#define elf_backend_plt_sym_val loongarch_elf_plt_sym_val
4151#define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
4152#define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
4153#define elf_backend_hash_symbol elf_loongarch64_hash_symbol
4154
4155#include "elfNN-target.h"
4156