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