xref: /netbsd-src/external/gpl3/gdb.old/dist/bfd/elfnn-loongarch.c (revision 8e33eff89e26cf71871ead62f0d5063e1313c33a)
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 
31 static bool
32 loongarch_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.  */
41 struct 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 
56 struct _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 
80 struct 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 
139 static bool
140 loongarch_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 
191 static bool
192 loongarch_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 
218 static struct bfd_hash_entry *
219 link_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 
249 static hashval_t
250 elfNN_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 
258 static int
259 elfNN_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.  */
268 static struct elf_link_hash_entry *
269 elfNN_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 
318 static void
319 elfNN_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 
334 static struct bfd_link_hash_table *
335 loongarch_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 
370 static bool
371 elfNN_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 
450 static bool
451 loongarch_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 
509 static bool
510 loongarch_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 
535 static bool
536 loongarch_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 
600 static bool
601 loongarch_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 
941 static asection *
942 readonly_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.  */
961 static bool
962 loongarch_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 
1024 static bool
1025 allocate_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 
1240 static bool
1241 local_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 
1487 static bool
1488 elfNN_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 
1534 static bool
1535 elfNN_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 
1552 static bool
1553 maybe_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 
1576 static bool
1577 loongarch_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
1810 static int64_t larch_opc_stack[LARCH_LD_STACK_DEPTH];
1811 static size_t larch_stack_top = 0;
1812 
1813 static bfd_reloc_status_type
1814 loongarch_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 
1822 static bfd_reloc_status_type
1823 loongarch_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 
1832 static bfd_reloc_status_type
1833 loongarch_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 
1842 static void
1843 loongarch_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.  */
1857 static bfd_reloc_status_type
1858 loongarch_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 
1880 static bfd_reloc_status_type
1881 loongarch_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 
1900 static bfd_reloc_status_type
1901 perform_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
2102 static 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];
2114 static size_t larch_reloc_queue_head = 0;
2115 static size_t larch_reloc_queue_tail = 0;
2116 
2117 static const char *
2118 loongarch_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 
2134 static void
2135 loongarch_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 
2156 static void
2157 loongarch_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 
2203 static bool
2204 loongarch_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 
2269 static int
2270 loongarch_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 
3524 static bool
3525 loongarch_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 
3737 static bool
3738 loongarch_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 
3791 static bool
3792 elfNN_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 
3800 static bool
3801 loongarch_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 
3888 static bfd_vma
3889 loongarch_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 
3895 static enum elf_reloc_type_class
3896 loongarch_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 
3946 static void
3947 loongarch_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 
4004 static bool
4005 loongarch_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 
4037 static bool
4038 loongarch_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.  */
4079 static bool
4080 loongarch_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 
4090 static asection *
4091 loongarch_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 
4111 static bool
4112 elf_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