* elf64-mips.c (define elf_backend_ignore_discarded_relocs): Remove
[deliverable/binutils-gdb.git] / bfd / elf64-mips.c
1 /* MIPS-specific support for 64-bit ELF
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Ian Lance Taylor, Cygnus Support
5 Linker support added by Mark Mitchell, CodeSourcery, LLC.
6 <mark@codesourcery.com>
7
8 This file is part of BFD, the Binary File Descriptor library.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23
24 /* This file supports the 64-bit MIPS ELF ABI.
25
26 The MIPS 64-bit ELF ABI uses an unusual reloc format. This file
27 overrides the usual ELF reloc handling, and handles reading and
28 writing the relocations here. */
29
30 /* TODO: Many things are unsupported, even if there is some code for it
31 . (which was mostly stolen from elf32-mips.c and slightly adapted).
32 .
33 . - Relocation handling for REL relocs is wrong in many cases and
34 . generally untested.
35 . - Relocation handling for RELA relocs related to GOT support are
36 . also likely to be wrong.
37 . - Support for MIPS16 is untested.
38 . - Combined relocs with RSS_* entries are unsupported.
39 . - The whole GOT handling for NewABI is missing, some parts of
40 . the OldABI version is still lying around and should be removed.
41 */
42
43 #include "bfd.h"
44 #include "sysdep.h"
45 #include "libbfd.h"
46 #include "aout/ar.h"
47 #include "bfdlink.h"
48 #include "genlink.h"
49 #include "elf-bfd.h"
50 #include "elfxx-mips.h"
51 #include "elf/mips.h"
52
53 /* Get the ECOFF swapping routines. The 64-bit ABI is not supposed to
54 use ECOFF. However, we support it anyhow for an easier changeover. */
55 #include "coff/sym.h"
56 #include "coff/symconst.h"
57 #include "coff/internal.h"
58 #include "coff/ecoff.h"
59 /* The 64 bit versions of the mdebug data structures are in alpha.h. */
60 #include "coff/alpha.h"
61 #define ECOFF_SIGNED_64
62 #include "ecoffswap.h"
63
64 static void mips_elf64_swap_reloc_in
65 PARAMS ((bfd *, const Elf64_Mips_External_Rel *,
66 Elf64_Mips_Internal_Rel *));
67 static void mips_elf64_swap_reloca_in
68 PARAMS ((bfd *, const Elf64_Mips_External_Rela *,
69 Elf64_Mips_Internal_Rela *));
70 static void mips_elf64_swap_reloc_out
71 PARAMS ((bfd *, const Elf64_Mips_Internal_Rel *,
72 Elf64_Mips_External_Rel *));
73 static void mips_elf64_swap_reloca_out
74 PARAMS ((bfd *, const Elf64_Mips_Internal_Rela *,
75 Elf64_Mips_External_Rela *));
76 static void mips_elf64_be_swap_reloc_in
77 PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rel *));
78 static void mips_elf64_be_swap_reloc_out
79 PARAMS ((bfd *, const Elf_Internal_Rel *, bfd_byte *));
80 static void mips_elf64_be_swap_reloca_in
81 PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *));
82 static void mips_elf64_be_swap_reloca_out
83 PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *));
84 static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup
85 PARAMS ((bfd *, bfd_reloc_code_real_type));
86 static reloc_howto_type *mips_elf64_rtype_to_howto
87 PARAMS ((unsigned int, boolean));
88 static void mips_elf64_info_to_howto_rel
89 PARAMS ((bfd *, arelent *, Elf64_Internal_Rel *));
90 static void mips_elf64_info_to_howto_rela
91 PARAMS ((bfd *, arelent *, Elf64_Internal_Rela *));
92 static long mips_elf64_get_reloc_upper_bound PARAMS ((bfd *, asection *));
93 static boolean mips_elf64_slurp_one_reloc_table
94 PARAMS ((bfd *, asection *, asymbol **, const Elf_Internal_Shdr *));
95 static boolean mips_elf64_slurp_reloc_table
96 PARAMS ((bfd *, asection *, asymbol **, boolean));
97 static void mips_elf64_write_relocs PARAMS ((bfd *, asection *, PTR));
98 static void mips_elf64_write_rel
99 PARAMS((bfd *, asection *, Elf_Internal_Shdr *, int *, PTR));
100 static void mips_elf64_write_rela
101 PARAMS((bfd *, asection *, Elf_Internal_Shdr *, int *, PTR));
102 static bfd_reloc_status_type mips_elf64_hi16_reloc
103 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
104 static bfd_reloc_status_type mips_elf64_gprel16_reloc
105 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
106 static bfd_reloc_status_type mips_elf64_literal_reloc
107 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
108 static bfd_reloc_status_type mips_elf64_gprel32_reloc
109 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
110 static bfd_reloc_status_type mips_elf64_shift6_reloc
111 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
112 static bfd_reloc_status_type mips_elf64_got16_reloc
113 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
114 static bfd_reloc_status_type mips16_jump_reloc
115 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
116 static bfd_reloc_status_type mips16_gprel_reloc
117 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
118 static boolean mips_elf64_assign_gp PARAMS ((bfd *, bfd_vma *));
119 static bfd_reloc_status_type mips_elf64_final_gp
120 PARAMS ((bfd *, asymbol *, boolean, char **, bfd_vma *));
121 static boolean mips_elf64_object_p PARAMS ((bfd *));
122 static irix_compat_t elf64_mips_irix_compat PARAMS ((bfd *));
123
124 extern const bfd_target bfd_elf64_bigmips_vec;
125 extern const bfd_target bfd_elf64_littlemips_vec;
126
127 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
128 from smaller values. Start with zero, widen, *then* decrement. */
129 #define MINUS_ONE (((bfd_vma)0) - 1)
130
131 /* The number of local .got entries we reserve. */
132 #define MIPS_RESERVED_GOTNO (2)
133 \f
134 /* The relocation table used for SHT_REL sections. */
135
136 static reloc_howto_type mips_elf64_howto_table_rel[] =
137 {
138 /* No relocation. */
139 HOWTO (R_MIPS_NONE, /* type */
140 0, /* rightshift */
141 0, /* size (0 = byte, 1 = short, 2 = long) */
142 0, /* bitsize */
143 false, /* pc_relative */
144 0, /* bitpos */
145 complain_overflow_dont, /* complain_on_overflow */
146 bfd_elf_generic_reloc, /* special_function */
147 "R_MIPS_NONE", /* name */
148 false, /* partial_inplace */
149 0, /* src_mask */
150 0, /* dst_mask */
151 false), /* pcrel_offset */
152
153 /* 16 bit relocation. */
154 HOWTO (R_MIPS_16, /* type */
155 0, /* rightshift */
156 2, /* size (0 = byte, 1 = short, 2 = long) */
157 16, /* bitsize */
158 false, /* pc_relative */
159 0, /* bitpos */
160 complain_overflow_signed, /* complain_on_overflow */
161 bfd_elf_generic_reloc, /* special_function */
162 "R_MIPS_16", /* name */
163 true, /* partial_inplace */
164 0x0000ffff, /* src_mask */
165 0x0000ffff, /* dst_mask */
166 false), /* pcrel_offset */
167
168 /* 32 bit relocation. */
169 HOWTO (R_MIPS_32, /* type */
170 0, /* rightshift */
171 2, /* size (0 = byte, 1 = short, 2 = long) */
172 32, /* bitsize */
173 false, /* pc_relative */
174 0, /* bitpos */
175 complain_overflow_dont, /* complain_on_overflow */
176 bfd_elf_generic_reloc, /* special_function */
177 "R_MIPS_32", /* name */
178 true, /* partial_inplace */
179 0xffffffff, /* src_mask */
180 0xffffffff, /* dst_mask */
181 false), /* pcrel_offset */
182
183 /* 32 bit symbol relative relocation. */
184 HOWTO (R_MIPS_REL32, /* type */
185 0, /* rightshift */
186 2, /* size (0 = byte, 1 = short, 2 = long) */
187 32, /* bitsize */
188 false, /* pc_relative */
189 0, /* bitpos */
190 complain_overflow_dont, /* complain_on_overflow */
191 bfd_elf_generic_reloc, /* special_function */
192 "R_MIPS_REL32", /* name */
193 true, /* partial_inplace */
194 0xffffffff, /* src_mask */
195 0xffffffff, /* dst_mask */
196 false), /* pcrel_offset */
197
198 /* 26 bit jump address. */
199 HOWTO (R_MIPS_26, /* type */
200 2, /* rightshift */
201 2, /* size (0 = byte, 1 = short, 2 = long) */
202 26, /* bitsize */
203 false, /* pc_relative */
204 0, /* bitpos */
205 complain_overflow_dont, /* complain_on_overflow */
206 /* This needs complex overflow
207 detection, because the upper 36
208 bits must match the PC + 4. */
209 bfd_elf_generic_reloc, /* special_function */
210 "R_MIPS_26", /* name */
211 true, /* partial_inplace */
212 0x03ffffff, /* src_mask */
213 0x03ffffff, /* dst_mask */
214 false), /* pcrel_offset */
215
216 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
217 However, the native IRIX6 tools use them, so we try our best. */
218
219 /* High 16 bits of symbol value. */
220 HOWTO (R_MIPS_HI16, /* type */
221 0, /* rightshift */
222 2, /* size (0 = byte, 1 = short, 2 = long) */
223 16, /* bitsize */
224 false, /* pc_relative */
225 0, /* bitpos */
226 complain_overflow_dont, /* complain_on_overflow */
227 mips_elf64_hi16_reloc, /* special_function */
228 "R_MIPS_HI16", /* name */
229 true, /* partial_inplace */
230 0x0000ffff, /* src_mask */
231 0x0000ffff, /* dst_mask */
232 false), /* pcrel_offset */
233
234 /* Low 16 bits of symbol value. */
235 HOWTO (R_MIPS_LO16, /* type */
236 0, /* rightshift */
237 2, /* size (0 = byte, 1 = short, 2 = long) */
238 16, /* bitsize */
239 false, /* pc_relative */
240 0, /* bitpos */
241 complain_overflow_dont, /* complain_on_overflow */
242 bfd_elf_generic_reloc, /* special_function */
243 "R_MIPS_LO16", /* name */
244 true, /* partial_inplace */
245 0x0000ffff, /* src_mask */
246 0x0000ffff, /* dst_mask */
247 false), /* pcrel_offset */
248
249 /* GP relative reference. */
250 HOWTO (R_MIPS_GPREL16, /* type */
251 0, /* rightshift */
252 2, /* size (0 = byte, 1 = short, 2 = long) */
253 16, /* bitsize */
254 false, /* pc_relative */
255 0, /* bitpos */
256 complain_overflow_signed, /* complain_on_overflow */
257 mips_elf64_gprel16_reloc, /* special_function */
258 "R_MIPS_GPREL16", /* name */
259 true, /* partial_inplace */
260 0x0000ffff, /* src_mask */
261 0x0000ffff, /* dst_mask */
262 false), /* pcrel_offset */
263
264 /* Reference to literal section. */
265 HOWTO (R_MIPS_LITERAL, /* type */
266 0, /* rightshift */
267 2, /* size (0 = byte, 1 = short, 2 = long) */
268 16, /* bitsize */
269 false, /* pc_relative */
270 0, /* bitpos */
271 complain_overflow_signed, /* complain_on_overflow */
272 mips_elf64_literal_reloc, /* special_function */
273 "R_MIPS_LITERAL", /* name */
274 true, /* partial_inplace */
275 0x0000ffff, /* src_mask */
276 0x0000ffff, /* dst_mask */
277 false), /* pcrel_offset */
278
279 /* Reference to global offset table. */
280 HOWTO (R_MIPS_GOT16, /* type */
281 0, /* rightshift */
282 2, /* size (0 = byte, 1 = short, 2 = long) */
283 16, /* bitsize */
284 false, /* pc_relative */
285 0, /* bitpos */
286 complain_overflow_signed, /* complain_on_overflow */
287 mips_elf64_got16_reloc, /* special_function */
288 "R_MIPS_GOT16", /* name */
289 true, /* partial_inplace */
290 0x0000ffff, /* src_mask */
291 0x0000ffff, /* dst_mask */
292 false), /* pcrel_offset */
293
294 /* 16 bit PC relative reference. */
295 HOWTO (R_MIPS_PC16, /* type */
296 0, /* rightshift */
297 2, /* size (0 = byte, 1 = short, 2 = long) */
298 16, /* bitsize */
299 true, /* pc_relative */
300 0, /* bitpos */
301 complain_overflow_signed, /* complain_on_overflow */
302 bfd_elf_generic_reloc, /* special_function */
303 "R_MIPS_PC16", /* name */
304 true, /* partial_inplace */
305 0x0000ffff, /* src_mask */
306 0x0000ffff, /* dst_mask */
307 true), /* pcrel_offset */
308
309 /* 16 bit call through global offset table. */
310 HOWTO (R_MIPS_CALL16, /* type */
311 0, /* rightshift */
312 2, /* size (0 = byte, 1 = short, 2 = long) */
313 16, /* bitsize */
314 false, /* pc_relative */
315 0, /* bitpos */
316 complain_overflow_signed, /* complain_on_overflow */
317 bfd_elf_generic_reloc, /* special_function */
318 "R_MIPS_CALL16", /* name */
319 true, /* partial_inplace */
320 0x0000ffff, /* src_mask */
321 0x0000ffff, /* dst_mask */
322 false), /* pcrel_offset */
323
324 /* 32 bit GP relative reference. */
325 HOWTO (R_MIPS_GPREL32, /* type */
326 0, /* rightshift */
327 2, /* size (0 = byte, 1 = short, 2 = long) */
328 32, /* bitsize */
329 false, /* pc_relative */
330 0, /* bitpos */
331 complain_overflow_dont, /* complain_on_overflow */
332 mips_elf64_gprel32_reloc, /* special_function */
333 "R_MIPS_GPREL32", /* name */
334 true, /* partial_inplace */
335 0xffffffff, /* src_mask */
336 0xffffffff, /* dst_mask */
337 false), /* pcrel_offset */
338
339 EMPTY_HOWTO (13),
340 EMPTY_HOWTO (14),
341 EMPTY_HOWTO (15),
342
343 /* A 5 bit shift field. */
344 HOWTO (R_MIPS_SHIFT5, /* type */
345 0, /* rightshift */
346 2, /* size (0 = byte, 1 = short, 2 = long) */
347 5, /* bitsize */
348 false, /* pc_relative */
349 6, /* bitpos */
350 complain_overflow_bitfield, /* complain_on_overflow */
351 bfd_elf_generic_reloc, /* special_function */
352 "R_MIPS_SHIFT5", /* name */
353 true, /* partial_inplace */
354 0x000007c0, /* src_mask */
355 0x000007c0, /* dst_mask */
356 false), /* pcrel_offset */
357
358 /* A 6 bit shift field. */
359 HOWTO (R_MIPS_SHIFT6, /* type */
360 0, /* rightshift */
361 2, /* size (0 = byte, 1 = short, 2 = long) */
362 6, /* bitsize */
363 false, /* pc_relative */
364 6, /* bitpos */
365 complain_overflow_bitfield, /* complain_on_overflow */
366 mips_elf64_shift6_reloc, /* special_function */
367 "R_MIPS_SHIFT6", /* name */
368 true, /* partial_inplace */
369 0x000007c4, /* src_mask */
370 0x000007c4, /* dst_mask */
371 false), /* pcrel_offset */
372
373 /* 64 bit relocation. */
374 HOWTO (R_MIPS_64, /* type */
375 0, /* rightshift */
376 4, /* size (0 = byte, 1 = short, 2 = long) */
377 64, /* bitsize */
378 false, /* pc_relative */
379 0, /* bitpos */
380 complain_overflow_dont, /* complain_on_overflow */
381 bfd_elf_generic_reloc, /* special_function */
382 "R_MIPS_64", /* name */
383 true, /* partial_inplace */
384 MINUS_ONE, /* src_mask */
385 MINUS_ONE, /* dst_mask */
386 false), /* pcrel_offset */
387
388 /* Displacement in the global offset table. */
389 HOWTO (R_MIPS_GOT_DISP, /* type */
390 0, /* rightshift */
391 2, /* size (0 = byte, 1 = short, 2 = long) */
392 16, /* bitsize */
393 false, /* pc_relative */
394 0, /* bitpos */
395 complain_overflow_signed, /* complain_on_overflow */
396 bfd_elf_generic_reloc, /* special_function */
397 "R_MIPS_GOT_DISP", /* name */
398 true, /* partial_inplace */
399 0x0000ffff, /* src_mask */
400 0x0000ffff, /* dst_mask */
401 false), /* pcrel_offset */
402
403 /* Displacement to page pointer in the global offset table. */
404 HOWTO (R_MIPS_GOT_PAGE, /* type */
405 0, /* rightshift */
406 2, /* size (0 = byte, 1 = short, 2 = long) */
407 16, /* bitsize */
408 false, /* pc_relative */
409 0, /* bitpos */
410 complain_overflow_signed, /* complain_on_overflow */
411 bfd_elf_generic_reloc, /* special_function */
412 "R_MIPS_GOT_PAGE", /* name */
413 true, /* partial_inplace */
414 0x0000ffff, /* src_mask */
415 0x0000ffff, /* dst_mask */
416 false), /* pcrel_offset */
417
418 /* Offset from page pointer in the global offset table. */
419 HOWTO (R_MIPS_GOT_OFST, /* type */
420 0, /* rightshift */
421 2, /* size (0 = byte, 1 = short, 2 = long) */
422 16, /* bitsize */
423 false, /* pc_relative */
424 0, /* bitpos */
425 complain_overflow_signed, /* complain_on_overflow */
426 bfd_elf_generic_reloc, /* special_function */
427 "R_MIPS_GOT_OFST", /* name */
428 true, /* partial_inplace */
429 0x0000ffff, /* src_mask */
430 0x0000ffff, /* dst_mask */
431 false), /* pcrel_offset */
432
433 /* High 16 bits of displacement in global offset table. */
434 HOWTO (R_MIPS_GOT_HI16, /* type */
435 0, /* rightshift */
436 2, /* size (0 = byte, 1 = short, 2 = long) */
437 16, /* bitsize */
438 false, /* pc_relative */
439 0, /* bitpos */
440 complain_overflow_dont, /* complain_on_overflow */
441 bfd_elf_generic_reloc, /* special_function */
442 "R_MIPS_GOT_HI16", /* name */
443 true, /* partial_inplace */
444 0x0000ffff, /* src_mask */
445 0x0000ffff, /* dst_mask */
446 false), /* pcrel_offset */
447
448 /* Low 16 bits of displacement in global offset table. */
449 HOWTO (R_MIPS_GOT_LO16, /* type */
450 0, /* rightshift */
451 2, /* size (0 = byte, 1 = short, 2 = long) */
452 16, /* bitsize */
453 false, /* pc_relative */
454 0, /* bitpos */
455 complain_overflow_dont, /* complain_on_overflow */
456 bfd_elf_generic_reloc, /* special_function */
457 "R_MIPS_GOT_LO16", /* name */
458 true, /* partial_inplace */
459 0x0000ffff, /* src_mask */
460 0x0000ffff, /* dst_mask */
461 false), /* pcrel_offset */
462
463 /* 64 bit substraction. */
464 HOWTO (R_MIPS_SUB, /* type */
465 0, /* rightshift */
466 4, /* size (0 = byte, 1 = short, 2 = long) */
467 64, /* bitsize */
468 false, /* pc_relative */
469 0, /* bitpos */
470 complain_overflow_dont, /* complain_on_overflow */
471 bfd_elf_generic_reloc, /* special_function */
472 "R_MIPS_SUB", /* name */
473 true, /* partial_inplace */
474 MINUS_ONE, /* src_mask */
475 MINUS_ONE, /* dst_mask */
476 false), /* pcrel_offset */
477
478 /* Insert the addend as an instruction. */
479 /* FIXME: Not handled correctly. */
480 HOWTO (R_MIPS_INSERT_A, /* type */
481 0, /* rightshift */
482 2, /* size (0 = byte, 1 = short, 2 = long) */
483 32, /* bitsize */
484 false, /* pc_relative */
485 0, /* bitpos */
486 complain_overflow_dont, /* complain_on_overflow */
487 bfd_elf_generic_reloc, /* special_function */
488 "R_MIPS_INSERT_A", /* name */
489 true, /* partial_inplace */
490 0xffffffff, /* src_mask */
491 0xffffffff, /* dst_mask */
492 false), /* pcrel_offset */
493
494 /* Insert the addend as an instruction, and change all relocations
495 to refer to the old instruction at the address. */
496 /* FIXME: Not handled correctly. */
497 HOWTO (R_MIPS_INSERT_B, /* type */
498 0, /* rightshift */
499 2, /* size (0 = byte, 1 = short, 2 = long) */
500 32, /* bitsize */
501 false, /* pc_relative */
502 0, /* bitpos */
503 complain_overflow_dont, /* complain_on_overflow */
504 bfd_elf_generic_reloc, /* special_function */
505 "R_MIPS_INSERT_B", /* name */
506 true, /* partial_inplace */
507 0xffffffff, /* src_mask */
508 0xffffffff, /* dst_mask */
509 false), /* pcrel_offset */
510
511 /* Delete a 32 bit instruction. */
512 /* FIXME: Not handled correctly. */
513 HOWTO (R_MIPS_DELETE, /* type */
514 0, /* rightshift */
515 2, /* size (0 = byte, 1 = short, 2 = long) */
516 32, /* bitsize */
517 false, /* pc_relative */
518 0, /* bitpos */
519 complain_overflow_dont, /* complain_on_overflow */
520 bfd_elf_generic_reloc, /* special_function */
521 "R_MIPS_DELETE", /* name */
522 true, /* partial_inplace */
523 0xffffffff, /* src_mask */
524 0xffffffff, /* dst_mask */
525 false), /* pcrel_offset */
526
527 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
528 We don't, because
529 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
530 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
531 fallable heuristics.
532 b) No other NewABI toolchain actually emits such relocations. */
533 EMPTY_HOWTO (R_MIPS_HIGHER),
534 EMPTY_HOWTO (R_MIPS_HIGHEST),
535
536 /* High 16 bits of displacement in global offset table. */
537 HOWTO (R_MIPS_CALL_HI16, /* type */
538 0, /* rightshift */
539 2, /* size (0 = byte, 1 = short, 2 = long) */
540 16, /* bitsize */
541 false, /* pc_relative */
542 0, /* bitpos */
543 complain_overflow_dont, /* complain_on_overflow */
544 bfd_elf_generic_reloc, /* special_function */
545 "R_MIPS_CALL_HI16", /* name */
546 true, /* partial_inplace */
547 0x0000ffff, /* src_mask */
548 0x0000ffff, /* dst_mask */
549 false), /* pcrel_offset */
550
551 /* Low 16 bits of displacement in global offset table. */
552 HOWTO (R_MIPS_CALL_LO16, /* type */
553 0, /* rightshift */
554 2, /* size (0 = byte, 1 = short, 2 = long) */
555 16, /* bitsize */
556 false, /* pc_relative */
557 0, /* bitpos */
558 complain_overflow_dont, /* complain_on_overflow */
559 bfd_elf_generic_reloc, /* special_function */
560 "R_MIPS_CALL_LO16", /* name */
561 true, /* partial_inplace */
562 0x0000ffff, /* src_mask */
563 0x0000ffff, /* dst_mask */
564 false), /* pcrel_offset */
565
566 /* Section displacement, used by an associated event location section. */
567 HOWTO (R_MIPS_SCN_DISP, /* type */
568 0, /* rightshift */
569 2, /* size (0 = byte, 1 = short, 2 = long) */
570 32, /* bitsize */
571 false, /* pc_relative */
572 0, /* bitpos */
573 complain_overflow_dont, /* complain_on_overflow */
574 bfd_elf_generic_reloc, /* special_function */
575 "R_MIPS_SCN_DISP", /* name */
576 true, /* partial_inplace */
577 0xffffffff, /* src_mask */
578 0xffffffff, /* dst_mask */
579 false), /* pcrel_offset */
580
581 HOWTO (R_MIPS_REL16, /* type */
582 0, /* rightshift */
583 1, /* size (0 = byte, 1 = short, 2 = long) */
584 16, /* bitsize */
585 false, /* pc_relative */
586 0, /* bitpos */
587 complain_overflow_signed, /* complain_on_overflow */
588 bfd_elf_generic_reloc, /* special_function */
589 "R_MIPS_REL16", /* name */
590 true, /* partial_inplace */
591 0xffff, /* src_mask */
592 0xffff, /* dst_mask */
593 false), /* pcrel_offset */
594
595 /* These two are obsolete. */
596 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
597 EMPTY_HOWTO (R_MIPS_PJUMP),
598
599 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
600 It must be used for multigot GOT's (and only there). */
601 HOWTO (R_MIPS_RELGOT, /* type */
602 0, /* rightshift */
603 2, /* size (0 = byte, 1 = short, 2 = long) */
604 32, /* bitsize */
605 false, /* pc_relative */
606 0, /* bitpos */
607 complain_overflow_dont, /* complain_on_overflow */
608 bfd_elf_generic_reloc, /* special_function */
609 "R_MIPS_RELGOT", /* name */
610 true, /* partial_inplace */
611 0xffffffff, /* src_mask */
612 0xffffffff, /* dst_mask */
613 false), /* pcrel_offset */
614
615 /* Protected jump conversion. This is an optimization hint. No
616 relocation is required for correctness. */
617 HOWTO (R_MIPS_JALR, /* type */
618 0, /* rightshift */
619 2, /* size (0 = byte, 1 = short, 2 = long) */
620 32, /* bitsize */
621 false, /* pc_relative */
622 0, /* bitpos */
623 complain_overflow_dont, /* complain_on_overflow */
624 bfd_elf_generic_reloc, /* special_function */
625 "R_MIPS_JALR", /* name */
626 false, /* partial_inplace */
627 0, /* src_mask */
628 0x00000000, /* dst_mask */
629 false), /* pcrel_offset */
630 };
631
632 /* The relocation table used for SHT_RELA sections. */
633
634 static reloc_howto_type mips_elf64_howto_table_rela[] =
635 {
636 /* No relocation. */
637 HOWTO (R_MIPS_NONE, /* type */
638 0, /* rightshift */
639 0, /* size (0 = byte, 1 = short, 2 = long) */
640 0, /* bitsize */
641 false, /* pc_relative */
642 0, /* bitpos */
643 complain_overflow_dont, /* complain_on_overflow */
644 bfd_elf_generic_reloc, /* special_function */
645 "R_MIPS_NONE", /* name */
646 false, /* partial_inplace */
647 0, /* src_mask */
648 0, /* dst_mask */
649 false), /* pcrel_offset */
650
651 /* 16 bit relocation. */
652 HOWTO (R_MIPS_16, /* type */
653 0, /* rightshift */
654 2, /* size (0 = byte, 1 = short, 2 = long) */
655 16, /* bitsize */
656 false, /* pc_relative */
657 0, /* bitpos */
658 complain_overflow_signed, /* complain_on_overflow */
659 bfd_elf_generic_reloc, /* special_function */
660 "R_MIPS_16", /* name */
661 false, /* partial_inplace */
662 0, /* src_mask */
663 0x0000ffff, /* dst_mask */
664 false), /* pcrel_offset */
665
666 /* 32 bit relocation. */
667 HOWTO (R_MIPS_32, /* type */
668 0, /* rightshift */
669 2, /* size (0 = byte, 1 = short, 2 = long) */
670 32, /* bitsize */
671 false, /* pc_relative */
672 0, /* bitpos */
673 complain_overflow_dont, /* complain_on_overflow */
674 bfd_elf_generic_reloc, /* special_function */
675 "R_MIPS_32", /* name */
676 false, /* partial_inplace */
677 0, /* src_mask */
678 0xffffffff, /* dst_mask */
679 false), /* pcrel_offset */
680
681 /* 32 bit symbol relative relocation. */
682 HOWTO (R_MIPS_REL32, /* type */
683 0, /* rightshift */
684 2, /* size (0 = byte, 1 = short, 2 = long) */
685 32, /* bitsize */
686 false, /* pc_relative */
687 0, /* bitpos */
688 complain_overflow_dont, /* complain_on_overflow */
689 bfd_elf_generic_reloc, /* special_function */
690 "R_MIPS_REL32", /* name */
691 false, /* partial_inplace */
692 0, /* src_mask */
693 0xffffffff, /* dst_mask */
694 false), /* pcrel_offset */
695
696 /* 26 bit jump address. */
697 HOWTO (R_MIPS_26, /* type */
698 2, /* rightshift */
699 2, /* size (0 = byte, 1 = short, 2 = long) */
700 26, /* bitsize */
701 false, /* pc_relative */
702 0, /* bitpos */
703 complain_overflow_dont, /* complain_on_overflow */
704 /* This needs complex overflow
705 detection, because the upper 36
706 bits must match the PC + 4. */
707 bfd_elf_generic_reloc, /* special_function */
708 "R_MIPS_26", /* name */
709 false, /* partial_inplace */
710 0, /* src_mask */
711 0x03ffffff, /* dst_mask */
712 false), /* pcrel_offset */
713
714 /* High 16 bits of symbol value. */
715 HOWTO (R_MIPS_HI16, /* type */
716 0, /* rightshift */
717 2, /* size (0 = byte, 1 = short, 2 = long) */
718 16, /* bitsize */
719 false, /* pc_relative */
720 0, /* bitpos */
721 complain_overflow_dont, /* complain_on_overflow */
722 bfd_elf_generic_reloc, /* special_function */
723 "R_MIPS_HI16", /* name */
724 false, /* partial_inplace */
725 0, /* src_mask */
726 0x0000ffff, /* dst_mask */
727 false), /* pcrel_offset */
728
729 /* Low 16 bits of symbol value. */
730 HOWTO (R_MIPS_LO16, /* type */
731 0, /* rightshift */
732 2, /* size (0 = byte, 1 = short, 2 = long) */
733 16, /* bitsize */
734 false, /* pc_relative */
735 0, /* bitpos */
736 complain_overflow_dont, /* complain_on_overflow */
737 bfd_elf_generic_reloc, /* special_function */
738 "R_MIPS_LO16", /* name */
739 false, /* partial_inplace */
740 0, /* src_mask */
741 0x0000ffff, /* dst_mask */
742 false), /* pcrel_offset */
743
744 /* GP relative reference. */
745 HOWTO (R_MIPS_GPREL16, /* type */
746 0, /* rightshift */
747 2, /* size (0 = byte, 1 = short, 2 = long) */
748 16, /* bitsize */
749 false, /* pc_relative */
750 0, /* bitpos */
751 complain_overflow_signed, /* complain_on_overflow */
752 mips_elf64_gprel16_reloc, /* special_function */
753 "R_MIPS_GPREL16", /* name */
754 false, /* partial_inplace */
755 0, /* src_mask */
756 0x0000ffff, /* dst_mask */
757 false), /* pcrel_offset */
758
759 /* Reference to literal section. */
760 HOWTO (R_MIPS_LITERAL, /* type */
761 0, /* rightshift */
762 2, /* size (0 = byte, 1 = short, 2 = long) */
763 16, /* bitsize */
764 false, /* pc_relative */
765 0, /* bitpos */
766 complain_overflow_signed, /* complain_on_overflow */
767 mips_elf64_literal_reloc, /* special_function */
768 "R_MIPS_LITERAL", /* name */
769 false, /* partial_inplace */
770 0, /* src_mask */
771 0x0000ffff, /* dst_mask */
772 false), /* pcrel_offset */
773
774 /* Reference to global offset table. */
775 HOWTO (R_MIPS_GOT16, /* type */
776 0, /* rightshift */
777 2, /* size (0 = byte, 1 = short, 2 = long) */
778 16, /* bitsize */
779 false, /* pc_relative */
780 0, /* bitpos */
781 complain_overflow_signed, /* complain_on_overflow */
782 mips_elf64_got16_reloc, /* special_function */
783 "R_MIPS_GOT16", /* name */
784 false, /* partial_inplace */
785 0, /* src_mask */
786 0x0000ffff, /* dst_mask */
787 false), /* pcrel_offset */
788
789 /* 16 bit PC relative reference. */
790 HOWTO (R_MIPS_PC16, /* type */
791 0, /* rightshift */
792 2, /* size (0 = byte, 1 = short, 2 = long) */
793 16, /* bitsize */
794 true, /* pc_relative */
795 0, /* bitpos */
796 complain_overflow_signed, /* complain_on_overflow */
797 bfd_elf_generic_reloc, /* special_function */
798 "R_MIPS_PC16", /* name */
799 false, /* partial_inplace */
800 0, /* src_mask */
801 0x0000ffff, /* dst_mask */
802 true), /* pcrel_offset */
803
804 /* 16 bit call through global offset table. */
805 HOWTO (R_MIPS_CALL16, /* type */
806 0, /* rightshift */
807 2, /* size (0 = byte, 1 = short, 2 = long) */
808 16, /* bitsize */
809 false, /* pc_relative */
810 0, /* bitpos */
811 complain_overflow_signed, /* complain_on_overflow */
812 bfd_elf_generic_reloc, /* special_function */
813 "R_MIPS_CALL16", /* name */
814 false, /* partial_inplace */
815 0, /* src_mask */
816 0x0000ffff, /* dst_mask */
817 false), /* pcrel_offset */
818
819 /* 32 bit GP relative reference. */
820 HOWTO (R_MIPS_GPREL32, /* type */
821 0, /* rightshift */
822 2, /* size (0 = byte, 1 = short, 2 = long) */
823 32, /* bitsize */
824 false, /* pc_relative */
825 0, /* bitpos */
826 complain_overflow_dont, /* complain_on_overflow */
827 mips_elf64_gprel32_reloc, /* special_function */
828 "R_MIPS_GPREL32", /* name */
829 false, /* partial_inplace */
830 0, /* src_mask */
831 0xffffffff, /* dst_mask */
832 false), /* pcrel_offset */
833
834 EMPTY_HOWTO (13),
835 EMPTY_HOWTO (14),
836 EMPTY_HOWTO (15),
837
838 /* A 5 bit shift field. */
839 HOWTO (R_MIPS_SHIFT5, /* type */
840 0, /* rightshift */
841 2, /* size (0 = byte, 1 = short, 2 = long) */
842 5, /* bitsize */
843 false, /* pc_relative */
844 6, /* bitpos */
845 complain_overflow_bitfield, /* complain_on_overflow */
846 bfd_elf_generic_reloc, /* special_function */
847 "R_MIPS_SHIFT5", /* name */
848 false, /* partial_inplace */
849 0, /* src_mask */
850 0x000007c0, /* dst_mask */
851 false), /* pcrel_offset */
852
853 /* A 6 bit shift field. */
854 HOWTO (R_MIPS_SHIFT6, /* type */
855 0, /* rightshift */
856 2, /* size (0 = byte, 1 = short, 2 = long) */
857 6, /* bitsize */
858 false, /* pc_relative */
859 6, /* bitpos */
860 complain_overflow_bitfield, /* complain_on_overflow */
861 mips_elf64_shift6_reloc, /* special_function */
862 "R_MIPS_SHIFT6", /* name */
863 false, /* partial_inplace */
864 0, /* src_mask */
865 0x000007c4, /* dst_mask */
866 false), /* pcrel_offset */
867
868 /* 64 bit relocation. */
869 HOWTO (R_MIPS_64, /* type */
870 0, /* rightshift */
871 4, /* size (0 = byte, 1 = short, 2 = long) */
872 64, /* bitsize */
873 false, /* pc_relative */
874 0, /* bitpos */
875 complain_overflow_dont, /* complain_on_overflow */
876 bfd_elf_generic_reloc, /* special_function */
877 "R_MIPS_64", /* name */
878 false, /* partial_inplace */
879 0, /* src_mask */
880 MINUS_ONE, /* dst_mask */
881 false), /* pcrel_offset */
882
883 /* Displacement in the global offset table. */
884 HOWTO (R_MIPS_GOT_DISP, /* type */
885 0, /* rightshift */
886 2, /* size (0 = byte, 1 = short, 2 = long) */
887 16, /* bitsize */
888 false, /* pc_relative */
889 0, /* bitpos */
890 complain_overflow_signed, /* complain_on_overflow */
891 bfd_elf_generic_reloc, /* special_function */
892 "R_MIPS_GOT_DISP", /* name */
893 false, /* partial_inplace */
894 0, /* src_mask */
895 0x0000ffff, /* dst_mask */
896 false), /* pcrel_offset */
897
898 /* Displacement to page pointer in the global offset table. */
899 HOWTO (R_MIPS_GOT_PAGE, /* type */
900 0, /* rightshift */
901 2, /* size (0 = byte, 1 = short, 2 = long) */
902 16, /* bitsize */
903 false, /* pc_relative */
904 0, /* bitpos */
905 complain_overflow_signed, /* complain_on_overflow */
906 bfd_elf_generic_reloc, /* special_function */
907 "R_MIPS_GOT_PAGE", /* name */
908 false, /* partial_inplace */
909 0, /* src_mask */
910 0x0000ffff, /* dst_mask */
911 false), /* pcrel_offset */
912
913 /* Offset from page pointer in the global offset table. */
914 HOWTO (R_MIPS_GOT_OFST, /* type */
915 0, /* rightshift */
916 2, /* size (0 = byte, 1 = short, 2 = long) */
917 16, /* bitsize */
918 false, /* pc_relative */
919 0, /* bitpos */
920 complain_overflow_signed, /* complain_on_overflow */
921 bfd_elf_generic_reloc, /* special_function */
922 "R_MIPS_GOT_OFST", /* name */
923 false, /* partial_inplace */
924 0, /* src_mask */
925 0x0000ffff, /* dst_mask */
926 false), /* pcrel_offset */
927
928 /* High 16 bits of displacement in global offset table. */
929 HOWTO (R_MIPS_GOT_HI16, /* type */
930 0, /* rightshift */
931 2, /* size (0 = byte, 1 = short, 2 = long) */
932 16, /* bitsize */
933 false, /* pc_relative */
934 0, /* bitpos */
935 complain_overflow_dont, /* complain_on_overflow */
936 bfd_elf_generic_reloc, /* special_function */
937 "R_MIPS_GOT_HI16", /* name */
938 false, /* partial_inplace */
939 0, /* src_mask */
940 0x0000ffff, /* dst_mask */
941 false), /* pcrel_offset */
942
943 /* Low 16 bits of displacement in global offset table. */
944 HOWTO (R_MIPS_GOT_LO16, /* type */
945 0, /* rightshift */
946 2, /* size (0 = byte, 1 = short, 2 = long) */
947 16, /* bitsize */
948 false, /* pc_relative */
949 0, /* bitpos */
950 complain_overflow_dont, /* complain_on_overflow */
951 bfd_elf_generic_reloc, /* special_function */
952 "R_MIPS_GOT_LO16", /* name */
953 false, /* partial_inplace */
954 0, /* src_mask */
955 0x0000ffff, /* dst_mask */
956 false), /* pcrel_offset */
957
958 /* 64 bit substraction. */
959 HOWTO (R_MIPS_SUB, /* type */
960 0, /* rightshift */
961 4, /* size (0 = byte, 1 = short, 2 = long) */
962 64, /* bitsize */
963 false, /* pc_relative */
964 0, /* bitpos */
965 complain_overflow_dont, /* complain_on_overflow */
966 bfd_elf_generic_reloc, /* special_function */
967 "R_MIPS_SUB", /* name */
968 false, /* partial_inplace */
969 0, /* src_mask */
970 MINUS_ONE, /* dst_mask */
971 false), /* pcrel_offset */
972
973 /* Insert the addend as an instruction. */
974 /* FIXME: Not handled correctly. */
975 HOWTO (R_MIPS_INSERT_A, /* type */
976 0, /* rightshift */
977 2, /* size (0 = byte, 1 = short, 2 = long) */
978 32, /* bitsize */
979 false, /* pc_relative */
980 0, /* bitpos */
981 complain_overflow_dont, /* complain_on_overflow */
982 bfd_elf_generic_reloc, /* special_function */
983 "R_MIPS_INSERT_A", /* name */
984 false, /* partial_inplace */
985 0, /* src_mask */
986 0xffffffff, /* dst_mask */
987 false), /* pcrel_offset */
988
989 /* Insert the addend as an instruction, and change all relocations
990 to refer to the old instruction at the address. */
991 /* FIXME: Not handled correctly. */
992 HOWTO (R_MIPS_INSERT_B, /* type */
993 0, /* rightshift */
994 2, /* size (0 = byte, 1 = short, 2 = long) */
995 32, /* bitsize */
996 false, /* pc_relative */
997 0, /* bitpos */
998 complain_overflow_dont, /* complain_on_overflow */
999 bfd_elf_generic_reloc, /* special_function */
1000 "R_MIPS_INSERT_B", /* name */
1001 false, /* partial_inplace */
1002 0, /* src_mask */
1003 0xffffffff, /* dst_mask */
1004 false), /* pcrel_offset */
1005
1006 /* Delete a 32 bit instruction. */
1007 /* FIXME: Not handled correctly. */
1008 HOWTO (R_MIPS_DELETE, /* type */
1009 0, /* rightshift */
1010 2, /* size (0 = byte, 1 = short, 2 = long) */
1011 32, /* bitsize */
1012 false, /* pc_relative */
1013 0, /* bitpos */
1014 complain_overflow_dont, /* complain_on_overflow */
1015 bfd_elf_generic_reloc, /* special_function */
1016 "R_MIPS_DELETE", /* name */
1017 false, /* partial_inplace */
1018 0, /* src_mask */
1019 0xffffffff, /* dst_mask */
1020 false), /* pcrel_offset */
1021
1022 /* Get the higher value of a 64 bit addend. */
1023 HOWTO (R_MIPS_HIGHER, /* type */
1024 0, /* rightshift */
1025 2, /* size (0 = byte, 1 = short, 2 = long) */
1026 16, /* bitsize */
1027 false, /* pc_relative */
1028 0, /* bitpos */
1029 complain_overflow_dont, /* complain_on_overflow */
1030 bfd_elf_generic_reloc, /* special_function */
1031 "R_MIPS_HIGHER", /* name */
1032 false, /* partial_inplace */
1033 0, /* src_mask */
1034 0x0000ffff, /* dst_mask */
1035 false), /* pcrel_offset */
1036
1037 /* Get the highest value of a 64 bit addend. */
1038 HOWTO (R_MIPS_HIGHEST, /* type */
1039 0, /* rightshift */
1040 2, /* size (0 = byte, 1 = short, 2 = long) */
1041 16, /* bitsize */
1042 false, /* pc_relative */
1043 0, /* bitpos */
1044 complain_overflow_dont, /* complain_on_overflow */
1045 bfd_elf_generic_reloc, /* special_function */
1046 "R_MIPS_HIGHEST", /* name */
1047 false, /* partial_inplace */
1048 0, /* src_mask */
1049 0x0000ffff, /* dst_mask */
1050 false), /* pcrel_offset */
1051
1052 /* High 16 bits of displacement in global offset table. */
1053 HOWTO (R_MIPS_CALL_HI16, /* type */
1054 0, /* rightshift */
1055 2, /* size (0 = byte, 1 = short, 2 = long) */
1056 16, /* bitsize */
1057 false, /* pc_relative */
1058 0, /* bitpos */
1059 complain_overflow_dont, /* complain_on_overflow */
1060 bfd_elf_generic_reloc, /* special_function */
1061 "R_MIPS_CALL_HI16", /* name */
1062 false, /* partial_inplace */
1063 0, /* src_mask */
1064 0x0000ffff, /* dst_mask */
1065 false), /* pcrel_offset */
1066
1067 /* Low 16 bits of displacement in global offset table. */
1068 HOWTO (R_MIPS_CALL_LO16, /* type */
1069 0, /* rightshift */
1070 2, /* size (0 = byte, 1 = short, 2 = long) */
1071 16, /* bitsize */
1072 false, /* pc_relative */
1073 0, /* bitpos */
1074 complain_overflow_dont, /* complain_on_overflow */
1075 bfd_elf_generic_reloc, /* special_function */
1076 "R_MIPS_CALL_LO16", /* name */
1077 false, /* partial_inplace */
1078 0, /* src_mask */
1079 0x0000ffff, /* dst_mask */
1080 false), /* pcrel_offset */
1081
1082 /* Section displacement, used by an associated event location section. */
1083 HOWTO (R_MIPS_SCN_DISP, /* type */
1084 0, /* rightshift */
1085 2, /* size (0 = byte, 1 = short, 2 = long) */
1086 32, /* bitsize */
1087 false, /* pc_relative */
1088 0, /* bitpos */
1089 complain_overflow_dont, /* complain_on_overflow */
1090 bfd_elf_generic_reloc, /* special_function */
1091 "R_MIPS_SCN_DISP", /* name */
1092 false, /* partial_inplace */
1093 0, /* src_mask */
1094 0xffffffff, /* dst_mask */
1095 false), /* pcrel_offset */
1096
1097 HOWTO (R_MIPS_REL16, /* type */
1098 0, /* rightshift */
1099 1, /* size (0 = byte, 1 = short, 2 = long) */
1100 16, /* bitsize */
1101 false, /* pc_relative */
1102 0, /* bitpos */
1103 complain_overflow_signed, /* complain_on_overflow */
1104 bfd_elf_generic_reloc, /* special_function */
1105 "R_MIPS_REL16", /* name */
1106 false, /* partial_inplace */
1107 0, /* src_mask */
1108 0xffff, /* dst_mask */
1109 false), /* pcrel_offset */
1110
1111 /* These two are obsolete. */
1112 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1113 EMPTY_HOWTO (R_MIPS_PJUMP),
1114
1115 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1116 It must be used for multigot GOT's (and only there). */
1117 HOWTO (R_MIPS_RELGOT, /* type */
1118 0, /* rightshift */
1119 2, /* size (0 = byte, 1 = short, 2 = long) */
1120 32, /* bitsize */
1121 false, /* pc_relative */
1122 0, /* bitpos */
1123 complain_overflow_dont, /* complain_on_overflow */
1124 bfd_elf_generic_reloc, /* special_function */
1125 "R_MIPS_RELGOT", /* name */
1126 false, /* partial_inplace */
1127 0, /* src_mask */
1128 0xffffffff, /* dst_mask */
1129 false), /* pcrel_offset */
1130
1131 /* Protected jump conversion. This is an optimization hint. No
1132 relocation is required for correctness. */
1133 HOWTO (R_MIPS_JALR, /* type */
1134 0, /* rightshift */
1135 2, /* size (0 = byte, 1 = short, 2 = long) */
1136 32, /* bitsize */
1137 false, /* pc_relative */
1138 0, /* bitpos */
1139 complain_overflow_dont, /* complain_on_overflow */
1140 bfd_elf_generic_reloc, /* special_function */
1141 "R_MIPS_JALR", /* name */
1142 false, /* partial_inplace */
1143 0, /* src_mask */
1144 0x00000000, /* dst_mask */
1145 false), /* pcrel_offset */
1146 };
1147
1148 /* The reloc used for the mips16 jump instruction. */
1149 static reloc_howto_type elf_mips16_jump_howto =
1150 HOWTO (R_MIPS16_26, /* type */
1151 2, /* rightshift */
1152 2, /* size (0 = byte, 1 = short, 2 = long) */
1153 26, /* bitsize */
1154 false, /* pc_relative */
1155 0, /* bitpos */
1156 complain_overflow_dont, /* complain_on_overflow */
1157 /* This needs complex overflow
1158 detection, because the upper four
1159 bits must match the PC. */
1160 mips16_jump_reloc, /* special_function */
1161 "R_MIPS16_26", /* name */
1162 true, /* partial_inplace */
1163 0x3ffffff, /* src_mask */
1164 0x3ffffff, /* dst_mask */
1165 false); /* pcrel_offset */
1166
1167 /* The reloc used for the mips16 gprel instruction. */
1168 static reloc_howto_type elf_mips16_gprel_howto =
1169 HOWTO (R_MIPS16_GPREL, /* type */
1170 0, /* rightshift */
1171 2, /* size (0 = byte, 1 = short, 2 = long) */
1172 16, /* bitsize */
1173 false, /* pc_relative */
1174 0, /* bitpos */
1175 complain_overflow_signed, /* complain_on_overflow */
1176 mips16_gprel_reloc, /* special_function */
1177 "R_MIPS16_GPREL", /* name */
1178 true, /* partial_inplace */
1179 0x07ff001f, /* src_mask */
1180 0x07ff001f, /* dst_mask */
1181 false); /* pcrel_offset */
1182
1183 /* GNU extension to record C++ vtable hierarchy */
1184 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
1185 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
1186 0, /* rightshift */
1187 2, /* size (0 = byte, 1 = short, 2 = long) */
1188 0, /* bitsize */
1189 false, /* pc_relative */
1190 0, /* bitpos */
1191 complain_overflow_dont, /* complain_on_overflow */
1192 NULL, /* special_function */
1193 "R_MIPS_GNU_VTINHERIT", /* name */
1194 false, /* partial_inplace */
1195 0, /* src_mask */
1196 0, /* dst_mask */
1197 false); /* pcrel_offset */
1198
1199 /* GNU extension to record C++ vtable member usage */
1200 static reloc_howto_type elf_mips_gnu_vtentry_howto =
1201 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
1202 0, /* rightshift */
1203 2, /* size (0 = byte, 1 = short, 2 = long) */
1204 0, /* bitsize */
1205 false, /* pc_relative */
1206 0, /* bitpos */
1207 complain_overflow_dont, /* complain_on_overflow */
1208 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1209 "R_MIPS_GNU_VTENTRY", /* name */
1210 false, /* partial_inplace */
1211 0, /* src_mask */
1212 0, /* dst_mask */
1213 false); /* pcrel_offset */
1214 \f
1215 /* Swap in a MIPS 64-bit Rel reloc. */
1216
1217 static void
1218 mips_elf64_swap_reloc_in (abfd, src, dst)
1219 bfd *abfd;
1220 const Elf64_Mips_External_Rel *src;
1221 Elf64_Mips_Internal_Rel *dst;
1222 {
1223 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1224 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1225 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1226 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1227 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1228 dst->r_type = H_GET_8 (abfd, src->r_type);
1229 }
1230
1231 /* Swap in a MIPS 64-bit Rela reloc. */
1232
1233 static void
1234 mips_elf64_swap_reloca_in (abfd, src, dst)
1235 bfd *abfd;
1236 const Elf64_Mips_External_Rela *src;
1237 Elf64_Mips_Internal_Rela *dst;
1238 {
1239 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1240 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1241 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1242 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1243 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1244 dst->r_type = H_GET_8 (abfd, src->r_type);
1245 dst->r_addend = H_GET_S64 (abfd, src->r_addend);
1246 }
1247
1248 /* Swap out a MIPS 64-bit Rel reloc. */
1249
1250 static void
1251 mips_elf64_swap_reloc_out (abfd, src, dst)
1252 bfd *abfd;
1253 const Elf64_Mips_Internal_Rel *src;
1254 Elf64_Mips_External_Rel *dst;
1255 {
1256 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1257 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1258 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1259 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1260 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1261 H_PUT_8 (abfd, src->r_type, dst->r_type);
1262 }
1263
1264 /* Swap out a MIPS 64-bit Rela reloc. */
1265
1266 static void
1267 mips_elf64_swap_reloca_out (abfd, src, dst)
1268 bfd *abfd;
1269 const Elf64_Mips_Internal_Rela *src;
1270 Elf64_Mips_External_Rela *dst;
1271 {
1272 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1273 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1274 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1275 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1276 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1277 H_PUT_8 (abfd, src->r_type, dst->r_type);
1278 H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
1279 }
1280
1281 /* Swap in a MIPS 64-bit Rel reloc. */
1282
1283 static void
1284 mips_elf64_be_swap_reloc_in (abfd, src, dst)
1285 bfd *abfd;
1286 const bfd_byte *src;
1287 Elf_Internal_Rel *dst;
1288 {
1289 Elf64_Mips_Internal_Rel mirel;
1290
1291 mips_elf64_swap_reloc_in (abfd,
1292 (const Elf64_Mips_External_Rel *) src,
1293 &mirel);
1294
1295 dst[0].r_offset = mirel.r_offset;
1296 dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
1297 dst[1].r_offset = mirel.r_offset;
1298 dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
1299 dst[2].r_offset = mirel.r_offset;
1300 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
1301 }
1302
1303 /* Swap in a MIPS 64-bit Rela reloc. */
1304
1305 static void
1306 mips_elf64_be_swap_reloca_in (abfd, src, dst)
1307 bfd *abfd;
1308 const bfd_byte *src;
1309 Elf_Internal_Rela *dst;
1310 {
1311 Elf64_Mips_Internal_Rela mirela;
1312
1313 mips_elf64_swap_reloca_in (abfd,
1314 (const Elf64_Mips_External_Rela *) src,
1315 &mirela);
1316
1317 dst[0].r_offset = mirela.r_offset;
1318 dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
1319 dst[0].r_addend = mirela.r_addend;
1320 dst[1].r_offset = mirela.r_offset;
1321 dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
1322 dst[1].r_addend = 0;
1323 dst[2].r_offset = mirela.r_offset;
1324 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
1325 dst[2].r_addend = 0;
1326 }
1327
1328 /* Swap out a MIPS 64-bit Rel reloc. */
1329
1330 static void
1331 mips_elf64_be_swap_reloc_out (abfd, src, dst)
1332 bfd *abfd;
1333 const Elf_Internal_Rel *src;
1334 bfd_byte *dst;
1335 {
1336 Elf64_Mips_Internal_Rel mirel;
1337
1338 mirel.r_offset = src[0].r_offset;
1339 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1340 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
1341
1342 mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1343 mirel.r_sym = ELF64_R_SYM (src[0].r_info);
1344 mirel.r_type2 = ELF64_MIPS_R_TYPE2 (src[1].r_info);
1345 mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1346 mirel.r_type3 = ELF64_MIPS_R_TYPE3 (src[2].r_info);
1347
1348 mips_elf64_swap_reloc_out (abfd, &mirel,
1349 (Elf64_Mips_External_Rel *) dst);
1350 }
1351
1352 /* Swap out a MIPS 64-bit Rela reloc. */
1353
1354 static void
1355 mips_elf64_be_swap_reloca_out (abfd, src, dst)
1356 bfd *abfd;
1357 const Elf_Internal_Rela *src;
1358 bfd_byte *dst;
1359 {
1360 Elf64_Mips_Internal_Rela mirela;
1361
1362 mirela.r_offset = src[0].r_offset;
1363 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1364 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
1365
1366 mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1367 mirela.r_sym = ELF64_R_SYM (src[0].r_info);
1368 mirela.r_addend = src[0].r_addend;
1369 BFD_ASSERT(src[1].r_addend == 0);
1370 BFD_ASSERT(src[2].r_addend == 0);
1371
1372 mirela.r_type2 = ELF64_MIPS_R_TYPE2 (src[1].r_info);
1373 mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1374 mirela.r_type3 = ELF64_MIPS_R_TYPE3 (src[2].r_info);
1375
1376 mips_elf64_swap_reloca_out (abfd, &mirela,
1377 (Elf64_Mips_External_Rela *) dst);
1378 }
1379 \f
1380 /* Do a R_MIPS_HI16 relocation. */
1381
1382 static bfd_reloc_status_type
1383 mips_elf64_hi16_reloc (abfd, reloc_entry, symbol, data, input_section,
1384 output_bfd, error_message)
1385 bfd *abfd ATTRIBUTE_UNUSED;
1386 arelent *reloc_entry;
1387 asymbol *symbol;
1388 PTR data ATTRIBUTE_UNUSED;
1389 asection *input_section;
1390 bfd *output_bfd;
1391 char **error_message ATTRIBUTE_UNUSED;
1392 {
1393 /* If we're relocating, and this is an external symbol, we don't
1394 want to change anything. */
1395 if (output_bfd != (bfd *) NULL
1396 && (symbol->flags & BSF_SECTION_SYM) == 0
1397 && (! reloc_entry->howto->partial_inplace
1398 || reloc_entry->addend == 0))
1399 {
1400 reloc_entry->address += input_section->output_offset;
1401 return bfd_reloc_ok;
1402 }
1403
1404 if (((reloc_entry->addend & 0xffff) + 0x8000) & ~0xffff)
1405 reloc_entry->addend += 0x8000;
1406
1407 return bfd_reloc_continue;
1408 }
1409
1410 /* Do a R_MIPS_GOT16 reloc. This is a reloc against the global offset
1411 table used for PIC code. If the symbol is an external symbol, the
1412 instruction is modified to contain the offset of the appropriate
1413 entry in the global offset table. If the symbol is a section
1414 symbol, the next reloc is a R_MIPS_LO16 reloc. The two 16 bit
1415 addends are combined to form the real addend against the section
1416 symbol; the GOT16 is modified to contain the offset of an entry in
1417 the global offset table, and the LO16 is modified to offset it
1418 appropriately. Thus an offset larger than 16 bits requires a
1419 modified value in the global offset table.
1420
1421 This implementation suffices for the assembler, but the linker does
1422 not yet know how to create global offset tables. */
1423
1424 static bfd_reloc_status_type
1425 mips_elf64_got16_reloc (abfd, reloc_entry, symbol, data, input_section,
1426 output_bfd, error_message)
1427 bfd *abfd;
1428 arelent *reloc_entry;
1429 asymbol *symbol;
1430 PTR data;
1431 asection *input_section;
1432 bfd *output_bfd;
1433 char **error_message;
1434 {
1435 /* If we're relocating, and this is a local symbol, we can handle it
1436 just like an R_MIPS_HI16. */
1437 if (output_bfd != (bfd *) NULL
1438 && (symbol->flags & BSF_SECTION_SYM) != 0)
1439 return mips_elf64_hi16_reloc (abfd, reloc_entry, symbol, data,
1440 input_section, output_bfd, error_message);
1441
1442
1443 /* Otherwise we try to handle it as R_MIPS_GOT_DISP. */
1444 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
1445 input_section, output_bfd, error_message);
1446 }
1447
1448 /* Set the GP value for OUTPUT_BFD. Returns false if this is a
1449 dangerous relocation. */
1450
1451 static boolean
1452 mips_elf64_assign_gp (output_bfd, pgp)
1453 bfd *output_bfd;
1454 bfd_vma *pgp;
1455 {
1456 unsigned int count;
1457 asymbol **sym;
1458 unsigned int i;
1459
1460 /* If we've already figured out what GP will be, just return it. */
1461 *pgp = _bfd_get_gp_value (output_bfd);
1462 if (*pgp)
1463 return true;
1464
1465 count = bfd_get_symcount (output_bfd);
1466 sym = bfd_get_outsymbols (output_bfd);
1467
1468 /* The linker script will have created a symbol named `_gp' with the
1469 appropriate value. */
1470 if (sym == (asymbol **) NULL)
1471 i = count;
1472 else
1473 {
1474 for (i = 0; i < count; i++, sym++)
1475 {
1476 register const char *name;
1477
1478 name = bfd_asymbol_name (*sym);
1479 if (*name == '_' && strcmp (name, "_gp") == 0)
1480 {
1481 *pgp = bfd_asymbol_value (*sym);
1482 _bfd_set_gp_value (output_bfd, *pgp);
1483 break;
1484 }
1485 }
1486 }
1487
1488 if (i >= count)
1489 {
1490 /* Only get the error once. */
1491 *pgp = 4;
1492 _bfd_set_gp_value (output_bfd, *pgp);
1493 return false;
1494 }
1495
1496 return true;
1497 }
1498
1499 /* We have to figure out the gp value, so that we can adjust the
1500 symbol value correctly. We look up the symbol _gp in the output
1501 BFD. If we can't find it, we're stuck. We cache it in the ELF
1502 target data. We don't need to adjust the symbol value for an
1503 external symbol if we are producing relocateable output. */
1504
1505 static bfd_reloc_status_type
1506 mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message, pgp)
1507 bfd *output_bfd;
1508 asymbol *symbol;
1509 boolean relocateable;
1510 char **error_message;
1511 bfd_vma *pgp;
1512 {
1513 if (bfd_is_und_section (symbol->section)
1514 && ! relocateable)
1515 {
1516 *pgp = 0;
1517 return bfd_reloc_undefined;
1518 }
1519
1520 *pgp = _bfd_get_gp_value (output_bfd);
1521 if (*pgp == 0
1522 && (! relocateable
1523 || (symbol->flags & BSF_SECTION_SYM) != 0))
1524 {
1525 if (relocateable)
1526 {
1527 /* Make up a value. */
1528 *pgp = symbol->section->output_section->vma + 0x4000;
1529 _bfd_set_gp_value (output_bfd, *pgp);
1530 }
1531 else if (!mips_elf64_assign_gp (output_bfd, pgp))
1532 {
1533 *error_message =
1534 (char *) _("GP relative relocation when _gp not defined");
1535 return bfd_reloc_dangerous;
1536 }
1537 }
1538
1539 return bfd_reloc_ok;
1540 }
1541
1542 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1543 become the offset from the gp register. */
1544
1545 static bfd_reloc_status_type
1546 mips_elf64_gprel16_reloc (abfd, reloc_entry, symbol, data, input_section,
1547 output_bfd, error_message)
1548 bfd *abfd;
1549 arelent *reloc_entry;
1550 asymbol *symbol;
1551 PTR data;
1552 asection *input_section;
1553 bfd *output_bfd;
1554 char **error_message;
1555 {
1556 boolean relocateable;
1557 bfd_reloc_status_type ret;
1558 bfd_vma gp;
1559
1560 /* If we're relocating, and this is an external symbol with no
1561 addend, we don't want to change anything. We will only have an
1562 addend if this is a newly created reloc, not read from an ELF
1563 file. */
1564 if (output_bfd != (bfd *) NULL
1565 && (symbol->flags & BSF_SECTION_SYM) == 0
1566 && (! reloc_entry->howto->partial_inplace
1567 || reloc_entry->addend == 0))
1568 {
1569 reloc_entry->address += input_section->output_offset;
1570 return bfd_reloc_ok;
1571 }
1572
1573 if (output_bfd != (bfd *) NULL)
1574 relocateable = true;
1575 else
1576 {
1577 relocateable = false;
1578 output_bfd = symbol->section->output_section->owner;
1579 }
1580
1581 ret = mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message,
1582 &gp);
1583 if (ret != bfd_reloc_ok)
1584 return ret;
1585
1586 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1587 input_section, relocateable,
1588 data, gp);
1589 }
1590
1591 /* Do a R_MIPS_LITERAL relocation. */
1592
1593 static bfd_reloc_status_type
1594 mips_elf64_literal_reloc (abfd, reloc_entry, symbol, data, input_section,
1595 output_bfd, error_message)
1596 bfd *abfd;
1597 arelent *reloc_entry;
1598 asymbol *symbol;
1599 PTR data;
1600 asection *input_section;
1601 bfd *output_bfd;
1602 char **error_message;
1603 {
1604 boolean relocateable;
1605 bfd_reloc_status_type ret;
1606 bfd_vma gp;
1607
1608 /* If we're relocating, and this is an external symbol, we don't
1609 want to change anything. */
1610 if (output_bfd != (bfd *) NULL
1611 && (symbol->flags & BSF_SECTION_SYM) == 0
1612 && (! reloc_entry->howto->partial_inplace
1613 || reloc_entry->addend == 0))
1614 {
1615 reloc_entry->address += input_section->output_offset;
1616 return bfd_reloc_ok;
1617 }
1618
1619 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
1620 if (output_bfd != (bfd *) NULL)
1621 relocateable = true;
1622 else
1623 {
1624 relocateable = false;
1625 output_bfd = symbol->section->output_section->owner;
1626 }
1627
1628 ret = mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message,
1629 &gp);
1630 if (ret != bfd_reloc_ok)
1631 return ret;
1632
1633 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1634 input_section, relocateable,
1635 data, gp);
1636 }
1637
1638 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1639 become the offset from the gp register. */
1640
1641 static bfd_reloc_status_type
1642 mips_elf64_gprel32_reloc (abfd, reloc_entry, symbol, data, input_section,
1643 output_bfd, error_message)
1644 bfd *abfd;
1645 arelent *reloc_entry;
1646 asymbol *symbol;
1647 PTR data;
1648 asection *input_section;
1649 bfd *output_bfd;
1650 char **error_message;
1651 {
1652 boolean relocateable;
1653 bfd_reloc_status_type ret;
1654 bfd_vma gp;
1655 bfd_vma relocation;
1656 unsigned long val;
1657
1658 /* If we're relocating, and this is an external symbol with no
1659 addend, we don't want to change anything. We will only have an
1660 addend if this is a newly created reloc, not read from an ELF
1661 file. */
1662 if (output_bfd != (bfd *) NULL
1663 && (symbol->flags & BSF_SECTION_SYM) == 0
1664 && reloc_entry->addend == 0)
1665 {
1666 *error_message = (char *)
1667 _("32bits gp relative relocation occurs for an external symbol");
1668 return bfd_reloc_outofrange;
1669 }
1670
1671 if (output_bfd != (bfd *) NULL)
1672 {
1673 relocateable = true;
1674 gp = _bfd_get_gp_value (output_bfd);
1675 }
1676 else
1677 {
1678 relocateable = false;
1679 output_bfd = symbol->section->output_section->owner;
1680
1681 ret = mips_elf64_final_gp (output_bfd, symbol, relocateable,
1682 error_message, &gp);
1683 if (ret != bfd_reloc_ok)
1684 return ret;
1685 }
1686
1687 if (bfd_is_com_section (symbol->section))
1688 relocation = 0;
1689 else
1690 relocation = symbol->value;
1691
1692 relocation += symbol->section->output_section->vma;
1693 relocation += symbol->section->output_offset;
1694
1695 if (reloc_entry->address > input_section->_cooked_size)
1696 return bfd_reloc_outofrange;
1697
1698 if (reloc_entry->howto->src_mask == 0)
1699 {
1700 /* This case arises with the 64-bit MIPS ELF ABI. */
1701 val = 0;
1702 }
1703 else
1704 val = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1705
1706 /* Set val to the offset into the section or symbol. */
1707 val += reloc_entry->addend;
1708
1709 /* Adjust val for the final section location and GP value. If we
1710 are producing relocateable output, we don't want to do this for
1711 an external symbol. */
1712 if (! relocateable
1713 || (symbol->flags & BSF_SECTION_SYM) != 0)
1714 val += relocation - gp;
1715
1716 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
1717
1718 if (relocateable)
1719 reloc_entry->address += input_section->output_offset;
1720
1721 return bfd_reloc_ok;
1722 }
1723
1724 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
1725 the rest is at bits 6-10. The bitpos already got right by the howto. */
1726
1727 static bfd_reloc_status_type
1728 mips_elf64_shift6_reloc (abfd, reloc_entry, symbol, data, input_section,
1729 output_bfd, error_message)
1730 bfd *abfd ATTRIBUTE_UNUSED;
1731 arelent *reloc_entry;
1732 asymbol *symbol;
1733 PTR data ATTRIBUTE_UNUSED;
1734 asection *input_section;
1735 bfd *output_bfd;
1736 char **error_message ATTRIBUTE_UNUSED;
1737 {
1738 /* If we're relocating, and this is an external symbol, we don't
1739 want to change anything. */
1740 if (output_bfd != (bfd *) NULL
1741 && (symbol->flags & BSF_SECTION_SYM) == 0
1742 && (! reloc_entry->howto->partial_inplace
1743 || reloc_entry->addend == 0))
1744 {
1745 reloc_entry->address += input_section->output_offset;
1746 return bfd_reloc_ok;
1747 }
1748
1749 reloc_entry->addend = (reloc_entry->addend & 0x00007c0)
1750 | (reloc_entry->addend & 0x00000800) >> 9;
1751
1752 return bfd_reloc_continue;
1753 }
1754
1755 /* Handle a mips16 jump. */
1756
1757 static bfd_reloc_status_type
1758 mips16_jump_reloc (abfd, reloc_entry, symbol, data, input_section,
1759 output_bfd, error_message)
1760 bfd *abfd ATTRIBUTE_UNUSED;
1761 arelent *reloc_entry;
1762 asymbol *symbol;
1763 PTR data ATTRIBUTE_UNUSED;
1764 asection *input_section;
1765 bfd *output_bfd;
1766 char **error_message ATTRIBUTE_UNUSED;
1767 {
1768 if (output_bfd != (bfd *) NULL
1769 && (symbol->flags & BSF_SECTION_SYM) == 0
1770 && (! reloc_entry->howto->partial_inplace
1771 || reloc_entry->addend == 0))
1772 {
1773 reloc_entry->address += input_section->output_offset;
1774 return bfd_reloc_ok;
1775 }
1776
1777 /* FIXME. */
1778 {
1779 static boolean warned;
1780
1781 if (! warned)
1782 (*_bfd_error_handler)
1783 (_("Linking mips16 objects into %s format is not supported"),
1784 bfd_get_target (input_section->output_section->owner));
1785 warned = true;
1786 }
1787
1788 return bfd_reloc_undefined;
1789 }
1790
1791 /* Handle a mips16 GP relative reloc. */
1792
1793 static bfd_reloc_status_type
1794 mips16_gprel_reloc (abfd, reloc_entry, symbol, data, input_section,
1795 output_bfd, error_message)
1796 bfd *abfd;
1797 arelent *reloc_entry;
1798 asymbol *symbol;
1799 PTR data;
1800 asection *input_section;
1801 bfd *output_bfd;
1802 char **error_message;
1803 {
1804 boolean relocateable;
1805 bfd_reloc_status_type ret;
1806 bfd_vma gp;
1807 unsigned short extend, insn;
1808 unsigned long final;
1809
1810 /* If we're relocating, and this is an external symbol with no
1811 addend, we don't want to change anything. We will only have an
1812 addend if this is a newly created reloc, not read from an ELF
1813 file. */
1814 if (output_bfd != NULL
1815 && (symbol->flags & BSF_SECTION_SYM) == 0
1816 && reloc_entry->addend == 0)
1817 {
1818 reloc_entry->address += input_section->output_offset;
1819 return bfd_reloc_ok;
1820 }
1821
1822 if (output_bfd != NULL)
1823 relocateable = true;
1824 else
1825 {
1826 relocateable = false;
1827 output_bfd = symbol->section->output_section->owner;
1828 }
1829
1830 ret = mips_elf64_final_gp (output_bfd, symbol, relocateable, error_message,
1831 &gp);
1832 if (ret != bfd_reloc_ok)
1833 return ret;
1834
1835 if (reloc_entry->address > input_section->_cooked_size)
1836 return bfd_reloc_outofrange;
1837
1838 /* Pick up the mips16 extend instruction and the real instruction. */
1839 extend = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);
1840 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address + 2);
1841
1842 /* Stuff the current addend back as a 32 bit value, do the usual
1843 relocation, and then clean up. */
1844 bfd_put_32 (abfd,
1845 (bfd_vma) (((extend & 0x1f) << 11)
1846 | (extend & 0x7e0)
1847 | (insn & 0x1f)),
1848 (bfd_byte *) data + reloc_entry->address);
1849
1850 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1851 input_section, relocateable, data, gp);
1852
1853 final = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1854 bfd_put_16 (abfd,
1855 (bfd_vma) ((extend & 0xf800)
1856 | ((final >> 11) & 0x1f)
1857 | (final & 0x7e0)),
1858 (bfd_byte *) data + reloc_entry->address);
1859 bfd_put_16 (abfd,
1860 (bfd_vma) ((insn & 0xffe0)
1861 | (final & 0x1f)),
1862 (bfd_byte *) data + reloc_entry->address + 2);
1863
1864 return ret;
1865 }
1866 \f
1867 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
1868
1869 struct elf_reloc_map {
1870 bfd_reloc_code_real_type bfd_val;
1871 enum elf_mips_reloc_type elf_val;
1872 };
1873
1874 static const struct elf_reloc_map mips_reloc_map[] =
1875 {
1876 { BFD_RELOC_NONE, R_MIPS_NONE },
1877 { BFD_RELOC_16, R_MIPS_16 },
1878 { BFD_RELOC_32, R_MIPS_32 },
1879 /* There is no BFD reloc for R_MIPS_REL32. */
1880 { BFD_RELOC_64, R_MIPS_64 },
1881 { BFD_RELOC_CTOR, R_MIPS_64 },
1882 { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
1883 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1884 { BFD_RELOC_LO16, R_MIPS_LO16 },
1885 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
1886 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
1887 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1888 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1889 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1890 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1891 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
1892 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
1893 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
1894 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1895 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1896 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1897 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1898 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1899 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
1900 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
1901 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
1902 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
1903 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
1904 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
1905 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1906 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
1907 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
1908 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
1909 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
1910 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR }
1911 };
1912
1913 /* Given a BFD reloc type, return a howto structure. */
1914
1915 static reloc_howto_type *
1916 bfd_elf64_bfd_reloc_type_lookup (abfd, code)
1917 bfd *abfd ATTRIBUTE_UNUSED;
1918 bfd_reloc_code_real_type code;
1919 {
1920 unsigned int i;
1921 /* FIXME: We default to RELA here instead of choosing the right
1922 relocation variant. */
1923 reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
1924
1925 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
1926 i++)
1927 {
1928 if (mips_reloc_map[i].bfd_val == code)
1929 return &howto_table[(int) mips_reloc_map[i].elf_val];
1930 }
1931
1932 switch (code)
1933 {
1934 case BFD_RELOC_MIPS16_JMP:
1935 return &elf_mips16_jump_howto;
1936 case BFD_RELOC_MIPS16_GPREL:
1937 return &elf_mips16_gprel_howto;
1938 case BFD_RELOC_VTABLE_INHERIT:
1939 return &elf_mips_gnu_vtinherit_howto;
1940 case BFD_RELOC_VTABLE_ENTRY:
1941 return &elf_mips_gnu_vtentry_howto;
1942 default:
1943 bfd_set_error (bfd_error_bad_value);
1944 return NULL;
1945 }
1946 }
1947
1948 /* Given a MIPS Elf64_Internal_Rel, fill in an arelent structure. */
1949
1950 static reloc_howto_type *
1951 mips_elf64_rtype_to_howto (r_type, rela_p)
1952 unsigned int r_type;
1953 boolean rela_p;
1954 {
1955 switch (r_type)
1956 {
1957 case R_MIPS16_26:
1958 return &elf_mips16_jump_howto;
1959 case R_MIPS16_GPREL:
1960 return &elf_mips16_gprel_howto;
1961 case R_MIPS_GNU_VTINHERIT:
1962 return &elf_mips_gnu_vtinherit_howto;
1963 case R_MIPS_GNU_VTENTRY:
1964 return &elf_mips_gnu_vtentry_howto;
1965 default:
1966 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
1967 if (rela_p)
1968 return &mips_elf64_howto_table_rela[r_type];
1969 else
1970 return &mips_elf64_howto_table_rel[r_type];
1971 break;
1972 }
1973 }
1974
1975 /* Prevent relocation handling by bfd for MIPS ELF64. */
1976
1977 static void
1978 mips_elf64_info_to_howto_rel (abfd, cache_ptr, dst)
1979 bfd *abfd ATTRIBUTE_UNUSED;
1980 arelent *cache_ptr ATTRIBUTE_UNUSED;
1981 Elf64_Internal_Rel *dst ATTRIBUTE_UNUSED;
1982 {
1983 BFD_ASSERT (0);
1984 }
1985
1986 static void
1987 mips_elf64_info_to_howto_rela (abfd, cache_ptr, dst)
1988 bfd *abfd ATTRIBUTE_UNUSED;
1989 arelent *cache_ptr ATTRIBUTE_UNUSED;
1990 Elf64_Internal_Rela *dst ATTRIBUTE_UNUSED;
1991 {
1992 BFD_ASSERT (0);
1993 }
1994
1995 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
1996 to three relocs, we must tell the user to allocate more space. */
1997
1998 static long
1999 mips_elf64_get_reloc_upper_bound (abfd, sec)
2000 bfd *abfd ATTRIBUTE_UNUSED;
2001 asection *sec;
2002 {
2003 return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
2004 }
2005
2006 /* Read the relocations from one reloc section. */
2007
2008 static boolean
2009 mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, rel_hdr)
2010 bfd *abfd;
2011 asection *asect;
2012 asymbol **symbols;
2013 const Elf_Internal_Shdr *rel_hdr;
2014 {
2015 PTR allocated = NULL;
2016 bfd_byte *native_relocs;
2017 arelent *relents;
2018 arelent *relent;
2019 bfd_vma count;
2020 bfd_vma i;
2021 int entsize;
2022 reloc_howto_type *howto_table;
2023
2024 allocated = (PTR) bfd_malloc (rel_hdr->sh_size);
2025 if (allocated == NULL)
2026 return false;
2027
2028 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
2029 || (bfd_bread (allocated, rel_hdr->sh_size, abfd) != rel_hdr->sh_size))
2030 goto error_return;
2031
2032 native_relocs = (bfd_byte *) allocated;
2033
2034 relents = asect->relocation + asect->reloc_count;
2035
2036 entsize = rel_hdr->sh_entsize;
2037 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
2038 || entsize == sizeof (Elf64_Mips_External_Rela));
2039
2040 count = rel_hdr->sh_size / entsize;
2041
2042 if (entsize == sizeof (Elf64_Mips_External_Rel))
2043 howto_table = mips_elf64_howto_table_rel;
2044 else
2045 howto_table = mips_elf64_howto_table_rela;
2046
2047 relent = relents;
2048 for (i = 0; i < count; i++, native_relocs += entsize)
2049 {
2050 Elf64_Mips_Internal_Rela rela;
2051 boolean used_sym, used_ssym;
2052 int ir;
2053
2054 if (entsize == sizeof (Elf64_Mips_External_Rela))
2055 mips_elf64_swap_reloca_in (abfd,
2056 (Elf64_Mips_External_Rela *) native_relocs,
2057 &rela);
2058 else
2059 {
2060 Elf64_Mips_Internal_Rel rel;
2061
2062 mips_elf64_swap_reloc_in (abfd,
2063 (Elf64_Mips_External_Rel *) native_relocs,
2064 &rel);
2065 rela.r_offset = rel.r_offset;
2066 rela.r_sym = rel.r_sym;
2067 rela.r_ssym = rel.r_ssym;
2068 rela.r_type3 = rel.r_type3;
2069 rela.r_type2 = rel.r_type2;
2070 rela.r_type = rel.r_type;
2071 rela.r_addend = 0;
2072 }
2073
2074 /* Each entry represents up to three actual relocations. */
2075
2076 used_sym = false;
2077 used_ssym = false;
2078 for (ir = 0; ir < 3; ir++)
2079 {
2080 enum elf_mips_reloc_type type;
2081
2082 switch (ir)
2083 {
2084 default:
2085 abort ();
2086 case 0:
2087 type = (enum elf_mips_reloc_type) rela.r_type;
2088 break;
2089 case 1:
2090 type = (enum elf_mips_reloc_type) rela.r_type2;
2091 break;
2092 case 2:
2093 type = (enum elf_mips_reloc_type) rela.r_type3;
2094 break;
2095 }
2096
2097 if (type == R_MIPS_NONE)
2098 {
2099 /* There are no more relocations in this entry. If this
2100 is the first entry, we need to generate a dummy
2101 relocation so that the generic linker knows that
2102 there has been a break in the sequence of relocations
2103 applying to a particular address. */
2104 if (ir == 0)
2105 {
2106 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2107 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2108 relent->address = rela.r_offset;
2109 else
2110 relent->address = rela.r_offset - asect->vma;
2111 relent->addend = 0;
2112 relent->howto = &howto_table[(int) R_MIPS_NONE];
2113 ++relent;
2114 }
2115 break;
2116 }
2117
2118 /* Some types require symbols, whereas some do not. */
2119 switch (type)
2120 {
2121 case R_MIPS_NONE:
2122 case R_MIPS_LITERAL:
2123 case R_MIPS_INSERT_A:
2124 case R_MIPS_INSERT_B:
2125 case R_MIPS_DELETE:
2126 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2127 break;
2128
2129 default:
2130 if (! used_sym)
2131 {
2132 if (rela.r_sym == 0)
2133 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2134 else
2135 {
2136 asymbol **ps, *s;
2137
2138 ps = symbols + rela.r_sym - 1;
2139 s = *ps;
2140 if ((s->flags & BSF_SECTION_SYM) == 0)
2141 relent->sym_ptr_ptr = ps;
2142 else
2143 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
2144 }
2145
2146 used_sym = true;
2147 }
2148 else if (! used_ssym)
2149 {
2150 switch (rela.r_ssym)
2151 {
2152 case RSS_UNDEF:
2153 relent->sym_ptr_ptr =
2154 bfd_abs_section_ptr->symbol_ptr_ptr;
2155 break;
2156
2157 case RSS_GP:
2158 case RSS_GP0:
2159 case RSS_LOC:
2160 /* FIXME: I think these need to be handled using
2161 special howto structures. */
2162 BFD_ASSERT (0);
2163 break;
2164
2165 default:
2166 BFD_ASSERT (0);
2167 break;
2168 }
2169
2170 used_ssym = true;
2171 }
2172 else
2173 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2174
2175 break;
2176 }
2177
2178 /* The address of an ELF reloc is section relative for an
2179 object file, and absolute for an executable file or
2180 shared library. The address of a BFD reloc is always
2181 section relative. */
2182 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2183 relent->address = rela.r_offset;
2184 else
2185 relent->address = rela.r_offset - asect->vma;
2186
2187 relent->addend = rela.r_addend;
2188
2189 relent->howto = &howto_table[(int) type];
2190
2191 ++relent;
2192 }
2193 }
2194
2195 asect->reloc_count += relent - relents;
2196
2197 if (allocated != NULL)
2198 free (allocated);
2199
2200 return true;
2201
2202 error_return:
2203 if (allocated != NULL)
2204 free (allocated);
2205 return false;
2206 }
2207
2208 /* Read the relocations. On Irix 6, there can be two reloc sections
2209 associated with a single data section. */
2210
2211 static boolean
2212 mips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic)
2213 bfd *abfd;
2214 asection *asect;
2215 asymbol **symbols;
2216 boolean dynamic;
2217 {
2218 bfd_size_type amt;
2219 struct bfd_elf_section_data * const d = elf_section_data (asect);
2220
2221 if (dynamic)
2222 {
2223 bfd_set_error (bfd_error_invalid_operation);
2224 return false;
2225 }
2226
2227 if (asect->relocation != NULL
2228 || (asect->flags & SEC_RELOC) == 0
2229 || asect->reloc_count == 0)
2230 return true;
2231
2232 /* Allocate space for 3 arelent structures for each Rel structure. */
2233 amt = asect->reloc_count;
2234 amt *= 3 * sizeof (arelent);
2235 asect->relocation = (arelent *) bfd_alloc (abfd, amt);
2236 if (asect->relocation == NULL)
2237 return false;
2238
2239 /* The slurp_one_reloc_table routine increments reloc_count. */
2240 asect->reloc_count = 0;
2241
2242 if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, &d->rel_hdr))
2243 return false;
2244 if (d->rel_hdr2 != NULL)
2245 {
2246 if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols,
2247 d->rel_hdr2))
2248 return false;
2249 }
2250
2251 return true;
2252 }
2253
2254 /* Write out the relocations. */
2255
2256 static void
2257 mips_elf64_write_relocs (abfd, sec, data)
2258 bfd *abfd;
2259 asection *sec;
2260 PTR data;
2261 {
2262 boolean *failedp = (boolean *) data;
2263 int count;
2264 Elf_Internal_Shdr *rel_hdr;
2265 unsigned int idx;
2266
2267 /* If we have already failed, don't do anything. */
2268 if (*failedp)
2269 return;
2270
2271 if ((sec->flags & SEC_RELOC) == 0)
2272 return;
2273
2274 /* The linker backend writes the relocs out itself, and sets the
2275 reloc_count field to zero to inhibit writing them here. Also,
2276 sometimes the SEC_RELOC flag gets set even when there aren't any
2277 relocs. */
2278 if (sec->reloc_count == 0)
2279 return;
2280
2281 /* We can combine up to three relocs that refer to the same address
2282 if the latter relocs have no associated symbol. */
2283 count = 0;
2284 for (idx = 0; idx < sec->reloc_count; idx++)
2285 {
2286 bfd_vma addr;
2287 unsigned int i;
2288
2289 ++count;
2290
2291 addr = sec->orelocation[idx]->address;
2292 for (i = 0; i < 2; i++)
2293 {
2294 arelent *r;
2295
2296 if (idx + 1 >= sec->reloc_count)
2297 break;
2298 r = sec->orelocation[idx + 1];
2299 if (r->address != addr
2300 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2301 || (*r->sym_ptr_ptr)->value != 0)
2302 break;
2303
2304 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2305
2306 ++idx;
2307 }
2308 }
2309
2310 rel_hdr = &elf_section_data (sec)->rel_hdr;
2311
2312 /* Do the actual relocation. */
2313
2314 if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
2315 mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
2316 else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
2317 mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
2318 else
2319 BFD_ASSERT (0);
2320 }
2321
2322 static void
2323 mips_elf64_write_rel (abfd, sec, rel_hdr, count, data)
2324 bfd *abfd;
2325 asection *sec;
2326 Elf_Internal_Shdr *rel_hdr;
2327 int *count;
2328 PTR data;
2329 {
2330 boolean *failedp = (boolean *) data;
2331 Elf64_Mips_External_Rel *ext_rel;
2332 unsigned int idx;
2333 asymbol *last_sym = 0;
2334 int last_sym_idx = 0;
2335
2336 rel_hdr->sh_size = (bfd_vma)(rel_hdr->sh_entsize * *count);
2337 rel_hdr->contents = (PTR) bfd_alloc (abfd, rel_hdr->sh_size);
2338 if (rel_hdr->contents == NULL)
2339 {
2340 *failedp = true;
2341 return;
2342 }
2343
2344 ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
2345 for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
2346 {
2347 arelent *ptr;
2348 Elf64_Mips_Internal_Rel int_rel;
2349 asymbol *sym;
2350 int n;
2351 unsigned int i;
2352
2353 ptr = sec->orelocation[idx];
2354
2355 /* The address of an ELF reloc is section relative for an object
2356 file, and absolute for an executable file or shared library.
2357 The address of a BFD reloc is always section relative. */
2358 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2359 int_rel.r_offset = ptr->address;
2360 else
2361 int_rel.r_offset = ptr->address + sec->vma;
2362
2363 sym = *ptr->sym_ptr_ptr;
2364 if (sym == last_sym)
2365 n = last_sym_idx;
2366 else
2367 {
2368 last_sym = sym;
2369 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2370 if (n < 0)
2371 {
2372 *failedp = true;
2373 return;
2374 }
2375 last_sym_idx = n;
2376 }
2377
2378 int_rel.r_sym = n;
2379 int_rel.r_ssym = RSS_UNDEF;
2380
2381 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2382 && ! _bfd_elf_validate_reloc (abfd, ptr))
2383 {
2384 *failedp = true;
2385 return;
2386 }
2387
2388 int_rel.r_type = ptr->howto->type;
2389 int_rel.r_type2 = (int) R_MIPS_NONE;
2390 int_rel.r_type3 = (int) R_MIPS_NONE;
2391
2392 for (i = 0; i < 2; i++)
2393 {
2394 arelent *r;
2395
2396 if (idx + 1 >= sec->reloc_count)
2397 break;
2398 r = sec->orelocation[idx + 1];
2399 if (r->address != ptr->address
2400 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2401 || (*r->sym_ptr_ptr)->value != 0)
2402 break;
2403
2404 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2405
2406 if (i == 0)
2407 int_rel.r_type2 = r->howto->type;
2408 else
2409 int_rel.r_type3 = r->howto->type;
2410
2411 ++idx;
2412 }
2413
2414 mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
2415 }
2416
2417 BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
2418 == *count);
2419 }
2420
2421 static void
2422 mips_elf64_write_rela (abfd, sec, rela_hdr, count, data)
2423 bfd *abfd;
2424 asection *sec;
2425 Elf_Internal_Shdr *rela_hdr;
2426 int *count;
2427 PTR data;
2428 {
2429 boolean *failedp = (boolean *) data;
2430 Elf64_Mips_External_Rela *ext_rela;
2431 unsigned int idx;
2432 asymbol *last_sym = 0;
2433 int last_sym_idx = 0;
2434
2435 rela_hdr->sh_size = (bfd_vma)(rela_hdr->sh_entsize * *count);
2436 rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
2437 if (rela_hdr->contents == NULL)
2438 {
2439 *failedp = true;
2440 return;
2441 }
2442
2443 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
2444 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
2445 {
2446 arelent *ptr;
2447 Elf64_Mips_Internal_Rela int_rela;
2448 asymbol *sym;
2449 int n;
2450 unsigned int i;
2451
2452 ptr = sec->orelocation[idx];
2453
2454 /* The address of an ELF reloc is section relative for an object
2455 file, and absolute for an executable file or shared library.
2456 The address of a BFD reloc is always section relative. */
2457 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2458 int_rela.r_offset = ptr->address;
2459 else
2460 int_rela.r_offset = ptr->address + sec->vma;
2461
2462 sym = *ptr->sym_ptr_ptr;
2463 if (sym == last_sym)
2464 n = last_sym_idx;
2465 else
2466 {
2467 last_sym = sym;
2468 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2469 if (n < 0)
2470 {
2471 *failedp = true;
2472 return;
2473 }
2474 last_sym_idx = n;
2475 }
2476
2477 int_rela.r_sym = n;
2478 int_rela.r_addend = ptr->addend;
2479 int_rela.r_ssym = RSS_UNDEF;
2480
2481 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2482 && ! _bfd_elf_validate_reloc (abfd, ptr))
2483 {
2484 *failedp = true;
2485 return;
2486 }
2487
2488 int_rela.r_type = ptr->howto->type;
2489 int_rela.r_type2 = (int) R_MIPS_NONE;
2490 int_rela.r_type3 = (int) R_MIPS_NONE;
2491
2492 for (i = 0; i < 2; i++)
2493 {
2494 arelent *r;
2495
2496 if (idx + 1 >= sec->reloc_count)
2497 break;
2498 r = sec->orelocation[idx + 1];
2499 if (r->address != ptr->address
2500 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2501 || (*r->sym_ptr_ptr)->value != 0)
2502 break;
2503
2504 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2505
2506 if (i == 0)
2507 int_rela.r_type2 = r->howto->type;
2508 else
2509 int_rela.r_type3 = r->howto->type;
2510
2511 ++idx;
2512 }
2513
2514 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
2515 }
2516
2517 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
2518 == *count);
2519 }
2520 \f
2521 /* Set the right machine number for a MIPS ELF file. */
2522
2523 static boolean
2524 mips_elf64_object_p (abfd)
2525 bfd *abfd;
2526 {
2527 unsigned long mach;
2528
2529 /* Irix 6 is broken. Object file symbol tables are not always
2530 sorted correctly such that local symbols precede global symbols,
2531 and the sh_info field in the symbol table is not always right. */
2532 if (elf64_mips_irix_compat (abfd) != ict_none)
2533 elf_bad_symtab (abfd) = true;
2534
2535 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
2536 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
2537 return true;
2538 }
2539
2540 /* Depending on the target vector we generate some version of Irix
2541 executables or "normal" MIPS ELF ABI executables. */
2542 static irix_compat_t
2543 elf64_mips_irix_compat (abfd)
2544 bfd *abfd;
2545 {
2546 if ((abfd->xvec == &bfd_elf64_bigmips_vec)
2547 || (abfd->xvec == &bfd_elf64_littlemips_vec))
2548 return ict_irix6;
2549 else
2550 return ict_none;
2551 }
2552 \f
2553 /* ECOFF swapping routines. These are used when dealing with the
2554 .mdebug section, which is in the ECOFF debugging format. */
2555 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
2556 {
2557 /* Symbol table magic number. */
2558 magicSym2,
2559 /* Alignment of debugging information. E.g., 4. */
2560 8,
2561 /* Sizes of external symbolic information. */
2562 sizeof (struct hdr_ext),
2563 sizeof (struct dnr_ext),
2564 sizeof (struct pdr_ext),
2565 sizeof (struct sym_ext),
2566 sizeof (struct opt_ext),
2567 sizeof (struct fdr_ext),
2568 sizeof (struct rfd_ext),
2569 sizeof (struct ext_ext),
2570 /* Functions to swap in external symbolic data. */
2571 ecoff_swap_hdr_in,
2572 ecoff_swap_dnr_in,
2573 ecoff_swap_pdr_in,
2574 ecoff_swap_sym_in,
2575 ecoff_swap_opt_in,
2576 ecoff_swap_fdr_in,
2577 ecoff_swap_rfd_in,
2578 ecoff_swap_ext_in,
2579 _bfd_ecoff_swap_tir_in,
2580 _bfd_ecoff_swap_rndx_in,
2581 /* Functions to swap out external symbolic data. */
2582 ecoff_swap_hdr_out,
2583 ecoff_swap_dnr_out,
2584 ecoff_swap_pdr_out,
2585 ecoff_swap_sym_out,
2586 ecoff_swap_opt_out,
2587 ecoff_swap_fdr_out,
2588 ecoff_swap_rfd_out,
2589 ecoff_swap_ext_out,
2590 _bfd_ecoff_swap_tir_out,
2591 _bfd_ecoff_swap_rndx_out,
2592 /* Function to read in symbolic data. */
2593 _bfd_mips_elf_read_ecoff_info
2594 };
2595 \f
2596 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
2597 standard ELF. This structure is used to redirect the relocation
2598 handling routines. */
2599
2600 const struct elf_size_info mips_elf64_size_info =
2601 {
2602 sizeof (Elf64_External_Ehdr),
2603 sizeof (Elf64_External_Phdr),
2604 sizeof (Elf64_External_Shdr),
2605 sizeof (Elf64_Mips_External_Rel),
2606 sizeof (Elf64_Mips_External_Rela),
2607 sizeof (Elf64_External_Sym),
2608 sizeof (Elf64_External_Dyn),
2609 sizeof (Elf_External_Note),
2610 4, /* hash-table entry size */
2611 3, /* internal relocations per external relocations */
2612 64, /* arch_size */
2613 8, /* file_align */
2614 ELFCLASS64,
2615 EV_CURRENT,
2616 bfd_elf64_write_out_phdrs,
2617 bfd_elf64_write_shdrs_and_ehdr,
2618 mips_elf64_write_relocs,
2619 bfd_elf64_swap_symbol_in,
2620 bfd_elf64_swap_symbol_out,
2621 mips_elf64_slurp_reloc_table,
2622 bfd_elf64_slurp_symbol_table,
2623 bfd_elf64_swap_dyn_in,
2624 bfd_elf64_swap_dyn_out,
2625 mips_elf64_be_swap_reloc_in,
2626 mips_elf64_be_swap_reloc_out,
2627 mips_elf64_be_swap_reloca_in,
2628 mips_elf64_be_swap_reloca_out
2629 };
2630
2631 #define ELF_ARCH bfd_arch_mips
2632 #define ELF_MACHINE_CODE EM_MIPS
2633
2634 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
2635 a value of 0x1000, and we are compatible.
2636 FIXME: How does this affect NewABI? */
2637 #define ELF_MAXPAGESIZE 0x1000
2638
2639 #define elf_backend_collect true
2640 #define elf_backend_type_change_ok true
2641 #define elf_backend_can_gc_sections true
2642 #define elf_info_to_howto mips_elf64_info_to_howto_rela
2643 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
2644 #define elf_backend_object_p mips_elf64_object_p
2645 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
2646 #define elf_backend_section_processing _bfd_mips_elf_section_processing
2647 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
2648 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
2649 #define elf_backend_section_from_bfd_section \
2650 _bfd_mips_elf_section_from_bfd_section
2651 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
2652 #define elf_backend_link_output_symbol_hook \
2653 _bfd_mips_elf_link_output_symbol_hook
2654 #define elf_backend_create_dynamic_sections \
2655 _bfd_mips_elf_create_dynamic_sections
2656 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
2657 #define elf_backend_adjust_dynamic_symbol \
2658 _bfd_mips_elf_adjust_dynamic_symbol
2659 #define elf_backend_always_size_sections \
2660 _bfd_mips_elf_always_size_sections
2661 #define elf_backend_size_dynamic_sections \
2662 _bfd_mips_elf_size_dynamic_sections
2663 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
2664 #define elf_backend_finish_dynamic_symbol \
2665 _bfd_mips_elf_finish_dynamic_symbol
2666 #define elf_backend_finish_dynamic_sections \
2667 _bfd_mips_elf_finish_dynamic_sections
2668 #define elf_backend_final_write_processing \
2669 _bfd_mips_elf_final_write_processing
2670 #define elf_backend_additional_program_headers \
2671 _bfd_mips_elf_additional_program_headers
2672 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
2673 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
2674 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
2675 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
2676 #define elf_backend_ignore_discarded_relocs \
2677 _bfd_mips_elf_ignore_discarded_relocs
2678 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
2679 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
2680 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
2681 #define elf_backend_size_info mips_elf64_size_info
2682
2683 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
2684 #define elf_backend_plt_header_size 0
2685
2686 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
2687 work better/work only in RELA, so we default to this. */
2688 #define elf_backend_may_use_rel_p 1
2689 #define elf_backend_may_use_rela_p 1
2690 #define elf_backend_default_use_rela_p 1
2691
2692 #define elf_backend_write_section _bfd_mips_elf_write_section
2693
2694 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
2695 MIPS-specific function only applies to IRIX5, which had no 64-bit
2696 ABI. */
2697 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
2698 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
2699 #define bfd_elf64_bfd_get_relocated_section_contents \
2700 _bfd_elf_mips_get_relocated_section_contents
2701 #define bfd_elf64_bfd_link_hash_table_create \
2702 _bfd_mips_elf_link_hash_table_create
2703 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
2704 #define bfd_elf64_bfd_merge_private_bfd_data \
2705 _bfd_mips_elf_merge_private_bfd_data
2706 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
2707 #define bfd_elf64_bfd_print_private_bfd_data \
2708 _bfd_mips_elf_print_private_bfd_data
2709
2710 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
2711
2712 /* MIPS ELF64 archive functions. */
2713 #define bfd_elf64_archive_functions
2714 extern boolean bfd_elf64_archive_slurp_armap
2715 PARAMS((bfd *));
2716 extern boolean bfd_elf64_archive_write_armap
2717 PARAMS((bfd *, unsigned int, struct orl *, unsigned int, int));
2718 #define bfd_elf64_archive_slurp_extended_name_table \
2719 _bfd_archive_coff_slurp_extended_name_table
2720 #define bfd_elf64_archive_construct_extended_name_table \
2721 _bfd_archive_coff_construct_extended_name_table
2722 #define bfd_elf64_archive_truncate_arname \
2723 _bfd_archive_coff_truncate_arname
2724 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
2725 #define bfd_elf64_archive_openr_next_archived_file \
2726 _bfd_archive_coff_openr_next_archived_file
2727 #define bfd_elf64_archive_get_elt_at_index \
2728 _bfd_archive_coff_get_elt_at_index
2729 #define bfd_elf64_archive_generic_stat_arch_elt \
2730 _bfd_archive_coff_generic_stat_arch_elt
2731 #define bfd_elf64_archive_update_armap_timestamp \
2732 _bfd_archive_coff_update_armap_timestamp
2733
2734 /* The SGI style (n)64 NewABI. */
2735 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
2736 #define TARGET_LITTLE_NAME "elf64-littlemips"
2737 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
2738 #define TARGET_BIG_NAME "elf64-bigmips"
2739
2740 #include "elf64-target.h"
2741
2742 #define INCLUDED_TARGET_FILE /* More a type of flag. */
2743
2744 /* The SYSV-style 'traditional' (n)64 NewABI. */
2745 #undef TARGET_LITTLE_SYM
2746 #undef TARGET_LITTLE_NAME
2747 #undef TARGET_BIG_SYM
2748 #undef TARGET_BIG_NAME
2749
2750 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
2751 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
2752 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
2753 #define TARGET_BIG_NAME "elf64-tradbigmips"
2754
2755 /* Include the target file again for this target. */
2756 #include "elf64-target.h"
This page took 0.085861 seconds and 5 git commands to generate.