xref: /netbsd-src/external/gpl3/binutils/dist/bfd/elfnn-loongarch.c (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
1 /* LoongArch-specific support for NN-bit ELF.
2    Copyright (C) 2021-2024 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 #include "opcode/loongarch.h"
31 
32 static bool
loongarch_info_to_howto_rela(bfd * abfd,arelent * cache_ptr,Elf_Internal_Rela * dst)33 loongarch_info_to_howto_rela (bfd *abfd, arelent *cache_ptr,
34 			      Elf_Internal_Rela *dst)
35 {
36   cache_ptr->howto = loongarch_elf_rtype_to_howto (abfd,
37 						   ELFNN_R_TYPE (dst->r_info));
38   return cache_ptr->howto != NULL;
39 }
40 
41 /* LoongArch ELF linker hash entry.  */
42 struct loongarch_elf_link_hash_entry
43 {
44   struct elf_link_hash_entry elf;
45 
46 #define GOT_UNKNOWN 0
47 #define GOT_NORMAL  1
48 #define GOT_TLS_GD  2
49 #define GOT_TLS_IE  4
50 #define GOT_TLS_LE  8
51 #define GOT_TLS_GDESC 16
52 
53 #define GOT_TLS_GD_BOTH_P(tls_type) \
54   ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC))
55 #define GOT_TLS_GD_ANY_P(tls_type) \
56   ((tls_type & GOT_TLS_GD) || (tls_type & GOT_TLS_GDESC))
57   char tls_type;
58 };
59 
60 #define loongarch_elf_hash_entry(ent)	\
61   ((struct loongarch_elf_link_hash_entry *) (ent))
62 
63 struct _bfd_loongarch_elf_obj_tdata
64 {
65   struct elf_obj_tdata root;
66 
67   /* The tls_type for each local got entry.  */
68   char *local_got_tls_type;
69 };
70 
71 #define _bfd_loongarch_elf_tdata(abfd)	\
72   ((struct _bfd_loongarch_elf_obj_tdata *) (abfd)->tdata.any)
73 
74 #define _bfd_loongarch_elf_local_got_tls_type(abfd)	\
75   (_bfd_loongarch_elf_tdata (abfd)->local_got_tls_type)
76 
77 #define _bfd_loongarch_elf_tls_type(abfd, h, symndx)			\
78   (*((h) != NULL							\
79      ? &loongarch_elf_hash_entry (h)->tls_type				\
80      : &_bfd_loongarch_elf_local_got_tls_type (abfd)[symndx]))
81 
82 #define is_loongarch_elf(bfd)						\
83   (bfd_get_flavour (bfd) == bfd_target_elf_flavour			\
84    && elf_tdata (bfd) != NULL						\
85    && elf_object_id (bfd) == LARCH_ELF_DATA)
86 
87 struct loongarch_elf_link_hash_table
88 {
89   struct elf_link_hash_table elf;
90 
91   /* Short-cuts to get to dynamic linker sections.  */
92   asection *sdyntdata;
93 
94   /* Small local sym to section mapping cache.  */
95   struct sym_cache sym_cache;
96 
97   /* Used by local STT_GNU_IFUNC symbols.  */
98   htab_t loc_hash_table;
99   void *loc_hash_memory;
100 
101   /* The max alignment of output sections.  */
102   bfd_vma max_alignment;
103 
104   /* The data segment phase, don't relax the section
105      when it is exp_seg_relro_adjust.  */
106   int *data_segment_phase;
107 };
108 
109 /* Get the LoongArch ELF linker hash table from a link_info structure.  */
110 #define loongarch_elf_hash_table(p)					\
111   (elf_hash_table_id (elf_hash_table (p)) == LARCH_ELF_DATA		\
112    ? ((struct loongarch_elf_link_hash_table *) ((p)->hash))		\
113    : NULL)
114 
115 #define MINUS_ONE ((bfd_vma) 0 - 1)
116 
117 #define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset)
118 
119 #define LARCH_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3)
120 #define LARCH_ELF_WORD_BYTES (1 << LARCH_ELF_LOG_WORD_BYTES)
121 
122 #define PLT_HEADER_INSNS 8
123 #define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
124 
125 #define PLT_ENTRY_INSNS 4
126 #define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
127 
128 #define GOT_ENTRY_SIZE (LARCH_ELF_WORD_BYTES)
129 
130 #define GOTPLT_HEADER_SIZE (GOT_ENTRY_SIZE * 2)
131 
132 #define elf_backend_want_got_plt 1
133 
134 #define elf_backend_plt_readonly 1
135 
136 #define elf_backend_want_plt_sym 1
137 #define elf_backend_plt_alignment 4
138 #define elf_backend_can_gc_sections 1
139 #define elf_backend_can_refcount 1
140 #define elf_backend_want_got_sym 1
141 
142 #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 1)
143 
144 #define elf_backend_want_dynrelro 1
145 #define elf_backend_rela_normal 1
146 #define elf_backend_default_execstack 0
147 
148 #define IS_LOONGARCH_TLS_TRANS_RELOC(R_TYPE)  \
149   ((R_TYPE) == R_LARCH_TLS_DESC_PC_HI20	      \
150    || (R_TYPE) == R_LARCH_TLS_DESC_PC_LO12    \
151    || (R_TYPE) == R_LARCH_TLS_DESC_LD	      \
152    || (R_TYPE) == R_LARCH_TLS_DESC_CALL	      \
153    || (R_TYPE) == R_LARCH_TLS_IE_PC_HI20      \
154    || (R_TYPE) == R_LARCH_TLS_IE_PC_LO12)
155 
156 /* Generate a PLT header.  */
157 
158 static bool
loongarch_make_plt_header(bfd_vma got_plt_addr,bfd_vma plt_header_addr,uint32_t * entry)159 loongarch_make_plt_header (bfd_vma got_plt_addr, bfd_vma plt_header_addr,
160 			   uint32_t *entry)
161 {
162   bfd_vma pcrel = got_plt_addr - plt_header_addr;
163   bfd_vma hi, lo;
164 
165   if (pcrel + 0x80000800 > 0xffffffff)
166     {
167       _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
168       bfd_set_error (bfd_error_bad_value);
169       return false;
170     }
171   hi = ((pcrel + 0x800) >> 12) & 0xfffff;
172   lo = pcrel & 0xfff;
173 
174   /* pcaddu12i  $t2, %hi(%pcrel(.got.plt))
175      sub.[wd]   $t1, $t1, $t3
176      ld.[wd]    $t3, $t2, %lo(%pcrel(.got.plt)) # _dl_runtime_resolve
177      addi.[wd]  $t1, $t1, -(PLT_HEADER_SIZE + 12)
178      addi.[wd]  $t0, $t2, %lo(%pcrel(.got.plt))
179      srli.[wd]  $t1, $t1, log2(16 / GOT_ENTRY_SIZE)
180      ld.[wd]    $t0, $t0, GOT_ENTRY_SIZE
181      jirl   $r0, $t3, 0 */
182 
183   if (GOT_ENTRY_SIZE == 8)
184     {
185       entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
186       entry[1] = 0x0011bdad;
187       entry[2] = 0x28c001cf | (lo & 0xfff) << 10;
188       entry[3] = 0x02c001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
189       entry[4] = 0x02c001cc | (lo & 0xfff) << 10;
190       entry[5] = 0x004501ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
191       entry[6] = 0x28c0018c | GOT_ENTRY_SIZE << 10;
192       entry[7] = 0x4c0001e0;
193     }
194   else
195     {
196       entry[0] = 0x1c00000e | (hi & 0xfffff) << 5;
197       entry[1] = 0x00113dad;
198       entry[2] = 0x288001cf | (lo & 0xfff) << 10;
199       entry[3] = 0x028001ad | ((-(PLT_HEADER_SIZE + 12)) & 0xfff) << 10;
200       entry[4] = 0x028001cc | (lo & 0xfff) << 10;
201       entry[5] = 0x004481ad | (4 - LARCH_ELF_LOG_WORD_BYTES) << 10;
202       entry[6] = 0x2880018c | GOT_ENTRY_SIZE << 10;
203       entry[7] = 0x4c0001e0;
204     }
205   return true;
206 }
207 
208 /* Generate a PLT entry.  */
209 
210 static bool
loongarch_make_plt_entry(bfd_vma got_plt_entry_addr,bfd_vma plt_entry_addr,uint32_t * entry)211 loongarch_make_plt_entry (bfd_vma got_plt_entry_addr, bfd_vma plt_entry_addr,
212 			  uint32_t *entry)
213 {
214   bfd_vma pcrel = got_plt_entry_addr - plt_entry_addr;
215   bfd_vma hi, lo;
216 
217   if (pcrel + 0x80000800 > 0xffffffff)
218     {
219       _bfd_error_handler (_("%#" PRIx64 " invaild imm"), (uint64_t) pcrel);
220       bfd_set_error (bfd_error_bad_value);
221       return false;
222     }
223   hi = ((pcrel + 0x800) >> 12) & 0xfffff;
224   lo = pcrel & 0xfff;
225 
226   entry[0] = 0x1c00000f | (hi & 0xfffff) << 5;
227   entry[1] = ((GOT_ENTRY_SIZE == 8 ? 0x28c001ef : 0x288001ef)
228 	      | (lo & 0xfff) << 10);
229   entry[2] = 0x4c0001ed;	/* jirl $r13, $15, 0 */
230   entry[3] = 0x03400000;	/* nop */
231 
232   return true;
233 }
234 
235 /* Create an entry in an LoongArch ELF linker hash table.  */
236 
237 static struct bfd_hash_entry *
link_hash_newfunc(struct bfd_hash_entry * entry,struct bfd_hash_table * table,const char * string)238 link_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
239 		   const char *string)
240 {
241   struct loongarch_elf_link_hash_entry *eh;
242 
243   /* Allocate the structure if it has not already been allocated by a
244      subclass.  */
245   if (entry == NULL)
246     {
247       entry = bfd_hash_allocate (table, sizeof (*eh));
248       if (entry == NULL)
249 	return entry;
250     }
251 
252   /* Call the allocation method of the superclass.  */
253   entry = _bfd_elf_link_hash_newfunc (entry, table, string);
254   if (entry != NULL)
255     {
256       eh = (struct loongarch_elf_link_hash_entry *) entry;
257       eh->tls_type = GOT_UNKNOWN;
258     }
259 
260   return entry;
261 }
262 
263 /* Compute a hash of a local hash entry.  We use elf_link_hash_entry
264   for local symbol so that we can handle local STT_GNU_IFUNC symbols
265   as global symbol.  We reuse indx and dynstr_index for local symbol
266   hash since they aren't used by global symbols in this backend.  */
267 
268 static hashval_t
elfNN_loongarch_local_htab_hash(const void * ptr)269 elfNN_loongarch_local_htab_hash (const void *ptr)
270 {
271   struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) ptr;
272   return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
273 }
274 
275 /* Compare local hash entries.  */
276 
277 static int
elfNN_loongarch_local_htab_eq(const void * ptr1,const void * ptr2)278 elfNN_loongarch_local_htab_eq (const void *ptr1, const void *ptr2)
279 {
280   struct elf_link_hash_entry *h1 = (struct elf_link_hash_entry *) ptr1;
281   struct elf_link_hash_entry *h2 = (struct elf_link_hash_entry *) ptr2;
282 
283   return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
284 }
285 
286 /* Find and/or create a hash entry for local symbol.  */
287 static struct elf_link_hash_entry *
elfNN_loongarch_get_local_sym_hash(struct loongarch_elf_link_hash_table * htab,bfd * abfd,const Elf_Internal_Rela * rel,bool create)288 elfNN_loongarch_get_local_sym_hash (struct loongarch_elf_link_hash_table *htab,
289 				    bfd *abfd, const Elf_Internal_Rela *rel,
290 				    bool create)
291 {
292   struct loongarch_elf_link_hash_entry e, *ret;
293   asection *sec = abfd->sections;
294   hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id, ELFNN_R_SYM (rel->r_info));
295   void **slot;
296 
297   e.elf.indx = sec->id;
298   e.elf.dynstr_index = ELFNN_R_SYM (rel->r_info);
299   slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
300 				   create ? INSERT : NO_INSERT);
301 
302   if (!slot)
303     return NULL;
304 
305   if (*slot)
306     {
307       ret = (struct loongarch_elf_link_hash_entry *) *slot;
308       return &ret->elf;
309     }
310 
311   ret = ((struct loongarch_elf_link_hash_entry *)
312 	 objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
313 			 sizeof (struct loongarch_elf_link_hash_entry)));
314   if (ret)
315     {
316       memset (ret, 0, sizeof (*ret));
317       ret->elf.indx = sec->id;
318       ret->elf.pointer_equality_needed = 0;
319       ret->elf.dynstr_index = ELFNN_R_SYM (rel->r_info);
320       ret->elf.dynindx = -1;
321       ret->elf.needs_plt = 0;
322       ret->elf.plt.refcount = -1;
323       ret->elf.got.refcount = -1;
324       ret->elf.def_dynamic = 0;
325       ret->elf.def_regular = 1;
326       ret->elf.ref_dynamic = 0; /* This should be always 0 for local.  */
327       ret->elf.ref_regular = 0;
328       ret->elf.forced_local = 1;
329       ret->elf.root.type = bfd_link_hash_defined;
330       *slot = ret;
331     }
332   return &ret->elf;
333 }
334 
335 /* Destroy an LoongArch elf linker hash table.  */
336 
337 static void
elfNN_loongarch_link_hash_table_free(bfd * obfd)338 elfNN_loongarch_link_hash_table_free (bfd *obfd)
339 {
340   struct loongarch_elf_link_hash_table *ret;
341   ret = (struct loongarch_elf_link_hash_table *) obfd->link.hash;
342 
343   if (ret->loc_hash_table)
344     htab_delete (ret->loc_hash_table);
345   if (ret->loc_hash_memory)
346     objalloc_free ((struct objalloc *) ret->loc_hash_memory);
347 
348   _bfd_elf_link_hash_table_free (obfd);
349 }
350 
351 /* Create a LoongArch ELF linker hash table.  */
352 
353 static struct bfd_link_hash_table *
loongarch_elf_link_hash_table_create(bfd * abfd)354 loongarch_elf_link_hash_table_create (bfd *abfd)
355 {
356   struct loongarch_elf_link_hash_table *ret;
357   bfd_size_type amt = sizeof (struct loongarch_elf_link_hash_table);
358 
359   ret = (struct loongarch_elf_link_hash_table *) bfd_zmalloc (amt);
360   if (ret == NULL)
361     return NULL;
362 
363   if (!_bfd_elf_link_hash_table_init
364       (&ret->elf, abfd, link_hash_newfunc,
365        sizeof (struct loongarch_elf_link_hash_entry), LARCH_ELF_DATA))
366     {
367       free (ret);
368       return NULL;
369     }
370 
371   ret->max_alignment = MINUS_ONE;
372 
373   ret->loc_hash_table = htab_try_create (1024, elfNN_loongarch_local_htab_hash,
374 					 elfNN_loongarch_local_htab_eq, NULL);
375   ret->loc_hash_memory = objalloc_create ();
376   if (!ret->loc_hash_table || !ret->loc_hash_memory)
377     {
378       elfNN_loongarch_link_hash_table_free (abfd);
379       return NULL;
380     }
381   ret->elf.root.hash_table_free = elfNN_loongarch_link_hash_table_free;
382 
383   return &ret->elf.root;
384 }
385 
386 /* Merge backend specific data from an object file to the output
387    object file when linking.  */
388 
389 static bool
elfNN_loongarch_merge_private_bfd_data(bfd * ibfd,struct bfd_link_info * info)390 elfNN_loongarch_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
391 {
392   bfd *obfd = info->output_bfd;
393   flagword in_flags = elf_elfheader (ibfd)->e_flags;
394   flagword out_flags = elf_elfheader (obfd)->e_flags;
395 
396   if (!is_loongarch_elf (ibfd) || !is_loongarch_elf (obfd))
397     return true;
398 
399   if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
400     {
401       _bfd_error_handler (_("%pB: ABI is incompatible with that of "
402 			    "the selected emulation:\n"
403 			    "  target emulation `%s' does not match `%s'"),
404 			  ibfd, bfd_get_target (ibfd), bfd_get_target (obfd));
405       return false;
406     }
407 
408   if (!_bfd_elf_merge_object_attributes (ibfd, info))
409     return false;
410 
411   /* If the input BFD is not a dynamic object and it does not contain any
412      non-data sections, do not account its ABI.  For example, various
413      packages produces such data-only relocatable objects with
414      `ld -r -b binary` or `objcopy`, and these objects have zero e_flags.
415      But they are compatible with all ABIs.  */
416   if (!(ibfd->flags & DYNAMIC))
417     {
418       asection *sec;
419       bool have_code_sections = false;
420       for (sec = ibfd->sections; sec != NULL; sec = sec->next)
421 	if ((bfd_section_flags (sec)
422 	     & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
423 	    == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
424 	  {
425 	    have_code_sections = true;
426 	    break;
427 	  }
428       if (!have_code_sections)
429 	return true;
430     }
431 
432   if (!elf_flags_init (obfd))
433     {
434       elf_flags_init (obfd) = true;
435       elf_elfheader (obfd)->e_flags = in_flags;
436       return true;
437     }
438   else if (out_flags != in_flags)
439     {
440       if ((EF_LOONGARCH_IS_OBJ_V0 (out_flags)
441 	   && EF_LOONGARCH_IS_OBJ_V1 (in_flags))
442 	  || (EF_LOONGARCH_IS_OBJ_V0 (in_flags)
443 	      && EF_LOONGARCH_IS_OBJ_V1 (out_flags)))
444 	{
445 	  elf_elfheader (obfd)->e_flags |= EF_LOONGARCH_OBJABI_V1;
446 	  out_flags = elf_elfheader (obfd)->e_flags;
447 	  in_flags = out_flags;
448 	}
449     }
450 
451   /* Disallow linking different ABIs.  */
452   /* Only check relocation version.
453      The obj_v0 is compatible with obj_v1.  */
454   if (EF_LOONGARCH_ABI(out_flags ^ in_flags) & EF_LOONGARCH_ABI_MASK)
455     {
456       _bfd_error_handler (_("%pB: can't link different ABI object."), ibfd);
457       goto fail;
458     }
459 
460   return true;
461 
462  fail:
463   bfd_set_error (bfd_error_bad_value);
464   return false;
465 }
466 
467 /* Create the .got section.  */
468 
469 static bool
loongarch_elf_create_got_section(bfd * abfd,struct bfd_link_info * info)470 loongarch_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
471 {
472   flagword flags;
473   char *name;
474   asection *s, *s_got;
475   struct elf_link_hash_entry *h;
476   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
477   struct elf_link_hash_table *htab = elf_hash_table (info);
478 
479   /* This function may be called more than once.  */
480   if (htab->sgot != NULL)
481     return true;
482 
483   flags = bed->dynamic_sec_flags;
484   name = bed->rela_plts_and_copies_p ? ".rela.got" : ".rel.got";
485   s = bfd_make_section_anyway_with_flags (abfd, name, flags | SEC_READONLY);
486 
487   if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
488     return false;
489   htab->srelgot = s;
490 
491   s = s_got = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
492   if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
493     return false;
494   htab->sgot = s;
495 
496   /* The first bit of the global offset table is the header.  */
497   s->size += bed->got_header_size;
498 
499   if (bed->want_got_plt)
500     {
501       s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
502       if (s == NULL || !bfd_set_section_alignment (s, bed->s->log_file_align))
503 	return false;
504       htab->sgotplt = s;
505 
506       /* Reserve room for the header.  */
507       s->size = GOTPLT_HEADER_SIZE;
508     }
509 
510   if (bed->want_got_sym)
511     {
512       /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
513 	 section.  We don't do this in the linker script because we don't want
514 	 to define the symbol if we are not creating a global offset table.  */
515       h = _bfd_elf_define_linkage_sym (abfd, info, s_got,
516 				       "_GLOBAL_OFFSET_TABLE_");
517       elf_hash_table (info)->hgot = h;
518       if (h == NULL)
519 	return false;
520     }
521   return true;
522 }
523 
524 /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
525    .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
526    hash table.  */
527 
528 static bool
loongarch_elf_create_dynamic_sections(bfd * dynobj,struct bfd_link_info * info)529 loongarch_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
530 {
531   struct loongarch_elf_link_hash_table *htab;
532 
533   htab = loongarch_elf_hash_table (info);
534   BFD_ASSERT (htab != NULL);
535 
536   if (!loongarch_elf_create_got_section (dynobj, info))
537     return false;
538 
539   if (!_bfd_elf_create_dynamic_sections (dynobj, info))
540     return false;
541 
542   if (!bfd_link_pic (info))
543     htab->sdyntdata
544       = bfd_make_section_anyway_with_flags (dynobj, ".tdata.dyn",
545 					    SEC_ALLOC | SEC_THREAD_LOCAL);
546 
547   if (!htab->elf.splt || !htab->elf.srelplt || !htab->elf.sdynbss
548       || (!bfd_link_pic (info) && (!htab->elf.srelbss || !htab->sdyntdata)))
549     abort ();
550 
551   return true;
552 }
553 
554 static bool
loongarch_elf_record_tls_and_got_reference(bfd * abfd,struct bfd_link_info * info,struct elf_link_hash_entry * h,unsigned long symndx,char tls_type)555 loongarch_elf_record_tls_and_got_reference (bfd *abfd,
556 					    struct bfd_link_info *info,
557 					    struct elf_link_hash_entry *h,
558 					    unsigned long symndx,
559 					    char tls_type)
560 {
561   struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
562   Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
563 
564   /* This is a global offset table entry for a local symbol.  */
565   if (elf_local_got_refcounts (abfd) == NULL)
566     {
567       bfd_size_type size =
568 	symtab_hdr->sh_info * (sizeof (bfd_vma) + sizeof (tls_type));
569       if (!(elf_local_got_refcounts (abfd) = bfd_zalloc (abfd, size)))
570 	return false;
571       _bfd_loongarch_elf_local_got_tls_type (abfd) =
572 	(char *) (elf_local_got_refcounts (abfd) + symtab_hdr->sh_info);
573     }
574 
575   switch (tls_type)
576     {
577     case GOT_NORMAL:
578     case GOT_TLS_GD:
579     case GOT_TLS_IE:
580     case GOT_TLS_GDESC:
581       /* Need GOT.  */
582       if (htab->elf.sgot == NULL
583 	  && !loongarch_elf_create_got_section (htab->elf.dynobj, info))
584 	return false;
585       if (h)
586 	{
587 	  if (h->got.refcount < 0)
588 	    h->got.refcount = 0;
589 	  h->got.refcount++;
590 	}
591       else
592 	elf_local_got_refcounts (abfd)[symndx]++;
593       break;
594     case GOT_TLS_LE:
595       /* No need for GOT.  */
596       break;
597     default:
598       _bfd_error_handler (_("Internal error: unreachable."));
599       return false;
600     }
601 
602   char *new_tls_type = &_bfd_loongarch_elf_tls_type (abfd, h, symndx);
603   *new_tls_type |= tls_type;
604 
605   /* If a symbol is accessed by both IE and DESC, relax DESC to IE.  */
606   if ((*new_tls_type & GOT_TLS_IE) && (*new_tls_type & GOT_TLS_GDESC))
607     *new_tls_type &= ~ (GOT_TLS_GDESC);
608   if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL))
609     {
610       _bfd_error_handler (_("%pB: `%s' accessed both as normal and "
611 			    "thread local symbol"),
612 			  abfd,
613 			  h ? h->root.root.string : "<local>");
614       return false;
615     }
616 
617   return true;
618 }
619 
620 static unsigned int
loongarch_reloc_got_type(unsigned int r_type)621 loongarch_reloc_got_type (unsigned int r_type)
622 {
623   switch (r_type)
624     {
625       case R_LARCH_TLS_DESC_PC_HI20:
626       case R_LARCH_TLS_DESC_PC_LO12:
627       case R_LARCH_TLS_DESC_LD:
628       case R_LARCH_TLS_DESC_CALL:
629 	return GOT_TLS_GDESC;
630 
631       case R_LARCH_TLS_IE_PC_HI20:
632       case R_LARCH_TLS_IE_PC_LO12:
633 	return GOT_TLS_IE;
634 
635       default:
636 	break;
637     }
638   return GOT_UNKNOWN;
639 }
640 
641 /* Return true if tls type transition can be performed.  */
642 static bool
loongarch_can_trans_tls(bfd * input_bfd,struct bfd_link_info * info,struct elf_link_hash_entry * h,const Elf_Internal_Rela * rel,unsigned int r_type)643 loongarch_can_trans_tls (bfd *input_bfd,
644 			  struct bfd_link_info *info,
645 			  struct elf_link_hash_entry *h,
646 			  const Elf_Internal_Rela *rel,
647 			  unsigned int r_type)
648 {
649   char symbol_tls_type;
650   unsigned int reloc_got_type;
651   unsigned int r_symndx = ELFNN_R_SYM (rel->r_info);
652 
653   /* Only TLS DESC/IE in normal code mode will perform type
654      transition.  */
655   if (! (IS_LOONGARCH_TLS_TRANS_RELOC (r_type)
656 	  && ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX))
657     return false;
658 
659   symbol_tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
660   reloc_got_type = loongarch_reloc_got_type (r_type);
661 
662   if (symbol_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (reloc_got_type))
663     return true;
664 
665   if (! bfd_link_executable (info))
666       return false;
667 
668   if (h && h->root.type == bfd_link_hash_undefweak)
669     return false;
670 
671   return true;
672 }
673 
674 /* The type of relocation that can be transitioned.  */
675 static unsigned int
loongarch_tls_transition_without_check(struct bfd_link_info * info,unsigned int r_type,struct elf_link_hash_entry * h)676 loongarch_tls_transition_without_check (struct bfd_link_info *info,
677 					unsigned int r_type,
678 					struct elf_link_hash_entry *h)
679 {
680   bool local_exec = bfd_link_executable (info)
681 		    && SYMBOL_REFERENCES_LOCAL (info, h);
682 
683   switch (r_type)
684     {
685       case R_LARCH_TLS_DESC_PC_HI20:
686 	return (local_exec
687 		? R_LARCH_TLS_LE_HI20
688 		: R_LARCH_TLS_IE_PC_HI20);
689 
690       case R_LARCH_TLS_DESC_PC_LO12:
691 	return (local_exec
692 		? R_LARCH_TLS_LE_LO12
693 		: R_LARCH_TLS_IE_PC_LO12);
694 
695       case R_LARCH_TLS_DESC_LD:
696       case R_LARCH_TLS_DESC_CALL:
697 	return R_LARCH_NONE;
698 
699       case R_LARCH_TLS_IE_PC_HI20:
700 	return local_exec ? R_LARCH_TLS_LE_HI20 : r_type;
701 
702       case R_LARCH_TLS_IE_PC_LO12:
703 	return local_exec ? R_LARCH_TLS_LE_LO12 : r_type;
704 
705       default:
706 	break;
707     }
708 
709   return r_type;
710 }
711 
712 static unsigned int
loongarch_tls_transition(bfd * input_bfd,struct bfd_link_info * info,struct elf_link_hash_entry * h,const Elf_Internal_Rela * rel,unsigned int r_type)713 loongarch_tls_transition (bfd *input_bfd,
714 			  struct bfd_link_info *info,
715 			  struct elf_link_hash_entry *h,
716 			  const Elf_Internal_Rela *rel,
717 			  unsigned int r_type)
718 {
719   if (! loongarch_can_trans_tls (input_bfd, info, h, rel, r_type))
720     return r_type;
721 
722   return loongarch_tls_transition_without_check (info, r_type, h);
723 }
724 
725 /* Look through the relocs for a section during the first phase, and
726    allocate space in the global offset table or procedure linkage
727    table.  */
728 
729 static bool
loongarch_elf_check_relocs(bfd * abfd,struct bfd_link_info * info,asection * sec,const Elf_Internal_Rela * relocs)730 loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
731 			    asection *sec, const Elf_Internal_Rela *relocs)
732 {
733   struct loongarch_elf_link_hash_table *htab;
734   Elf_Internal_Shdr *symtab_hdr;
735   struct elf_link_hash_entry **sym_hashes;
736   const Elf_Internal_Rela *rel;
737   asection *sreloc = NULL;
738 
739   if (bfd_link_relocatable (info))
740     return true;
741 
742   htab = loongarch_elf_hash_table (info);
743   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
744   sym_hashes = elf_sym_hashes (abfd);
745 
746   if (htab->elf.dynobj == NULL)
747     htab->elf.dynobj = abfd;
748 
749   for (rel = relocs; rel < relocs + sec->reloc_count; rel++)
750     {
751       unsigned int r_type;
752       unsigned int r_symndx;
753       struct elf_link_hash_entry *h;
754       Elf_Internal_Sym *isym = NULL;
755 
756       r_symndx = ELFNN_R_SYM (rel->r_info);
757       r_type = ELFNN_R_TYPE (rel->r_info);
758 
759       if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
760 	{
761 	  _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd, r_symndx);
762 	  return false;
763 	}
764 
765       if (r_symndx < symtab_hdr->sh_info)
766 	{
767 	  /* A local symbol.  */
768 	  isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, r_symndx);
769 	  if (isym == NULL)
770 	    return false;
771 
772 	  if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
773 	    {
774 	      h = elfNN_loongarch_get_local_sym_hash (htab, abfd, rel, true);
775 	      if (h == NULL)
776 		return false;
777 
778 	      h->type = STT_GNU_IFUNC;
779 	      h->ref_regular = 1;
780 	    }
781 	  else
782 	    h = NULL;
783 	}
784       else
785 	{
786 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
787 	  while (h->root.type == bfd_link_hash_indirect
788 		 || h->root.type == bfd_link_hash_warning)
789 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
790 	}
791 
792       /* It is referenced by a non-shared object.  */
793       if (h != NULL)
794 	h->ref_regular = 1;
795 
796       if (h && h->type == STT_GNU_IFUNC)
797 	{
798 	  if (htab->elf.dynobj == NULL)
799 	    htab->elf.dynobj = abfd;
800 
801 	  /* Create 'irelifunc' in PIC object.  */
802 	  if (bfd_link_pic (info)
803 	      && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
804 	    return false;
805 	  /* If '.plt' not represent, create '.iplt' to deal with ifunc.  */
806 	  else if (!htab->elf.splt
807 		   && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
808 	    return false;
809 	  /* Create the ifunc sections, iplt and ipltgot, for static
810 	     executables.  */
811 	  if ((r_type == R_LARCH_64 || r_type == R_LARCH_32)
812 	      && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj, info))
813 	    return false;
814 
815 	  if (h->plt.refcount < 0)
816 	    h->plt.refcount = 0;
817 	  h->plt.refcount++;
818 	  h->needs_plt = 1;
819 
820 	  elf_tdata (info->output_bfd)->has_gnu_osabi |= elf_gnu_osabi_ifunc;
821 	}
822 
823       int need_dynreloc = 0;
824       int only_need_pcrel = 0;
825 
826       /* Type transitions are only possible with relocations accompanied
827 	 by R_LARCH_RELAX.  */
828       if (rel + 1 != relocs + sec->reloc_count)
829 	r_type = loongarch_tls_transition (abfd, info, h, rel, r_type);
830       switch (r_type)
831 	{
832 	case R_LARCH_GOT_PC_HI20:
833 	case R_LARCH_GOT_HI20:
834 	case R_LARCH_SOP_PUSH_GPREL:
835 	  /* For la.global.  */
836 	  if (h)
837 	    h->pointer_equality_needed = 1;
838 	  if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
839 							   r_symndx,
840 							   GOT_NORMAL))
841 	    return false;
842 	  break;
843 
844 	case R_LARCH_TLS_LD_PC_HI20:
845 	case R_LARCH_TLS_LD_HI20:
846 	case R_LARCH_TLS_GD_PC_HI20:
847 	case R_LARCH_TLS_GD_HI20:
848 	case R_LARCH_SOP_PUSH_TLS_GD:
849 	  if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
850 							   r_symndx,
851 							   GOT_TLS_GD))
852 	    return false;
853 	  break;
854 
855 	case R_LARCH_TLS_IE_PC_HI20:
856 	case R_LARCH_TLS_IE_HI20:
857 	case R_LARCH_SOP_PUSH_TLS_GOT:
858 	  if (bfd_link_pic (info))
859 	    /* May fail for lazy-bind.  */
860 	    info->flags |= DF_STATIC_TLS;
861 
862 	  if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
863 							   r_symndx,
864 							   GOT_TLS_IE))
865 	    return false;
866 	  break;
867 
868 	case R_LARCH_TLS_LE_HI20:
869 	case R_LARCH_TLS_LE_HI20_R:
870 	case R_LARCH_SOP_PUSH_TLS_TPREL:
871 	  if (!bfd_link_executable (info))
872 	    return false;
873 
874 	  info->flags |= DF_STATIC_TLS;
875 
876 	  if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
877 							   r_symndx,
878 							   GOT_TLS_LE))
879 	    return false;
880 	  break;
881 
882 	case R_LARCH_TLS_DESC_PC_HI20:
883 	case R_LARCH_TLS_DESC_HI20:
884 	  if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
885 							   r_symndx,
886 							   GOT_TLS_GDESC))
887 	    return false;
888 	  break;
889 
890 	case R_LARCH_ABS_HI20:
891 	case R_LARCH_SOP_PUSH_ABSOLUTE:
892 	  if (h != NULL)
893 	    /* If this reloc is in a read-only section, we might
894 	       need a copy reloc.  We can't check reliably at this
895 	       stage whether the section is read-only, as input
896 	       sections have not yet been mapped to output sections.
897 	       Tentatively set the flag for now, and correct in
898 	       adjust_dynamic_symbol.  */
899 	    h->non_got_ref = 1;
900 	  break;
901 
902 	/* For normal cmodel, pcalau12i + addi.d/w used to data.
903 	   For first version medium cmodel, pcalau12i + jirl are used to
904 	   function call, it need to creat PLT entry for STT_FUNC and
905 	   STT_GNU_IFUNC type symbol.  */
906 	case R_LARCH_PCALA_HI20:
907 	  if (h != NULL && (STT_FUNC == h->type || STT_GNU_IFUNC == h->type))
908 	    {
909 	      /* For pcalau12i + jirl.  */
910 	      h->needs_plt = 1;
911 	      if (h->plt.refcount < 0)
912 		h->plt.refcount = 0;
913 	      h->plt.refcount++;
914 
915 	      h->non_got_ref = 1;
916 	      h->pointer_equality_needed = 1;
917 	    }
918 
919 	  break;
920 
921 	case R_LARCH_B16:
922 	case R_LARCH_B21:
923 	case R_LARCH_B26:
924 	case R_LARCH_CALL36:
925 	  if (h != NULL)
926 	    {
927 	      h->needs_plt = 1;
928 	      if (!bfd_link_pic (info))
929 		h->non_got_ref = 1;
930 
931 	      /* We try to create PLT stub for all non-local function.  */
932 	      if (h->plt.refcount < 0)
933 		h->plt.refcount = 0;
934 	      h->plt.refcount++;
935 	    }
936 
937 	  break;
938 
939 	case R_LARCH_SOP_PUSH_PCREL:
940 	  if (h != NULL)
941 	    {
942 	      if (!bfd_link_pic (info))
943 		h->non_got_ref = 1;
944 
945 	      /* We try to create PLT stub for all non-local function.  */
946 	      if (h->plt.refcount < 0)
947 		h->plt.refcount = 0;
948 	      h->plt.refcount++;
949 	      h->pointer_equality_needed = 1;
950 	    }
951 
952 	  break;
953 
954 	case R_LARCH_SOP_PUSH_PLT_PCREL:
955 	  /* This symbol requires a procedure linkage table entry.  We
956 	     actually build the entry in adjust_dynamic_symbol,
957 	     because this might be a case of linking PIC code without
958 	     linking in any dynamic objects, in which case we don't
959 	     need to generate a procedure linkage table after all.  */
960 	  if (h != NULL)
961 	    {
962 	      h->needs_plt = 1;
963 	      if (h->plt.refcount < 0)
964 		h->plt.refcount = 0;
965 	      h->plt.refcount++;
966 	    }
967 	  break;
968 
969 	case R_LARCH_TLS_DTPREL32:
970 	case R_LARCH_TLS_DTPREL64:
971 	  need_dynreloc = 1;
972 	  only_need_pcrel = 1;
973 	  break;
974 
975 	case R_LARCH_JUMP_SLOT:
976 	case R_LARCH_32:
977 	case R_LARCH_64:
978 
979 	  need_dynreloc = 1;
980 
981 	  /* If resolved symbol is defined in this object,
982 	     1. Under pie, the symbol is known.  We convert it
983 	     into R_LARCH_RELATIVE and need load-addr still.
984 	     2. Under pde, the symbol is known and we can discard R_LARCH_NN.
985 	     3. Under dll, R_LARCH_NN can't be changed normally, since
986 	     its defination could be covered by the one in executable.
987 	     For symbolic, we convert it into R_LARCH_RELATIVE.
988 	     Thus, only under pde, it needs pcrel only.  We discard it.  */
989 	  only_need_pcrel = bfd_link_pde (info);
990 
991 	  if (h != NULL
992 	      && (!bfd_link_pic (info)
993 		  || h->type == STT_GNU_IFUNC))
994 	    {
995 	      /* This reloc might not bind locally.  */
996 	      h->non_got_ref = 1;
997 	      h->pointer_equality_needed = 1;
998 
999 	      if (!h->def_regular
1000 		  || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
1001 		{
1002 		  /* We may need a .plt entry if the symbol is a function
1003 		     defined in a shared lib or is a function referenced
1004 		     from the code or read-only section.  */
1005 		  h->plt.refcount += 1;
1006 		}
1007 	    }
1008 	  break;
1009 
1010 	case R_LARCH_GNU_VTINHERIT:
1011 	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1012 	    return false;
1013 	  break;
1014 
1015 	case R_LARCH_GNU_VTENTRY:
1016 	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
1017 	    return false;
1018 	  break;
1019 
1020 	default:
1021 	  break;
1022 	}
1023 
1024       /* Record some info for sizing and allocating dynamic entry.  */
1025       if (need_dynreloc && (sec->flags & SEC_ALLOC))
1026 	{
1027 	  /* When creating a shared object, we must copy these
1028 	     relocs into the output file.  We create a reloc
1029 	     section in dynobj and make room for the reloc.  */
1030 	  struct elf_dyn_relocs *p;
1031 	  struct elf_dyn_relocs **head;
1032 
1033 	  if (sreloc == NULL)
1034 	    {
1035 	      sreloc
1036 		= _bfd_elf_make_dynamic_reloc_section (sec, htab->elf.dynobj,
1037 						       LARCH_ELF_LOG_WORD_BYTES,
1038 						       abfd, /*rela?*/ true);
1039 	      if (sreloc == NULL)
1040 		return false;
1041 	    }
1042 
1043 	  /* If this is a global symbol, we count the number of
1044 	     relocations we need for this symbol.  */
1045 	  if (h != NULL)
1046 	    head = &h->dyn_relocs;
1047 	  else
1048 	    {
1049 	      /* Track dynamic relocs needed for local syms too.
1050 		 We really need local syms available to do this
1051 		 easily.  Oh well.  */
1052 
1053 	      asection *s;
1054 	      void *vpp;
1055 
1056 	      s = bfd_section_from_elf_index (abfd, isym->st_shndx);
1057 	      if (s == NULL)
1058 		s = sec;
1059 
1060 	      vpp = &elf_section_data (s)->local_dynrel;
1061 	      head = (struct elf_dyn_relocs **) vpp;
1062 	    }
1063 
1064 	  p = *head;
1065 	  if (p == NULL || p->sec != sec)
1066 	    {
1067 	      bfd_size_type amt = sizeof *p;
1068 	      p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj, amt);
1069 	      if (p == NULL)
1070 		return false;
1071 	      p->next = *head;
1072 	      *head = p;
1073 	      p->sec = sec;
1074 	      p->count = 0;
1075 	      p->pc_count = 0;
1076 	    }
1077 
1078 	  p->count++;
1079 	  p->pc_count += only_need_pcrel;
1080 	}
1081     }
1082 
1083   return true;
1084 }
1085 
1086 /* Find dynamic relocs for H that apply to read-only sections.  */
1087 
1088 static asection *
readonly_dynrelocs(struct elf_link_hash_entry * h)1089 readonly_dynrelocs (struct elf_link_hash_entry *h)
1090 {
1091   struct elf_dyn_relocs *p;
1092 
1093   for (p = h->dyn_relocs; p != NULL; p = p->next)
1094     {
1095       asection *s = p->sec->output_section;
1096 
1097       if (s != NULL && (s->flags & SEC_READONLY) != 0)
1098 	return p->sec;
1099     }
1100   return NULL;
1101 }
1102 
1103 /* Adjust a symbol defined by a dynamic object and referenced by a
1104    regular object.  The current definition is in some section of the
1105    dynamic object, but we're not including those sections.  We have to
1106    change the definition to something the rest of the link can
1107    understand.  */
1108 static bool
loongarch_elf_adjust_dynamic_symbol(struct bfd_link_info * info,struct elf_link_hash_entry * h)1109 loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
1110 				     struct elf_link_hash_entry *h)
1111 {
1112   struct loongarch_elf_link_hash_table *htab;
1113   bfd *dynobj;
1114 
1115   htab = loongarch_elf_hash_table (info);
1116   BFD_ASSERT (htab != NULL);
1117 
1118   dynobj = htab->elf.dynobj;
1119 
1120   /* Make sure we know what is going on here.  */
1121   BFD_ASSERT (dynobj != NULL
1122 	      && (h->needs_plt
1123 		  || h->type == STT_GNU_IFUNC
1124 		  || h->is_weakalias
1125 		  || (h->def_dynamic
1126 		      && h->ref_regular
1127 		      && !h->def_regular)));
1128 
1129   /* If this is a function, put it in the procedure linkage table.  We
1130      will fill in the contents of the procedure linkage table later
1131      (although we could actually do it here).  */
1132   if (h->type == STT_FUNC || h->type == STT_GNU_IFUNC || h->needs_plt)
1133     {
1134       if (h->plt.refcount <= 0
1135 	  || (h->type != STT_GNU_IFUNC
1136 	      && (SYMBOL_REFERENCES_LOCAL (info, h)
1137 		  || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1138 		      && h->root.type == bfd_link_hash_undefweak))))
1139 	{
1140 	  /* This case can occur if we saw a R_LARCH_SOP_PUSH_PLT_PCREL reloc
1141 	     in an input file, but the symbol was never referred to by a
1142 	     dynamic object, or if all references were garbage collected.
1143 	     In such a case, we don't actually need to build a PLT entry.  */
1144 	  h->plt.offset = MINUS_ONE;
1145 	  h->needs_plt = 0;
1146 	}
1147 
1148       return true;
1149     }
1150   else
1151     h->plt.offset = MINUS_ONE;
1152 
1153   /* If this is a weak symbol, and there is a real definition, the
1154      processor independent code will have arranged for us to see the
1155      real definition first, and we can just use the same value.  */
1156   if (h->is_weakalias)
1157     {
1158       struct elf_link_hash_entry *def = weakdef (h);
1159       BFD_ASSERT (def->root.type == bfd_link_hash_defined);
1160       h->root.u.def.section = def->root.u.def.section;
1161       h->root.u.def.value = def->root.u.def.value;
1162       return true;
1163     }
1164 
1165   /* R_LARCH_COPY is not adept glibc, not to generate.  */
1166   /* Can not print anything, because make check ld.  */
1167   return true;
1168 }
1169 
1170 /* Allocate space in .plt, .got and associated reloc sections for
1171    dynamic relocs.  */
1172 
1173 static bool
allocate_dynrelocs(struct elf_link_hash_entry * h,void * inf)1174 allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
1175 {
1176   struct bfd_link_info *info;
1177   struct loongarch_elf_link_hash_table *htab;
1178   struct elf_dyn_relocs *p;
1179 
1180   if (h->root.type == bfd_link_hash_indirect)
1181     return true;
1182 
1183   if (h->type == STT_GNU_IFUNC
1184       && h->def_regular)
1185     return true;
1186 
1187   info = (struct bfd_link_info *) inf;
1188   htab = loongarch_elf_hash_table (info);
1189   bool dyn = htab->elf.dynamic_sections_created;
1190   BFD_ASSERT (htab != NULL);
1191 
1192   do
1193     {
1194       asection *plt, *gotplt, *relplt;
1195 
1196       if (!h->needs_plt)
1197 	break;
1198 
1199       h->needs_plt = 0;
1200 
1201       if (htab->elf.splt)
1202 	{
1203 	  if (h->dynindx == -1 && !h->forced_local && dyn
1204 	      && h->root.type == bfd_link_hash_undefweak)
1205 	    {
1206 	      if (!bfd_elf_link_record_dynamic_symbol (info, h))
1207 		return false;
1208 	    }
1209 
1210 	  if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h)
1211 	      && h->type != STT_GNU_IFUNC)
1212 	    break;
1213 
1214 	  plt = htab->elf.splt;
1215 	  gotplt = htab->elf.sgotplt;
1216 	  relplt = htab->elf.srelplt;
1217 	}
1218       else if (htab->elf.iplt)
1219 	{
1220 	  /* .iplt only for IFUNC.  */
1221 	  if (h->type != STT_GNU_IFUNC)
1222 	    break;
1223 
1224 	  plt = htab->elf.iplt;
1225 	  gotplt = htab->elf.igotplt;
1226 	  relplt = htab->elf.irelplt;
1227 	}
1228       else
1229 	break;
1230 
1231       if (plt->size == 0)
1232 	plt->size = PLT_HEADER_SIZE;
1233 
1234       h->plt.offset = plt->size;
1235       plt->size += PLT_ENTRY_SIZE;
1236       gotplt->size += GOT_ENTRY_SIZE;
1237       relplt->size += sizeof (ElfNN_External_Rela);
1238 
1239       /* If this symbol is not defined in a regular file, and we are
1240 	 not generating a shared library, then set the symbol to this
1241 	 location in the .plt.  This is required to make function
1242 	 pointers compare as equal between the normal executable and
1243 	 the shared library.  */
1244       if (!bfd_link_pic (info)
1245 	  && !h->def_regular)
1246 	{
1247 	  h->root.u.def.section = plt;
1248 	  h->root.u.def.value = h->plt.offset;
1249 	}
1250 
1251       h->needs_plt = 1;
1252     }
1253   while (0);
1254 
1255   if (!h->needs_plt)
1256     h->plt.offset = MINUS_ONE;
1257 
1258   if (0 < h->got.refcount)
1259     {
1260       asection *s;
1261       int tls_type = loongarch_elf_hash_entry (h)->tls_type;
1262 
1263       /* Make sure this symbol is output as a dynamic symbol.
1264 	 Undefined weak syms won't yet be marked as dynamic.  */
1265       if (h->dynindx == -1 && !h->forced_local && dyn
1266 	  && h->root.type == bfd_link_hash_undefweak)
1267 	{
1268 	  if (!bfd_elf_link_record_dynamic_symbol (info, h))
1269 	    return false;
1270 	}
1271 
1272       s = htab->elf.sgot;
1273       h->got.offset = s->size;
1274       if (tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
1275 	{
1276 	  /* TLS_GD needs two dynamic relocs and two GOT slots.  */
1277 	  if (tls_type & GOT_TLS_GD)
1278 	    {
1279 	      s->size += 2 * GOT_ENTRY_SIZE;
1280 	      if (bfd_link_executable (info))
1281 		{
1282 		  /* Link exe and not defined local.  */
1283 		  if (!SYMBOL_REFERENCES_LOCAL (info, h))
1284 		    htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
1285 		}
1286 	      else
1287 		{
1288 		  if (SYMBOL_REFERENCES_LOCAL (info, h))
1289 		    htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1290 		  else
1291 		    htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
1292 		}
1293 	    }
1294 
1295 	  /* TLS_IE needs one dynamic reloc and one GOT slot.  */
1296 	  if (tls_type & GOT_TLS_IE)
1297 	    {
1298 	      s->size += GOT_ENTRY_SIZE;
1299 
1300 	      if (bfd_link_executable (info))
1301 		{
1302 		  /* Link exe and not defined local.  */
1303 		  if (!SYMBOL_REFERENCES_LOCAL (info, h))
1304 		    htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1305 		}
1306 	      else
1307 		{
1308 		  htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1309 		}
1310 	    }
1311 
1312 	  /* TLS_DESC needs one dynamic reloc and two GOT slot.  */
1313 	  if (tls_type & GOT_TLS_GDESC)
1314 	    {
1315 	      s->size += GOT_ENTRY_SIZE * 2;
1316 	      htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1317 	    }
1318 	}
1319 
1320       else
1321 	{
1322 	  s->size += GOT_ENTRY_SIZE;
1323 	  if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1324 	       || h->root.type != bfd_link_hash_undefweak)
1325 	      && (bfd_link_pic (info)
1326 		  || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info),
1327 						      h))
1328 	      && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
1329 	      /* Undefined weak symbol in static PIE resolves to 0 without
1330 		 any dynamic relocations.  */
1331 	    htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1332 	}
1333     }
1334   else
1335     h->got.offset = MINUS_ONE;
1336 
1337   if (h->dyn_relocs == NULL)
1338     return true;
1339 
1340   /* Extra dynamic relocate,
1341    * R_LARCH_64
1342    * R_LARCH_TLS_DTPRELNN
1343    * R_LARCH_JUMP_SLOT
1344    * R_LARCH_NN.  */
1345 
1346   if (SYMBOL_CALLS_LOCAL (info, h))
1347     {
1348       struct elf_dyn_relocs **pp;
1349 
1350       for (pp = &h->dyn_relocs; (p = *pp) != NULL;)
1351 	{
1352 	  p->count -= p->pc_count;
1353 	  p->pc_count = 0;
1354 	  if (p->count == 0)
1355 	    *pp = p->next;
1356 	  else
1357 	    pp = &p->next;
1358 	}
1359     }
1360 
1361   if (h->root.type == bfd_link_hash_undefweak)
1362     {
1363       if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)
1364 	  || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1365 	  || (!bfd_link_pic (info) && h->non_got_ref))
1366 	h->dyn_relocs = NULL;
1367       else if (h->dynindx == -1 && !h->forced_local)
1368 	{
1369 	  /* Make sure this symbol is output as a dynamic symbol.
1370 	     Undefined weak syms won't yet be marked as dynamic.  */
1371 	  if (!bfd_elf_link_record_dynamic_symbol (info, h))
1372 	    return false;
1373 
1374 	  if (h->dynindx == -1)
1375 	    h->dyn_relocs = NULL;
1376 	}
1377     }
1378 
1379   for (p = h->dyn_relocs; p != NULL; p = p->next)
1380     {
1381       asection *sreloc = elf_section_data (p->sec)->sreloc;
1382       sreloc->size += p->count * sizeof (ElfNN_External_Rela);
1383     }
1384 
1385   return true;
1386 }
1387 
1388 /* A modified version of _bfd_elf_allocate_ifunc_dyn_relocs.
1389    For local def and ref ifunc,
1390    dynamic relocations are stored in
1391    1.  rela.srelgot section in dynamic object (dll or exec).
1392    2.  rela.irelplt section in static executable.
1393    Unlike _bfd_elf_allocate_ifunc_dyn_relocs, rela.srelgot is used
1394    instead of rela.srelplt.  Glibc ELF loader will not support
1395    R_LARCH_IRELATIVE relocation in rela.plt.  */
1396 
1397 static bool
local_allocate_ifunc_dyn_relocs(struct bfd_link_info * info,struct elf_link_hash_entry * h,struct elf_dyn_relocs ** head,unsigned int plt_entry_size,unsigned int plt_header_size,unsigned int got_entry_size,bool avoid_plt)1398 local_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
1399 				    struct elf_link_hash_entry *h,
1400 				    struct elf_dyn_relocs **head,
1401 				    unsigned int plt_entry_size,
1402 				    unsigned int plt_header_size,
1403 				    unsigned int got_entry_size,
1404 				    bool avoid_plt)
1405 {
1406   asection *plt, *gotplt, *relplt;
1407   struct elf_dyn_relocs *p;
1408   unsigned int sizeof_reloc;
1409   const struct elf_backend_data *bed;
1410   struct elf_link_hash_table *htab;
1411   /* If AVOID_PLT is TRUE, don't use PLT if possible.  */
1412   bool use_plt = !avoid_plt || h->plt.refcount > 0;
1413   bool need_dynreloc = !use_plt || bfd_link_pic (info);
1414 
1415   /* When a PIC object references a STT_GNU_IFUNC symbol defined
1416      in executable or it isn't referenced via PLT, the address of
1417      the resolved function may be used.  But in non-PIC executable,
1418      the address of its plt slot may be used.  Pointer equality may
1419      not work correctly.  PIE or non-PLT reference should be used if
1420      pointer equality is required here.
1421 
1422      If STT_GNU_IFUNC symbol is defined in position-dependent executable,
1423      backend should change it to the normal function and set its address
1424      to its PLT entry which should be resolved by R_*_IRELATIVE at
1425      run-time.  All external references should be resolved to its PLT in
1426      executable.  */
1427   if (!need_dynreloc
1428       && !(bfd_link_pde (info) && h->def_regular)
1429       && (h->dynindx != -1
1430 	  || info->export_dynamic)
1431       && h->pointer_equality_needed)
1432     {
1433       info->callbacks->einfo
1434 	/* xgettext:c-format.  */
1435 	(_("%F%P: dynamic STT_GNU_IFUNC symbol `%s' with pointer "
1436 	   "equality in `%pB' can not be used when making an "
1437 	   "executable; recompile with -fPIE and relink with -pie\n"),
1438 	 h->root.root.string,
1439 	 h->root.u.def.section->owner);
1440       bfd_set_error (bfd_error_bad_value);
1441       return false;
1442     }
1443 
1444   htab = elf_hash_table (info);
1445 
1446   /* When the symbol is marked with regular reference, if PLT isn't used
1447      or we are building a PIC object, we must keep dynamic relocation
1448      if there is non-GOT reference and use PLT if there is PC-relative
1449      reference.  */
1450   if (need_dynreloc && h->ref_regular)
1451     {
1452       bool keep = false;
1453       for (p = *head; p != NULL; p = p->next)
1454 	if (p->count)
1455 	  {
1456 	    h->non_got_ref = 1;
1457 	    /* Need dynamic relocations for non-GOT reference.  */
1458 	    keep = true;
1459 	    if (p->pc_count)
1460 	      {
1461 		/* Must use PLT for PC-relative reference.  */
1462 		use_plt = true;
1463 		need_dynreloc = bfd_link_pic (info);
1464 		break;
1465 	      }
1466 	  }
1467       if (keep)
1468 	goto keep;
1469     }
1470 
1471   /* Support garbage collection against STT_GNU_IFUNC symbols.  */
1472   if (h->plt.refcount <= 0 && h->got.refcount <= 0)
1473     {
1474       h->got = htab->init_got_offset;
1475       h->plt = htab->init_plt_offset;
1476       *head = NULL;
1477       return true;
1478     }
1479 
1480   /* Return and discard space for dynamic relocations against it if
1481      it is never referenced.  */
1482   if (!h->ref_regular)
1483     {
1484       if (h->plt.refcount > 0
1485 	  || h->got.refcount > 0)
1486 	abort ();
1487       h->got = htab->init_got_offset;
1488       h->plt = htab->init_plt_offset;
1489       *head = NULL;
1490       return true;
1491     }
1492 
1493  keep:
1494   bed = get_elf_backend_data (info->output_bfd);
1495   if (bed->rela_plts_and_copies_p)
1496     sizeof_reloc = bed->s->sizeof_rela;
1497   else
1498     sizeof_reloc = bed->s->sizeof_rel;
1499 
1500   /* When building a static executable, use iplt, igot.plt and
1501      rela.iplt sections for STT_GNU_IFUNC symbols.  */
1502   if (htab->splt != NULL)
1503     {
1504       plt = htab->splt;
1505       gotplt = htab->sgotplt;
1506       /* Change dynamic info of ifunc gotplt from srelplt to srelgot.  */
1507       relplt = htab->srelgot;
1508 
1509       /* If this is the first plt entry and PLT is used, make room for
1510 	 the special first entry.  */
1511       if (plt->size == 0 && use_plt)
1512 	plt->size += plt_header_size;
1513     }
1514   else
1515     {
1516       plt = htab->iplt;
1517       gotplt = htab->igotplt;
1518       relplt = htab->irelplt;
1519     }
1520 
1521   if (use_plt)
1522     {
1523       /* Don't update value of STT_GNU_IFUNC symbol to PLT.  We need
1524 	 the original value for R_*_IRELATIVE.  */
1525       h->plt.offset = plt->size;
1526 
1527       /* Make room for this entry in the plt/iplt section.  */
1528       plt->size += plt_entry_size;
1529 
1530       /* We also need to make an entry in the got.plt/got.iplt section,
1531 	 which will be placed in the got section by the linker script.  */
1532       gotplt->size += got_entry_size;
1533     }
1534 
1535   /* We also need to make an entry in the rela.plt/.rela.iplt
1536      section for GOTPLT relocation if PLT is used.  */
1537   if (use_plt)
1538     {
1539       relplt->size += sizeof_reloc;
1540       relplt->reloc_count++;
1541     }
1542 
1543   /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
1544      there is a non-GOT reference in a PIC object or PLT isn't used.  */
1545   if (!need_dynreloc || !h->non_got_ref)
1546     *head = NULL;
1547 
1548   /* Finally, allocate space.  */
1549   p = *head;
1550   if (p != NULL)
1551     {
1552       bfd_size_type count = 0;
1553       do
1554 	{
1555 	  count += p->count;
1556 	  p = p->next;
1557 	}
1558       while (p != NULL);
1559 
1560       htab->ifunc_resolvers = count != 0;
1561 
1562       /* Dynamic relocations are stored in
1563 	 1.  rela.srelgot section in PIC object.
1564 	 2.  rela.srelgot section in dynamic executable.
1565 	 3.  rela.irelplt section in static executable.  */
1566       if (htab->splt != NULL)
1567 	htab->srelgot->size += count * sizeof_reloc;
1568       else
1569 	{
1570 	  relplt->size += count * sizeof_reloc;
1571 	  relplt->reloc_count += count;
1572 	}
1573     }
1574 
1575   /* For STT_GNU_IFUNC symbol, got.plt has the real function address
1576      and got has the PLT entry adddress.  We will load the GOT entry
1577      with the PLT entry in finish_dynamic_symbol if it is used.  For
1578      branch, it uses got.plt.  For symbol value, if PLT is used,
1579      1.  Use got.plt in a PIC object if it is forced local or not
1580      dynamic.
1581      2.  Use got.plt in a non-PIC object if pointer equality isn't
1582      needed.
1583      3.  Use got.plt in PIE.
1584      4.  Use got.plt if got isn't used.
1585      5.  Otherwise use got so that it can be shared among different
1586      objects at run-time.
1587      If PLT isn't used, always use got for symbol value.
1588      We only need to relocate got entry in PIC object or in dynamic
1589      executable without PLT.  */
1590   if (use_plt
1591       && (h->got.refcount <= 0
1592 	  || (bfd_link_pic (info)
1593 	      && (h->dynindx == -1
1594 		  || h->forced_local))
1595 	  || (
1596 	      !h->pointer_equality_needed)
1597 	  || htab->sgot == NULL))
1598     {
1599       /* Use got.plt.  */
1600       h->got.offset = (bfd_vma) -1;
1601     }
1602   else
1603     {
1604       if (!use_plt)
1605 	{
1606 	  /* PLT isn't used.  */
1607 	  h->plt.offset = (bfd_vma) -1;
1608 	}
1609       if (h->got.refcount <= 0)
1610 	{
1611 	  /* GOT isn't need when there are only relocations for static
1612 	     pointers.  */
1613 	  h->got.offset = (bfd_vma) -1;
1614 	}
1615       else
1616 	{
1617 	  h->got.offset = htab->sgot->size;
1618 	  htab->sgot->size += got_entry_size;
1619 	  /* Need to relocate the GOT entry in a PIC object or PLT isn't
1620 	     used.  Otherwise, the GOT entry will be filled with the PLT
1621 	     entry and dynamic GOT relocation isn't needed.  */
1622 	  if (need_dynreloc)
1623 	    {
1624 	      /* For non-static executable, dynamic GOT relocation is in
1625 		 rela.got section, but for static executable, it is
1626 		 in rela.iplt section.  */
1627 	      if (htab->splt != NULL)
1628 		htab->srelgot->size += sizeof_reloc;
1629 	      else
1630 		{
1631 		  relplt->size += sizeof_reloc;
1632 		  relplt->reloc_count++;
1633 		}
1634 	    }
1635 	}
1636     }
1637 
1638   return true;
1639 }
1640 
1641 /* Allocate space in .plt, .got and associated reloc sections for
1642    ifunc dynamic relocs.  */
1643 
1644 static bool
elfNN_allocate_ifunc_dynrelocs(struct elf_link_hash_entry * h,void * inf)1645 elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf)
1646 {
1647   struct bfd_link_info *info;
1648   /* An example of a bfd_link_hash_indirect symbol is versioned
1649      symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
1650      -> __gxx_personality_v0(bfd_link_hash_defined)
1651 
1652      There is no need to process bfd_link_hash_indirect symbols here
1653      because we will also be presented with the concrete instance of
1654      the symbol and loongarch_elf_copy_indirect_symbol () will have been
1655      called to copy all relevant data from the generic to the concrete
1656      symbol instance.  */
1657   if (h->root.type == bfd_link_hash_indirect)
1658     return true;
1659 
1660   if (h->root.type == bfd_link_hash_warning)
1661     h = (struct elf_link_hash_entry *) h->root.u.i.link;
1662 
1663   info = (struct bfd_link_info *) inf;
1664 
1665   /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
1666      here if it is defined and referenced in a non-shared object.  */
1667   if (h->type == STT_GNU_IFUNC && h->def_regular)
1668     {
1669       if (SYMBOL_REFERENCES_LOCAL (info, h))
1670 	return local_allocate_ifunc_dyn_relocs (info, h,
1671 						&h->dyn_relocs,
1672 						PLT_ENTRY_SIZE,
1673 						PLT_HEADER_SIZE,
1674 						GOT_ENTRY_SIZE,
1675 						false);
1676       else
1677 	return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
1678 						   &h->dyn_relocs,
1679 						   PLT_ENTRY_SIZE,
1680 						   PLT_HEADER_SIZE,
1681 						   GOT_ENTRY_SIZE,
1682 						   false);
1683     }
1684 
1685   return true;
1686 }
1687 
1688 /* Allocate space in .plt, .got and associated reloc sections for
1689    ifunc dynamic relocs.  */
1690 
1691 static int
elfNN_allocate_local_ifunc_dynrelocs(void ** slot,void * inf)1692 elfNN_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
1693 {
1694   struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
1695 
1696   if (h->type != STT_GNU_IFUNC
1697       || !h->def_regular
1698       || !h->ref_regular
1699       || !h->forced_local
1700       || h->root.type != bfd_link_hash_defined)
1701     abort ();
1702 
1703   return elfNN_allocate_ifunc_dynrelocs (h, inf);
1704 }
1705 
1706 /* Set DF_TEXTREL if we find any dynamic relocs that apply to
1707    read-only sections.  */
1708 
1709 static bool
maybe_set_textrel(struct elf_link_hash_entry * h,void * info_p)1710 maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
1711 {
1712   asection *sec;
1713 
1714   if (h->root.type == bfd_link_hash_indirect)
1715     return true;
1716 
1717   sec = readonly_dynrelocs (h);
1718   if (sec != NULL)
1719     {
1720       struct bfd_link_info *info = (struct bfd_link_info *) info_p;
1721 
1722       info->flags |= DF_TEXTREL;
1723       info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' in "
1724 				"read-only section `%pA'\n"),
1725 			      sec->owner, h->root.root.string, sec);
1726 
1727       /* Not an error, just cut short the traversal.  */
1728       return false;
1729     }
1730   return true;
1731 }
1732 
1733 static bool
loongarch_elf_size_dynamic_sections(bfd * output_bfd,struct bfd_link_info * info)1734 loongarch_elf_size_dynamic_sections (bfd *output_bfd,
1735 				     struct bfd_link_info *info)
1736 {
1737   struct loongarch_elf_link_hash_table *htab;
1738   bfd *dynobj;
1739   asection *s;
1740   bfd *ibfd;
1741 
1742   htab = loongarch_elf_hash_table (info);
1743   BFD_ASSERT (htab != NULL);
1744   dynobj = htab->elf.dynobj;
1745   BFD_ASSERT (dynobj != NULL);
1746 
1747   if (htab->elf.dynamic_sections_created)
1748     {
1749       /* Set the contents of the .interp section to the interpreter.  */
1750       if (bfd_link_executable (info) && !info->nointerp)
1751 	{
1752 	  const char *interpreter;
1753 	  s = bfd_get_linker_section (dynobj, ".interp");
1754 	  BFD_ASSERT (s != NULL);
1755 
1756 	  if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS32)
1757 	    interpreter = "/lib32/ld.so.1";
1758 	  else if (elf_elfheader (output_bfd)->e_ident[EI_CLASS] == ELFCLASS64)
1759 	    interpreter = "/lib64/ld.so.1";
1760 	  else
1761 	    interpreter = "/lib/ld.so.1";
1762 
1763 	  s->contents = (unsigned char *) interpreter;
1764 	  s->size = strlen (interpreter) + 1;
1765 	}
1766     }
1767 
1768   /* Set up .got offsets for local syms, and space for local dynamic
1769      relocs.  */
1770   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
1771     {
1772       bfd_signed_vma *local_got;
1773       bfd_signed_vma *end_local_got;
1774       char *local_tls_type;
1775       bfd_size_type locsymcount;
1776       Elf_Internal_Shdr *symtab_hdr;
1777       asection *srel;
1778 
1779       if (!is_loongarch_elf (ibfd))
1780 	continue;
1781 
1782       for (s = ibfd->sections; s != NULL; s = s->next)
1783 	{
1784 	  struct elf_dyn_relocs *p;
1785 
1786 	  for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
1787 	    {
1788 	      p->count -= p->pc_count;
1789 	      if (!bfd_is_abs_section (p->sec)
1790 		  && bfd_is_abs_section (p->sec->output_section))
1791 		{
1792 		  /* Input section has been discarded, either because
1793 		     it is a copy of a linkonce section or due to
1794 		     linker script /DISCARD/, so we'll be discarding
1795 		     the relocs too.  */
1796 		}
1797 	      else if (0 < p->count)
1798 		{
1799 		  srel = elf_section_data (p->sec)->sreloc;
1800 		  srel->size += p->count * sizeof (ElfNN_External_Rela);
1801 		  if ((p->sec->output_section->flags & SEC_READONLY) != 0)
1802 		    info->flags |= DF_TEXTREL;
1803 		}
1804 	    }
1805 	}
1806 
1807       local_got = elf_local_got_refcounts (ibfd);
1808       if (!local_got)
1809 	continue;
1810 
1811       symtab_hdr = &elf_symtab_hdr (ibfd);
1812       locsymcount = symtab_hdr->sh_info;
1813       end_local_got = local_got + locsymcount;
1814       local_tls_type = _bfd_loongarch_elf_local_got_tls_type (ibfd);
1815       s = htab->elf.sgot;
1816       srel = htab->elf.srelgot;
1817       for (; local_got < end_local_got; ++local_got, ++local_tls_type)
1818 	{
1819 	  if (0 < *local_got)
1820 	    {
1821 	      *local_got = s->size;
1822 	      if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
1823 		{
1824 		  /* TLS gd use two got.  */
1825 		  if (*local_tls_type & GOT_TLS_GD)
1826 		    {
1827 		      s->size += 2 * GOT_ENTRY_SIZE;
1828 		      if (!bfd_link_executable (info))
1829 			srel->size += sizeof (ElfNN_External_Rela);
1830 		    }
1831 
1832 		  /* TLS_DESC use two got.  */
1833 		  if (*local_tls_type & GOT_TLS_GDESC)
1834 		    {
1835 		      s->size += 2 * GOT_ENTRY_SIZE;
1836 		      srel->size += sizeof (ElfNN_External_Rela);
1837 		    }
1838 
1839 		  /* TLS ie and use one got.  */
1840 		  if (*local_tls_type & GOT_TLS_IE)
1841 		    {
1842 		      s->size += GOT_ENTRY_SIZE;
1843 		      if (!bfd_link_executable (info))
1844 			srel->size += sizeof (ElfNN_External_Rela);
1845 		    }
1846 		}
1847 	      else
1848 		{
1849 		  s->size += GOT_ENTRY_SIZE;
1850 		  srel->size += sizeof (ElfNN_External_Rela);
1851 		}
1852 	    }
1853 	  else
1854 	    *local_got = MINUS_ONE;
1855 	}
1856     }
1857 
1858   /* Allocate global sym .plt and .got entries, and space for global
1859      sym dynamic relocs.  */
1860   elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
1861 
1862   /* Allocate global ifunc sym .plt and .got entries, and space for global
1863      ifunc sym dynamic relocs.  */
1864   elf_link_hash_traverse (&htab->elf, elfNN_allocate_ifunc_dynrelocs, info);
1865 
1866   /* Allocate .plt and .got entries, and space for local ifunc symbols.  */
1867   htab_traverse (htab->loc_hash_table,
1868 		 elfNN_allocate_local_ifunc_dynrelocs, info);
1869 
1870   /* Don't allocate .got.plt section if there are no PLT.  */
1871   if (htab->elf.sgotplt && htab->elf.sgotplt->size == GOTPLT_HEADER_SIZE
1872       && (htab->elf.splt == NULL || htab->elf.splt->size == 0))
1873     htab->elf.sgotplt->size = 0;
1874 
1875   /* The check_relocs and adjust_dynamic_symbol entry points have
1876      determined the sizes of the various dynamic sections.  Allocate
1877      memory for them.  */
1878   for (s = dynobj->sections; s != NULL; s = s->next)
1879     {
1880       if ((s->flags & SEC_LINKER_CREATED) == 0)
1881 	continue;
1882 
1883       if (s == htab->elf.splt || s == htab->elf.iplt || s == htab->elf.sgot
1884 	  || s == htab->elf.sgotplt || s == htab->elf.igotplt
1885 	  || s == htab->elf.sdynbss || s == htab->elf.sdynrelro)
1886 	{
1887 	  /* Strip this section if we don't need it; see the
1888 	     comment below.  */
1889 	}
1890       else if (strncmp (s->name, ".rela", 5) == 0)
1891 	{
1892 	  if (s->size != 0)
1893 	    {
1894 	      /* We use the reloc_count field as a counter if we need
1895 		 to copy relocs into the output file.  */
1896 	      s->reloc_count = 0;
1897 	    }
1898 	}
1899       else
1900 	{
1901 	  /* It's not one of our sections.  */
1902 	  continue;
1903 	}
1904 
1905       if (s->size == 0)
1906 	{
1907 	  /* If we don't need this section, strip it from the
1908 	     output file.  This is mostly to handle .rela.bss and
1909 	     .rela.plt.  We must create both sections in
1910 	     create_dynamic_sections, because they must be created
1911 	     before the linker maps input sections to output
1912 	     sections.  The linker does that before
1913 	     adjust_dynamic_symbol is called, and it is that
1914 	     function which decides whether anything needs to go
1915 	     into these sections.  */
1916 	  s->flags |= SEC_EXCLUDE;
1917 	  continue;
1918 	}
1919 
1920       if ((s->flags & SEC_HAS_CONTENTS) == 0)
1921 	continue;
1922 
1923       /* Allocate memory for the section contents.  Zero the memory
1924 	 for the benefit of .rela.plt, which has 4 unused entries
1925 	 at the beginning, and we don't want garbage.  */
1926       s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
1927       if (s->contents == NULL)
1928 	return false;
1929     }
1930 
1931   if (elf_hash_table (info)->dynamic_sections_created)
1932     {
1933       /* Add some entries to the .dynamic section.  We fill in the
1934 	 values later, in loongarch_elf_finish_dynamic_sections, but we
1935 	 must add the entries now so that we get the correct size for
1936 	 the .dynamic section.  The DT_DEBUG entry is filled in by the
1937 	 dynamic linker and used by the debugger.  */
1938 #define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL)
1939 
1940       if (bfd_link_executable (info))
1941 	{
1942 	  if (!add_dynamic_entry (DT_DEBUG, 0))
1943 	    return false;
1944 	}
1945 
1946       if (htab->elf.srelplt->size != 0)
1947 	{
1948 	  if (!add_dynamic_entry (DT_PLTGOT, 0)
1949 	      || !add_dynamic_entry (DT_PLTRELSZ, 0)
1950 	      || !add_dynamic_entry (DT_PLTREL, DT_RELA)
1951 	      || !add_dynamic_entry (DT_JMPREL, 0))
1952 	    return false;
1953 	}
1954 
1955       if (!add_dynamic_entry (DT_RELA, 0)
1956 	  || !add_dynamic_entry (DT_RELASZ, 0)
1957 	  || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
1958 	return false;
1959 
1960       /* If any dynamic relocs apply to a read-only section,
1961 	 then we need a DT_TEXTREL entry.  */
1962       if ((info->flags & DF_TEXTREL) == 0)
1963 	elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
1964 
1965       if (info->flags & DF_TEXTREL)
1966 	{
1967 	  if (!add_dynamic_entry (DT_TEXTREL, 0))
1968 	    return false;
1969 	  /* Clear the DF_TEXTREL flag.  It will be set again if we
1970 	     write out an actual text relocation; we may not, because
1971 	     at this point we do not know whether e.g.  any .eh_frame
1972 	     absolute relocations have been converted to PC-relative.  */
1973 	  info->flags &= ~DF_TEXTREL;
1974 	}
1975     }
1976 #undef add_dynamic_entry
1977 
1978   return true;
1979 }
1980 
1981 #define LARCH_LD_STACK_DEPTH 16
1982 static int64_t larch_opc_stack[LARCH_LD_STACK_DEPTH];
1983 static size_t larch_stack_top = 0;
1984 
1985 static bfd_reloc_status_type
loongarch_push(int64_t val)1986 loongarch_push (int64_t val)
1987 {
1988   if (LARCH_LD_STACK_DEPTH <= larch_stack_top)
1989     return bfd_reloc_outofrange;
1990   larch_opc_stack[larch_stack_top++] = val;
1991   return bfd_reloc_ok;
1992 }
1993 
1994 static bfd_reloc_status_type
loongarch_pop(int64_t * val)1995 loongarch_pop (int64_t *val)
1996 {
1997   if (larch_stack_top == 0)
1998     return bfd_reloc_outofrange;
1999   BFD_ASSERT (val);
2000   *val = larch_opc_stack[--larch_stack_top];
2001   return bfd_reloc_ok;
2002 }
2003 
2004 static bfd_reloc_status_type
loongarch_top(int64_t * val)2005 loongarch_top (int64_t *val)
2006 {
2007   if (larch_stack_top == 0)
2008     return bfd_reloc_outofrange;
2009   BFD_ASSERT (val);
2010   *val = larch_opc_stack[larch_stack_top - 1];
2011   return bfd_reloc_ok;
2012 }
2013 
2014 static void
loongarch_elf_append_rela(bfd * abfd,asection * s,Elf_Internal_Rela * rel)2015 loongarch_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
2016 {
2017   BFD_ASSERT (s && s->contents);
2018   const struct elf_backend_data *bed;
2019   bfd_byte *loc;
2020 
2021   bed = get_elf_backend_data (abfd);
2022   if (!(s->size > s->reloc_count * bed->s->sizeof_rela))
2023     BFD_ASSERT (s->size > s->reloc_count * bed->s->sizeof_rela);
2024   loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela);
2025   bed->s->swap_reloca_out (abfd, rel, loc);
2026 }
2027 
2028 /* Check rel->r_offset in range of contents.  */
2029 static bfd_reloc_status_type
loongarch_check_offset(const Elf_Internal_Rela * rel,const asection * input_section)2030 loongarch_check_offset (const Elf_Internal_Rela *rel,
2031 			const asection *input_section)
2032 {
2033   if (0 == strcmp(input_section->name, ".text")
2034       && rel->r_offset > input_section->size)
2035     return bfd_reloc_overflow;
2036 
2037   return bfd_reloc_ok;
2038 }
2039 
2040 #define LARCH_RELOC_PERFORM_3OP(op1, op2, op3)	      \
2041   ({						      \
2042     bfd_reloc_status_type ret = loongarch_pop (&op2); \
2043     if (ret == bfd_reloc_ok)			      \
2044       {						      \
2045 	ret = loongarch_pop (&op1);		      \
2046 	if (ret == bfd_reloc_ok)		      \
2047 	  ret = loongarch_push (op3);		      \
2048       }						      \
2049     ret;					      \
2050    })
2051 
2052 /* Write immediate to instructions.  */
2053 
2054 static bfd_reloc_status_type
loongarch_reloc_rewrite_imm_insn(const Elf_Internal_Rela * rel,const asection * input_section ATTRIBUTE_UNUSED,reloc_howto_type * howto,bfd * input_bfd,bfd_byte * contents,bfd_vma reloc_val)2055 loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela *rel,
2056 				  const asection *input_section ATTRIBUTE_UNUSED,
2057 				  reloc_howto_type *howto, bfd *input_bfd,
2058 				  bfd_byte *contents, bfd_vma reloc_val)
2059 {
2060   /* Adjust the immediate based on alignment and
2061      its position in the instruction.  */
2062   if (!loongarch_adjust_reloc_bitsfield (input_bfd, howto, &reloc_val))
2063     return bfd_reloc_overflow;
2064 
2065   int bits = bfd_get_reloc_size (howto) * 8;
2066   uint64_t insn = bfd_get (bits, input_bfd, contents + rel->r_offset);
2067 
2068   /* Write immediate to instruction.  */
2069   insn = (insn & ~howto->dst_mask) | (reloc_val & howto->dst_mask);
2070 
2071   bfd_put (bits, input_bfd, insn, contents + rel->r_offset);
2072 
2073   return bfd_reloc_ok;
2074 }
2075 
2076 static bfd_reloc_status_type
perform_relocation(const Elf_Internal_Rela * rel,asection * input_section,reloc_howto_type * howto,bfd_vma value,bfd * input_bfd,bfd_byte * contents)2077 perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
2078 		    reloc_howto_type *howto, bfd_vma value,
2079 		    bfd *input_bfd, bfd_byte *contents)
2080 {
2081   int64_t opr1, opr2, opr3;
2082   bfd_reloc_status_type r = bfd_reloc_ok;
2083   int bits = bfd_get_reloc_size (howto) * 8;
2084 
2085   switch (ELFNN_R_TYPE (rel->r_info))
2086     {
2087     case R_LARCH_SOP_PUSH_PCREL:
2088     case R_LARCH_SOP_PUSH_ABSOLUTE:
2089     case R_LARCH_SOP_PUSH_GPREL:
2090     case R_LARCH_SOP_PUSH_TLS_TPREL:
2091     case R_LARCH_SOP_PUSH_TLS_GOT:
2092     case R_LARCH_SOP_PUSH_TLS_GD:
2093     case R_LARCH_SOP_PUSH_PLT_PCREL:
2094       r = loongarch_push (value);
2095       break;
2096 
2097     case R_LARCH_SOP_PUSH_DUP:
2098       r = loongarch_pop (&opr1);
2099       if (r == bfd_reloc_ok)
2100 	{
2101 	  r = loongarch_push (opr1);
2102 	  if (r == bfd_reloc_ok)
2103 	    r = loongarch_push (opr1);
2104 	}
2105       break;
2106 
2107     case R_LARCH_SOP_ASSERT:
2108       r = loongarch_pop (&opr1);
2109       if (r != bfd_reloc_ok || !opr1)
2110 	r = bfd_reloc_notsupported;
2111       break;
2112 
2113     case R_LARCH_SOP_NOT:
2114       r = loongarch_pop (&opr1);
2115       if (r == bfd_reloc_ok)
2116 	r = loongarch_push (!opr1);
2117       break;
2118 
2119     case R_LARCH_SOP_SUB:
2120       r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 - opr2);
2121       break;
2122 
2123     case R_LARCH_SOP_SL:
2124       r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 << opr2);
2125       break;
2126 
2127     case R_LARCH_SOP_SR:
2128       r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 >> opr2);
2129       break;
2130 
2131     case R_LARCH_SOP_AND:
2132       r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 & opr2);
2133       break;
2134 
2135     case R_LARCH_SOP_ADD:
2136       r = LARCH_RELOC_PERFORM_3OP (opr1, opr2, opr1 + opr2);
2137       break;
2138 
2139     case R_LARCH_SOP_IF_ELSE:
2140       r = loongarch_pop (&opr3);
2141       if (r == bfd_reloc_ok)
2142 	{
2143 	  r = loongarch_pop (&opr2);
2144 	  if (r == bfd_reloc_ok)
2145 	    {
2146 	      r = loongarch_pop (&opr1);
2147 	      if (r == bfd_reloc_ok)
2148 		r = loongarch_push (opr1 ? opr2 : opr3);
2149 	    }
2150 	}
2151       break;
2152 
2153     case R_LARCH_SOP_POP_32_S_10_5:
2154     case R_LARCH_SOP_POP_32_S_10_12:
2155     case R_LARCH_SOP_POP_32_S_10_16:
2156     case R_LARCH_SOP_POP_32_S_10_16_S2:
2157     case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
2158     case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
2159     case R_LARCH_SOP_POP_32_S_5_20:
2160     case R_LARCH_SOP_POP_32_U_10_12:
2161     case R_LARCH_SOP_POP_32_U:
2162       r = loongarch_pop (&opr1);
2163       if (r != bfd_reloc_ok)
2164 	break;
2165       r = loongarch_check_offset (rel, input_section);
2166       if (r != bfd_reloc_ok)
2167 	break;
2168 
2169       r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
2170 					    howto, input_bfd,
2171 					    contents, (bfd_vma)opr1);
2172       break;
2173 
2174     case R_LARCH_TLS_DTPREL32:
2175     case R_LARCH_32:
2176     case R_LARCH_TLS_DTPREL64:
2177     case R_LARCH_64:
2178       r = loongarch_check_offset (rel, input_section);
2179       if (r != bfd_reloc_ok)
2180 	break;
2181 
2182       bfd_put (bits, input_bfd, value, contents + rel->r_offset);
2183       break;
2184 
2185     /* LoongArch only has add/sub reloc pair, not has set/sub reloc pair.
2186        Because set/sub reloc pair not support multi-thread. While add/sub
2187        reloc pair process order not affect the final result.
2188 
2189        For add/sub reloc, the original value will be involved in the
2190        calculation. In order not to add/sub extra value, we write 0 to symbol
2191        address at assembly time.
2192 
2193        add/sub reloc bits determined by the value after symbol subtraction,
2194        not symbol value.
2195 
2196        add/sub reloc save part of the symbol value, so we only need to
2197        save howto->dst_mask bits.  */
2198     case R_LARCH_ADD6:
2199     case R_LARCH_SUB6:
2200       {
2201 	bfd_vma word = bfd_get (howto->bitsize, input_bfd,
2202 				contents + rel->r_offset);
2203 	word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
2204 	bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2205 	r = bfd_reloc_ok;
2206 	break;
2207       }
2208 
2209     /* Not need to read the original value, just write the new value.  */
2210     case R_LARCH_ADD8:
2211     case R_LARCH_ADD16:
2212     case R_LARCH_ADD24:
2213     case R_LARCH_ADD32:
2214     case R_LARCH_ADD64:
2215     case R_LARCH_SUB8:
2216     case R_LARCH_SUB16:
2217     case R_LARCH_SUB24:
2218     case R_LARCH_SUB32:
2219     case R_LARCH_SUB64:
2220       {
2221 	/* Because add/sub reloc is processed separately,
2222 	   so the high bits is invalid.  */
2223 	bfd_vma word = value & howto->dst_mask;
2224 	bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2225 	r = bfd_reloc_ok;
2226 	break;
2227       }
2228 
2229     case R_LARCH_ADD_ULEB128:
2230     case R_LARCH_SUB_ULEB128:
2231       {
2232 	unsigned int len = 0;
2233 	/* Before write uleb128, first read it to get it's length.  */
2234 	_bfd_read_unsigned_leb128 (input_bfd, contents + rel->r_offset, &len);
2235 	loongarch_write_unsigned_leb128 (contents + rel->r_offset, len, value);
2236 	r = bfd_reloc_ok;
2237 	break;
2238       }
2239 
2240     /* For eh_frame and debug info.  */
2241     case R_LARCH_32_PCREL:
2242     case R_LARCH_64_PCREL:
2243       {
2244 	value -= sec_addr (input_section) + rel->r_offset;
2245 	value += rel->r_addend;
2246 	bfd_vma word = bfd_get (howto->bitsize, input_bfd,
2247 				contents + rel->r_offset);
2248 	word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
2249 	bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
2250 	r = bfd_reloc_ok;
2251 	break;
2252       }
2253 
2254     /* New reloc type.
2255        R_LARCH_B16 ~ R_LARCH_TLS_GD_HI20.  */
2256     case R_LARCH_B16:
2257     case R_LARCH_B21:
2258     case R_LARCH_B26:
2259     case R_LARCH_ABS_HI20:
2260     case R_LARCH_ABS_LO12:
2261     case R_LARCH_ABS64_LO20:
2262     case R_LARCH_ABS64_HI12:
2263     case R_LARCH_PCALA_HI20:
2264     case R_LARCH_PCALA_LO12:
2265     case R_LARCH_PCALA64_LO20:
2266     case R_LARCH_PCALA64_HI12:
2267     case R_LARCH_GOT_PC_HI20:
2268     case R_LARCH_GOT_PC_LO12:
2269     case R_LARCH_GOT64_PC_LO20:
2270     case R_LARCH_GOT64_PC_HI12:
2271     case R_LARCH_GOT_HI20:
2272     case R_LARCH_GOT_LO12:
2273     case R_LARCH_GOT64_LO20:
2274     case R_LARCH_GOT64_HI12:
2275     case R_LARCH_TLS_LE_HI20:
2276     case R_LARCH_TLS_LE_LO12:
2277     case R_LARCH_TLS_LE_HI20_R:
2278     case R_LARCH_TLS_LE_LO12_R:
2279     case R_LARCH_TLS_LE64_LO20:
2280     case R_LARCH_TLS_LE64_HI12:
2281     case R_LARCH_TLS_IE_PC_HI20:
2282     case R_LARCH_TLS_IE_PC_LO12:
2283     case R_LARCH_TLS_IE64_PC_LO20:
2284     case R_LARCH_TLS_IE64_PC_HI12:
2285     case R_LARCH_TLS_IE_HI20:
2286     case R_LARCH_TLS_IE_LO12:
2287     case R_LARCH_TLS_IE64_LO20:
2288     case R_LARCH_TLS_IE64_HI12:
2289     case R_LARCH_TLS_LD_PC_HI20:
2290     case R_LARCH_TLS_LD_HI20:
2291     case R_LARCH_TLS_GD_PC_HI20:
2292     case R_LARCH_TLS_GD_HI20:
2293     case R_LARCH_PCREL20_S2:
2294     case R_LARCH_CALL36:
2295     case R_LARCH_TLS_DESC_PC_HI20:
2296     case R_LARCH_TLS_DESC_PC_LO12:
2297     case R_LARCH_TLS_DESC64_PC_LO20:
2298     case R_LARCH_TLS_DESC64_PC_HI12:
2299     case R_LARCH_TLS_DESC_HI20:
2300     case R_LARCH_TLS_DESC_LO12:
2301     case R_LARCH_TLS_DESC64_LO20:
2302     case R_LARCH_TLS_DESC64_HI12:
2303     case R_LARCH_TLS_LD_PCREL20_S2:
2304     case R_LARCH_TLS_GD_PCREL20_S2:
2305     case R_LARCH_TLS_DESC_PCREL20_S2:
2306       r = loongarch_check_offset (rel, input_section);
2307       if (r != bfd_reloc_ok)
2308 	break;
2309 
2310       r = loongarch_reloc_rewrite_imm_insn (rel, input_section,
2311 					    howto, input_bfd,
2312 					    contents, value);
2313       break;
2314 
2315     case R_LARCH_TLS_DESC_LD:
2316     case R_LARCH_TLS_DESC_CALL:
2317       r = bfd_reloc_ok;
2318       break;
2319 
2320     case R_LARCH_RELAX:
2321     case R_LARCH_TLS_LE_ADD_R:
2322       break;
2323 
2324     default:
2325       r = bfd_reloc_notsupported;
2326     }
2327   return r;
2328 }
2329 
2330 #define LARCH_RECENT_RELOC_QUEUE_LENGTH 72
2331 static struct
2332 {
2333   bfd *bfd;
2334   asection *section;
2335   bfd_vma r_offset;
2336   int r_type;
2337   bfd_vma relocation;
2338   Elf_Internal_Sym *sym;
2339   struct elf_link_hash_entry *h;
2340   bfd_vma addend;
2341   int64_t top_then;
2342 } larch_reloc_queue[LARCH_RECENT_RELOC_QUEUE_LENGTH];
2343 static size_t larch_reloc_queue_head = 0;
2344 static size_t larch_reloc_queue_tail = 0;
2345 
2346 static const char *
loongarch_sym_name(bfd * input_bfd,struct elf_link_hash_entry * h,Elf_Internal_Sym * sym)2347 loongarch_sym_name (bfd *input_bfd, struct elf_link_hash_entry *h,
2348 		    Elf_Internal_Sym *sym)
2349 {
2350   const char *ret = NULL;
2351   if (sym)
2352     ret = bfd_elf_string_from_elf_section (input_bfd,
2353 					   elf_symtab_hdr (input_bfd).sh_link,
2354 					   sym->st_name);
2355   else if (h)
2356     ret = h->root.root.string;
2357 
2358   if (ret == NULL || *ret == '\0')
2359     ret = "<nameless>";
2360   return ret;
2361 }
2362 
2363 static void
loongarch_record_one_reloc(bfd * abfd,asection * section,int r_type,bfd_vma r_offset,Elf_Internal_Sym * sym,struct elf_link_hash_entry * h,bfd_vma addend)2364 loongarch_record_one_reloc (bfd *abfd, asection *section, int r_type,
2365 			    bfd_vma r_offset, Elf_Internal_Sym *sym,
2366 			    struct elf_link_hash_entry *h, bfd_vma addend)
2367 {
2368   if ((larch_reloc_queue_head == 0
2369        && larch_reloc_queue_tail == LARCH_RECENT_RELOC_QUEUE_LENGTH - 1)
2370       || larch_reloc_queue_head == larch_reloc_queue_tail + 1)
2371     larch_reloc_queue_head =
2372       (larch_reloc_queue_head + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2373   larch_reloc_queue[larch_reloc_queue_tail].bfd = abfd;
2374   larch_reloc_queue[larch_reloc_queue_tail].section = section;
2375   larch_reloc_queue[larch_reloc_queue_tail].r_offset = r_offset;
2376   larch_reloc_queue[larch_reloc_queue_tail].r_type = r_type;
2377   larch_reloc_queue[larch_reloc_queue_tail].sym = sym;
2378   larch_reloc_queue[larch_reloc_queue_tail].h = h;
2379   larch_reloc_queue[larch_reloc_queue_tail].addend = addend;
2380   loongarch_top (&larch_reloc_queue[larch_reloc_queue_tail].top_then);
2381   larch_reloc_queue_tail =
2382     (larch_reloc_queue_tail + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2383 }
2384 
2385 static void
loongarch_dump_reloc_record(void (* p)(const char * fmt,...))2386 loongarch_dump_reloc_record (void (*p) (const char *fmt, ...))
2387 {
2388   size_t i = larch_reloc_queue_head;
2389   bfd *a_bfd = NULL;
2390   asection *section = NULL;
2391   bfd_vma r_offset = 0;
2392   int inited = 0;
2393   p ("Dump relocate record:\n");
2394   p ("stack top\t\trelocation name\t\tsymbol");
2395   while (i != larch_reloc_queue_tail)
2396     {
2397       if (a_bfd != larch_reloc_queue[i].bfd
2398 	  || section != larch_reloc_queue[i].section
2399 	  || r_offset != larch_reloc_queue[i].r_offset)
2400 	{
2401 	  a_bfd = larch_reloc_queue[i].bfd;
2402 	  section = larch_reloc_queue[i].section;
2403 	  r_offset = larch_reloc_queue[i].r_offset;
2404 	  p ("\nat %pB(%pA+0x%v):\n", larch_reloc_queue[i].bfd,
2405 	     larch_reloc_queue[i].section, larch_reloc_queue[i].r_offset);
2406 	}
2407 
2408       if (!inited)
2409 	inited = 1, p ("...\n");
2410 
2411       reloc_howto_type *howto =
2412 	loongarch_elf_rtype_to_howto (larch_reloc_queue[i].bfd,
2413 				      larch_reloc_queue[i].r_type);
2414       p ("0x%V %s\t`%s'", (bfd_vma) larch_reloc_queue[i].top_then,
2415 	 howto ? howto->name : "<unknown reloc>",
2416 	 loongarch_sym_name (larch_reloc_queue[i].bfd, larch_reloc_queue[i].h,
2417 			     larch_reloc_queue[i].sym));
2418 
2419       long addend = larch_reloc_queue[i].addend;
2420       if (addend < 0)
2421 	p (" - %ld", -addend);
2422       else if (0 < addend)
2423 	p (" + %ld(0x%v)", addend, larch_reloc_queue[i].addend);
2424 
2425       p ("\n");
2426       i = (i + 1) % LARCH_RECENT_RELOC_QUEUE_LENGTH;
2427     }
2428   p ("\n"
2429      "-- Record dump end --\n\n");
2430 }
2431 
2432 static bool
loongarch_reloc_is_fatal(struct bfd_link_info * info,bfd * input_bfd,asection * input_section,Elf_Internal_Rela * rel,reloc_howto_type * howto,bfd_reloc_status_type rtype,bool is_undefweak,const char * name,const char * msg)2433 loongarch_reloc_is_fatal (struct bfd_link_info *info,
2434 			  bfd *input_bfd,
2435 			  asection *input_section,
2436 			  Elf_Internal_Rela *rel,
2437 			  reloc_howto_type *howto,
2438 			  bfd_reloc_status_type rtype,
2439 			  bool is_undefweak,
2440 			  const char *name,
2441 			  const char *msg)
2442 {
2443   bool fatal = true;
2444   switch (rtype)
2445     {
2446       /* 'dangerous' means we do it but can't promise it's ok
2447 	 'unsupport' means out of ability of relocation type
2448 	 'undefined' means we can't deal with the undefined symbol.  */
2449     case bfd_reloc_undefined:
2450       info->callbacks->undefined_symbol (info, name, input_bfd, input_section,
2451 					 rel->r_offset, true);
2452       info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2453 			     input_bfd, input_section, rel->r_offset,
2454 			     howto->name,
2455 			     is_undefweak ? "[undefweak] " : "", name, msg);
2456       break;
2457     case bfd_reloc_dangerous:
2458       info->callbacks->info ("%pB(%pA+0x%v): warning: %s against %s`%s':\n%s\n",
2459 			     input_bfd, input_section, rel->r_offset,
2460 			     howto->name,
2461 			     is_undefweak ? "[undefweak] " : "", name, msg);
2462       fatal = false;
2463       break;
2464     case bfd_reloc_notsupported:
2465       info->callbacks->info ("%X%pB(%pA+0x%v): error: %s against %s`%s':\n%s\n",
2466 			     input_bfd, input_section, rel->r_offset,
2467 			     howto->name,
2468 			     is_undefweak ? "[undefweak] " : "", name, msg);
2469       break;
2470     default:
2471       break;
2472     }
2473   return fatal;
2474 }
2475 
2476 /* If lo12 immediate > 0x7ff, because sign-extend caused by addi.d/ld.d,
2477    hi20 immediate need to add 0x1.
2478    For example: pc 0x120000000, symbol 0x120000812
2479    lo12 immediate is 0x812, 0x120000812 & 0xfff = 0x812
2480    hi20 immediate is 1, because lo12 imm > 0x7ff, symbol need to add 0x1000
2481    (((0x120000812 + 0x1000) & ~0xfff) - (0x120000000 & ~0xfff)) >> 12 = 0x1
2482 
2483    At run:
2484    pcalau12i $t0, hi20 (0x1)
2485       $t0 = 0x120000000 + (0x1 << 12) = 0x120001000
2486    addi.d $t0, $t0, lo12 (0x812)
2487       $t0 = 0x120001000 + 0xfffffffffffff812 (-(0x1000 - 0x812) = -0x7ee)
2488 	  = 0x120001000 - 0x7ee (0x1000 - 0x7ee = 0x812)
2489 	  = 0x120000812
2490     Without hi20 add 0x1000, the result 0x120000000 - 0x7ee = 0x11ffff812 is
2491     error.
2492     0x1000 + sign-extend-to64(0x8xx) = 0x8xx.  */
2493 #define RELOCATE_CALC_PC32_HI20(relocation, pc) 	\
2494   ({							\
2495     bfd_vma __lo = (relocation) & ((bfd_vma)0xfff);	\
2496     relocation = (relocation & ~(bfd_vma)0xfff)		\
2497 		  - (pc & ~(bfd_vma)0xfff);		\
2498     if (__lo > 0x7ff)					\
2499 	relocation += 0x1000;				\
2500   })
2501 
2502 /* Handle problems caused by symbol extensions in TLS LE, The processing
2503    is similar to the macro RELOCATE_CALC_PC32_HI20 method.  */
2504 #define RELOCATE_TLS_TP32_HI20(relocation)		\
2505   ({							\
2506     bfd_vma __lo = (relocation) & ((bfd_vma)0xfff);	\
2507     if (__lo > 0x7ff)					\
2508 	relocation += 0x800;				\
2509     relocation = relocation & ~(bfd_vma)0xfff;		\
2510   })
2511 
2512 /* For example: pc is 0x11000010000100, symbol is 0x1812348ffff812
2513    offset = (0x1812348ffff812 & ~0xfff) - (0x11000010000100 & ~0xfff)
2514 	  = 0x712347ffff000
2515    lo12: 0x1812348ffff812 & 0xfff = 0x812
2516    hi20: 0x7ffff + 0x1(lo12 > 0x7ff) = 0x80000
2517    lo20: 0x71234 - 0x1(lo12 > 0x7ff) + 0x1(hi20 > 0x7ffff)
2518    hi12: 0x0
2519 
2520    pcalau12i $t1, hi20 (0x80000)
2521       $t1 = 0x11000010000100 + sign-extend(0x80000 << 12)
2522 	  = 0x11000010000100 + 0xffffffff80000000
2523 	  = 0x10ffff90000000
2524    addi.d $t0, $zero, lo12 (0x812)
2525       $t0 = 0xfffffffffffff812 (if lo12 > 0x7ff, because sign-extend,
2526       lo20 need to sub 0x1)
2527    lu32i.d $t0, lo20 (0x71234)
2528       $t0 = {0x71234, 0xfffff812}
2529 	  = 0x71234fffff812
2530    lu52i.d $t0, hi12 (0x0)
2531       $t0 = {0x0, 0x71234fffff812}
2532 	  = 0x71234fffff812
2533    add.d $t1, $t1, $t0
2534       $t1 = 0x10ffff90000000 + 0x71234fffff812
2535 	  = 0x1812348ffff812.  */
2536 #define RELOCATE_CALC_PC64_HI32(relocation, pc)  	\
2537   ({							\
2538     bfd_vma __lo = (relocation & (bfd_vma)0xfff);	\
2539     relocation = (relocation & ~(bfd_vma)0xfff)		\
2540 		  - ((pc) & ~(bfd_vma)0xfff);		\
2541     if (__lo > 0x7ff)					\
2542 	relocation += (0x1000 - 0x100000000);		\
2543     if (relocation & 0x80000000)			\
2544       relocation += 0x100000000;			\
2545   })
2546 
2547 /* Transition instruction sequence to relax instruction sequence.  */
2548 static bool
loongarch_tls_perform_trans(bfd * abfd,asection * sec,Elf_Internal_Rela * rel,int r_type,struct elf_link_hash_entry * h,struct bfd_link_info * info)2549 loongarch_tls_perform_trans (bfd *abfd, asection *sec, Elf_Internal_Rela *rel,
2550 		    int r_type, struct elf_link_hash_entry *h,
2551 		    struct bfd_link_info *info)
2552 {
2553   bool local_exec = bfd_link_executable (info)
2554 		    && SYMBOL_REFERENCES_LOCAL (info, h);
2555   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
2556   unsigned long insn;
2557 
2558   switch (r_type)
2559     {
2560       case R_LARCH_TLS_DESC_PC_HI20:
2561 	if (local_exec)
2562 	    /* DESC -> LE relaxation:
2563 	       pcalalau12i $a0,%desc_pc_hi20(var) =>
2564 	       lu12i.w $a0,%le_hi20(var)
2565 	    */
2566 	    bfd_put (32, abfd, LARCH_LU12I_W | LARCH_RD_A0,
2567 		     contents + rel->r_offset);
2568 
2569 	/* DESC -> IE relaxation:
2570 	   pcalalau12i $a0,%desc_pc_hi20(var) =>
2571 	   pcalalau12i $a0,%ie_pc_hi20(var)
2572 	*/
2573 	return true;
2574 
2575       case R_LARCH_TLS_DESC_PC_LO12:
2576 	if (local_exec)
2577 	  {
2578 	    /* DESC -> LE relaxation:
2579 	       addi.d $a0,$a0,%desc_pc_lo12(var) =>
2580 	       ori  $a0,$a0,le_lo12(var)
2581 	    */
2582 	    insn = LARCH_ORI | LARCH_RD_RJ_A0;
2583 	    bfd_put (32, abfd, LARCH_ORI | LARCH_RD_RJ_A0,
2584 		     contents + rel->r_offset);
2585 	  }
2586 	else
2587 	  {
2588 	    /* DESC -> IE relaxation:
2589 	       addi.d $a0,$a0,%desc_pc_lo12(var) =>
2590 	       ld.d $a0,$a0,%%ie_pc_lo12
2591 	    */
2592 	    bfd_put (32, abfd, LARCH_LD_D | LARCH_RD_RJ_A0,
2593 		     contents + rel->r_offset);
2594 	  }
2595 	return true;
2596 
2597       case R_LARCH_TLS_DESC_LD:
2598       case R_LARCH_TLS_DESC_CALL:
2599 	/* DESC -> LE/IE relaxation:
2600 	   ld.d $ra,$a0,%desc_ld(var) => NOP
2601 	   jirl $ra,$ra,%desc_call(var) => NOP
2602 	*/
2603 	bfd_put (32, abfd, LARCH_NOP, contents + rel->r_offset);
2604 	return true;
2605 
2606       case R_LARCH_TLS_IE_PC_HI20:
2607 	if (local_exec)
2608 	  {
2609 	    /* IE -> LE relaxation:
2610 	       pcalalau12i $rd,%ie_pc_hi20(var) =>
2611 	       lu12i.w $rd,%le_hi20(var)
2612 	    */
2613 	    insn = bfd_getl32 (contents + rel->r_offset);
2614 	    bfd_put (32, abfd, LARCH_LU12I_W | (insn & 0x1f),
2615 		     contents + rel->r_offset);
2616 	  }
2617 	return true;
2618 
2619       case R_LARCH_TLS_IE_PC_LO12:
2620 	if (local_exec)
2621 	  {
2622 	    /* IE -> LE relaxation:
2623 	       ld.d $rd,$rj,%%ie_pc_lo12 =>
2624 	       ori  $rd,$rj,le_lo12(var)
2625 	    */
2626 	    insn = bfd_getl32 (contents + rel->r_offset);
2627 	    bfd_put (32, abfd, LARCH_ORI | (insn & 0x3ff),
2628 		     contents + rel->r_offset);
2629 	  }
2630 	return true;
2631     }
2632 
2633   return false;
2634 }
2635 
2636 
2637 static int
loongarch_elf_relocate_section(bfd * output_bfd,struct bfd_link_info * info,bfd * input_bfd,asection * input_section,bfd_byte * contents,Elf_Internal_Rela * relocs,Elf_Internal_Sym * local_syms,asection ** local_sections)2638 loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
2639 				bfd *input_bfd, asection *input_section,
2640 				bfd_byte *contents, Elf_Internal_Rela *relocs,
2641 				Elf_Internal_Sym *local_syms,
2642 				asection **local_sections)
2643 {
2644   Elf_Internal_Rela *rel;
2645   Elf_Internal_Rela *relend;
2646   bool fatal = false;
2647   asection *sreloc = elf_section_data (input_section)->sreloc;
2648   struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
2649   Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd);
2650   struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
2651   bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd);
2652   bool is_pic = bfd_link_pic (info);
2653   bool is_dyn = elf_hash_table (info)->dynamic_sections_created;
2654   asection *plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
2655   asection *got = htab->elf.sgot;
2656 
2657   relend = relocs + input_section->reloc_count;
2658   for (rel = relocs; rel < relend; rel++)
2659     {
2660       unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
2661       unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
2662       bfd_vma pc = sec_addr (input_section) + rel->r_offset;
2663       reloc_howto_type *howto = NULL;
2664       asection *sec = NULL;
2665       Elf_Internal_Sym *sym = NULL;
2666       struct elf_link_hash_entry *h = NULL;
2667       const char *name;
2668       bfd_reloc_status_type r = bfd_reloc_ok;
2669       bool is_ie, is_desc, is_undefweak, unresolved_reloc, defined_local;
2670       unsigned int trans_r_type = r_type;
2671       bool resolved_local, resolved_dynly, resolved_to_const;
2672       char tls_type;
2673       bfd_vma relocation, off, ie_off, desc_off;
2674       int i, j;
2675 
2676       howto = loongarch_elf_rtype_to_howto (input_bfd, r_type);
2677       if (howto == NULL || r_type == R_LARCH_GNU_VTINHERIT
2678 	  || r_type == R_LARCH_GNU_VTENTRY)
2679 	continue;
2680 
2681       /* This is a final link.  */
2682       if (r_symndx < symtab_hdr->sh_info)
2683 	{
2684 	  is_undefweak = false;
2685 	  unresolved_reloc = false;
2686 	  sym = local_syms + r_symndx;
2687 	  sec = local_sections[r_symndx];
2688 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2689 
2690 	  /* Relocate against local STT_GNU_IFUNC symbol.  */
2691 	  if (!bfd_link_relocatable (info)
2692 	      && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
2693 	    {
2694 	      h = elfNN_loongarch_get_local_sym_hash (htab, input_bfd, rel,
2695 						      false);
2696 	      if (h == NULL)
2697 		abort ();
2698 
2699 	      /* Set STT_GNU_IFUNC symbol value.  */
2700 	      h->root.u.def.value = sym->st_value;
2701 	      h->root.u.def.section = sec;
2702 	    }
2703 	  defined_local = true;
2704 	  resolved_local = true;
2705 	  resolved_dynly = false;
2706 	  resolved_to_const = false;
2707 
2708 	  /* Calc in funtion elf_link_input_bfd,
2709 	   * if #define elf_backend_rela_normal to 1.  */
2710 	  if (bfd_link_relocatable (info)
2711 	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
2712 	    continue;
2713 	}
2714       else
2715 	{
2716 	  bool warned, ignored;
2717 
2718 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2719 				   r_symndx, symtab_hdr, sym_hashes,
2720 				   h, sec, relocation,
2721 				   unresolved_reloc, warned, ignored);
2722 	  /* Here means symbol isn't local symbol only and 'h != NULL'.  */
2723 
2724 	  /* The 'unresolved_syms_in_objects' specify how to deal with undefined
2725 	     symbol.  And 'dynamic_undefined_weak' specify what to do when
2726 	     meeting undefweak.  */
2727 
2728 	  if ((is_undefweak = h->root.type == bfd_link_hash_undefweak))
2729 	    {
2730 	      defined_local = false;
2731 	      resolved_local = false;
2732 	      resolved_to_const = (!is_dyn || h->dynindx == -1
2733 				   || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
2734 	      resolved_dynly = !resolved_local && !resolved_to_const;
2735 	    }
2736 	  else if (warned)
2737 	    {
2738 	      /* Symbol undefined offen means failed already.  I don't know why
2739 		 'warned' here but I guess it want to continue relocating as if
2740 		 no error occures to find other errors as more as possible.  */
2741 
2742 	      /* To avoid generating warning messages about truncated
2743 		 relocations, set the relocation's address to be the same as
2744 		 the start of this section.  */
2745 	      relocation = (input_section->output_section
2746 			    ? input_section->output_section->vma
2747 			    : 0);
2748 
2749 	      defined_local = relocation != 0;
2750 	      resolved_local = defined_local;
2751 	      resolved_to_const = !resolved_local;
2752 	      resolved_dynly = false;
2753 	    }
2754 	  else
2755 	    {
2756 	      defined_local = !unresolved_reloc && !ignored;
2757 	      resolved_local =
2758 		defined_local && SYMBOL_REFERENCES_LOCAL (info, h);
2759 	      resolved_dynly = !resolved_local;
2760 	      resolved_to_const = !resolved_local && !resolved_dynly;
2761 	    }
2762 	}
2763 
2764       name = loongarch_sym_name (input_bfd, h, sym);
2765 
2766       if (sec != NULL && discarded_section (sec))
2767 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel,
2768 					 1, relend, howto, 0, contents);
2769 
2770       if (bfd_link_relocatable (info))
2771 	continue;
2772 
2773       /* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
2774 	 from removed linkonce sections, or sections discarded by a linker
2775 	 script.  Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const.  */
2776       if (r_symndx == STN_UNDEF || bfd_is_abs_section (sec))
2777 	{
2778 	  defined_local = false;
2779 	  resolved_local = false;
2780 	  resolved_dynly = false;
2781 	  resolved_to_const = true;
2782 	}
2783 
2784       /* The ifunc reference generate plt.  */
2785       if (h && h->type == STT_GNU_IFUNC && h->plt.offset != MINUS_ONE)
2786 	{
2787 	  defined_local = true;
2788 	  resolved_local = true;
2789 	  resolved_dynly = false;
2790 	  resolved_to_const = false;
2791 	  relocation = sec_addr (plt) + h->plt.offset;
2792 	}
2793 
2794       unresolved_reloc = resolved_dynly;
2795 
2796       BFD_ASSERT (resolved_local + resolved_dynly + resolved_to_const == 1);
2797 
2798       /* BFD_ASSERT (!resolved_dynly || (h && h->dynindx != -1));.  */
2799 
2800       BFD_ASSERT (!resolved_local || defined_local);
2801 
2802       if (rel + 1 != relend)
2803 	trans_r_type = loongarch_tls_transition (input_bfd, info, h,
2804 						rel, r_type);
2805       if (trans_r_type != r_type)
2806       {
2807 	howto = loongarch_elf_rtype_to_howto (input_bfd, trans_r_type);
2808 	BFD_ASSERT (howto != NULL);
2809 
2810 	if (loongarch_tls_perform_trans (input_bfd, input_section,
2811 					rel, r_type, h, info))
2812 	  r_type = trans_r_type;
2813       }
2814 
2815       is_desc = false;
2816       is_ie = false;
2817       switch (r_type)
2818 	{
2819 	case R_LARCH_MARK_PCREL:
2820 	case R_LARCH_MARK_LA:
2821 	case R_LARCH_NONE:
2822 	  r = bfd_reloc_continue;
2823 	  unresolved_reloc = false;
2824 	  break;
2825 
2826 	case R_LARCH_32:
2827 	case R_LARCH_64:
2828 	  if (resolved_dynly || (is_pic && resolved_local))
2829 	    {
2830 	      Elf_Internal_Rela outrel;
2831 
2832 	      /* When generating a shared object, these relocations are copied
2833 		 into the output file to be resolved at run time.  */
2834 
2835 	      outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2836 							 input_section,
2837 							 rel->r_offset);
2838 
2839 	      unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2840 				  && (input_section->flags & SEC_ALLOC));
2841 
2842 	      outrel.r_offset += sec_addr (input_section);
2843 
2844 	      /* A pointer point to a ifunc symbol.  */
2845 	      if (h && h->type == STT_GNU_IFUNC)
2846 		{
2847 		  if (h->dynindx == -1)
2848 		    {
2849 		      outrel.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
2850 		      outrel.r_addend = (h->root.u.def.value
2851 				  + h->root.u.def.section->output_section->vma
2852 				  + h->root.u.def.section->output_offset);
2853 		    }
2854 		  else
2855 		    {
2856 		      outrel.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
2857 		      outrel.r_addend = 0;
2858 		    }
2859 
2860 		  if (SYMBOL_REFERENCES_LOCAL (info, h))
2861 		    {
2862 
2863 		      if (htab->elf.splt != NULL)
2864 			sreloc = htab->elf.srelgot;
2865 		      else
2866 			sreloc = htab->elf.irelplt;
2867 		    }
2868 		  else
2869 		    {
2870 
2871 		      if (bfd_link_pic (info))
2872 			sreloc = htab->elf.irelifunc;
2873 		      else if (htab->elf.splt != NULL)
2874 			sreloc = htab->elf.srelgot;
2875 		      else
2876 			sreloc = htab->elf.irelplt;
2877 		    }
2878 		}
2879 	      else if (resolved_dynly)
2880 		{
2881 		  if (h->dynindx == -1)
2882 		    {
2883 		      if (h->root.type == bfd_link_hash_undefined)
2884 			(*info->callbacks->undefined_symbol)
2885 			  (info, name, input_bfd, input_section,
2886 			   rel->r_offset, true);
2887 
2888 		      outrel.r_info = ELFNN_R_INFO (0, r_type);
2889 		    }
2890 		  else
2891 		    outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
2892 
2893 		  outrel.r_addend = rel->r_addend;
2894 		}
2895 	      else
2896 		{
2897 		  outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
2898 		  outrel.r_addend = relocation + rel->r_addend;
2899 		}
2900 
2901 	      /* No alloc space of func allocate_dynrelocs.  */
2902 	      if (unresolved_reloc
2903 		  && !(h && (h->is_weakalias || !h->dyn_relocs)))
2904 		loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2905 	    }
2906 
2907 	  relocation += rel->r_addend;
2908 	  break;
2909 
2910 	case R_LARCH_ADD6:
2911 	case R_LARCH_ADD8:
2912 	case R_LARCH_ADD16:
2913 	case R_LARCH_ADD24:
2914 	case R_LARCH_ADD32:
2915 	case R_LARCH_ADD64:
2916 	  {
2917 	    bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
2918 					 contents + rel->r_offset);
2919 	    relocation = old_value + relocation + rel->r_addend;
2920 	    break;
2921 	  }
2922 
2923 	case R_LARCH_SUB6:
2924 	case R_LARCH_SUB8:
2925 	case R_LARCH_SUB16:
2926 	case R_LARCH_SUB24:
2927 	case R_LARCH_SUB32:
2928 	case R_LARCH_SUB64:
2929 	  {
2930 	    bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
2931 					  contents + rel->r_offset);
2932 	    relocation = old_value - relocation - rel->r_addend;
2933 	    break;
2934 	  }
2935 
2936 	case R_LARCH_ADD_ULEB128:
2937 	case R_LARCH_SUB_ULEB128:
2938 	  {
2939 	    /* Get the value and length of the uleb128 data.  */
2940 	    unsigned int len = 0;
2941 	    bfd_vma old_value = _bfd_read_unsigned_leb128 (input_bfd,
2942 				    contents + rel->r_offset, &len);
2943 
2944 	    if (R_LARCH_ADD_ULEB128 == ELFNN_R_TYPE (rel->r_info))
2945 	      relocation = old_value + relocation + rel->r_addend;
2946 	    else if (R_LARCH_SUB_ULEB128 == ELFNN_R_TYPE (rel->r_info))
2947 	      relocation = old_value - relocation - rel->r_addend;
2948 
2949 	    bfd_vma mask = (1 << (7 * len)) - 1;
2950 	    relocation &= mask;
2951 	    break;
2952 	  }
2953 
2954 	case R_LARCH_TLS_DTPREL32:
2955 	case R_LARCH_TLS_DTPREL64:
2956 	  if (resolved_dynly)
2957 	    {
2958 	      Elf_Internal_Rela outrel;
2959 
2960 	      outrel.r_offset = _bfd_elf_section_offset (output_bfd, info,
2961 							 input_section,
2962 							 rel->r_offset);
2963 	      unresolved_reloc = (!((bfd_vma) -2 <= outrel.r_offset)
2964 				  && (input_section->flags & SEC_ALLOC));
2965 	      outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
2966 	      outrel.r_offset += sec_addr (input_section);
2967 	      outrel.r_addend = rel->r_addend;
2968 	      if (unresolved_reloc)
2969 		loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
2970 	      break;
2971 	    }
2972 
2973 	  if (resolved_to_const)
2974 	    fatal = loongarch_reloc_is_fatal (info, input_bfd, input_section,
2975 					      rel, howto,
2976 					      bfd_reloc_notsupported,
2977 					      is_undefweak, name,
2978 					      "Internal:");
2979 	  if (resolved_local)
2980 	    {
2981 	      if (!elf_hash_table (info)->tls_sec)
2982 		{
2983 		fatal = loongarch_reloc_is_fatal (info, input_bfd,
2984 			  input_section, rel, howto, bfd_reloc_notsupported,
2985 			  is_undefweak, name, "TLS section not be created");
2986 		}
2987 	      else
2988 		relocation -= elf_hash_table (info)->tls_sec->vma;
2989 	    }
2990 	  else
2991 	    {
2992 	    fatal = loongarch_reloc_is_fatal (info, input_bfd,
2993 		      input_section, rel, howto, bfd_reloc_undefined,
2994 		      is_undefweak, name,
2995 		      "TLS LE just can be resolved local only.");
2996 	    }
2997 
2998 	  break;
2999 
3000 	case R_LARCH_SOP_PUSH_TLS_TPREL:
3001 	  if (resolved_local)
3002 	    {
3003 	      if (!elf_hash_table (info)->tls_sec)
3004 		fatal = (loongarch_reloc_is_fatal
3005 			 (info, input_bfd, input_section, rel, howto,
3006 			  bfd_reloc_notsupported, is_undefweak, name,
3007 			  "TLS section not be created"));
3008 	      else
3009 		relocation -= elf_hash_table (info)->tls_sec->vma;
3010 	    }
3011 	  else
3012 	    fatal = (loongarch_reloc_is_fatal
3013 		     (info, input_bfd, input_section, rel, howto,
3014 		      bfd_reloc_undefined, is_undefweak, name,
3015 		      "TLS LE just can be resolved local only."));
3016 	  break;
3017 
3018 	case R_LARCH_SOP_PUSH_ABSOLUTE:
3019 	  if (is_undefweak)
3020 	    {
3021 	      if (resolved_dynly)
3022 		fatal = (loongarch_reloc_is_fatal
3023 			 (info, input_bfd, input_section, rel, howto,
3024 			  bfd_reloc_dangerous, is_undefweak, name,
3025 			  "Someone require us to resolve undefweak "
3026 			  "symbol dynamically.  \n"
3027 			  "But this reloc can't be done.  "
3028 			  "I think I can't throw error "
3029 			  "for this\n"
3030 			  "so I resolved it to 0.  "
3031 			  "I suggest to re-compile with '-fpic'."));
3032 
3033 	      relocation = 0;
3034 	      unresolved_reloc = false;
3035 	      break;
3036 	    }
3037 
3038 	  if (resolved_to_const)
3039 	    {
3040 	      relocation += rel->r_addend;
3041 	      break;
3042 	    }
3043 
3044 	  if (is_pic)
3045 	    {
3046 	      fatal = (loongarch_reloc_is_fatal
3047 		       (info, input_bfd, input_section, rel, howto,
3048 			bfd_reloc_notsupported, is_undefweak, name,
3049 			"Under PIC we don't know load address.  Re-compile "
3050 			"with '-fpic'?"));
3051 	      break;
3052 	    }
3053 
3054 	  if (resolved_dynly)
3055 	    {
3056 	      if (!(plt && h && h->plt.offset != MINUS_ONE))
3057 		{
3058 		  fatal = (loongarch_reloc_is_fatal
3059 			   (info, input_bfd, input_section, rel, howto,
3060 			    bfd_reloc_undefined, is_undefweak, name,
3061 			    "Can't be resolved dynamically.  Try to re-compile "
3062 			    "with '-fpic'?"));
3063 		  break;
3064 		}
3065 
3066 	      if (rel->r_addend != 0)
3067 		{
3068 		  fatal = (loongarch_reloc_is_fatal
3069 			   (info, input_bfd, input_section, rel, howto,
3070 			    bfd_reloc_notsupported, is_undefweak, name,
3071 			    "Shouldn't be with r_addend."));
3072 		  break;
3073 		}
3074 
3075 	      relocation = sec_addr (plt) + h->plt.offset;
3076 	      unresolved_reloc = false;
3077 	      break;
3078 	    }
3079 
3080 	  if (resolved_local)
3081 	    {
3082 	      relocation += rel->r_addend;
3083 	      break;
3084 	    }
3085 
3086 	  break;
3087 
3088 	case R_LARCH_SOP_PUSH_PCREL:
3089 	case R_LARCH_SOP_PUSH_PLT_PCREL:
3090 	  unresolved_reloc = false;
3091 
3092 	  if (is_undefweak)
3093 	    {
3094 	      i = 0, j = 0;
3095 	      relocation = 0;
3096 	      if (resolved_dynly)
3097 		{
3098 		  if (h && h->plt.offset != MINUS_ONE)
3099 		    i = 1, j = 2;
3100 		  else
3101 		    fatal = (loongarch_reloc_is_fatal
3102 			     (info, input_bfd, input_section, rel, howto,
3103 			      bfd_reloc_dangerous, is_undefweak, name,
3104 			      "Undefweak need to be resolved dynamically, "
3105 			      "but PLT stub doesn't represent."));
3106 		}
3107 	    }
3108 	  else
3109 	    {
3110 	      if (!(defined_local || (h && h->plt.offset != MINUS_ONE)))
3111 		{
3112 		  fatal = (loongarch_reloc_is_fatal
3113 			   (info, input_bfd, input_section, rel, howto,
3114 			    bfd_reloc_undefined, is_undefweak, name,
3115 			    "PLT stub does not represent and "
3116 			    "symbol not defined."));
3117 		  break;
3118 		}
3119 
3120 	      if (resolved_local)
3121 		i = 0, j = 2;
3122 	      else /* if (resolved_dynly) */
3123 		{
3124 		  if (!(h && h->plt.offset != MINUS_ONE))
3125 		    fatal = (loongarch_reloc_is_fatal
3126 			     (info, input_bfd, input_section, rel, howto,
3127 			      bfd_reloc_dangerous, is_undefweak, name,
3128 			      "Internal: PLT stub doesn't represent.  "
3129 			      "Resolve it with pcrel"));
3130 		  i = 1, j = 3;
3131 		}
3132 	    }
3133 
3134 	  for (; i < j; i++)
3135 	    {
3136 	      if ((i & 1) == 0 && defined_local)
3137 		{
3138 		  relocation -= pc;
3139 		  relocation += rel->r_addend;
3140 		  break;
3141 		}
3142 
3143 	      if ((i & 1) && h && h->plt.offset != MINUS_ONE)
3144 		{
3145 		  if (rel->r_addend != 0)
3146 		    {
3147 		      fatal = (loongarch_reloc_is_fatal
3148 			       (info, input_bfd, input_section, rel, howto,
3149 				bfd_reloc_notsupported, is_undefweak, name,
3150 				"PLT shouldn't be with r_addend."));
3151 		      break;
3152 		    }
3153 		  relocation = sec_addr (plt) + h->plt.offset - pc;
3154 		  break;
3155 		}
3156 	    }
3157 	  break;
3158 
3159 	case R_LARCH_SOP_PUSH_GPREL:
3160 	  unresolved_reloc = false;
3161 
3162 	  if (rel->r_addend != 0)
3163 	    {
3164 	      fatal = (loongarch_reloc_is_fatal
3165 		       (info, input_bfd, input_section, rel, howto,
3166 			bfd_reloc_notsupported, is_undefweak, name,
3167 			"Shouldn't be with r_addend."));
3168 	      break;
3169 	    }
3170 
3171 	  if (h != NULL)
3172 	    {
3173 	      off = h->got.offset & (~1);
3174 
3175 	      if (h->got.offset == MINUS_ONE && h->type != STT_GNU_IFUNC)
3176 		{
3177 		  fatal = (loongarch_reloc_is_fatal
3178 			   (info, input_bfd, input_section, rel, howto,
3179 			    bfd_reloc_notsupported, is_undefweak, name,
3180 			    "Internal: GOT entry doesn't represent."));
3181 		  break;
3182 		}
3183 
3184 	      /* Hidden symbol not has .got entry, only .got.plt entry
3185 		 so gprel is (plt - got).  */
3186 	      if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3187 		{
3188 		  if (h->plt.offset == (bfd_vma) -1)
3189 		    {
3190 		      abort();
3191 		    }
3192 
3193 		  bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE;
3194 		  off = plt_index * GOT_ENTRY_SIZE;
3195 
3196 		  if (htab->elf.splt != NULL)
3197 		    {
3198 		      /* Section .plt header is 2 times of plt entry.  */
3199 		      off = sec_addr (htab->elf.sgotplt) + off
3200 			- sec_addr (htab->elf.sgot);
3201 		    }
3202 		  else
3203 		    {
3204 		      /* Section iplt not has plt header.  */
3205 		      off = sec_addr (htab->elf.igotplt) + off
3206 			- sec_addr (htab->elf.sgot);
3207 		    }
3208 		}
3209 
3210 	      if ((h->got.offset & 1) == 0)
3211 		{
3212 		  if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
3213 							bfd_link_pic (info), h)
3214 		      && ((bfd_link_pic (info)
3215 			   && SYMBOL_REFERENCES_LOCAL (info, h))))
3216 		    {
3217 		      /* This is actually a static link, or it is a
3218 			 -Bsymbolic link and the symbol is defined
3219 			 locally, or the symbol was forced to be local
3220 			 because of a version file.  We must initialize
3221 			 this entry in the global offset table.  Since the
3222 			 offset must always be a multiple of the word size,
3223 			 we use the least significant bit to record whether
3224 			 we have initialized it already.
3225 
3226 			 When doing a dynamic link, we create a rela.got
3227 			 relocation entry to initialize the value.  This
3228 			 is done in the finish_dynamic_symbol routine.  */
3229 
3230 		      if (resolved_dynly)
3231 			{
3232 			  fatal = (loongarch_reloc_is_fatal
3233 				   (info, input_bfd, input_section, rel, howto,
3234 				    bfd_reloc_dangerous, is_undefweak, name,
3235 				    "Internal: here shouldn't dynamic."));
3236 			}
3237 
3238 		      if (!(defined_local || resolved_to_const))
3239 			{
3240 			  fatal = (loongarch_reloc_is_fatal
3241 				   (info, input_bfd, input_section, rel, howto,
3242 				    bfd_reloc_undefined, is_undefweak, name,
3243 				    "Internal: "));
3244 			  break;
3245 			}
3246 
3247 		      asection *s;
3248 		      Elf_Internal_Rela outrel;
3249 		      /* We need to generate a R_LARCH_RELATIVE reloc
3250 			 for the dynamic linker.  */
3251 		      s = htab->elf.srelgot;
3252 		      if (!s)
3253 			{
3254 			  fatal = loongarch_reloc_is_fatal
3255 			    (info, input_bfd,
3256 			     input_section, rel, howto,
3257 			     bfd_reloc_notsupported, is_undefweak, name,
3258 			     "Internal: '.rel.got' not represent");
3259 			  break;
3260 			}
3261 
3262 		      outrel.r_offset = sec_addr (got) + off;
3263 		      outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3264 		      outrel.r_addend = relocation; /* Link-time addr.  */
3265 		      loongarch_elf_append_rela (output_bfd, s, &outrel);
3266 		    }
3267 		  bfd_put_NN (output_bfd, relocation, got->contents + off);
3268 		  h->got.offset |= 1;
3269 		}
3270 	    }
3271 	  else
3272 	    {
3273 	      if (!local_got_offsets)
3274 		{
3275 		  fatal = (loongarch_reloc_is_fatal
3276 			   (info, input_bfd, input_section, rel, howto,
3277 			    bfd_reloc_notsupported, is_undefweak, name,
3278 			    "Internal: local got offsets not reporesent."));
3279 		  break;
3280 		}
3281 
3282 	      off = local_got_offsets[r_symndx] & (~1);
3283 
3284 	      if (local_got_offsets[r_symndx] == MINUS_ONE)
3285 		{
3286 		  fatal = (loongarch_reloc_is_fatal
3287 			   (info, input_bfd, input_section, rel, howto,
3288 			    bfd_reloc_notsupported, is_undefweak, name,
3289 			    "Internal: GOT entry doesn't represent."));
3290 		  break;
3291 		}
3292 
3293 	      /* The offset must always be a multiple of the word size.
3294 		 So, we can use the least significant bit to record
3295 		 whether we have already processed this entry.  */
3296 	      if ((local_got_offsets[r_symndx] & 1) == 0)
3297 		{
3298 		  if (is_pic)
3299 		    {
3300 		      asection *s;
3301 		      Elf_Internal_Rela outrel;
3302 		      /* We need to generate a R_LARCH_RELATIVE reloc
3303 			 for the dynamic linker.  */
3304 		      s = htab->elf.srelgot;
3305 		      if (!s)
3306 			{
3307 			  fatal = (loongarch_reloc_is_fatal
3308 				   (info, input_bfd, input_section, rel, howto,
3309 				    bfd_reloc_notsupported, is_undefweak, name,
3310 				    "Internal: '.rel.got' not represent"));
3311 			  break;
3312 			}
3313 
3314 		      outrel.r_offset = sec_addr (got) + off;
3315 		      outrel.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3316 		      outrel.r_addend = relocation; /* Link-time addr.  */
3317 		      loongarch_elf_append_rela (output_bfd, s, &outrel);
3318 		    }
3319 
3320 		  bfd_put_NN (output_bfd, relocation, got->contents + off);
3321 		  local_got_offsets[r_symndx] |= 1;
3322 		}
3323 	    }
3324 	  relocation = off;
3325 
3326 	  break;
3327 
3328 	case R_LARCH_SOP_PUSH_TLS_GOT:
3329 	case R_LARCH_SOP_PUSH_TLS_GD:
3330 	  {
3331 	    unresolved_reloc = false;
3332 	    if (r_type == R_LARCH_SOP_PUSH_TLS_GOT)
3333 	      is_ie = true;
3334 
3335 	    bfd_vma got_off = 0;
3336 	    if (h != NULL)
3337 	      {
3338 		got_off = h->got.offset;
3339 		h->got.offset |= 1;
3340 	      }
3341 	    else
3342 	      {
3343 		got_off = local_got_offsets[r_symndx];
3344 		local_got_offsets[r_symndx] |= 1;
3345 	      }
3346 
3347 	    BFD_ASSERT (got_off != MINUS_ONE);
3348 
3349 	    ie_off = 0;
3350 	    tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3351 	    if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
3352 	      ie_off = 2 * GOT_ENTRY_SIZE;
3353 
3354 	    if ((got_off & 1) == 0)
3355 	      {
3356 		Elf_Internal_Rela rela;
3357 		asection *srel = htab->elf.srelgot;
3358 		bfd_vma tls_block_off = 0;
3359 
3360 		if (SYMBOL_REFERENCES_LOCAL (info, h))
3361 		  {
3362 		    BFD_ASSERT (elf_hash_table (info)->tls_sec);
3363 		    tls_block_off = relocation
3364 			- elf_hash_table (info)->tls_sec->vma;
3365 		  }
3366 
3367 		if (tls_type & GOT_TLS_GD)
3368 		  {
3369 		    rela.r_offset = sec_addr (got) + got_off;
3370 		    rela.r_addend = 0;
3371 		    if (SYMBOL_REFERENCES_LOCAL (info, h))
3372 		      {
3373 			/* Local sym, used in exec, set module id 1.  */
3374 			if (bfd_link_executable (info))
3375 			  bfd_put_NN (output_bfd, 1, got->contents + got_off);
3376 			else
3377 			  {
3378 			    rela.r_info = ELFNN_R_INFO (0,
3379 							R_LARCH_TLS_DTPMODNN);
3380 			    loongarch_elf_append_rela (output_bfd, srel, &rela);
3381 			  }
3382 
3383 			bfd_put_NN (output_bfd, tls_block_off,
3384 				    got->contents + got_off + GOT_ENTRY_SIZE);
3385 		      }
3386 		    /* Dynamic resolved.  */
3387 		    else
3388 		      {
3389 			/* Dynamic relocate module id.  */
3390 			rela.r_info = ELFNN_R_INFO (h->dynindx,
3391 						    R_LARCH_TLS_DTPMODNN);
3392 			loongarch_elf_append_rela (output_bfd, srel, &rela);
3393 
3394 			/* Dynamic relocate offset of block.  */
3395 			rela.r_offset += GOT_ENTRY_SIZE;
3396 			rela.r_info = ELFNN_R_INFO (h->dynindx,
3397 						    R_LARCH_TLS_DTPRELNN);
3398 			loongarch_elf_append_rela (output_bfd, srel, &rela);
3399 		      }
3400 		  }
3401 		if (tls_type & GOT_TLS_IE)
3402 		  {
3403 		    rela.r_offset = sec_addr (got) + got_off + ie_off;
3404 		    if (SYMBOL_REFERENCES_LOCAL (info, h))
3405 		      {
3406 			/* Local sym, used in exec, set module id 1.  */
3407 			if (!bfd_link_executable (info))
3408 			  {
3409 			    rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
3410 			    rela.r_addend = tls_block_off;
3411 			    loongarch_elf_append_rela (output_bfd, srel, &rela);
3412 			  }
3413 
3414 			bfd_put_NN (output_bfd, tls_block_off,
3415 				    got->contents + got_off + ie_off);
3416 		      }
3417 		    /* Dynamic resolved.  */
3418 		    else
3419 		      {
3420 			/* Dynamic relocate offset of block.  */
3421 			rela.r_info = ELFNN_R_INFO (h->dynindx,
3422 						    R_LARCH_TLS_TPRELNN);
3423 			rela.r_addend = 0;
3424 			loongarch_elf_append_rela (output_bfd, srel, &rela);
3425 		      }
3426 		  }
3427 	      }
3428 
3429 	    relocation = (got_off & (~(bfd_vma)1)) + (is_ie ? ie_off : 0);
3430 	  }
3431 	  break;
3432 
3433 	/* New reloc types.  */
3434 	case R_LARCH_B16:
3435 	case R_LARCH_B21:
3436 	case R_LARCH_B26:
3437 	case R_LARCH_CALL36:
3438 	  unresolved_reloc = false;
3439 	  if (is_undefweak)
3440 	    {
3441 	      relocation = 0;
3442 	    }
3443 
3444 	  if (resolved_local)
3445 	    {
3446 	      relocation -= pc;
3447 	      relocation += rel->r_addend;
3448 	    }
3449 	  else if (resolved_dynly)
3450 	    {
3451 	      BFD_ASSERT (h
3452 			  && (h->plt.offset != MINUS_ONE
3453 			      || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
3454 			  && rel->r_addend == 0);
3455 	      if (h && h->plt.offset == MINUS_ONE
3456 		  && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
3457 		{
3458 		  relocation -= pc;
3459 		  relocation += rel->r_addend;
3460 		}
3461 	      else
3462 		relocation = sec_addr (plt) + h->plt.offset - pc;
3463 	    }
3464 
3465 	  break;
3466 
3467 	case R_LARCH_ABS_HI20:
3468 	case R_LARCH_ABS_LO12:
3469 	case R_LARCH_ABS64_LO20:
3470 	case R_LARCH_ABS64_HI12:
3471 	  BFD_ASSERT (!is_pic);
3472 
3473 	  if (is_undefweak)
3474 	    {
3475 	      BFD_ASSERT (resolved_dynly);
3476 	      relocation = 0;
3477 	      break;
3478 	    }
3479 	  else if (resolved_to_const || resolved_local)
3480 	    {
3481 	      relocation += rel->r_addend;
3482 	    }
3483 	  else if (resolved_dynly)
3484 	    {
3485 	      unresolved_reloc = false;
3486 	      BFD_ASSERT ((plt && h && h->plt.offset != MINUS_ONE)
3487 			  && rel->r_addend == 0);
3488 	      relocation = sec_addr (plt) + h->plt.offset;
3489 	    }
3490 
3491 	  break;
3492 
3493 	case R_LARCH_PCREL20_S2:
3494 	  unresolved_reloc = false;
3495 	  if (h && h->plt.offset != MINUS_ONE)
3496 	    relocation = sec_addr (plt) + h->plt.offset;
3497 	  else
3498 	    relocation += rel->r_addend;
3499 	  relocation -= pc;
3500 	  break;
3501 
3502 	case R_LARCH_PCALA_HI20:
3503 	  unresolved_reloc = false;
3504 	  if (h && h->plt.offset != MINUS_ONE)
3505 	    relocation = sec_addr (plt) + h->plt.offset;
3506 	  else
3507 	    relocation += rel->r_addend;
3508 
3509 	  RELOCATE_CALC_PC32_HI20 (relocation, pc);
3510 	  break;
3511 
3512 	case R_LARCH_TLS_LE_HI20_R:
3513 	  relocation += rel->r_addend;
3514 	  relocation -= elf_hash_table (info)->tls_sec->vma;
3515 	  RELOCATE_TLS_TP32_HI20 (relocation);
3516 	  break;
3517 
3518 	case R_LARCH_PCALA_LO12:
3519 	  /* Not support if sym_addr in 2k page edge.
3520 	     pcalau12i pc_hi20 (sym_addr)
3521 	     ld.w/d pc_lo12 (sym_addr)
3522 	     ld.w/d pc_lo12 (sym_addr + x)
3523 	     ...
3524 	     can not calc correct address
3525 	     if sym_addr < 0x800 && sym_addr + x >= 0x800.  */
3526 
3527 	  if (h && h->plt.offset != MINUS_ONE)
3528 	    relocation = sec_addr (plt) + h->plt.offset;
3529 	  else
3530 	    relocation += rel->r_addend;
3531 
3532 	  /* For 2G jump, generate pcalau12i, jirl.  */
3533 	  /* If use jirl, turns to R_LARCH_B16.  */
3534 	  uint32_t insn = bfd_get (32, input_bfd, contents + rel->r_offset);
3535 	  if ((insn & 0x4c000000) == 0x4c000000)
3536 	    {
3537 	      relocation &= 0xfff;
3538 	      /* Signed extend.  */
3539 	      relocation = (relocation ^ 0x800) - 0x800;
3540 
3541 	      rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_B16);
3542 	      howto = loongarch_elf_rtype_to_howto (input_bfd, R_LARCH_B16);
3543 	    }
3544 	  break;
3545 
3546 	case R_LARCH_PCALA64_HI12:
3547 	  pc -= 4;
3548 	  /* Fall through.  */
3549 	case R_LARCH_PCALA64_LO20:
3550 	  if (h && h->plt.offset != MINUS_ONE)
3551 	    relocation = sec_addr (plt) + h->plt.offset;
3552 	  else
3553 	    relocation += rel->r_addend;
3554 
3555 	  RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
3556 
3557 	  break;
3558 
3559 	case R_LARCH_GOT_PC_HI20:
3560 	case R_LARCH_GOT_HI20:
3561 	  /* Calc got offset.  */
3562 	    {
3563 	      unresolved_reloc = false;
3564 	      BFD_ASSERT (rel->r_addend == 0);
3565 
3566 	      bfd_vma got_off = 0;
3567 	      if (h != NULL)
3568 		{
3569 		  /* GOT ref or ifunc.  */
3570 		  BFD_ASSERT (h->got.offset != MINUS_ONE
3571 			      || h->type == STT_GNU_IFUNC);
3572 
3573 		  got_off = h->got.offset  & (~(bfd_vma)1);
3574 		  /* Hidden symbol not has got entry,
3575 		   * only got.plt entry so it is (plt - got).  */
3576 		  if (h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3577 		    {
3578 		      bfd_vma idx;
3579 		      if (htab->elf.splt != NULL)
3580 			{
3581 			  idx = (h->plt.offset - PLT_HEADER_SIZE)
3582 			    / PLT_ENTRY_SIZE;
3583 			  got_off = sec_addr (htab->elf.sgotplt)
3584 			    + GOTPLT_HEADER_SIZE
3585 			    + (idx * GOT_ENTRY_SIZE)
3586 			    - sec_addr (htab->elf.sgot);
3587 			}
3588 		      else
3589 			{
3590 			  idx = h->plt.offset / PLT_ENTRY_SIZE;
3591 			  got_off = sec_addr (htab->elf.sgotplt)
3592 			    + (idx * GOT_ENTRY_SIZE)
3593 			    - sec_addr (htab->elf.sgot);
3594 			}
3595 		    }
3596 
3597 		  if ((h->got.offset & 1) == 0)
3598 		    {
3599 		      /* We need to generate a R_LARCH_RELATIVE reloc once
3600 		       * in loongarch_elf_finish_dynamic_symbol or now,
3601 		       * call finish_dyn && nopic
3602 		       * or !call finish_dyn && pic.  */
3603 		      if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
3604 							    bfd_link_pic (info),
3605 							    h)
3606 			  && bfd_link_pic (info)
3607 			  && SYMBOL_REFERENCES_LOCAL (info, h))
3608 			{
3609 			  Elf_Internal_Rela rela;
3610 			  rela.r_offset = sec_addr (got) + got_off;
3611 			  rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3612 			  rela.r_addend = relocation;
3613 			  loongarch_elf_append_rela (output_bfd,
3614 						     htab->elf.srelgot, &rela);
3615 			}
3616 		      h->got.offset |= 1;
3617 		      bfd_put_NN (output_bfd, relocation,
3618 				  got->contents + got_off);
3619 		    }
3620 		}
3621 	      else
3622 		{
3623 		  BFD_ASSERT (local_got_offsets
3624 			      && local_got_offsets[r_symndx] != MINUS_ONE);
3625 
3626 		  got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
3627 		  if ((local_got_offsets[r_symndx] & 1) == 0)
3628 		    {
3629 		      if (bfd_link_pic (info))
3630 			{
3631 			  Elf_Internal_Rela rela;
3632 			  rela.r_offset = sec_addr (got) + got_off;
3633 			  rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
3634 			  rela.r_addend = relocation;
3635 			  loongarch_elf_append_rela (output_bfd,
3636 						     htab->elf.srelgot, &rela);
3637 			}
3638 		      local_got_offsets[r_symndx] |= 1;
3639 		    }
3640 		  bfd_put_NN (output_bfd, relocation, got->contents + got_off);
3641 		}
3642 
3643 	      relocation = got_off + sec_addr (got);
3644 	    }
3645 
3646 	  if (r_type == R_LARCH_GOT_PC_HI20)
3647 	    RELOCATE_CALC_PC32_HI20 (relocation, pc);
3648 
3649 	  break;
3650 
3651 	case R_LARCH_GOT_PC_LO12:
3652 	case R_LARCH_GOT64_PC_LO20:
3653 	case R_LARCH_GOT64_PC_HI12:
3654 	case R_LARCH_GOT_LO12:
3655 	case R_LARCH_GOT64_LO20:
3656 	case R_LARCH_GOT64_HI12:
3657 	    {
3658 	      unresolved_reloc = false;
3659 	      bfd_vma got_off;
3660 	      if (h)
3661 		got_off = h->got.offset & (~(bfd_vma)1);
3662 	      else
3663 		got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
3664 
3665 	      if (h && h->got.offset == MINUS_ONE && h->type == STT_GNU_IFUNC)
3666 		{
3667 		  bfd_vma idx;
3668 		  if (htab->elf.splt != NULL)
3669 		    idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
3670 		  else
3671 		    idx = h->plt.offset / PLT_ENTRY_SIZE;
3672 
3673 		  got_off = sec_addr (htab->elf.sgotplt)
3674 		    + GOTPLT_HEADER_SIZE
3675 		    + (idx * GOT_ENTRY_SIZE)
3676 		    - sec_addr (htab->elf.sgot);
3677 		}
3678 
3679 	      relocation = got_off + sec_addr (got);
3680 	    }
3681 
3682 	  if (r_type == R_LARCH_GOT64_PC_HI12)
3683 	    RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
3684 	  else if (r_type == R_LARCH_GOT64_PC_LO20)
3685 	    RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
3686 
3687 	  break;
3688 
3689 	case R_LARCH_TLS_LE_HI20:
3690 	case R_LARCH_TLS_LE_LO12:
3691 	case R_LARCH_TLS_LE_LO12_R:
3692 	case R_LARCH_TLS_LE64_LO20:
3693 	case R_LARCH_TLS_LE64_HI12:
3694 	  BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec);
3695 
3696 	  relocation += rel->r_addend;
3697 	  relocation -= elf_hash_table (info)->tls_sec->vma;
3698 	  break;
3699 
3700 	/* TLS IE LD/GD process separately is troublesome.
3701 	   When a symbol is both ie and LD/GD, h->got.off |= 1
3702 	   make only one type be relocated.  We must use
3703 	   h->got.offset |= 1 and h->got.offset |= 2
3704 	   diff IE and LD/GD.  And all (got_off & (~(bfd_vma)1))
3705 	   (IE LD/GD and reusable GOT reloc) must change to
3706 	   (got_off & (~(bfd_vma)3)), beause we use lowest 2 bits
3707 	   as a tag.
3708 	   Now, LD and GD is both GOT_TLS_GD type, LD seems to
3709 	   can be omitted.  */
3710 	case R_LARCH_TLS_IE_PC_HI20:
3711 	case R_LARCH_TLS_IE_HI20:
3712 	case R_LARCH_TLS_LD_PC_HI20:
3713 	case R_LARCH_TLS_LD_HI20:
3714 	case R_LARCH_TLS_GD_PC_HI20:
3715 	case R_LARCH_TLS_GD_HI20:
3716 	case R_LARCH_TLS_DESC_PC_HI20:
3717 	case R_LARCH_TLS_DESC_HI20:
3718 	case R_LARCH_TLS_LD_PCREL20_S2:
3719 	case R_LARCH_TLS_GD_PCREL20_S2:
3720 	case R_LARCH_TLS_DESC_PCREL20_S2:
3721 	  BFD_ASSERT (rel->r_addend == 0);
3722 	  unresolved_reloc = false;
3723 
3724 	  if (r_type == R_LARCH_TLS_IE_PC_HI20
3725 	      || r_type == R_LARCH_TLS_IE_HI20)
3726 	    is_ie = true;
3727 
3728 	  if (r_type == R_LARCH_TLS_DESC_PC_HI20
3729 	      || r_type == R_LARCH_TLS_DESC_HI20
3730 	      || r_type == R_LARCH_TLS_DESC_PCREL20_S2)
3731 	    is_desc = true;
3732 
3733 	  bfd_vma got_off = 0;
3734 	  if (h != NULL)
3735 	    {
3736 	      got_off = h->got.offset;
3737 	      h->got.offset |= 1;
3738 	    }
3739 	  else
3740 	    {
3741 	      got_off = local_got_offsets[r_symndx];
3742 	      local_got_offsets[r_symndx] |= 1;
3743 	    }
3744 
3745 	  BFD_ASSERT (got_off != MINUS_ONE);
3746 
3747 	  tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3748 
3749 	  /* If a tls variable is accessed in multiple ways, GD uses
3750 	     the first two slots of GOT, desc follows with two slots,
3751 	     and IE uses one slot at the end.  */
3752 	  desc_off = 0;
3753 	  if (GOT_TLS_GD_BOTH_P (tls_type))
3754 	    desc_off = 2 * GOT_ENTRY_SIZE;
3755 
3756 	  ie_off = 0;
3757 	  if (GOT_TLS_GD_BOTH_P (tls_type) && (tls_type & GOT_TLS_IE))
3758 	    ie_off = 4 * GOT_ENTRY_SIZE;
3759 	  else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
3760 	    ie_off = 2 * GOT_ENTRY_SIZE;
3761 
3762 	  if ((got_off & 1) == 0)
3763 	    {
3764 	      Elf_Internal_Rela rela;
3765 	      asection *relgot = htab->elf.srelgot;
3766 	      bfd_vma tls_block_off = 0;
3767 
3768 	      if (SYMBOL_REFERENCES_LOCAL (info, h))
3769 		{
3770 		  BFD_ASSERT (elf_hash_table (info)->tls_sec);
3771 		  tls_block_off = relocation
3772 		      - elf_hash_table (info)->tls_sec->vma;
3773 		}
3774 
3775 	      if (tls_type & GOT_TLS_GD)
3776 		{
3777 		  rela.r_offset = sec_addr (got) + got_off;
3778 		  rela.r_addend = 0;
3779 		  if (SYMBOL_REFERENCES_LOCAL (info, h))
3780 		    {
3781 		      /* Local sym, used in exec, set module id 1.  */
3782 		      if (bfd_link_executable (info))
3783 			bfd_put_NN (output_bfd, 1, got->contents + got_off);
3784 		      else
3785 			{
3786 			  rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_DTPMODNN);
3787 			  loongarch_elf_append_rela (output_bfd, relgot, &rela);
3788 			}
3789 
3790 		      bfd_put_NN (output_bfd, tls_block_off,
3791 				  got->contents + got_off + GOT_ENTRY_SIZE);
3792 		    }
3793 		  /* Dynamic resolved.  */
3794 		  else
3795 		    {
3796 		      /* Dynamic relocate module id.  */
3797 		      rela.r_info = ELFNN_R_INFO (h->dynindx,
3798 						  R_LARCH_TLS_DTPMODNN);
3799 		      loongarch_elf_append_rela (output_bfd, relgot, &rela);
3800 
3801 		      /* Dynamic relocate offset of block.  */
3802 		      rela.r_offset += GOT_ENTRY_SIZE;
3803 		      rela.r_info = ELFNN_R_INFO (h->dynindx,
3804 						  R_LARCH_TLS_DTPRELNN);
3805 		      loongarch_elf_append_rela (output_bfd, relgot, &rela);
3806 		    }
3807 		}
3808 	      if (tls_type & GOT_TLS_GDESC)
3809 		{
3810 		  /* Unless it is a static link, DESC always emits a
3811 		     dynamic relocation.  */
3812 		  int indx = h && h->dynindx != -1 ? h->dynindx : 0;
3813 		  rela.r_offset = sec_addr (got) + got_off + desc_off;
3814 		  rela.r_addend = 0;
3815 		  if (indx == 0)
3816 		    rela.r_addend = relocation - elf_hash_table (info)->tls_sec->vma;
3817 
3818 		  rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_DESCNN);
3819 		  loongarch_elf_append_rela (output_bfd, relgot, &rela);
3820 		  bfd_put_NN (output_bfd, 0,
3821 			      got->contents + got_off + desc_off);
3822 		}
3823 	      if (tls_type & GOT_TLS_IE)
3824 		{
3825 		  rela.r_offset = sec_addr (got) + got_off + ie_off;
3826 		  if (SYMBOL_REFERENCES_LOCAL (info, h))
3827 		    {
3828 		      /* Local sym, used in exec, set module id 1.  */
3829 		      if (!bfd_link_executable (info))
3830 			{
3831 			  rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
3832 			  rela.r_addend = tls_block_off;
3833 			  loongarch_elf_append_rela (output_bfd, relgot, &rela);
3834 			}
3835 
3836 		      bfd_put_NN (output_bfd, tls_block_off,
3837 				  got->contents + got_off + ie_off);
3838 		    }
3839 		  /* Dynamic resolved.  */
3840 		  else
3841 		    {
3842 		      /* Dynamic relocate offset of block.  */
3843 		      rela.r_info = ELFNN_R_INFO (h->dynindx,
3844 						  R_LARCH_TLS_TPRELNN);
3845 		      rela.r_addend = 0;
3846 		      loongarch_elf_append_rela (output_bfd, relgot, &rela);
3847 		    }
3848 		}
3849 	    }
3850 	  relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got);
3851 	  if (is_desc)
3852 	    relocation += desc_off;
3853 	  else if (is_ie)
3854 	    relocation += ie_off;
3855 
3856 	  if (r_type == R_LARCH_TLS_LD_PC_HI20
3857 	      || r_type == R_LARCH_TLS_GD_PC_HI20
3858 	      || r_type == R_LARCH_TLS_IE_PC_HI20
3859 	      || r_type == R_LARCH_TLS_DESC_PC_HI20)
3860 	    RELOCATE_CALC_PC32_HI20 (relocation, pc);
3861 	  else if (r_type == R_LARCH_TLS_LD_PCREL20_S2
3862 	      || r_type == R_LARCH_TLS_GD_PCREL20_S2
3863 	      || r_type == R_LARCH_TLS_DESC_PCREL20_S2)
3864 	    relocation -= pc;
3865 	  /* else {} ABS relocations.  */
3866 	  break;
3867 
3868 	case R_LARCH_TLS_DESC_PC_LO12:
3869 	case R_LARCH_TLS_DESC64_PC_LO20:
3870 	case R_LARCH_TLS_DESC64_PC_HI12:
3871 	case R_LARCH_TLS_DESC_LO12:
3872 	case R_LARCH_TLS_DESC64_LO20:
3873 	case R_LARCH_TLS_DESC64_HI12:
3874 	  {
3875 	    unresolved_reloc = false;
3876 
3877 	    if (h)
3878 	      relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1));
3879 	    else
3880 	      relocation = sec_addr (got)
3881 			   + (local_got_offsets[r_symndx] & (~(bfd_vma)1));
3882 
3883 	    tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3884 	    /* Use both TLS_GD and TLS_DESC.  */
3885 	    if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC))
3886 	      relocation += 2 * GOT_ENTRY_SIZE;
3887 
3888 	    if (r_type == R_LARCH_TLS_DESC64_PC_LO20)
3889 	      RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
3890 	    else if (r_type == R_LARCH_TLS_DESC64_PC_HI12)
3891 	      RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
3892 
3893 	    break;
3894 	  }
3895 
3896 	case R_LARCH_TLS_DESC_LD:
3897 	case R_LARCH_TLS_DESC_CALL:
3898 	  unresolved_reloc = false;
3899 	  break;
3900 
3901 	case R_LARCH_TLS_IE_PC_LO12:
3902 	case R_LARCH_TLS_IE64_PC_LO20:
3903 	case R_LARCH_TLS_IE64_PC_HI12:
3904 	case R_LARCH_TLS_IE_LO12:
3905 	case R_LARCH_TLS_IE64_LO20:
3906 	case R_LARCH_TLS_IE64_HI12:
3907 	  unresolved_reloc = false;
3908 
3909 	  if (h)
3910 	    relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1));
3911 	  else
3912 	    relocation = sec_addr (got)
3913 	      + (local_got_offsets[r_symndx] & (~(bfd_vma)1));
3914 
3915 	  tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
3916 	  /* Use TLS_GD TLS_DESC and TLS_IE.  */
3917 	  if (GOT_TLS_GD_BOTH_P (tls_type) && (tls_type & GOT_TLS_IE))
3918 	    relocation += 4 * GOT_ENTRY_SIZE;
3919 	  /* Use GOT_TLS_GD_ANY_P (tls_type) and TLS_IE.  */
3920 	  else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
3921 	    relocation += 2 * GOT_ENTRY_SIZE;
3922 
3923 	  if (r_type == R_LARCH_TLS_IE64_PC_LO20)
3924 	    RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
3925 	  else if (r_type == R_LARCH_TLS_IE64_PC_HI12)
3926 	    RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
3927 
3928 	  break;
3929 
3930 	case R_LARCH_RELAX:
3931 	case R_LARCH_ALIGN:
3932 	  r = bfd_reloc_continue;
3933 	  unresolved_reloc = false;
3934 	  break;
3935 
3936 	default:
3937 	  break;
3938 	}
3939 
3940       if (fatal)
3941 	break;
3942 
3943       do
3944 	{
3945 	  /* 'unresolved_reloc' means we haven't done it yet.
3946 	     We need help of dynamic linker to fix this memory location up.  */
3947 	  if (!unresolved_reloc)
3948 	    break;
3949 
3950 	  if (_bfd_elf_section_offset (output_bfd, info, input_section,
3951 				       rel->r_offset) == MINUS_ONE)
3952 	    /* WHY? May because it's invalid so skip checking.
3953 	       But why dynamic reloc a invalid section?  */
3954 	    break;
3955 
3956 	  if (input_section->output_section->flags & SEC_DEBUGGING)
3957 	    {
3958 	      fatal = (loongarch_reloc_is_fatal
3959 		       (info, input_bfd, input_section, rel, howto,
3960 			bfd_reloc_dangerous, is_undefweak, name,
3961 			"Seems dynamic linker not process "
3962 			"sections 'SEC_DEBUGGING'."));
3963 	    }
3964 	  if (!is_dyn)
3965 	    break;
3966 
3967 	  if ((info->flags & DF_TEXTREL) == 0)
3968 	    if (input_section->output_section->flags & SEC_READONLY)
3969 	      info->flags |= DF_TEXTREL;
3970 	}
3971       while (0);
3972 
3973       if (fatal)
3974 	break;
3975 
3976       loongarch_record_one_reloc (input_bfd, input_section, r_type,
3977 				  rel->r_offset, sym, h, rel->r_addend);
3978 
3979       if (r != bfd_reloc_continue)
3980 	r = perform_relocation (rel, input_section, howto, relocation,
3981 				input_bfd, contents);
3982 
3983       switch (r)
3984 	{
3985 	case bfd_reloc_dangerous:
3986 	case bfd_reloc_continue:
3987 	case bfd_reloc_ok:
3988 	  continue;
3989 
3990 	case bfd_reloc_overflow:
3991 	  /* Overflow value can't be filled in.  */
3992 	  loongarch_dump_reloc_record (info->callbacks->info);
3993 	  info->callbacks->reloc_overflow
3994 	    (info, h ? &h->root : NULL, name, howto->name, rel->r_addend,
3995 	     input_bfd, input_section, rel->r_offset);
3996 	  break;
3997 
3998 	case bfd_reloc_outofrange:
3999 	  /* Stack state incorrect.  */
4000 	  loongarch_dump_reloc_record (info->callbacks->info);
4001 	  info->callbacks->info
4002 	    ("%X%H: Internal stack state is incorrect.\n"
4003 	     "Want to push to full stack or pop from empty stack?\n",
4004 	     input_bfd, input_section, rel->r_offset);
4005 	  break;
4006 
4007 	case bfd_reloc_notsupported:
4008 	  info->callbacks->info ("%X%H: Unknown relocation type.\n", input_bfd,
4009 				 input_section, rel->r_offset);
4010 	  break;
4011 
4012 	default:
4013 	  info->callbacks->info ("%X%H: Internal: unknown error.\n", input_bfd,
4014 				 input_section, rel->r_offset);
4015 	  break;
4016 	}
4017 
4018       fatal = true;
4019     }
4020 
4021   return !fatal;
4022 }
4023 
4024 static bool
loongarch_relax_delete_bytes(bfd * abfd,asection * sec,bfd_vma addr,size_t count,struct bfd_link_info * link_info)4025 loongarch_relax_delete_bytes (bfd *abfd,
4026 			  asection *sec,
4027 			  bfd_vma addr,
4028 			  size_t count,
4029 			  struct bfd_link_info *link_info)
4030 {
4031   unsigned int i, symcount;
4032   bfd_vma toaddr = sec->size;
4033   struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd);
4034   Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
4035   unsigned int sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
4036   struct bfd_elf_section_data *data = elf_section_data (sec);
4037   bfd_byte *contents = data->this_hdr.contents;
4038 
4039   /* Actually delete the bytes.  */
4040   sec->size -= count;
4041   memmove (contents + addr, contents + addr + count, toaddr - addr - count);
4042 
4043   /* Adjust the location of all of the relocs.  Note that we need not
4044      adjust the addends, since all PC-relative references must be against
4045      symbols, which we will adjust below.  */
4046   for (i = 0; i < sec->reloc_count; i++)
4047     if (data->relocs[i].r_offset > addr && data->relocs[i].r_offset < toaddr)
4048       data->relocs[i].r_offset -= count;
4049 
4050   /* Adjust the local symbols defined in this section.  */
4051   for (i = 0; i < symtab_hdr->sh_info; i++)
4052     {
4053       Elf_Internal_Sym *sym = (Elf_Internal_Sym *) symtab_hdr->contents + i;
4054       if (sym->st_shndx == sec_shndx)
4055 	{
4056 	  /* If the symbol is in the range of memory we just moved, we
4057 	     have to adjust its value.  */
4058 	  if (sym->st_value > addr && sym->st_value <= toaddr)
4059 	    sym->st_value -= count;
4060 
4061 	  /* If the symbol *spans* the bytes we just deleted (i.e. its
4062 	     *end* is in the moved bytes but its *start* isn't), then we
4063 	     must adjust its size.
4064 
4065 	     This test needs to use the original value of st_value, otherwise
4066 	     we might accidentally decrease size when deleting bytes right
4067 	     before the symbol.  But since deleted relocs can't span across
4068 	     symbols, we can't have both a st_value and a st_size decrease,
4069 	     so it is simpler to just use an else.  */
4070 	  else if (sym->st_value <= addr
4071 		   && sym->st_value + sym->st_size > addr
4072 		   && sym->st_value + sym->st_size <= toaddr)
4073 	    sym->st_size -= count;
4074 	}
4075     }
4076 
4077   /* Now adjust the global symbols defined in this section.  */
4078   symcount = ((symtab_hdr->sh_size / sizeof (ElfNN_External_Sym))
4079 	      - symtab_hdr->sh_info);
4080 
4081   for (i = 0; i < symcount; i++)
4082     {
4083       struct elf_link_hash_entry *sym_hash = sym_hashes[i];
4084 
4085       /* The '--wrap SYMBOL' option is causing a pain when the object file,
4086 	 containing the definition of __wrap_SYMBOL, includes a direct
4087 	 call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
4088 	 the same symbol (which is __wrap_SYMBOL), but still exist as two
4089 	 different symbols in 'sym_hashes', we don't want to adjust
4090 	 the global symbol __wrap_SYMBOL twice.
4091 
4092 	 The same problem occurs with symbols that are versioned_hidden, as
4093 	 foo becomes an alias for foo@BAR, and hence they need the same
4094 	 treatment.  */
4095       if (link_info->wrap_hash != NULL
4096 	  || sym_hash->versioned != unversioned)
4097 	{
4098 	  struct elf_link_hash_entry **cur_sym_hashes;
4099 
4100 	  /* Loop only over the symbols which have already been checked.  */
4101 	  for (cur_sym_hashes = sym_hashes; cur_sym_hashes < &sym_hashes[i];
4102 	       cur_sym_hashes++)
4103 	    {
4104 	      /* If the current symbol is identical to 'sym_hash', that means
4105 		 the symbol was already adjusted (or at least checked).  */
4106 	      if (*cur_sym_hashes == sym_hash)
4107 		break;
4108 	    }
4109 	  /* Don't adjust the symbol again.  */
4110 	  if (cur_sym_hashes < &sym_hashes[i])
4111 	    continue;
4112 	}
4113 
4114       if ((sym_hash->root.type == bfd_link_hash_defined
4115 	   || sym_hash->root.type == bfd_link_hash_defweak)
4116 	  && sym_hash->root.u.def.section == sec)
4117 	{
4118 	  /* As above, adjust the value if needed.  */
4119 	  if (sym_hash->root.u.def.value > addr
4120 	      && sym_hash->root.u.def.value <= toaddr)
4121 	    sym_hash->root.u.def.value -= count;
4122 
4123 	  /* As above, adjust the size if needed.  */
4124 	  else if (sym_hash->root.u.def.value <= addr
4125 		   && sym_hash->root.u.def.value + sym_hash->size > addr
4126 		   && sym_hash->root.u.def.value + sym_hash->size <= toaddr)
4127 	    sym_hash->size -= count;
4128 	}
4129     }
4130 
4131   return true;
4132 }
4133 /*  Relax tls le, mainly relax the process of getting TLS le symbolic addresses.
4134   there are three situations in which an assembly instruction sequence needs to
4135   be relaxed:
4136   symbol address = tp + offset (symbol),offset (symbol) = le_hi20_r + le_lo12_r
4137 
4138   Case 1:
4139   in this case, the rd register in the st.{w/d} instruction does not store the
4140   full tls symbolic address, but tp + le_hi20_r, which is a part of the tls
4141   symbolic address, and then obtains the rd + le_lo12_r address through the
4142   st.w instruction feature.
4143   this is the full tls symbolic address (tp + le_hi20_r + le_lo12_r).
4144 
4145   before relax:				after relax:
4146 
4147   lu12i.w   $rd,%le_hi20_r (sym)	==> (instruction deleted)
4148   add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4149   st.{w/d}  $rs,$rd,%le_lo12_r (sym)    ==> st.{w/d}   $rs,$tp,%le_lo12_r (sym)
4150 
4151   Case 2:
4152   in this case, ld.{w/d} is similar to st.{w/d} in case1.
4153 
4154   before relax:				after relax:
4155 
4156   lu12i.w   $rd,%le_hi20_r (sym)	==> (instruction deleted)
4157   add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4158   ld.{w/d}  $rs,$rd,%le_lo12_r (sym)    ==> ld.{w/d}   $rs,$tp,%le_lo12_r (sym)
4159 
4160   Case 3:
4161   in this case,the rs register in addi.{w/d} stores the full address of the tls
4162   symbol (tp + le_hi20_r + le_lo12_r).
4163 
4164   before relax:				after relax:
4165 
4166   lu12i.w    $rd,%le_hi20_r (sym)	 ==> (instruction deleted)
4167   add.{w/d}  $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
4168   addi.{w/d} $rs,$rd,%le_lo12_r (sym)    ==> addi.{w/d} $rs,$tp,%le_lo12_r (sym)
4169 */
4170 static bool
loongarch_relax_tls_le(bfd * abfd,asection * sec,Elf_Internal_Rela * rel,struct bfd_link_info * link_info,bfd_vma symval)4171 loongarch_relax_tls_le (bfd *abfd, asection *sec,
4172 			Elf_Internal_Rela *rel,
4173 			struct bfd_link_info *link_info,
4174 			bfd_vma symval)
4175 {
4176   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
4177   uint32_t insn = bfd_get (32, abfd, contents + rel->r_offset);
4178   static uint32_t insn_rj,insn_rd;
4179   symval = symval - elf_hash_table (link_info)->tls_sec->vma;
4180   /* Whether the symbol offset is in the interval (offset < 0x800).  */
4181   if (ELFNN_R_TYPE ((rel + 1)->r_info == R_LARCH_RELAX) && (symval < 0x800))
4182     {
4183       switch (ELFNN_R_TYPE (rel->r_info))
4184 	{
4185 	case R_LARCH_TLS_LE_HI20_R:
4186 	case R_LARCH_TLS_LE_ADD_R:
4187 	  /* delete insn.  */
4188 	  rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4189 	  loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, link_info);
4190 	  break;
4191 	case R_LARCH_TLS_LE_LO12_R:
4192 	  /* Change rj to $tp.  */
4193 	  insn_rj = 0x2 << 5;
4194 	  /* Get rd register.  */
4195 	  insn_rd = insn & 0x1f;
4196 	  /* Write symbol offset.  */
4197 	  symval <<= 10;
4198 	  /* Writes the modified instruction.  */
4199 	  insn = insn & 0xffc00000;
4200 	  insn = insn | symval | insn_rj | insn_rd;
4201 	  bfd_put (32, abfd, insn, contents + rel->r_offset);
4202 	  break;
4203 	default:
4204 	  break;
4205 	}
4206     }
4207   return true;
4208 }
4209 
4210 /* Relax pcalau12i,addi.d => pcaddi.  */
4211 static bool
loongarch_relax_pcala_addi(bfd * abfd,asection * sec,asection * sym_sec,Elf_Internal_Rela * rel_hi,bfd_vma symval,struct bfd_link_info * info,bool * again,bfd_vma max_alignment)4212 loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
4213 			    Elf_Internal_Rela *rel_hi, bfd_vma symval,
4214 			    struct bfd_link_info *info, bool *again,
4215 			    bfd_vma max_alignment)
4216 {
4217   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
4218   Elf_Internal_Rela *rel_lo = rel_hi + 2;
4219   uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
4220   uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset);
4221   uint32_t rd = pca & 0x1f;
4222 
4223   /* This section's output_offset need to subtract the bytes of instructions
4224      relaxed by the previous sections, so it needs to be updated beforehand.
4225      size_input_section already took care of updating it after relaxation,
4226      so we additionally update once here.  */
4227   sec->output_offset = sec->output_section->size;
4228   bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
4229 
4230   /* If pc and symbol not in the same segment, add/sub segment alignment.
4231      FIXME: if there are multiple readonly segments? How to determine if
4232      two sections are in the same segment.  */
4233   if (!(sym_sec->flags & SEC_READONLY))
4234     {
4235       max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
4236 							  : max_alignment;
4237       if (symval > pc)
4238 	pc -= max_alignment;
4239       else if (symval < pc)
4240 	pc += max_alignment;
4241     }
4242   else
4243     if (symval > pc)
4244       pc -= max_alignment;
4245     else if (symval < pc)
4246       pc += max_alignment;
4247 
4248   const uint32_t addi_d = 0x02c00000;
4249   const uint32_t pcaddi = 0x18000000;
4250 
4251   /* Is pcalau12i + addi.d insns?  */
4252   if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_PCALA_LO12)
4253       || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
4254       || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
4255       || (rel_hi->r_offset + 4 != rel_lo->r_offset)
4256       || ((add & addi_d) != addi_d)
4257       /* Is pcalau12i $rd + addi.d $rd,$rd?  */
4258       || ((add & 0x1f) != rd)
4259       || (((add >> 5) & 0x1f) != rd)
4260       /* Can be relaxed to pcaddi?  */
4261       || (symval & 0x3) /* 4 bytes align.  */
4262       || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000)
4263       || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc))
4264     return false;
4265 
4266   /* Continue next relax trip.  */
4267   *again = true;
4268 
4269   pca = pcaddi | rd;
4270   bfd_put (32, abfd, pca, contents + rel_hi->r_offset);
4271 
4272   /* Adjust relocations.  */
4273   rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4274 				 R_LARCH_PCREL20_S2);
4275   rel_lo->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4276 
4277   loongarch_relax_delete_bytes (abfd, sec, rel_lo->r_offset, 4, info);
4278 
4279   return true;
4280 }
4281 
4282 /* Relax pcalau12i,ld.d => pcalau12i,addi.d.  */
4283 static bool
loongarch_relax_pcala_ld(bfd * abfd,asection * sec,Elf_Internal_Rela * rel_hi)4284 loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
4285 		Elf_Internal_Rela *rel_hi)
4286 {
4287   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
4288   Elf_Internal_Rela *rel_lo = rel_hi + 2;
4289   uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
4290   uint32_t ld = bfd_get (32, abfd, contents + rel_lo->r_offset);
4291   uint32_t rd = pca & 0x1f;
4292   const uint32_t ld_d = 0x28c00000;
4293   uint32_t addi_d = 0x02c00000;
4294 
4295   if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12)
4296       || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
4297       || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
4298       || (rel_hi->r_offset + 4 != rel_lo->r_offset)
4299       || ((ld & 0x1f) != rd)
4300       || (((ld >> 5) & 0x1f) != rd)
4301       || ((ld & ld_d) != ld_d))
4302     return false;
4303 
4304   addi_d = addi_d | (rd << 5) | rd;
4305   bfd_put (32, abfd, addi_d, contents + rel_lo->r_offset);
4306 
4307   rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4308 				 R_LARCH_PCALA_HI20);
4309   rel_lo->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_lo->r_info),
4310 				 R_LARCH_PCALA_LO12);
4311   return true;
4312 }
4313 
4314 /* Called by after_allocation to set the information of data segment
4315    before relaxing.  */
4316 
4317 void
bfd_elfNN_loongarch_set_data_segment_info(struct bfd_link_info * info,int * data_segment_phase)4318 bfd_elfNN_loongarch_set_data_segment_info (struct bfd_link_info *info,
4319 				     int *data_segment_phase)
4320 {
4321   struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4322   htab->data_segment_phase = data_segment_phase;
4323 }
4324 
4325 /* Implement R_LARCH_ALIGN by deleting excess alignment NOPs.
4326    Once we've handled an R_LARCH_ALIGN, we can't relax anything else.  */
4327 static bool
loongarch_relax_align(bfd * abfd,asection * sec,asection * sym_sec,struct bfd_link_info * link_info,Elf_Internal_Rela * rel,bfd_vma symval)4328 loongarch_relax_align (bfd *abfd, asection *sec,
4329 			asection *sym_sec,
4330 			struct bfd_link_info *link_info,
4331 			Elf_Internal_Rela *rel,
4332 			bfd_vma symval)
4333 {
4334   bfd_vma  addend, max = 0, alignment = 1;
4335 
4336   int sym_index = ELFNN_R_SYM (rel->r_info);
4337   if (sym_index > 0)
4338     {
4339       alignment = 1 << (rel->r_addend & 0xff);
4340       max = rel->r_addend >> 8;
4341     }
4342   else
4343     alignment = rel->r_addend + 4;
4344 
4345   addend = alignment - 4; /* The bytes of NOPs added by R_LARCH_ALIGN.  */
4346   symval -= addend; /* The address of first NOP added by R_LARCH_ALIGN.  */
4347   bfd_vma aligned_addr = ((symval - 1) & ~(alignment - 1)) + alignment;
4348   bfd_vma need_nop_bytes = aligned_addr - symval; /* */
4349 
4350   /* Make sure there are enough NOPs to actually achieve the alignment.  */
4351   if (addend < need_nop_bytes)
4352     {
4353       _bfd_error_handler
4354 	(_("%pB(%pA+%#" PRIx64 "): %" PRId64 " bytes required for alignment "
4355 	   "to %" PRId64 "-byte boundary, but only %" PRId64 " present"),
4356 	 abfd, sym_sec, (uint64_t) rel->r_offset,
4357 	 (int64_t) need_nop_bytes, (int64_t) alignment, (int64_t) addend);
4358       bfd_set_error (bfd_error_bad_value);
4359       return false;
4360     }
4361 
4362   /* Once we've handled an R_LARCH_ALIGN in a section,
4363      we can't relax anything else in this section.  */
4364   sec->sec_flg0 = true;
4365   rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4366 
4367   /* If skipping more bytes than the specified maximum,
4368      then the alignment is not done at all and delete all NOPs.  */
4369   if (max > 0 && need_nop_bytes > max)
4370     return loongarch_relax_delete_bytes (abfd, sec, rel->r_offset,
4371 					  addend, link_info);
4372 
4373   /* If the number of NOPs is already correct, there's nothing to do.  */
4374   if (need_nop_bytes == addend)
4375     return true;
4376 
4377   /* Delete the excess NOPs.  */
4378   return loongarch_relax_delete_bytes (abfd, sec,
4379 					rel->r_offset + need_nop_bytes,
4380 					addend - need_nop_bytes, link_info);
4381 }
4382 
4383 /* Relax pcalau12i + addi.d of TLS LD/GD/DESC to pcaddi.  */
4384 static bool
loongarch_relax_tls_ld_gd_desc(bfd * abfd,asection * sec,asection * sym_sec,Elf_Internal_Rela * rel_hi,bfd_vma symval,struct bfd_link_info * info,bool * again,bfd_vma max_alignment)4385 loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
4386 				Elf_Internal_Rela *rel_hi, bfd_vma symval,
4387 				struct bfd_link_info *info, bool *again,
4388 				bfd_vma max_alignment)
4389 {
4390   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
4391   Elf_Internal_Rela *rel_lo = rel_hi + 2;
4392   uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
4393   uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset);
4394   uint32_t rd = pca & 0x1f;
4395 
4396   /* This section's output_offset need to subtract the bytes of instructions
4397      relaxed by the previous sections, so it needs to be updated beforehand.
4398      size_input_section already took care of updating it after relaxation,
4399      so we additionally update once here.  */
4400   sec->output_offset = sec->output_section->size;
4401   bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
4402 
4403   /* If pc and symbol not in the same segment, add/sub segment alignment.
4404      FIXME: if there are multiple readonly segments?  */
4405   if (!(sym_sec->flags & SEC_READONLY))
4406     {
4407       max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
4408 							  : max_alignment;
4409       if (symval > pc)
4410 	pc -= max_alignment;
4411       else if (symval < pc)
4412 	pc += max_alignment;
4413     }
4414   else
4415     if (symval > pc)
4416       pc -= max_alignment;
4417     else if (symval < pc)
4418       pc += max_alignment;
4419 
4420   const uint32_t addi_d = 0x02c00000;
4421   const uint32_t pcaddi = 0x18000000;
4422 
4423   /* Is pcalau12i + addi.d insns?  */
4424   if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12
4425 	&& ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_TLS_DESC_PC_LO12)
4426       || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
4427       || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
4428       || (rel_hi->r_offset + 4 != rel_lo->r_offset)
4429       || ((add & addi_d) != addi_d)
4430       /* Is pcalau12i $rd + addi.d $rd,$rd?  */
4431       || ((add & 0x1f) != rd)
4432       || (((add >> 5) & 0x1f) != rd)
4433       /* Can be relaxed to pcaddi?  */
4434       || (symval & 0x3) /* 4 bytes align.  */
4435       || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000)
4436       || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc))
4437     return false;
4438 
4439   /* Continue next relax trip.  */
4440   *again = true;
4441 
4442   pca = pcaddi | rd;
4443   bfd_put (32, abfd, pca, contents + rel_hi->r_offset);
4444 
4445   /* Adjust relocations.  */
4446   switch (ELFNN_R_TYPE (rel_hi->r_info))
4447     {
4448     case R_LARCH_TLS_LD_PC_HI20:
4449       rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4450 				      R_LARCH_TLS_LD_PCREL20_S2);
4451       break;
4452     case R_LARCH_TLS_GD_PC_HI20:
4453       rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4454 				      R_LARCH_TLS_GD_PCREL20_S2);
4455       break;
4456     case R_LARCH_TLS_DESC_PC_HI20:
4457       rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
4458 				      R_LARCH_TLS_DESC_PCREL20_S2);
4459       break;
4460     default:
4461       break;
4462     }
4463   rel_lo->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4464 
4465   loongarch_relax_delete_bytes (abfd, sec, rel_lo->r_offset, 4, info);
4466 
4467   return true;
4468 }
4469 
4470 /* Traverse all output sections and return the max alignment.  */
4471 
4472 static bfd_vma
loongarch_get_max_alignment(asection * sec)4473 loongarch_get_max_alignment (asection *sec)
4474 {
4475   asection *o;
4476   unsigned int max_alignment_power = 0;
4477 
4478   for (o = sec->output_section->owner->sections; o != NULL; o = o->next)
4479       if (o->alignment_power > max_alignment_power)
4480 	max_alignment_power = o->alignment_power;
4481 
4482   return (bfd_vma) 1 << max_alignment_power;
4483 }
4484 
4485 static bool
loongarch_elf_relax_section(bfd * abfd,asection * sec,struct bfd_link_info * info,bool * again)4486 loongarch_elf_relax_section (bfd *abfd, asection *sec,
4487 			       struct bfd_link_info *info,
4488 			       bool *again)
4489 {
4490   struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4491   struct bfd_elf_section_data *data = elf_section_data (sec);
4492   Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd);
4493   Elf_Internal_Rela *relocs;
4494   *again = false;
4495   bfd_vma max_alignment = 0;
4496 
4497   if (bfd_link_relocatable (info)
4498       || sec->sec_flg0
4499       || (sec->flags & SEC_RELOC) == 0
4500       || sec->reloc_count == 0
4501       || (info->disable_target_specific_optimizations
4502 	  && info->relax_pass == 0)
4503       /* The exp_seg_relro_adjust is enum phase_enum (0x4),
4504 	 and defined in ld/ldexp.h.  */
4505       || *(htab->data_segment_phase) == 4)
4506     return true;
4507 
4508   if (data->relocs)
4509     relocs = data->relocs;
4510   else if (!(relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
4511 						 info->keep_memory)))
4512     return true;
4513 
4514   if (!data->this_hdr.contents
4515       && !bfd_malloc_and_get_section (abfd, sec, &data->this_hdr.contents))
4516     return true;
4517 
4518   if (symtab_hdr->sh_info != 0
4519       && !symtab_hdr->contents
4520       && !(symtab_hdr->contents =
4521 	   (unsigned char *) bfd_elf_get_elf_syms (abfd, symtab_hdr,
4522 						   symtab_hdr->sh_info,
4523 						   0, NULL, NULL, NULL)))
4524     return true;
4525 
4526   data->relocs = relocs;
4527 
4528   /* Estimate the maximum alignment for all output sections once time
4529      should be enough.  */
4530   max_alignment = htab->max_alignment;
4531   if (max_alignment == (bfd_vma) -1)
4532     {
4533       max_alignment = loongarch_get_max_alignment (sec);
4534       htab->max_alignment = max_alignment;
4535     }
4536 
4537   for (unsigned int i = 0; i < sec->reloc_count; i++)
4538     {
4539       char symtype;
4540       bfd_vma symval;
4541       asection *sym_sec;
4542       bool local_got = false;
4543       Elf_Internal_Rela *rel = relocs + i;
4544       struct elf_link_hash_entry *h = NULL;
4545       unsigned long r_type = ELFNN_R_TYPE (rel->r_info);
4546       unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
4547 
4548       /* Four kind of relocations:
4549 	 Normal: symval is the symbol address.
4550 	 R_LARCH_ALIGN: symval is the address of the last NOP instruction
4551 	 added by this relocation, and then adds 4 more.
4552 	 R_LARCH_CALL36: symval is the symbol address for local symbols,
4553 	 or the PLT entry address of the symbol. (Todo)
4554 	 R_LARCHL_TLS_LD/GD/DESC_PC_HI20: symval is the GOT entry address
4555 	 of the symbol.  */
4556       if (r_symndx < symtab_hdr->sh_info)
4557 	{
4558 	  Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents
4559 				    + r_symndx;
4560 	  if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
4561 	    continue;
4562 
4563 	  if (R_LARCH_TLS_LD_PC_HI20 == r_type
4564 	      || R_LARCH_TLS_GD_PC_HI20 == r_type
4565 	      || R_LARCH_TLS_DESC_PC_HI20 == r_type)
4566 	    {
4567 	      if (i + 1 != sec->reloc_count
4568 		  && loongarch_can_trans_tls (abfd, info, h, rel, r_type))
4569 		continue;
4570 	      else
4571 		{
4572 		  sym_sec = htab->elf.sgot;
4573 		  symval = elf_local_got_offsets (abfd)[r_symndx];
4574 		  char tls_type = _bfd_loongarch_elf_tls_type (abfd, h,
4575 								r_symndx);
4576 		  if (R_LARCH_TLS_DESC_PC_HI20 == r_type
4577 			&& GOT_TLS_GD_BOTH_P (tls_type))
4578 		    symval += 2 * GOT_ENTRY_SIZE;
4579 		}
4580 	    }
4581 	  else if (sym->st_shndx == SHN_UNDEF || R_LARCH_ALIGN == r_type)
4582 	    {
4583 	      sym_sec = sec;
4584 	      symval = rel->r_offset;
4585 	    }
4586 	  else
4587 	    {
4588 	      sym_sec = elf_elfsections (abfd)[sym->st_shndx]->bfd_section;
4589 	      symval = sym->st_value;
4590 	    }
4591 	  symtype = ELF_ST_TYPE (sym->st_info);
4592 	}
4593       else
4594 	{
4595 	  r_symndx = ELFNN_R_SYM (rel->r_info) - symtab_hdr->sh_info;
4596 	  h = elf_sym_hashes (abfd)[r_symndx];
4597 
4598 	  while (h->root.type == bfd_link_hash_indirect
4599 		 || h->root.type == bfd_link_hash_warning)
4600 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
4601 
4602 	  /* Disable the relaxation for ifunc.  */
4603 	  if (h != NULL && h->type == STT_GNU_IFUNC)
4604 	    continue;
4605 
4606 	  /* The GOT entry of tls symbols must in current execute file or
4607 	     shared object.  */
4608 	  if (R_LARCH_TLS_LD_PC_HI20 == r_type
4609 	      || R_LARCH_TLS_GD_PC_HI20 == r_type
4610 	      || R_LARCH_TLS_DESC_PC_HI20 == r_type)
4611 	    {
4612 	      if (i + 1 != sec->reloc_count
4613 		  && loongarch_can_trans_tls (abfd, info, h, rel, r_type))
4614 		continue;
4615 	      else
4616 		{
4617 		  sym_sec = htab->elf.sgot;
4618 		  symval = h->got.offset;
4619 		  char tls_type = _bfd_loongarch_elf_tls_type (abfd, h,
4620 								r_symndx);
4621 		  if (R_LARCH_TLS_DESC_PC_HI20 == r_type
4622 			&& GOT_TLS_GD_BOTH_P (tls_type))
4623 		    symval += 2 * GOT_ENTRY_SIZE;
4624 		}
4625 	    }
4626 	  else if ((h->root.type == bfd_link_hash_defined
4627 		  || h->root.type == bfd_link_hash_defweak)
4628 		&& h->root.u.def.section != NULL
4629 		&& h->root.u.def.section->output_section != NULL)
4630 	    {
4631 	      symval = h->root.u.def.value;
4632 	      sym_sec = h->root.u.def.section;
4633 	    }
4634 	  else
4635 	    continue;
4636 
4637 	  if (h && SYMBOL_REFERENCES_LOCAL (info, h))
4638 	    local_got = true;
4639 	  symtype = h->type;
4640 	}
4641 
4642       if (sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE
4643 	   && (sym_sec->flags & SEC_MERGE))
4644 	{
4645 	   if (symtype == STT_SECTION)
4646 	     symval += rel->r_addend;
4647 
4648 	   symval = _bfd_merged_section_offset (abfd, &sym_sec,
4649 				elf_section_data (sym_sec)->sec_info,
4650 				symval);
4651 
4652 	   if (symtype != STT_SECTION)
4653 	     symval += rel->r_addend;
4654 	}
4655       /* For R_LARCH_ALIGN, symval is sec_addr (sec) + rel->r_offset
4656 	 + (alingmeng - 4).
4657 	 If r_symndx is 0, alignmeng-4 is r_addend.
4658 	 If r_symndx > 0, alignment-4 is 2^(r_addend & 0xff)-4.  */
4659       else if (R_LARCH_ALIGN == r_type)
4660 	if (r_symndx > 0)
4661 	  symval += ((1 << (rel->r_addend & 0xff)) - 4);
4662 	else
4663 	  symval += rel->r_addend;
4664       else
4665 	symval += rel->r_addend;
4666 
4667       symval += sec_addr (sym_sec);
4668 
4669       switch (r_type)
4670 	{
4671 	case R_LARCH_ALIGN:
4672 	  if (1 == info->relax_pass)
4673 	    loongarch_relax_align (abfd, sec, sym_sec, info, rel, symval);
4674 	  break;
4675 
4676 	case R_LARCH_DELETE:
4677 	  if (1 == info->relax_pass)
4678 	    {
4679 	      loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, info);
4680 	      rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
4681 	    }
4682 	  break;
4683 
4684 	case R_LARCH_TLS_LE_HI20_R:
4685 	case R_LARCH_TLS_LE_LO12_R:
4686 	case R_LARCH_TLS_LE_ADD_R:
4687 	  if (0 == info->relax_pass && (i + 2) <= sec->reloc_count)
4688 	    loongarch_relax_tls_le (abfd, sec, rel, info, symval);
4689 	  break;
4690 
4691 	case R_LARCH_PCALA_HI20:
4692 	  if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
4693 	    loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
4694 					info, again, max_alignment);
4695 	  break;
4696 
4697 	case R_LARCH_GOT_PC_HI20:
4698 	  if (local_got && 0 == info->relax_pass
4699 	      && (i + 4) <= sec->reloc_count)
4700 	    {
4701 	      if (loongarch_relax_pcala_ld (abfd, sec, rel))
4702 		loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
4703 					    info, again, max_alignment);
4704 	    }
4705 	  break;
4706 
4707 	case R_LARCH_TLS_LD_PC_HI20:
4708 	case R_LARCH_TLS_GD_PC_HI20:
4709 	case R_LARCH_TLS_DESC_PC_HI20:
4710 	  if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
4711 	    loongarch_relax_tls_ld_gd_desc (abfd, sec, sym_sec, rel, symval,
4712 					    info, again, max_alignment);
4713 	  break;
4714 
4715 	default:
4716 	  break;
4717 	}
4718     }
4719 
4720   return true;
4721 }
4722 
4723 /* Finish up dynamic symbol handling.  We set the contents of various
4724    dynamic sections here.  */
4725 
4726 static bool
loongarch_elf_finish_dynamic_symbol(bfd * output_bfd,struct bfd_link_info * info,struct elf_link_hash_entry * h,Elf_Internal_Sym * sym)4727 loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
4728 				     struct bfd_link_info *info,
4729 				     struct elf_link_hash_entry *h,
4730 				     Elf_Internal_Sym *sym)
4731 {
4732   struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4733   const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
4734 
4735   if (h->plt.offset != MINUS_ONE)
4736     {
4737       size_t i, plt_idx;
4738       asection *plt, *gotplt, *relplt;
4739       bfd_vma got_address;
4740       uint32_t plt_entry[PLT_ENTRY_INSNS];
4741       bfd_byte *loc;
4742       Elf_Internal_Rela rela;
4743 
4744       if (htab->elf.splt)
4745 	{
4746 	  BFD_ASSERT ((h->type == STT_GNU_IFUNC
4747 		       && SYMBOL_REFERENCES_LOCAL (info, h))
4748 		      || h->dynindx != -1);
4749 
4750 	  plt = htab->elf.splt;
4751 	  gotplt = htab->elf.sgotplt;
4752 	  if (h->type == STT_GNU_IFUNC && SYMBOL_REFERENCES_LOCAL (info, h))
4753 	    relplt = htab->elf.srelgot;
4754 	  else
4755 	    relplt = htab->elf.srelplt;
4756 	  plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
4757 	  got_address =
4758 	    sec_addr (gotplt) + GOTPLT_HEADER_SIZE + plt_idx * GOT_ENTRY_SIZE;
4759 	}
4760       else /* if (htab->elf.iplt) */
4761 	{
4762 	  BFD_ASSERT (h->type == STT_GNU_IFUNC
4763 		      && SYMBOL_REFERENCES_LOCAL (info, h));
4764 
4765 	  plt = htab->elf.iplt;
4766 	  gotplt = htab->elf.igotplt;
4767 	  relplt = htab->elf.irelplt;
4768 	  plt_idx = h->plt.offset / PLT_ENTRY_SIZE;
4769 	  got_address = sec_addr (gotplt) + plt_idx * GOT_ENTRY_SIZE;
4770 	}
4771 
4772       /* Find out where the .plt entry should go.  */
4773       loc = plt->contents + h->plt.offset;
4774 
4775       /* Fill in the PLT entry itself.  */
4776       if (!loongarch_make_plt_entry (got_address,
4777 				     sec_addr (plt) + h->plt.offset,
4778 				     plt_entry))
4779 	return false;
4780 
4781       for (i = 0; i < PLT_ENTRY_INSNS; i++)
4782 	bfd_put_32 (output_bfd, plt_entry[i], loc + 4 * i);
4783 
4784       /* Fill in the initial value of the got.plt entry.  */
4785       loc = gotplt->contents + (got_address - sec_addr (gotplt));
4786       bfd_put_NN (output_bfd, sec_addr (plt), loc);
4787 
4788       rela.r_offset = got_address;
4789 
4790       /* TRUE if this is a PLT reference to a local IFUNC.  */
4791       if (PLT_LOCAL_IFUNC_P (info, h)
4792 	  && (relplt == htab->elf.srelgot
4793 	      || relplt == htab->elf.irelplt))
4794 	{
4795 	  rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
4796 	  rela.r_addend = (h->root.u.def.value
4797 			       + h->root.u.def.section->output_section->vma
4798 			       + h->root.u.def.section->output_offset);
4799 
4800 	  loongarch_elf_append_rela (output_bfd, relplt, &rela);
4801 	}
4802       else
4803 	{
4804 	  /* Fill in the entry in the rela.plt section.  */
4805 	  rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_JUMP_SLOT);
4806 	  rela.r_addend = 0;
4807 	  loc = relplt->contents + plt_idx * sizeof (ElfNN_External_Rela);
4808 	  bed->s->swap_reloca_out (output_bfd, &rela, loc);
4809 	}
4810 
4811       if (!h->def_regular)
4812 	{
4813 	  /* Mark the symbol as undefined, rather than as defined in
4814 	     the .plt section.  Leave the value alone.  */
4815 	  sym->st_shndx = SHN_UNDEF;
4816 	  /* If the symbol is weak, we do need to clear the value.
4817 	     Otherwise, the PLT entry would provide a definition for
4818 	     the symbol even if the symbol wasn't defined anywhere,
4819 	     and so the symbol would never be NULL.  */
4820 	  if (!h->ref_regular_nonweak)
4821 	    sym->st_value = 0;
4822 	}
4823     }
4824 
4825   if (h->got.offset != MINUS_ONE
4826       /* TLS got entry have been handled in elf_relocate_section.  */
4827       && !(loongarch_elf_hash_entry (h)->tls_type
4828 	   & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
4829       /* Have allocated got entry but not allocated rela before.  */
4830       && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
4831     {
4832       asection *sgot, *srela;
4833       Elf_Internal_Rela rela;
4834       bfd_vma off = h->got.offset & ~(bfd_vma)1;
4835 
4836       /* This symbol has an entry in the GOT.  Set it up.  */
4837       sgot = htab->elf.sgot;
4838       srela = htab->elf.srelgot;
4839       BFD_ASSERT (sgot && srela);
4840 
4841       rela.r_offset = sec_addr (sgot) + off;
4842 
4843       if (h->def_regular
4844 	  && h->type == STT_GNU_IFUNC)
4845 	{
4846 	  if(h->plt.offset == MINUS_ONE)
4847 	    {
4848 	      if (htab->elf.splt == NULL)
4849 		srela = htab->elf.irelplt;
4850 
4851 	      if (SYMBOL_REFERENCES_LOCAL (info, h))
4852 		{
4853 		  asection *sec = h->root.u.def.section;
4854 		  rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
4855 		  rela.r_addend = h->root.u.def.value + sec->output_section->vma
4856 		    + sec->output_offset;
4857 		  bfd_put_NN (output_bfd, 0, sgot->contents + off);
4858 		}
4859 	      else
4860 		{
4861 		  BFD_ASSERT (h->dynindx != -1);
4862 		  rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
4863 		  rela.r_addend = 0;
4864 		  bfd_put_NN (output_bfd, (bfd_vma) 0, sgot->contents + off);
4865 		}
4866 	    }
4867 	  else if(bfd_link_pic (info))
4868 	    {
4869 	      rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
4870 	      rela.r_addend = 0;
4871 	      bfd_put_NN (output_bfd, rela.r_addend, sgot->contents + off);
4872 	    }
4873 	  else
4874 	    {
4875 	      asection *plt;
4876 	      /* For non-shared object, we can't use .got.plt, which
4877 		 contains the real function address if we need pointer
4878 		 equality.  We load the GOT entry with the PLT entry.  */
4879 	      plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
4880 	      bfd_put_NN (output_bfd,
4881 			  (plt->output_section->vma
4882 			   + plt->output_offset
4883 			   + h->plt.offset),
4884 			  sgot->contents + off);
4885 	      return true;
4886 	    }
4887 	}
4888       else if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h))
4889 	{
4890 	  asection *sec = h->root.u.def.section;
4891 	  rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
4892 	  rela.r_addend = (h->root.u.def.value + sec->output_section->vma
4893 			   + sec->output_offset);
4894 	}
4895       else
4896 	{
4897 	  BFD_ASSERT (h->dynindx != -1);
4898 	  rela.r_info = ELFNN_R_INFO (h->dynindx, R_LARCH_NN);
4899 	  rela.r_addend = 0;
4900 	}
4901 
4902       loongarch_elf_append_rela (output_bfd, srela, &rela);
4903     }
4904 
4905   /* Mark some specially defined symbols as absolute.  */
4906   if (h == htab->elf.hdynamic || h == htab->elf.hgot || h == htab->elf.hplt)
4907     sym->st_shndx = SHN_ABS;
4908 
4909   return true;
4910 }
4911 
4912 /* Finish up the dynamic sections.  */
4913 
4914 static bool
loongarch_finish_dyn(bfd * output_bfd,struct bfd_link_info * info,bfd * dynobj,asection * sdyn)4915 loongarch_finish_dyn (bfd *output_bfd, struct bfd_link_info *info, bfd *dynobj,
4916 		      asection *sdyn)
4917 {
4918   struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4919   const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
4920   size_t dynsize = bed->s->sizeof_dyn, skipped_size = 0;
4921   bfd_byte *dyncon, *dynconend;
4922 
4923   dynconend = sdyn->contents + sdyn->size;
4924   for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize)
4925     {
4926       Elf_Internal_Dyn dyn;
4927       asection *s;
4928       int skipped = 0;
4929 
4930       bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
4931 
4932       switch (dyn.d_tag)
4933 	{
4934 	case DT_PLTGOT:
4935 	  s = htab->elf.sgotplt;
4936 	  dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4937 	  break;
4938 	case DT_JMPREL:
4939 	  s = htab->elf.srelplt;
4940 	  dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4941 	  break;
4942 	case DT_PLTRELSZ:
4943 	  s = htab->elf.srelplt;
4944 	  dyn.d_un.d_val = s->size;
4945 	  break;
4946 	case DT_TEXTREL:
4947 	  if ((info->flags & DF_TEXTREL) == 0)
4948 	    skipped = 1;
4949 	  break;
4950 	case DT_FLAGS:
4951 	  if ((info->flags & DF_TEXTREL) == 0)
4952 	    dyn.d_un.d_val &= ~DF_TEXTREL;
4953 	  break;
4954 	}
4955       if (skipped)
4956 	skipped_size += dynsize;
4957       else
4958 	bed->s->swap_dyn_out (output_bfd, &dyn, dyncon - skipped_size);
4959     }
4960   /* Wipe out any trailing entries if we shifted down a dynamic tag.  */
4961   memset (dyncon - skipped_size, 0, skipped_size);
4962   return true;
4963 }
4964 
4965 /* Finish up local dynamic symbol handling.  We set the contents of
4966    various dynamic sections here.  */
4967 
4968 static int
elfNN_loongarch_finish_local_dynamic_symbol(void ** slot,void * inf)4969 elfNN_loongarch_finish_local_dynamic_symbol (void **slot, void *inf)
4970 {
4971   struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) *slot;
4972   struct bfd_link_info *info = (struct bfd_link_info *) inf;
4973 
4974   return loongarch_elf_finish_dynamic_symbol (info->output_bfd, info, h, NULL);
4975 }
4976 
4977 /* Value of struct elf_backend_data->elf_backend_output_arch_local_syms,
4978    this function is called before elf_link_sort_relocs.
4979    So relocation R_LARCH_IRELATIVE for local ifunc can be append to
4980    .rela.dyn (.rela.got) by loongarch_elf_append_rela.  */
4981 
4982 static bool
elf_loongarch_output_arch_local_syms(bfd * output_bfd ATTRIBUTE_UNUSED,struct bfd_link_info * info,void * flaginfo ATTRIBUTE_UNUSED,int (* func)(void *,const char *,Elf_Internal_Sym *,asection *,struct elf_link_hash_entry *)ATTRIBUTE_UNUSED)4983 elf_loongarch_output_arch_local_syms
4984   (bfd *output_bfd ATTRIBUTE_UNUSED,
4985    struct bfd_link_info *info,
4986    void *flaginfo ATTRIBUTE_UNUSED,
4987    int (*func) (void *, const char *,
4988 		Elf_Internal_Sym *,
4989 		asection *,
4990 		struct elf_link_hash_entry *) ATTRIBUTE_UNUSED)
4991 {
4992   struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
4993   if (htab == NULL)
4994     return false;
4995 
4996   /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
4997   htab_traverse (htab->loc_hash_table,
4998 		 elfNN_loongarch_finish_local_dynamic_symbol,
4999 		 info);
5000 
5001   return true;
5002 }
5003 
5004 static bool
loongarch_elf_finish_dynamic_sections(bfd * output_bfd,struct bfd_link_info * info)5005 loongarch_elf_finish_dynamic_sections (bfd *output_bfd,
5006 				       struct bfd_link_info *info)
5007 {
5008   bfd *dynobj;
5009   asection *sdyn, *plt, *gotplt = NULL;
5010   struct loongarch_elf_link_hash_table *htab;
5011 
5012   htab = loongarch_elf_hash_table (info);
5013   BFD_ASSERT (htab);
5014   dynobj = htab->elf.dynobj;
5015   sdyn = bfd_get_linker_section (dynobj, ".dynamic");
5016 
5017   if (elf_hash_table (info)->dynamic_sections_created)
5018     {
5019       BFD_ASSERT (htab->elf.splt && sdyn);
5020 
5021       if (!loongarch_finish_dyn (output_bfd, info, dynobj, sdyn))
5022 	return false;
5023     }
5024 
5025   plt = htab->elf.splt;
5026   gotplt = htab->elf.sgotplt;
5027 
5028   if (plt && 0 < plt->size)
5029     {
5030       size_t i;
5031       uint32_t plt_header[PLT_HEADER_INSNS];
5032       if (!loongarch_make_plt_header (sec_addr (gotplt), sec_addr (plt),
5033 				      plt_header))
5034 	return false;
5035 
5036       for (i = 0; i < PLT_HEADER_INSNS; i++)
5037 	bfd_put_32 (output_bfd, plt_header[i], plt->contents + 4 * i);
5038 
5039       elf_section_data (plt->output_section)->this_hdr.sh_entsize =
5040 	PLT_ENTRY_SIZE;
5041     }
5042 
5043   if (htab->elf.sgotplt)
5044     {
5045       asection *output_section = htab->elf.sgotplt->output_section;
5046 
5047       if (bfd_is_abs_section (output_section))
5048 	{
5049 	  _bfd_error_handler (_("discarded output section: `%pA'"),
5050 			      htab->elf.sgotplt);
5051 	  return false;
5052 	}
5053 
5054       if (0 < htab->elf.sgotplt->size)
5055 	{
5056 	  /* Write the first two entries in .got.plt, needed for the dynamic
5057 	     linker.  */
5058 	  bfd_put_NN (output_bfd, MINUS_ONE, htab->elf.sgotplt->contents);
5059 
5060 	  bfd_put_NN (output_bfd, (bfd_vma) 0,
5061 		      htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
5062 	}
5063 
5064       elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
5065     }
5066 
5067   if (htab->elf.sgot)
5068     {
5069       asection *output_section = htab->elf.sgot->output_section;
5070 
5071       if (0 < htab->elf.sgot->size)
5072 	{
5073 	  /* Set the first entry in the global offset table to the address of
5074 	     the dynamic section.  */
5075 	  bfd_vma val = sdyn ? sec_addr (sdyn) : 0;
5076 	  bfd_put_NN (output_bfd, val, htab->elf.sgot->contents);
5077 	}
5078 
5079       elf_section_data (output_section)->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
5080     }
5081 
5082   return true;
5083 }
5084 
5085 /* Return address for Ith PLT stub in section PLT, for relocation REL
5086    or (bfd_vma) -1 if it should not be included.  */
5087 
5088 static bfd_vma
loongarch_elf_plt_sym_val(bfd_vma i,const asection * plt,const arelent * rel ATTRIBUTE_UNUSED)5089 loongarch_elf_plt_sym_val (bfd_vma i, const asection *plt,
5090 			   const arelent *rel ATTRIBUTE_UNUSED)
5091 {
5092   return plt->vma + PLT_HEADER_SIZE + i * PLT_ENTRY_SIZE;
5093 }
5094 
5095 static enum elf_reloc_type_class
loongarch_reloc_type_class(const struct bfd_link_info * info ATTRIBUTE_UNUSED,const asection * rel_sec ATTRIBUTE_UNUSED,const Elf_Internal_Rela * rela)5096 loongarch_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
5097 			    const asection *rel_sec ATTRIBUTE_UNUSED,
5098 			    const Elf_Internal_Rela *rela)
5099 {
5100   struct loongarch_elf_link_hash_table *htab;
5101   htab = loongarch_elf_hash_table (info);
5102 
5103   if (htab->elf.dynsym != NULL && htab->elf.dynsym->contents != NULL)
5104     {
5105       /* Check relocation against STT_GNU_IFUNC symbol if there are
5106 	 dynamic symbols.  */
5107       bfd *abfd = info->output_bfd;
5108       const struct elf_backend_data *bed = get_elf_backend_data (abfd);
5109       unsigned long r_symndx = ELFNN_R_SYM (rela->r_info);
5110       if (r_symndx != STN_UNDEF)
5111 	{
5112 	  Elf_Internal_Sym sym;
5113 	  if (!bed->s->swap_symbol_in (abfd,
5114 				       htab->elf.dynsym->contents
5115 				       + r_symndx * bed->s->sizeof_sym,
5116 				       0, &sym))
5117 	    {
5118 	      /* xgettext:c-format  */
5119 	      _bfd_error_handler (_("%pB symbol number %lu references"
5120 				    " nonexistent SHT_SYMTAB_SHNDX section"),
5121 				  abfd, r_symndx);
5122 	      /* Ideally an error class should be returned here.  */
5123 	    }
5124 	  else if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
5125 	    return reloc_class_ifunc;
5126 	}
5127     }
5128 
5129   switch (ELFNN_R_TYPE (rela->r_info))
5130     {
5131     case R_LARCH_IRELATIVE:
5132       return reloc_class_ifunc;
5133     case R_LARCH_RELATIVE:
5134       return reloc_class_relative;
5135     case R_LARCH_JUMP_SLOT:
5136       return reloc_class_plt;
5137     case R_LARCH_COPY:
5138       return reloc_class_copy;
5139     default:
5140       return reloc_class_normal;
5141     }
5142 }
5143 
5144 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
5145 
5146 static void
loongarch_elf_copy_indirect_symbol(struct bfd_link_info * info,struct elf_link_hash_entry * dir,struct elf_link_hash_entry * ind)5147 loongarch_elf_copy_indirect_symbol (struct bfd_link_info *info,
5148 				    struct elf_link_hash_entry *dir,
5149 				    struct elf_link_hash_entry *ind)
5150 {
5151   struct elf_link_hash_entry *edir, *eind;
5152 
5153   edir = dir;
5154   eind = ind;
5155 
5156   if (eind->dyn_relocs != NULL)
5157     {
5158       if (edir->dyn_relocs != NULL)
5159 	{
5160 	  struct elf_dyn_relocs **pp;
5161 	  struct elf_dyn_relocs *p;
5162 
5163 	  /* Add reloc counts against the indirect sym to the direct sym
5164 	     list.  Merge any entries against the same section.  */
5165 	  for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
5166 	    {
5167 	      struct elf_dyn_relocs *q;
5168 
5169 	      for (q = edir->dyn_relocs; q != NULL; q = q->next)
5170 		if (q->sec == p->sec)
5171 		  {
5172 		    q->pc_count += p->pc_count;
5173 		    q->count += p->count;
5174 		    *pp = p->next;
5175 		    break;
5176 		  }
5177 	      if (q == NULL)
5178 		pp = &p->next;
5179 	    }
5180 	  *pp = edir->dyn_relocs;
5181 	}
5182 
5183       edir->dyn_relocs = eind->dyn_relocs;
5184       eind->dyn_relocs = NULL;
5185     }
5186 
5187   if (ind->root.type == bfd_link_hash_indirect && dir->got.refcount < 0)
5188     {
5189       loongarch_elf_hash_entry(edir)->tls_type
5190 	= loongarch_elf_hash_entry(eind)->tls_type;
5191       loongarch_elf_hash_entry(eind)->tls_type = GOT_UNKNOWN;
5192     }
5193   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
5194 }
5195 
5196 #define PRSTATUS_SIZE		    0x1d8
5197 #define PRSTATUS_OFFSET_PR_CURSIG   0xc
5198 #define PRSTATUS_OFFSET_PR_PID	    0x20
5199 #define ELF_GREGSET_T_SIZE	    0x168
5200 #define PRSTATUS_OFFSET_PR_REG	    0x70
5201 
5202 /* Support for core dump NOTE sections.  */
5203 
5204 static bool
loongarch_elf_grok_prstatus(bfd * abfd,Elf_Internal_Note * note)5205 loongarch_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
5206 {
5207   switch (note->descsz)
5208     {
5209     default:
5210       return false;
5211 
5212     /* The sizeof (struct elf_prstatus) on Linux/LoongArch.  */
5213     case PRSTATUS_SIZE:
5214       /* pr_cursig  */
5215       elf_tdata (abfd)->core->signal =
5216 	bfd_get_16 (abfd, note->descdata + PRSTATUS_OFFSET_PR_CURSIG);
5217 
5218       /* pr_pid  */
5219       elf_tdata (abfd)->core->lwpid =
5220 	bfd_get_32 (abfd, note->descdata + PRSTATUS_OFFSET_PR_PID);
5221       break;
5222     }
5223 
5224   /* Make a ".reg/999" section.  */
5225   return _bfd_elfcore_make_pseudosection (abfd, ".reg", ELF_GREGSET_T_SIZE,
5226 					  note->descpos
5227 					  + PRSTATUS_OFFSET_PR_REG);
5228 }
5229 
5230 #define PRPSINFO_SIZE		    0x88
5231 #define PRPSINFO_OFFSET_PR_PID	    0x18
5232 #define PRPSINFO_OFFSET_PR_FNAME    0x28
5233 #define PRPSINFO_SIZEOF_PR_FNAME    0x10
5234 #define PRPSINFO_OFFSET_PR_PS_ARGS  0x38
5235 #define PRPSINFO_SIZEOF_PR_PS_ARGS  0x50
5236 
5237 static bool
loongarch_elf_grok_psinfo(bfd * abfd,Elf_Internal_Note * note)5238 loongarch_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
5239 {
5240   switch (note->descsz)
5241     {
5242     default:
5243       return false;
5244 
5245     /* The sizeof (prpsinfo_t) on Linux/LoongArch.  */
5246     case PRPSINFO_SIZE:
5247       /* pr_pid  */
5248       elf_tdata (abfd)->core->pid =
5249 	bfd_get_32 (abfd, note->descdata + PRPSINFO_OFFSET_PR_PID);
5250 
5251       /* pr_fname  */
5252       elf_tdata (abfd)->core->program =
5253 	_bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_FNAME,
5254 			      PRPSINFO_SIZEOF_PR_FNAME);
5255 
5256       /* pr_psargs  */
5257       elf_tdata (abfd)->core->command =
5258 	_bfd_elfcore_strndup (abfd, note->descdata + PRPSINFO_OFFSET_PR_PS_ARGS,
5259 			      PRPSINFO_SIZEOF_PR_PS_ARGS);
5260       break;
5261     }
5262 
5263   /* Note that for some reason, a spurious space is tacked
5264      onto the end of the args in some (at least one anyway)
5265      implementations, so strip it off if it exists.  */
5266 
5267   {
5268     char *command = elf_tdata (abfd)->core->command;
5269     int n = strlen (command);
5270 
5271     if (0 < n && command[n - 1] == ' ')
5272       command[n - 1] = '\0';
5273   }
5274 
5275   return true;
5276 }
5277 
5278 /* Set the right mach type.  */
5279 static bool
loongarch_elf_object_p(bfd * abfd)5280 loongarch_elf_object_p (bfd *abfd)
5281 {
5282   /* There are only two mach types in LoongArch currently.  */
5283   if (strcmp (abfd->xvec->name, "elf64-loongarch") == 0)
5284     bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch64);
5285   else
5286     bfd_default_set_arch_mach (abfd, bfd_arch_loongarch, bfd_mach_loongarch32);
5287   return true;
5288 }
5289 
5290 static asection *
loongarch_elf_gc_mark_hook(asection * sec,struct bfd_link_info * info,Elf_Internal_Rela * rel,struct elf_link_hash_entry * h,Elf_Internal_Sym * sym)5291 loongarch_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info,
5292 			    Elf_Internal_Rela *rel,
5293 			    struct elf_link_hash_entry *h,
5294 			    Elf_Internal_Sym *sym)
5295 {
5296   if (h != NULL)
5297     switch (ELFNN_R_TYPE (rel->r_info))
5298       {
5299       case R_LARCH_GNU_VTINHERIT:
5300       case R_LARCH_GNU_VTENTRY:
5301 	return NULL;
5302       }
5303 
5304   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
5305 }
5306 
5307 /* Return TRUE if symbol H should be hashed in the `.gnu.hash' section.  For
5308    executable PLT slots where the executable never takes the address of those
5309    functions, the function symbols are not added to the hash table.  */
5310 
5311 static bool
elf_loongarch64_hash_symbol(struct elf_link_hash_entry * h)5312 elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
5313 {
5314   if (h->plt.offset != (bfd_vma) -1
5315       && !h->def_regular
5316       && !h->pointer_equality_needed)
5317     return false;
5318 
5319   return _bfd_elf_hash_symbol (h);
5320 }
5321 
5322 #define TARGET_LITTLE_SYM loongarch_elfNN_vec
5323 #define TARGET_LITTLE_NAME "elfNN-loongarch"
5324 #define ELF_ARCH bfd_arch_loongarch
5325 #define ELF_TARGET_ID LARCH_ELF_DATA
5326 #define ELF_MACHINE_CODE EM_LOONGARCH
5327 #define ELF_MAXPAGESIZE 0x4000
5328 #define bfd_elfNN_bfd_reloc_type_lookup loongarch_reloc_type_lookup
5329 #define bfd_elfNN_bfd_link_hash_table_create				  \
5330   loongarch_elf_link_hash_table_create
5331 #define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup
5332 #define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto.  */
5333 #define elf_info_to_howto loongarch_info_to_howto_rela
5334 #define bfd_elfNN_bfd_merge_private_bfd_data				  \
5335   elfNN_loongarch_merge_private_bfd_data
5336 
5337 #define elf_backend_reloc_type_class loongarch_reloc_type_class
5338 #define elf_backend_copy_indirect_symbol loongarch_elf_copy_indirect_symbol
5339 #define elf_backend_create_dynamic_sections				   \
5340   loongarch_elf_create_dynamic_sections
5341 #define elf_backend_check_relocs loongarch_elf_check_relocs
5342 #define elf_backend_adjust_dynamic_symbol loongarch_elf_adjust_dynamic_symbol
5343 #define elf_backend_size_dynamic_sections loongarch_elf_size_dynamic_sections
5344 #define elf_backend_relocate_section loongarch_elf_relocate_section
5345 #define elf_backend_finish_dynamic_symbol loongarch_elf_finish_dynamic_symbol
5346 #define elf_backend_output_arch_local_syms \
5347   elf_loongarch_output_arch_local_syms
5348 #define elf_backend_finish_dynamic_sections				   \
5349   loongarch_elf_finish_dynamic_sections
5350 #define elf_backend_object_p loongarch_elf_object_p
5351 #define elf_backend_gc_mark_hook loongarch_elf_gc_mark_hook
5352 #define elf_backend_plt_sym_val loongarch_elf_plt_sym_val
5353 #define elf_backend_grok_prstatus loongarch_elf_grok_prstatus
5354 #define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
5355 #define elf_backend_hash_symbol elf_loongarch64_hash_symbol
5356 #define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section
5357 
5358 #define elf_backend_dtrel_excludes_plt 1
5359 
5360 #include "elfNN-target.h"
5361