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