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