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