2010-08-04 Tristan Gingold <gingold@adacore.com>
[binutils.git] / bfd / elf64-mips.c
blob95186d4c3aa5c82877120b17d7a43f6630ea79bc
1 /* MIPS-specific support for 64-bit ELF
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Ian Lance Taylor, Cygnus Support
6 Linker support added by Mark Mitchell, CodeSourcery, LLC.
7 <mark@codesourcery.com>
9 This file is part of BFD, the Binary File Descriptor library.
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
24 MA 02110-1301, USA. */
27 /* This file supports the 64-bit MIPS ELF ABI.
29 The MIPS 64-bit ELF ABI uses an unusual reloc format. This file
30 overrides the usual ELF reloc handling, and handles reading and
31 writing the relocations here. */
33 /* TODO: Many things are unsupported, even if there is some code for it
34 . (which was mostly stolen from elf32-mips.c and slightly adapted).
36 . - Relocation handling for REL relocs is wrong in many cases and
37 . generally untested.
38 . - Relocation handling for RELA relocs related to GOT support are
39 . also likely to be wrong.
40 . - Support for MIPS16 is untested.
41 . - Combined relocs with RSS_* entries are unsupported.
42 . - The whole GOT handling for NewABI is missing, some parts of
43 . the OldABI version is still lying around and should be removed.
46 #include "sysdep.h"
47 #include "bfd.h"
48 #include "libbfd.h"
49 #include "aout/ar.h"
50 #include "bfdlink.h"
51 #include "genlink.h"
52 #include "elf-bfd.h"
53 #include "elfxx-mips.h"
54 #include "elf/mips.h"
56 /* Get the ECOFF swapping routines. The 64-bit ABI is not supposed to
57 use ECOFF. However, we support it anyhow for an easier changeover. */
58 #include "coff/sym.h"
59 #include "coff/symconst.h"
60 #include "coff/internal.h"
61 #include "coff/ecoff.h"
62 /* The 64 bit versions of the mdebug data structures are in alpha.h. */
63 #include "coff/alpha.h"
64 #define ECOFF_SIGNED_64
65 #include "ecoffswap.h"
67 static void mips_elf64_swap_reloc_in
68 (bfd *, const Elf64_Mips_External_Rel *, Elf64_Mips_Internal_Rela *);
69 static void mips_elf64_swap_reloca_in
70 (bfd *, const Elf64_Mips_External_Rela *, Elf64_Mips_Internal_Rela *);
71 static void mips_elf64_swap_reloc_out
72 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rel *);
73 static void mips_elf64_swap_reloca_out
74 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rela *);
75 static void mips_elf64_be_swap_reloc_in
76 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
77 static void mips_elf64_be_swap_reloc_out
78 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
79 static void mips_elf64_be_swap_reloca_in
80 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
81 static void mips_elf64_be_swap_reloca_out
82 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
83 static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup
84 (bfd *, bfd_reloc_code_real_type);
85 static reloc_howto_type *mips_elf64_rtype_to_howto
86 (unsigned int, bfd_boolean);
87 static void mips_elf64_info_to_howto_rel
88 (bfd *, arelent *, Elf_Internal_Rela *);
89 static void mips_elf64_info_to_howto_rela
90 (bfd *, arelent *, Elf_Internal_Rela *);
91 static long mips_elf64_get_reloc_upper_bound
92 (bfd *, asection *);
93 static long mips_elf64_canonicalize_reloc
94 (bfd *, asection *, arelent **, asymbol **);
95 static long mips_elf64_get_dynamic_reloc_upper_bound
96 (bfd *);
97 static long mips_elf64_canonicalize_dynamic_reloc
98 (bfd *, arelent **, asymbol **);
99 static bfd_boolean mips_elf64_slurp_one_reloc_table
100 (bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type, arelent *,
101 asymbol **, bfd_boolean);
102 static bfd_boolean mips_elf64_slurp_reloc_table
103 (bfd *, asection *, asymbol **, bfd_boolean);
104 static void mips_elf64_write_relocs
105 (bfd *, asection *, void *);
106 static void mips_elf64_write_rel
107 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
108 static void mips_elf64_write_rela
109 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
110 static bfd_reloc_status_type mips_elf64_gprel16_reloc
111 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
112 static bfd_reloc_status_type mips_elf64_literal_reloc
113 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
114 static bfd_reloc_status_type mips_elf64_gprel32_reloc
115 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
116 static bfd_reloc_status_type mips_elf64_shift6_reloc
117 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
118 static bfd_reloc_status_type mips16_gprel_reloc
119 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
120 static bfd_boolean mips_elf64_assign_gp
121 (bfd *, bfd_vma *);
122 static bfd_reloc_status_type mips_elf64_final_gp
123 (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
124 static bfd_boolean mips_elf64_object_p
125 (bfd *);
126 static irix_compat_t elf64_mips_irix_compat
127 (bfd *);
128 static bfd_boolean elf64_mips_grok_prstatus
129 (bfd *, Elf_Internal_Note *);
130 static bfd_boolean elf64_mips_grok_psinfo
131 (bfd *, Elf_Internal_Note *);
133 extern const bfd_target bfd_elf64_bigmips_vec;
134 extern const bfd_target bfd_elf64_littlemips_vec;
136 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
137 from smaller values. Start with zero, widen, *then* decrement. */
138 #define MINUS_ONE (((bfd_vma)0) - 1)
140 /* The number of local .got entries we reserve. */
141 #define MIPS_RESERVED_GOTNO (2)
143 /* The relocation table used for SHT_REL sections. */
145 static reloc_howto_type mips_elf64_howto_table_rel[] =
147 /* No relocation. */
148 HOWTO (R_MIPS_NONE, /* type */
149 0, /* rightshift */
150 0, /* size (0 = byte, 1 = short, 2 = long) */
151 0, /* bitsize */
152 FALSE, /* pc_relative */
153 0, /* bitpos */
154 complain_overflow_dont, /* complain_on_overflow */
155 _bfd_mips_elf_generic_reloc, /* special_function */
156 "R_MIPS_NONE", /* name */
157 FALSE, /* partial_inplace */
158 0, /* src_mask */
159 0, /* dst_mask */
160 FALSE), /* pcrel_offset */
162 /* 16 bit relocation. */
163 HOWTO (R_MIPS_16, /* type */
164 0, /* rightshift */
165 2, /* size (0 = byte, 1 = short, 2 = long) */
166 16, /* bitsize */
167 FALSE, /* pc_relative */
168 0, /* bitpos */
169 complain_overflow_signed, /* complain_on_overflow */
170 _bfd_mips_elf_generic_reloc, /* special_function */
171 "R_MIPS_16", /* name */
172 TRUE, /* partial_inplace */
173 0x0000ffff, /* src_mask */
174 0x0000ffff, /* dst_mask */
175 FALSE), /* pcrel_offset */
177 /* 32 bit relocation. */
178 HOWTO (R_MIPS_32, /* type */
179 0, /* rightshift */
180 2, /* size (0 = byte, 1 = short, 2 = long) */
181 32, /* bitsize */
182 FALSE, /* pc_relative */
183 0, /* bitpos */
184 complain_overflow_dont, /* complain_on_overflow */
185 _bfd_mips_elf_generic_reloc, /* special_function */
186 "R_MIPS_32", /* name */
187 TRUE, /* partial_inplace */
188 0xffffffff, /* src_mask */
189 0xffffffff, /* dst_mask */
190 FALSE), /* pcrel_offset */
192 /* 32 bit symbol relative relocation. */
193 HOWTO (R_MIPS_REL32, /* type */
194 0, /* rightshift */
195 2, /* size (0 = byte, 1 = short, 2 = long) */
196 32, /* bitsize */
197 FALSE, /* pc_relative */
198 0, /* bitpos */
199 complain_overflow_dont, /* complain_on_overflow */
200 _bfd_mips_elf_generic_reloc, /* special_function */
201 "R_MIPS_REL32", /* name */
202 TRUE, /* partial_inplace */
203 0xffffffff, /* src_mask */
204 0xffffffff, /* dst_mask */
205 FALSE), /* pcrel_offset */
207 /* 26 bit jump address. */
208 HOWTO (R_MIPS_26, /* type */
209 2, /* rightshift */
210 2, /* size (0 = byte, 1 = short, 2 = long) */
211 26, /* bitsize */
212 FALSE, /* pc_relative */
213 0, /* bitpos */
214 complain_overflow_dont, /* complain_on_overflow */
215 /* This needs complex overflow
216 detection, because the upper 36
217 bits must match the PC + 4. */
218 _bfd_mips_elf_generic_reloc, /* special_function */
219 "R_MIPS_26", /* name */
220 TRUE, /* partial_inplace */
221 0x03ffffff, /* src_mask */
222 0x03ffffff, /* dst_mask */
223 FALSE), /* pcrel_offset */
225 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
226 However, the native IRIX6 tools use them, so we try our best. */
228 /* High 16 bits of symbol value. */
229 HOWTO (R_MIPS_HI16, /* type */
230 16, /* rightshift */
231 2, /* size (0 = byte, 1 = short, 2 = long) */
232 16, /* bitsize */
233 FALSE, /* pc_relative */
234 0, /* bitpos */
235 complain_overflow_dont, /* complain_on_overflow */
236 _bfd_mips_elf_hi16_reloc, /* special_function */
237 "R_MIPS_HI16", /* name */
238 TRUE, /* partial_inplace */
239 0x0000ffff, /* src_mask */
240 0x0000ffff, /* dst_mask */
241 FALSE), /* pcrel_offset */
243 /* Low 16 bits of symbol value. */
244 HOWTO (R_MIPS_LO16, /* type */
245 0, /* rightshift */
246 2, /* size (0 = byte, 1 = short, 2 = long) */
247 16, /* bitsize */
248 FALSE, /* pc_relative */
249 0, /* bitpos */
250 complain_overflow_dont, /* complain_on_overflow */
251 _bfd_mips_elf_lo16_reloc, /* special_function */
252 "R_MIPS_LO16", /* name */
253 TRUE, /* partial_inplace */
254 0x0000ffff, /* src_mask */
255 0x0000ffff, /* dst_mask */
256 FALSE), /* pcrel_offset */
258 /* GP relative reference. */
259 HOWTO (R_MIPS_GPREL16, /* type */
260 0, /* rightshift */
261 2, /* size (0 = byte, 1 = short, 2 = long) */
262 16, /* bitsize */
263 FALSE, /* pc_relative */
264 0, /* bitpos */
265 complain_overflow_signed, /* complain_on_overflow */
266 mips_elf64_gprel16_reloc, /* special_function */
267 "R_MIPS_GPREL16", /* name */
268 TRUE, /* partial_inplace */
269 0x0000ffff, /* src_mask */
270 0x0000ffff, /* dst_mask */
271 FALSE), /* pcrel_offset */
273 /* Reference to literal section. */
274 HOWTO (R_MIPS_LITERAL, /* type */
275 0, /* rightshift */
276 2, /* size (0 = byte, 1 = short, 2 = long) */
277 16, /* bitsize */
278 FALSE, /* pc_relative */
279 0, /* bitpos */
280 complain_overflow_signed, /* complain_on_overflow */
281 mips_elf64_literal_reloc, /* special_function */
282 "R_MIPS_LITERAL", /* name */
283 TRUE, /* partial_inplace */
284 0x0000ffff, /* src_mask */
285 0x0000ffff, /* dst_mask */
286 FALSE), /* pcrel_offset */
288 /* Reference to global offset table. */
289 HOWTO (R_MIPS_GOT16, /* type */
290 0, /* rightshift */
291 2, /* size (0 = byte, 1 = short, 2 = long) */
292 16, /* bitsize */
293 FALSE, /* pc_relative */
294 0, /* bitpos */
295 complain_overflow_signed, /* complain_on_overflow */
296 _bfd_mips_elf_got16_reloc, /* special_function */
297 "R_MIPS_GOT16", /* name */
298 TRUE, /* partial_inplace */
299 0x0000ffff, /* src_mask */
300 0x0000ffff, /* dst_mask */
301 FALSE), /* pcrel_offset */
303 /* 16 bit PC relative reference. Note that the ABI document has a typo
304 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
305 We do the right thing here. */
306 HOWTO (R_MIPS_PC16, /* type */
307 2, /* rightshift */
308 2, /* size (0 = byte, 1 = short, 2 = long) */
309 16, /* bitsize */
310 TRUE, /* pc_relative */
311 0, /* bitpos */
312 complain_overflow_signed, /* complain_on_overflow */
313 _bfd_mips_elf_generic_reloc, /* special_function */
314 "R_MIPS_PC16", /* name */
315 TRUE, /* partial_inplace */
316 0x0000ffff, /* src_mask */
317 0x0000ffff, /* dst_mask */
318 TRUE), /* pcrel_offset */
320 /* 16 bit call through global offset table. */
321 HOWTO (R_MIPS_CALL16, /* type */
322 0, /* rightshift */
323 2, /* size (0 = byte, 1 = short, 2 = long) */
324 16, /* bitsize */
325 FALSE, /* pc_relative */
326 0, /* bitpos */
327 complain_overflow_signed, /* complain_on_overflow */
328 _bfd_mips_elf_generic_reloc, /* special_function */
329 "R_MIPS_CALL16", /* name */
330 TRUE, /* partial_inplace */
331 0x0000ffff, /* src_mask */
332 0x0000ffff, /* dst_mask */
333 FALSE), /* pcrel_offset */
335 /* 32 bit GP relative reference. */
336 HOWTO (R_MIPS_GPREL32, /* type */
337 0, /* rightshift */
338 2, /* size (0 = byte, 1 = short, 2 = long) */
339 32, /* bitsize */
340 FALSE, /* pc_relative */
341 0, /* bitpos */
342 complain_overflow_dont, /* complain_on_overflow */
343 mips_elf64_gprel32_reloc, /* special_function */
344 "R_MIPS_GPREL32", /* name */
345 TRUE, /* partial_inplace */
346 0xffffffff, /* src_mask */
347 0xffffffff, /* dst_mask */
348 FALSE), /* pcrel_offset */
350 EMPTY_HOWTO (13),
351 EMPTY_HOWTO (14),
352 EMPTY_HOWTO (15),
354 /* A 5 bit shift field. */
355 HOWTO (R_MIPS_SHIFT5, /* type */
356 0, /* rightshift */
357 2, /* size (0 = byte, 1 = short, 2 = long) */
358 5, /* bitsize */
359 FALSE, /* pc_relative */
360 6, /* bitpos */
361 complain_overflow_bitfield, /* complain_on_overflow */
362 _bfd_mips_elf_generic_reloc, /* special_function */
363 "R_MIPS_SHIFT5", /* name */
364 TRUE, /* partial_inplace */
365 0x000007c0, /* src_mask */
366 0x000007c0, /* dst_mask */
367 FALSE), /* pcrel_offset */
369 /* A 6 bit shift field. */
370 HOWTO (R_MIPS_SHIFT6, /* type */
371 0, /* rightshift */
372 2, /* size (0 = byte, 1 = short, 2 = long) */
373 6, /* bitsize */
374 FALSE, /* pc_relative */
375 6, /* bitpos */
376 complain_overflow_bitfield, /* complain_on_overflow */
377 mips_elf64_shift6_reloc, /* special_function */
378 "R_MIPS_SHIFT6", /* name */
379 TRUE, /* partial_inplace */
380 0x000007c4, /* src_mask */
381 0x000007c4, /* dst_mask */
382 FALSE), /* pcrel_offset */
384 /* 64 bit relocation. */
385 HOWTO (R_MIPS_64, /* type */
386 0, /* rightshift */
387 4, /* size (0 = byte, 1 = short, 2 = long) */
388 64, /* bitsize */
389 FALSE, /* pc_relative */
390 0, /* bitpos */
391 complain_overflow_dont, /* complain_on_overflow */
392 _bfd_mips_elf_generic_reloc, /* special_function */
393 "R_MIPS_64", /* name */
394 TRUE, /* partial_inplace */
395 MINUS_ONE, /* src_mask */
396 MINUS_ONE, /* dst_mask */
397 FALSE), /* pcrel_offset */
399 /* Displacement in the global offset table. */
400 HOWTO (R_MIPS_GOT_DISP, /* type */
401 0, /* rightshift */
402 2, /* size (0 = byte, 1 = short, 2 = long) */
403 16, /* bitsize */
404 FALSE, /* pc_relative */
405 0, /* bitpos */
406 complain_overflow_signed, /* complain_on_overflow */
407 _bfd_mips_elf_generic_reloc, /* special_function */
408 "R_MIPS_GOT_DISP", /* name */
409 TRUE, /* partial_inplace */
410 0x0000ffff, /* src_mask */
411 0x0000ffff, /* dst_mask */
412 FALSE), /* pcrel_offset */
414 /* Displacement to page pointer in the global offset table. */
415 HOWTO (R_MIPS_GOT_PAGE, /* type */
416 0, /* rightshift */
417 2, /* size (0 = byte, 1 = short, 2 = long) */
418 16, /* bitsize */
419 FALSE, /* pc_relative */
420 0, /* bitpos */
421 complain_overflow_signed, /* complain_on_overflow */
422 _bfd_mips_elf_generic_reloc, /* special_function */
423 "R_MIPS_GOT_PAGE", /* name */
424 TRUE, /* partial_inplace */
425 0x0000ffff, /* src_mask */
426 0x0000ffff, /* dst_mask */
427 FALSE), /* pcrel_offset */
429 /* Offset from page pointer in the global offset table. */
430 HOWTO (R_MIPS_GOT_OFST, /* type */
431 0, /* rightshift */
432 2, /* size (0 = byte, 1 = short, 2 = long) */
433 16, /* bitsize */
434 FALSE, /* pc_relative */
435 0, /* bitpos */
436 complain_overflow_signed, /* complain_on_overflow */
437 _bfd_mips_elf_generic_reloc, /* special_function */
438 "R_MIPS_GOT_OFST", /* name */
439 TRUE, /* partial_inplace */
440 0x0000ffff, /* src_mask */
441 0x0000ffff, /* dst_mask */
442 FALSE), /* pcrel_offset */
444 /* High 16 bits of displacement in global offset table. */
445 HOWTO (R_MIPS_GOT_HI16, /* type */
446 0, /* rightshift */
447 2, /* size (0 = byte, 1 = short, 2 = long) */
448 16, /* bitsize */
449 FALSE, /* pc_relative */
450 0, /* bitpos */
451 complain_overflow_dont, /* complain_on_overflow */
452 _bfd_mips_elf_generic_reloc, /* special_function */
453 "R_MIPS_GOT_HI16", /* name */
454 TRUE, /* partial_inplace */
455 0x0000ffff, /* src_mask */
456 0x0000ffff, /* dst_mask */
457 FALSE), /* pcrel_offset */
459 /* Low 16 bits of displacement in global offset table. */
460 HOWTO (R_MIPS_GOT_LO16, /* type */
461 0, /* rightshift */
462 2, /* size (0 = byte, 1 = short, 2 = long) */
463 16, /* bitsize */
464 FALSE, /* pc_relative */
465 0, /* bitpos */
466 complain_overflow_dont, /* complain_on_overflow */
467 _bfd_mips_elf_generic_reloc, /* special_function */
468 "R_MIPS_GOT_LO16", /* name */
469 TRUE, /* partial_inplace */
470 0x0000ffff, /* src_mask */
471 0x0000ffff, /* dst_mask */
472 FALSE), /* pcrel_offset */
474 /* 64 bit subtraction. */
475 HOWTO (R_MIPS_SUB, /* type */
476 0, /* rightshift */
477 4, /* size (0 = byte, 1 = short, 2 = long) */
478 64, /* bitsize */
479 FALSE, /* pc_relative */
480 0, /* bitpos */
481 complain_overflow_dont, /* complain_on_overflow */
482 _bfd_mips_elf_generic_reloc, /* special_function */
483 "R_MIPS_SUB", /* name */
484 TRUE, /* partial_inplace */
485 MINUS_ONE, /* src_mask */
486 MINUS_ONE, /* dst_mask */
487 FALSE), /* pcrel_offset */
489 /* Insert the addend as an instruction. */
490 /* FIXME: Not handled correctly. */
491 HOWTO (R_MIPS_INSERT_A, /* type */
492 0, /* rightshift */
493 2, /* size (0 = byte, 1 = short, 2 = long) */
494 32, /* bitsize */
495 FALSE, /* pc_relative */
496 0, /* bitpos */
497 complain_overflow_dont, /* complain_on_overflow */
498 _bfd_mips_elf_generic_reloc, /* special_function */
499 "R_MIPS_INSERT_A", /* name */
500 TRUE, /* partial_inplace */
501 0xffffffff, /* src_mask */
502 0xffffffff, /* dst_mask */
503 FALSE), /* pcrel_offset */
505 /* Insert the addend as an instruction, and change all relocations
506 to refer to the old instruction at the address. */
507 /* FIXME: Not handled correctly. */
508 HOWTO (R_MIPS_INSERT_B, /* type */
509 0, /* rightshift */
510 2, /* size (0 = byte, 1 = short, 2 = long) */
511 32, /* bitsize */
512 FALSE, /* pc_relative */
513 0, /* bitpos */
514 complain_overflow_dont, /* complain_on_overflow */
515 _bfd_mips_elf_generic_reloc, /* special_function */
516 "R_MIPS_INSERT_B", /* name */
517 TRUE, /* partial_inplace */
518 0xffffffff, /* src_mask */
519 0xffffffff, /* dst_mask */
520 FALSE), /* pcrel_offset */
522 /* Delete a 32 bit instruction. */
523 /* FIXME: Not handled correctly. */
524 HOWTO (R_MIPS_DELETE, /* type */
525 0, /* rightshift */
526 2, /* size (0 = byte, 1 = short, 2 = long) */
527 32, /* bitsize */
528 FALSE, /* pc_relative */
529 0, /* bitpos */
530 complain_overflow_dont, /* complain_on_overflow */
531 _bfd_mips_elf_generic_reloc, /* special_function */
532 "R_MIPS_DELETE", /* name */
533 TRUE, /* partial_inplace */
534 0xffffffff, /* src_mask */
535 0xffffffff, /* dst_mask */
536 FALSE), /* pcrel_offset */
538 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
539 We don't, because
540 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
541 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
542 fallable heuristics.
543 b) No other NewABI toolchain actually emits such relocations. */
544 EMPTY_HOWTO (R_MIPS_HIGHER),
545 EMPTY_HOWTO (R_MIPS_HIGHEST),
547 /* High 16 bits of displacement in global offset table. */
548 HOWTO (R_MIPS_CALL_HI16, /* type */
549 0, /* rightshift */
550 2, /* size (0 = byte, 1 = short, 2 = long) */
551 16, /* bitsize */
552 FALSE, /* pc_relative */
553 0, /* bitpos */
554 complain_overflow_dont, /* complain_on_overflow */
555 _bfd_mips_elf_generic_reloc, /* special_function */
556 "R_MIPS_CALL_HI16", /* name */
557 TRUE, /* partial_inplace */
558 0x0000ffff, /* src_mask */
559 0x0000ffff, /* dst_mask */
560 FALSE), /* pcrel_offset */
562 /* Low 16 bits of displacement in global offset table. */
563 HOWTO (R_MIPS_CALL_LO16, /* type */
564 0, /* rightshift */
565 2, /* size (0 = byte, 1 = short, 2 = long) */
566 16, /* bitsize */
567 FALSE, /* pc_relative */
568 0, /* bitpos */
569 complain_overflow_dont, /* complain_on_overflow */
570 _bfd_mips_elf_generic_reloc, /* special_function */
571 "R_MIPS_CALL_LO16", /* name */
572 TRUE, /* partial_inplace */
573 0x0000ffff, /* src_mask */
574 0x0000ffff, /* dst_mask */
575 FALSE), /* pcrel_offset */
577 /* Section displacement, used by an associated event location section. */
578 HOWTO (R_MIPS_SCN_DISP, /* type */
579 0, /* rightshift */
580 2, /* size (0 = byte, 1 = short, 2 = long) */
581 32, /* bitsize */
582 FALSE, /* pc_relative */
583 0, /* bitpos */
584 complain_overflow_dont, /* complain_on_overflow */
585 _bfd_mips_elf_generic_reloc, /* special_function */
586 "R_MIPS_SCN_DISP", /* name */
587 TRUE, /* partial_inplace */
588 0xffffffff, /* src_mask */
589 0xffffffff, /* dst_mask */
590 FALSE), /* pcrel_offset */
592 HOWTO (R_MIPS_REL16, /* type */
593 0, /* rightshift */
594 1, /* size (0 = byte, 1 = short, 2 = long) */
595 16, /* bitsize */
596 FALSE, /* pc_relative */
597 0, /* bitpos */
598 complain_overflow_signed, /* complain_on_overflow */
599 _bfd_mips_elf_generic_reloc, /* special_function */
600 "R_MIPS_REL16", /* name */
601 TRUE, /* partial_inplace */
602 0xffff, /* src_mask */
603 0xffff, /* dst_mask */
604 FALSE), /* pcrel_offset */
606 /* These two are obsolete. */
607 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
608 EMPTY_HOWTO (R_MIPS_PJUMP),
610 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
611 It must be used for multigot GOT's (and only there). */
612 HOWTO (R_MIPS_RELGOT, /* type */
613 0, /* rightshift */
614 2, /* size (0 = byte, 1 = short, 2 = long) */
615 32, /* bitsize */
616 FALSE, /* pc_relative */
617 0, /* bitpos */
618 complain_overflow_dont, /* complain_on_overflow */
619 _bfd_mips_elf_generic_reloc, /* special_function */
620 "R_MIPS_RELGOT", /* name */
621 TRUE, /* partial_inplace */
622 0xffffffff, /* src_mask */
623 0xffffffff, /* dst_mask */
624 FALSE), /* pcrel_offset */
626 /* Protected jump conversion. This is an optimization hint. No
627 relocation is required for correctness. */
628 HOWTO (R_MIPS_JALR, /* type */
629 0, /* rightshift */
630 2, /* size (0 = byte, 1 = short, 2 = long) */
631 32, /* bitsize */
632 FALSE, /* pc_relative */
633 0, /* bitpos */
634 complain_overflow_dont, /* complain_on_overflow */
635 _bfd_mips_elf_generic_reloc, /* special_function */
636 "R_MIPS_JALR", /* name */
637 FALSE, /* partial_inplace */
638 0, /* src_mask */
639 0x00000000, /* dst_mask */
640 FALSE), /* pcrel_offset */
642 /* TLS relocations. */
643 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
644 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
646 HOWTO (R_MIPS_TLS_DTPMOD64, /* type */
647 0, /* rightshift */
648 4, /* size (0 = byte, 1 = short, 2 = long) */
649 64, /* bitsize */
650 FALSE, /* pc_relative */
651 0, /* bitpos */
652 complain_overflow_dont, /* complain_on_overflow */
653 _bfd_mips_elf_generic_reloc, /* special_function */
654 "R_MIPS_TLS_DTPMOD64", /* name */
655 TRUE, /* partial_inplace */
656 MINUS_ONE, /* src_mask */
657 MINUS_ONE, /* dst_mask */
658 FALSE), /* pcrel_offset */
660 HOWTO (R_MIPS_TLS_DTPREL64, /* type */
661 0, /* rightshift */
662 4, /* size (0 = byte, 1 = short, 2 = long) */
663 64, /* bitsize */
664 FALSE, /* pc_relative */
665 0, /* bitpos */
666 complain_overflow_dont, /* complain_on_overflow */
667 _bfd_mips_elf_generic_reloc, /* special_function */
668 "R_MIPS_TLS_DTPREL64", /* name */
669 TRUE, /* partial_inplace */
670 MINUS_ONE, /* src_mask */
671 MINUS_ONE, /* dst_mask */
672 FALSE), /* pcrel_offset */
674 /* TLS general dynamic variable reference. */
675 HOWTO (R_MIPS_TLS_GD, /* type */
676 0, /* rightshift */
677 2, /* size (0 = byte, 1 = short, 2 = long) */
678 16, /* bitsize */
679 FALSE, /* pc_relative */
680 0, /* bitpos */
681 complain_overflow_signed, /* complain_on_overflow */
682 _bfd_mips_elf_generic_reloc, /* special_function */
683 "R_MIPS_TLS_GD", /* name */
684 TRUE, /* partial_inplace */
685 0x0000ffff, /* src_mask */
686 0x0000ffff, /* dst_mask */
687 FALSE), /* pcrel_offset */
689 /* TLS local dynamic variable reference. */
690 HOWTO (R_MIPS_TLS_LDM, /* type */
691 0, /* rightshift */
692 2, /* size (0 = byte, 1 = short, 2 = long) */
693 16, /* bitsize */
694 FALSE, /* pc_relative */
695 0, /* bitpos */
696 complain_overflow_signed, /* complain_on_overflow */
697 _bfd_mips_elf_generic_reloc, /* special_function */
698 "R_MIPS_TLS_LDM", /* name */
699 TRUE, /* partial_inplace */
700 0x0000ffff, /* src_mask */
701 0x0000ffff, /* dst_mask */
702 FALSE), /* pcrel_offset */
704 /* TLS local dynamic offset. */
705 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
706 0, /* rightshift */
707 2, /* size (0 = byte, 1 = short, 2 = long) */
708 16, /* bitsize */
709 FALSE, /* pc_relative */
710 0, /* bitpos */
711 complain_overflow_signed, /* complain_on_overflow */
712 _bfd_mips_elf_generic_reloc, /* special_function */
713 "R_MIPS_TLS_DTPREL_HI16", /* name */
714 TRUE, /* partial_inplace */
715 0x0000ffff, /* src_mask */
716 0x0000ffff, /* dst_mask */
717 FALSE), /* pcrel_offset */
719 /* TLS local dynamic offset. */
720 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
721 0, /* rightshift */
722 2, /* size (0 = byte, 1 = short, 2 = long) */
723 16, /* bitsize */
724 FALSE, /* pc_relative */
725 0, /* bitpos */
726 complain_overflow_signed, /* complain_on_overflow */
727 _bfd_mips_elf_generic_reloc, /* special_function */
728 "R_MIPS_TLS_DTPREL_LO16", /* name */
729 TRUE, /* partial_inplace */
730 0x0000ffff, /* src_mask */
731 0x0000ffff, /* dst_mask */
732 FALSE), /* pcrel_offset */
734 /* TLS thread pointer offset. */
735 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
736 0, /* rightshift */
737 2, /* size (0 = byte, 1 = short, 2 = long) */
738 16, /* bitsize */
739 FALSE, /* pc_relative */
740 0, /* bitpos */
741 complain_overflow_signed, /* complain_on_overflow */
742 _bfd_mips_elf_generic_reloc, /* special_function */
743 "R_MIPS_TLS_GOTTPREL", /* name */
744 TRUE, /* partial_inplace */
745 0x0000ffff, /* src_mask */
746 0x0000ffff, /* dst_mask */
747 FALSE), /* pcrel_offset */
749 /* TLS IE dynamic relocations. */
750 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
752 HOWTO (R_MIPS_TLS_TPREL64, /* type */
753 0, /* rightshift */
754 4, /* size (0 = byte, 1 = short, 2 = long) */
755 64, /* bitsize */
756 FALSE, /* pc_relative */
757 0, /* bitpos */
758 complain_overflow_dont, /* complain_on_overflow */
759 _bfd_mips_elf_generic_reloc, /* special_function */
760 "R_MIPS_TLS_TPREL64", /* name */
761 TRUE, /* partial_inplace */
762 MINUS_ONE, /* src_mask */
763 MINUS_ONE, /* dst_mask */
764 FALSE), /* pcrel_offset */
766 /* TLS thread pointer offset. */
767 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
768 0, /* rightshift */
769 2, /* size (0 = byte, 1 = short, 2 = long) */
770 16, /* bitsize */
771 FALSE, /* pc_relative */
772 0, /* bitpos */
773 complain_overflow_signed, /* complain_on_overflow */
774 _bfd_mips_elf_generic_reloc, /* special_function */
775 "R_MIPS_TLS_TPREL_HI16", /* name */
776 TRUE, /* partial_inplace */
777 0x0000ffff, /* src_mask */
778 0x0000ffff, /* dst_mask */
779 FALSE), /* pcrel_offset */
781 /* TLS thread pointer offset. */
782 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
783 0, /* rightshift */
784 2, /* size (0 = byte, 1 = short, 2 = long) */
785 16, /* bitsize */
786 FALSE, /* pc_relative */
787 0, /* bitpos */
788 complain_overflow_signed, /* complain_on_overflow */
789 _bfd_mips_elf_generic_reloc, /* special_function */
790 "R_MIPS_TLS_TPREL_LO16", /* name */
791 TRUE, /* partial_inplace */
792 0x0000ffff, /* src_mask */
793 0x0000ffff, /* dst_mask */
794 FALSE), /* pcrel_offset */
796 /* 32 bit relocation with no addend. */
797 HOWTO (R_MIPS_GLOB_DAT, /* type */
798 0, /* rightshift */
799 2, /* size (0 = byte, 1 = short, 2 = long) */
800 32, /* bitsize */
801 FALSE, /* pc_relative */
802 0, /* bitpos */
803 complain_overflow_dont, /* complain_on_overflow */
804 _bfd_mips_elf_generic_reloc, /* special_function */
805 "R_MIPS_GLOB_DAT", /* name */
806 FALSE, /* partial_inplace */
807 0x0, /* src_mask */
808 0xffffffff, /* dst_mask */
809 FALSE), /* pcrel_offset */
812 /* The relocation table used for SHT_RELA sections. */
814 static reloc_howto_type mips_elf64_howto_table_rela[] =
816 /* No relocation. */
817 HOWTO (R_MIPS_NONE, /* type */
818 0, /* rightshift */
819 0, /* size (0 = byte, 1 = short, 2 = long) */
820 0, /* bitsize */
821 FALSE, /* pc_relative */
822 0, /* bitpos */
823 complain_overflow_dont, /* complain_on_overflow */
824 _bfd_mips_elf_generic_reloc, /* special_function */
825 "R_MIPS_NONE", /* name */
826 FALSE, /* partial_inplace */
827 0, /* src_mask */
828 0, /* dst_mask */
829 FALSE), /* pcrel_offset */
831 /* 16 bit relocation. */
832 HOWTO (R_MIPS_16, /* type */
833 0, /* rightshift */
834 2, /* size (0 = byte, 1 = short, 2 = long) */
835 16, /* bitsize */
836 FALSE, /* pc_relative */
837 0, /* bitpos */
838 complain_overflow_signed, /* complain_on_overflow */
839 _bfd_mips_elf_generic_reloc, /* special_function */
840 "R_MIPS_16", /* name */
841 FALSE, /* partial_inplace */
842 0, /* src_mask */
843 0x0000ffff, /* dst_mask */
844 FALSE), /* pcrel_offset */
846 /* 32 bit relocation. */
847 HOWTO (R_MIPS_32, /* type */
848 0, /* rightshift */
849 2, /* size (0 = byte, 1 = short, 2 = long) */
850 32, /* bitsize */
851 FALSE, /* pc_relative */
852 0, /* bitpos */
853 complain_overflow_dont, /* complain_on_overflow */
854 _bfd_mips_elf_generic_reloc, /* special_function */
855 "R_MIPS_32", /* name */
856 FALSE, /* partial_inplace */
857 0, /* src_mask */
858 0xffffffff, /* dst_mask */
859 FALSE), /* pcrel_offset */
861 /* 32 bit symbol relative relocation. */
862 HOWTO (R_MIPS_REL32, /* type */
863 0, /* rightshift */
864 2, /* size (0 = byte, 1 = short, 2 = long) */
865 32, /* bitsize */
866 FALSE, /* pc_relative */
867 0, /* bitpos */
868 complain_overflow_dont, /* complain_on_overflow */
869 _bfd_mips_elf_generic_reloc, /* special_function */
870 "R_MIPS_REL32", /* name */
871 FALSE, /* partial_inplace */
872 0, /* src_mask */
873 0xffffffff, /* dst_mask */
874 FALSE), /* pcrel_offset */
876 /* 26 bit jump address. */
877 HOWTO (R_MIPS_26, /* type */
878 2, /* rightshift */
879 2, /* size (0 = byte, 1 = short, 2 = long) */
880 26, /* bitsize */
881 FALSE, /* pc_relative */
882 0, /* bitpos */
883 complain_overflow_dont, /* complain_on_overflow */
884 /* This needs complex overflow
885 detection, because the upper 36
886 bits must match the PC + 4. */
887 _bfd_mips_elf_generic_reloc, /* special_function */
888 "R_MIPS_26", /* name */
889 FALSE, /* partial_inplace */
890 0, /* src_mask */
891 0x03ffffff, /* dst_mask */
892 FALSE), /* pcrel_offset */
894 /* High 16 bits of symbol value. */
895 HOWTO (R_MIPS_HI16, /* type */
896 0, /* rightshift */
897 2, /* size (0 = byte, 1 = short, 2 = long) */
898 16, /* bitsize */
899 FALSE, /* pc_relative */
900 0, /* bitpos */
901 complain_overflow_dont, /* complain_on_overflow */
902 _bfd_mips_elf_generic_reloc, /* special_function */
903 "R_MIPS_HI16", /* name */
904 FALSE, /* partial_inplace */
905 0, /* src_mask */
906 0x0000ffff, /* dst_mask */
907 FALSE), /* pcrel_offset */
909 /* Low 16 bits of symbol value. */
910 HOWTO (R_MIPS_LO16, /* type */
911 0, /* rightshift */
912 2, /* size (0 = byte, 1 = short, 2 = long) */
913 16, /* bitsize */
914 FALSE, /* pc_relative */
915 0, /* bitpos */
916 complain_overflow_dont, /* complain_on_overflow */
917 _bfd_mips_elf_generic_reloc, /* special_function */
918 "R_MIPS_LO16", /* name */
919 FALSE, /* partial_inplace */
920 0, /* src_mask */
921 0x0000ffff, /* dst_mask */
922 FALSE), /* pcrel_offset */
924 /* GP relative reference. */
925 HOWTO (R_MIPS_GPREL16, /* type */
926 0, /* rightshift */
927 2, /* size (0 = byte, 1 = short, 2 = long) */
928 16, /* bitsize */
929 FALSE, /* pc_relative */
930 0, /* bitpos */
931 complain_overflow_signed, /* complain_on_overflow */
932 mips_elf64_gprel16_reloc, /* special_function */
933 "R_MIPS_GPREL16", /* name */
934 FALSE, /* partial_inplace */
935 0, /* src_mask */
936 0x0000ffff, /* dst_mask */
937 FALSE), /* pcrel_offset */
939 /* Reference to literal section. */
940 HOWTO (R_MIPS_LITERAL, /* type */
941 0, /* rightshift */
942 2, /* size (0 = byte, 1 = short, 2 = long) */
943 16, /* bitsize */
944 FALSE, /* pc_relative */
945 0, /* bitpos */
946 complain_overflow_signed, /* complain_on_overflow */
947 mips_elf64_literal_reloc, /* special_function */
948 "R_MIPS_LITERAL", /* name */
949 FALSE, /* partial_inplace */
950 0, /* src_mask */
951 0x0000ffff, /* dst_mask */
952 FALSE), /* pcrel_offset */
954 /* Reference to global offset table. */
955 HOWTO (R_MIPS_GOT16, /* type */
956 0, /* rightshift */
957 2, /* size (0 = byte, 1 = short, 2 = long) */
958 16, /* bitsize */
959 FALSE, /* pc_relative */
960 0, /* bitpos */
961 complain_overflow_signed, /* complain_on_overflow */
962 _bfd_mips_elf_generic_reloc, /* special_function */
963 "R_MIPS_GOT16", /* name */
964 FALSE, /* partial_inplace */
965 0, /* src_mask */
966 0x0000ffff, /* dst_mask */
967 FALSE), /* pcrel_offset */
969 /* 16 bit PC relative reference. Note that the ABI document has a typo
970 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
971 We do the right thing here. */
972 HOWTO (R_MIPS_PC16, /* type */
973 2, /* rightshift */
974 2, /* size (0 = byte, 1 = short, 2 = long) */
975 16, /* bitsize */
976 TRUE, /* pc_relative */
977 0, /* bitpos */
978 complain_overflow_signed, /* complain_on_overflow */
979 _bfd_mips_elf_generic_reloc, /* special_function */
980 "R_MIPS_PC16", /* name */
981 FALSE, /* partial_inplace */
982 0, /* src_mask */
983 0x0000ffff, /* dst_mask */
984 TRUE), /* pcrel_offset */
986 /* 16 bit call through global offset table. */
987 HOWTO (R_MIPS_CALL16, /* type */
988 0, /* rightshift */
989 2, /* size (0 = byte, 1 = short, 2 = long) */
990 16, /* bitsize */
991 FALSE, /* pc_relative */
992 0, /* bitpos */
993 complain_overflow_signed, /* complain_on_overflow */
994 _bfd_mips_elf_generic_reloc, /* special_function */
995 "R_MIPS_CALL16", /* name */
996 FALSE, /* partial_inplace */
997 0, /* src_mask */
998 0x0000ffff, /* dst_mask */
999 FALSE), /* pcrel_offset */
1001 /* 32 bit GP relative reference. */
1002 HOWTO (R_MIPS_GPREL32, /* type */
1003 0, /* rightshift */
1004 2, /* size (0 = byte, 1 = short, 2 = long) */
1005 32, /* bitsize */
1006 FALSE, /* pc_relative */
1007 0, /* bitpos */
1008 complain_overflow_dont, /* complain_on_overflow */
1009 mips_elf64_gprel32_reloc, /* special_function */
1010 "R_MIPS_GPREL32", /* name */
1011 FALSE, /* partial_inplace */
1012 0, /* src_mask */
1013 0xffffffff, /* dst_mask */
1014 FALSE), /* pcrel_offset */
1016 EMPTY_HOWTO (13),
1017 EMPTY_HOWTO (14),
1018 EMPTY_HOWTO (15),
1020 /* A 5 bit shift field. */
1021 HOWTO (R_MIPS_SHIFT5, /* type */
1022 0, /* rightshift */
1023 2, /* size (0 = byte, 1 = short, 2 = long) */
1024 5, /* bitsize */
1025 FALSE, /* pc_relative */
1026 6, /* bitpos */
1027 complain_overflow_bitfield, /* complain_on_overflow */
1028 _bfd_mips_elf_generic_reloc, /* special_function */
1029 "R_MIPS_SHIFT5", /* name */
1030 FALSE, /* partial_inplace */
1031 0, /* src_mask */
1032 0x000007c0, /* dst_mask */
1033 FALSE), /* pcrel_offset */
1035 /* A 6 bit shift field. */
1036 HOWTO (R_MIPS_SHIFT6, /* type */
1037 0, /* rightshift */
1038 2, /* size (0 = byte, 1 = short, 2 = long) */
1039 6, /* bitsize */
1040 FALSE, /* pc_relative */
1041 6, /* bitpos */
1042 complain_overflow_bitfield, /* complain_on_overflow */
1043 mips_elf64_shift6_reloc, /* special_function */
1044 "R_MIPS_SHIFT6", /* name */
1045 FALSE, /* partial_inplace */
1046 0, /* src_mask */
1047 0x000007c4, /* dst_mask */
1048 FALSE), /* pcrel_offset */
1050 /* 64 bit relocation. */
1051 HOWTO (R_MIPS_64, /* type */
1052 0, /* rightshift */
1053 4, /* size (0 = byte, 1 = short, 2 = long) */
1054 64, /* bitsize */
1055 FALSE, /* pc_relative */
1056 0, /* bitpos */
1057 complain_overflow_dont, /* complain_on_overflow */
1058 _bfd_mips_elf_generic_reloc, /* special_function */
1059 "R_MIPS_64", /* name */
1060 FALSE, /* partial_inplace */
1061 0, /* src_mask */
1062 MINUS_ONE, /* dst_mask */
1063 FALSE), /* pcrel_offset */
1065 /* Displacement in the global offset table. */
1066 HOWTO (R_MIPS_GOT_DISP, /* type */
1067 0, /* rightshift */
1068 2, /* size (0 = byte, 1 = short, 2 = long) */
1069 16, /* bitsize */
1070 FALSE, /* pc_relative */
1071 0, /* bitpos */
1072 complain_overflow_signed, /* complain_on_overflow */
1073 _bfd_mips_elf_generic_reloc, /* special_function */
1074 "R_MIPS_GOT_DISP", /* name */
1075 FALSE, /* partial_inplace */
1076 0, /* src_mask */
1077 0x0000ffff, /* dst_mask */
1078 FALSE), /* pcrel_offset */
1080 /* Displacement to page pointer in the global offset table. */
1081 HOWTO (R_MIPS_GOT_PAGE, /* type */
1082 0, /* rightshift */
1083 2, /* size (0 = byte, 1 = short, 2 = long) */
1084 16, /* bitsize */
1085 FALSE, /* pc_relative */
1086 0, /* bitpos */
1087 complain_overflow_signed, /* complain_on_overflow */
1088 _bfd_mips_elf_generic_reloc, /* special_function */
1089 "R_MIPS_GOT_PAGE", /* name */
1090 FALSE, /* partial_inplace */
1091 0, /* src_mask */
1092 0x0000ffff, /* dst_mask */
1093 FALSE), /* pcrel_offset */
1095 /* Offset from page pointer in the global offset table. */
1096 HOWTO (R_MIPS_GOT_OFST, /* type */
1097 0, /* rightshift */
1098 2, /* size (0 = byte, 1 = short, 2 = long) */
1099 16, /* bitsize */
1100 FALSE, /* pc_relative */
1101 0, /* bitpos */
1102 complain_overflow_signed, /* complain_on_overflow */
1103 _bfd_mips_elf_generic_reloc, /* special_function */
1104 "R_MIPS_GOT_OFST", /* name */
1105 FALSE, /* partial_inplace */
1106 0, /* src_mask */
1107 0x0000ffff, /* dst_mask */
1108 FALSE), /* pcrel_offset */
1110 /* High 16 bits of displacement in global offset table. */
1111 HOWTO (R_MIPS_GOT_HI16, /* type */
1112 0, /* rightshift */
1113 2, /* size (0 = byte, 1 = short, 2 = long) */
1114 16, /* bitsize */
1115 FALSE, /* pc_relative */
1116 0, /* bitpos */
1117 complain_overflow_dont, /* complain_on_overflow */
1118 _bfd_mips_elf_generic_reloc, /* special_function */
1119 "R_MIPS_GOT_HI16", /* name */
1120 FALSE, /* partial_inplace */
1121 0, /* src_mask */
1122 0x0000ffff, /* dst_mask */
1123 FALSE), /* pcrel_offset */
1125 /* Low 16 bits of displacement in global offset table. */
1126 HOWTO (R_MIPS_GOT_LO16, /* type */
1127 0, /* rightshift */
1128 2, /* size (0 = byte, 1 = short, 2 = long) */
1129 16, /* bitsize */
1130 FALSE, /* pc_relative */
1131 0, /* bitpos */
1132 complain_overflow_dont, /* complain_on_overflow */
1133 _bfd_mips_elf_generic_reloc, /* special_function */
1134 "R_MIPS_GOT_LO16", /* name */
1135 FALSE, /* partial_inplace */
1136 0, /* src_mask */
1137 0x0000ffff, /* dst_mask */
1138 FALSE), /* pcrel_offset */
1140 /* 64 bit subtraction. */
1141 HOWTO (R_MIPS_SUB, /* type */
1142 0, /* rightshift */
1143 4, /* size (0 = byte, 1 = short, 2 = long) */
1144 64, /* bitsize */
1145 FALSE, /* pc_relative */
1146 0, /* bitpos */
1147 complain_overflow_dont, /* complain_on_overflow */
1148 _bfd_mips_elf_generic_reloc, /* special_function */
1149 "R_MIPS_SUB", /* name */
1150 FALSE, /* partial_inplace */
1151 0, /* src_mask */
1152 MINUS_ONE, /* dst_mask */
1153 FALSE), /* pcrel_offset */
1155 /* Insert the addend as an instruction. */
1156 /* FIXME: Not handled correctly. */
1157 HOWTO (R_MIPS_INSERT_A, /* type */
1158 0, /* rightshift */
1159 2, /* size (0 = byte, 1 = short, 2 = long) */
1160 32, /* bitsize */
1161 FALSE, /* pc_relative */
1162 0, /* bitpos */
1163 complain_overflow_dont, /* complain_on_overflow */
1164 _bfd_mips_elf_generic_reloc, /* special_function */
1165 "R_MIPS_INSERT_A", /* name */
1166 FALSE, /* partial_inplace */
1167 0, /* src_mask */
1168 0xffffffff, /* dst_mask */
1169 FALSE), /* pcrel_offset */
1171 /* Insert the addend as an instruction, and change all relocations
1172 to refer to the old instruction at the address. */
1173 /* FIXME: Not handled correctly. */
1174 HOWTO (R_MIPS_INSERT_B, /* type */
1175 0, /* rightshift */
1176 2, /* size (0 = byte, 1 = short, 2 = long) */
1177 32, /* bitsize */
1178 FALSE, /* pc_relative */
1179 0, /* bitpos */
1180 complain_overflow_dont, /* complain_on_overflow */
1181 _bfd_mips_elf_generic_reloc, /* special_function */
1182 "R_MIPS_INSERT_B", /* name */
1183 FALSE, /* partial_inplace */
1184 0, /* src_mask */
1185 0xffffffff, /* dst_mask */
1186 FALSE), /* pcrel_offset */
1188 /* Delete a 32 bit instruction. */
1189 /* FIXME: Not handled correctly. */
1190 HOWTO (R_MIPS_DELETE, /* type */
1191 0, /* rightshift */
1192 2, /* size (0 = byte, 1 = short, 2 = long) */
1193 32, /* bitsize */
1194 FALSE, /* pc_relative */
1195 0, /* bitpos */
1196 complain_overflow_dont, /* complain_on_overflow */
1197 _bfd_mips_elf_generic_reloc, /* special_function */
1198 "R_MIPS_DELETE", /* name */
1199 FALSE, /* partial_inplace */
1200 0, /* src_mask */
1201 0xffffffff, /* dst_mask */
1202 FALSE), /* pcrel_offset */
1204 /* Get the higher value of a 64 bit addend. */
1205 HOWTO (R_MIPS_HIGHER, /* type */
1206 0, /* rightshift */
1207 2, /* size (0 = byte, 1 = short, 2 = long) */
1208 16, /* bitsize */
1209 FALSE, /* pc_relative */
1210 0, /* bitpos */
1211 complain_overflow_dont, /* complain_on_overflow */
1212 _bfd_mips_elf_generic_reloc, /* special_function */
1213 "R_MIPS_HIGHER", /* name */
1214 FALSE, /* partial_inplace */
1215 0, /* src_mask */
1216 0x0000ffff, /* dst_mask */
1217 FALSE), /* pcrel_offset */
1219 /* Get the highest value of a 64 bit addend. */
1220 HOWTO (R_MIPS_HIGHEST, /* type */
1221 0, /* rightshift */
1222 2, /* size (0 = byte, 1 = short, 2 = long) */
1223 16, /* bitsize */
1224 FALSE, /* pc_relative */
1225 0, /* bitpos */
1226 complain_overflow_dont, /* complain_on_overflow */
1227 _bfd_mips_elf_generic_reloc, /* special_function */
1228 "R_MIPS_HIGHEST", /* name */
1229 FALSE, /* partial_inplace */
1230 0, /* src_mask */
1231 0x0000ffff, /* dst_mask */
1232 FALSE), /* pcrel_offset */
1234 /* High 16 bits of displacement in global offset table. */
1235 HOWTO (R_MIPS_CALL_HI16, /* type */
1236 0, /* rightshift */
1237 2, /* size (0 = byte, 1 = short, 2 = long) */
1238 16, /* bitsize */
1239 FALSE, /* pc_relative */
1240 0, /* bitpos */
1241 complain_overflow_dont, /* complain_on_overflow */
1242 _bfd_mips_elf_generic_reloc, /* special_function */
1243 "R_MIPS_CALL_HI16", /* name */
1244 FALSE, /* partial_inplace */
1245 0, /* src_mask */
1246 0x0000ffff, /* dst_mask */
1247 FALSE), /* pcrel_offset */
1249 /* Low 16 bits of displacement in global offset table. */
1250 HOWTO (R_MIPS_CALL_LO16, /* type */
1251 0, /* rightshift */
1252 2, /* size (0 = byte, 1 = short, 2 = long) */
1253 16, /* bitsize */
1254 FALSE, /* pc_relative */
1255 0, /* bitpos */
1256 complain_overflow_dont, /* complain_on_overflow */
1257 _bfd_mips_elf_generic_reloc, /* special_function */
1258 "R_MIPS_CALL_LO16", /* name */
1259 FALSE, /* partial_inplace */
1260 0, /* src_mask */
1261 0x0000ffff, /* dst_mask */
1262 FALSE), /* pcrel_offset */
1264 /* Section displacement, used by an associated event location section. */
1265 HOWTO (R_MIPS_SCN_DISP, /* type */
1266 0, /* rightshift */
1267 2, /* size (0 = byte, 1 = short, 2 = long) */
1268 32, /* bitsize */
1269 FALSE, /* pc_relative */
1270 0, /* bitpos */
1271 complain_overflow_dont, /* complain_on_overflow */
1272 _bfd_mips_elf_generic_reloc, /* special_function */
1273 "R_MIPS_SCN_DISP", /* name */
1274 FALSE, /* partial_inplace */
1275 0, /* src_mask */
1276 0xffffffff, /* dst_mask */
1277 FALSE), /* pcrel_offset */
1279 HOWTO (R_MIPS_REL16, /* type */
1280 0, /* rightshift */
1281 1, /* size (0 = byte, 1 = short, 2 = long) */
1282 16, /* bitsize */
1283 FALSE, /* pc_relative */
1284 0, /* bitpos */
1285 complain_overflow_signed, /* complain_on_overflow */
1286 _bfd_mips_elf_generic_reloc, /* special_function */
1287 "R_MIPS_REL16", /* name */
1288 FALSE, /* partial_inplace */
1289 0, /* src_mask */
1290 0xffff, /* dst_mask */
1291 FALSE), /* pcrel_offset */
1293 /* These two are obsolete. */
1294 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1295 EMPTY_HOWTO (R_MIPS_PJUMP),
1297 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1298 It must be used for multigot GOT's (and only there). */
1299 HOWTO (R_MIPS_RELGOT, /* type */
1300 0, /* rightshift */
1301 2, /* size (0 = byte, 1 = short, 2 = long) */
1302 32, /* bitsize */
1303 FALSE, /* pc_relative */
1304 0, /* bitpos */
1305 complain_overflow_dont, /* complain_on_overflow */
1306 _bfd_mips_elf_generic_reloc, /* special_function */
1307 "R_MIPS_RELGOT", /* name */
1308 FALSE, /* partial_inplace */
1309 0, /* src_mask */
1310 0xffffffff, /* dst_mask */
1311 FALSE), /* pcrel_offset */
1313 /* Protected jump conversion. This is an optimization hint. No
1314 relocation is required for correctness. */
1315 HOWTO (R_MIPS_JALR, /* type */
1316 0, /* rightshift */
1317 2, /* size (0 = byte, 1 = short, 2 = long) */
1318 32, /* bitsize */
1319 FALSE, /* pc_relative */
1320 0, /* bitpos */
1321 complain_overflow_dont, /* complain_on_overflow */
1322 _bfd_mips_elf_generic_reloc, /* special_function */
1323 "R_MIPS_JALR", /* name */
1324 FALSE, /* partial_inplace */
1325 0, /* src_mask */
1326 0x00000000, /* dst_mask */
1327 FALSE), /* pcrel_offset */
1329 /* TLS relocations. */
1330 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
1331 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
1333 HOWTO (R_MIPS_TLS_DTPMOD64, /* type */
1334 0, /* rightshift */
1335 4, /* size (0 = byte, 1 = short, 2 = long) */
1336 64, /* bitsize */
1337 FALSE, /* pc_relative */
1338 0, /* bitpos */
1339 complain_overflow_dont, /* complain_on_overflow */
1340 _bfd_mips_elf_generic_reloc, /* special_function */
1341 "R_MIPS_TLS_DTPMOD64", /* name */
1342 FALSE, /* partial_inplace */
1343 MINUS_ONE, /* src_mask */
1344 MINUS_ONE, /* dst_mask */
1345 FALSE), /* pcrel_offset */
1347 HOWTO (R_MIPS_TLS_DTPREL64, /* type */
1348 0, /* rightshift */
1349 4, /* size (0 = byte, 1 = short, 2 = long) */
1350 64, /* bitsize */
1351 FALSE, /* pc_relative */
1352 0, /* bitpos */
1353 complain_overflow_dont, /* complain_on_overflow */
1354 _bfd_mips_elf_generic_reloc, /* special_function */
1355 "R_MIPS_TLS_DTPREL64", /* name */
1356 FALSE, /* partial_inplace */
1357 MINUS_ONE, /* src_mask */
1358 MINUS_ONE, /* dst_mask */
1359 FALSE), /* pcrel_offset */
1361 /* TLS general dynamic variable reference. */
1362 HOWTO (R_MIPS_TLS_GD, /* type */
1363 0, /* rightshift */
1364 2, /* size (0 = byte, 1 = short, 2 = long) */
1365 16, /* bitsize */
1366 FALSE, /* pc_relative */
1367 0, /* bitpos */
1368 complain_overflow_signed, /* complain_on_overflow */
1369 _bfd_mips_elf_generic_reloc, /* special_function */
1370 "R_MIPS_TLS_GD", /* name */
1371 FALSE, /* partial_inplace */
1372 0x0000ffff, /* src_mask */
1373 0x0000ffff, /* dst_mask */
1374 FALSE), /* pcrel_offset */
1376 /* TLS local dynamic variable reference. */
1377 HOWTO (R_MIPS_TLS_LDM, /* type */
1378 0, /* rightshift */
1379 2, /* size (0 = byte, 1 = short, 2 = long) */
1380 16, /* bitsize */
1381 FALSE, /* pc_relative */
1382 0, /* bitpos */
1383 complain_overflow_signed, /* complain_on_overflow */
1384 _bfd_mips_elf_generic_reloc, /* special_function */
1385 "R_MIPS_TLS_LDM", /* name */
1386 FALSE, /* partial_inplace */
1387 0x0000ffff, /* src_mask */
1388 0x0000ffff, /* dst_mask */
1389 FALSE), /* pcrel_offset */
1391 /* TLS local dynamic offset. */
1392 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
1393 0, /* rightshift */
1394 2, /* size (0 = byte, 1 = short, 2 = long) */
1395 16, /* bitsize */
1396 FALSE, /* pc_relative */
1397 0, /* bitpos */
1398 complain_overflow_signed, /* complain_on_overflow */
1399 _bfd_mips_elf_generic_reloc, /* special_function */
1400 "R_MIPS_TLS_DTPREL_HI16", /* name */
1401 FALSE, /* partial_inplace */
1402 0x0000ffff, /* src_mask */
1403 0x0000ffff, /* dst_mask */
1404 FALSE), /* pcrel_offset */
1406 /* TLS local dynamic offset. */
1407 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
1408 0, /* rightshift */
1409 2, /* size (0 = byte, 1 = short, 2 = long) */
1410 16, /* bitsize */
1411 FALSE, /* pc_relative */
1412 0, /* bitpos */
1413 complain_overflow_signed, /* complain_on_overflow */
1414 _bfd_mips_elf_generic_reloc, /* special_function */
1415 "R_MIPS_TLS_DTPREL_LO16", /* name */
1416 FALSE, /* partial_inplace */
1417 0x0000ffff, /* src_mask */
1418 0x0000ffff, /* dst_mask */
1419 FALSE), /* pcrel_offset */
1421 /* TLS thread pointer offset. */
1422 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
1423 0, /* rightshift */
1424 2, /* size (0 = byte, 1 = short, 2 = long) */
1425 16, /* bitsize */
1426 FALSE, /* pc_relative */
1427 0, /* bitpos */
1428 complain_overflow_signed, /* complain_on_overflow */
1429 _bfd_mips_elf_generic_reloc, /* special_function */
1430 "R_MIPS_TLS_GOTTPREL", /* name */
1431 FALSE, /* partial_inplace */
1432 0x0000ffff, /* src_mask */
1433 0x0000ffff, /* dst_mask */
1434 FALSE), /* pcrel_offset */
1436 /* TLS IE dynamic relocations. */
1437 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
1439 HOWTO (R_MIPS_TLS_TPREL64, /* type */
1440 0, /* rightshift */
1441 4, /* size (0 = byte, 1 = short, 2 = long) */
1442 64, /* bitsize */
1443 FALSE, /* pc_relative */
1444 0, /* bitpos */
1445 complain_overflow_dont, /* complain_on_overflow */
1446 _bfd_mips_elf_generic_reloc, /* special_function */
1447 "R_MIPS_TLS_TPREL64", /* name */
1448 FALSE, /* partial_inplace */
1449 MINUS_ONE, /* src_mask */
1450 MINUS_ONE, /* dst_mask */
1451 FALSE), /* pcrel_offset */
1453 /* TLS thread pointer offset. */
1454 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
1455 0, /* rightshift */
1456 2, /* size (0 = byte, 1 = short, 2 = long) */
1457 16, /* bitsize */
1458 FALSE, /* pc_relative */
1459 0, /* bitpos */
1460 complain_overflow_signed, /* complain_on_overflow */
1461 _bfd_mips_elf_generic_reloc, /* special_function */
1462 "R_MIPS_TLS_TPREL_HI16", /* name */
1463 FALSE, /* partial_inplace */
1464 0x0000ffff, /* src_mask */
1465 0x0000ffff, /* dst_mask */
1466 FALSE), /* pcrel_offset */
1468 /* TLS thread pointer offset. */
1469 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
1470 0, /* rightshift */
1471 2, /* size (0 = byte, 1 = short, 2 = long) */
1472 16, /* bitsize */
1473 FALSE, /* pc_relative */
1474 0, /* bitpos */
1475 complain_overflow_signed, /* complain_on_overflow */
1476 _bfd_mips_elf_generic_reloc, /* special_function */
1477 "R_MIPS_TLS_TPREL_LO16", /* name */
1478 FALSE, /* partial_inplace */
1479 0x0000ffff, /* src_mask */
1480 0x0000ffff, /* dst_mask */
1481 FALSE), /* pcrel_offset */
1483 /* 32 bit relocation with no addend. */
1484 HOWTO (R_MIPS_GLOB_DAT, /* type */
1485 0, /* rightshift */
1486 2, /* size (0 = byte, 1 = short, 2 = long) */
1487 32, /* bitsize */
1488 FALSE, /* pc_relative */
1489 0, /* bitpos */
1490 complain_overflow_dont, /* complain_on_overflow */
1491 _bfd_mips_elf_generic_reloc, /* special_function */
1492 "R_MIPS_GLOB_DAT", /* name */
1493 FALSE, /* partial_inplace */
1494 0x0, /* src_mask */
1495 0xffffffff, /* dst_mask */
1496 FALSE), /* pcrel_offset */
1499 static reloc_howto_type mips16_elf64_howto_table_rel[] =
1501 /* The reloc used for the mips16 jump instruction. */
1502 HOWTO (R_MIPS16_26, /* type */
1503 2, /* rightshift */
1504 2, /* size (0 = byte, 1 = short, 2 = long) */
1505 26, /* bitsize */
1506 FALSE, /* pc_relative */
1507 0, /* bitpos */
1508 complain_overflow_dont, /* complain_on_overflow */
1509 /* This needs complex overflow
1510 detection, because the upper four
1511 bits must match the PC. */
1512 _bfd_mips_elf_generic_reloc, /* special_function */
1513 "R_MIPS16_26", /* name */
1514 TRUE, /* partial_inplace */
1515 0x3ffffff, /* src_mask */
1516 0x3ffffff, /* dst_mask */
1517 FALSE), /* pcrel_offset */
1519 /* The reloc used for the mips16 gprel instruction. */
1520 HOWTO (R_MIPS16_GPREL, /* type */
1521 0, /* rightshift */
1522 2, /* size (0 = byte, 1 = short, 2 = long) */
1523 16, /* bitsize */
1524 FALSE, /* pc_relative */
1525 0, /* bitpos */
1526 complain_overflow_signed, /* complain_on_overflow */
1527 mips16_gprel_reloc, /* special_function */
1528 "R_MIPS16_GPREL", /* name */
1529 TRUE, /* partial_inplace */
1530 0x0000ffff, /* src_mask */
1531 0x0000ffff, /* dst_mask */
1532 FALSE), /* pcrel_offset */
1534 /* A MIPS16 reference to the global offset table. */
1535 HOWTO (R_MIPS16_GOT16, /* type */
1536 0, /* rightshift */
1537 2, /* size (0 = byte, 1 = short, 2 = long) */
1538 16, /* bitsize */
1539 FALSE, /* pc_relative */
1540 0, /* bitpos */
1541 complain_overflow_dont, /* complain_on_overflow */
1542 _bfd_mips_elf_got16_reloc, /* special_function */
1543 "R_MIPS16_GOT16", /* name */
1544 TRUE, /* partial_inplace */
1545 0x0000ffff, /* src_mask */
1546 0x0000ffff, /* dst_mask */
1547 FALSE), /* pcrel_offset */
1549 /* A MIPS16 call through the global offset table. */
1550 HOWTO (R_MIPS16_CALL16, /* type */
1551 0, /* rightshift */
1552 2, /* size (0 = byte, 1 = short, 2 = long) */
1553 16, /* bitsize */
1554 FALSE, /* pc_relative */
1555 0, /* bitpos */
1556 complain_overflow_dont, /* complain_on_overflow */
1557 _bfd_mips_elf_generic_reloc, /* special_function */
1558 "R_MIPS16_CALL16", /* name */
1559 TRUE, /* partial_inplace */
1560 0x0000ffff, /* src_mask */
1561 0x0000ffff, /* dst_mask */
1562 FALSE), /* pcrel_offset */
1564 /* MIPS16 high 16 bits of symbol value. */
1565 HOWTO (R_MIPS16_HI16, /* type */
1566 16, /* rightshift */
1567 2, /* size (0 = byte, 1 = short, 2 = long) */
1568 16, /* bitsize */
1569 FALSE, /* pc_relative */
1570 0, /* bitpos */
1571 complain_overflow_dont, /* complain_on_overflow */
1572 _bfd_mips_elf_hi16_reloc, /* special_function */
1573 "R_MIPS16_HI16", /* name */
1574 TRUE, /* partial_inplace */
1575 0x0000ffff, /* src_mask */
1576 0x0000ffff, /* dst_mask */
1577 FALSE), /* pcrel_offset */
1579 /* MIPS16 low 16 bits of symbol value. */
1580 HOWTO (R_MIPS16_LO16, /* type */
1581 0, /* rightshift */
1582 2, /* size (0 = byte, 1 = short, 2 = long) */
1583 16, /* bitsize */
1584 FALSE, /* pc_relative */
1585 0, /* bitpos */
1586 complain_overflow_dont, /* complain_on_overflow */
1587 _bfd_mips_elf_lo16_reloc, /* special_function */
1588 "R_MIPS16_LO16", /* name */
1589 TRUE, /* partial_inplace */
1590 0x0000ffff, /* src_mask */
1591 0x0000ffff, /* dst_mask */
1592 FALSE), /* pcrel_offset */
1595 static reloc_howto_type mips16_elf64_howto_table_rela[] =
1597 /* The reloc used for the mips16 jump instruction. */
1598 HOWTO (R_MIPS16_26, /* type */
1599 2, /* rightshift */
1600 2, /* size (0 = byte, 1 = short, 2 = long) */
1601 26, /* bitsize */
1602 FALSE, /* pc_relative */
1603 0, /* bitpos */
1604 complain_overflow_dont, /* complain_on_overflow */
1605 /* This needs complex overflow
1606 detection, because the upper four
1607 bits must match the PC. */
1608 _bfd_mips_elf_generic_reloc, /* special_function */
1609 "R_MIPS16_26", /* name */
1610 FALSE, /* partial_inplace */
1611 0x3ffffff, /* src_mask */
1612 0x3ffffff, /* dst_mask */
1613 FALSE), /* pcrel_offset */
1615 /* The reloc used for the mips16 gprel instruction. */
1616 HOWTO (R_MIPS16_GPREL, /* type */
1617 0, /* rightshift */
1618 2, /* size (0 = byte, 1 = short, 2 = long) */
1619 16, /* bitsize */
1620 FALSE, /* pc_relative */
1621 0, /* bitpos */
1622 complain_overflow_signed, /* complain_on_overflow */
1623 mips16_gprel_reloc, /* special_function */
1624 "R_MIPS16_GPREL", /* name */
1625 FALSE, /* partial_inplace */
1626 0x0000ffff, /* src_mask */
1627 0x0000ffff, /* dst_mask */
1628 FALSE), /* pcrel_offset */
1630 /* A MIPS16 reference to the global offset table. */
1631 HOWTO (R_MIPS16_GOT16, /* type */
1632 0, /* rightshift */
1633 2, /* size (0 = byte, 1 = short, 2 = long) */
1634 16, /* bitsize */
1635 FALSE, /* pc_relative */
1636 0, /* bitpos */
1637 complain_overflow_dont, /* complain_on_overflow */
1638 _bfd_mips_elf_got16_reloc, /* special_function */
1639 "R_MIPS16_GOT16", /* name */
1640 FALSE, /* partial_inplace */
1641 0x0000ffff, /* src_mask */
1642 0x0000ffff, /* dst_mask */
1643 FALSE), /* pcrel_offset */
1645 /* A MIPS16 call through the global offset table. */
1646 HOWTO (R_MIPS16_CALL16, /* type */
1647 0, /* rightshift */
1648 2, /* size (0 = byte, 1 = short, 2 = long) */
1649 16, /* bitsize */
1650 FALSE, /* pc_relative */
1651 0, /* bitpos */
1652 complain_overflow_dont, /* complain_on_overflow */
1653 _bfd_mips_elf_generic_reloc, /* special_function */
1654 "R_MIPS16_CALL16", /* name */
1655 FALSE, /* partial_inplace */
1656 0x0000ffff, /* src_mask */
1657 0x0000ffff, /* dst_mask */
1658 FALSE), /* pcrel_offset */
1660 /* MIPS16 high 16 bits of symbol value. */
1661 HOWTO (R_MIPS16_HI16, /* type */
1662 16, /* rightshift */
1663 2, /* size (0 = byte, 1 = short, 2 = long) */
1664 16, /* bitsize */
1665 FALSE, /* pc_relative */
1666 0, /* bitpos */
1667 complain_overflow_dont, /* complain_on_overflow */
1668 _bfd_mips_elf_hi16_reloc, /* special_function */
1669 "R_MIPS16_HI16", /* name */
1670 FALSE, /* partial_inplace */
1671 0x0000ffff, /* src_mask */
1672 0x0000ffff, /* dst_mask */
1673 FALSE), /* pcrel_offset */
1675 /* MIPS16 low 16 bits of symbol value. */
1676 HOWTO (R_MIPS16_LO16, /* type */
1677 0, /* rightshift */
1678 2, /* size (0 = byte, 1 = short, 2 = long) */
1679 16, /* bitsize */
1680 FALSE, /* pc_relative */
1681 0, /* bitpos */
1682 complain_overflow_dont, /* complain_on_overflow */
1683 _bfd_mips_elf_lo16_reloc, /* special_function */
1684 "R_MIPS16_LO16", /* name */
1685 FALSE, /* partial_inplace */
1686 0x0000ffff, /* src_mask */
1687 0x0000ffff, /* dst_mask */
1688 FALSE), /* pcrel_offset */
1691 /* GNU extension to record C++ vtable hierarchy */
1692 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
1693 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
1694 0, /* rightshift */
1695 2, /* size (0 = byte, 1 = short, 2 = long) */
1696 0, /* bitsize */
1697 FALSE, /* pc_relative */
1698 0, /* bitpos */
1699 complain_overflow_dont, /* complain_on_overflow */
1700 NULL, /* special_function */
1701 "R_MIPS_GNU_VTINHERIT", /* name */
1702 FALSE, /* partial_inplace */
1703 0, /* src_mask */
1704 0, /* dst_mask */
1705 FALSE); /* pcrel_offset */
1707 /* GNU extension to record C++ vtable member usage */
1708 static reloc_howto_type elf_mips_gnu_vtentry_howto =
1709 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
1710 0, /* rightshift */
1711 2, /* size (0 = byte, 1 = short, 2 = long) */
1712 0, /* bitsize */
1713 FALSE, /* pc_relative */
1714 0, /* bitpos */
1715 complain_overflow_dont, /* complain_on_overflow */
1716 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1717 "R_MIPS_GNU_VTENTRY", /* name */
1718 FALSE, /* partial_inplace */
1719 0, /* src_mask */
1720 0, /* dst_mask */
1721 FALSE); /* pcrel_offset */
1723 /* 16 bit offset for pc-relative branches. */
1724 static reloc_howto_type elf_mips_gnu_rel16_s2 =
1725 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
1726 2, /* rightshift */
1727 2, /* size (0 = byte, 1 = short, 2 = long) */
1728 16, /* bitsize */
1729 TRUE, /* pc_relative */
1730 0, /* bitpos */
1731 complain_overflow_signed, /* complain_on_overflow */
1732 _bfd_mips_elf_generic_reloc, /* special_function */
1733 "R_MIPS_GNU_REL16_S2", /* name */
1734 TRUE, /* partial_inplace */
1735 0x0000ffff, /* src_mask */
1736 0x0000ffff, /* dst_mask */
1737 TRUE); /* pcrel_offset */
1739 /* 16 bit offset for pc-relative branches. */
1740 static reloc_howto_type elf_mips_gnu_rela16_s2 =
1741 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
1742 2, /* rightshift */
1743 2, /* size (0 = byte, 1 = short, 2 = long) */
1744 16, /* bitsize */
1745 TRUE, /* pc_relative */
1746 0, /* bitpos */
1747 complain_overflow_signed, /* complain_on_overflow */
1748 _bfd_mips_elf_generic_reloc, /* special_function */
1749 "R_MIPS_GNU_REL16_S2", /* name */
1750 FALSE, /* partial_inplace */
1751 0, /* src_mask */
1752 0x0000ffff, /* dst_mask */
1753 TRUE); /* pcrel_offset */
1755 /* Originally a VxWorks extension, but now used for other systems too. */
1756 static reloc_howto_type elf_mips_copy_howto =
1757 HOWTO (R_MIPS_COPY, /* type */
1758 0, /* rightshift */
1759 0, /* this one is variable size */
1760 0, /* bitsize */
1761 FALSE, /* pc_relative */
1762 0, /* bitpos */
1763 complain_overflow_bitfield, /* complain_on_overflow */
1764 bfd_elf_generic_reloc, /* special_function */
1765 "R_MIPS_COPY", /* name */
1766 FALSE, /* partial_inplace */
1767 0x0, /* src_mask */
1768 0x0, /* dst_mask */
1769 FALSE); /* pcrel_offset */
1771 /* Originally a VxWorks extension, but now used for other systems too. */
1772 static reloc_howto_type elf_mips_jump_slot_howto =
1773 HOWTO (R_MIPS_JUMP_SLOT, /* type */
1774 0, /* rightshift */
1775 4, /* size (0 = byte, 1 = short, 2 = long) */
1776 64, /* bitsize */
1777 FALSE, /* pc_relative */
1778 0, /* bitpos */
1779 complain_overflow_bitfield, /* complain_on_overflow */
1780 bfd_elf_generic_reloc, /* special_function */
1781 "R_MIPS_JUMP_SLOT", /* name */
1782 FALSE, /* partial_inplace */
1783 0x0, /* src_mask */
1784 0x0, /* dst_mask */
1785 FALSE); /* pcrel_offset */
1787 /* Swap in a MIPS 64-bit Rel reloc. */
1789 static void
1790 mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src,
1791 Elf64_Mips_Internal_Rela *dst)
1793 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1794 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1795 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1796 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1797 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1798 dst->r_type = H_GET_8 (abfd, src->r_type);
1799 dst->r_addend = 0;
1802 /* Swap in a MIPS 64-bit Rela reloc. */
1804 static void
1805 mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src,
1806 Elf64_Mips_Internal_Rela *dst)
1808 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1809 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1810 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1811 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1812 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1813 dst->r_type = H_GET_8 (abfd, src->r_type);
1814 dst->r_addend = H_GET_S64 (abfd, src->r_addend);
1817 /* Swap out a MIPS 64-bit Rel reloc. */
1819 static void
1820 mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1821 Elf64_Mips_External_Rel *dst)
1823 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1824 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1825 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1826 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1827 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1828 H_PUT_8 (abfd, src->r_type, dst->r_type);
1831 /* Swap out a MIPS 64-bit Rela reloc. */
1833 static void
1834 mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1835 Elf64_Mips_External_Rela *dst)
1837 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1838 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1839 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1840 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1841 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1842 H_PUT_8 (abfd, src->r_type, dst->r_type);
1843 H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
1846 /* Swap in a MIPS 64-bit Rel reloc. */
1848 static void
1849 mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src,
1850 Elf_Internal_Rela *dst)
1852 Elf64_Mips_Internal_Rela mirel;
1854 mips_elf64_swap_reloc_in (abfd,
1855 (const Elf64_Mips_External_Rel *) src,
1856 &mirel);
1858 dst[0].r_offset = mirel.r_offset;
1859 dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
1860 dst[0].r_addend = 0;
1861 dst[1].r_offset = mirel.r_offset;
1862 dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
1863 dst[1].r_addend = 0;
1864 dst[2].r_offset = mirel.r_offset;
1865 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
1866 dst[2].r_addend = 0;
1869 /* Swap in a MIPS 64-bit Rela reloc. */
1871 static void
1872 mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src,
1873 Elf_Internal_Rela *dst)
1875 Elf64_Mips_Internal_Rela mirela;
1877 mips_elf64_swap_reloca_in (abfd,
1878 (const Elf64_Mips_External_Rela *) src,
1879 &mirela);
1881 dst[0].r_offset = mirela.r_offset;
1882 dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
1883 dst[0].r_addend = mirela.r_addend;
1884 dst[1].r_offset = mirela.r_offset;
1885 dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
1886 dst[1].r_addend = 0;
1887 dst[2].r_offset = mirela.r_offset;
1888 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
1889 dst[2].r_addend = 0;
1892 /* Swap out a MIPS 64-bit Rel reloc. */
1894 static void
1895 mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src,
1896 bfd_byte *dst)
1898 Elf64_Mips_Internal_Rela mirel;
1900 mirel.r_offset = src[0].r_offset;
1901 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1903 mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1904 mirel.r_sym = ELF64_R_SYM (src[0].r_info);
1905 mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1906 mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1907 mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1909 mips_elf64_swap_reloc_out (abfd, &mirel,
1910 (Elf64_Mips_External_Rel *) dst);
1913 /* Swap out a MIPS 64-bit Rela reloc. */
1915 static void
1916 mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
1917 bfd_byte *dst)
1919 Elf64_Mips_Internal_Rela mirela;
1921 mirela.r_offset = src[0].r_offset;
1922 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1923 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
1925 mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1926 mirela.r_sym = ELF64_R_SYM (src[0].r_info);
1927 mirela.r_addend = src[0].r_addend;
1928 BFD_ASSERT(src[1].r_addend == 0);
1929 BFD_ASSERT(src[2].r_addend == 0);
1931 mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1932 mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1933 mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1935 mips_elf64_swap_reloca_out (abfd, &mirela,
1936 (Elf64_Mips_External_Rela *) dst);
1939 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1940 dangerous relocation. */
1942 static bfd_boolean
1943 mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp)
1945 unsigned int count;
1946 asymbol **sym;
1947 unsigned int i;
1949 /* If we've already figured out what GP will be, just return it. */
1950 *pgp = _bfd_get_gp_value (output_bfd);
1951 if (*pgp)
1952 return TRUE;
1954 count = bfd_get_symcount (output_bfd);
1955 sym = bfd_get_outsymbols (output_bfd);
1957 /* The linker script will have created a symbol named `_gp' with the
1958 appropriate value. */
1959 if (sym == NULL)
1960 i = count;
1961 else
1963 for (i = 0; i < count; i++, sym++)
1965 register const char *name;
1967 name = bfd_asymbol_name (*sym);
1968 if (*name == '_' && strcmp (name, "_gp") == 0)
1970 *pgp = bfd_asymbol_value (*sym);
1971 _bfd_set_gp_value (output_bfd, *pgp);
1972 break;
1977 if (i >= count)
1979 /* Only get the error once. */
1980 *pgp = 4;
1981 _bfd_set_gp_value (output_bfd, *pgp);
1982 return FALSE;
1985 return TRUE;
1988 /* We have to figure out the gp value, so that we can adjust the
1989 symbol value correctly. We look up the symbol _gp in the output
1990 BFD. If we can't find it, we're stuck. We cache it in the ELF
1991 target data. We don't need to adjust the symbol value for an
1992 external symbol if we are producing relocatable output. */
1994 static bfd_reloc_status_type
1995 mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
1996 char **error_message, bfd_vma *pgp)
1998 if (bfd_is_und_section (symbol->section)
1999 && ! relocatable)
2001 *pgp = 0;
2002 return bfd_reloc_undefined;
2005 *pgp = _bfd_get_gp_value (output_bfd);
2006 if (*pgp == 0
2007 && (! relocatable
2008 || (symbol->flags & BSF_SECTION_SYM) != 0))
2010 if (relocatable)
2012 /* Make up a value. */
2013 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
2014 _bfd_set_gp_value (output_bfd, *pgp);
2016 else if (!mips_elf64_assign_gp (output_bfd, pgp))
2018 *error_message =
2019 (char *) _("GP relative relocation when _gp not defined");
2020 return bfd_reloc_dangerous;
2024 return bfd_reloc_ok;
2027 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
2028 become the offset from the gp register. */
2030 static bfd_reloc_status_type
2031 mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2032 void *data, asection *input_section, bfd *output_bfd,
2033 char **error_message)
2035 bfd_boolean relocatable;
2036 bfd_reloc_status_type ret;
2037 bfd_vma gp;
2039 /* If we're relocating, and this is an external symbol, we don't want
2040 to change anything. */
2041 if (output_bfd != NULL
2042 && (symbol->flags & BSF_SECTION_SYM) == 0
2043 && (symbol->flags & BSF_LOCAL) != 0)
2045 reloc_entry->address += input_section->output_offset;
2046 return bfd_reloc_ok;
2049 if (output_bfd != NULL)
2050 relocatable = TRUE;
2051 else
2053 relocatable = FALSE;
2054 output_bfd = symbol->section->output_section->owner;
2057 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
2058 &gp);
2059 if (ret != bfd_reloc_ok)
2060 return ret;
2062 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2063 input_section, relocatable,
2064 data, gp);
2067 /* Do a R_MIPS_LITERAL relocation. */
2069 static bfd_reloc_status_type
2070 mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2071 void *data, asection *input_section, bfd *output_bfd,
2072 char **error_message)
2074 bfd_boolean relocatable;
2075 bfd_reloc_status_type ret;
2076 bfd_vma gp;
2078 /* R_MIPS_LITERAL relocations are defined for local symbols only. */
2079 if (output_bfd != NULL
2080 && (symbol->flags & BSF_SECTION_SYM) == 0
2081 && (symbol->flags & BSF_LOCAL) != 0)
2083 *error_message = (char *)
2084 _("literal relocation occurs for an external symbol");
2085 return bfd_reloc_outofrange;
2088 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
2089 if (output_bfd != NULL)
2090 relocatable = TRUE;
2091 else
2093 relocatable = FALSE;
2094 output_bfd = symbol->section->output_section->owner;
2097 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
2098 &gp);
2099 if (ret != bfd_reloc_ok)
2100 return ret;
2102 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2103 input_section, relocatable,
2104 data, gp);
2107 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
2108 become the offset from the gp register. */
2110 static bfd_reloc_status_type
2111 mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2112 void *data, asection *input_section, bfd *output_bfd,
2113 char **error_message)
2115 bfd_boolean relocatable;
2116 bfd_reloc_status_type ret;
2117 bfd_vma gp;
2118 bfd_vma relocation;
2119 bfd_vma val;
2121 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
2122 if (output_bfd != NULL
2123 && (symbol->flags & BSF_SECTION_SYM) == 0
2124 && (symbol->flags & BSF_LOCAL) != 0)
2126 *error_message = (char *)
2127 _("32bits gp relative relocation occurs for an external symbol");
2128 return bfd_reloc_outofrange;
2131 if (output_bfd != NULL)
2132 relocatable = TRUE;
2133 else
2135 relocatable = FALSE;
2136 output_bfd = symbol->section->output_section->owner;
2139 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
2140 error_message, &gp);
2141 if (ret != bfd_reloc_ok)
2142 return ret;
2144 if (bfd_is_com_section (symbol->section))
2145 relocation = 0;
2146 else
2147 relocation = symbol->value;
2149 relocation += symbol->section->output_section->vma;
2150 relocation += symbol->section->output_offset;
2152 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
2153 return bfd_reloc_outofrange;
2155 /* Set val to the offset into the section or symbol. */
2156 val = reloc_entry->addend;
2158 if (reloc_entry->howto->partial_inplace)
2159 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
2161 /* Adjust val for the final section location and GP value. If we
2162 are producing relocatable output, we don't want to do this for
2163 an external symbol. */
2164 if (! relocatable
2165 || (symbol->flags & BSF_SECTION_SYM) != 0)
2166 val += relocation - gp;
2168 if (reloc_entry->howto->partial_inplace)
2169 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
2170 else
2171 reloc_entry->addend = val;
2173 if (relocatable)
2174 reloc_entry->address += input_section->output_offset;
2176 return bfd_reloc_ok;
2179 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
2180 the rest is at bits 6-10. The bitpos already got right by the howto. */
2182 static bfd_reloc_status_type
2183 mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2184 void *data, asection *input_section, bfd *output_bfd,
2185 char **error_message)
2187 if (reloc_entry->howto->partial_inplace)
2189 reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
2190 | (reloc_entry->addend & 0x00000800) >> 9);
2193 return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
2194 input_section, output_bfd,
2195 error_message);
2198 /* Handle a mips16 GP relative reloc. */
2200 static bfd_reloc_status_type
2201 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2202 void *data, asection *input_section, bfd *output_bfd,
2203 char **error_message)
2205 bfd_boolean relocatable;
2206 bfd_reloc_status_type ret;
2207 bfd_byte *location;
2208 bfd_vma gp;
2210 /* If we're relocating, and this is an external symbol, we don't want
2211 to change anything. */
2212 if (output_bfd != NULL
2213 && (symbol->flags & BSF_SECTION_SYM) == 0
2214 && (symbol->flags & BSF_LOCAL) != 0)
2216 reloc_entry->address += input_section->output_offset;
2217 return bfd_reloc_ok;
2220 if (output_bfd != NULL)
2221 relocatable = TRUE;
2222 else
2224 relocatable = FALSE;
2225 output_bfd = symbol->section->output_section->owner;
2228 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
2229 &gp);
2230 if (ret != bfd_reloc_ok)
2231 return ret;
2233 location = (bfd_byte *) data + reloc_entry->address;
2234 _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
2235 location);
2236 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2237 input_section, relocatable,
2238 data, gp);
2239 _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
2240 location);
2242 return ret;
2245 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
2247 struct elf_reloc_map {
2248 bfd_reloc_code_real_type bfd_val;
2249 enum elf_mips_reloc_type elf_val;
2252 static const struct elf_reloc_map mips_reloc_map[] =
2254 { BFD_RELOC_NONE, R_MIPS_NONE },
2255 { BFD_RELOC_16, R_MIPS_16 },
2256 { BFD_RELOC_32, R_MIPS_32 },
2257 /* There is no BFD reloc for R_MIPS_REL32. */
2258 { BFD_RELOC_64, R_MIPS_64 },
2259 { BFD_RELOC_CTOR, R_MIPS_64 },
2260 { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
2261 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
2262 { BFD_RELOC_LO16, R_MIPS_LO16 },
2263 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
2264 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
2265 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
2266 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
2267 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
2268 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
2269 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
2270 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
2271 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
2272 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
2273 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
2274 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
2275 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
2276 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
2277 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
2278 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
2279 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
2280 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
2281 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
2282 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
2283 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
2284 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
2285 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
2286 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
2287 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
2288 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
2289 { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
2290 { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
2291 { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
2292 { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
2293 { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
2294 { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
2295 { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
2296 { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
2297 { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
2298 { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
2299 { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
2300 { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
2301 { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
2304 static const struct elf_reloc_map mips16_reloc_map[] =
2306 { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
2307 { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
2308 { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
2309 { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
2310 { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
2311 { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
2314 /* Given a BFD reloc type, return a howto structure. */
2316 static reloc_howto_type *
2317 bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
2318 bfd_reloc_code_real_type code)
2320 unsigned int i;
2321 /* FIXME: We default to RELA here instead of choosing the right
2322 relocation variant. */
2323 reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
2324 reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela;
2326 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
2327 i++)
2329 if (mips_reloc_map[i].bfd_val == code)
2330 return &howto_table[(int) mips_reloc_map[i].elf_val];
2333 for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
2334 i++)
2336 if (mips16_reloc_map[i].bfd_val == code)
2337 return &howto16_table[(int) mips16_reloc_map[i].elf_val];
2340 switch (code)
2342 case BFD_RELOC_VTABLE_INHERIT:
2343 return &elf_mips_gnu_vtinherit_howto;
2344 case BFD_RELOC_VTABLE_ENTRY:
2345 return &elf_mips_gnu_vtentry_howto;
2346 case BFD_RELOC_MIPS_COPY:
2347 return &elf_mips_copy_howto;
2348 case BFD_RELOC_MIPS_JUMP_SLOT:
2349 return &elf_mips_jump_slot_howto;
2350 default:
2351 bfd_set_error (bfd_error_bad_value);
2352 return NULL;
2356 static reloc_howto_type *
2357 bfd_elf64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
2358 const char *r_name)
2360 unsigned int i;
2362 for (i = 0;
2363 i < (sizeof (mips_elf64_howto_table_rela)
2364 / sizeof (mips_elf64_howto_table_rela[0])); i++)
2365 if (mips_elf64_howto_table_rela[i].name != NULL
2366 && strcasecmp (mips_elf64_howto_table_rela[i].name, r_name) == 0)
2367 return &mips_elf64_howto_table_rela[i];
2369 for (i = 0;
2370 i < (sizeof (mips16_elf64_howto_table_rela)
2371 / sizeof (mips16_elf64_howto_table_rela[0]));
2372 i++)
2373 if (mips16_elf64_howto_table_rela[i].name != NULL
2374 && strcasecmp (mips16_elf64_howto_table_rela[i].name, r_name) == 0)
2375 return &mips16_elf64_howto_table_rela[i];
2377 if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
2378 return &elf_mips_gnu_vtinherit_howto;
2379 if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
2380 return &elf_mips_gnu_vtentry_howto;
2381 if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
2382 return &elf_mips_gnu_rel16_s2;
2383 if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
2384 return &elf_mips_gnu_rela16_s2;
2385 if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
2386 return &elf_mips_copy_howto;
2387 if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
2388 return &elf_mips_jump_slot_howto;
2390 return NULL;
2393 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
2395 static reloc_howto_type *
2396 mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
2398 switch (r_type)
2400 case R_MIPS_GNU_VTINHERIT:
2401 return &elf_mips_gnu_vtinherit_howto;
2402 case R_MIPS_GNU_VTENTRY:
2403 return &elf_mips_gnu_vtentry_howto;
2404 case R_MIPS_GNU_REL16_S2:
2405 if (rela_p)
2406 return &elf_mips_gnu_rela16_s2;
2407 else
2408 return &elf_mips_gnu_rel16_s2;
2409 case R_MIPS_COPY:
2410 return &elf_mips_copy_howto;
2411 case R_MIPS_JUMP_SLOT:
2412 return &elf_mips_jump_slot_howto;
2413 default:
2414 if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
2416 if (rela_p)
2417 return &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min];
2418 else
2419 return &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min];
2421 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
2422 if (rela_p)
2423 return &mips_elf64_howto_table_rela[r_type];
2424 else
2425 return &mips_elf64_howto_table_rel[r_type];
2426 break;
2430 /* Prevent relocation handling by bfd for MIPS ELF64. */
2432 static void
2433 mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
2434 arelent *cache_ptr ATTRIBUTE_UNUSED,
2435 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
2437 BFD_ASSERT (0);
2440 static void
2441 mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
2442 arelent *cache_ptr ATTRIBUTE_UNUSED,
2443 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
2445 BFD_ASSERT (0);
2448 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
2449 to three relocs, we must tell the user to allocate more space. */
2451 static long
2452 mips_elf64_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
2454 return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
2457 static long
2458 mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
2460 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
2463 /* We must also copy more relocations than the corresponding functions
2464 in elf.c would, so the two following functions are slightly
2465 modified from elf.c, that multiply the external relocation count by
2466 3 to obtain the internal relocation count. */
2468 static long
2469 mips_elf64_canonicalize_reloc (bfd *abfd, sec_ptr section,
2470 arelent **relptr, asymbol **symbols)
2472 arelent *tblptr;
2473 unsigned int i;
2474 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
2476 if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
2477 return -1;
2479 tblptr = section->relocation;
2480 for (i = 0; i < section->reloc_count * 3; i++)
2481 *relptr++ = tblptr++;
2483 *relptr = NULL;
2485 return section->reloc_count * 3;
2488 static long
2489 mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
2490 asymbol **syms)
2492 bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
2493 asection *s;
2494 long ret;
2496 if (elf_dynsymtab (abfd) == 0)
2498 bfd_set_error (bfd_error_invalid_operation);
2499 return -1;
2502 slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
2503 ret = 0;
2504 for (s = abfd->sections; s != NULL; s = s->next)
2506 if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
2507 && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
2508 || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
2510 arelent *p;
2511 long count, i;
2513 if (! (*slurp_relocs) (abfd, s, syms, TRUE))
2514 return -1;
2515 count = s->size / elf_section_data (s)->this_hdr.sh_entsize * 3;
2516 p = s->relocation;
2517 for (i = 0; i < count; i++)
2518 *storage++ = p++;
2519 ret += count;
2523 *storage = NULL;
2525 return ret;
2528 /* Read the relocations from one reloc section. This is mostly copied
2529 from elfcode.h, except for the changes to expand one external
2530 relocation to 3 internal ones. We must unfortunately set
2531 reloc_count to the number of external relocations, because a lot of
2532 generic code seems to depend on this. */
2534 static bfd_boolean
2535 mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
2536 Elf_Internal_Shdr *rel_hdr,
2537 bfd_size_type reloc_count,
2538 arelent *relents, asymbol **symbols,
2539 bfd_boolean dynamic)
2541 void *allocated;
2542 bfd_byte *native_relocs;
2543 arelent *relent;
2544 bfd_vma i;
2545 int entsize;
2546 bfd_boolean rela_p;
2548 allocated = bfd_malloc (rel_hdr->sh_size);
2549 if (allocated == NULL)
2550 return FALSE;
2552 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
2553 || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
2554 != rel_hdr->sh_size))
2555 goto error_return;
2557 native_relocs = allocated;
2559 entsize = rel_hdr->sh_entsize;
2560 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
2561 || entsize == sizeof (Elf64_Mips_External_Rela));
2563 if (entsize == sizeof (Elf64_Mips_External_Rel))
2564 rela_p = FALSE;
2565 else
2566 rela_p = TRUE;
2568 for (i = 0, relent = relents;
2569 i < reloc_count;
2570 i++, native_relocs += entsize)
2572 Elf64_Mips_Internal_Rela rela;
2573 bfd_boolean used_sym, used_ssym;
2574 int ir;
2576 if (entsize == sizeof (Elf64_Mips_External_Rela))
2577 mips_elf64_swap_reloca_in (abfd,
2578 (Elf64_Mips_External_Rela *) native_relocs,
2579 &rela);
2580 else
2581 mips_elf64_swap_reloc_in (abfd,
2582 (Elf64_Mips_External_Rel *) native_relocs,
2583 &rela);
2585 /* Each entry represents exactly three actual relocations. */
2587 used_sym = FALSE;
2588 used_ssym = FALSE;
2589 for (ir = 0; ir < 3; ir++)
2591 enum elf_mips_reloc_type type;
2593 switch (ir)
2595 default:
2596 abort ();
2597 case 0:
2598 type = (enum elf_mips_reloc_type) rela.r_type;
2599 break;
2600 case 1:
2601 type = (enum elf_mips_reloc_type) rela.r_type2;
2602 break;
2603 case 2:
2604 type = (enum elf_mips_reloc_type) rela.r_type3;
2605 break;
2608 /* Some types require symbols, whereas some do not. */
2609 switch (type)
2611 case R_MIPS_NONE:
2612 case R_MIPS_LITERAL:
2613 case R_MIPS_INSERT_A:
2614 case R_MIPS_INSERT_B:
2615 case R_MIPS_DELETE:
2616 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2617 break;
2619 default:
2620 if (! used_sym)
2622 if (rela.r_sym == 0)
2623 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2624 else
2626 asymbol **ps, *s;
2628 ps = symbols + rela.r_sym - 1;
2629 s = *ps;
2630 if ((s->flags & BSF_SECTION_SYM) == 0)
2631 relent->sym_ptr_ptr = ps;
2632 else
2633 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
2636 used_sym = TRUE;
2638 else if (! used_ssym)
2640 switch (rela.r_ssym)
2642 case RSS_UNDEF:
2643 relent->sym_ptr_ptr =
2644 bfd_abs_section_ptr->symbol_ptr_ptr;
2645 break;
2647 case RSS_GP:
2648 case RSS_GP0:
2649 case RSS_LOC:
2650 /* FIXME: I think these need to be handled using
2651 special howto structures. */
2652 BFD_ASSERT (0);
2653 break;
2655 default:
2656 BFD_ASSERT (0);
2657 break;
2660 used_ssym = TRUE;
2662 else
2663 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2665 break;
2668 /* The address of an ELF reloc is section relative for an
2669 object file, and absolute for an executable file or
2670 shared library. The address of a BFD reloc is always
2671 section relative. */
2672 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
2673 relent->address = rela.r_offset;
2674 else
2675 relent->address = rela.r_offset - asect->vma;
2677 relent->addend = rela.r_addend;
2679 relent->howto = mips_elf64_rtype_to_howto (type, rela_p);
2681 ++relent;
2685 asect->reloc_count += (relent - relents) / 3;
2687 if (allocated != NULL)
2688 free (allocated);
2690 return TRUE;
2692 error_return:
2693 if (allocated != NULL)
2694 free (allocated);
2695 return FALSE;
2698 /* Read the relocations. On Irix 6, there can be two reloc sections
2699 associated with a single data section. This is copied from
2700 elfcode.h as well, with changes as small as accounting for 3
2701 internal relocs per external reloc and resetting reloc_count to
2702 zero before processing the relocs of a section. */
2704 static bfd_boolean
2705 mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
2706 asymbol **symbols, bfd_boolean dynamic)
2708 struct bfd_elf_section_data * const d = elf_section_data (asect);
2709 Elf_Internal_Shdr *rel_hdr;
2710 Elf_Internal_Shdr *rel_hdr2;
2711 bfd_size_type reloc_count;
2712 bfd_size_type reloc_count2;
2713 arelent *relents;
2714 bfd_size_type amt;
2716 if (asect->relocation != NULL)
2717 return TRUE;
2719 if (! dynamic)
2721 if ((asect->flags & SEC_RELOC) == 0
2722 || asect->reloc_count == 0)
2723 return TRUE;
2725 rel_hdr = &d->rel_hdr;
2726 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2727 rel_hdr2 = d->rel_hdr2;
2728 reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
2730 BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
2731 BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
2732 || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
2735 else
2737 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
2738 case because relocations against this section may use the
2739 dynamic symbol table, and in that case bfd_section_from_shdr
2740 in elf.c does not update the RELOC_COUNT. */
2741 if (asect->size == 0)
2742 return TRUE;
2744 rel_hdr = &d->this_hdr;
2745 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2746 rel_hdr2 = NULL;
2747 reloc_count2 = 0;
2750 /* Allocate space for 3 arelent structures for each Rel structure. */
2751 amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
2752 relents = bfd_alloc (abfd, amt);
2753 if (relents == NULL)
2754 return FALSE;
2756 /* The slurp_one_reloc_table routine increments reloc_count. */
2757 asect->reloc_count = 0;
2759 if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2760 rel_hdr, reloc_count,
2761 relents,
2762 symbols, dynamic))
2763 return FALSE;
2764 if (d->rel_hdr2 != NULL)
2766 if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2767 rel_hdr2, reloc_count2,
2768 relents + reloc_count * 3,
2769 symbols, dynamic))
2770 return FALSE;
2773 asect->relocation = relents;
2774 return TRUE;
2777 /* Write out the relocations. */
2779 static void
2780 mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
2782 bfd_boolean *failedp = data;
2783 int count;
2784 Elf_Internal_Shdr *rel_hdr;
2785 unsigned int idx;
2787 /* If we have already failed, don't do anything. */
2788 if (*failedp)
2789 return;
2791 if ((sec->flags & SEC_RELOC) == 0)
2792 return;
2794 /* The linker backend writes the relocs out itself, and sets the
2795 reloc_count field to zero to inhibit writing them here. Also,
2796 sometimes the SEC_RELOC flag gets set even when there aren't any
2797 relocs. */
2798 if (sec->reloc_count == 0)
2799 return;
2801 /* We can combine up to three relocs that refer to the same address
2802 if the latter relocs have no associated symbol. */
2803 count = 0;
2804 for (idx = 0; idx < sec->reloc_count; idx++)
2806 bfd_vma addr;
2807 unsigned int i;
2809 ++count;
2811 addr = sec->orelocation[idx]->address;
2812 for (i = 0; i < 2; i++)
2814 arelent *r;
2816 if (idx + 1 >= sec->reloc_count)
2817 break;
2818 r = sec->orelocation[idx + 1];
2819 if (r->address != addr
2820 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2821 || (*r->sym_ptr_ptr)->value != 0)
2822 break;
2824 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2826 ++idx;
2830 rel_hdr = &elf_section_data (sec)->rel_hdr;
2832 /* Do the actual relocation. */
2834 if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
2835 mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
2836 else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
2837 mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
2838 else
2839 BFD_ASSERT (0);
2842 static void
2843 mips_elf64_write_rel (bfd *abfd, asection *sec,
2844 Elf_Internal_Shdr *rel_hdr,
2845 int *count, void *data)
2847 bfd_boolean *failedp = data;
2848 Elf64_Mips_External_Rel *ext_rel;
2849 unsigned int idx;
2850 asymbol *last_sym = 0;
2851 int last_sym_idx = 0;
2853 rel_hdr->sh_size = rel_hdr->sh_entsize * *count;
2854 rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size);
2855 if (rel_hdr->contents == NULL)
2857 *failedp = TRUE;
2858 return;
2861 ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
2862 for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
2864 arelent *ptr;
2865 Elf64_Mips_Internal_Rela int_rel;
2866 asymbol *sym;
2867 int n;
2868 unsigned int i;
2870 ptr = sec->orelocation[idx];
2872 /* The address of an ELF reloc is section relative for an object
2873 file, and absolute for an executable file or shared library.
2874 The address of a BFD reloc is always section relative. */
2875 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2876 int_rel.r_offset = ptr->address;
2877 else
2878 int_rel.r_offset = ptr->address + sec->vma;
2880 sym = *ptr->sym_ptr_ptr;
2881 if (sym == last_sym)
2882 n = last_sym_idx;
2883 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2884 n = STN_UNDEF;
2885 else
2887 last_sym = sym;
2888 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2889 if (n < 0)
2891 *failedp = TRUE;
2892 return;
2894 last_sym_idx = n;
2897 int_rel.r_sym = n;
2898 int_rel.r_ssym = RSS_UNDEF;
2900 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2901 && ! _bfd_elf_validate_reloc (abfd, ptr))
2903 *failedp = TRUE;
2904 return;
2907 int_rel.r_type = ptr->howto->type;
2908 int_rel.r_type2 = (int) R_MIPS_NONE;
2909 int_rel.r_type3 = (int) R_MIPS_NONE;
2911 for (i = 0; i < 2; i++)
2913 arelent *r;
2915 if (idx + 1 >= sec->reloc_count)
2916 break;
2917 r = sec->orelocation[idx + 1];
2918 if (r->address != ptr->address
2919 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2920 || (*r->sym_ptr_ptr)->value != 0)
2921 break;
2923 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2925 if (i == 0)
2926 int_rel.r_type2 = r->howto->type;
2927 else
2928 int_rel.r_type3 = r->howto->type;
2930 ++idx;
2933 mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
2936 BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
2937 == *count);
2940 static void
2941 mips_elf64_write_rela (bfd *abfd, asection *sec,
2942 Elf_Internal_Shdr *rela_hdr,
2943 int *count, void *data)
2945 bfd_boolean *failedp = data;
2946 Elf64_Mips_External_Rela *ext_rela;
2947 unsigned int idx;
2948 asymbol *last_sym = 0;
2949 int last_sym_idx = 0;
2951 rela_hdr->sh_size = rela_hdr->sh_entsize * *count;
2952 rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
2953 if (rela_hdr->contents == NULL)
2955 *failedp = TRUE;
2956 return;
2959 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
2960 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
2962 arelent *ptr;
2963 Elf64_Mips_Internal_Rela int_rela;
2964 asymbol *sym;
2965 int n;
2966 unsigned int i;
2968 ptr = sec->orelocation[idx];
2970 /* The address of an ELF reloc is section relative for an object
2971 file, and absolute for an executable file or shared library.
2972 The address of a BFD reloc is always section relative. */
2973 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2974 int_rela.r_offset = ptr->address;
2975 else
2976 int_rela.r_offset = ptr->address + sec->vma;
2978 sym = *ptr->sym_ptr_ptr;
2979 if (sym == last_sym)
2980 n = last_sym_idx;
2981 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2982 n = STN_UNDEF;
2983 else
2985 last_sym = sym;
2986 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2987 if (n < 0)
2989 *failedp = TRUE;
2990 return;
2992 last_sym_idx = n;
2995 int_rela.r_sym = n;
2996 int_rela.r_addend = ptr->addend;
2997 int_rela.r_ssym = RSS_UNDEF;
2999 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
3000 && ! _bfd_elf_validate_reloc (abfd, ptr))
3002 *failedp = TRUE;
3003 return;
3006 int_rela.r_type = ptr->howto->type;
3007 int_rela.r_type2 = (int) R_MIPS_NONE;
3008 int_rela.r_type3 = (int) R_MIPS_NONE;
3010 for (i = 0; i < 2; i++)
3012 arelent *r;
3014 if (idx + 1 >= sec->reloc_count)
3015 break;
3016 r = sec->orelocation[idx + 1];
3017 if (r->address != ptr->address
3018 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
3019 || (*r->sym_ptr_ptr)->value != 0)
3020 break;
3022 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
3024 if (i == 0)
3025 int_rela.r_type2 = r->howto->type;
3026 else
3027 int_rela.r_type3 = r->howto->type;
3029 ++idx;
3032 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
3035 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
3036 == *count);
3039 /* Set the right machine number for a MIPS ELF file. */
3041 static bfd_boolean
3042 mips_elf64_object_p (bfd *abfd)
3044 unsigned long mach;
3046 /* Irix 6 is broken. Object file symbol tables are not always
3047 sorted correctly such that local symbols precede global symbols,
3048 and the sh_info field in the symbol table is not always right. */
3049 if (elf64_mips_irix_compat (abfd) != ict_none)
3050 elf_bad_symtab (abfd) = TRUE;
3052 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
3053 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
3054 return TRUE;
3057 /* Depending on the target vector we generate some version of Irix
3058 executables or "normal" MIPS ELF ABI executables. */
3059 static irix_compat_t
3060 elf64_mips_irix_compat (bfd *abfd)
3062 if ((abfd->xvec == &bfd_elf64_bigmips_vec)
3063 || (abfd->xvec == &bfd_elf64_littlemips_vec))
3064 return ict_irix6;
3065 else
3066 return ict_none;
3069 /* Support for core dump NOTE sections. */
3070 static bfd_boolean
3071 elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3073 int offset;
3074 unsigned int size;
3076 switch (note->descsz)
3078 default:
3079 return FALSE;
3081 case 480: /* Linux/MIPS - N64 kernel */
3082 /* pr_cursig */
3083 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
3085 /* pr_pid */
3086 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 32);
3088 /* pr_reg */
3089 offset = 112;
3090 size = 360;
3092 break;
3095 /* Make a ".reg/999" section. */
3096 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
3097 size, note->descpos + offset);
3100 static bfd_boolean
3101 elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3103 switch (note->descsz)
3105 default:
3106 return FALSE;
3108 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
3109 elf_tdata (abfd)->core_program
3110 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
3111 elf_tdata (abfd)->core_command
3112 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
3115 /* Note that for some reason, a spurious space is tacked
3116 onto the end of the args in some (at least one anyway)
3117 implementations, so strip it off if it exists. */
3120 char *command = elf_tdata (abfd)->core_command;
3121 int n = strlen (command);
3123 if (0 < n && command[n - 1] == ' ')
3124 command[n - 1] = '\0';
3127 return TRUE;
3130 /* ECOFF swapping routines. These are used when dealing with the
3131 .mdebug section, which is in the ECOFF debugging format. */
3132 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
3134 /* Symbol table magic number. */
3135 magicSym2,
3136 /* Alignment of debugging information. E.g., 4. */
3138 /* Sizes of external symbolic information. */
3139 sizeof (struct hdr_ext),
3140 sizeof (struct dnr_ext),
3141 sizeof (struct pdr_ext),
3142 sizeof (struct sym_ext),
3143 sizeof (struct opt_ext),
3144 sizeof (struct fdr_ext),
3145 sizeof (struct rfd_ext),
3146 sizeof (struct ext_ext),
3147 /* Functions to swap in external symbolic data. */
3148 ecoff_swap_hdr_in,
3149 ecoff_swap_dnr_in,
3150 ecoff_swap_pdr_in,
3151 ecoff_swap_sym_in,
3152 ecoff_swap_opt_in,
3153 ecoff_swap_fdr_in,
3154 ecoff_swap_rfd_in,
3155 ecoff_swap_ext_in,
3156 _bfd_ecoff_swap_tir_in,
3157 _bfd_ecoff_swap_rndx_in,
3158 /* Functions to swap out external symbolic data. */
3159 ecoff_swap_hdr_out,
3160 ecoff_swap_dnr_out,
3161 ecoff_swap_pdr_out,
3162 ecoff_swap_sym_out,
3163 ecoff_swap_opt_out,
3164 ecoff_swap_fdr_out,
3165 ecoff_swap_rfd_out,
3166 ecoff_swap_ext_out,
3167 _bfd_ecoff_swap_tir_out,
3168 _bfd_ecoff_swap_rndx_out,
3169 /* Function to read in symbolic data. */
3170 _bfd_mips_elf_read_ecoff_info
3173 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
3174 standard ELF. This structure is used to redirect the relocation
3175 handling routines. */
3177 const struct elf_size_info mips_elf64_size_info =
3179 sizeof (Elf64_External_Ehdr),
3180 sizeof (Elf64_External_Phdr),
3181 sizeof (Elf64_External_Shdr),
3182 sizeof (Elf64_Mips_External_Rel),
3183 sizeof (Elf64_Mips_External_Rela),
3184 sizeof (Elf64_External_Sym),
3185 sizeof (Elf64_External_Dyn),
3186 sizeof (Elf_External_Note),
3187 4, /* hash-table entry size */
3188 3, /* internal relocations per external relocations */
3189 64, /* arch_size */
3190 3, /* log_file_align */
3191 ELFCLASS64,
3192 EV_CURRENT,
3193 bfd_elf64_write_out_phdrs,
3194 bfd_elf64_write_shdrs_and_ehdr,
3195 bfd_elf64_checksum_contents,
3196 mips_elf64_write_relocs,
3197 bfd_elf64_swap_symbol_in,
3198 bfd_elf64_swap_symbol_out,
3199 mips_elf64_slurp_reloc_table,
3200 bfd_elf64_slurp_symbol_table,
3201 bfd_elf64_swap_dyn_in,
3202 bfd_elf64_swap_dyn_out,
3203 mips_elf64_be_swap_reloc_in,
3204 mips_elf64_be_swap_reloc_out,
3205 mips_elf64_be_swap_reloca_in,
3206 mips_elf64_be_swap_reloca_out
3209 #define ELF_ARCH bfd_arch_mips
3210 #define ELF_MACHINE_CODE EM_MIPS
3212 #define elf_backend_collect TRUE
3213 #define elf_backend_type_change_ok TRUE
3214 #define elf_backend_can_gc_sections TRUE
3215 #define elf_info_to_howto mips_elf64_info_to_howto_rela
3216 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
3217 #define elf_backend_object_p mips_elf64_object_p
3218 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
3219 #define elf_backend_section_processing _bfd_mips_elf_section_processing
3220 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
3221 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
3222 #define elf_backend_section_from_bfd_section \
3223 _bfd_mips_elf_section_from_bfd_section
3224 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
3225 #define elf_backend_link_output_symbol_hook \
3226 _bfd_mips_elf_link_output_symbol_hook
3227 #define elf_backend_create_dynamic_sections \
3228 _bfd_mips_elf_create_dynamic_sections
3229 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
3230 #define elf_backend_merge_symbol_attribute \
3231 _bfd_mips_elf_merge_symbol_attribute
3232 #define elf_backend_get_target_dtag _bfd_mips_elf_get_target_dtag
3233 #define elf_backend_adjust_dynamic_symbol \
3234 _bfd_mips_elf_adjust_dynamic_symbol
3235 #define elf_backend_always_size_sections \
3236 _bfd_mips_elf_always_size_sections
3237 #define elf_backend_size_dynamic_sections \
3238 _bfd_mips_elf_size_dynamic_sections
3239 #define elf_backend_init_index_section _bfd_elf_init_1_index_section
3240 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
3241 #define elf_backend_finish_dynamic_symbol \
3242 _bfd_mips_elf_finish_dynamic_symbol
3243 #define elf_backend_finish_dynamic_sections \
3244 _bfd_mips_elf_finish_dynamic_sections
3245 #define elf_backend_final_write_processing \
3246 _bfd_mips_elf_final_write_processing
3247 #define elf_backend_additional_program_headers \
3248 _bfd_mips_elf_additional_program_headers
3249 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
3250 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
3251 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
3252 #define elf_backend_copy_indirect_symbol \
3253 _bfd_mips_elf_copy_indirect_symbol
3254 #define elf_backend_ignore_discarded_relocs \
3255 _bfd_mips_elf_ignore_discarded_relocs
3256 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
3257 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
3258 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
3259 #define elf_backend_size_info mips_elf64_size_info
3261 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus
3262 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo
3264 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
3266 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
3267 work better/work only in RELA, so we default to this. */
3268 #define elf_backend_may_use_rel_p 1
3269 #define elf_backend_may_use_rela_p 1
3270 #define elf_backend_default_use_rela_p 1
3271 #define elf_backend_rela_plts_and_copies_p 0
3272 #define elf_backend_plt_readonly 1
3273 #define elf_backend_plt_sym_val _bfd_mips_elf_plt_sym_val
3275 #define elf_backend_sign_extend_vma TRUE
3277 #define elf_backend_write_section _bfd_mips_elf_write_section
3279 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
3280 MIPS-specific function only applies to IRIX5, which had no 64-bit
3281 ABI. */
3282 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
3283 #define bfd_elf64_find_inliner_info _bfd_mips_elf_find_inliner_info
3284 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
3285 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
3286 #define bfd_elf64_bfd_get_relocated_section_contents \
3287 _bfd_elf_mips_get_relocated_section_contents
3288 #define bfd_elf64_mkobject _bfd_mips_elf_mkobject
3289 #define bfd_elf64_bfd_link_hash_table_create \
3290 _bfd_mips_elf_link_hash_table_create
3291 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
3292 #define bfd_elf64_bfd_merge_private_bfd_data \
3293 _bfd_mips_elf_merge_private_bfd_data
3294 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
3295 #define bfd_elf64_bfd_print_private_bfd_data \
3296 _bfd_mips_elf_print_private_bfd_data
3298 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
3299 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
3300 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
3301 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
3302 #define bfd_elf64_bfd_relax_section _bfd_mips_relax_section
3304 /* MIPS ELF64 archive functions. */
3305 #define bfd_elf64_archive_functions
3306 extern bfd_boolean bfd_elf64_archive_slurp_armap
3307 (bfd *);
3308 extern bfd_boolean bfd_elf64_archive_write_armap
3309 (bfd *, unsigned int, struct orl *, unsigned int, int);
3310 #define bfd_elf64_archive_slurp_extended_name_table \
3311 _bfd_archive_coff_slurp_extended_name_table
3312 #define bfd_elf64_archive_construct_extended_name_table \
3313 _bfd_archive_coff_construct_extended_name_table
3314 #define bfd_elf64_archive_truncate_arname \
3315 _bfd_archive_coff_truncate_arname
3316 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
3317 #define bfd_elf64_archive_write_ar_hdr _bfd_archive_coff_write_ar_hdr
3318 #define bfd_elf64_archive_openr_next_archived_file \
3319 _bfd_archive_coff_openr_next_archived_file
3320 #define bfd_elf64_archive_get_elt_at_index \
3321 _bfd_archive_coff_get_elt_at_index
3322 #define bfd_elf64_archive_generic_stat_arch_elt \
3323 _bfd_archive_coff_generic_stat_arch_elt
3324 #define bfd_elf64_archive_update_armap_timestamp \
3325 _bfd_archive_coff_update_armap_timestamp
3327 /* The SGI style (n)64 NewABI. */
3328 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
3329 #define TARGET_LITTLE_NAME "elf64-littlemips"
3330 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
3331 #define TARGET_BIG_NAME "elf64-bigmips"
3333 #define ELF_MAXPAGESIZE 0x10000
3334 #define ELF_COMMONPAGESIZE 0x1000
3336 #include "elf64-target.h"
3338 /* The SYSV-style 'traditional' (n)64 NewABI. */
3339 #undef TARGET_LITTLE_SYM
3340 #undef TARGET_LITTLE_NAME
3341 #undef TARGET_BIG_SYM
3342 #undef TARGET_BIG_NAME
3344 #undef ELF_MAXPAGESIZE
3345 #undef ELF_COMMONPAGESIZE
3347 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
3348 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
3349 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
3350 #define TARGET_BIG_NAME "elf64-tradbigmips"
3352 #define ELF_MAXPAGESIZE 0x10000
3353 #define ELF_COMMONPAGESIZE 0x1000
3354 #define elf64_bed elf64_tradbed
3356 /* Include the target file again for this target. */
3357 #include "elf64-target.h"