elfnn-kvx.c revision 1.1.1.3 1 1.1 christos /* KVX-specific support for NN-bit ELF.
2 1.1.1.3 christos Copyright (C) 2009-2026 Free Software Foundation, Inc.
3 1.1 christos Contributed by Kalray SA.
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 "sysdep.h"
22 1.1 christos #include "bfd.h"
23 1.1 christos #include "libiberty.h"
24 1.1 christos #include "libbfd.h"
25 1.1 christos #include "elf-bfd.h"
26 1.1 christos #include "bfdlink.h"
27 1.1 christos #include "objalloc.h"
28 1.1 christos #include "elf/kvx.h"
29 1.1 christos #include "elfxx-kvx.h"
30 1.1 christos
31 1.1 christos #define ARCH_SIZE NN
32 1.1 christos
33 1.1 christos #if ARCH_SIZE == 64
34 1.1 christos #define LOG_FILE_ALIGN 3
35 1.1 christos #endif
36 1.1 christos
37 1.1 christos #if ARCH_SIZE == 32
38 1.1 christos #define LOG_FILE_ALIGN 2
39 1.1 christos #endif
40 1.1 christos
41 1.1 christos #define IS_KVX_TLS_RELOC(R_TYPE) \
42 1.1 christos ((R_TYPE) == BFD_RELOC_KVX_S37_TLS_LE_LO10 \
43 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S37_TLS_LE_UP27 \
44 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S43_TLS_LE_LO10 \
45 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S43_TLS_LE_UP27 \
46 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S43_TLS_LE_EX6 \
47 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S37_TLS_DTPOFF_LO10 \
48 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S37_TLS_DTPOFF_UP27 \
49 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S43_TLS_DTPOFF_LO10 \
50 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S43_TLS_DTPOFF_UP27 \
51 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S43_TLS_DTPOFF_EX6 \
52 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S37_TLS_IE_LO10 \
53 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S37_TLS_IE_UP27 \
54 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S43_TLS_IE_LO10 \
55 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S43_TLS_IE_UP27 \
56 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S43_TLS_IE_EX6 \
57 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S37_TLS_GD_LO10 \
58 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S37_TLS_GD_UP27 \
59 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S43_TLS_GD_LO10 \
60 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S43_TLS_GD_UP27 \
61 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S43_TLS_GD_EX6 \
62 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S37_TLS_LD_LO10 \
63 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S37_TLS_LD_UP27 \
64 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S43_TLS_LD_LO10 \
65 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S43_TLS_LD_UP27 \
66 1.1 christos || (R_TYPE) == BFD_RELOC_KVX_S43_TLS_LD_EX6 \
67 1.1 christos )
68 1.1 christos
69 1.1 christos #define IS_KVX_TLS_RELAX_RELOC(R_TYPE) 0
70 1.1 christos
71 1.1 christos #define ELIMINATE_COPY_RELOCS 0
72 1.1 christos
73 1.1 christos /* Return size of a relocation entry. HTAB is the bfd's
74 1.1 christos elf_kvx_link_hash_entry. */
75 1.1 christos #define RELOC_SIZE(HTAB) (sizeof (ElfNN_External_Rela))
76 1.1 christos
77 1.1 christos /* GOT Entry size - 8 bytes in ELF64 and 4 bytes in ELF32. */
78 1.1 christos #define GOT_ENTRY_SIZE (ARCH_SIZE / 8)
79 1.1 christos #define PLT_ENTRY_SIZE (32)
80 1.1 christos
81 1.1 christos #define PLT_SMALL_ENTRY_SIZE (4*4)
82 1.1 christos
83 1.1 christos /* Encoding of the nop instruction */
84 1.1 christos #define INSN_NOP 0x00f0037f
85 1.1 christos
86 1.1 christos #define kvx_compute_jump_table_size(htab) \
87 1.1 christos (((htab)->root.srelplt == NULL) ? 0 \
88 1.1 christos : (htab)->root.srelplt->reloc_count * GOT_ENTRY_SIZE)
89 1.1 christos
90 1.1 christos static const bfd_byte elfNN_kvx_small_plt0_entry[PLT_ENTRY_SIZE] =
91 1.1 christos {
92 1.1 christos /* FIXME KVX: no first entry, not used yet */
93 1.1 christos 0
94 1.1 christos };
95 1.1 christos
96 1.1 christos /* Per function entry in a procedure linkage table looks like this
97 1.1 christos if the distance between the PLTGOT and the PLT is < 4GB use
98 1.1 christos these PLT entries. */
99 1.1 christos static const bfd_byte elfNN_kvx_small_plt_entry[PLT_SMALL_ENTRY_SIZE] =
100 1.1 christos {
101 1.1 christos 0x10, 0x00, 0xc4, 0x0f, /* get $r16 = $pc ;; */
102 1.1 christos #if ARCH_SIZE == 32
103 1.1 christos 0x10, 0x00, 0x40, 0xb0, /* lwz $r16 = 0[$r16] ;; */
104 1.1 christos #else
105 1.1 christos 0x10, 0x00, 0x40, 0xb8, /* ld $r16 = 0[$r16] ;; */
106 1.1 christos #endif
107 1.1 christos 0x00, 0x00, 0x00, 0x18, /* upper 27 bits for LSU */
108 1.1 christos 0x10, 0x00, 0xd8, 0x0f, /* igoto $r16 ;; */
109 1.1 christos };
110 1.1 christos
111 1.1 christos /* Long stub use 43bits format of make. */
112 1.1 christos static const uint32_t elfNN_kvx_long_branch_stub[] =
113 1.1 christos {
114 1.1 christos 0xe0400000, /* make $r16 = LO10<emm43> EX6<imm43> */
115 1.1 christos 0x00000000, /* UP27<imm43> ;; */
116 1.1 christos 0x0fd80010, /* igoto "r16 ;; */
117 1.1 christos };
118 1.1 christos
119 1.1 christos #define elf_info_to_howto elfNN_kvx_info_to_howto
120 1.1 christos #define elf_info_to_howto_rel elfNN_kvx_info_to_howto
121 1.1 christos
122 1.1 christos #define KVX_ELF_ABI_VERSION 0
123 1.1 christos
124 1.1 christos /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
125 1.1 christos #define ALL_ONES (~ (bfd_vma) 0)
126 1.1 christos
127 1.1 christos /* Indexed by the bfd interal reloc enumerators.
128 1.1 christos Therefore, the table needs to be synced with BFD_RELOC_KVX_*
129 1.1 christos in reloc.c. */
130 1.1 christos
131 1.1 christos #define KVX_KV3_V1_KV3_V2_KV4_V1
132 1.1 christos #include "elfxx-kvx-relocs.h"
133 1.1 christos #undef KVX_KV3_V1_KV3_V2_KV4_V1
134 1.1 christos
135 1.1 christos /* Given HOWTO, return the bfd internal relocation enumerator. */
136 1.1 christos
137 1.1 christos static bfd_reloc_code_real_type
138 1.1 christos elfNN_kvx_bfd_reloc_from_howto (reloc_howto_type *howto)
139 1.1 christos {
140 1.1 christos const int size = (int) ARRAY_SIZE (elf_kvx_howto_table);
141 1.1 christos const ptrdiff_t offset = howto - elf_kvx_howto_table;
142 1.1 christos
143 1.1 christos if (offset >= 0 && offset < size)
144 1.1 christos return BFD_RELOC_KVX_RELOC_START + offset + 1;
145 1.1 christos
146 1.1 christos return BFD_RELOC_KVX_RELOC_START + 1;
147 1.1 christos }
148 1.1 christos
149 1.1 christos /* Given R_TYPE, return the bfd internal relocation enumerator. */
150 1.1 christos
151 1.1 christos static bfd_reloc_code_real_type
152 1.1 christos elfNN_kvx_bfd_reloc_from_type (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type)
153 1.1 christos {
154 1.1 christos static bool initialized_p = false;
155 1.1 christos /* Indexed by R_TYPE, values are offsets in the howto_table. */
156 1.1 christos static unsigned int offsets[R_KVX_end];
157 1.1 christos
158 1.1 christos if (!initialized_p)
159 1.1 christos {
160 1.1 christos unsigned int i;
161 1.1 christos
162 1.1 christos for (i = 0; i < ARRAY_SIZE (elf_kvx_howto_table); ++i)
163 1.1 christos offsets[elf_kvx_howto_table[i].type] = i;
164 1.1 christos
165 1.1 christos initialized_p = true;
166 1.1 christos }
167 1.1 christos
168 1.1 christos /* PR 17512: file: b371e70a. */
169 1.1 christos if (r_type >= R_KVX_end)
170 1.1 christos {
171 1.1 christos bfd_set_error (bfd_error_bad_value);
172 1.1 christos return BFD_RELOC_KVX_RELOC_END;
173 1.1 christos }
174 1.1 christos
175 1.1 christos return (BFD_RELOC_KVX_RELOC_START + 1) + offsets[r_type];
176 1.1 christos }
177 1.1 christos
178 1.1 christos struct elf_kvx_reloc_map
179 1.1 christos {
180 1.1 christos bfd_reloc_code_real_type from;
181 1.1 christos bfd_reloc_code_real_type to;
182 1.1 christos };
183 1.1 christos
184 1.1 christos /* Map bfd generic reloc to KVX-specific reloc. */
185 1.1 christos static const struct elf_kvx_reloc_map elf_kvx_reloc_map[] =
186 1.1 christos {
187 1.1 christos {BFD_RELOC_NONE, BFD_RELOC_KVX_NONE},
188 1.1 christos
189 1.1 christos /* Basic data relocations. */
190 1.1 christos {BFD_RELOC_CTOR, BFD_RELOC_KVX_NN},
191 1.1 christos {BFD_RELOC_64, BFD_RELOC_KVX_64},
192 1.1 christos {BFD_RELOC_32, BFD_RELOC_KVX_32},
193 1.1 christos {BFD_RELOC_16, BFD_RELOC_KVX_16},
194 1.1 christos {BFD_RELOC_8, BFD_RELOC_KVX_8},
195 1.1 christos
196 1.1 christos {BFD_RELOC_64_PCREL, BFD_RELOC_KVX_64_PCREL},
197 1.1 christos {BFD_RELOC_32_PCREL, BFD_RELOC_KVX_32_PCREL},
198 1.1 christos };
199 1.1 christos
200 1.1 christos /* Given the bfd internal relocation enumerator in CODE, return the
201 1.1 christos corresponding howto entry. */
202 1.1 christos
203 1.1 christos static reloc_howto_type *
204 1.1 christos elfNN_kvx_howto_from_bfd_reloc (bfd_reloc_code_real_type code)
205 1.1 christos {
206 1.1 christos unsigned int i;
207 1.1 christos
208 1.1 christos /* Convert bfd generic reloc to KVX-specific reloc. */
209 1.1 christos if (code < BFD_RELOC_KVX_RELOC_START || code > BFD_RELOC_KVX_RELOC_END)
210 1.1 christos for (i = 0; i < ARRAY_SIZE (elf_kvx_reloc_map) ; i++)
211 1.1 christos if (elf_kvx_reloc_map[i].from == code)
212 1.1 christos {
213 1.1 christos code = elf_kvx_reloc_map[i].to;
214 1.1 christos break;
215 1.1 christos }
216 1.1 christos
217 1.1 christos if (code > BFD_RELOC_KVX_RELOC_START && code < BFD_RELOC_KVX_RELOC_END)
218 1.1 christos return &elf_kvx_howto_table[code - (BFD_RELOC_KVX_RELOC_START + 1)];
219 1.1 christos
220 1.1 christos return NULL;
221 1.1 christos }
222 1.1 christos
223 1.1 christos static reloc_howto_type *
224 1.1 christos elfNN_kvx_howto_from_type (bfd *abfd, unsigned int r_type)
225 1.1 christos {
226 1.1 christos bfd_reloc_code_real_type val;
227 1.1 christos reloc_howto_type *howto;
228 1.1 christos
229 1.1 christos #if ARCH_SIZE == 32
230 1.1 christos if (r_type > 256)
231 1.1 christos {
232 1.1 christos bfd_set_error (bfd_error_bad_value);
233 1.1 christos return NULL;
234 1.1 christos }
235 1.1 christos #endif
236 1.1 christos
237 1.1 christos val = elfNN_kvx_bfd_reloc_from_type (abfd, r_type);
238 1.1 christos howto = elfNN_kvx_howto_from_bfd_reloc (val);
239 1.1 christos
240 1.1 christos if (howto != NULL)
241 1.1 christos return howto;
242 1.1 christos
243 1.1 christos bfd_set_error (bfd_error_bad_value);
244 1.1 christos return NULL;
245 1.1 christos }
246 1.1 christos
247 1.1 christos static bool
248 1.1 christos elfNN_kvx_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
249 1.1 christos Elf_Internal_Rela *elf_reloc)
250 1.1 christos {
251 1.1 christos unsigned int r_type;
252 1.1 christos
253 1.1 christos r_type = ELFNN_R_TYPE (elf_reloc->r_info);
254 1.1 christos bfd_reloc->howto = elfNN_kvx_howto_from_type (abfd, r_type);
255 1.1 christos
256 1.1 christos if (bfd_reloc->howto == NULL)
257 1.1 christos {
258 1.1 christos /* xgettext:c-format */
259 1.1 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
260 1.1 christos abfd, r_type);
261 1.1 christos return false;
262 1.1 christos }
263 1.1 christos return true;
264 1.1 christos }
265 1.1 christos
266 1.1 christos static reloc_howto_type *
267 1.1 christos elfNN_kvx_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
268 1.1 christos bfd_reloc_code_real_type code)
269 1.1 christos {
270 1.1 christos reloc_howto_type *howto = elfNN_kvx_howto_from_bfd_reloc (code);
271 1.1 christos
272 1.1 christos if (howto != NULL)
273 1.1 christos return howto;
274 1.1 christos
275 1.1 christos bfd_set_error (bfd_error_bad_value);
276 1.1 christos return NULL;
277 1.1 christos }
278 1.1 christos
279 1.1 christos static reloc_howto_type *
280 1.1 christos elfNN_kvx_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
281 1.1 christos const char *r_name)
282 1.1 christos {
283 1.1 christos unsigned int i;
284 1.1 christos
285 1.1 christos for (i = 0; i < ARRAY_SIZE (elf_kvx_howto_table); ++i)
286 1.1 christos if (elf_kvx_howto_table[i].name != NULL
287 1.1 christos && strcasecmp (elf_kvx_howto_table[i].name, r_name) == 0)
288 1.1 christos return &elf_kvx_howto_table[i];
289 1.1 christos
290 1.1 christos return NULL;
291 1.1 christos }
292 1.1 christos
293 1.1 christos #define TARGET_LITTLE_SYM kvx_elfNN_vec
294 1.1 christos #define TARGET_LITTLE_NAME "elfNN-kvx"
295 1.1 christos
296 1.1 christos /* The linker script knows the section names for placement.
297 1.1 christos The entry_names are used to do simple name mangling on the stubs.
298 1.1 christos Given a function name, and its type, the stub can be found. The
299 1.1 christos name can be changed. The only requirement is the %s be present. */
300 1.1 christos #define STUB_ENTRY_NAME "__%s_veneer"
301 1.1 christos
302 1.1 christos /* The name of the dynamic interpreter. This is put in the .interp
303 1.1 christos section. */
304 1.1 christos #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
305 1.1 christos
306 1.1 christos
307 1.1 christos /* PCREL 27 is signed-extended and scaled by 4 */
308 1.1 christos #define KVX_MAX_FWD_CALL_OFFSET \
309 1.1 christos (((1 << 26) - 1) << 2)
310 1.1 christos #define KVX_MAX_BWD_CALL_OFFSET \
311 1.1 christos (-((1 << 26) << 2))
312 1.1 christos
313 1.1 christos /* Check that the destination of the call is within the PCREL27
314 1.1 christos range. */
315 1.1 christos static int
316 1.1 christos kvx_valid_call_p (bfd_vma value, bfd_vma place)
317 1.1 christos {
318 1.1 christos bfd_signed_vma offset = (bfd_signed_vma) (value - place);
319 1.1 christos return (offset <= KVX_MAX_FWD_CALL_OFFSET
320 1.1 christos && offset >= KVX_MAX_BWD_CALL_OFFSET);
321 1.1 christos }
322 1.1 christos
323 1.1 christos /* Section name for stubs is the associated section name plus this
324 1.1 christos string. */
325 1.1 christos #define STUB_SUFFIX ".stub"
326 1.1 christos
327 1.1 christos enum elf_kvx_stub_type
328 1.1 christos {
329 1.1 christos kvx_stub_none,
330 1.1 christos kvx_stub_long_branch,
331 1.1 christos };
332 1.1 christos
333 1.1 christos struct elf_kvx_stub_hash_entry
334 1.1 christos {
335 1.1 christos /* Base hash table entry structure. */
336 1.1 christos struct bfd_hash_entry root;
337 1.1 christos
338 1.1 christos /* The stub section. */
339 1.1 christos asection *stub_sec;
340 1.1 christos
341 1.1 christos /* Offset within stub_sec of the beginning of this stub. */
342 1.1 christos bfd_vma stub_offset;
343 1.1 christos
344 1.1 christos /* Given the symbol's value and its section we can determine its final
345 1.1 christos value when building the stubs (so the stub knows where to jump). */
346 1.1 christos bfd_vma target_value;
347 1.1 christos asection *target_section;
348 1.1 christos
349 1.1 christos enum elf_kvx_stub_type stub_type;
350 1.1 christos
351 1.1 christos /* The symbol table entry, if any, that this was derived from. */
352 1.1 christos struct elf_kvx_link_hash_entry *h;
353 1.1 christos
354 1.1 christos /* Destination symbol type */
355 1.1 christos unsigned char st_type;
356 1.1 christos
357 1.1 christos /* Where this stub is being called from, or, in the case of combined
358 1.1 christos stub sections, the first input section in the group. */
359 1.1 christos asection *id_sec;
360 1.1 christos
361 1.1 christos /* The name for the local symbol at the start of this stub. The
362 1.1 christos stub name in the hash table has to be unique; this does not, so
363 1.1 christos it can be friendlier. */
364 1.1 christos char *output_name;
365 1.1 christos };
366 1.1 christos
367 1.1 christos /* Used to build a map of a section. This is required for mixed-endian
368 1.1 christos code/data. */
369 1.1 christos
370 1.1 christos typedef struct elf_elf_section_map
371 1.1 christos {
372 1.1 christos bfd_vma vma;
373 1.1 christos char type;
374 1.1 christos }
375 1.1 christos elf_kvx_section_map;
376 1.1 christos
377 1.1 christos
378 1.1 christos typedef struct _kvx_elf_section_data
379 1.1 christos {
380 1.1 christos struct bfd_elf_section_data elf;
381 1.1 christos unsigned int mapcount;
382 1.1 christos unsigned int mapsize;
383 1.1 christos elf_kvx_section_map *map;
384 1.1 christos }
385 1.1 christos _kvx_elf_section_data;
386 1.1 christos
387 1.1 christos #define elf_kvx_section_data(sec) \
388 1.1 christos ((_kvx_elf_section_data *) elf_section_data (sec))
389 1.1 christos
390 1.1 christos struct elf_kvx_local_symbol
391 1.1 christos {
392 1.1 christos unsigned int got_type;
393 1.1 christos bfd_signed_vma got_refcount;
394 1.1 christos bfd_vma got_offset;
395 1.1 christos };
396 1.1 christos
397 1.1 christos struct elf_kvx_obj_tdata
398 1.1 christos {
399 1.1 christos struct elf_obj_tdata root;
400 1.1 christos
401 1.1 christos /* local symbol descriptors */
402 1.1 christos struct elf_kvx_local_symbol *locals;
403 1.1 christos
404 1.1 christos /* Zero to warn when linking objects with incompatible enum sizes. */
405 1.1 christos int no_enum_size_warning;
406 1.1 christos
407 1.1 christos /* Zero to warn when linking objects with incompatible wchar_t sizes. */
408 1.1 christos int no_wchar_size_warning;
409 1.1 christos };
410 1.1 christos
411 1.1 christos #define elf_kvx_tdata(bfd) \
412 1.1 christos ((struct elf_kvx_obj_tdata *) (bfd)->tdata.any)
413 1.1 christos
414 1.1 christos #define elf_kvx_locals(bfd) (elf_kvx_tdata (bfd)->locals)
415 1.1 christos
416 1.1 christos #define is_kvx_elf(bfd) \
417 1.1 christos (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
418 1.1 christos && elf_tdata (bfd) != NULL \
419 1.1 christos && elf_object_id (bfd) == KVX_ELF_DATA)
420 1.1 christos
421 1.1 christos static bool
422 1.1 christos elfNN_kvx_mkobject (bfd *abfd)
423 1.1 christos {
424 1.1.1.2 christos return bfd_elf_allocate_object (abfd, sizeof (struct elf_kvx_obj_tdata));
425 1.1 christos }
426 1.1 christos
427 1.1 christos #define elf_kvx_hash_entry(ent) \
428 1.1 christos ((struct elf_kvx_link_hash_entry *)(ent))
429 1.1 christos
430 1.1 christos #define GOT_UNKNOWN 0
431 1.1 christos #define GOT_NORMAL 1
432 1.1 christos
433 1.1 christos #define GOT_TLS_GD 2
434 1.1 christos #define GOT_TLS_IE 4
435 1.1 christos #define GOT_TLS_LD 8
436 1.1 christos
437 1.1 christos /* KVX ELF linker hash entry. */
438 1.1 christos struct elf_kvx_link_hash_entry
439 1.1 christos {
440 1.1 christos struct elf_link_hash_entry root;
441 1.1 christos
442 1.1 christos /* Since PLT entries have variable size, we need to record the
443 1.1 christos index into .got.plt instead of recomputing it from the PLT
444 1.1 christos offset. */
445 1.1 christos bfd_signed_vma plt_got_offset;
446 1.1 christos
447 1.1 christos /* Bit mask representing the type of GOT entry(s) if any required by
448 1.1 christos this symbol. */
449 1.1 christos unsigned int got_type;
450 1.1 christos
451 1.1 christos /* A pointer to the most recently used stub hash entry against this
452 1.1 christos symbol. */
453 1.1 christos struct elf_kvx_stub_hash_entry *stub_cache;
454 1.1 christos };
455 1.1 christos
456 1.1 christos /* Get the KVX elf linker hash table from a link_info structure. */
457 1.1 christos #define elf_kvx_hash_table(info) \
458 1.1 christos ((struct elf_kvx_link_hash_table *) ((info)->hash))
459 1.1 christos
460 1.1 christos #define kvx_stub_hash_lookup(table, string, create, copy) \
461 1.1 christos ((struct elf_kvx_stub_hash_entry *) \
462 1.1 christos bfd_hash_lookup ((table), (string), (create), (copy)))
463 1.1 christos
464 1.1 christos /* KVX ELF linker hash table. */
465 1.1 christos struct elf_kvx_link_hash_table
466 1.1 christos {
467 1.1 christos /* The main hash table. */
468 1.1 christos struct elf_link_hash_table root;
469 1.1 christos
470 1.1 christos /* Nonzero to force PIC branch veneers. */
471 1.1 christos int pic_veneer;
472 1.1 christos
473 1.1 christos /* The number of bytes in the initial entry in the PLT. */
474 1.1 christos bfd_size_type plt_header_size;
475 1.1 christos
476 1.1 christos /* The number of bytes in the subsequent PLT etries. */
477 1.1 christos bfd_size_type plt_entry_size;
478 1.1 christos
479 1.1 christos /* The bytes of the subsequent PLT entry. */
480 1.1 christos const bfd_byte *plt_entry;
481 1.1 christos
482 1.1 christos /* Short-cuts to get to dynamic linker sections. */
483 1.1 christos asection *sdynbss;
484 1.1 christos asection *srelbss;
485 1.1 christos
486 1.1 christos /* Small local sym cache. */
487 1.1 christos struct sym_cache sym_cache;
488 1.1 christos
489 1.1 christos /* For convenience in allocate_dynrelocs. */
490 1.1 christos bfd *obfd;
491 1.1 christos
492 1.1 christos /* The amount of space used by the reserved portion of the sgotplt
493 1.1 christos section, plus whatever space is used by the jump slots. */
494 1.1 christos bfd_vma sgotplt_jump_table_size;
495 1.1 christos
496 1.1 christos /* The stub hash table. */
497 1.1 christos struct bfd_hash_table stub_hash_table;
498 1.1 christos
499 1.1 christos /* Linker stub bfd. */
500 1.1 christos bfd *stub_bfd;
501 1.1 christos
502 1.1 christos /* Linker call-backs. */
503 1.1 christos asection *(*add_stub_section) (const char *, asection *);
504 1.1 christos void (*layout_sections_again) (void);
505 1.1 christos
506 1.1 christos /* Array to keep track of which stub sections have been created, and
507 1.1 christos information on stub grouping. */
508 1.1 christos struct map_stub
509 1.1 christos {
510 1.1 christos /* This is the section to which stubs in the group will be
511 1.1 christos attached. */
512 1.1 christos asection *link_sec;
513 1.1 christos /* The stub section. */
514 1.1 christos asection *stub_sec;
515 1.1 christos } *stub_group;
516 1.1 christos
517 1.1 christos /* Assorted information used by elfNN_kvx_size_stubs. */
518 1.1 christos unsigned int bfd_count;
519 1.1 christos unsigned int top_index;
520 1.1 christos asection **input_list;
521 1.1 christos };
522 1.1 christos
523 1.1 christos /* Create an entry in an KVX ELF linker hash table. */
524 1.1 christos
525 1.1 christos static struct bfd_hash_entry *
526 1.1 christos elfNN_kvx_link_hash_newfunc (struct bfd_hash_entry *entry,
527 1.1 christos struct bfd_hash_table *table,
528 1.1 christos const char *string)
529 1.1 christos {
530 1.1 christos struct elf_kvx_link_hash_entry *ret =
531 1.1 christos (struct elf_kvx_link_hash_entry *) entry;
532 1.1 christos
533 1.1 christos /* Allocate the structure if it has not already been allocated by a
534 1.1 christos subclass. */
535 1.1 christos if (ret == NULL)
536 1.1 christos ret = bfd_hash_allocate (table,
537 1.1 christos sizeof (struct elf_kvx_link_hash_entry));
538 1.1 christos if (ret == NULL)
539 1.1 christos return (struct bfd_hash_entry *) ret;
540 1.1 christos
541 1.1 christos /* Call the allocation method of the superclass. */
542 1.1 christos ret = ((struct elf_kvx_link_hash_entry *)
543 1.1 christos _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
544 1.1 christos table, string));
545 1.1 christos if (ret != NULL)
546 1.1 christos {
547 1.1 christos ret->got_type = GOT_UNKNOWN;
548 1.1 christos ret->plt_got_offset = (bfd_vma) - 1;
549 1.1 christos ret->stub_cache = NULL;
550 1.1 christos }
551 1.1 christos
552 1.1 christos return (struct bfd_hash_entry *) ret;
553 1.1 christos }
554 1.1 christos
555 1.1 christos /* Initialize an entry in the stub hash table. */
556 1.1 christos
557 1.1 christos static struct bfd_hash_entry *
558 1.1 christos stub_hash_newfunc (struct bfd_hash_entry *entry,
559 1.1 christos struct bfd_hash_table *table, const char *string)
560 1.1 christos {
561 1.1 christos /* Allocate the structure if it has not already been allocated by a
562 1.1 christos subclass. */
563 1.1 christos if (entry == NULL)
564 1.1 christos {
565 1.1 christos entry = bfd_hash_allocate (table,
566 1.1 christos sizeof (struct
567 1.1 christos elf_kvx_stub_hash_entry));
568 1.1 christos if (entry == NULL)
569 1.1 christos return entry;
570 1.1 christos }
571 1.1 christos
572 1.1 christos /* Call the allocation method of the superclass. */
573 1.1 christos entry = bfd_hash_newfunc (entry, table, string);
574 1.1 christos if (entry != NULL)
575 1.1 christos {
576 1.1 christos struct elf_kvx_stub_hash_entry *eh;
577 1.1 christos
578 1.1 christos /* Initialize the local fields. */
579 1.1 christos eh = (struct elf_kvx_stub_hash_entry *) entry;
580 1.1 christos eh->stub_sec = NULL;
581 1.1 christos eh->stub_offset = 0;
582 1.1 christos eh->target_value = 0;
583 1.1 christos eh->target_section = NULL;
584 1.1 christos eh->stub_type = kvx_stub_none;
585 1.1 christos eh->h = NULL;
586 1.1 christos eh->id_sec = NULL;
587 1.1 christos }
588 1.1 christos
589 1.1 christos return entry;
590 1.1 christos }
591 1.1 christos
592 1.1 christos /* Copy the extra info we tack onto an elf_link_hash_entry. */
593 1.1 christos
594 1.1 christos static void
595 1.1 christos elfNN_kvx_copy_indirect_symbol (struct bfd_link_info *info,
596 1.1 christos struct elf_link_hash_entry *dir,
597 1.1 christos struct elf_link_hash_entry *ind)
598 1.1 christos {
599 1.1 christos struct elf_kvx_link_hash_entry *edir, *eind;
600 1.1 christos
601 1.1 christos edir = (struct elf_kvx_link_hash_entry *) dir;
602 1.1 christos eind = (struct elf_kvx_link_hash_entry *) ind;
603 1.1 christos
604 1.1 christos if (ind->root.type == bfd_link_hash_indirect)
605 1.1 christos {
606 1.1 christos /* Copy over PLT info. */
607 1.1 christos if (dir->got.refcount <= 0)
608 1.1 christos {
609 1.1 christos edir->got_type = eind->got_type;
610 1.1 christos eind->got_type = GOT_UNKNOWN;
611 1.1 christos }
612 1.1 christos }
613 1.1 christos
614 1.1 christos _bfd_elf_link_hash_copy_indirect (info, dir, ind);
615 1.1 christos }
616 1.1 christos
617 1.1 christos /* Destroy a KVX elf linker hash table. */
618 1.1 christos
619 1.1 christos static void
620 1.1 christos elfNN_kvx_link_hash_table_free (bfd *obfd)
621 1.1 christos {
622 1.1 christos struct elf_kvx_link_hash_table *ret
623 1.1 christos = (struct elf_kvx_link_hash_table *) obfd->link.hash;
624 1.1 christos
625 1.1 christos bfd_hash_table_free (&ret->stub_hash_table);
626 1.1 christos _bfd_elf_link_hash_table_free (obfd);
627 1.1 christos }
628 1.1 christos
629 1.1 christos /* Create a KVX elf linker hash table. */
630 1.1 christos
631 1.1 christos static struct bfd_link_hash_table *
632 1.1 christos elfNN_kvx_link_hash_table_create (bfd *abfd)
633 1.1 christos {
634 1.1 christos struct elf_kvx_link_hash_table *ret;
635 1.1 christos bfd_size_type amt = sizeof (struct elf_kvx_link_hash_table);
636 1.1 christos
637 1.1 christos ret = bfd_zmalloc (amt);
638 1.1 christos if (ret == NULL)
639 1.1 christos return NULL;
640 1.1 christos
641 1.1 christos if (!_bfd_elf_link_hash_table_init
642 1.1 christos (&ret->root, abfd, elfNN_kvx_link_hash_newfunc,
643 1.1.1.2 christos sizeof (struct elf_kvx_link_hash_entry)))
644 1.1 christos {
645 1.1 christos free (ret);
646 1.1 christos return NULL;
647 1.1 christos }
648 1.1 christos
649 1.1 christos ret->plt_header_size = PLT_ENTRY_SIZE;
650 1.1 christos ret->plt_entry_size = PLT_SMALL_ENTRY_SIZE;
651 1.1 christos ret->plt_entry = elfNN_kvx_small_plt_entry;
652 1.1 christos
653 1.1 christos ret->obfd = abfd;
654 1.1 christos
655 1.1 christos if (!bfd_hash_table_init (&ret->stub_hash_table, stub_hash_newfunc,
656 1.1 christos sizeof (struct elf_kvx_stub_hash_entry)))
657 1.1 christos {
658 1.1 christos _bfd_elf_link_hash_table_free (abfd);
659 1.1 christos return NULL;
660 1.1 christos }
661 1.1 christos
662 1.1 christos ret->root.root.hash_table_free = elfNN_kvx_link_hash_table_free;
663 1.1 christos
664 1.1 christos return &ret->root.root;
665 1.1 christos }
666 1.1 christos
667 1.1 christos static bfd_reloc_status_type
668 1.1 christos kvx_relocate (unsigned int r_type, bfd *input_bfd, asection *input_section,
669 1.1 christos bfd_vma offset, bfd_vma value)
670 1.1 christos {
671 1.1 christos reloc_howto_type *howto;
672 1.1 christos
673 1.1 christos howto = elfNN_kvx_howto_from_type (input_bfd, r_type);
674 1.1 christos r_type = elfNN_kvx_bfd_reloc_from_type (input_bfd, r_type);
675 1.1 christos return _bfd_kvx_elf_put_addend (input_bfd,
676 1.1 christos input_section->contents + offset, r_type,
677 1.1 christos howto, value);
678 1.1 christos }
679 1.1 christos
680 1.1 christos /* Determine the type of stub needed, if any, for a call. */
681 1.1 christos
682 1.1 christos static enum elf_kvx_stub_type
683 1.1 christos kvx_type_of_stub (asection *input_sec,
684 1.1 christos const Elf_Internal_Rela *rel,
685 1.1 christos asection *sym_sec,
686 1.1 christos unsigned char st_type,
687 1.1 christos bfd_vma destination)
688 1.1 christos {
689 1.1 christos bfd_vma location;
690 1.1 christos bfd_signed_vma branch_offset;
691 1.1 christos unsigned int r_type;
692 1.1 christos enum elf_kvx_stub_type stub_type = kvx_stub_none;
693 1.1 christos
694 1.1 christos if (st_type != STT_FUNC
695 1.1 christos && (sym_sec == input_sec))
696 1.1 christos return stub_type;
697 1.1 christos
698 1.1 christos /* Determine where the call point is. */
699 1.1 christos location = (input_sec->output_offset
700 1.1 christos + input_sec->output_section->vma + rel->r_offset);
701 1.1 christos
702 1.1 christos branch_offset = (bfd_signed_vma) (destination - location);
703 1.1 christos
704 1.1 christos r_type = ELFNN_R_TYPE (rel->r_info);
705 1.1 christos
706 1.1 christos /* We don't want to redirect any old unconditional jump in this way,
707 1.1 christos only one which is being used for a sibcall, where it is
708 1.1 christos acceptable for the R16 and R17 registers to be clobbered. */
709 1.1 christos if (r_type == R_KVX_PCREL27
710 1.1 christos && (branch_offset > KVX_MAX_FWD_CALL_OFFSET
711 1.1 christos || branch_offset < KVX_MAX_BWD_CALL_OFFSET))
712 1.1 christos {
713 1.1 christos stub_type = kvx_stub_long_branch;
714 1.1 christos }
715 1.1 christos
716 1.1 christos return stub_type;
717 1.1 christos }
718 1.1 christos
719 1.1 christos /* Build a name for an entry in the stub hash table. */
720 1.1 christos
721 1.1 christos static char *
722 1.1 christos elfNN_kvx_stub_name (const asection *input_section,
723 1.1 christos const asection *sym_sec,
724 1.1 christos const struct elf_kvx_link_hash_entry *hash,
725 1.1 christos const Elf_Internal_Rela *rel)
726 1.1 christos {
727 1.1 christos char *stub_name;
728 1.1 christos bfd_size_type len;
729 1.1 christos
730 1.1 christos if (hash)
731 1.1 christos {
732 1.1 christos len = 8 + 1 + strlen (hash->root.root.root.string) + 1 + 16 + 1;
733 1.1 christos stub_name = bfd_malloc (len);
734 1.1 christos if (stub_name != NULL)
735 1.1 christos snprintf (stub_name, len, "%08x_%s+%" PRIx64 "x",
736 1.1 christos (unsigned int) input_section->id,
737 1.1 christos hash->root.root.root.string,
738 1.1 christos (uint64_t) rel->r_addend);
739 1.1 christos }
740 1.1 christos else
741 1.1 christos {
742 1.1 christos len = 8 + 1 + 8 + 1 + 8 + 1 + 16 + 1;
743 1.1 christos stub_name = bfd_malloc (len);
744 1.1 christos if (stub_name != NULL)
745 1.1 christos snprintf (stub_name, len, "%08x_%x:%x+%" PRIx64 "x",
746 1.1 christos (unsigned int) input_section->id,
747 1.1 christos (unsigned int) sym_sec->id,
748 1.1 christos (unsigned int) ELFNN_R_SYM (rel->r_info),
749 1.1 christos (uint64_t) rel->r_addend);
750 1.1 christos }
751 1.1 christos
752 1.1 christos return stub_name;
753 1.1 christos }
754 1.1 christos
755 1.1 christos /* Return true if symbol H should be hashed in the `.gnu.hash' section. For
756 1.1 christos executable PLT slots where the executable never takes the address of those
757 1.1 christos functions, the function symbols are not added to the hash table. */
758 1.1 christos
759 1.1 christos static bool
760 1.1 christos elf_kvx_hash_symbol (struct elf_link_hash_entry *h)
761 1.1 christos {
762 1.1 christos if (h->plt.offset != (bfd_vma) -1
763 1.1 christos && !h->def_regular
764 1.1 christos && !h->pointer_equality_needed)
765 1.1 christos return false;
766 1.1 christos
767 1.1 christos return _bfd_elf_hash_symbol (h);
768 1.1 christos }
769 1.1 christos
770 1.1 christos
771 1.1 christos /* Look up an entry in the stub hash. Stub entries are cached because
772 1.1 christos creating the stub name takes a bit of time. */
773 1.1 christos
774 1.1 christos static struct elf_kvx_stub_hash_entry *
775 1.1 christos elfNN_kvx_get_stub_entry (const asection *input_section,
776 1.1 christos const asection *sym_sec,
777 1.1 christos struct elf_link_hash_entry *hash,
778 1.1 christos const Elf_Internal_Rela *rel,
779 1.1 christos struct elf_kvx_link_hash_table *htab)
780 1.1 christos {
781 1.1 christos struct elf_kvx_stub_hash_entry *stub_entry;
782 1.1 christos struct elf_kvx_link_hash_entry *h =
783 1.1 christos (struct elf_kvx_link_hash_entry *) hash;
784 1.1 christos const asection *id_sec;
785 1.1 christos
786 1.1 christos if ((input_section->flags & SEC_CODE) == 0)
787 1.1 christos return NULL;
788 1.1 christos
789 1.1 christos /* If this input section is part of a group of sections sharing one
790 1.1 christos stub section, then use the id of the first section in the group.
791 1.1 christos Stub names need to include a section id, as there may well be
792 1.1 christos more than one stub used to reach say, printf, and we need to
793 1.1 christos distinguish between them. */
794 1.1 christos id_sec = htab->stub_group[input_section->id].link_sec;
795 1.1 christos
796 1.1 christos if (h != NULL && h->stub_cache != NULL
797 1.1 christos && h->stub_cache->h == h && h->stub_cache->id_sec == id_sec)
798 1.1 christos {
799 1.1 christos stub_entry = h->stub_cache;
800 1.1 christos }
801 1.1 christos else
802 1.1 christos {
803 1.1 christos char *stub_name;
804 1.1 christos
805 1.1 christos stub_name = elfNN_kvx_stub_name (id_sec, sym_sec, h, rel);
806 1.1 christos if (stub_name == NULL)
807 1.1 christos return NULL;
808 1.1 christos
809 1.1 christos stub_entry = kvx_stub_hash_lookup (&htab->stub_hash_table,
810 1.1 christos stub_name, false, false);
811 1.1 christos if (h != NULL)
812 1.1 christos h->stub_cache = stub_entry;
813 1.1 christos
814 1.1 christos free (stub_name);
815 1.1 christos }
816 1.1 christos
817 1.1 christos return stub_entry;
818 1.1 christos }
819 1.1 christos
820 1.1 christos
821 1.1 christos /* Create a stub section. */
822 1.1 christos
823 1.1 christos static asection *
824 1.1 christos _bfd_kvx_create_stub_section (asection *section,
825 1.1 christos struct elf_kvx_link_hash_table *htab)
826 1.1 christos
827 1.1 christos {
828 1.1 christos size_t namelen;
829 1.1 christos bfd_size_type len;
830 1.1 christos char *s_name;
831 1.1 christos
832 1.1 christos namelen = strlen (section->name);
833 1.1 christos len = namelen + sizeof (STUB_SUFFIX);
834 1.1 christos s_name = bfd_alloc (htab->stub_bfd, len);
835 1.1 christos if (s_name == NULL)
836 1.1 christos return NULL;
837 1.1 christos
838 1.1 christos memcpy (s_name, section->name, namelen);
839 1.1 christos memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
840 1.1 christos return (*htab->add_stub_section) (s_name, section);
841 1.1 christos }
842 1.1 christos
843 1.1 christos
844 1.1 christos /* Find or create a stub section for a link section.
845 1.1 christos
846 1.1 christos Fix or create the stub section used to collect stubs attached to
847 1.1 christos the specified link section. */
848 1.1 christos
849 1.1 christos static asection *
850 1.1 christos _bfd_kvx_get_stub_for_link_section (asection *link_section,
851 1.1 christos struct elf_kvx_link_hash_table *htab)
852 1.1 christos {
853 1.1 christos if (htab->stub_group[link_section->id].stub_sec == NULL)
854 1.1 christos htab->stub_group[link_section->id].stub_sec
855 1.1 christos = _bfd_kvx_create_stub_section (link_section, htab);
856 1.1 christos return htab->stub_group[link_section->id].stub_sec;
857 1.1 christos }
858 1.1 christos
859 1.1 christos
860 1.1 christos /* Find or create a stub section in the stub group for an input
861 1.1 christos section. */
862 1.1 christos
863 1.1 christos static asection *
864 1.1 christos _bfd_kvx_create_or_find_stub_sec (asection *section,
865 1.1 christos struct elf_kvx_link_hash_table *htab)
866 1.1 christos {
867 1.1 christos asection *link_sec = htab->stub_group[section->id].link_sec;
868 1.1 christos return _bfd_kvx_get_stub_for_link_section (link_sec, htab);
869 1.1 christos }
870 1.1 christos
871 1.1 christos
872 1.1 christos /* Add a new stub entry in the stub group associated with an input
873 1.1 christos section to the stub hash. Not all fields of the new stub entry are
874 1.1 christos initialised. */
875 1.1 christos
876 1.1 christos static struct elf_kvx_stub_hash_entry *
877 1.1 christos _bfd_kvx_add_stub_entry_in_group (const char *stub_name,
878 1.1 christos asection *section,
879 1.1 christos struct elf_kvx_link_hash_table *htab)
880 1.1 christos {
881 1.1 christos asection *link_sec;
882 1.1 christos asection *stub_sec;
883 1.1 christos struct elf_kvx_stub_hash_entry *stub_entry;
884 1.1 christos
885 1.1 christos link_sec = htab->stub_group[section->id].link_sec;
886 1.1 christos stub_sec = _bfd_kvx_create_or_find_stub_sec (section, htab);
887 1.1 christos
888 1.1 christos /* Enter this entry into the linker stub hash table. */
889 1.1 christos stub_entry = kvx_stub_hash_lookup (&htab->stub_hash_table, stub_name,
890 1.1 christos true, false);
891 1.1 christos if (stub_entry == NULL)
892 1.1 christos {
893 1.1 christos /* xgettext:c-format */
894 1.1 christos _bfd_error_handler (_("%pB: cannot create stub entry %s"),
895 1.1 christos section->owner, stub_name);
896 1.1 christos return NULL;
897 1.1 christos }
898 1.1 christos
899 1.1 christos stub_entry->stub_sec = stub_sec;
900 1.1 christos stub_entry->stub_offset = 0;
901 1.1 christos stub_entry->id_sec = link_sec;
902 1.1 christos
903 1.1 christos return stub_entry;
904 1.1 christos }
905 1.1 christos
906 1.1 christos static bool
907 1.1 christos kvx_build_one_stub (struct bfd_hash_entry *gen_entry,
908 1.1 christos void *in_arg)
909 1.1 christos {
910 1.1 christos struct elf_kvx_stub_hash_entry *stub_entry;
911 1.1 christos asection *stub_sec;
912 1.1 christos bfd *stub_bfd;
913 1.1 christos bfd_byte *loc;
914 1.1 christos bfd_vma sym_value;
915 1.1 christos unsigned int template_size;
916 1.1 christos const uint32_t *template;
917 1.1 christos unsigned int i;
918 1.1 christos struct bfd_link_info *info;
919 1.1 christos
920 1.1 christos /* Massage our args to the form they really have. */
921 1.1 christos stub_entry = (struct elf_kvx_stub_hash_entry *) gen_entry;
922 1.1 christos
923 1.1 christos info = (struct bfd_link_info *) in_arg;
924 1.1 christos
925 1.1 christos /* Fail if the target section could not be assigned to an output
926 1.1 christos section. The user should fix his linker script. */
927 1.1 christos if (stub_entry->target_section->output_section == NULL
928 1.1 christos && info->non_contiguous_regions)
929 1.1.1.2 christos info->callbacks->fatal (_("%P: Could not assign '%pA' to an output section. "
930 1.1 christos "Retry without "
931 1.1 christos "--enable-non-contiguous-regions.\n"),
932 1.1 christos stub_entry->target_section);
933 1.1 christos
934 1.1 christos stub_sec = stub_entry->stub_sec;
935 1.1 christos
936 1.1 christos /* Make a note of the offset within the stubs for this entry. */
937 1.1 christos stub_entry->stub_offset = stub_sec->size;
938 1.1 christos loc = stub_sec->contents + stub_entry->stub_offset;
939 1.1 christos
940 1.1 christos stub_bfd = stub_sec->owner;
941 1.1 christos
942 1.1 christos /* This is the address of the stub destination. */
943 1.1 christos sym_value = (stub_entry->target_value
944 1.1 christos + stub_entry->target_section->output_offset
945 1.1 christos + stub_entry->target_section->output_section->vma);
946 1.1 christos
947 1.1 christos switch (stub_entry->stub_type)
948 1.1 christos {
949 1.1 christos case kvx_stub_long_branch:
950 1.1 christos template = elfNN_kvx_long_branch_stub;
951 1.1 christos template_size = sizeof (elfNN_kvx_long_branch_stub);
952 1.1 christos break;
953 1.1 christos default:
954 1.1 christos abort ();
955 1.1 christos }
956 1.1 christos
957 1.1 christos for (i = 0; i < (template_size / sizeof template[0]); i++)
958 1.1 christos {
959 1.1 christos bfd_putl32 (template[i], loc);
960 1.1 christos loc += 4;
961 1.1 christos }
962 1.1 christos
963 1.1 christos stub_sec->size += template_size;
964 1.1 christos
965 1.1 christos switch (stub_entry->stub_type)
966 1.1 christos {
967 1.1 christos case kvx_stub_long_branch:
968 1.1 christos /* The stub uses a make insn with 43bits immediate.
969 1.1 christos We need to apply 3 relocations:
970 1.1 christos BFD_RELOC_KVX_S43_LO10,
971 1.1 christos BFD_RELOC_KVX_S43_UP27,
972 1.1 christos BFD_RELOC_KVX_S43_EX6. */
973 1.1 christos if (kvx_relocate (R_KVX_S43_LO10, stub_bfd, stub_sec,
974 1.1 christos stub_entry->stub_offset, sym_value) != bfd_reloc_ok)
975 1.1 christos BFD_FAIL ();
976 1.1 christos if (kvx_relocate (R_KVX_S43_EX6, stub_bfd, stub_sec,
977 1.1 christos stub_entry->stub_offset, sym_value) != bfd_reloc_ok)
978 1.1 christos BFD_FAIL ();
979 1.1 christos if (kvx_relocate (R_KVX_S43_UP27, stub_bfd, stub_sec,
980 1.1 christos stub_entry->stub_offset + 4, sym_value) != bfd_reloc_ok)
981 1.1 christos BFD_FAIL ();
982 1.1 christos break;
983 1.1 christos default:
984 1.1 christos abort ();
985 1.1 christos }
986 1.1 christos
987 1.1 christos return true;
988 1.1 christos }
989 1.1 christos
990 1.1 christos /* As above, but don't actually build the stub. Just bump offset so
991 1.1 christos we know stub section sizes. */
992 1.1 christos
993 1.1 christos static bool
994 1.1 christos kvx_size_one_stub (struct bfd_hash_entry *gen_entry,
995 1.1 christos void *in_arg ATTRIBUTE_UNUSED)
996 1.1 christos {
997 1.1 christos struct elf_kvx_stub_hash_entry *stub_entry;
998 1.1 christos int size;
999 1.1 christos
1000 1.1 christos /* Massage our args to the form they really have. */
1001 1.1 christos stub_entry = (struct elf_kvx_stub_hash_entry *) gen_entry;
1002 1.1 christos
1003 1.1 christos switch (stub_entry->stub_type)
1004 1.1 christos {
1005 1.1 christos case kvx_stub_long_branch:
1006 1.1 christos size = sizeof (elfNN_kvx_long_branch_stub);
1007 1.1 christos break;
1008 1.1 christos default:
1009 1.1 christos abort ();
1010 1.1 christos }
1011 1.1 christos
1012 1.1 christos stub_entry->stub_sec->size += size;
1013 1.1 christos return true;
1014 1.1 christos }
1015 1.1 christos
1016 1.1 christos /* External entry points for sizing and building linker stubs. */
1017 1.1 christos
1018 1.1 christos /* Set up various things so that we can make a list of input sections
1019 1.1 christos for each output section included in the link. Returns -1 on error,
1020 1.1 christos 0 when no stubs will be needed, and 1 on success. */
1021 1.1 christos
1022 1.1 christos int
1023 1.1 christos elfNN_kvx_setup_section_lists (bfd *output_bfd,
1024 1.1 christos struct bfd_link_info *info)
1025 1.1 christos {
1026 1.1 christos bfd *input_bfd;
1027 1.1 christos unsigned int bfd_count;
1028 1.1 christos unsigned int top_id, top_index;
1029 1.1 christos asection *section;
1030 1.1 christos asection **input_list, **list;
1031 1.1 christos bfd_size_type amt;
1032 1.1 christos struct elf_kvx_link_hash_table *htab =
1033 1.1 christos elf_kvx_hash_table (info);
1034 1.1 christos
1035 1.1 christos if (!is_elf_hash_table ((const struct bfd_link_hash_table *)htab))
1036 1.1 christos return 0;
1037 1.1 christos
1038 1.1 christos /* Count the number of input BFDs and find the top input section id. */
1039 1.1 christos for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
1040 1.1 christos input_bfd != NULL; input_bfd = input_bfd->link.next)
1041 1.1 christos {
1042 1.1 christos bfd_count += 1;
1043 1.1 christos for (section = input_bfd->sections;
1044 1.1 christos section != NULL; section = section->next)
1045 1.1 christos {
1046 1.1 christos if (top_id < section->id)
1047 1.1 christos top_id = section->id;
1048 1.1 christos }
1049 1.1 christos }
1050 1.1 christos htab->bfd_count = bfd_count;
1051 1.1 christos
1052 1.1 christos amt = sizeof (struct map_stub) * (top_id + 1);
1053 1.1 christos htab->stub_group = bfd_zmalloc (amt);
1054 1.1 christos if (htab->stub_group == NULL)
1055 1.1 christos return -1;
1056 1.1 christos
1057 1.1 christos /* We can't use output_bfd->section_count here to find the top output
1058 1.1 christos section index as some sections may have been removed, and
1059 1.1 christos _bfd_strip_section_from_output doesn't renumber the indices. */
1060 1.1 christos for (section = output_bfd->sections, top_index = 0;
1061 1.1 christos section != NULL; section = section->next)
1062 1.1 christos {
1063 1.1 christos if (top_index < section->index)
1064 1.1 christos top_index = section->index;
1065 1.1 christos }
1066 1.1 christos
1067 1.1 christos htab->top_index = top_index;
1068 1.1 christos amt = sizeof (asection *) * (top_index + 1);
1069 1.1 christos input_list = bfd_malloc (amt);
1070 1.1 christos htab->input_list = input_list;
1071 1.1 christos if (input_list == NULL)
1072 1.1 christos return -1;
1073 1.1 christos
1074 1.1 christos /* For sections we aren't interested in, mark their entries with a
1075 1.1 christos value we can check later. */
1076 1.1 christos list = input_list + top_index;
1077 1.1 christos do
1078 1.1 christos *list = bfd_abs_section_ptr;
1079 1.1 christos while (list-- != input_list);
1080 1.1 christos
1081 1.1 christos for (section = output_bfd->sections;
1082 1.1 christos section != NULL; section = section->next)
1083 1.1 christos {
1084 1.1 christos if ((section->flags & SEC_CODE) != 0)
1085 1.1 christos input_list[section->index] = NULL;
1086 1.1 christos }
1087 1.1 christos
1088 1.1 christos return 1;
1089 1.1 christos }
1090 1.1 christos
1091 1.1 christos /* Used by elfNN_kvx_next_input_section and group_sections. */
1092 1.1 christos #define PREV_SEC(sec) (htab->stub_group[(sec)->id].link_sec)
1093 1.1 christos
1094 1.1 christos /* The linker repeatedly calls this function for each input section,
1095 1.1 christos in the order that input sections are linked into output sections.
1096 1.1 christos Build lists of input sections to determine groupings between which
1097 1.1 christos we may insert linker stubs. */
1098 1.1 christos
1099 1.1 christos void
1100 1.1 christos elfNN_kvx_next_input_section (struct bfd_link_info *info, asection *isec)
1101 1.1 christos {
1102 1.1 christos struct elf_kvx_link_hash_table *htab =
1103 1.1 christos elf_kvx_hash_table (info);
1104 1.1 christos
1105 1.1 christos if (isec->output_section->index <= htab->top_index)
1106 1.1 christos {
1107 1.1 christos asection **list = htab->input_list + isec->output_section->index;
1108 1.1 christos
1109 1.1 christos if (*list != bfd_abs_section_ptr)
1110 1.1 christos {
1111 1.1 christos /* Steal the link_sec pointer for our list. */
1112 1.1 christos /* This happens to make the list in reverse order,
1113 1.1 christos which is what we want. */
1114 1.1 christos PREV_SEC (isec) = *list;
1115 1.1 christos *list = isec;
1116 1.1 christos }
1117 1.1 christos }
1118 1.1 christos }
1119 1.1 christos
1120 1.1 christos /* See whether we can group stub sections together. Grouping stub
1121 1.1 christos sections may result in fewer stubs. More importantly, we need to
1122 1.1 christos put all .init* and .fini* stubs at the beginning of the .init or
1123 1.1 christos .fini output sections respectively, because glibc splits the
1124 1.1 christos _init and _fini functions into multiple parts. Putting a stub in
1125 1.1 christos the middle of a function is not a good idea. */
1126 1.1 christos
1127 1.1 christos static void
1128 1.1 christos group_sections (struct elf_kvx_link_hash_table *htab,
1129 1.1 christos bfd_size_type stub_group_size,
1130 1.1 christos bool stubs_always_after_branch)
1131 1.1 christos {
1132 1.1 christos asection **list = htab->input_list;
1133 1.1 christos
1134 1.1 christos do
1135 1.1 christos {
1136 1.1 christos asection *tail = *list;
1137 1.1 christos asection *head;
1138 1.1 christos
1139 1.1 christos if (tail == bfd_abs_section_ptr)
1140 1.1 christos continue;
1141 1.1 christos
1142 1.1 christos /* Reverse the list: we must avoid placing stubs at the
1143 1.1 christos beginning of the section because the beginning of the text
1144 1.1 christos section may be required for an interrupt vector in bare metal
1145 1.1 christos code. */
1146 1.1 christos #define NEXT_SEC PREV_SEC
1147 1.1 christos head = NULL;
1148 1.1 christos while (tail != NULL)
1149 1.1 christos {
1150 1.1 christos /* Pop from tail. */
1151 1.1 christos asection *item = tail;
1152 1.1 christos tail = PREV_SEC (item);
1153 1.1 christos
1154 1.1 christos /* Push on head. */
1155 1.1 christos NEXT_SEC (item) = head;
1156 1.1 christos head = item;
1157 1.1 christos }
1158 1.1 christos
1159 1.1 christos while (head != NULL)
1160 1.1 christos {
1161 1.1 christos asection *curr;
1162 1.1 christos asection *next;
1163 1.1 christos bfd_vma stub_group_start = head->output_offset;
1164 1.1 christos bfd_vma end_of_next;
1165 1.1 christos
1166 1.1 christos curr = head;
1167 1.1 christos while (NEXT_SEC (curr) != NULL)
1168 1.1 christos {
1169 1.1 christos next = NEXT_SEC (curr);
1170 1.1 christos end_of_next = next->output_offset + next->size;
1171 1.1 christos if (end_of_next - stub_group_start >= stub_group_size)
1172 1.1 christos /* End of NEXT is too far from start, so stop. */
1173 1.1 christos break;
1174 1.1 christos /* Add NEXT to the group. */
1175 1.1 christos curr = next;
1176 1.1 christos }
1177 1.1 christos
1178 1.1 christos /* OK, the size from the start to the start of CURR is less
1179 1.1 christos than stub_group_size and thus can be handled by one stub
1180 1.1 christos section. (Or the head section is itself larger than
1181 1.1 christos stub_group_size, in which case we may be toast.)
1182 1.1 christos We should really be keeping track of the total size of
1183 1.1 christos stubs added here, as stubs contribute to the final output
1184 1.1 christos section size. */
1185 1.1 christos do
1186 1.1 christos {
1187 1.1 christos next = NEXT_SEC (head);
1188 1.1 christos /* Set up this stub group. */
1189 1.1 christos htab->stub_group[head->id].link_sec = curr;
1190 1.1 christos }
1191 1.1 christos while (head != curr && (head = next) != NULL);
1192 1.1 christos
1193 1.1 christos /* But wait, there's more! Input sections up to stub_group_size
1194 1.1 christos bytes after the stub section can be handled by it too. */
1195 1.1 christos if (!stubs_always_after_branch)
1196 1.1 christos {
1197 1.1 christos stub_group_start = curr->output_offset + curr->size;
1198 1.1 christos
1199 1.1 christos while (next != NULL)
1200 1.1 christos {
1201 1.1 christos end_of_next = next->output_offset + next->size;
1202 1.1 christos if (end_of_next - stub_group_start >= stub_group_size)
1203 1.1 christos /* End of NEXT is too far from stubs, so stop. */
1204 1.1 christos break;
1205 1.1 christos /* Add NEXT to the stub group. */
1206 1.1 christos head = next;
1207 1.1 christos next = NEXT_SEC (head);
1208 1.1 christos htab->stub_group[head->id].link_sec = curr;
1209 1.1 christos }
1210 1.1 christos }
1211 1.1 christos head = next;
1212 1.1 christos }
1213 1.1 christos }
1214 1.1 christos while (list++ != htab->input_list + htab->top_index);
1215 1.1 christos
1216 1.1 christos free (htab->input_list);
1217 1.1 christos }
1218 1.1 christos
1219 1.1 christos static void
1220 1.1 christos _bfd_kvx_resize_stubs (struct elf_kvx_link_hash_table *htab)
1221 1.1 christos {
1222 1.1 christos asection *section;
1223 1.1 christos
1224 1.1 christos /* OK, we've added some stubs. Find out the new size of the
1225 1.1 christos stub sections. */
1226 1.1 christos for (section = htab->stub_bfd->sections;
1227 1.1 christos section != NULL; section = section->next)
1228 1.1 christos {
1229 1.1 christos /* Ignore non-stub sections. */
1230 1.1 christos if (!strstr (section->name, STUB_SUFFIX))
1231 1.1 christos continue;
1232 1.1 christos section->size = 0;
1233 1.1 christos }
1234 1.1 christos
1235 1.1 christos bfd_hash_traverse (&htab->stub_hash_table, kvx_size_one_stub, htab);
1236 1.1 christos }
1237 1.1 christos
1238 1.1 christos /* Satisfy the ELF linker by filling in some fields in our fake bfd. */
1239 1.1 christos
1240 1.1 christos bool
1241 1.1 christos kvx_elfNN_init_stub_bfd (struct bfd_link_info *info,
1242 1.1 christos bfd *stub_bfd)
1243 1.1 christos {
1244 1.1 christos struct elf_kvx_link_hash_table *htab;
1245 1.1 christos
1246 1.1 christos elf_elfheader (stub_bfd)->e_ident[EI_CLASS] = ELFCLASSNN;
1247 1.1 christos
1248 1.1 christos /* Always hook our dynamic sections into the first bfd, which is the
1249 1.1 christos linker created stub bfd. This ensures that the GOT header is at
1250 1.1 christos the start of the output TOC section. */
1251 1.1 christos htab = elf_kvx_hash_table (info);
1252 1.1 christos if (htab == NULL)
1253 1.1 christos return false;
1254 1.1 christos
1255 1.1 christos return true;
1256 1.1 christos }
1257 1.1 christos
1258 1.1 christos /* Determine and set the size of the stub section for a final link.
1259 1.1 christos
1260 1.1 christos The basic idea here is to examine all the relocations looking for
1261 1.1 christos PC-relative calls to a target that is unreachable with a 27bits
1262 1.1 christos immediate (found in call and goto). */
1263 1.1 christos
1264 1.1 christos bool
1265 1.1 christos elfNN_kvx_size_stubs (bfd *output_bfd,
1266 1.1 christos bfd *stub_bfd,
1267 1.1 christos struct bfd_link_info *info,
1268 1.1 christos bfd_signed_vma group_size,
1269 1.1 christos asection * (*add_stub_section) (const char *,
1270 1.1 christos asection *),
1271 1.1 christos void (*layout_sections_again) (void))
1272 1.1 christos {
1273 1.1 christos bfd_size_type stub_group_size;
1274 1.1 christos bool stubs_always_before_branch;
1275 1.1 christos bool stub_changed = false;
1276 1.1 christos struct elf_kvx_link_hash_table *htab = elf_kvx_hash_table (info);
1277 1.1 christos
1278 1.1 christos /* Propagate mach to stub bfd, because it may not have been
1279 1.1 christos finalized when we created stub_bfd. */
1280 1.1 christos bfd_set_arch_mach (stub_bfd, bfd_get_arch (output_bfd),
1281 1.1 christos bfd_get_mach (output_bfd));
1282 1.1 christos
1283 1.1 christos /* Stash our params away. */
1284 1.1 christos htab->stub_bfd = stub_bfd;
1285 1.1 christos htab->add_stub_section = add_stub_section;
1286 1.1 christos htab->layout_sections_again = layout_sections_again;
1287 1.1 christos stubs_always_before_branch = group_size < 0;
1288 1.1 christos if (group_size < 0)
1289 1.1 christos stub_group_size = -group_size;
1290 1.1 christos else
1291 1.1 christos stub_group_size = group_size;
1292 1.1 christos
1293 1.1 christos if (stub_group_size == 1)
1294 1.1 christos {
1295 1.1 christos /* Default values. */
1296 1.1 christos /* KVX branch range is +-256MB. The value used is 1MB less. */
1297 1.1 christos stub_group_size = 255 * 1024 * 1024;
1298 1.1 christos }
1299 1.1 christos
1300 1.1 christos group_sections (htab, stub_group_size, stubs_always_before_branch);
1301 1.1 christos
1302 1.1 christos (*htab->layout_sections_again) ();
1303 1.1 christos
1304 1.1 christos while (1)
1305 1.1 christos {
1306 1.1 christos bfd *input_bfd;
1307 1.1 christos
1308 1.1 christos for (input_bfd = info->input_bfds;
1309 1.1 christos input_bfd != NULL; input_bfd = input_bfd->link.next)
1310 1.1 christos {
1311 1.1 christos Elf_Internal_Shdr *symtab_hdr;
1312 1.1 christos asection *section;
1313 1.1 christos Elf_Internal_Sym *local_syms = NULL;
1314 1.1 christos
1315 1.1 christos if (!is_kvx_elf (input_bfd)
1316 1.1 christos || (input_bfd->flags & BFD_LINKER_CREATED) != 0)
1317 1.1 christos continue;
1318 1.1 christos
1319 1.1 christos /* We'll need the symbol table in a second. */
1320 1.1 christos symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1321 1.1 christos if (symtab_hdr->sh_info == 0)
1322 1.1 christos continue;
1323 1.1 christos
1324 1.1 christos /* Walk over each section attached to the input bfd. */
1325 1.1 christos for (section = input_bfd->sections;
1326 1.1 christos section != NULL; section = section->next)
1327 1.1 christos {
1328 1.1 christos Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
1329 1.1 christos
1330 1.1 christos /* If there aren't any relocs, then there's nothing more
1331 1.1 christos to do. */
1332 1.1 christos if ((section->flags & SEC_RELOC) == 0
1333 1.1 christos || section->reloc_count == 0
1334 1.1 christos || (section->flags & SEC_CODE) == 0)
1335 1.1 christos continue;
1336 1.1 christos
1337 1.1 christos /* If this section is a link-once section that will be
1338 1.1 christos discarded, then don't create any stubs. */
1339 1.1 christos if (section->output_section == NULL
1340 1.1 christos || section->output_section->owner != output_bfd)
1341 1.1 christos continue;
1342 1.1 christos
1343 1.1 christos /* Get the relocs. */
1344 1.1 christos internal_relocs
1345 1.1 christos = _bfd_elf_link_read_relocs (input_bfd, section, NULL,
1346 1.1 christos NULL, info->keep_memory);
1347 1.1 christos if (internal_relocs == NULL)
1348 1.1 christos goto error_ret_free_local;
1349 1.1 christos
1350 1.1 christos /* Now examine each relocation. */
1351 1.1 christos irela = internal_relocs;
1352 1.1 christos irelaend = irela + section->reloc_count;
1353 1.1 christos for (; irela < irelaend; irela++)
1354 1.1 christos {
1355 1.1 christos unsigned int r_type, r_indx;
1356 1.1 christos enum elf_kvx_stub_type stub_type;
1357 1.1 christos struct elf_kvx_stub_hash_entry *stub_entry;
1358 1.1 christos asection *sym_sec;
1359 1.1 christos bfd_vma sym_value;
1360 1.1 christos bfd_vma destination;
1361 1.1 christos struct elf_kvx_link_hash_entry *hash;
1362 1.1 christos const char *sym_name;
1363 1.1 christos char *stub_name;
1364 1.1 christos const asection *id_sec;
1365 1.1 christos unsigned char st_type;
1366 1.1 christos bfd_size_type len;
1367 1.1 christos
1368 1.1 christos r_type = ELFNN_R_TYPE (irela->r_info);
1369 1.1 christos r_indx = ELFNN_R_SYM (irela->r_info);
1370 1.1 christos
1371 1.1 christos if (r_type >= (unsigned int) R_KVX_end)
1372 1.1 christos {
1373 1.1 christos bfd_set_error (bfd_error_bad_value);
1374 1.1 christos error_ret_free_internal:
1375 1.1 christos if (elf_section_data (section)->relocs == NULL)
1376 1.1 christos free (internal_relocs);
1377 1.1 christos goto error_ret_free_local;
1378 1.1 christos }
1379 1.1 christos
1380 1.1 christos /* Only look for stubs on unconditional branch and
1381 1.1 christos branch and link instructions. */
1382 1.1 christos /* This catches CALL and GOTO insn */
1383 1.1 christos if (r_type != (unsigned int) R_KVX_PCREL27)
1384 1.1 christos continue;
1385 1.1 christos
1386 1.1 christos /* Now determine the call target, its name, value,
1387 1.1 christos section. */
1388 1.1 christos sym_sec = NULL;
1389 1.1 christos sym_value = 0;
1390 1.1 christos destination = 0;
1391 1.1 christos hash = NULL;
1392 1.1 christos sym_name = NULL;
1393 1.1 christos if (r_indx < symtab_hdr->sh_info)
1394 1.1 christos {
1395 1.1 christos /* It's a local symbol. */
1396 1.1 christos Elf_Internal_Sym *sym;
1397 1.1 christos Elf_Internal_Shdr *hdr;
1398 1.1 christos
1399 1.1 christos if (local_syms == NULL)
1400 1.1 christos {
1401 1.1 christos local_syms
1402 1.1 christos = (Elf_Internal_Sym *) symtab_hdr->contents;
1403 1.1 christos if (local_syms == NULL)
1404 1.1 christos local_syms
1405 1.1 christos = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1406 1.1 christos symtab_hdr->sh_info, 0,
1407 1.1 christos NULL, NULL, NULL);
1408 1.1 christos if (local_syms == NULL)
1409 1.1 christos goto error_ret_free_internal;
1410 1.1 christos }
1411 1.1 christos
1412 1.1 christos sym = local_syms + r_indx;
1413 1.1 christos hdr = elf_elfsections (input_bfd)[sym->st_shndx];
1414 1.1 christos sym_sec = hdr->bfd_section;
1415 1.1 christos if (!sym_sec)
1416 1.1 christos /* This is an undefined symbol. It can never
1417 1.1 christos be resolved. */
1418 1.1 christos continue;
1419 1.1 christos
1420 1.1 christos if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
1421 1.1 christos sym_value = sym->st_value;
1422 1.1 christos destination = (sym_value + irela->r_addend
1423 1.1 christos + sym_sec->output_offset
1424 1.1 christos + sym_sec->output_section->vma);
1425 1.1 christos st_type = ELF_ST_TYPE (sym->st_info);
1426 1.1 christos sym_name
1427 1.1 christos = bfd_elf_string_from_elf_section (input_bfd,
1428 1.1 christos symtab_hdr->sh_link,
1429 1.1 christos sym->st_name);
1430 1.1 christos }
1431 1.1 christos else
1432 1.1 christos {
1433 1.1 christos int e_indx;
1434 1.1 christos
1435 1.1 christos e_indx = r_indx - symtab_hdr->sh_info;
1436 1.1 christos hash = ((struct elf_kvx_link_hash_entry *)
1437 1.1 christos elf_sym_hashes (input_bfd)[e_indx]);
1438 1.1 christos
1439 1.1 christos while (hash->root.root.type == bfd_link_hash_indirect
1440 1.1 christos || hash->root.root.type == bfd_link_hash_warning)
1441 1.1 christos hash = ((struct elf_kvx_link_hash_entry *)
1442 1.1 christos hash->root.root.u.i.link);
1443 1.1 christos
1444 1.1 christos if (hash->root.root.type == bfd_link_hash_defined
1445 1.1 christos || hash->root.root.type == bfd_link_hash_defweak)
1446 1.1 christos {
1447 1.1 christos struct elf_kvx_link_hash_table *globals =
1448 1.1 christos elf_kvx_hash_table (info);
1449 1.1 christos sym_sec = hash->root.root.u.def.section;
1450 1.1 christos sym_value = hash->root.root.u.def.value;
1451 1.1 christos /* For a destination in a shared library,
1452 1.1 christos use the PLT stub as target address to
1453 1.1 christos decide whether a branch stub is
1454 1.1 christos needed. */
1455 1.1 christos if (globals->root.splt != NULL && hash != NULL
1456 1.1 christos && hash->root.plt.offset != (bfd_vma) - 1)
1457 1.1 christos {
1458 1.1 christos sym_sec = globals->root.splt;
1459 1.1 christos sym_value = hash->root.plt.offset;
1460 1.1 christos if (sym_sec->output_section != NULL)
1461 1.1 christos destination = (sym_value
1462 1.1 christos + sym_sec->output_offset
1463 1.1 christos + sym_sec->output_section->vma);
1464 1.1 christos }
1465 1.1 christos else if (sym_sec->output_section != NULL)
1466 1.1 christos destination = (sym_value + irela->r_addend
1467 1.1 christos + sym_sec->output_offset
1468 1.1 christos + sym_sec->output_section->vma);
1469 1.1 christos }
1470 1.1 christos else if (hash->root.root.type == bfd_link_hash_undefined
1471 1.1 christos || (hash->root.root.type
1472 1.1 christos == bfd_link_hash_undefweak))
1473 1.1 christos {
1474 1.1 christos /* For a shared library, use the PLT stub as
1475 1.1 christos target address to decide whether a long
1476 1.1 christos branch stub is needed.
1477 1.1 christos For absolute code, they cannot be handled. */
1478 1.1 christos struct elf_kvx_link_hash_table *globals =
1479 1.1 christos elf_kvx_hash_table (info);
1480 1.1 christos
1481 1.1 christos if (globals->root.splt != NULL && hash != NULL
1482 1.1 christos && hash->root.plt.offset != (bfd_vma) - 1)
1483 1.1 christos {
1484 1.1 christos sym_sec = globals->root.splt;
1485 1.1 christos sym_value = hash->root.plt.offset;
1486 1.1 christos if (sym_sec->output_section != NULL)
1487 1.1 christos destination = (sym_value
1488 1.1 christos + sym_sec->output_offset
1489 1.1 christos + sym_sec->output_section->vma);
1490 1.1 christos }
1491 1.1 christos else
1492 1.1 christos continue;
1493 1.1 christos }
1494 1.1 christos else
1495 1.1 christos {
1496 1.1 christos bfd_set_error (bfd_error_bad_value);
1497 1.1 christos goto error_ret_free_internal;
1498 1.1 christos }
1499 1.1 christos st_type = ELF_ST_TYPE (hash->root.type);
1500 1.1 christos sym_name = hash->root.root.root.string;
1501 1.1 christos }
1502 1.1 christos
1503 1.1 christos /* Determine what (if any) linker stub is needed. */
1504 1.1 christos stub_type = kvx_type_of_stub (section, irela, sym_sec,
1505 1.1 christos st_type, destination);
1506 1.1 christos if (stub_type == kvx_stub_none)
1507 1.1 christos continue;
1508 1.1 christos
1509 1.1 christos /* Support for grouping stub sections. */
1510 1.1 christos id_sec = htab->stub_group[section->id].link_sec;
1511 1.1 christos
1512 1.1 christos /* Get the name of this stub. */
1513 1.1 christos stub_name = elfNN_kvx_stub_name (id_sec, sym_sec, hash,
1514 1.1 christos irela);
1515 1.1 christos if (!stub_name)
1516 1.1 christos goto error_ret_free_internal;
1517 1.1 christos
1518 1.1 christos stub_entry =
1519 1.1 christos kvx_stub_hash_lookup (&htab->stub_hash_table,
1520 1.1 christos stub_name, false, false);
1521 1.1 christos if (stub_entry != NULL)
1522 1.1 christos {
1523 1.1 christos /* The proper stub has already been created. */
1524 1.1 christos free (stub_name);
1525 1.1 christos /* Always update this stub's target since it may have
1526 1.1 christos changed after layout. */
1527 1.1 christos stub_entry->target_value = sym_value + irela->r_addend;
1528 1.1 christos continue;
1529 1.1 christos }
1530 1.1 christos
1531 1.1 christos stub_entry = _bfd_kvx_add_stub_entry_in_group
1532 1.1 christos (stub_name, section, htab);
1533 1.1 christos if (stub_entry == NULL)
1534 1.1 christos {
1535 1.1 christos free (stub_name);
1536 1.1 christos goto error_ret_free_internal;
1537 1.1 christos }
1538 1.1 christos
1539 1.1 christos stub_entry->target_value = sym_value + irela->r_addend;
1540 1.1 christos stub_entry->target_section = sym_sec;
1541 1.1 christos stub_entry->stub_type = stub_type;
1542 1.1 christos stub_entry->h = hash;
1543 1.1 christos stub_entry->st_type = st_type;
1544 1.1 christos
1545 1.1 christos if (sym_name == NULL)
1546 1.1 christos sym_name = "unnamed";
1547 1.1 christos len = sizeof (STUB_ENTRY_NAME) + strlen (sym_name);
1548 1.1 christos stub_entry->output_name = bfd_alloc (htab->stub_bfd, len);
1549 1.1 christos if (stub_entry->output_name == NULL)
1550 1.1 christos {
1551 1.1 christos free (stub_name);
1552 1.1 christos goto error_ret_free_internal;
1553 1.1 christos }
1554 1.1 christos
1555 1.1 christos snprintf (stub_entry->output_name, len, STUB_ENTRY_NAME,
1556 1.1 christos sym_name);
1557 1.1 christos
1558 1.1 christos stub_changed = true;
1559 1.1 christos }
1560 1.1 christos
1561 1.1 christos /* We're done with the internal relocs, free them. */
1562 1.1 christos if (elf_section_data (section)->relocs == NULL)
1563 1.1 christos free (internal_relocs);
1564 1.1 christos }
1565 1.1 christos }
1566 1.1 christos
1567 1.1 christos if (!stub_changed)
1568 1.1 christos break;
1569 1.1 christos
1570 1.1 christos _bfd_kvx_resize_stubs (htab);
1571 1.1 christos
1572 1.1 christos /* Ask the linker to do its stuff. */
1573 1.1 christos (*htab->layout_sections_again) ();
1574 1.1 christos stub_changed = false;
1575 1.1 christos }
1576 1.1 christos
1577 1.1 christos return true;
1578 1.1 christos
1579 1.1 christos error_ret_free_local:
1580 1.1 christos return false;
1581 1.1 christos
1582 1.1 christos }
1583 1.1 christos
1584 1.1 christos /* Build all the stubs associated with the current output file. The
1585 1.1 christos stubs are kept in a hash table attached to the main linker hash
1586 1.1 christos table. We also set up the .plt entries for statically linked PIC
1587 1.1 christos functions here. This function is called via kvx_elf_finish in the
1588 1.1 christos linker. */
1589 1.1 christos
1590 1.1 christos bool
1591 1.1 christos elfNN_kvx_build_stubs (struct bfd_link_info *info)
1592 1.1 christos {
1593 1.1 christos asection *stub_sec;
1594 1.1 christos struct bfd_hash_table *table;
1595 1.1 christos struct elf_kvx_link_hash_table *htab;
1596 1.1 christos
1597 1.1 christos htab = elf_kvx_hash_table (info);
1598 1.1 christos
1599 1.1 christos for (stub_sec = htab->stub_bfd->sections;
1600 1.1 christos stub_sec != NULL; stub_sec = stub_sec->next)
1601 1.1 christos {
1602 1.1 christos bfd_size_type size;
1603 1.1 christos
1604 1.1 christos /* Ignore non-stub sections. */
1605 1.1 christos if (!strstr (stub_sec->name, STUB_SUFFIX))
1606 1.1 christos continue;
1607 1.1 christos
1608 1.1 christos /* Allocate memory to hold the linker stubs. */
1609 1.1 christos size = stub_sec->size;
1610 1.1 christos stub_sec->contents = bfd_zalloc (htab->stub_bfd, size);
1611 1.1 christos if (stub_sec->contents == NULL && size != 0)
1612 1.1 christos return false;
1613 1.1.1.2 christos stub_sec->alloced = 1;
1614 1.1 christos stub_sec->size = 0;
1615 1.1 christos }
1616 1.1 christos
1617 1.1 christos /* Build the stubs as directed by the stub hash table. */
1618 1.1 christos table = &htab->stub_hash_table;
1619 1.1 christos bfd_hash_traverse (table, kvx_build_one_stub, info);
1620 1.1 christos
1621 1.1 christos return true;
1622 1.1 christos }
1623 1.1 christos
1624 1.1 christos static bfd_vma
1625 1.1 christos kvx_calculate_got_entry_vma (struct elf_link_hash_entry *h,
1626 1.1 christos struct elf_kvx_link_hash_table
1627 1.1 christos *globals, struct bfd_link_info *info,
1628 1.1 christos bfd_vma value, bfd *output_bfd,
1629 1.1 christos bool *unresolved_reloc_p)
1630 1.1 christos {
1631 1.1 christos bfd_vma off = (bfd_vma) - 1;
1632 1.1 christos asection *basegot = globals->root.sgot;
1633 1.1 christos bool dyn = globals->root.dynamic_sections_created;
1634 1.1 christos
1635 1.1 christos if (h != NULL)
1636 1.1 christos {
1637 1.1 christos BFD_ASSERT (basegot != NULL);
1638 1.1 christos off = h->got.offset;
1639 1.1 christos BFD_ASSERT (off != (bfd_vma) - 1);
1640 1.1 christos if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
1641 1.1 christos || (bfd_link_pic (info)
1642 1.1 christos && SYMBOL_REFERENCES_LOCAL (info, h))
1643 1.1 christos || (ELF_ST_VISIBILITY (h->other)
1644 1.1 christos && h->root.type == bfd_link_hash_undefweak))
1645 1.1 christos {
1646 1.1 christos /* This is actually a static link, or it is a -Bsymbolic link
1647 1.1 christos and the symbol is defined locally. We must initialize this
1648 1.1 christos entry in the global offset table. Since the offset must
1649 1.1 christos always be a multiple of 8 (4 in the case of ILP32), we use
1650 1.1 christos the least significant bit to record whether we have
1651 1.1 christos initialized it already.
1652 1.1 christos When doing a dynamic link, we create a .rel(a).got relocation
1653 1.1 christos entry to initialize the value. This is done in the
1654 1.1 christos finish_dynamic_symbol routine. */
1655 1.1 christos if ((off & 1) != 0)
1656 1.1 christos off &= ~1;
1657 1.1 christos else
1658 1.1 christos {
1659 1.1 christos bfd_put_NN (output_bfd, value, basegot->contents + off);
1660 1.1 christos h->got.offset |= 1;
1661 1.1 christos }
1662 1.1 christos }
1663 1.1 christos else
1664 1.1 christos *unresolved_reloc_p = false;
1665 1.1 christos }
1666 1.1 christos
1667 1.1 christos return off;
1668 1.1 christos }
1669 1.1 christos
1670 1.1 christos static unsigned int
1671 1.1 christos kvx_reloc_got_type (bfd_reloc_code_real_type r_type)
1672 1.1 christos {
1673 1.1 christos switch (r_type)
1674 1.1 christos {
1675 1.1 christos /* Extracted with:
1676 1.1 christos awk 'match ($0, /HOWTO.*R_(KVX.*_GOT(OFF)?(64)?_.*),/,ary) \
1677 1.1 christos {print "case BFD_RELOC_" ary[1] ":";}' elfxx-kvxc.def */
1678 1.1 christos case BFD_RELOC_KVX_S37_GOTOFF_LO10:
1679 1.1 christos case BFD_RELOC_KVX_S37_GOTOFF_UP27:
1680 1.1 christos
1681 1.1 christos case BFD_RELOC_KVX_S37_GOT_LO10:
1682 1.1 christos case BFD_RELOC_KVX_S37_GOT_UP27:
1683 1.1 christos
1684 1.1 christos case BFD_RELOC_KVX_S43_GOTOFF_LO10:
1685 1.1 christos case BFD_RELOC_KVX_S43_GOTOFF_UP27:
1686 1.1 christos case BFD_RELOC_KVX_S43_GOTOFF_EX6:
1687 1.1 christos
1688 1.1 christos case BFD_RELOC_KVX_S43_GOT_LO10:
1689 1.1 christos case BFD_RELOC_KVX_S43_GOT_UP27:
1690 1.1 christos case BFD_RELOC_KVX_S43_GOT_EX6:
1691 1.1 christos return GOT_NORMAL;
1692 1.1 christos
1693 1.1 christos case BFD_RELOC_KVX_S37_TLS_GD_LO10:
1694 1.1 christos case BFD_RELOC_KVX_S37_TLS_GD_UP27:
1695 1.1 christos case BFD_RELOC_KVX_S43_TLS_GD_LO10:
1696 1.1 christos case BFD_RELOC_KVX_S43_TLS_GD_UP27:
1697 1.1 christos case BFD_RELOC_KVX_S43_TLS_GD_EX6:
1698 1.1 christos return GOT_TLS_GD;
1699 1.1 christos
1700 1.1 christos case BFD_RELOC_KVX_S37_TLS_LD_LO10:
1701 1.1 christos case BFD_RELOC_KVX_S37_TLS_LD_UP27:
1702 1.1 christos case BFD_RELOC_KVX_S43_TLS_LD_LO10:
1703 1.1 christos case BFD_RELOC_KVX_S43_TLS_LD_UP27:
1704 1.1 christos case BFD_RELOC_KVX_S43_TLS_LD_EX6:
1705 1.1 christos return GOT_TLS_LD;
1706 1.1 christos
1707 1.1 christos case BFD_RELOC_KVX_S37_TLS_IE_LO10:
1708 1.1 christos case BFD_RELOC_KVX_S37_TLS_IE_UP27:
1709 1.1 christos case BFD_RELOC_KVX_S43_TLS_IE_LO10:
1710 1.1 christos case BFD_RELOC_KVX_S43_TLS_IE_UP27:
1711 1.1 christos case BFD_RELOC_KVX_S43_TLS_IE_EX6:
1712 1.1 christos return GOT_TLS_IE;
1713 1.1 christos
1714 1.1 christos default:
1715 1.1 christos break;
1716 1.1 christos }
1717 1.1 christos return GOT_UNKNOWN;
1718 1.1 christos }
1719 1.1 christos
1720 1.1 christos static bool
1721 1.1 christos kvx_can_relax_tls (bfd *input_bfd ATTRIBUTE_UNUSED,
1722 1.1 christos struct bfd_link_info *info ATTRIBUTE_UNUSED,
1723 1.1 christos bfd_reloc_code_real_type r_type ATTRIBUTE_UNUSED,
1724 1.1 christos struct elf_link_hash_entry *h ATTRIBUTE_UNUSED,
1725 1.1 christos unsigned long r_symndx ATTRIBUTE_UNUSED)
1726 1.1 christos {
1727 1.1 christos if (! IS_KVX_TLS_RELAX_RELOC (r_type))
1728 1.1 christos return false;
1729 1.1 christos
1730 1.1 christos /* Relaxing hook. Disabled on KVX. */
1731 1.1 christos /* See elfnn-aarch64.c */
1732 1.1 christos return true;
1733 1.1 christos }
1734 1.1 christos
1735 1.1 christos /* Given the relocation code R_TYPE, return the relaxed bfd reloc
1736 1.1 christos enumerator. */
1737 1.1 christos
1738 1.1 christos static bfd_reloc_code_real_type
1739 1.1 christos kvx_tls_transition (bfd *input_bfd,
1740 1.1 christos struct bfd_link_info *info,
1741 1.1 christos unsigned int r_type,
1742 1.1 christos struct elf_link_hash_entry *h,
1743 1.1 christos unsigned long r_symndx)
1744 1.1 christos {
1745 1.1 christos bfd_reloc_code_real_type bfd_r_type
1746 1.1 christos = elfNN_kvx_bfd_reloc_from_type (input_bfd, r_type);
1747 1.1 christos
1748 1.1 christos if (! kvx_can_relax_tls (input_bfd, info, bfd_r_type, h, r_symndx))
1749 1.1 christos return bfd_r_type;
1750 1.1 christos
1751 1.1 christos return bfd_r_type;
1752 1.1 christos }
1753 1.1 christos
1754 1.1 christos /* Return the base VMA address which should be subtracted from real addresses
1755 1.1 christos when resolving R_KVX_*_TLS_GD_* and R_KVX_*_TLS_LD_* relocation. */
1756 1.1 christos
1757 1.1 christos static bfd_vma
1758 1.1 christos dtpoff_base (struct bfd_link_info *info)
1759 1.1 christos {
1760 1.1 christos /* If tls_sec is NULL, we should have signalled an error already. */
1761 1.1 christos BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
1762 1.1 christos return elf_hash_table (info)->tls_sec->vma;
1763 1.1 christos }
1764 1.1 christos
1765 1.1 christos /* Return the base VMA address which should be subtracted from real addresses
1766 1.1 christos when resolving R_KVX_*_TLS_IE_* and R_KVX_*_TLS_LE_* relocations. */
1767 1.1 christos
1768 1.1 christos static bfd_vma
1769 1.1 christos tpoff_base (struct bfd_link_info *info)
1770 1.1 christos {
1771 1.1 christos struct elf_link_hash_table *htab = elf_hash_table (info);
1772 1.1 christos
1773 1.1 christos /* If tls_sec is NULL, we should have signalled an error already. */
1774 1.1 christos BFD_ASSERT (htab->tls_sec != NULL);
1775 1.1 christos
1776 1.1 christos bfd_vma base = align_power ((bfd_vma) 0,
1777 1.1 christos htab->tls_sec->alignment_power);
1778 1.1 christos return htab->tls_sec->vma - base;
1779 1.1 christos }
1780 1.1 christos
1781 1.1 christos static bfd_vma *
1782 1.1 christos symbol_got_offset_ref (bfd *input_bfd, struct elf_link_hash_entry *h,
1783 1.1 christos unsigned long r_symndx)
1784 1.1 christos {
1785 1.1 christos /* Calculate the address of the GOT entry for symbol
1786 1.1 christos referred to in h. */
1787 1.1 christos if (h != NULL)
1788 1.1 christos return &h->got.offset;
1789 1.1 christos else
1790 1.1 christos {
1791 1.1 christos /* local symbol */
1792 1.1 christos struct elf_kvx_local_symbol *l;
1793 1.1 christos
1794 1.1 christos l = elf_kvx_locals (input_bfd);
1795 1.1 christos return &l[r_symndx].got_offset;
1796 1.1 christos }
1797 1.1 christos }
1798 1.1 christos
1799 1.1 christos static void
1800 1.1 christos symbol_got_offset_mark (bfd *input_bfd, struct elf_link_hash_entry *h,
1801 1.1 christos unsigned long r_symndx)
1802 1.1 christos {
1803 1.1 christos bfd_vma *p;
1804 1.1 christos p = symbol_got_offset_ref (input_bfd, h, r_symndx);
1805 1.1 christos *p |= 1;
1806 1.1 christos }
1807 1.1 christos
1808 1.1 christos static int
1809 1.1 christos symbol_got_offset_mark_p (bfd *input_bfd, struct elf_link_hash_entry *h,
1810 1.1 christos unsigned long r_symndx)
1811 1.1 christos {
1812 1.1 christos bfd_vma value;
1813 1.1 christos value = * symbol_got_offset_ref (input_bfd, h, r_symndx);
1814 1.1 christos return value & 1;
1815 1.1 christos }
1816 1.1 christos
1817 1.1 christos static bfd_vma
1818 1.1 christos symbol_got_offset (bfd *input_bfd, struct elf_link_hash_entry *h,
1819 1.1 christos unsigned long r_symndx)
1820 1.1 christos {
1821 1.1 christos bfd_vma value;
1822 1.1 christos value = * symbol_got_offset_ref (input_bfd, h, r_symndx);
1823 1.1 christos value &= ~1;
1824 1.1 christos return value;
1825 1.1 christos }
1826 1.1 christos
1827 1.1 christos /* N_ONES produces N one bits, without overflowing machine arithmetic. */
1828 1.1 christos #define N_ONES(n) (((((bfd_vma) 1 << ((n) -1)) - 1) << 1) | 1)
1829 1.1 christos
1830 1.1 christos /* This is a copy/paste + modification from
1831 1.1 christos reloc.c:_bfd_relocate_contents. Relocations are applied to 32bits
1832 1.1 christos words, so all overflow checks will overflow for values above
1833 1.1 christos 32bits. */
1834 1.1 christos static bfd_reloc_status_type
1835 1.1 christos check_signed_overflow (enum complain_overflow complain_on_overflow,
1836 1.1 christos bfd_reloc_code_real_type bfd_r_type, bfd *input_bfd,
1837 1.1 christos bfd_vma relocation)
1838 1.1 christos {
1839 1.1 christos bfd_reloc_status_type flag = bfd_reloc_ok;
1840 1.1 christos bfd_vma addrmask, fieldmask, signmask, ss;
1841 1.1 christos bfd_vma a, b, sum;
1842 1.1 christos bfd_vma x = 0;
1843 1.1 christos
1844 1.1 christos /* These usually come from howto struct. As we don't check for
1845 1.1 christos values fitting in bitfields or in subpart of words, we set all
1846 1.1 christos these to values to check as if the field is starting from first
1847 1.1 christos bit. */
1848 1.1 christos unsigned int rightshift = 0;
1849 1.1 christos unsigned int bitpos = 0;
1850 1.1 christos unsigned int bitsize = 0;
1851 1.1 christos bfd_vma src_mask = -1;
1852 1.1 christos
1853 1.1 christos /* Only regular symbol relocations are checked here. Others
1854 1.1 christos relocations (GOT, TLS) could be checked if the need is
1855 1.1 christos confirmed. At the moment, we keep previous behavior
1856 1.1 christos (ie. unchecked) for those. */
1857 1.1 christos switch (bfd_r_type)
1858 1.1 christos {
1859 1.1 christos case BFD_RELOC_KVX_S37_LO10:
1860 1.1 christos case BFD_RELOC_KVX_S37_UP27:
1861 1.1 christos bitsize = 37;
1862 1.1 christos break;
1863 1.1 christos
1864 1.1 christos case BFD_RELOC_KVX_S32_LO5:
1865 1.1 christos case BFD_RELOC_KVX_S32_UP27:
1866 1.1 christos bitsize = 32;
1867 1.1 christos break;
1868 1.1 christos
1869 1.1 christos case BFD_RELOC_KVX_S43_LO10:
1870 1.1 christos case BFD_RELOC_KVX_S43_UP27:
1871 1.1 christos case BFD_RELOC_KVX_S43_EX6:
1872 1.1 christos bitsize = 43;
1873 1.1 christos break;
1874 1.1 christos
1875 1.1 christos case BFD_RELOC_KVX_S64_LO10:
1876 1.1 christos case BFD_RELOC_KVX_S64_UP27:
1877 1.1 christos case BFD_RELOC_KVX_S64_EX27:
1878 1.1 christos bitsize = 64;
1879 1.1 christos break;
1880 1.1 christos
1881 1.1 christos default:
1882 1.1 christos return bfd_reloc_ok;
1883 1.1 christos }
1884 1.1 christos
1885 1.1 christos /* direct copy/paste from reloc.c below */
1886 1.1 christos
1887 1.1 christos /* Get the values to be added together. For signed and unsigned
1888 1.1 christos relocations, we assume that all values should be truncated to
1889 1.1 christos the size of an address. For bitfields, all the bits matter.
1890 1.1 christos See also bfd_check_overflow. */
1891 1.1 christos fieldmask = N_ONES (bitsize);
1892 1.1 christos signmask = ~fieldmask;
1893 1.1 christos addrmask = (N_ONES (bfd_arch_bits_per_address (input_bfd))
1894 1.1 christos | (fieldmask << rightshift));
1895 1.1 christos a = (relocation & addrmask) >> rightshift;
1896 1.1 christos b = (x & src_mask & addrmask) >> bitpos;
1897 1.1 christos addrmask >>= rightshift;
1898 1.1 christos
1899 1.1 christos switch (complain_on_overflow)
1900 1.1 christos {
1901 1.1 christos case complain_overflow_signed:
1902 1.1 christos /* If any sign bits are set, all sign bits must be set.
1903 1.1 christos That is, A must be a valid negative address after
1904 1.1 christos shifting. */
1905 1.1 christos signmask = ~(fieldmask >> 1);
1906 1.1 christos /* Fall thru */
1907 1.1 christos
1908 1.1 christos case complain_overflow_bitfield:
1909 1.1 christos /* Much like the signed check, but for a field one bit
1910 1.1 christos wider. We allow a bitfield to represent numbers in the
1911 1.1 christos range -2**n to 2**n-1, where n is the number of bits in the
1912 1.1 christos field. Note that when bfd_vma is 32 bits, a 32-bit reloc
1913 1.1 christos can't overflow, which is exactly what we want. */
1914 1.1 christos ss = a & signmask;
1915 1.1 christos if (ss != 0 && ss != (addrmask & signmask))
1916 1.1 christos flag = bfd_reloc_overflow;
1917 1.1 christos
1918 1.1 christos /* We only need this next bit of code if the sign bit of B
1919 1.1 christos is below the sign bit of A. This would only happen if
1920 1.1 christos SRC_MASK had fewer bits than BITSIZE. Note that if
1921 1.1 christos SRC_MASK has more bits than BITSIZE, we can get into
1922 1.1 christos trouble; we would need to verify that B is in range, as
1923 1.1 christos we do for A above. */
1924 1.1 christos ss = ((~src_mask) >> 1) & src_mask;
1925 1.1 christos ss >>= bitpos;
1926 1.1 christos
1927 1.1 christos /* Set all the bits above the sign bit. */
1928 1.1 christos b = (b ^ ss) - ss;
1929 1.1 christos
1930 1.1 christos /* Now we can do the addition. */
1931 1.1 christos sum = a + b;
1932 1.1 christos
1933 1.1 christos /* See if the result has the correct sign. Bits above the
1934 1.1 christos sign bit are junk now; ignore them. If the sum is
1935 1.1 christos positive, make sure we did not have all negative inputs;
1936 1.1 christos if the sum is negative, make sure we did not have all
1937 1.1 christos positive inputs. The test below looks only at the sign
1938 1.1 christos bits, and it really just
1939 1.1 christos SIGN (A) == SIGN (B) && SIGN (A) != SIGN (SUM)
1940 1.1 christos
1941 1.1 christos We mask with addrmask here to explicitly allow an address
1942 1.1 christos wrap-around. The Linux kernel relies on it, and it is
1943 1.1 christos the only way to write assembler code which can run when
1944 1.1 christos loaded at a location 0x80000000 away from the location at
1945 1.1 christos which it is linked. */
1946 1.1 christos if (((~(a ^ b)) & (a ^ sum)) & signmask & addrmask)
1947 1.1 christos flag = bfd_reloc_overflow;
1948 1.1 christos break;
1949 1.1 christos
1950 1.1 christos case complain_overflow_unsigned:
1951 1.1 christos /* Checking for an unsigned overflow is relatively easy:
1952 1.1 christos trim the addresses and add, and trim the result as well.
1953 1.1 christos Overflow is normally indicated when the result does not
1954 1.1 christos fit in the field. However, we also need to consider the
1955 1.1 christos case when, e.g., fieldmask is 0x7fffffff or smaller, an
1956 1.1 christos input is 0x80000000, and bfd_vma is only 32 bits; then we
1957 1.1 christos will get sum == 0, but there is an overflow, since the
1958 1.1 christos inputs did not fit in the field. Instead of doing a
1959 1.1 christos separate test, we can check for this by or-ing in the
1960 1.1 christos operands when testing for the sum overflowing its final
1961 1.1 christos field. */
1962 1.1 christos sum = (a + b) & addrmask;
1963 1.1 christos if ((a | b | sum) & signmask)
1964 1.1 christos flag = bfd_reloc_overflow;
1965 1.1 christos break;
1966 1.1 christos
1967 1.1 christos default:
1968 1.1 christos abort ();
1969 1.1 christos }
1970 1.1 christos return flag;
1971 1.1 christos }
1972 1.1 christos
1973 1.1 christos /* Perform a relocation as part of a final link. */
1974 1.1 christos static bfd_reloc_status_type
1975 1.1 christos elfNN_kvx_final_link_relocate (reloc_howto_type *howto,
1976 1.1 christos bfd *input_bfd,
1977 1.1 christos bfd *output_bfd,
1978 1.1 christos asection *input_section,
1979 1.1 christos bfd_byte *contents,
1980 1.1 christos Elf_Internal_Rela *rel,
1981 1.1 christos bfd_vma value,
1982 1.1 christos struct bfd_link_info *info,
1983 1.1 christos asection *sym_sec,
1984 1.1 christos struct elf_link_hash_entry *h,
1985 1.1 christos bool *unresolved_reloc_p,
1986 1.1 christos bool save_addend,
1987 1.1 christos bfd_vma *saved_addend,
1988 1.1 christos Elf_Internal_Sym *sym)
1989 1.1 christos {
1990 1.1 christos Elf_Internal_Shdr *symtab_hdr;
1991 1.1 christos unsigned int r_type = howto->type;
1992 1.1 christos bfd_reloc_code_real_type bfd_r_type
1993 1.1 christos = elfNN_kvx_bfd_reloc_from_howto (howto);
1994 1.1 christos bfd_reloc_code_real_type new_bfd_r_type;
1995 1.1 christos unsigned long r_symndx;
1996 1.1 christos bfd_byte *hit_data = contents + rel->r_offset;
1997 1.1 christos bfd_vma place, off;
1998 1.1 christos bfd_vma addend;
1999 1.1 christos struct elf_kvx_link_hash_table *globals;
2000 1.1 christos bool weak_undef_p;
2001 1.1 christos asection *base_got;
2002 1.1 christos bfd_reloc_status_type rret = bfd_reloc_ok;
2003 1.1 christos bool resolved_to_zero;
2004 1.1 christos globals = elf_kvx_hash_table (info);
2005 1.1 christos
2006 1.1 christos symtab_hdr = &elf_symtab_hdr (input_bfd);
2007 1.1 christos
2008 1.1 christos BFD_ASSERT (is_kvx_elf (input_bfd));
2009 1.1 christos
2010 1.1 christos r_symndx = ELFNN_R_SYM (rel->r_info);
2011 1.1 christos
2012 1.1 christos /* It is possible to have linker relaxations on some TLS access
2013 1.1 christos models. Update our information here. */
2014 1.1 christos new_bfd_r_type = kvx_tls_transition (input_bfd, info, r_type, h, r_symndx);
2015 1.1 christos if (new_bfd_r_type != bfd_r_type)
2016 1.1 christos {
2017 1.1 christos bfd_r_type = new_bfd_r_type;
2018 1.1 christos howto = elfNN_kvx_howto_from_bfd_reloc (bfd_r_type);
2019 1.1 christos BFD_ASSERT (howto != NULL);
2020 1.1 christos r_type = howto->type;
2021 1.1 christos }
2022 1.1 christos
2023 1.1 christos place = input_section->output_section->vma
2024 1.1 christos + input_section->output_offset + rel->r_offset;
2025 1.1 christos
2026 1.1 christos /* Get addend, accumulating the addend for consecutive relocs
2027 1.1 christos which refer to the same offset. */
2028 1.1 christos addend = saved_addend ? *saved_addend : 0;
2029 1.1 christos addend += rel->r_addend;
2030 1.1 christos
2031 1.1 christos weak_undef_p = (h ? h->root.type == bfd_link_hash_undefweak
2032 1.1 christos : bfd_is_und_section (sym_sec));
2033 1.1 christos resolved_to_zero = (h != NULL
2034 1.1 christos && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
2035 1.1 christos
2036 1.1 christos switch (bfd_r_type)
2037 1.1 christos {
2038 1.1 christos case BFD_RELOC_KVX_NN:
2039 1.1 christos #if ARCH_SIZE == 64
2040 1.1 christos case BFD_RELOC_KVX_32:
2041 1.1 christos #endif
2042 1.1 christos case BFD_RELOC_KVX_S37_LO10:
2043 1.1 christos case BFD_RELOC_KVX_S37_UP27:
2044 1.1 christos
2045 1.1 christos case BFD_RELOC_KVX_S32_LO5:
2046 1.1 christos case BFD_RELOC_KVX_S32_UP27:
2047 1.1 christos
2048 1.1 christos case BFD_RELOC_KVX_S43_LO10:
2049 1.1 christos case BFD_RELOC_KVX_S43_UP27:
2050 1.1 christos case BFD_RELOC_KVX_S43_EX6:
2051 1.1 christos
2052 1.1 christos case BFD_RELOC_KVX_S64_LO10:
2053 1.1 christos case BFD_RELOC_KVX_S64_UP27:
2054 1.1 christos case BFD_RELOC_KVX_S64_EX27:
2055 1.1.1.2 christos /* When generating a shared library or PIE, these relocations
2056 1.1.1.2 christos are copied into the output file to be resolved at run time. */
2057 1.1.1.2 christos if (bfd_link_pic (info)
2058 1.1 christos && (input_section->flags & SEC_ALLOC)
2059 1.1 christos && (h == NULL
2060 1.1 christos || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
2061 1.1 christos && !resolved_to_zero)
2062 1.1 christos || h->root.type != bfd_link_hash_undefweak))
2063 1.1 christos {
2064 1.1 christos Elf_Internal_Rela outrel;
2065 1.1 christos bfd_byte *loc;
2066 1.1 christos bool skip, relocate;
2067 1.1 christos asection *sreloc;
2068 1.1 christos
2069 1.1 christos *unresolved_reloc_p = false;
2070 1.1 christos
2071 1.1 christos skip = false;
2072 1.1 christos relocate = false;
2073 1.1 christos
2074 1.1 christos outrel.r_addend = addend;
2075 1.1 christos outrel.r_offset =
2076 1.1 christos _bfd_elf_section_offset (output_bfd, info, input_section,
2077 1.1 christos rel->r_offset);
2078 1.1 christos if (outrel.r_offset == (bfd_vma) - 1)
2079 1.1 christos skip = true;
2080 1.1 christos else if (outrel.r_offset == (bfd_vma) - 2)
2081 1.1 christos {
2082 1.1 christos skip = true;
2083 1.1 christos relocate = true;
2084 1.1 christos }
2085 1.1 christos
2086 1.1 christos outrel.r_offset += (input_section->output_section->vma
2087 1.1 christos + input_section->output_offset);
2088 1.1 christos
2089 1.1 christos if (skip)
2090 1.1 christos memset (&outrel, 0, sizeof outrel);
2091 1.1 christos else if (h != NULL
2092 1.1 christos && h->dynindx != -1
2093 1.1 christos && (!bfd_link_pic (info) || !info->symbolic
2094 1.1 christos || !h->def_regular))
2095 1.1 christos outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
2096 1.1 christos else if (bfd_r_type == BFD_RELOC_KVX_32
2097 1.1 christos || bfd_r_type == BFD_RELOC_KVX_64)
2098 1.1 christos {
2099 1.1 christos int symbol;
2100 1.1 christos
2101 1.1 christos /* On SVR4-ish systems, the dynamic loader cannot
2102 1.1 christos relocate the text and data segments independently,
2103 1.1 christos so the symbol does not matter. */
2104 1.1 christos symbol = 0;
2105 1.1 christos outrel.r_info = ELFNN_R_INFO (symbol, R_KVX_RELATIVE);
2106 1.1 christos outrel.r_addend += value;
2107 1.1 christos }
2108 1.1 christos else if (bfd_link_pic (info) && info->symbolic)
2109 1.1 christos {
2110 1.1 christos goto skip_because_pic;
2111 1.1 christos }
2112 1.1 christos else
2113 1.1 christos {
2114 1.1 christos /* We may endup here from bad input code trying to
2115 1.1 christos insert relocation on symbols within code. We do not
2116 1.1 christos want that currently, and such code should use GOT +
2117 1.1 christos KVX_32/64 reloc that translate in KVX_RELATIVE. */
2118 1.1 christos const char *name;
2119 1.1 christos if (h && h->root.root.string)
2120 1.1 christos name = h->root.root.string;
2121 1.1 christos else
2122 1.1 christos name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
2123 1.1 christos NULL);
2124 1.1 christos
2125 1.1 christos (*_bfd_error_handler)
2126 1.1 christos /* xgettext:c-format */
2127 1.1 christos (_("%pB(%pA+%#" PRIx64 "): "
2128 1.1 christos "unresolvable %s relocation in section `%s'"),
2129 1.1 christos input_bfd, input_section, (uint64_t) rel->r_offset, howto->name,
2130 1.1 christos name);
2131 1.1 christos return bfd_reloc_notsupported;
2132 1.1 christos }
2133 1.1 christos
2134 1.1 christos sreloc = elf_section_data (input_section)->sreloc;
2135 1.1 christos if (sreloc == NULL || sreloc->contents == NULL)
2136 1.1 christos return bfd_reloc_notsupported;
2137 1.1 christos
2138 1.1 christos loc = sreloc->contents + sreloc->reloc_count++ * RELOC_SIZE (globals);
2139 1.1 christos bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
2140 1.1 christos
2141 1.1 christos if (sreloc->reloc_count * RELOC_SIZE (globals) > sreloc->size)
2142 1.1 christos {
2143 1.1 christos /* Sanity to check that we have previously allocated
2144 1.1 christos sufficient space in the relocation section for the
2145 1.1 christos number of relocations we actually want to emit. */
2146 1.1 christos abort ();
2147 1.1 christos }
2148 1.1 christos
2149 1.1 christos /* If this reloc is against an external symbol, we do not want to
2150 1.1 christos fiddle with the addend. Otherwise, we need to include the symbol
2151 1.1 christos value so that it becomes an addend for the dynamic reloc. */
2152 1.1 christos if (!relocate)
2153 1.1 christos return bfd_reloc_ok;
2154 1.1 christos
2155 1.1 christos rret = check_signed_overflow (complain_overflow_signed, bfd_r_type,
2156 1.1 christos input_bfd, value + addend);
2157 1.1 christos if (rret != bfd_reloc_ok)
2158 1.1 christos return rret;
2159 1.1 christos
2160 1.1 christos return _bfd_final_link_relocate (howto, input_bfd, input_section,
2161 1.1 christos contents, rel->r_offset, value,
2162 1.1 christos addend);
2163 1.1 christos }
2164 1.1 christos
2165 1.1 christos skip_because_pic:
2166 1.1 christos rret = check_signed_overflow (complain_overflow_signed, bfd_r_type,
2167 1.1 christos input_bfd, value + addend);
2168 1.1 christos if (rret != bfd_reloc_ok)
2169 1.1 christos return rret;
2170 1.1 christos
2171 1.1 christos return _bfd_final_link_relocate (howto, input_bfd, input_section,
2172 1.1 christos contents, rel->r_offset, value,
2173 1.1 christos addend);
2174 1.1 christos break;
2175 1.1 christos
2176 1.1 christos case BFD_RELOC_KVX_PCREL17:
2177 1.1 christos case BFD_RELOC_KVX_PCREL27:
2178 1.1 christos {
2179 1.1 christos /* BCU insn are always first in a bundle, so there is no need
2180 1.1 christos to correct the address using offset within bundle. */
2181 1.1 christos
2182 1.1 christos asection *splt = globals->root.splt;
2183 1.1 christos bool via_plt_p =
2184 1.1 christos splt != NULL && h != NULL && h->plt.offset != (bfd_vma) - 1;
2185 1.1 christos
2186 1.1 christos /* A call to an undefined weak symbol is converted to a jump to
2187 1.1 christos the next instruction unless a PLT entry will be created.
2188 1.1 christos The jump to the next instruction is optimized as a NOP.
2189 1.1 christos Do the same for local undefined symbols. */
2190 1.1 christos if (weak_undef_p && ! via_plt_p)
2191 1.1 christos {
2192 1.1 christos bfd_putl32 (INSN_NOP, hit_data);
2193 1.1 christos return bfd_reloc_ok;
2194 1.1 christos }
2195 1.1 christos
2196 1.1 christos /* If the call goes through a PLT entry, make sure to
2197 1.1 christos check distance to the right destination address. */
2198 1.1 christos if (via_plt_p)
2199 1.1 christos value = (splt->output_section->vma
2200 1.1 christos + splt->output_offset + h->plt.offset);
2201 1.1 christos
2202 1.1 christos /* Check if a stub has to be inserted because the destination
2203 1.1 christos is too far away. */
2204 1.1 christos struct elf_kvx_stub_hash_entry *stub_entry = NULL;
2205 1.1 christos
2206 1.1 christos /* If the target symbol is global and marked as a function the
2207 1.1 christos relocation applies a function call or a tail call. In this
2208 1.1 christos situation we can veneer out of range branches. The veneers
2209 1.1 christos use R16 and R17 hence cannot be used arbitrary out of range
2210 1.1 christos branches that occur within the body of a function. */
2211 1.1 christos
2212 1.1 christos /* Check if a stub has to be inserted because the destination
2213 1.1 christos is too far away. */
2214 1.1 christos if (! kvx_valid_call_p (value, place))
2215 1.1 christos {
2216 1.1 christos /* The target is out of reach, so redirect the branch to
2217 1.1 christos the local stub for this function. */
2218 1.1 christos stub_entry = elfNN_kvx_get_stub_entry (input_section,
2219 1.1 christos sym_sec, h,
2220 1.1 christos rel, globals);
2221 1.1 christos if (stub_entry != NULL)
2222 1.1 christos value = (stub_entry->stub_offset
2223 1.1 christos + stub_entry->stub_sec->output_offset
2224 1.1 christos + stub_entry->stub_sec->output_section->vma);
2225 1.1 christos /* We have redirected the destination to stub entry address,
2226 1.1 christos so ignore any addend record in the original rela entry. */
2227 1.1 christos addend = 0;
2228 1.1 christos }
2229 1.1 christos }
2230 1.1 christos *unresolved_reloc_p = false;
2231 1.1 christos
2232 1.1 christos /* FALLTHROUGH */
2233 1.1 christos
2234 1.1 christos /* PCREL 32 are used in dwarf2 table for exception handling */
2235 1.1 christos case BFD_RELOC_KVX_32_PCREL:
2236 1.1 christos case BFD_RELOC_KVX_S64_PCREL_LO10:
2237 1.1 christos case BFD_RELOC_KVX_S64_PCREL_UP27:
2238 1.1 christos case BFD_RELOC_KVX_S64_PCREL_EX27:
2239 1.1 christos case BFD_RELOC_KVX_S37_PCREL_LO10:
2240 1.1 christos case BFD_RELOC_KVX_S37_PCREL_UP27:
2241 1.1 christos case BFD_RELOC_KVX_S43_PCREL_LO10:
2242 1.1 christos case BFD_RELOC_KVX_S43_PCREL_UP27:
2243 1.1 christos case BFD_RELOC_KVX_S43_PCREL_EX6:
2244 1.1 christos return _bfd_final_link_relocate (howto, input_bfd, input_section,
2245 1.1 christos contents, rel->r_offset, value,
2246 1.1 christos addend);
2247 1.1 christos break;
2248 1.1 christos
2249 1.1 christos case BFD_RELOC_KVX_S37_TLS_LE_LO10:
2250 1.1 christos case BFD_RELOC_KVX_S37_TLS_LE_UP27:
2251 1.1 christos
2252 1.1 christos case BFD_RELOC_KVX_S43_TLS_LE_LO10:
2253 1.1 christos case BFD_RELOC_KVX_S43_TLS_LE_UP27:
2254 1.1 christos case BFD_RELOC_KVX_S43_TLS_LE_EX6:
2255 1.1 christos return _bfd_final_link_relocate (howto, input_bfd, input_section,
2256 1.1 christos contents, rel->r_offset,
2257 1.1 christos value - tpoff_base (info), addend);
2258 1.1 christos break;
2259 1.1 christos
2260 1.1 christos case BFD_RELOC_KVX_S37_TLS_DTPOFF_LO10:
2261 1.1 christos case BFD_RELOC_KVX_S37_TLS_DTPOFF_UP27:
2262 1.1 christos
2263 1.1 christos case BFD_RELOC_KVX_S43_TLS_DTPOFF_LO10:
2264 1.1 christos case BFD_RELOC_KVX_S43_TLS_DTPOFF_UP27:
2265 1.1 christos case BFD_RELOC_KVX_S43_TLS_DTPOFF_EX6:
2266 1.1 christos return _bfd_final_link_relocate (howto, input_bfd, input_section,
2267 1.1 christos contents, rel->r_offset,
2268 1.1 christos value - dtpoff_base (info), addend);
2269 1.1 christos
2270 1.1 christos case BFD_RELOC_KVX_S37_TLS_GD_UP27:
2271 1.1 christos case BFD_RELOC_KVX_S37_TLS_GD_LO10:
2272 1.1 christos
2273 1.1 christos case BFD_RELOC_KVX_S43_TLS_GD_UP27:
2274 1.1 christos case BFD_RELOC_KVX_S43_TLS_GD_EX6:
2275 1.1 christos case BFD_RELOC_KVX_S43_TLS_GD_LO10:
2276 1.1 christos
2277 1.1 christos case BFD_RELOC_KVX_S37_TLS_IE_UP27:
2278 1.1 christos case BFD_RELOC_KVX_S37_TLS_IE_LO10:
2279 1.1 christos
2280 1.1 christos case BFD_RELOC_KVX_S43_TLS_IE_UP27:
2281 1.1 christos case BFD_RELOC_KVX_S43_TLS_IE_EX6:
2282 1.1 christos case BFD_RELOC_KVX_S43_TLS_IE_LO10:
2283 1.1 christos
2284 1.1 christos case BFD_RELOC_KVX_S37_TLS_LD_UP27:
2285 1.1 christos case BFD_RELOC_KVX_S37_TLS_LD_LO10:
2286 1.1 christos
2287 1.1 christos case BFD_RELOC_KVX_S43_TLS_LD_UP27:
2288 1.1 christos case BFD_RELOC_KVX_S43_TLS_LD_EX6:
2289 1.1 christos case BFD_RELOC_KVX_S43_TLS_LD_LO10:
2290 1.1 christos
2291 1.1 christos if (globals->root.sgot == NULL)
2292 1.1 christos return bfd_reloc_notsupported;
2293 1.1 christos value = symbol_got_offset (input_bfd, h, r_symndx);
2294 1.1 christos
2295 1.1 christos _bfd_final_link_relocate (howto, input_bfd, input_section,
2296 1.1 christos contents, rel->r_offset, value, addend);
2297 1.1 christos *unresolved_reloc_p = false;
2298 1.1 christos break;
2299 1.1 christos
2300 1.1 christos case BFD_RELOC_KVX_S37_GOTADDR_UP27:
2301 1.1 christos case BFD_RELOC_KVX_S37_GOTADDR_LO10:
2302 1.1 christos
2303 1.1 christos case BFD_RELOC_KVX_S43_GOTADDR_UP27:
2304 1.1 christos case BFD_RELOC_KVX_S43_GOTADDR_EX6:
2305 1.1 christos case BFD_RELOC_KVX_S43_GOTADDR_LO10:
2306 1.1 christos
2307 1.1 christos case BFD_RELOC_KVX_S64_GOTADDR_UP27:
2308 1.1 christos case BFD_RELOC_KVX_S64_GOTADDR_EX27:
2309 1.1 christos case BFD_RELOC_KVX_S64_GOTADDR_LO10:
2310 1.1 christos {
2311 1.1 christos if (globals->root.sgot == NULL)
2312 1.1 christos BFD_ASSERT (h != NULL);
2313 1.1 christos
2314 1.1 christos value = globals->root.sgot->output_section->vma
2315 1.1 christos + globals->root.sgot->output_offset;
2316 1.1 christos
2317 1.1 christos return _bfd_final_link_relocate (howto, input_bfd, input_section,
2318 1.1 christos contents, rel->r_offset, value,
2319 1.1 christos addend);
2320 1.1 christos }
2321 1.1 christos break;
2322 1.1 christos
2323 1.1 christos case BFD_RELOC_KVX_S37_GOTOFF_LO10:
2324 1.1 christos case BFD_RELOC_KVX_S37_GOTOFF_UP27:
2325 1.1 christos
2326 1.1 christos case BFD_RELOC_KVX_32_GOTOFF:
2327 1.1 christos case BFD_RELOC_KVX_64_GOTOFF:
2328 1.1 christos
2329 1.1 christos case BFD_RELOC_KVX_S43_GOTOFF_LO10:
2330 1.1 christos case BFD_RELOC_KVX_S43_GOTOFF_UP27:
2331 1.1 christos case BFD_RELOC_KVX_S43_GOTOFF_EX6:
2332 1.1 christos
2333 1.1 christos {
2334 1.1 christos asection *basegot = globals->root.sgot;
2335 1.1 christos /* BFD_ASSERT(h == NULL); */
2336 1.1 christos BFD_ASSERT(globals->root.sgot != NULL);
2337 1.1 christos value -= basegot->output_section->vma + basegot->output_offset;
2338 1.1 christos return _bfd_final_link_relocate (howto, input_bfd, input_section,
2339 1.1 christos contents, rel->r_offset, value,
2340 1.1 christos addend);
2341 1.1 christos }
2342 1.1 christos break;
2343 1.1 christos
2344 1.1 christos case BFD_RELOC_KVX_S37_GOT_LO10:
2345 1.1 christos case BFD_RELOC_KVX_S37_GOT_UP27:
2346 1.1 christos
2347 1.1 christos case BFD_RELOC_KVX_32_GOT:
2348 1.1 christos case BFD_RELOC_KVX_64_GOT:
2349 1.1 christos
2350 1.1 christos case BFD_RELOC_KVX_S43_GOT_LO10:
2351 1.1 christos case BFD_RELOC_KVX_S43_GOT_UP27:
2352 1.1 christos case BFD_RELOC_KVX_S43_GOT_EX6:
2353 1.1 christos
2354 1.1 christos if (globals->root.sgot == NULL)
2355 1.1 christos BFD_ASSERT (h != NULL);
2356 1.1 christos
2357 1.1 christos if (h != NULL)
2358 1.1 christos {
2359 1.1 christos value = kvx_calculate_got_entry_vma (h, globals, info, value,
2360 1.1 christos output_bfd,
2361 1.1 christos unresolved_reloc_p);
2362 1.1 christos #ifdef UGLY_DEBUG
2363 1.1 christos printf("GOT_LO/HI for %s, value %x\n", h->root.root.string, value);
2364 1.1 christos #endif
2365 1.1 christos
2366 1.1 christos return _bfd_final_link_relocate (howto, input_bfd, input_section,
2367 1.1 christos contents, rel->r_offset, value,
2368 1.1 christos addend);
2369 1.1 christos }
2370 1.1 christos else
2371 1.1 christos {
2372 1.1 christos #ifdef UGLY_DEBUG
2373 1.1 christos printf("GOT_LO/HI with h NULL, initial value %x\n", value);
2374 1.1 christos #endif
2375 1.1 christos struct elf_kvx_local_symbol *locals = elf_kvx_locals (input_bfd);
2376 1.1 christos
2377 1.1 christos if (locals == NULL)
2378 1.1 christos {
2379 1.1 christos int howto_index = bfd_r_type - BFD_RELOC_KVX_RELOC_START;
2380 1.1 christos _bfd_error_handler
2381 1.1 christos /* xgettext:c-format */
2382 1.1 christos (_("%pB: local symbol descriptor table be NULL when applying "
2383 1.1 christos "relocation %s against local symbol"),
2384 1.1 christos input_bfd, elf_kvx_howto_table[howto_index].name);
2385 1.1 christos abort ();
2386 1.1 christos }
2387 1.1 christos
2388 1.1 christos off = symbol_got_offset (input_bfd, h, r_symndx);
2389 1.1 christos base_got = globals->root.sgot;
2390 1.1 christos bfd_vma got_entry_addr = (base_got->output_section->vma
2391 1.1 christos + base_got->output_offset + off);
2392 1.1 christos
2393 1.1 christos if (!symbol_got_offset_mark_p (input_bfd, h, r_symndx))
2394 1.1 christos {
2395 1.1 christos bfd_put_64 (output_bfd, value, base_got->contents + off);
2396 1.1 christos
2397 1.1 christos if (bfd_link_pic (info))
2398 1.1 christos {
2399 1.1 christos asection *s;
2400 1.1 christos Elf_Internal_Rela outrel;
2401 1.1 christos
2402 1.1 christos /* For PIC executables and shared libraries we need
2403 1.1 christos to relocate the GOT entry at run time. */
2404 1.1 christos s = globals->root.srelgot;
2405 1.1 christos if (s == NULL)
2406 1.1 christos abort ();
2407 1.1 christos
2408 1.1 christos outrel.r_offset = got_entry_addr;
2409 1.1 christos outrel.r_info = ELFNN_R_INFO (0, R_KVX_RELATIVE);
2410 1.1 christos outrel.r_addend = value;
2411 1.1.1.3 christos _bfd_elf_append_rela (output_bfd, s, &outrel);
2412 1.1 christos }
2413 1.1 christos
2414 1.1 christos symbol_got_offset_mark (input_bfd, h, r_symndx);
2415 1.1 christos }
2416 1.1 christos
2417 1.1 christos /* Update the relocation value to GOT entry addr as we have
2418 1.1 christos transformed the direct data access into an indirect data
2419 1.1 christos access through GOT. */
2420 1.1 christos value = got_entry_addr;
2421 1.1 christos
2422 1.1 christos return _bfd_final_link_relocate (howto, input_bfd, input_section,
2423 1.1 christos contents, rel->r_offset, off, 0);
2424 1.1 christos }
2425 1.1 christos break;
2426 1.1 christos
2427 1.1 christos default:
2428 1.1 christos return bfd_reloc_notsupported;
2429 1.1 christos }
2430 1.1 christos
2431 1.1 christos if (saved_addend)
2432 1.1 christos *saved_addend = value;
2433 1.1 christos
2434 1.1 christos /* Only apply the final relocation in a sequence. */
2435 1.1 christos if (save_addend)
2436 1.1 christos return bfd_reloc_continue;
2437 1.1 christos
2438 1.1 christos return _bfd_kvx_elf_put_addend (input_bfd, hit_data, bfd_r_type,
2439 1.1 christos howto, value);
2440 1.1 christos }
2441 1.1 christos
2442 1.1 christos
2443 1.1 christos
2444 1.1 christos /* Relocate a KVX ELF section. */
2445 1.1 christos
2446 1.1 christos static int
2447 1.1 christos elfNN_kvx_relocate_section (bfd *output_bfd,
2448 1.1 christos struct bfd_link_info *info,
2449 1.1 christos bfd *input_bfd,
2450 1.1 christos asection *input_section,
2451 1.1 christos bfd_byte *contents,
2452 1.1 christos Elf_Internal_Rela *relocs,
2453 1.1 christos Elf_Internal_Sym *local_syms,
2454 1.1 christos asection **local_sections)
2455 1.1 christos {
2456 1.1 christos Elf_Internal_Shdr *symtab_hdr;
2457 1.1 christos struct elf_link_hash_entry **sym_hashes;
2458 1.1 christos Elf_Internal_Rela *rel;
2459 1.1 christos Elf_Internal_Rela *relend;
2460 1.1 christos const char *name;
2461 1.1 christos struct elf_kvx_link_hash_table *globals;
2462 1.1 christos bool save_addend = false;
2463 1.1 christos bfd_vma addend = 0;
2464 1.1 christos
2465 1.1 christos globals = elf_kvx_hash_table (info);
2466 1.1 christos
2467 1.1 christos symtab_hdr = &elf_symtab_hdr (input_bfd);
2468 1.1 christos sym_hashes = elf_sym_hashes (input_bfd);
2469 1.1 christos
2470 1.1 christos rel = relocs;
2471 1.1 christos relend = relocs + input_section->reloc_count;
2472 1.1 christos for (; rel < relend; rel++)
2473 1.1 christos {
2474 1.1 christos unsigned int r_type;
2475 1.1 christos bfd_reloc_code_real_type bfd_r_type;
2476 1.1 christos reloc_howto_type *howto;
2477 1.1 christos unsigned long r_symndx;
2478 1.1 christos Elf_Internal_Sym *sym;
2479 1.1 christos asection *sec;
2480 1.1 christos struct elf_link_hash_entry *h;
2481 1.1 christos bfd_vma relocation;
2482 1.1 christos bfd_reloc_status_type r;
2483 1.1 christos arelent bfd_reloc;
2484 1.1 christos char sym_type;
2485 1.1 christos bool unresolved_reloc = false;
2486 1.1 christos char *error_message = NULL;
2487 1.1 christos
2488 1.1 christos r_symndx = ELFNN_R_SYM (rel->r_info);
2489 1.1 christos r_type = ELFNN_R_TYPE (rel->r_info);
2490 1.1 christos
2491 1.1 christos bfd_reloc.howto = elfNN_kvx_howto_from_type (input_bfd, r_type);
2492 1.1 christos howto = bfd_reloc.howto;
2493 1.1 christos
2494 1.1 christos if (howto == NULL)
2495 1.1 christos return _bfd_unrecognized_reloc (input_bfd, input_section, r_type);
2496 1.1 christos
2497 1.1 christos bfd_r_type = elfNN_kvx_bfd_reloc_from_howto (howto);
2498 1.1 christos
2499 1.1 christos h = NULL;
2500 1.1 christos sym = NULL;
2501 1.1 christos sec = NULL;
2502 1.1 christos
2503 1.1 christos if (r_symndx < symtab_hdr->sh_info) /* A local symbol. */
2504 1.1 christos {
2505 1.1 christos sym = local_syms + r_symndx;
2506 1.1 christos sym_type = ELFNN_ST_TYPE (sym->st_info);
2507 1.1 christos sec = local_sections[r_symndx];
2508 1.1 christos
2509 1.1 christos /* An object file might have a reference to a local
2510 1.1 christos undefined symbol. This is a draft object file, but we
2511 1.1 christos should at least do something about it. */
2512 1.1 christos if (r_type != R_KVX_NONE
2513 1.1 christos && r_type != R_KVX_S37_GOTADDR_LO10
2514 1.1 christos && r_type != R_KVX_S37_GOTADDR_UP27
2515 1.1 christos && r_type != R_KVX_S64_GOTADDR_LO10
2516 1.1 christos && r_type != R_KVX_S64_GOTADDR_UP27
2517 1.1 christos && r_type != R_KVX_S64_GOTADDR_EX27
2518 1.1 christos && r_type != R_KVX_S43_GOTADDR_LO10
2519 1.1 christos && r_type != R_KVX_S43_GOTADDR_UP27
2520 1.1 christos && r_type != R_KVX_S43_GOTADDR_EX6
2521 1.1 christos && bfd_is_und_section (sec)
2522 1.1 christos && ELF_ST_BIND (sym->st_info) != STB_WEAK)
2523 1.1 christos (*info->callbacks->undefined_symbol)
2524 1.1 christos (info, bfd_elf_string_from_elf_section
2525 1.1 christos (input_bfd, symtab_hdr->sh_link, sym->st_name),
2526 1.1 christos input_bfd, input_section, rel->r_offset, true);
2527 1.1 christos
2528 1.1 christos relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2529 1.1 christos }
2530 1.1 christos else
2531 1.1 christos {
2532 1.1 christos bool warned, ignored;
2533 1.1 christos
2534 1.1 christos RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2535 1.1 christos r_symndx, symtab_hdr, sym_hashes,
2536 1.1 christos h, sec, relocation,
2537 1.1 christos unresolved_reloc, warned, ignored);
2538 1.1 christos
2539 1.1 christos sym_type = h->type;
2540 1.1 christos }
2541 1.1 christos
2542 1.1 christos if (sec != NULL && discarded_section (sec))
2543 1.1 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
2544 1.1.1.3 christos rel, 1, relend, R_KVX_NONE,
2545 1.1.1.3 christos howto, 0, contents);
2546 1.1 christos
2547 1.1 christos if (bfd_link_relocatable (info))
2548 1.1 christos continue;
2549 1.1 christos
2550 1.1 christos if (h != NULL)
2551 1.1 christos name = h->root.root.string;
2552 1.1 christos else
2553 1.1 christos {
2554 1.1 christos name = (bfd_elf_string_from_elf_section
2555 1.1 christos (input_bfd, symtab_hdr->sh_link, sym->st_name));
2556 1.1 christos if (name == NULL || *name == '\0')
2557 1.1 christos name = bfd_section_name (sec);
2558 1.1 christos }
2559 1.1 christos
2560 1.1 christos if (r_symndx != 0
2561 1.1 christos && r_type != R_KVX_NONE
2562 1.1 christos && (h == NULL
2563 1.1 christos || h->root.type == bfd_link_hash_defined
2564 1.1 christos || h->root.type == bfd_link_hash_defweak)
2565 1.1 christos && IS_KVX_TLS_RELOC (bfd_r_type) != (sym_type == STT_TLS))
2566 1.1 christos {
2567 1.1 christos (*_bfd_error_handler)
2568 1.1 christos ((sym_type == STT_TLS
2569 1.1 christos /* xgettext:c-format */
2570 1.1 christos ? _("%pB(%pA+%#" PRIx64 "): %s used with TLS symbol %s")
2571 1.1 christos /* xgettext:c-format */
2572 1.1 christos : _("%pB(%pA+%#" PRIx64 "): %s used with non-TLS symbol %s")),
2573 1.1 christos input_bfd,
2574 1.1 christos input_section, (uint64_t) rel->r_offset, howto->name, name);
2575 1.1 christos }
2576 1.1 christos
2577 1.1 christos /* Original aarch64 has relaxation handling for TLS here. */
2578 1.1 christos r = bfd_reloc_continue;
2579 1.1 christos
2580 1.1 christos /* There may be multiple consecutive relocations for the
2581 1.1 christos same offset. In that case we are supposed to treat the
2582 1.1 christos output of each relocation as the addend for the next. */
2583 1.1 christos if (rel + 1 < relend
2584 1.1 christos && rel->r_offset == rel[1].r_offset
2585 1.1 christos && ELFNN_R_TYPE (rel[1].r_info) != R_KVX_NONE)
2586 1.1 christos
2587 1.1 christos save_addend = true;
2588 1.1 christos else
2589 1.1 christos save_addend = false;
2590 1.1 christos
2591 1.1 christos if (r == bfd_reloc_continue)
2592 1.1 christos r = elfNN_kvx_final_link_relocate (howto, input_bfd, output_bfd,
2593 1.1 christos input_section, contents, rel,
2594 1.1 christos relocation, info, sec,
2595 1.1 christos h, &unresolved_reloc,
2596 1.1 christos save_addend, &addend, sym);
2597 1.1 christos
2598 1.1 christos switch (elfNN_kvx_bfd_reloc_from_type (input_bfd, r_type))
2599 1.1 christos {
2600 1.1 christos case BFD_RELOC_KVX_S37_TLS_GD_LO10:
2601 1.1 christos case BFD_RELOC_KVX_S37_TLS_GD_UP27:
2602 1.1 christos
2603 1.1 christos case BFD_RELOC_KVX_S43_TLS_GD_LO10:
2604 1.1 christos case BFD_RELOC_KVX_S43_TLS_GD_UP27:
2605 1.1 christos case BFD_RELOC_KVX_S43_TLS_GD_EX6:
2606 1.1 christos
2607 1.1 christos case BFD_RELOC_KVX_S37_TLS_LD_LO10:
2608 1.1 christos case BFD_RELOC_KVX_S37_TLS_LD_UP27:
2609 1.1 christos
2610 1.1 christos case BFD_RELOC_KVX_S43_TLS_LD_LO10:
2611 1.1 christos case BFD_RELOC_KVX_S43_TLS_LD_UP27:
2612 1.1 christos case BFD_RELOC_KVX_S43_TLS_LD_EX6:
2613 1.1 christos
2614 1.1 christos if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
2615 1.1 christos {
2616 1.1 christos bool need_relocs = false;
2617 1.1 christos bfd_byte *loc;
2618 1.1 christos int indx;
2619 1.1 christos bfd_vma off;
2620 1.1 christos
2621 1.1 christos off = symbol_got_offset (input_bfd, h, r_symndx);
2622 1.1 christos indx = h && h->dynindx != -1 ? h->dynindx : 0;
2623 1.1 christos
2624 1.1 christos need_relocs =
2625 1.1 christos (bfd_link_pic (info) || indx != 0) &&
2626 1.1 christos (h == NULL
2627 1.1 christos || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
2628 1.1 christos || h->root.type != bfd_link_hash_undefweak);
2629 1.1 christos
2630 1.1 christos BFD_ASSERT (globals->root.srelgot != NULL);
2631 1.1 christos
2632 1.1 christos if (need_relocs)
2633 1.1 christos {
2634 1.1 christos Elf_Internal_Rela rela;
2635 1.1 christos rela.r_info = ELFNN_R_INFO (indx, R_KVX_64_DTPMOD);
2636 1.1 christos rela.r_addend = 0;
2637 1.1 christos rela.r_offset = globals->root.sgot->output_section->vma +
2638 1.1 christos globals->root.sgot->output_offset + off;
2639 1.1 christos
2640 1.1 christos loc = globals->root.srelgot->contents;
2641 1.1 christos loc += globals->root.srelgot->reloc_count++
2642 1.1 christos * RELOC_SIZE (htab);
2643 1.1 christos bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
2644 1.1 christos
2645 1.1 christos bfd_reloc_code_real_type real_type =
2646 1.1 christos elfNN_kvx_bfd_reloc_from_type (input_bfd, r_type);
2647 1.1 christos
2648 1.1 christos if (real_type == BFD_RELOC_KVX_S37_TLS_LD_LO10
2649 1.1 christos || real_type == BFD_RELOC_KVX_S37_TLS_LD_UP27
2650 1.1 christos || real_type == BFD_RELOC_KVX_S43_TLS_LD_LO10
2651 1.1 christos || real_type == BFD_RELOC_KVX_S43_TLS_LD_UP27
2652 1.1 christos || real_type == BFD_RELOC_KVX_S43_TLS_LD_EX6)
2653 1.1 christos {
2654 1.1 christos /* For local dynamic, don't generate DTPOFF in any case.
2655 1.1 christos Initialize the DTPOFF slot into zero, so we get module
2656 1.1 christos base address when invoke runtime TLS resolver. */
2657 1.1 christos bfd_put_NN (output_bfd, 0,
2658 1.1 christos globals->root.sgot->contents + off
2659 1.1 christos + GOT_ENTRY_SIZE);
2660 1.1 christos }
2661 1.1 christos else if (indx == 0)
2662 1.1 christos {
2663 1.1 christos bfd_put_NN (output_bfd,
2664 1.1 christos relocation - dtpoff_base (info),
2665 1.1 christos globals->root.sgot->contents + off
2666 1.1 christos + GOT_ENTRY_SIZE);
2667 1.1 christos }
2668 1.1 christos else
2669 1.1 christos {
2670 1.1 christos /* This TLS symbol is global. We emit a
2671 1.1 christos relocation to fixup the tls offset at load
2672 1.1 christos time. */
2673 1.1 christos rela.r_info =
2674 1.1 christos ELFNN_R_INFO (indx, R_KVX_64_DTPOFF);
2675 1.1 christos rela.r_addend = 0;
2676 1.1 christos rela.r_offset =
2677 1.1 christos (globals->root.sgot->output_section->vma
2678 1.1 christos + globals->root.sgot->output_offset + off
2679 1.1 christos + GOT_ENTRY_SIZE);
2680 1.1 christos
2681 1.1 christos loc = globals->root.srelgot->contents;
2682 1.1 christos loc += globals->root.srelgot->reloc_count++
2683 1.1 christos * RELOC_SIZE (globals);
2684 1.1 christos bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
2685 1.1 christos bfd_put_NN (output_bfd, (bfd_vma) 0,
2686 1.1 christos globals->root.sgot->contents + off
2687 1.1 christos + GOT_ENTRY_SIZE);
2688 1.1 christos }
2689 1.1 christos }
2690 1.1 christos else
2691 1.1 christos {
2692 1.1 christos bfd_put_NN (output_bfd, (bfd_vma) 1,
2693 1.1 christos globals->root.sgot->contents + off);
2694 1.1 christos bfd_put_NN (output_bfd,
2695 1.1 christos relocation - dtpoff_base (info),
2696 1.1 christos globals->root.sgot->contents + off
2697 1.1 christos + GOT_ENTRY_SIZE);
2698 1.1 christos }
2699 1.1 christos
2700 1.1 christos symbol_got_offset_mark (input_bfd, h, r_symndx);
2701 1.1 christos }
2702 1.1 christos break;
2703 1.1 christos
2704 1.1 christos case BFD_RELOC_KVX_S37_TLS_IE_LO10:
2705 1.1 christos case BFD_RELOC_KVX_S37_TLS_IE_UP27:
2706 1.1 christos
2707 1.1 christos case BFD_RELOC_KVX_S43_TLS_IE_LO10:
2708 1.1 christos case BFD_RELOC_KVX_S43_TLS_IE_UP27:
2709 1.1 christos case BFD_RELOC_KVX_S43_TLS_IE_EX6:
2710 1.1 christos if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
2711 1.1 christos {
2712 1.1 christos bool need_relocs = false;
2713 1.1 christos bfd_byte *loc;
2714 1.1 christos int indx;
2715 1.1 christos bfd_vma off;
2716 1.1 christos
2717 1.1 christos off = symbol_got_offset (input_bfd, h, r_symndx);
2718 1.1 christos
2719 1.1 christos indx = h && h->dynindx != -1 ? h->dynindx : 0;
2720 1.1 christos
2721 1.1 christos need_relocs =
2722 1.1 christos (bfd_link_pic (info) || indx != 0) &&
2723 1.1 christos (h == NULL
2724 1.1 christos || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
2725 1.1 christos || h->root.type != bfd_link_hash_undefweak);
2726 1.1 christos
2727 1.1 christos BFD_ASSERT (globals->root.srelgot != NULL);
2728 1.1 christos
2729 1.1 christos if (need_relocs)
2730 1.1 christos {
2731 1.1 christos Elf_Internal_Rela rela;
2732 1.1 christos
2733 1.1 christos if (indx == 0)
2734 1.1 christos rela.r_addend = relocation - dtpoff_base (info);
2735 1.1 christos else
2736 1.1 christos rela.r_addend = 0;
2737 1.1 christos
2738 1.1 christos rela.r_info = ELFNN_R_INFO (indx, R_KVX_64_TPOFF);
2739 1.1 christos rela.r_offset = globals->root.sgot->output_section->vma +
2740 1.1 christos globals->root.sgot->output_offset + off;
2741 1.1 christos
2742 1.1 christos loc = globals->root.srelgot->contents;
2743 1.1 christos loc += globals->root.srelgot->reloc_count++
2744 1.1 christos * RELOC_SIZE (htab);
2745 1.1 christos
2746 1.1 christos bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
2747 1.1 christos
2748 1.1 christos bfd_put_NN (output_bfd, rela.r_addend,
2749 1.1 christos globals->root.sgot->contents + off);
2750 1.1 christos }
2751 1.1 christos else
2752 1.1 christos bfd_put_NN (output_bfd, relocation - tpoff_base (info),
2753 1.1 christos globals->root.sgot->contents + off);
2754 1.1 christos
2755 1.1 christos symbol_got_offset_mark (input_bfd, h, r_symndx);
2756 1.1 christos }
2757 1.1 christos break;
2758 1.1 christos
2759 1.1 christos default:
2760 1.1 christos break;
2761 1.1 christos }
2762 1.1 christos
2763 1.1 christos /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
2764 1.1 christos because such sections are not SEC_ALLOC and thus ld.so will
2765 1.1 christos not process them. */
2766 1.1 christos if (unresolved_reloc
2767 1.1 christos && !((input_section->flags & SEC_DEBUGGING) != 0
2768 1.1 christos && h->def_dynamic)
2769 1.1 christos && _bfd_elf_section_offset (output_bfd, info, input_section,
2770 1.1 christos +rel->r_offset) != (bfd_vma) - 1)
2771 1.1 christos {
2772 1.1 christos (*_bfd_error_handler)
2773 1.1 christos /* xgettext:c-format */
2774 1.1 christos (_("%pB(%pA+%#" PRIx64 "): "
2775 1.1 christos "unresolvable %s relocation against symbol `%s'"),
2776 1.1 christos input_bfd, input_section, (uint64_t) rel->r_offset, howto->name,
2777 1.1 christos h->root.root.string);
2778 1.1 christos return false;
2779 1.1 christos }
2780 1.1 christos
2781 1.1 christos if (r != bfd_reloc_ok && r != bfd_reloc_continue)
2782 1.1 christos {
2783 1.1 christos switch (r)
2784 1.1 christos {
2785 1.1 christos case bfd_reloc_overflow:
2786 1.1 christos (*info->callbacks->reloc_overflow)
2787 1.1 christos (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
2788 1.1 christos input_bfd, input_section, rel->r_offset);
2789 1.1 christos
2790 1.1 christos /* Original aarch64 code had a check for alignement correctness */
2791 1.1 christos break;
2792 1.1 christos
2793 1.1 christos case bfd_reloc_undefined:
2794 1.1 christos (*info->callbacks->undefined_symbol)
2795 1.1 christos (info, name, input_bfd, input_section, rel->r_offset, true);
2796 1.1 christos break;
2797 1.1 christos
2798 1.1 christos case bfd_reloc_outofrange:
2799 1.1 christos error_message = _("out of range");
2800 1.1 christos goto common_error;
2801 1.1 christos
2802 1.1 christos case bfd_reloc_notsupported:
2803 1.1 christos error_message = _("unsupported relocation");
2804 1.1 christos goto common_error;
2805 1.1 christos
2806 1.1 christos case bfd_reloc_dangerous:
2807 1.1 christos /* error_message should already be set. */
2808 1.1 christos goto common_error;
2809 1.1 christos
2810 1.1 christos default:
2811 1.1 christos error_message = _("unknown error");
2812 1.1 christos /* Fall through. */
2813 1.1 christos
2814 1.1 christos common_error:
2815 1.1 christos BFD_ASSERT (error_message != NULL);
2816 1.1 christos (*info->callbacks->reloc_dangerous)
2817 1.1 christos (info, error_message, input_bfd, input_section, rel->r_offset);
2818 1.1 christos break;
2819 1.1 christos }
2820 1.1 christos }
2821 1.1 christos
2822 1.1 christos if (!save_addend)
2823 1.1 christos addend = 0;
2824 1.1 christos }
2825 1.1 christos
2826 1.1 christos return true;
2827 1.1 christos }
2828 1.1 christos
2829 1.1 christos /* Set the right machine number. */
2830 1.1 christos
2831 1.1 christos static bool
2832 1.1 christos elfNN_kvx_object_p (bfd *abfd)
2833 1.1 christos {
2834 1.1 christos /* must be coherent with default arch in cpu-kvx.c */
2835 1.1 christos int e_set = bfd_mach_kv3_1;
2836 1.1 christos
2837 1.1 christos if (elf_elfheader (abfd)->e_machine == EM_KVX)
2838 1.1 christos {
2839 1.1 christos int e_core = elf_elfheader (abfd)->e_flags & ELF_KVX_CORE_MASK;
2840 1.1 christos switch(e_core)
2841 1.1 christos {
2842 1.1 christos #if ARCH_SIZE == 64
2843 1.1 christos case ELF_KVX_CORE_KV3_1 : e_set = bfd_mach_kv3_1_64; break;
2844 1.1 christos case ELF_KVX_CORE_KV3_2 : e_set = bfd_mach_kv3_2_64; break;
2845 1.1 christos case ELF_KVX_CORE_KV4_1 : e_set = bfd_mach_kv4_1_64; break;
2846 1.1 christos #else
2847 1.1 christos case ELF_KVX_CORE_KV3_1 : e_set = bfd_mach_kv3_1; break;
2848 1.1 christos case ELF_KVX_CORE_KV3_2 : e_set = bfd_mach_kv3_2; break;
2849 1.1 christos case ELF_KVX_CORE_KV4_1 : e_set = bfd_mach_kv4_1; break;
2850 1.1 christos #endif
2851 1.1 christos default:
2852 1.1 christos (*_bfd_error_handler)(_("%s: Bad ELF id: `%d'"),
2853 1.1 christos abfd->filename, e_core);
2854 1.1 christos }
2855 1.1 christos }
2856 1.1 christos return bfd_default_set_arch_mach (abfd, bfd_arch_kvx, e_set);
2857 1.1 christos }
2858 1.1 christos
2859 1.1 christos /* Function to keep KVX specific flags in the ELF header. */
2860 1.1 christos
2861 1.1 christos static bool
2862 1.1 christos elfNN_kvx_set_private_flags (bfd *abfd, flagword flags)
2863 1.1 christos {
2864 1.1 christos if (elf_flags_init (abfd) && elf_elfheader (abfd)->e_flags != flags)
2865 1.1 christos {
2866 1.1 christos }
2867 1.1 christos else
2868 1.1 christos {
2869 1.1 christos elf_elfheader (abfd)->e_flags = flags;
2870 1.1 christos elf_flags_init (abfd) = true;
2871 1.1 christos }
2872 1.1 christos
2873 1.1 christos return true;
2874 1.1 christos }
2875 1.1 christos
2876 1.1 christos /* Merge backend specific data from an object file to the output
2877 1.1 christos object file when linking. */
2878 1.1 christos
2879 1.1 christos static bool
2880 1.1 christos elfNN_kvx_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
2881 1.1 christos {
2882 1.1 christos bfd *obfd = info->output_bfd;
2883 1.1 christos flagword out_flags;
2884 1.1 christos flagword in_flags;
2885 1.1 christos bool flags_compatible = true;
2886 1.1 christos asection *sec;
2887 1.1 christos
2888 1.1 christos /* Check if we have the same endianess. */
2889 1.1 christos if (!_bfd_generic_verify_endian_match (ibfd, info))
2890 1.1 christos return false;
2891 1.1 christos
2892 1.1.1.3 christos if (!is_kvx_elf (ibfd))
2893 1.1 christos return true;
2894 1.1 christos
2895 1.1 christos /* The input BFD must have had its flags initialised. */
2896 1.1 christos /* The following seems bogus to me -- The flags are initialized in
2897 1.1 christos the assembler but I don't think an elf_flags_init field is
2898 1.1 christos written into the object. */
2899 1.1 christos /* BFD_ASSERT (elf_flags_init (ibfd)); */
2900 1.1 christos
2901 1.1 christos if (bfd_get_arch_size (ibfd) != bfd_get_arch_size (obfd))
2902 1.1 christos {
2903 1.1 christos const char *msg;
2904 1.1 christos
2905 1.1 christos if (bfd_get_arch_size (ibfd) == 32
2906 1.1 christos && bfd_get_arch_size (obfd) == 64)
2907 1.1 christos msg = _("%s: compiled as 32-bit object and %s is 64-bit");
2908 1.1 christos else if (bfd_get_arch_size (ibfd) == 64
2909 1.1 christos && bfd_get_arch_size (obfd) == 32)
2910 1.1 christos msg = _("%s: compiled as 64-bit object and %s is 32-bit");
2911 1.1 christos else
2912 1.1 christos msg = _("%s: object size does not match that of target %s");
2913 1.1 christos
2914 1.1 christos (*_bfd_error_handler) (msg, bfd_get_filename (ibfd),
2915 1.1 christos bfd_get_filename (obfd));
2916 1.1 christos bfd_set_error (bfd_error_wrong_format);
2917 1.1 christos return false;
2918 1.1 christos }
2919 1.1 christos
2920 1.1 christos in_flags = elf_elfheader (ibfd)->e_flags;
2921 1.1 christos out_flags = elf_elfheader (obfd)->e_flags;
2922 1.1 christos
2923 1.1 christos if (!elf_flags_init (obfd))
2924 1.1 christos {
2925 1.1 christos /* If the input is the default architecture and had the default
2926 1.1 christos flags then do not bother setting the flags for the output
2927 1.1 christos architecture, instead allow future merges to do this. If no
2928 1.1 christos future merges ever set these flags then they will retain their
2929 1.1 christos uninitialised values, which surprise surprise, correspond
2930 1.1 christos to the default values. */
2931 1.1 christos if (bfd_get_arch_info (ibfd)->the_default
2932 1.1 christos && elf_elfheader (ibfd)->e_flags == 0)
2933 1.1 christos return true;
2934 1.1 christos
2935 1.1 christos elf_flags_init (obfd) = true;
2936 1.1 christos elf_elfheader (obfd)->e_flags = in_flags;
2937 1.1 christos
2938 1.1 christos if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
2939 1.1 christos && bfd_get_arch_info (obfd)->the_default)
2940 1.1 christos return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
2941 1.1 christos bfd_get_mach (ibfd));
2942 1.1 christos
2943 1.1 christos return true;
2944 1.1 christos }
2945 1.1 christos
2946 1.1 christos /* Identical flags must be compatible. */
2947 1.1 christos if (in_flags == out_flags)
2948 1.1 christos return true;
2949 1.1 christos
2950 1.1 christos /* Check to see if the input BFD actually contains any sections. If
2951 1.1 christos not, its flags may not have been initialised either, but it
2952 1.1 christos cannot actually cause any incompatiblity. Do not short-circuit
2953 1.1 christos dynamic objects; their section list may be emptied by
2954 1.1 christos elf_link_add_object_symbols.
2955 1.1 christos
2956 1.1 christos Also check to see if there are no code sections in the input.
2957 1.1 christos In this case there is no need to check for code specific flags.
2958 1.1 christos XXX - do we need to worry about floating-point format compatability
2959 1.1 christos in data sections ? */
2960 1.1 christos if (!(ibfd->flags & DYNAMIC))
2961 1.1 christos {
2962 1.1 christos bool null_input_bfd = true;
2963 1.1 christos bool only_data_sections = true;
2964 1.1 christos
2965 1.1 christos for (sec = ibfd->sections; sec != NULL; sec = sec->next)
2966 1.1 christos {
2967 1.1 christos if ((bfd_section_flags (sec)
2968 1.1 christos & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
2969 1.1 christos == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
2970 1.1 christos only_data_sections = false;
2971 1.1 christos
2972 1.1 christos null_input_bfd = false;
2973 1.1 christos break;
2974 1.1 christos }
2975 1.1 christos
2976 1.1 christos if (null_input_bfd || only_data_sections)
2977 1.1 christos return true;
2978 1.1 christos }
2979 1.1 christos return flags_compatible;
2980 1.1 christos }
2981 1.1 christos
2982 1.1 christos /* Display the flags field. */
2983 1.1 christos
2984 1.1 christos static bool
2985 1.1 christos elfNN_kvx_print_private_bfd_data (bfd *abfd, void *ptr)
2986 1.1 christos {
2987 1.1 christos FILE *file = (FILE *) ptr;
2988 1.1 christos unsigned long flags;
2989 1.1 christos
2990 1.1 christos BFD_ASSERT (abfd != NULL && ptr != NULL);
2991 1.1 christos
2992 1.1 christos /* Print normal ELF private data. */
2993 1.1 christos _bfd_elf_print_private_bfd_data (abfd, ptr);
2994 1.1 christos
2995 1.1 christos flags = elf_elfheader (abfd)->e_flags;
2996 1.1 christos /* Ignore init flag - it may not be set, despite the flags field
2997 1.1 christos containing valid data. */
2998 1.1 christos
2999 1.1 christos /* xgettext:c-format */
3000 1.1 christos fprintf (file, _("Private flags = 0x%lx : "), elf_elfheader (abfd)->e_flags);
3001 1.1 christos if((flags & ELF_KVX_ABI_64B_ADDR_BIT) == ELF_KVX_ABI_64B_ADDR_BIT)
3002 1.1 christos {
3003 1.1 christos if (ELF_KVX_CHECK_CORE(flags,ELF_KVX_CORE_KV3_1))
3004 1.1 christos fprintf (file, _("Coolidge (kv3) V1 64 bits"));
3005 1.1 christos else if (ELF_KVX_CHECK_CORE(flags,ELF_KVX_CORE_KV3_2))
3006 1.1 christos fprintf (file, _("Coolidge (kv3) V2 64 bits"));
3007 1.1 christos else if (ELF_KVX_CHECK_CORE(flags,ELF_KVX_CORE_KV4_1))
3008 1.1 christos fprintf (file, _("Coolidge (kv4) V1 64 bits"));
3009 1.1 christos }
3010 1.1 christos else
3011 1.1 christos {
3012 1.1 christos if (ELF_KVX_CHECK_CORE(flags,ELF_KVX_CORE_KV3_1))
3013 1.1 christos fprintf (file, _("Coolidge (kv3) V1 32 bits"));
3014 1.1 christos else if (ELF_KVX_CHECK_CORE(flags,ELF_KVX_CORE_KV3_2))
3015 1.1 christos fprintf (file, _("Coolidge (kv3) V2 32 bits"));
3016 1.1 christos else if (ELF_KVX_CHECK_CORE(flags,ELF_KVX_CORE_KV4_1))
3017 1.1 christos fprintf (file, _("Coolidge (kv4) V1 32 bits"));
3018 1.1 christos }
3019 1.1 christos
3020 1.1 christos fputc ('\n', file);
3021 1.1 christos
3022 1.1 christos return true;
3023 1.1 christos }
3024 1.1 christos
3025 1.1 christos /* Adjust a symbol defined by a dynamic object and referenced by a
3026 1.1 christos regular object. The current definition is in some section of the
3027 1.1 christos dynamic object, but we're not including those sections. We have to
3028 1.1 christos change the definition to something the rest of the link can
3029 1.1 christos understand. */
3030 1.1 christos
3031 1.1 christos static bool
3032 1.1 christos elfNN_kvx_adjust_dynamic_symbol (struct bfd_link_info *info,
3033 1.1 christos struct elf_link_hash_entry *h)
3034 1.1 christos {
3035 1.1 christos struct elf_kvx_link_hash_table *htab;
3036 1.1 christos asection *s;
3037 1.1 christos
3038 1.1 christos /* If this is a function, put it in the procedure linkage table. We
3039 1.1 christos will fill in the contents of the procedure linkage table later,
3040 1.1 christos when we know the address of the .got section. */
3041 1.1 christos if (h->type == STT_FUNC || h->needs_plt)
3042 1.1 christos {
3043 1.1 christos if (h->plt.refcount <= 0
3044 1.1 christos || ((SYMBOL_CALLS_LOCAL (info, h)
3045 1.1 christos || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
3046 1.1 christos && h->root.type == bfd_link_hash_undefweak))))
3047 1.1 christos {
3048 1.1 christos /* This case can occur if we saw a CALL26 reloc in
3049 1.1 christos an input file, but the symbol wasn't referred to
3050 1.1 christos by a dynamic object or all references were
3051 1.1 christos garbage collected. In which case we can end up
3052 1.1 christos resolving. */
3053 1.1 christos h->plt.offset = (bfd_vma) - 1;
3054 1.1 christos h->needs_plt = 0;
3055 1.1 christos }
3056 1.1 christos
3057 1.1 christos return true;
3058 1.1 christos }
3059 1.1 christos else
3060 1.1 christos /* Otherwise, reset to -1. */
3061 1.1 christos h->plt.offset = (bfd_vma) - 1;
3062 1.1 christos
3063 1.1 christos
3064 1.1 christos /* If this is a weak symbol, and there is a real definition, the
3065 1.1 christos processor independent code will have arranged for us to see the
3066 1.1 christos real definition first, and we can just use the same value. */
3067 1.1 christos if (h->is_weakalias)
3068 1.1 christos {
3069 1.1 christos struct elf_link_hash_entry *def = weakdef (h);
3070 1.1 christos BFD_ASSERT (def->root.type == bfd_link_hash_defined);
3071 1.1 christos h->root.u.def.section = def->root.u.def.section;
3072 1.1 christos h->root.u.def.value = def->root.u.def.value;
3073 1.1 christos if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
3074 1.1 christos h->non_got_ref = def->non_got_ref;
3075 1.1 christos return true;
3076 1.1 christos }
3077 1.1 christos
3078 1.1 christos /* If we are creating a shared library, we must presume that the
3079 1.1 christos only references to the symbol are via the global offset table.
3080 1.1 christos For such cases we need not do anything here; the relocations will
3081 1.1 christos be handled correctly by relocate_section. */
3082 1.1 christos if (bfd_link_pic (info))
3083 1.1 christos return true;
3084 1.1 christos
3085 1.1 christos /* If there are no references to this symbol that do not use the
3086 1.1 christos GOT, we don't need to generate a copy reloc. */
3087 1.1 christos if (!h->non_got_ref)
3088 1.1 christos return true;
3089 1.1 christos
3090 1.1 christos /* If -z nocopyreloc was given, we won't generate them either. */
3091 1.1 christos if (info->nocopyreloc)
3092 1.1 christos {
3093 1.1 christos h->non_got_ref = 0;
3094 1.1 christos return true;
3095 1.1 christos }
3096 1.1 christos
3097 1.1 christos /* We must allocate the symbol in our .dynbss section, which will
3098 1.1 christos become part of the .bss section of the executable. There will be
3099 1.1 christos an entry for this symbol in the .dynsym section. The dynamic
3100 1.1 christos object will contain position independent code, so all references
3101 1.1 christos from the dynamic object to this symbol will go through the global
3102 1.1 christos offset table. The dynamic linker will use the .dynsym entry to
3103 1.1 christos determine the address it must put in the global offset table, so
3104 1.1 christos both the dynamic object and the regular object will refer to the
3105 1.1 christos same memory location for the variable. */
3106 1.1 christos
3107 1.1 christos htab = elf_kvx_hash_table (info);
3108 1.1 christos
3109 1.1 christos /* We must generate a R_KVX_COPY reloc to tell the dynamic linker
3110 1.1 christos to copy the initial value out of the dynamic object and into the
3111 1.1 christos runtime process image. */
3112 1.1 christos if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
3113 1.1 christos {
3114 1.1 christos htab->srelbss->size += RELOC_SIZE (htab);
3115 1.1 christos h->needs_copy = 1;
3116 1.1 christos }
3117 1.1 christos
3118 1.1 christos s = htab->sdynbss;
3119 1.1 christos
3120 1.1 christos return _bfd_elf_adjust_dynamic_copy (info, h, s);
3121 1.1 christos }
3122 1.1 christos
3123 1.1 christos static bool
3124 1.1 christos elfNN_kvx_allocate_local_symbols (bfd *abfd, unsigned number)
3125 1.1 christos {
3126 1.1 christos struct elf_kvx_local_symbol *locals;
3127 1.1 christos locals = elf_kvx_locals (abfd);
3128 1.1 christos if (locals == NULL)
3129 1.1 christos {
3130 1.1 christos locals = (struct elf_kvx_local_symbol *)
3131 1.1 christos bfd_zalloc (abfd, number * sizeof (struct elf_kvx_local_symbol));
3132 1.1 christos if (locals == NULL)
3133 1.1 christos return false;
3134 1.1 christos elf_kvx_locals (abfd) = locals;
3135 1.1 christos }
3136 1.1 christos return true;
3137 1.1 christos }
3138 1.1 christos
3139 1.1 christos /* Create the .got section to hold the global offset table. */
3140 1.1 christos
3141 1.1 christos static bool
3142 1.1 christos kvx_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
3143 1.1 christos {
3144 1.1.1.3 christos elf_backend_data *bed = get_elf_backend_data (abfd);
3145 1.1 christos flagword flags;
3146 1.1 christos asection *s;
3147 1.1 christos struct elf_link_hash_entry *h;
3148 1.1 christos struct elf_link_hash_table *htab = elf_hash_table (info);
3149 1.1 christos
3150 1.1 christos /* This function may be called more than once. */
3151 1.1 christos s = bfd_get_linker_section (abfd, ".got");
3152 1.1 christos if (s != NULL)
3153 1.1 christos return true;
3154 1.1 christos
3155 1.1 christos flags = bed->dynamic_sec_flags;
3156 1.1 christos
3157 1.1 christos s = bfd_make_section_anyway_with_flags (abfd,
3158 1.1 christos (bed->rela_plts_and_copies_p
3159 1.1 christos ? ".rela.got" : ".rel.got"),
3160 1.1 christos (bed->dynamic_sec_flags
3161 1.1 christos | SEC_READONLY));
3162 1.1 christos if (s == NULL
3163 1.1 christos || !bfd_set_section_alignment (s, bed->s->log_file_align))
3164 1.1 christos
3165 1.1 christos return false;
3166 1.1 christos htab->srelgot = s;
3167 1.1 christos
3168 1.1 christos s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
3169 1.1 christos if (s == NULL
3170 1.1 christos || !bfd_set_section_alignment (s, bed->s->log_file_align))
3171 1.1 christos return false;
3172 1.1 christos htab->sgot = s;
3173 1.1 christos htab->sgot->size += GOT_ENTRY_SIZE;
3174 1.1 christos
3175 1.1 christos if (bed->want_got_sym)
3176 1.1 christos {
3177 1.1 christos /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
3178 1.1 christos (or .got.plt) section. We don't do this in the linker script
3179 1.1 christos because we don't want to define the symbol if we are not creating
3180 1.1 christos a global offset table. */
3181 1.1 christos h = _bfd_elf_define_linkage_sym (abfd, info, s,
3182 1.1 christos "_GLOBAL_OFFSET_TABLE_");
3183 1.1 christos elf_hash_table (info)->hgot = h;
3184 1.1 christos if (h == NULL)
3185 1.1 christos return false;
3186 1.1 christos }
3187 1.1 christos
3188 1.1 christos if (bed->want_got_plt)
3189 1.1 christos {
3190 1.1 christos s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
3191 1.1 christos if (s == NULL
3192 1.1 christos || !bfd_set_section_alignment (s,
3193 1.1 christos bed->s->log_file_align))
3194 1.1 christos return false;
3195 1.1 christos htab->sgotplt = s;
3196 1.1 christos }
3197 1.1 christos
3198 1.1 christos /* The first bit of the global offset table is the header. */
3199 1.1 christos s->size += bed->got_header_size;
3200 1.1 christos
3201 1.1 christos /* we still need to handle got content when doing static link with PIC */
3202 1.1 christos if (bfd_link_executable (info) && !bfd_link_pic (info)) {
3203 1.1 christos htab->dynobj = abfd;
3204 1.1 christos }
3205 1.1 christos
3206 1.1 christos return true;
3207 1.1 christos }
3208 1.1 christos
3209 1.1 christos /* Look through the relocs for a section during the first phase. */
3210 1.1 christos
3211 1.1 christos static bool
3212 1.1 christos elfNN_kvx_check_relocs (bfd *abfd, struct bfd_link_info *info,
3213 1.1 christos asection *sec, const Elf_Internal_Rela *relocs)
3214 1.1 christos {
3215 1.1 christos Elf_Internal_Shdr *symtab_hdr;
3216 1.1 christos struct elf_link_hash_entry **sym_hashes;
3217 1.1 christos const Elf_Internal_Rela *rel;
3218 1.1 christos const Elf_Internal_Rela *rel_end;
3219 1.1 christos asection *sreloc;
3220 1.1 christos
3221 1.1 christos struct elf_kvx_link_hash_table *htab;
3222 1.1 christos
3223 1.1 christos if (bfd_link_relocatable (info))
3224 1.1 christos return true;
3225 1.1 christos
3226 1.1 christos BFD_ASSERT (is_kvx_elf (abfd));
3227 1.1 christos
3228 1.1 christos htab = elf_kvx_hash_table (info);
3229 1.1 christos sreloc = NULL;
3230 1.1 christos
3231 1.1 christos symtab_hdr = &elf_symtab_hdr (abfd);
3232 1.1 christos sym_hashes = elf_sym_hashes (abfd);
3233 1.1 christos
3234 1.1 christos rel_end = relocs + sec->reloc_count;
3235 1.1 christos for (rel = relocs; rel < rel_end; rel++)
3236 1.1 christos {
3237 1.1 christos struct elf_link_hash_entry *h;
3238 1.1 christos unsigned int r_symndx;
3239 1.1 christos unsigned int r_type;
3240 1.1 christos bfd_reloc_code_real_type bfd_r_type;
3241 1.1 christos Elf_Internal_Sym *isym;
3242 1.1 christos
3243 1.1 christos r_symndx = ELFNN_R_SYM (rel->r_info);
3244 1.1 christos r_type = ELFNN_R_TYPE (rel->r_info);
3245 1.1 christos
3246 1.1 christos if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
3247 1.1 christos {
3248 1.1 christos /* xgettext:c-format */
3249 1.1 christos _bfd_error_handler (_("%pB: bad symbol index: %d"), abfd, r_symndx);
3250 1.1 christos return false;
3251 1.1 christos }
3252 1.1 christos
3253 1.1 christos if (r_symndx < symtab_hdr->sh_info)
3254 1.1 christos {
3255 1.1 christos /* A local symbol. */
3256 1.1 christos isym = bfd_sym_from_r_symndx (&htab->sym_cache,
3257 1.1 christos abfd, r_symndx);
3258 1.1 christos if (isym == NULL)
3259 1.1 christos return false;
3260 1.1 christos
3261 1.1 christos h = NULL;
3262 1.1 christos }
3263 1.1 christos else
3264 1.1 christos {
3265 1.1 christos h = sym_hashes[r_symndx - symtab_hdr->sh_info];
3266 1.1 christos while (h->root.type == bfd_link_hash_indirect
3267 1.1 christos || h->root.type == bfd_link_hash_warning)
3268 1.1 christos h = (struct elf_link_hash_entry *) h->root.u.i.link;
3269 1.1 christos }
3270 1.1 christos
3271 1.1 christos /* Could be done earlier, if h were already available. */
3272 1.1 christos bfd_r_type = kvx_tls_transition (abfd, info, r_type, h, r_symndx);
3273 1.1 christos
3274 1.1 christos if (h != NULL)
3275 1.1 christos {
3276 1.1 christos /* Create the ifunc sections for static executables. If we
3277 1.1 christos never see an indirect function symbol nor we are building
3278 1.1 christos a static executable, those sections will be empty and
3279 1.1 christos won't appear in output. */
3280 1.1 christos switch (bfd_r_type)
3281 1.1 christos {
3282 1.1 christos default:
3283 1.1 christos break;
3284 1.1 christos }
3285 1.1 christos
3286 1.1 christos /* It is referenced by a non-shared object. */
3287 1.1 christos h->ref_regular = 1;
3288 1.1 christos }
3289 1.1 christos
3290 1.1 christos switch (bfd_r_type)
3291 1.1 christos {
3292 1.1 christos
3293 1.1 christos case BFD_RELOC_KVX_S43_LO10:
3294 1.1 christos case BFD_RELOC_KVX_S43_UP27:
3295 1.1 christos case BFD_RELOC_KVX_S43_EX6:
3296 1.1 christos
3297 1.1 christos case BFD_RELOC_KVX_S37_LO10:
3298 1.1 christos case BFD_RELOC_KVX_S37_UP27:
3299 1.1 christos
3300 1.1 christos case BFD_RELOC_KVX_S64_LO10:
3301 1.1 christos case BFD_RELOC_KVX_S64_UP27:
3302 1.1 christos case BFD_RELOC_KVX_S64_EX27:
3303 1.1 christos
3304 1.1 christos case BFD_RELOC_KVX_32:
3305 1.1 christos case BFD_RELOC_KVX_64:
3306 1.1 christos
3307 1.1 christos /* We don't need to handle relocs into sections not going into
3308 1.1 christos the "real" output. */
3309 1.1 christos if ((sec->flags & SEC_ALLOC) == 0)
3310 1.1 christos break;
3311 1.1 christos
3312 1.1 christos if (h != NULL)
3313 1.1 christos {
3314 1.1 christos if (!bfd_link_pic (info))
3315 1.1 christos h->non_got_ref = 1;
3316 1.1 christos
3317 1.1 christos h->plt.refcount += 1;
3318 1.1 christos h->pointer_equality_needed = 1;
3319 1.1 christos }
3320 1.1 christos
3321 1.1 christos /* No need to do anything if we're not creating a shared
3322 1.1 christos object. */
3323 1.1 christos if (! bfd_link_pic (info))
3324 1.1 christos break;
3325 1.1 christos
3326 1.1 christos {
3327 1.1 christos struct elf_dyn_relocs *p;
3328 1.1 christos struct elf_dyn_relocs **head;
3329 1.1 christos
3330 1.1 christos /* We must copy these reloc types into the output file.
3331 1.1 christos Create a reloc section in dynobj and make room for
3332 1.1 christos this reloc. */
3333 1.1 christos if (sreloc == NULL)
3334 1.1 christos {
3335 1.1 christos if (htab->root.dynobj == NULL)
3336 1.1 christos htab->root.dynobj = abfd;
3337 1.1 christos
3338 1.1 christos sreloc = _bfd_elf_make_dynamic_reloc_section
3339 1.1 christos (sec, htab->root.dynobj, LOG_FILE_ALIGN, abfd, /*rela? */ true);
3340 1.1 christos
3341 1.1 christos if (sreloc == NULL)
3342 1.1 christos return false;
3343 1.1 christos }
3344 1.1 christos
3345 1.1 christos /* If this is a global symbol, we count the number of
3346 1.1 christos relocations we need for this symbol. */
3347 1.1 christos if (h != NULL)
3348 1.1 christos {
3349 1.1 christos head = &h->dyn_relocs;
3350 1.1 christos }
3351 1.1 christos else
3352 1.1 christos {
3353 1.1 christos /* Track dynamic relocs needed for local syms too.
3354 1.1 christos We really need local syms available to do this
3355 1.1 christos easily. Oh well. */
3356 1.1 christos
3357 1.1 christos asection *s;
3358 1.1 christos void **vpp;
3359 1.1 christos
3360 1.1 christos isym = bfd_sym_from_r_symndx (&htab->sym_cache,
3361 1.1 christos abfd, r_symndx);
3362 1.1 christos if (isym == NULL)
3363 1.1 christos return false;
3364 1.1 christos
3365 1.1 christos s = bfd_section_from_elf_index (abfd, isym->st_shndx);
3366 1.1 christos if (s == NULL)
3367 1.1 christos s = sec;
3368 1.1 christos
3369 1.1 christos /* Beware of type punned pointers vs strict aliasing
3370 1.1 christos rules. */
3371 1.1 christos vpp = &(elf_section_data (s)->local_dynrel);
3372 1.1 christos head = (struct elf_dyn_relocs **) vpp;
3373 1.1 christos }
3374 1.1 christos
3375 1.1 christos p = *head;
3376 1.1 christos if (p == NULL || p->sec != sec)
3377 1.1 christos {
3378 1.1 christos bfd_size_type amt = sizeof *p;
3379 1.1 christos p = ((struct elf_dyn_relocs *)
3380 1.1 christos bfd_zalloc (htab->root.dynobj, amt));
3381 1.1 christos if (p == NULL)
3382 1.1 christos return false;
3383 1.1 christos p->next = *head;
3384 1.1 christos *head = p;
3385 1.1 christos p->sec = sec;
3386 1.1 christos }
3387 1.1 christos
3388 1.1 christos p->count += 1;
3389 1.1 christos
3390 1.1 christos }
3391 1.1 christos break;
3392 1.1 christos
3393 1.1 christos case BFD_RELOC_KVX_S37_GOT_LO10:
3394 1.1 christos case BFD_RELOC_KVX_S37_GOT_UP27:
3395 1.1 christos
3396 1.1 christos case BFD_RELOC_KVX_S37_GOTOFF_LO10:
3397 1.1 christos case BFD_RELOC_KVX_S37_GOTOFF_UP27:
3398 1.1 christos
3399 1.1 christos case BFD_RELOC_KVX_S43_GOT_LO10:
3400 1.1 christos case BFD_RELOC_KVX_S43_GOT_UP27:
3401 1.1 christos case BFD_RELOC_KVX_S43_GOT_EX6:
3402 1.1 christos
3403 1.1 christos case BFD_RELOC_KVX_S43_GOTOFF_LO10:
3404 1.1 christos case BFD_RELOC_KVX_S43_GOTOFF_UP27:
3405 1.1 christos case BFD_RELOC_KVX_S43_GOTOFF_EX6:
3406 1.1 christos
3407 1.1 christos case BFD_RELOC_KVX_S37_TLS_GD_LO10:
3408 1.1 christos case BFD_RELOC_KVX_S37_TLS_GD_UP27:
3409 1.1 christos
3410 1.1 christos case BFD_RELOC_KVX_S43_TLS_GD_LO10:
3411 1.1 christos case BFD_RELOC_KVX_S43_TLS_GD_UP27:
3412 1.1 christos case BFD_RELOC_KVX_S43_TLS_GD_EX6:
3413 1.1 christos
3414 1.1 christos case BFD_RELOC_KVX_S37_TLS_IE_LO10:
3415 1.1 christos case BFD_RELOC_KVX_S37_TLS_IE_UP27:
3416 1.1 christos
3417 1.1 christos case BFD_RELOC_KVX_S43_TLS_IE_LO10:
3418 1.1 christos case BFD_RELOC_KVX_S43_TLS_IE_UP27:
3419 1.1 christos case BFD_RELOC_KVX_S43_TLS_IE_EX6:
3420 1.1 christos
3421 1.1 christos case BFD_RELOC_KVX_S37_TLS_LD_LO10:
3422 1.1 christos case BFD_RELOC_KVX_S37_TLS_LD_UP27:
3423 1.1 christos
3424 1.1 christos case BFD_RELOC_KVX_S43_TLS_LD_LO10:
3425 1.1 christos case BFD_RELOC_KVX_S43_TLS_LD_UP27:
3426 1.1 christos case BFD_RELOC_KVX_S43_TLS_LD_EX6:
3427 1.1 christos {
3428 1.1 christos unsigned got_type;
3429 1.1 christos unsigned old_got_type;
3430 1.1 christos
3431 1.1 christos got_type = kvx_reloc_got_type (bfd_r_type);
3432 1.1 christos
3433 1.1 christos if (h)
3434 1.1 christos {
3435 1.1 christos h->got.refcount += 1;
3436 1.1 christos old_got_type = elf_kvx_hash_entry (h)->got_type;
3437 1.1 christos }
3438 1.1 christos else
3439 1.1 christos {
3440 1.1 christos struct elf_kvx_local_symbol *locals;
3441 1.1 christos
3442 1.1 christos if (!elfNN_kvx_allocate_local_symbols
3443 1.1 christos (abfd, symtab_hdr->sh_info))
3444 1.1 christos return false;
3445 1.1 christos
3446 1.1 christos locals = elf_kvx_locals (abfd);
3447 1.1 christos BFD_ASSERT (r_symndx < symtab_hdr->sh_info);
3448 1.1 christos locals[r_symndx].got_refcount += 1;
3449 1.1 christos old_got_type = locals[r_symndx].got_type;
3450 1.1 christos }
3451 1.1 christos
3452 1.1 christos /* We will already have issued an error message if there
3453 1.1 christos is a TLS/non-TLS mismatch, based on the symbol type.
3454 1.1 christos So just combine any TLS types needed. */
3455 1.1 christos if (old_got_type != GOT_UNKNOWN && old_got_type != GOT_NORMAL
3456 1.1 christos && got_type != GOT_NORMAL)
3457 1.1 christos got_type |= old_got_type;
3458 1.1 christos
3459 1.1 christos /* If the symbol is accessed by both IE and GD methods, we
3460 1.1 christos are able to relax. Turn off the GD flag, without
3461 1.1 christos messing up with any other kind of TLS types that may be
3462 1.1 christos involved. */
3463 1.1 christos /* Disabled untested and unused TLS */
3464 1.1 christos /* if ((got_type & GOT_TLS_IE) && GOT_TLS_GD_ANY_P (got_type)) */
3465 1.1 christos /* got_type &= ~ (GOT_TLSDESC_GD | GOT_TLS_GD); */
3466 1.1 christos
3467 1.1 christos if (old_got_type != got_type)
3468 1.1 christos {
3469 1.1 christos if (h != NULL)
3470 1.1 christos elf_kvx_hash_entry (h)->got_type = got_type;
3471 1.1 christos else
3472 1.1 christos {
3473 1.1 christos struct elf_kvx_local_symbol *locals;
3474 1.1 christos locals = elf_kvx_locals (abfd);
3475 1.1 christos BFD_ASSERT (r_symndx < symtab_hdr->sh_info);
3476 1.1 christos locals[r_symndx].got_type = got_type;
3477 1.1 christos }
3478 1.1 christos }
3479 1.1 christos
3480 1.1 christos if (htab->root.dynobj == NULL)
3481 1.1 christos htab->root.dynobj = abfd;
3482 1.1 christos if (! kvx_elf_create_got_section (htab->root.dynobj, info))
3483 1.1 christos return false;
3484 1.1 christos break;
3485 1.1 christos }
3486 1.1 christos
3487 1.1 christos case BFD_RELOC_KVX_S64_GOTADDR_LO10:
3488 1.1 christos case BFD_RELOC_KVX_S64_GOTADDR_UP27:
3489 1.1 christos case BFD_RELOC_KVX_S64_GOTADDR_EX27:
3490 1.1 christos
3491 1.1 christos case BFD_RELOC_KVX_S43_GOTADDR_LO10:
3492 1.1 christos case BFD_RELOC_KVX_S43_GOTADDR_UP27:
3493 1.1 christos case BFD_RELOC_KVX_S43_GOTADDR_EX6:
3494 1.1 christos
3495 1.1 christos case BFD_RELOC_KVX_S37_GOTADDR_LO10:
3496 1.1 christos case BFD_RELOC_KVX_S37_GOTADDR_UP27:
3497 1.1 christos
3498 1.1 christos if (htab->root.dynobj == NULL)
3499 1.1 christos htab->root.dynobj = abfd;
3500 1.1 christos if (! kvx_elf_create_got_section (htab->root.dynobj, info))
3501 1.1 christos return false;
3502 1.1 christos break;
3503 1.1 christos
3504 1.1 christos case BFD_RELOC_KVX_PCREL27:
3505 1.1 christos case BFD_RELOC_KVX_PCREL17:
3506 1.1 christos /* If this is a local symbol then we resolve it
3507 1.1 christos directly without creating a PLT entry. */
3508 1.1 christos if (h == NULL)
3509 1.1 christos continue;
3510 1.1 christos
3511 1.1 christos h->needs_plt = 1;
3512 1.1 christos if (h->plt.refcount <= 0)
3513 1.1 christos h->plt.refcount = 1;
3514 1.1 christos else
3515 1.1 christos h->plt.refcount += 1;
3516 1.1 christos break;
3517 1.1 christos
3518 1.1 christos default:
3519 1.1 christos break;
3520 1.1 christos }
3521 1.1 christos }
3522 1.1 christos
3523 1.1 christos return true;
3524 1.1 christos }
3525 1.1 christos
3526 1.1 christos static bool
3527 1.1 christos elfNN_kvx_init_file_header (bfd *abfd, struct bfd_link_info *link_info)
3528 1.1 christos {
3529 1.1 christos Elf_Internal_Ehdr *i_ehdrp; /* ELF file header, internal form. */
3530 1.1 christos
3531 1.1 christos if (!_bfd_elf_init_file_header (abfd, link_info))
3532 1.1 christos return false;
3533 1.1 christos
3534 1.1 christos i_ehdrp = elf_elfheader (abfd);
3535 1.1 christos i_ehdrp->e_ident[EI_ABIVERSION] = KVX_ELF_ABI_VERSION;
3536 1.1 christos return true;
3537 1.1 christos }
3538 1.1 christos
3539 1.1 christos static enum elf_reloc_type_class
3540 1.1 christos elfNN_kvx_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
3541 1.1 christos const asection *rel_sec ATTRIBUTE_UNUSED,
3542 1.1 christos const Elf_Internal_Rela *rela)
3543 1.1 christos {
3544 1.1 christos switch ((int) ELFNN_R_TYPE (rela->r_info))
3545 1.1 christos {
3546 1.1 christos case R_KVX_RELATIVE:
3547 1.1 christos return reloc_class_relative;
3548 1.1 christos case R_KVX_JMP_SLOT:
3549 1.1 christos return reloc_class_plt;
3550 1.1 christos case R_KVX_COPY:
3551 1.1 christos return reloc_class_copy;
3552 1.1 christos default:
3553 1.1 christos return reloc_class_normal;
3554 1.1 christos }
3555 1.1 christos }
3556 1.1 christos
3557 1.1 christos /* A structure used to record a list of sections, independently
3558 1.1 christos of the next and prev fields in the asection structure. */
3559 1.1 christos typedef struct section_list
3560 1.1 christos {
3561 1.1 christos asection *sec;
3562 1.1 christos struct section_list *next;
3563 1.1 christos struct section_list *prev;
3564 1.1 christos }
3565 1.1 christos section_list;
3566 1.1 christos
3567 1.1 christos typedef struct
3568 1.1 christos {
3569 1.1 christos void *finfo;
3570 1.1 christos struct bfd_link_info *info;
3571 1.1 christos asection *sec;
3572 1.1 christos int sec_shndx;
3573 1.1 christos int (*func) (void *, const char *, Elf_Internal_Sym *,
3574 1.1 christos asection *, struct elf_link_hash_entry *);
3575 1.1 christos } output_arch_syminfo;
3576 1.1 christos
3577 1.1 christos /* Output a single local symbol for a generated stub. */
3578 1.1 christos
3579 1.1 christos static bool
3580 1.1 christos elfNN_kvx_output_stub_sym (output_arch_syminfo *osi, const char *name,
3581 1.1 christos bfd_vma offset, bfd_vma size)
3582 1.1 christos {
3583 1.1 christos Elf_Internal_Sym sym;
3584 1.1 christos
3585 1.1 christos sym.st_value = (osi->sec->output_section->vma
3586 1.1 christos + osi->sec->output_offset + offset);
3587 1.1 christos sym.st_size = size;
3588 1.1 christos sym.st_other = 0;
3589 1.1 christos sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
3590 1.1 christos sym.st_shndx = osi->sec_shndx;
3591 1.1 christos return osi->func (osi->finfo, name, &sym, osi->sec, NULL) == 1;
3592 1.1 christos }
3593 1.1 christos
3594 1.1 christos static bool
3595 1.1 christos kvx_map_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
3596 1.1 christos {
3597 1.1 christos struct elf_kvx_stub_hash_entry *stub_entry;
3598 1.1 christos asection *stub_sec;
3599 1.1 christos bfd_vma addr;
3600 1.1 christos char *stub_name;
3601 1.1 christos output_arch_syminfo *osi;
3602 1.1 christos
3603 1.1 christos /* Massage our args to the form they really have. */
3604 1.1 christos stub_entry = (struct elf_kvx_stub_hash_entry *) gen_entry;
3605 1.1 christos osi = (output_arch_syminfo *) in_arg;
3606 1.1 christos
3607 1.1 christos stub_sec = stub_entry->stub_sec;
3608 1.1 christos
3609 1.1 christos /* Ensure this stub is attached to the current section being
3610 1.1 christos processed. */
3611 1.1 christos if (stub_sec != osi->sec)
3612 1.1 christos return true;
3613 1.1 christos
3614 1.1 christos addr = (bfd_vma) stub_entry->stub_offset;
3615 1.1 christos
3616 1.1 christos stub_name = stub_entry->output_name;
3617 1.1 christos
3618 1.1 christos switch (stub_entry->stub_type)
3619 1.1 christos {
3620 1.1 christos case kvx_stub_long_branch:
3621 1.1 christos if (!elfNN_kvx_output_stub_sym
3622 1.1 christos (osi, stub_name, addr, sizeof (elfNN_kvx_long_branch_stub)))
3623 1.1 christos return false;
3624 1.1 christos break;
3625 1.1 christos
3626 1.1 christos default:
3627 1.1 christos abort ();
3628 1.1 christos }
3629 1.1 christos
3630 1.1 christos return true;
3631 1.1 christos }
3632 1.1 christos
3633 1.1 christos /* Output mapping symbols for linker generated sections. */
3634 1.1 christos
3635 1.1 christos static bool
3636 1.1 christos elfNN_kvx_output_arch_local_syms (bfd *output_bfd,
3637 1.1 christos struct bfd_link_info *info,
3638 1.1 christos void *finfo,
3639 1.1 christos int (*func) (void *, const char *,
3640 1.1 christos Elf_Internal_Sym *,
3641 1.1 christos asection *,
3642 1.1 christos struct elf_link_hash_entry *))
3643 1.1 christos {
3644 1.1 christos output_arch_syminfo osi;
3645 1.1 christos struct elf_kvx_link_hash_table *htab;
3646 1.1 christos
3647 1.1 christos htab = elf_kvx_hash_table (info);
3648 1.1 christos
3649 1.1 christos osi.finfo = finfo;
3650 1.1 christos osi.info = info;
3651 1.1 christos osi.func = func;
3652 1.1 christos
3653 1.1 christos /* Long calls stubs. */
3654 1.1 christos if (htab->stub_bfd && htab->stub_bfd->sections)
3655 1.1 christos {
3656 1.1 christos asection *stub_sec;
3657 1.1 christos
3658 1.1 christos for (stub_sec = htab->stub_bfd->sections;
3659 1.1 christos stub_sec != NULL; stub_sec = stub_sec->next)
3660 1.1 christos {
3661 1.1 christos /* Ignore non-stub sections. */
3662 1.1 christos if (!strstr (stub_sec->name, STUB_SUFFIX))
3663 1.1 christos continue;
3664 1.1 christos
3665 1.1 christos osi.sec = stub_sec;
3666 1.1 christos
3667 1.1 christos osi.sec_shndx = _bfd_elf_section_from_bfd_section
3668 1.1 christos (output_bfd, osi.sec->output_section);
3669 1.1 christos
3670 1.1 christos bfd_hash_traverse (&htab->stub_hash_table, kvx_map_one_stub,
3671 1.1 christos &osi);
3672 1.1 christos }
3673 1.1 christos }
3674 1.1 christos
3675 1.1 christos /* Finally, output mapping symbols for the PLT. */
3676 1.1 christos if (!htab->root.splt || htab->root.splt->size == 0)
3677 1.1 christos return true;
3678 1.1 christos
3679 1.1 christos osi.sec_shndx = _bfd_elf_section_from_bfd_section
3680 1.1 christos (output_bfd, htab->root.splt->output_section);
3681 1.1 christos osi.sec = htab->root.splt;
3682 1.1 christos
3683 1.1 christos return true;
3684 1.1 christos
3685 1.1 christos }
3686 1.1 christos
3687 1.1 christos /* Allocate target specific section data. */
3688 1.1 christos
3689 1.1 christos static bool
3690 1.1 christos elfNN_kvx_new_section_hook (bfd *abfd, asection *sec)
3691 1.1 christos {
3692 1.1.1.2 christos _kvx_elf_section_data *sdata;
3693 1.1 christos
3694 1.1.1.2 christos sdata = bfd_zalloc (abfd, sizeof (*sdata));
3695 1.1.1.2 christos if (sdata == NULL)
3696 1.1.1.2 christos return false;
3697 1.1.1.2 christos sec->used_by_bfd = sdata;
3698 1.1 christos
3699 1.1 christos return _bfd_elf_new_section_hook (abfd, sec);
3700 1.1 christos }
3701 1.1 christos
3702 1.1 christos /* Create dynamic sections. This is different from the ARM backend in that
3703 1.1 christos the got, plt, gotplt and their relocation sections are all created in the
3704 1.1 christos standard part of the bfd elf backend. */
3705 1.1 christos
3706 1.1 christos static bool
3707 1.1 christos elfNN_kvx_create_dynamic_sections (bfd *dynobj,
3708 1.1 christos struct bfd_link_info *info)
3709 1.1 christos {
3710 1.1 christos struct elf_kvx_link_hash_table *htab;
3711 1.1 christos
3712 1.1 christos /* We need to create .got section. */
3713 1.1 christos if (!kvx_elf_create_got_section (dynobj, info))
3714 1.1 christos return false;
3715 1.1 christos
3716 1.1 christos if (!_bfd_elf_create_dynamic_sections (dynobj, info))
3717 1.1 christos return false;
3718 1.1 christos
3719 1.1 christos htab = elf_kvx_hash_table (info);
3720 1.1 christos htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
3721 1.1 christos if (!bfd_link_pic (info))
3722 1.1 christos htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
3723 1.1 christos
3724 1.1 christos if (!htab->sdynbss || (!bfd_link_pic (info) && !htab->srelbss))
3725 1.1 christos abort ();
3726 1.1 christos
3727 1.1 christos return true;
3728 1.1 christos }
3729 1.1 christos
3730 1.1 christos
3731 1.1 christos /* Allocate space in .plt, .got and associated reloc sections for
3732 1.1 christos dynamic relocs. */
3733 1.1 christos
3734 1.1 christos static bool
3735 1.1 christos elfNN_kvx_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
3736 1.1 christos {
3737 1.1 christos struct bfd_link_info *info;
3738 1.1 christos struct elf_kvx_link_hash_table *htab;
3739 1.1 christos struct elf_dyn_relocs *p;
3740 1.1 christos
3741 1.1 christos /* An example of a bfd_link_hash_indirect symbol is versioned
3742 1.1 christos symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
3743 1.1 christos -> __gxx_personality_v0(bfd_link_hash_defined)
3744 1.1 christos
3745 1.1 christos There is no need to process bfd_link_hash_indirect symbols here
3746 1.1 christos because we will also be presented with the concrete instance of
3747 1.1 christos the symbol and elfNN_kvx_copy_indirect_symbol () will have been
3748 1.1 christos called to copy all relevant data from the generic to the concrete
3749 1.1 christos symbol instance. */
3750 1.1 christos if (h->root.type == bfd_link_hash_indirect)
3751 1.1 christos return true;
3752 1.1 christos
3753 1.1 christos if (h->root.type == bfd_link_hash_warning)
3754 1.1 christos h = (struct elf_link_hash_entry *) h->root.u.i.link;
3755 1.1 christos
3756 1.1 christos info = (struct bfd_link_info *) inf;
3757 1.1 christos htab = elf_kvx_hash_table (info);
3758 1.1 christos
3759 1.1 christos if (htab->root.dynamic_sections_created && h->plt.refcount > 0)
3760 1.1 christos {
3761 1.1 christos /* Make sure this symbol is output as a dynamic symbol.
3762 1.1 christos Undefined weak syms won't yet be marked as dynamic. */
3763 1.1 christos if (h->dynindx == -1 && !h->forced_local)
3764 1.1 christos {
3765 1.1 christos if (!bfd_elf_link_record_dynamic_symbol (info, h))
3766 1.1 christos return false;
3767 1.1 christos }
3768 1.1 christos
3769 1.1 christos if (bfd_link_pic (info) || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
3770 1.1 christos {
3771 1.1 christos asection *s = htab->root.splt;
3772 1.1 christos
3773 1.1 christos /* If this is the first .plt entry, make room for the special
3774 1.1 christos first entry. */
3775 1.1 christos if (s->size == 0)
3776 1.1 christos s->size += htab->plt_header_size;
3777 1.1 christos
3778 1.1 christos h->plt.offset = s->size;
3779 1.1 christos
3780 1.1 christos /* If this symbol is not defined in a regular file, and we are
3781 1.1 christos not generating a shared library, then set the symbol to this
3782 1.1 christos location in the .plt. This is required to make function
3783 1.1 christos pointers compare as equal between the normal executable and
3784 1.1 christos the shared library. */
3785 1.1 christos if (!bfd_link_pic (info) && !h->def_regular)
3786 1.1 christos {
3787 1.1 christos h->root.u.def.section = s;
3788 1.1 christos h->root.u.def.value = h->plt.offset;
3789 1.1 christos }
3790 1.1 christos
3791 1.1 christos /* Make room for this entry. For now we only create the
3792 1.1 christos small model PLT entries. We later need to find a way
3793 1.1 christos of relaxing into these from the large model PLT entries. */
3794 1.1 christos s->size += PLT_SMALL_ENTRY_SIZE;
3795 1.1 christos
3796 1.1 christos /* We also need to make an entry in the .got.plt section, which
3797 1.1 christos will be placed in the .got section by the linker script. */
3798 1.1 christos htab->root.sgotplt->size += GOT_ENTRY_SIZE;
3799 1.1 christos
3800 1.1 christos /* We also need to make an entry in the .rela.plt section. */
3801 1.1 christos htab->root.srelplt->size += RELOC_SIZE (htab);
3802 1.1 christos
3803 1.1 christos /* We need to ensure that all GOT entries that serve the PLT
3804 1.1 christos are consecutive with the special GOT slots [0] [1] and
3805 1.1 christos [2]. Any addtional relocations must be placed after the
3806 1.1 christos PLT related entries. We abuse the reloc_count such that
3807 1.1 christos during sizing we adjust reloc_count to indicate the
3808 1.1 christos number of PLT related reserved entries. In subsequent
3809 1.1 christos phases when filling in the contents of the reloc entries,
3810 1.1 christos PLT related entries are placed by computing their PLT
3811 1.1 christos index (0 .. reloc_count). While other none PLT relocs are
3812 1.1 christos placed at the slot indicated by reloc_count and
3813 1.1 christos reloc_count is updated. */
3814 1.1 christos
3815 1.1 christos htab->root.srelplt->reloc_count++;
3816 1.1 christos }
3817 1.1 christos else
3818 1.1 christos {
3819 1.1 christos h->plt.offset = (bfd_vma) - 1;
3820 1.1 christos h->needs_plt = 0;
3821 1.1 christos }
3822 1.1 christos }
3823 1.1 christos else
3824 1.1 christos {
3825 1.1 christos h->plt.offset = (bfd_vma) - 1;
3826 1.1 christos h->needs_plt = 0;
3827 1.1 christos }
3828 1.1 christos
3829 1.1 christos if (h->got.refcount > 0)
3830 1.1 christos {
3831 1.1 christos bool dyn;
3832 1.1 christos unsigned got_type = elf_kvx_hash_entry (h)->got_type;
3833 1.1 christos
3834 1.1 christos h->got.offset = (bfd_vma) - 1;
3835 1.1 christos
3836 1.1 christos dyn = htab->root.dynamic_sections_created;
3837 1.1 christos
3838 1.1 christos /* Make sure this symbol is output as a dynamic symbol.
3839 1.1 christos Undefined weak syms won't yet be marked as dynamic. */
3840 1.1 christos if (dyn && h->dynindx == -1 && !h->forced_local)
3841 1.1 christos {
3842 1.1 christos if (!bfd_elf_link_record_dynamic_symbol (info, h))
3843 1.1 christos return false;
3844 1.1 christos }
3845 1.1 christos
3846 1.1 christos if (got_type == GOT_UNKNOWN)
3847 1.1 christos {
3848 1.1 christos (*_bfd_error_handler)
3849 1.1 christos (_("relocation against `%s' has faulty GOT type "),
3850 1.1 christos (h) ? h->root.root.string : "a local symbol");
3851 1.1 christos bfd_set_error (bfd_error_bad_value);
3852 1.1 christos return false;
3853 1.1 christos }
3854 1.1 christos else if (got_type == GOT_NORMAL)
3855 1.1 christos {
3856 1.1 christos h->got.offset = htab->root.sgot->size;
3857 1.1 christos htab->root.sgot->size += GOT_ENTRY_SIZE;
3858 1.1 christos if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3859 1.1 christos || h->root.type != bfd_link_hash_undefweak)
3860 1.1 christos && (bfd_link_pic (info)
3861 1.1 christos || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
3862 1.1 christos {
3863 1.1 christos htab->root.srelgot->size += RELOC_SIZE (htab);
3864 1.1 christos }
3865 1.1 christos }
3866 1.1 christos else
3867 1.1 christos {
3868 1.1 christos int indx;
3869 1.1 christos
3870 1.1 christos /* Any of these will require 2 GOT slots because
3871 1.1 christos * they use __tls_get_addr() */
3872 1.1 christos if (got_type & (GOT_TLS_GD | GOT_TLS_LD))
3873 1.1 christos {
3874 1.1 christos h->got.offset = htab->root.sgot->size;
3875 1.1 christos htab->root.sgot->size += GOT_ENTRY_SIZE * 2;
3876 1.1 christos }
3877 1.1 christos
3878 1.1 christos if (got_type & GOT_TLS_IE)
3879 1.1 christos {
3880 1.1 christos h->got.offset = htab->root.sgot->size;
3881 1.1 christos htab->root.sgot->size += GOT_ENTRY_SIZE;
3882 1.1 christos }
3883 1.1 christos
3884 1.1 christos indx = h && h->dynindx != -1 ? h->dynindx : 0;
3885 1.1 christos if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3886 1.1 christos || h->root.type != bfd_link_hash_undefweak)
3887 1.1 christos && (bfd_link_pic (info)
3888 1.1 christos || indx != 0
3889 1.1 christos || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
3890 1.1 christos {
3891 1.1 christos /* Only the GD case requires 2 relocations. */
3892 1.1 christos if (got_type & GOT_TLS_GD)
3893 1.1 christos htab->root.srelgot->size += RELOC_SIZE (htab) * 2;
3894 1.1 christos
3895 1.1 christos /* LD needs a DTPMOD reloc, IE needs a DTPOFF. */
3896 1.1 christos if (got_type & (GOT_TLS_LD | GOT_TLS_IE))
3897 1.1 christos htab->root.srelgot->size += RELOC_SIZE (htab);
3898 1.1 christos }
3899 1.1 christos }
3900 1.1 christos }
3901 1.1 christos else
3902 1.1 christos {
3903 1.1 christos h->got.offset = (bfd_vma) - 1;
3904 1.1 christos }
3905 1.1 christos
3906 1.1 christos if (h->dyn_relocs == NULL)
3907 1.1 christos return true;
3908 1.1 christos
3909 1.1 christos /* In the shared -Bsymbolic case, discard space allocated for
3910 1.1 christos dynamic pc-relative relocs against symbols which turn out to be
3911 1.1 christos defined in regular objects. For the normal shared case, discard
3912 1.1 christos space for pc-relative relocs that have become local due to symbol
3913 1.1 christos visibility changes. */
3914 1.1 christos
3915 1.1 christos if (bfd_link_pic (info))
3916 1.1 christos {
3917 1.1 christos /* Relocs that use pc_count are those that appear on a call
3918 1.1 christos insn, or certain REL relocs that can generated via assembly.
3919 1.1 christos We want calls to protected symbols to resolve directly to the
3920 1.1 christos function rather than going via the plt. If people want
3921 1.1 christos function pointer comparisons to work as expected then they
3922 1.1 christos should avoid writing weird assembly. */
3923 1.1 christos if (SYMBOL_CALLS_LOCAL (info, h))
3924 1.1 christos {
3925 1.1 christos struct elf_dyn_relocs **pp;
3926 1.1 christos
3927 1.1 christos for (pp = &h->dyn_relocs; (p = *pp) != NULL;)
3928 1.1 christos {
3929 1.1 christos p->count -= p->pc_count;
3930 1.1 christos p->pc_count = 0;
3931 1.1 christos if (p->count == 0)
3932 1.1 christos *pp = p->next;
3933 1.1 christos else
3934 1.1 christos pp = &p->next;
3935 1.1 christos }
3936 1.1 christos }
3937 1.1 christos
3938 1.1 christos /* Also discard relocs on undefined weak syms with non-default
3939 1.1 christos visibility. */
3940 1.1 christos if (h->dyn_relocs != NULL && h->root.type == bfd_link_hash_undefweak)
3941 1.1 christos {
3942 1.1 christos if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
3943 1.1 christos || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
3944 1.1 christos h->dyn_relocs = NULL;
3945 1.1 christos
3946 1.1 christos /* Make sure undefined weak symbols are output as a dynamic
3947 1.1 christos symbol in PIEs. */
3948 1.1 christos else if (h->dynindx == -1
3949 1.1 christos && !h->forced_local
3950 1.1 christos && !bfd_elf_link_record_dynamic_symbol (info, h))
3951 1.1 christos return false;
3952 1.1 christos }
3953 1.1 christos
3954 1.1 christos }
3955 1.1 christos else if (ELIMINATE_COPY_RELOCS)
3956 1.1 christos {
3957 1.1 christos /* For the non-shared case, discard space for relocs against
3958 1.1 christos symbols which turn out to need copy relocs or are not
3959 1.1 christos dynamic. */
3960 1.1 christos
3961 1.1 christos if (!h->non_got_ref
3962 1.1 christos && ((h->def_dynamic
3963 1.1 christos && !h->def_regular)
3964 1.1 christos || (htab->root.dynamic_sections_created
3965 1.1 christos && (h->root.type == bfd_link_hash_undefweak
3966 1.1 christos || h->root.type == bfd_link_hash_undefined))))
3967 1.1 christos {
3968 1.1 christos /* Make sure this symbol is output as a dynamic symbol.
3969 1.1 christos Undefined weak syms won't yet be marked as dynamic. */
3970 1.1 christos if (h->dynindx == -1
3971 1.1 christos && !h->forced_local
3972 1.1 christos && !bfd_elf_link_record_dynamic_symbol (info, h))
3973 1.1 christos return false;
3974 1.1 christos
3975 1.1 christos /* If that succeeded, we know we'll be keeping all the
3976 1.1 christos relocs. */
3977 1.1 christos if (h->dynindx != -1)
3978 1.1 christos goto keep;
3979 1.1 christos }
3980 1.1 christos
3981 1.1 christos h->dyn_relocs = NULL;
3982 1.1 christos
3983 1.1 christos keep:;
3984 1.1 christos }
3985 1.1 christos
3986 1.1 christos /* Finally, allocate space. */
3987 1.1 christos for (p = h->dyn_relocs; p != NULL; p = p->next)
3988 1.1 christos {
3989 1.1 christos asection *sreloc;
3990 1.1 christos
3991 1.1 christos sreloc = elf_section_data (p->sec)->sreloc;
3992 1.1 christos
3993 1.1 christos BFD_ASSERT (sreloc != NULL);
3994 1.1 christos
3995 1.1 christos sreloc->size += p->count * RELOC_SIZE (htab);
3996 1.1 christos }
3997 1.1 christos
3998 1.1 christos return true;
3999 1.1 christos }
4000 1.1 christos
4001 1.1 christos /* Find any dynamic relocs that apply to read-only sections. */
4002 1.1 christos
4003 1.1 christos static bool
4004 1.1 christos kvx_readonly_dynrelocs (struct elf_link_hash_entry * h, void * inf)
4005 1.1 christos {
4006 1.1 christos struct elf_dyn_relocs * p;
4007 1.1 christos
4008 1.1 christos for (p = h->dyn_relocs; p != NULL; p = p->next)
4009 1.1 christos {
4010 1.1 christos asection *s = p->sec;
4011 1.1 christos
4012 1.1 christos if (s != NULL && (s->flags & SEC_READONLY) != 0)
4013 1.1 christos {
4014 1.1 christos struct bfd_link_info *info = (struct bfd_link_info *) inf;
4015 1.1 christos
4016 1.1 christos info->flags |= DF_TEXTREL;
4017 1.1 christos info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' in "
4018 1.1 christos "read-only section `%pA'\n"),
4019 1.1 christos s->owner, h->root.root.string, s);
4020 1.1 christos
4021 1.1 christos /* Not an error, just cut short the traversal. */
4022 1.1 christos return false;
4023 1.1 christos }
4024 1.1 christos }
4025 1.1 christos return true;
4026 1.1 christos }
4027 1.1 christos
4028 1.1 christos /* This is the most important function of all . Innocuosly named
4029 1.1 christos though ! */
4030 1.1 christos static bool
4031 1.1.1.2 christos elfNN_kvx_late_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
4032 1.1.1.2 christos struct bfd_link_info *info)
4033 1.1 christos {
4034 1.1 christos struct elf_kvx_link_hash_table *htab;
4035 1.1 christos bfd *dynobj;
4036 1.1 christos asection *s;
4037 1.1 christos bool relocs;
4038 1.1 christos bfd *ibfd;
4039 1.1 christos
4040 1.1 christos htab = elf_kvx_hash_table ((info));
4041 1.1 christos dynobj = htab->root.dynobj;
4042 1.1.1.2 christos if (dynobj == NULL)
4043 1.1.1.2 christos return true;
4044 1.1 christos
4045 1.1 christos if (htab->root.dynamic_sections_created)
4046 1.1 christos {
4047 1.1 christos if (bfd_link_executable (info) && !info->nointerp)
4048 1.1 christos {
4049 1.1.1.3 christos s = htab->root.interp;
4050 1.1 christos if (s == NULL)
4051 1.1 christos abort ();
4052 1.1 christos s->size = sizeof ELF_DYNAMIC_INTERPRETER;
4053 1.1 christos s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
4054 1.1.1.2 christos s->alloced = 1;
4055 1.1 christos }
4056 1.1 christos }
4057 1.1 christos
4058 1.1 christos /* Set up .got offsets for local syms, and space for local dynamic
4059 1.1 christos relocs. */
4060 1.1 christos for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
4061 1.1 christos {
4062 1.1 christos struct elf_kvx_local_symbol *locals = NULL;
4063 1.1 christos Elf_Internal_Shdr *symtab_hdr;
4064 1.1 christos asection *srel;
4065 1.1 christos unsigned int i;
4066 1.1 christos
4067 1.1 christos if (!is_kvx_elf (ibfd))
4068 1.1 christos continue;
4069 1.1 christos
4070 1.1 christos for (s = ibfd->sections; s != NULL; s = s->next)
4071 1.1 christos {
4072 1.1 christos struct elf_dyn_relocs *p;
4073 1.1 christos
4074 1.1 christos for (p = (struct elf_dyn_relocs *)
4075 1.1 christos (elf_section_data (s)->local_dynrel); p != NULL; p = p->next)
4076 1.1 christos {
4077 1.1 christos if (!bfd_is_abs_section (p->sec)
4078 1.1 christos && bfd_is_abs_section (p->sec->output_section))
4079 1.1 christos {
4080 1.1 christos /* Input section has been discarded, either because
4081 1.1 christos it is a copy of a linkonce section or due to
4082 1.1 christos linker script /DISCARD/, so we'll be discarding
4083 1.1 christos the relocs too. */
4084 1.1 christos }
4085 1.1 christos else if (p->count != 0)
4086 1.1 christos {
4087 1.1 christos srel = elf_section_data (p->sec)->sreloc;
4088 1.1 christos srel->size += p->count * RELOC_SIZE (htab);
4089 1.1 christos if ((p->sec->output_section->flags & SEC_READONLY) != 0)
4090 1.1 christos info->flags |= DF_TEXTREL;
4091 1.1 christos }
4092 1.1 christos }
4093 1.1 christos }
4094 1.1 christos
4095 1.1 christos locals = elf_kvx_locals (ibfd);
4096 1.1 christos if (!locals)
4097 1.1 christos continue;
4098 1.1 christos
4099 1.1 christos symtab_hdr = &elf_symtab_hdr (ibfd);
4100 1.1 christos srel = htab->root.srelgot;
4101 1.1 christos for (i = 0; i < symtab_hdr->sh_info; i++)
4102 1.1 christos {
4103 1.1 christos locals[i].got_offset = (bfd_vma) - 1;
4104 1.1 christos if (locals[i].got_refcount > 0)
4105 1.1 christos {
4106 1.1 christos unsigned got_type = locals[i].got_type;
4107 1.1 christos if (got_type & (GOT_TLS_GD | GOT_TLS_LD))
4108 1.1 christos {
4109 1.1 christos locals[i].got_offset = htab->root.sgot->size;
4110 1.1 christos htab->root.sgot->size += GOT_ENTRY_SIZE * 2;
4111 1.1 christos }
4112 1.1 christos
4113 1.1 christos if (got_type & (GOT_NORMAL | GOT_TLS_IE ))
4114 1.1 christos {
4115 1.1 christos locals[i].got_offset = htab->root.sgot->size;
4116 1.1 christos htab->root.sgot->size += GOT_ENTRY_SIZE;
4117 1.1 christos }
4118 1.1 christos
4119 1.1 christos if (got_type == GOT_UNKNOWN)
4120 1.1 christos {
4121 1.1 christos }
4122 1.1 christos
4123 1.1 christos if (bfd_link_pic (info))
4124 1.1 christos {
4125 1.1 christos if (got_type & GOT_TLS_GD)
4126 1.1 christos htab->root.srelgot->size += RELOC_SIZE (htab) * 2;
4127 1.1 christos
4128 1.1 christos if (got_type & GOT_TLS_IE
4129 1.1 christos || got_type & GOT_TLS_LD
4130 1.1 christos || got_type & GOT_NORMAL)
4131 1.1 christos htab->root.srelgot->size += RELOC_SIZE (htab);
4132 1.1 christos }
4133 1.1 christos }
4134 1.1 christos else
4135 1.1 christos {
4136 1.1 christos locals[i].got_refcount = (bfd_vma) - 1;
4137 1.1 christos }
4138 1.1 christos }
4139 1.1 christos }
4140 1.1 christos
4141 1.1 christos
4142 1.1 christos /* Allocate global sym .plt and .got entries, and space for global
4143 1.1 christos sym dynamic relocs. */
4144 1.1 christos elf_link_hash_traverse (&htab->root, elfNN_kvx_allocate_dynrelocs,
4145 1.1 christos info);
4146 1.1 christos
4147 1.1 christos /* For every jump slot reserved in the sgotplt, reloc_count is
4148 1.1 christos incremented. However, when we reserve space for TLS descriptors,
4149 1.1 christos it's not incremented, so in order to compute the space reserved
4150 1.1 christos for them, it suffices to multiply the reloc count by the jump
4151 1.1 christos slot size. */
4152 1.1 christos
4153 1.1 christos if (htab->root.srelplt)
4154 1.1 christos htab->sgotplt_jump_table_size = kvx_compute_jump_table_size (htab);
4155 1.1 christos
4156 1.1 christos /* We now have determined the sizes of the various dynamic sections.
4157 1.1 christos Allocate memory for them. */
4158 1.1 christos relocs = false;
4159 1.1 christos for (s = dynobj->sections; s != NULL; s = s->next)
4160 1.1 christos {
4161 1.1 christos if ((s->flags & SEC_LINKER_CREATED) == 0)
4162 1.1 christos continue;
4163 1.1 christos
4164 1.1 christos if (s == htab->root.splt
4165 1.1 christos || s == htab->root.sgot
4166 1.1 christos || s == htab->root.sgotplt
4167 1.1 christos || s == htab->root.iplt
4168 1.1 christos || s == htab->root.igotplt || s == htab->sdynbss)
4169 1.1 christos {
4170 1.1 christos /* Strip this section if we don't need it; see the
4171 1.1 christos comment below. */
4172 1.1 christos }
4173 1.1 christos else if (startswith (bfd_section_name (s), ".rela"))
4174 1.1 christos {
4175 1.1 christos if (s->size != 0 && s != htab->root.srelplt)
4176 1.1 christos relocs = true;
4177 1.1 christos
4178 1.1 christos /* We use the reloc_count field as a counter if we need
4179 1.1 christos to copy relocs into the output file. */
4180 1.1 christos if (s != htab->root.srelplt)
4181 1.1 christos s->reloc_count = 0;
4182 1.1 christos }
4183 1.1 christos else
4184 1.1 christos {
4185 1.1 christos /* It's not one of our sections, so don't allocate space. */
4186 1.1 christos continue;
4187 1.1 christos }
4188 1.1 christos
4189 1.1 christos if (s->size == 0)
4190 1.1 christos {
4191 1.1 christos /* If we don't need this section, strip it from the
4192 1.1 christos output file. This is mostly to handle .rela.bss and
4193 1.1 christos .rela.plt. We must create both sections in
4194 1.1 christos create_dynamic_sections, because they must be created
4195 1.1 christos before the linker maps input sections to output
4196 1.1 christos sections. The linker does that before
4197 1.1 christos adjust_dynamic_symbol is called, and it is that
4198 1.1 christos function which decides whether anything needs to go
4199 1.1 christos into these sections. */
4200 1.1 christos
4201 1.1 christos s->flags |= SEC_EXCLUDE;
4202 1.1 christos continue;
4203 1.1 christos }
4204 1.1 christos
4205 1.1 christos if ((s->flags & SEC_HAS_CONTENTS) == 0)
4206 1.1 christos continue;
4207 1.1 christos
4208 1.1 christos /* Allocate memory for the section contents. We use bfd_zalloc
4209 1.1 christos here in case unused entries are not reclaimed before the
4210 1.1 christos section's contents are written out. This should not happen,
4211 1.1 christos but this way if it does, we get a R_KVX_NONE reloc instead
4212 1.1 christos of garbage. */
4213 1.1 christos s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
4214 1.1 christos if (s->contents == NULL)
4215 1.1 christos return false;
4216 1.1.1.2 christos s->alloced = 1;
4217 1.1 christos }
4218 1.1 christos
4219 1.1 christos if (htab->root.dynamic_sections_created)
4220 1.1 christos {
4221 1.1 christos /* Add some entries to the .dynamic section. We fill in the
4222 1.1 christos values later, in elfNN_kvx_finish_dynamic_sections, but we
4223 1.1 christos must add the entries now so that we get the correct size for
4224 1.1 christos the .dynamic section. The DT_DEBUG entry is filled in by the
4225 1.1 christos dynamic linker and used by the debugger. */
4226 1.1 christos #define add_dynamic_entry(TAG, VAL) \
4227 1.1 christos _bfd_elf_add_dynamic_entry (info, TAG, VAL)
4228 1.1 christos
4229 1.1 christos if (bfd_link_executable (info))
4230 1.1 christos {
4231 1.1 christos if (!add_dynamic_entry (DT_DEBUG, 0))
4232 1.1 christos return false;
4233 1.1 christos }
4234 1.1 christos
4235 1.1 christos if (htab->root.splt->size != 0)
4236 1.1 christos {
4237 1.1 christos if (!add_dynamic_entry (DT_PLTGOT, 0)
4238 1.1 christos || !add_dynamic_entry (DT_PLTRELSZ, 0)
4239 1.1 christos || !add_dynamic_entry (DT_PLTREL, DT_RELA)
4240 1.1 christos || !add_dynamic_entry (DT_JMPREL, 0))
4241 1.1 christos return false;
4242 1.1 christos }
4243 1.1 christos
4244 1.1 christos if (relocs)
4245 1.1 christos {
4246 1.1 christos if (!add_dynamic_entry (DT_RELA, 0)
4247 1.1 christos || !add_dynamic_entry (DT_RELASZ, 0)
4248 1.1 christos || !add_dynamic_entry (DT_RELAENT, RELOC_SIZE (htab)))
4249 1.1 christos return false;
4250 1.1 christos
4251 1.1 christos /* If any dynamic relocs apply to a read-only section,
4252 1.1 christos then we need a DT_TEXTREL entry. */
4253 1.1 christos if ((info->flags & DF_TEXTREL) == 0)
4254 1.1 christos elf_link_hash_traverse (&htab->root, kvx_readonly_dynrelocs,
4255 1.1 christos info);
4256 1.1 christos
4257 1.1 christos if ((info->flags & DF_TEXTREL) != 0)
4258 1.1 christos {
4259 1.1 christos if (!add_dynamic_entry (DT_TEXTREL, 0))
4260 1.1 christos return false;
4261 1.1 christos }
4262 1.1 christos }
4263 1.1 christos }
4264 1.1 christos #undef add_dynamic_entry
4265 1.1 christos
4266 1.1 christos return true;
4267 1.1 christos }
4268 1.1 christos
4269 1.1 christos static inline void
4270 1.1 christos elf_kvx_update_plt_entry (bfd *output_bfd,
4271 1.1 christos bfd_reloc_code_real_type r_type,
4272 1.1 christos bfd_byte *plt_entry, bfd_vma value)
4273 1.1 christos {
4274 1.1 christos reloc_howto_type *howto = elfNN_kvx_howto_from_bfd_reloc (r_type);
4275 1.1 christos BFD_ASSERT(howto != NULL);
4276 1.1 christos _bfd_kvx_elf_put_addend (output_bfd, plt_entry, r_type, howto, value);
4277 1.1 christos }
4278 1.1 christos
4279 1.1 christos static void
4280 1.1 christos elfNN_kvx_create_small_pltn_entry (struct elf_link_hash_entry *h,
4281 1.1 christos struct elf_kvx_link_hash_table *htab,
4282 1.1 christos bfd *output_bfd)
4283 1.1 christos {
4284 1.1 christos bfd_byte *plt_entry;
4285 1.1 christos bfd_vma plt_index;
4286 1.1 christos bfd_vma got_offset;
4287 1.1 christos bfd_vma gotplt_entry_address;
4288 1.1 christos bfd_vma plt_entry_address;
4289 1.1 christos Elf_Internal_Rela rela;
4290 1.1 christos bfd_byte *loc;
4291 1.1 christos asection *plt, *gotplt, *relplt;
4292 1.1 christos
4293 1.1 christos plt = htab->root.splt;
4294 1.1 christos gotplt = htab->root.sgotplt;
4295 1.1 christos relplt = htab->root.srelplt;
4296 1.1 christos
4297 1.1 christos /* Get the index in the procedure linkage table which
4298 1.1 christos corresponds to this symbol. This is the index of this symbol
4299 1.1 christos in all the symbols for which we are making plt entries. The
4300 1.1 christos first entry in the procedure linkage table is reserved.
4301 1.1 christos
4302 1.1 christos Get the offset into the .got table of the entry that
4303 1.1 christos corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
4304 1.1 christos bytes. The first three are reserved for the dynamic linker.
4305 1.1 christos
4306 1.1 christos For static executables, we don't reserve anything. */
4307 1.1 christos
4308 1.1 christos if (plt == htab->root.splt)
4309 1.1 christos {
4310 1.1 christos plt_index = (h->plt.offset - htab->plt_header_size) / htab->plt_entry_size;
4311 1.1 christos got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
4312 1.1 christos }
4313 1.1 christos else
4314 1.1 christos {
4315 1.1 christos plt_index = h->plt.offset / htab->plt_entry_size;
4316 1.1 christos got_offset = plt_index * GOT_ENTRY_SIZE;
4317 1.1 christos }
4318 1.1 christos
4319 1.1 christos plt_entry = plt->contents + h->plt.offset;
4320 1.1 christos plt_entry_address = plt->output_section->vma
4321 1.1 christos + plt->output_offset + h->plt.offset;
4322 1.1 christos gotplt_entry_address = gotplt->output_section->vma +
4323 1.1 christos gotplt->output_offset + got_offset;
4324 1.1 christos
4325 1.1 christos /* Copy in the boiler-plate for the PLTn entry. */
4326 1.1 christos memcpy (plt_entry, elfNN_kvx_small_plt_entry, PLT_SMALL_ENTRY_SIZE);
4327 1.1 christos
4328 1.1 christos /* Patch the loading of the GOT entry, relative to the PLT entry
4329 1.1 christos address. */
4330 1.1 christos
4331 1.1 christos /* Use 37bits offset for both 32 and 64bits mode.
4332 1.1 christos Fill the LO10 of of lw $r9 = 0[$r14]. */
4333 1.1 christos elf_kvx_update_plt_entry(output_bfd, BFD_RELOC_KVX_S37_LO10,
4334 1.1 christos plt_entry+4,
4335 1.1 christos gotplt_entry_address - plt_entry_address);
4336 1.1 christos
4337 1.1 christos /* Fill the UP27 of of lw $r9 = 0[$r14]. */
4338 1.1 christos elf_kvx_update_plt_entry(output_bfd, BFD_RELOC_KVX_S37_UP27,
4339 1.1 christos plt_entry+8,
4340 1.1 christos gotplt_entry_address - plt_entry_address);
4341 1.1 christos
4342 1.1 christos rela.r_offset = gotplt_entry_address;
4343 1.1 christos
4344 1.1 christos /* Fill in the entry in the .rela.plt section. */
4345 1.1 christos rela.r_info = ELFNN_R_INFO (h->dynindx, R_KVX_JMP_SLOT);
4346 1.1 christos rela.r_addend = 0;
4347 1.1 christos
4348 1.1 christos /* Compute the relocation entry to used based on PLT index and do
4349 1.1 christos not adjust reloc_count. The reloc_count has already been adjusted
4350 1.1 christos to account for this entry. */
4351 1.1 christos loc = relplt->contents + plt_index * RELOC_SIZE (htab);
4352 1.1 christos bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
4353 1.1 christos }
4354 1.1 christos
4355 1.1 christos /* Size sections even though they're not dynamic. We use it to setup
4356 1.1 christos _TLS_MODULE_BASE_, if needed. */
4357 1.1 christos
4358 1.1 christos static bool
4359 1.1.1.2 christos elfNN_kvx_early_size_sections (bfd *output_bfd, struct bfd_link_info *info)
4360 1.1 christos {
4361 1.1 christos asection *tls_sec;
4362 1.1 christos
4363 1.1 christos if (bfd_link_relocatable (info))
4364 1.1 christos return true;
4365 1.1 christos
4366 1.1 christos tls_sec = elf_hash_table (info)->tls_sec;
4367 1.1 christos
4368 1.1 christos if (tls_sec)
4369 1.1 christos {
4370 1.1 christos struct elf_link_hash_entry *tlsbase;
4371 1.1 christos
4372 1.1 christos tlsbase = elf_link_hash_lookup (elf_hash_table (info),
4373 1.1 christos "_TLS_MODULE_BASE_", true, true, false);
4374 1.1 christos
4375 1.1 christos if (tlsbase)
4376 1.1 christos {
4377 1.1 christos struct bfd_link_hash_entry *h = NULL;
4378 1.1.1.3 christos elf_backend_data *bed = get_elf_backend_data (output_bfd);
4379 1.1 christos
4380 1.1 christos if (!(_bfd_generic_link_add_one_symbol
4381 1.1 christos (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
4382 1.1 christos tls_sec, 0, NULL, false, bed->collect, &h)))
4383 1.1 christos return false;
4384 1.1 christos
4385 1.1 christos tlsbase->type = STT_TLS;
4386 1.1 christos tlsbase = (struct elf_link_hash_entry *) h;
4387 1.1 christos tlsbase->def_regular = 1;
4388 1.1 christos tlsbase->other = STV_HIDDEN;
4389 1.1 christos (*bed->elf_backend_hide_symbol) (info, tlsbase, true);
4390 1.1 christos }
4391 1.1 christos }
4392 1.1 christos
4393 1.1 christos return true;
4394 1.1 christos }
4395 1.1 christos
4396 1.1 christos /* Finish up dynamic symbol handling. We set the contents of various
4397 1.1 christos dynamic sections here. */
4398 1.1 christos static bool
4399 1.1 christos elfNN_kvx_finish_dynamic_symbol (bfd *output_bfd,
4400 1.1 christos struct bfd_link_info *info,
4401 1.1 christos struct elf_link_hash_entry *h,
4402 1.1 christos Elf_Internal_Sym *sym)
4403 1.1 christos {
4404 1.1 christos struct elf_kvx_link_hash_table *htab;
4405 1.1 christos htab = elf_kvx_hash_table (info);
4406 1.1 christos
4407 1.1 christos if (h->plt.offset != (bfd_vma) - 1)
4408 1.1 christos {
4409 1.1 christos asection *plt = NULL, *gotplt = NULL, *relplt = NULL;
4410 1.1 christos
4411 1.1 christos /* This symbol has an entry in the procedure linkage table. Set
4412 1.1 christos it up. */
4413 1.1 christos
4414 1.1 christos if (htab->root.splt != NULL)
4415 1.1 christos {
4416 1.1 christos plt = htab->root.splt;
4417 1.1 christos gotplt = htab->root.sgotplt;
4418 1.1 christos relplt = htab->root.srelplt;
4419 1.1 christos }
4420 1.1 christos
4421 1.1 christos /* This symbol has an entry in the procedure linkage table. Set
4422 1.1 christos it up. */
4423 1.1 christos if ((h->dynindx == -1
4424 1.1 christos && !((h->forced_local || bfd_link_executable (info))
4425 1.1 christos && h->def_regular
4426 1.1 christos && h->type == STT_GNU_IFUNC))
4427 1.1 christos || plt == NULL
4428 1.1 christos || gotplt == NULL
4429 1.1 christos || relplt == NULL)
4430 1.1 christos abort ();
4431 1.1 christos
4432 1.1 christos elfNN_kvx_create_small_pltn_entry (h, htab, output_bfd);
4433 1.1 christos if (!h->def_regular)
4434 1.1 christos {
4435 1.1 christos /* Mark the symbol as undefined, rather than as defined in
4436 1.1 christos the .plt section. */
4437 1.1 christos sym->st_shndx = SHN_UNDEF;
4438 1.1 christos /* If the symbol is weak we need to clear the value.
4439 1.1 christos Otherwise, the PLT entry would provide a definition for
4440 1.1 christos the symbol even if the symbol wasn't defined anywhere,
4441 1.1 christos and so the symbol would never be NULL. Leave the value if
4442 1.1 christos there were any relocations where pointer equality matters
4443 1.1 christos (this is a clue for the dynamic linker, to make function
4444 1.1 christos pointer comparisons work between an application and shared
4445 1.1 christos library). */
4446 1.1 christos if (!h->ref_regular_nonweak || !h->pointer_equality_needed)
4447 1.1 christos sym->st_value = 0;
4448 1.1 christos }
4449 1.1 christos }
4450 1.1 christos
4451 1.1 christos if (h->got.offset != (bfd_vma) - 1
4452 1.1 christos && elf_kvx_hash_entry (h)->got_type == GOT_NORMAL)
4453 1.1 christos {
4454 1.1 christos Elf_Internal_Rela rela;
4455 1.1 christos bfd_byte *loc;
4456 1.1 christos
4457 1.1 christos /* This symbol has an entry in the global offset table. Set it
4458 1.1 christos up. */
4459 1.1 christos if (htab->root.sgot == NULL || htab->root.srelgot == NULL)
4460 1.1 christos abort ();
4461 1.1 christos
4462 1.1 christos rela.r_offset = (htab->root.sgot->output_section->vma
4463 1.1 christos + htab->root.sgot->output_offset
4464 1.1 christos + (h->got.offset & ~(bfd_vma) 1));
4465 1.1 christos
4466 1.1 christos #ifdef UGLY_DEBUG
4467 1.1 christos printf("setting rela at offset 0x%x(0x%x + 0x%x + 0x%x) for %s\n",
4468 1.1 christos rela.r_offset,
4469 1.1 christos htab->root.sgot->output_section->vma,
4470 1.1 christos htab->root.sgot->output_offset,
4471 1.1 christos h->got.offset,
4472 1.1 christos h->root.root.string);
4473 1.1 christos #endif
4474 1.1 christos
4475 1.1 christos if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h))
4476 1.1 christos {
4477 1.1 christos if (!h->def_regular)
4478 1.1 christos return false;
4479 1.1 christos
4480 1.1 christos /* in case of PLT related GOT entry, it is not clear who is
4481 1.1 christos supposed to set the LSB of GOT entry...
4482 1.1 christos kvx_calculate_got_entry_vma() would be a good candidate,
4483 1.1 christos but it is not called currently
4484 1.1 christos So we are commenting it ATM. */
4485 1.1 christos // BFD_ASSERT ((h->got.offset & 1) != 0);
4486 1.1 christos rela.r_info = ELFNN_R_INFO (0, R_KVX_RELATIVE);
4487 1.1 christos rela.r_addend = (h->root.u.def.value
4488 1.1 christos + h->root.u.def.section->output_section->vma
4489 1.1 christos + h->root.u.def.section->output_offset);
4490 1.1 christos }
4491 1.1 christos else
4492 1.1 christos {
4493 1.1 christos BFD_ASSERT ((h->got.offset & 1) == 0);
4494 1.1 christos bfd_put_NN (output_bfd, (bfd_vma) 0,
4495 1.1 christos htab->root.sgot->contents + h->got.offset);
4496 1.1 christos rela.r_info = ELFNN_R_INFO (h->dynindx, R_KVX_GLOB_DAT);
4497 1.1 christos rela.r_addend = 0;
4498 1.1 christos }
4499 1.1 christos
4500 1.1 christos loc = htab->root.srelgot->contents;
4501 1.1 christos loc += htab->root.srelgot->reloc_count++ * RELOC_SIZE (htab);
4502 1.1 christos bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
4503 1.1 christos }
4504 1.1 christos
4505 1.1 christos if (h->needs_copy)
4506 1.1 christos {
4507 1.1 christos Elf_Internal_Rela rela;
4508 1.1 christos bfd_byte *loc;
4509 1.1 christos
4510 1.1 christos /* This symbol needs a copy reloc. Set it up. */
4511 1.1 christos
4512 1.1 christos if (h->dynindx == -1
4513 1.1 christos || (h->root.type != bfd_link_hash_defined
4514 1.1 christos && h->root.type != bfd_link_hash_defweak)
4515 1.1 christos || htab->srelbss == NULL)
4516 1.1 christos abort ();
4517 1.1 christos
4518 1.1 christos rela.r_offset = (h->root.u.def.value
4519 1.1 christos + h->root.u.def.section->output_section->vma
4520 1.1 christos + h->root.u.def.section->output_offset);
4521 1.1 christos rela.r_info = ELFNN_R_INFO (h->dynindx, R_KVX_COPY);
4522 1.1 christos rela.r_addend = 0;
4523 1.1 christos loc = htab->srelbss->contents;
4524 1.1 christos loc += htab->srelbss->reloc_count++ * RELOC_SIZE (htab);
4525 1.1 christos bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
4526 1.1 christos }
4527 1.1 christos
4528 1.1 christos /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. SYM may
4529 1.1 christos be NULL for local symbols. */
4530 1.1 christos if (sym != NULL
4531 1.1 christos && (h == elf_hash_table (info)->hdynamic
4532 1.1 christos || h == elf_hash_table (info)->hgot))
4533 1.1 christos sym->st_shndx = SHN_ABS;
4534 1.1 christos
4535 1.1 christos return true;
4536 1.1 christos }
4537 1.1 christos
4538 1.1 christos static void
4539 1.1 christos elfNN_kvx_init_small_plt0_entry (bfd *output_bfd ATTRIBUTE_UNUSED,
4540 1.1 christos struct elf_kvx_link_hash_table *htab)
4541 1.1 christos {
4542 1.1 christos memcpy (htab->root.splt->contents, elfNN_kvx_small_plt0_entry,
4543 1.1 christos PLT_ENTRY_SIZE);
4544 1.1 christos elf_section_data (htab->root.splt->output_section)->this_hdr.sh_entsize =
4545 1.1 christos PLT_ENTRY_SIZE;
4546 1.1 christos }
4547 1.1 christos
4548 1.1 christos static bool
4549 1.1 christos elfNN_kvx_finish_dynamic_sections (bfd *output_bfd,
4550 1.1.1.3 christos struct bfd_link_info *info,
4551 1.1.1.3 christos bfd_byte *buf ATTRIBUTE_UNUSED)
4552 1.1 christos {
4553 1.1 christos struct elf_kvx_link_hash_table *htab;
4554 1.1 christos bfd *dynobj;
4555 1.1 christos asection *sdyn;
4556 1.1 christos
4557 1.1 christos htab = elf_kvx_hash_table (info);
4558 1.1 christos dynobj = htab->root.dynobj;
4559 1.1 christos sdyn = bfd_get_linker_section (dynobj, ".dynamic");
4560 1.1 christos
4561 1.1 christos if (htab->root.dynamic_sections_created)
4562 1.1 christos {
4563 1.1 christos ElfNN_External_Dyn *dyncon, *dynconend;
4564 1.1 christos
4565 1.1 christos if (sdyn == NULL || htab->root.sgot == NULL)
4566 1.1 christos abort ();
4567 1.1 christos
4568 1.1 christos dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4569 1.1 christos dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
4570 1.1 christos for (; dyncon < dynconend; dyncon++)
4571 1.1 christos {
4572 1.1 christos Elf_Internal_Dyn dyn;
4573 1.1 christos asection *s;
4574 1.1 christos
4575 1.1 christos bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4576 1.1 christos
4577 1.1 christos switch (dyn.d_tag)
4578 1.1 christos {
4579 1.1 christos default:
4580 1.1 christos continue;
4581 1.1 christos
4582 1.1 christos case DT_PLTGOT:
4583 1.1 christos s = htab->root.sgotplt;
4584 1.1 christos dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4585 1.1 christos break;
4586 1.1 christos
4587 1.1 christos case DT_JMPREL:
4588 1.1 christos s = htab->root.srelplt;
4589 1.1 christos dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4590 1.1 christos break;
4591 1.1 christos
4592 1.1 christos case DT_PLTRELSZ:
4593 1.1 christos s = htab->root.srelplt;
4594 1.1 christos dyn.d_un.d_val = s->size;
4595 1.1 christos break;
4596 1.1 christos
4597 1.1 christos case DT_RELASZ:
4598 1.1 christos /* The procedure linkage table relocs (DT_JMPREL) should
4599 1.1 christos not be included in the overall relocs (DT_RELA).
4600 1.1 christos Therefore, we override the DT_RELASZ entry here to
4601 1.1 christos make it not include the JMPREL relocs. Since the
4602 1.1 christos linker script arranges for .rela.plt to follow all
4603 1.1 christos other relocation sections, we don't have to worry
4604 1.1 christos about changing the DT_RELA entry. */
4605 1.1 christos if (htab->root.srelplt != NULL)
4606 1.1 christos {
4607 1.1 christos s = htab->root.srelplt;
4608 1.1 christos dyn.d_un.d_val -= s->size;
4609 1.1 christos }
4610 1.1 christos break;
4611 1.1 christos }
4612 1.1 christos
4613 1.1 christos bfd_elfNN_swap_dyn_out (output_bfd, &dyn, dyncon);
4614 1.1 christos }
4615 1.1 christos
4616 1.1 christos }
4617 1.1 christos
4618 1.1 christos /* Fill in the special first entry in the procedure linkage table. */
4619 1.1 christos if (htab->root.splt && htab->root.splt->size > 0)
4620 1.1 christos {
4621 1.1 christos elfNN_kvx_init_small_plt0_entry (output_bfd, htab);
4622 1.1 christos
4623 1.1 christos elf_section_data (htab->root.splt->output_section)->
4624 1.1 christos this_hdr.sh_entsize = htab->plt_entry_size;
4625 1.1 christos }
4626 1.1 christos
4627 1.1 christos if (htab->root.sgotplt)
4628 1.1 christos {
4629 1.1 christos if (bfd_is_abs_section (htab->root.sgotplt->output_section))
4630 1.1 christos {
4631 1.1 christos (*_bfd_error_handler)
4632 1.1 christos (_("discarded output section: `%pA'"), htab->root.sgotplt);
4633 1.1 christos return false;
4634 1.1 christos }
4635 1.1 christos
4636 1.1 christos /* Fill in the first three entries in the global offset table. */
4637 1.1 christos if (htab->root.sgotplt->size > 0)
4638 1.1 christos {
4639 1.1 christos bfd_put_NN (output_bfd, (bfd_vma) 0, htab->root.sgotplt->contents);
4640 1.1 christos
4641 1.1 christos /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
4642 1.1 christos bfd_put_NN (output_bfd,
4643 1.1 christos (bfd_vma) 0,
4644 1.1 christos htab->root.sgotplt->contents + GOT_ENTRY_SIZE);
4645 1.1 christos bfd_put_NN (output_bfd,
4646 1.1 christos (bfd_vma) 0,
4647 1.1 christos htab->root.sgotplt->contents + GOT_ENTRY_SIZE * 2);
4648 1.1 christos }
4649 1.1 christos
4650 1.1 christos if (htab->root.sgot)
4651 1.1 christos {
4652 1.1 christos if (htab->root.sgot->size > 0)
4653 1.1 christos {
4654 1.1 christos bfd_vma addr =
4655 1.1 christos sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0;
4656 1.1 christos bfd_put_NN (output_bfd, addr, htab->root.sgot->contents);
4657 1.1 christos }
4658 1.1 christos }
4659 1.1 christos
4660 1.1 christos elf_section_data (htab->root.sgotplt->output_section)->
4661 1.1 christos this_hdr.sh_entsize = GOT_ENTRY_SIZE;
4662 1.1 christos }
4663 1.1 christos
4664 1.1 christos if (htab->root.sgot && htab->root.sgot->size > 0)
4665 1.1 christos elf_section_data (htab->root.sgot->output_section)->this_hdr.sh_entsize
4666 1.1 christos = GOT_ENTRY_SIZE;
4667 1.1 christos
4668 1.1 christos return true;
4669 1.1 christos }
4670 1.1 christos
4671 1.1 christos /* Return address for Ith PLT stub in section PLT, for relocation REL
4672 1.1 christos or (bfd_vma) -1 if it should not be included. */
4673 1.1 christos
4674 1.1 christos static bfd_vma
4675 1.1 christos elfNN_kvx_plt_sym_val (bfd_vma i, const asection *plt,
4676 1.1 christos const arelent *rel ATTRIBUTE_UNUSED)
4677 1.1 christos {
4678 1.1 christos return plt->vma + PLT_ENTRY_SIZE + i * PLT_SMALL_ENTRY_SIZE;
4679 1.1 christos }
4680 1.1 christos
4681 1.1 christos #define ELF_ARCH bfd_arch_kvx
4682 1.1.1.2 christos #define ELF_TARGET_ID KVX_ELF_DATA
4683 1.1 christos #define ELF_MACHINE_CODE EM_KVX
4684 1.1 christos #define ELF_MAXPAGESIZE 0x10000
4685 1.1 christos #define ELF_MINPAGESIZE 0x1000
4686 1.1 christos #define ELF_COMMONPAGESIZE 0x1000
4687 1.1 christos
4688 1.1 christos #define bfd_elfNN_bfd_link_hash_table_create \
4689 1.1 christos elfNN_kvx_link_hash_table_create
4690 1.1 christos
4691 1.1 christos #define bfd_elfNN_bfd_merge_private_bfd_data \
4692 1.1 christos elfNN_kvx_merge_private_bfd_data
4693 1.1 christos
4694 1.1 christos #define bfd_elfNN_bfd_print_private_bfd_data \
4695 1.1 christos elfNN_kvx_print_private_bfd_data
4696 1.1 christos
4697 1.1 christos #define bfd_elfNN_bfd_reloc_type_lookup \
4698 1.1 christos elfNN_kvx_reloc_type_lookup
4699 1.1 christos
4700 1.1 christos #define bfd_elfNN_bfd_reloc_name_lookup \
4701 1.1 christos elfNN_kvx_reloc_name_lookup
4702 1.1 christos
4703 1.1 christos #define bfd_elfNN_bfd_set_private_flags \
4704 1.1 christos elfNN_kvx_set_private_flags
4705 1.1 christos
4706 1.1 christos #define bfd_elfNN_mkobject \
4707 1.1 christos elfNN_kvx_mkobject
4708 1.1 christos
4709 1.1 christos #define bfd_elfNN_new_section_hook \
4710 1.1 christos elfNN_kvx_new_section_hook
4711 1.1 christos
4712 1.1 christos #define elf_backend_adjust_dynamic_symbol \
4713 1.1 christos elfNN_kvx_adjust_dynamic_symbol
4714 1.1 christos
4715 1.1.1.2 christos #define elf_backend_early_size_sections \
4716 1.1.1.2 christos elfNN_kvx_early_size_sections
4717 1.1 christos
4718 1.1 christos #define elf_backend_check_relocs \
4719 1.1 christos elfNN_kvx_check_relocs
4720 1.1 christos
4721 1.1 christos #define elf_backend_copy_indirect_symbol \
4722 1.1 christos elfNN_kvx_copy_indirect_symbol
4723 1.1 christos
4724 1.1 christos /* Create .dynbss, and .rela.bss sections in DYNOBJ, and set up shortcuts
4725 1.1 christos to them in our hash. */
4726 1.1 christos #define elf_backend_create_dynamic_sections \
4727 1.1 christos elfNN_kvx_create_dynamic_sections
4728 1.1 christos
4729 1.1 christos #define elf_backend_init_index_section \
4730 1.1 christos _bfd_elf_init_2_index_sections
4731 1.1 christos
4732 1.1 christos #define elf_backend_finish_dynamic_sections \
4733 1.1 christos elfNN_kvx_finish_dynamic_sections
4734 1.1 christos
4735 1.1 christos #define elf_backend_finish_dynamic_symbol \
4736 1.1 christos elfNN_kvx_finish_dynamic_symbol
4737 1.1 christos
4738 1.1 christos #define elf_backend_object_p \
4739 1.1 christos elfNN_kvx_object_p
4740 1.1 christos
4741 1.1 christos #define elf_backend_output_arch_local_syms \
4742 1.1 christos elfNN_kvx_output_arch_local_syms
4743 1.1 christos
4744 1.1 christos #define elf_backend_plt_sym_val \
4745 1.1 christos elfNN_kvx_plt_sym_val
4746 1.1 christos
4747 1.1 christos #define elf_backend_init_file_header \
4748 1.1 christos elfNN_kvx_init_file_header
4749 1.1 christos
4750 1.1 christos #define elf_backend_init_process_headers \
4751 1.1 christos elfNN_kvx_init_process_headers
4752 1.1 christos
4753 1.1 christos #define elf_backend_relocate_section \
4754 1.1 christos elfNN_kvx_relocate_section
4755 1.1 christos
4756 1.1 christos #define elf_backend_reloc_type_class \
4757 1.1 christos elfNN_kvx_reloc_type_class
4758 1.1 christos
4759 1.1.1.2 christos #define elf_backend_late_size_sections \
4760 1.1.1.2 christos elfNN_kvx_late_size_sections
4761 1.1 christos
4762 1.1 christos #define elf_backend_can_refcount 1
4763 1.1 christos #define elf_backend_can_gc_sections 1
4764 1.1 christos #define elf_backend_plt_readonly 1
4765 1.1 christos #define elf_backend_want_got_plt 1
4766 1.1 christos #define elf_backend_want_plt_sym 0
4767 1.1 christos #define elf_backend_may_use_rel_p 0
4768 1.1 christos #define elf_backend_may_use_rela_p 1
4769 1.1 christos #define elf_backend_default_use_rela_p 1
4770 1.1 christos #define elf_backend_rela_normal 1
4771 1.1 christos #define elf_backend_got_header_size (GOT_ENTRY_SIZE * 3)
4772 1.1 christos #define elf_backend_default_execstack 0
4773 1.1 christos #define elf_backend_extern_protected_data 1
4774 1.1 christos #define elf_backend_hash_symbol elf_kvx_hash_symbol
4775 1.1 christos
4776 1.1 christos #include "elfNN-target.h"
4777