merge from gcc
[binutils.git] / bfd / elf64-mips.c
blob7f0bb12e670149eee7d9df7e06ce7c4651830662
1 /* MIPS-specific support for 64-bit ELF
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
4 Ian Lance Taylor, Cygnus Support
5 Linker support added by Mark Mitchell, CodeSourcery, LLC.
6 <mark@codesourcery.com>
8 This file is part of BFD, the Binary File Descriptor library.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
24 /* This file supports the 64-bit MIPS ELF ABI.
26 The MIPS 64-bit ELF ABI uses an unusual reloc format. This file
27 overrides the usual ELF reloc handling, and handles reading and
28 writing the relocations here. */
30 /* TODO: Many things are unsupported, even if there is some code for it
31 . (which was mostly stolen from elf32-mips.c and slightly adapted).
33 . - Relocation handling for REL relocs is wrong in many cases and
34 . generally untested.
35 . - Relocation handling for RELA relocs related to GOT support are
36 . also likely to be wrong.
37 . - Support for MIPS16 is untested.
38 . - Combined relocs with RSS_* entries are unsupported.
39 . - The whole GOT handling for NewABI is missing, some parts of
40 . the OldABI version is still lying around and should be removed.
43 #include "bfd.h"
44 #include "sysdep.h"
45 #include "libbfd.h"
46 #include "aout/ar.h"
47 #include "bfdlink.h"
48 #include "genlink.h"
49 #include "elf-bfd.h"
50 #include "elfxx-mips.h"
51 #include "elf/mips.h"
53 /* Get the ECOFF swapping routines. The 64-bit ABI is not supposed to
54 use ECOFF. However, we support it anyhow for an easier changeover. */
55 #include "coff/sym.h"
56 #include "coff/symconst.h"
57 #include "coff/internal.h"
58 #include "coff/ecoff.h"
59 /* The 64 bit versions of the mdebug data structures are in alpha.h. */
60 #include "coff/alpha.h"
61 #define ECOFF_SIGNED_64
62 #include "ecoffswap.h"
64 static void mips_elf64_swap_reloc_in
65 (bfd *, const Elf64_Mips_External_Rel *, Elf64_Mips_Internal_Rela *);
66 static void mips_elf64_swap_reloca_in
67 (bfd *, const Elf64_Mips_External_Rela *, Elf64_Mips_Internal_Rela *);
68 static void mips_elf64_swap_reloc_out
69 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rel *);
70 static void mips_elf64_swap_reloca_out
71 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rela *);
72 static void mips_elf64_be_swap_reloc_in
73 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
74 static void mips_elf64_be_swap_reloc_out
75 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
76 static void mips_elf64_be_swap_reloca_in
77 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
78 static void mips_elf64_be_swap_reloca_out
79 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
80 static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup
81 (bfd *, bfd_reloc_code_real_type);
82 static reloc_howto_type *mips_elf64_rtype_to_howto
83 (unsigned int, bfd_boolean);
84 static void mips_elf64_info_to_howto_rel
85 (bfd *, arelent *, Elf_Internal_Rela *);
86 static void mips_elf64_info_to_howto_rela
87 (bfd *, arelent *, Elf_Internal_Rela *);
88 static long mips_elf64_get_reloc_upper_bound
89 (bfd *, asection *);
90 static long mips_elf64_canonicalize_reloc
91 (bfd *, asection *, arelent **, asymbol **);
92 static long mips_elf64_get_dynamic_reloc_upper_bound
93 (bfd *);
94 static long mips_elf64_canonicalize_dynamic_reloc
95 (bfd *, arelent **, asymbol **);
96 static bfd_boolean mips_elf64_slurp_one_reloc_table
97 (bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type, arelent *,
98 asymbol **, bfd_boolean);
99 static bfd_boolean mips_elf64_slurp_reloc_table
100 (bfd *, asection *, asymbol **, bfd_boolean);
101 static void mips_elf64_write_relocs
102 (bfd *, asection *, void *);
103 static void mips_elf64_write_rel
104 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
105 static void mips_elf64_write_rela
106 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
107 static bfd_reloc_status_type mips_elf64_gprel16_reloc
108 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
109 static bfd_reloc_status_type mips_elf64_literal_reloc
110 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
111 static bfd_reloc_status_type mips_elf64_gprel32_reloc
112 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
113 static bfd_reloc_status_type mips_elf64_shift6_reloc
114 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
115 static bfd_reloc_status_type mips16_jump_reloc
116 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
117 static bfd_reloc_status_type mips16_gprel_reloc
118 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
119 static bfd_boolean mips_elf64_assign_gp
120 (bfd *, bfd_vma *);
121 static bfd_reloc_status_type mips_elf64_final_gp
122 (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
123 static bfd_boolean mips_elf64_object_p
124 (bfd *);
125 static irix_compat_t elf64_mips_irix_compat
126 (bfd *);
127 static bfd_boolean elf64_mips_grok_prstatus
128 (bfd *, Elf_Internal_Note *);
129 static bfd_boolean elf64_mips_grok_psinfo
130 (bfd *, Elf_Internal_Note *);
132 extern const bfd_target bfd_elf64_bigmips_vec;
133 extern const bfd_target bfd_elf64_littlemips_vec;
135 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
136 from smaller values. Start with zero, widen, *then* decrement. */
137 #define MINUS_ONE (((bfd_vma)0) - 1)
139 /* The number of local .got entries we reserve. */
140 #define MIPS_RESERVED_GOTNO (2)
142 /* The relocation table used for SHT_REL sections. */
144 static reloc_howto_type mips_elf64_howto_table_rel[] =
146 /* No relocation. */
147 HOWTO (R_MIPS_NONE, /* type */
148 0, /* rightshift */
149 0, /* size (0 = byte, 1 = short, 2 = long) */
150 0, /* bitsize */
151 FALSE, /* pc_relative */
152 0, /* bitpos */
153 complain_overflow_dont, /* complain_on_overflow */
154 _bfd_mips_elf_generic_reloc, /* special_function */
155 "R_MIPS_NONE", /* name */
156 FALSE, /* partial_inplace */
157 0, /* src_mask */
158 0, /* dst_mask */
159 FALSE), /* pcrel_offset */
161 /* 16 bit relocation. */
162 HOWTO (R_MIPS_16, /* type */
163 0, /* rightshift */
164 2, /* size (0 = byte, 1 = short, 2 = long) */
165 16, /* bitsize */
166 FALSE, /* pc_relative */
167 0, /* bitpos */
168 complain_overflow_signed, /* complain_on_overflow */
169 _bfd_mips_elf_generic_reloc, /* special_function */
170 "R_MIPS_16", /* name */
171 TRUE, /* partial_inplace */
172 0x0000ffff, /* src_mask */
173 0x0000ffff, /* dst_mask */
174 FALSE), /* pcrel_offset */
176 /* 32 bit relocation. */
177 HOWTO (R_MIPS_32, /* type */
178 0, /* rightshift */
179 2, /* size (0 = byte, 1 = short, 2 = long) */
180 32, /* bitsize */
181 FALSE, /* pc_relative */
182 0, /* bitpos */
183 complain_overflow_dont, /* complain_on_overflow */
184 _bfd_mips_elf_generic_reloc, /* special_function */
185 "R_MIPS_32", /* name */
186 TRUE, /* partial_inplace */
187 0xffffffff, /* src_mask */
188 0xffffffff, /* dst_mask */
189 FALSE), /* pcrel_offset */
191 /* 32 bit symbol relative relocation. */
192 HOWTO (R_MIPS_REL32, /* type */
193 0, /* rightshift */
194 2, /* size (0 = byte, 1 = short, 2 = long) */
195 32, /* bitsize */
196 FALSE, /* pc_relative */
197 0, /* bitpos */
198 complain_overflow_dont, /* complain_on_overflow */
199 _bfd_mips_elf_generic_reloc, /* special_function */
200 "R_MIPS_REL32", /* name */
201 TRUE, /* partial_inplace */
202 0xffffffff, /* src_mask */
203 0xffffffff, /* dst_mask */
204 FALSE), /* pcrel_offset */
206 /* 26 bit jump address. */
207 HOWTO (R_MIPS_26, /* type */
208 2, /* rightshift */
209 2, /* size (0 = byte, 1 = short, 2 = long) */
210 26, /* bitsize */
211 FALSE, /* pc_relative */
212 0, /* bitpos */
213 complain_overflow_dont, /* complain_on_overflow */
214 /* This needs complex overflow
215 detection, because the upper 36
216 bits must match the PC + 4. */
217 _bfd_mips_elf_generic_reloc, /* special_function */
218 "R_MIPS_26", /* name */
219 TRUE, /* partial_inplace */
220 0x03ffffff, /* src_mask */
221 0x03ffffff, /* dst_mask */
222 FALSE), /* pcrel_offset */
224 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
225 However, the native IRIX6 tools use them, so we try our best. */
227 /* High 16 bits of symbol value. */
228 HOWTO (R_MIPS_HI16, /* type */
229 16, /* rightshift */
230 2, /* size (0 = byte, 1 = short, 2 = long) */
231 16, /* bitsize */
232 FALSE, /* pc_relative */
233 0, /* bitpos */
234 complain_overflow_dont, /* complain_on_overflow */
235 _bfd_mips_elf_hi16_reloc, /* special_function */
236 "R_MIPS_HI16", /* name */
237 TRUE, /* partial_inplace */
238 0x0000ffff, /* src_mask */
239 0x0000ffff, /* dst_mask */
240 FALSE), /* pcrel_offset */
242 /* Low 16 bits of symbol value. */
243 HOWTO (R_MIPS_LO16, /* type */
244 0, /* rightshift */
245 2, /* size (0 = byte, 1 = short, 2 = long) */
246 16, /* bitsize */
247 FALSE, /* pc_relative */
248 0, /* bitpos */
249 complain_overflow_dont, /* complain_on_overflow */
250 _bfd_mips_elf_lo16_reloc, /* special_function */
251 "R_MIPS_LO16", /* name */
252 TRUE, /* partial_inplace */
253 0x0000ffff, /* src_mask */
254 0x0000ffff, /* dst_mask */
255 FALSE), /* pcrel_offset */
257 /* GP relative reference. */
258 HOWTO (R_MIPS_GPREL16, /* type */
259 0, /* rightshift */
260 2, /* size (0 = byte, 1 = short, 2 = long) */
261 16, /* bitsize */
262 FALSE, /* pc_relative */
263 0, /* bitpos */
264 complain_overflow_signed, /* complain_on_overflow */
265 mips_elf64_gprel16_reloc, /* special_function */
266 "R_MIPS_GPREL16", /* name */
267 TRUE, /* partial_inplace */
268 0x0000ffff, /* src_mask */
269 0x0000ffff, /* dst_mask */
270 FALSE), /* pcrel_offset */
272 /* Reference to literal section. */
273 HOWTO (R_MIPS_LITERAL, /* type */
274 0, /* rightshift */
275 2, /* size (0 = byte, 1 = short, 2 = long) */
276 16, /* bitsize */
277 FALSE, /* pc_relative */
278 0, /* bitpos */
279 complain_overflow_signed, /* complain_on_overflow */
280 mips_elf64_literal_reloc, /* special_function */
281 "R_MIPS_LITERAL", /* name */
282 TRUE, /* partial_inplace */
283 0x0000ffff, /* src_mask */
284 0x0000ffff, /* dst_mask */
285 FALSE), /* pcrel_offset */
287 /* Reference to global offset table. */
288 HOWTO (R_MIPS_GOT16, /* type */
289 0, /* rightshift */
290 2, /* size (0 = byte, 1 = short, 2 = long) */
291 16, /* bitsize */
292 FALSE, /* pc_relative */
293 0, /* bitpos */
294 complain_overflow_signed, /* complain_on_overflow */
295 _bfd_mips_elf_got16_reloc, /* special_function */
296 "R_MIPS_GOT16", /* name */
297 TRUE, /* partial_inplace */
298 0x0000ffff, /* src_mask */
299 0x0000ffff, /* dst_mask */
300 FALSE), /* pcrel_offset */
302 /* 16 bit PC relative reference. */
303 HOWTO (R_MIPS_PC16, /* type */
304 0, /* rightshift */
305 2, /* size (0 = byte, 1 = short, 2 = long) */
306 16, /* bitsize */
307 TRUE, /* pc_relative */
308 0, /* bitpos */
309 complain_overflow_signed, /* complain_on_overflow */
310 _bfd_mips_elf_generic_reloc, /* special_function */
311 "R_MIPS_PC16", /* name */
312 TRUE, /* partial_inplace */
313 0x0000ffff, /* src_mask */
314 0x0000ffff, /* dst_mask */
315 TRUE), /* pcrel_offset */
317 /* 16 bit call through global offset table. */
318 HOWTO (R_MIPS_CALL16, /* type */
319 0, /* rightshift */
320 2, /* size (0 = byte, 1 = short, 2 = long) */
321 16, /* bitsize */
322 FALSE, /* pc_relative */
323 0, /* bitpos */
324 complain_overflow_signed, /* complain_on_overflow */
325 _bfd_mips_elf_generic_reloc, /* special_function */
326 "R_MIPS_CALL16", /* name */
327 TRUE, /* partial_inplace */
328 0x0000ffff, /* src_mask */
329 0x0000ffff, /* dst_mask */
330 FALSE), /* pcrel_offset */
332 /* 32 bit GP relative reference. */
333 HOWTO (R_MIPS_GPREL32, /* type */
334 0, /* rightshift */
335 2, /* size (0 = byte, 1 = short, 2 = long) */
336 32, /* bitsize */
337 FALSE, /* pc_relative */
338 0, /* bitpos */
339 complain_overflow_dont, /* complain_on_overflow */
340 mips_elf64_gprel32_reloc, /* special_function */
341 "R_MIPS_GPREL32", /* name */
342 TRUE, /* partial_inplace */
343 0xffffffff, /* src_mask */
344 0xffffffff, /* dst_mask */
345 FALSE), /* pcrel_offset */
347 EMPTY_HOWTO (13),
348 EMPTY_HOWTO (14),
349 EMPTY_HOWTO (15),
351 /* A 5 bit shift field. */
352 HOWTO (R_MIPS_SHIFT5, /* type */
353 0, /* rightshift */
354 2, /* size (0 = byte, 1 = short, 2 = long) */
355 5, /* bitsize */
356 FALSE, /* pc_relative */
357 6, /* bitpos */
358 complain_overflow_bitfield, /* complain_on_overflow */
359 _bfd_mips_elf_generic_reloc, /* special_function */
360 "R_MIPS_SHIFT5", /* name */
361 TRUE, /* partial_inplace */
362 0x000007c0, /* src_mask */
363 0x000007c0, /* dst_mask */
364 FALSE), /* pcrel_offset */
366 /* A 6 bit shift field. */
367 HOWTO (R_MIPS_SHIFT6, /* type */
368 0, /* rightshift */
369 2, /* size (0 = byte, 1 = short, 2 = long) */
370 6, /* bitsize */
371 FALSE, /* pc_relative */
372 6, /* bitpos */
373 complain_overflow_bitfield, /* complain_on_overflow */
374 mips_elf64_shift6_reloc, /* special_function */
375 "R_MIPS_SHIFT6", /* name */
376 TRUE, /* partial_inplace */
377 0x000007c4, /* src_mask */
378 0x000007c4, /* dst_mask */
379 FALSE), /* pcrel_offset */
381 /* 64 bit relocation. */
382 HOWTO (R_MIPS_64, /* type */
383 0, /* rightshift */
384 4, /* size (0 = byte, 1 = short, 2 = long) */
385 64, /* bitsize */
386 FALSE, /* pc_relative */
387 0, /* bitpos */
388 complain_overflow_dont, /* complain_on_overflow */
389 _bfd_mips_elf_generic_reloc, /* special_function */
390 "R_MIPS_64", /* name */
391 TRUE, /* partial_inplace */
392 MINUS_ONE, /* src_mask */
393 MINUS_ONE, /* dst_mask */
394 FALSE), /* pcrel_offset */
396 /* Displacement in the global offset table. */
397 HOWTO (R_MIPS_GOT_DISP, /* type */
398 0, /* rightshift */
399 2, /* size (0 = byte, 1 = short, 2 = long) */
400 16, /* bitsize */
401 FALSE, /* pc_relative */
402 0, /* bitpos */
403 complain_overflow_signed, /* complain_on_overflow */
404 _bfd_mips_elf_generic_reloc, /* special_function */
405 "R_MIPS_GOT_DISP", /* name */
406 TRUE, /* partial_inplace */
407 0x0000ffff, /* src_mask */
408 0x0000ffff, /* dst_mask */
409 FALSE), /* pcrel_offset */
411 /* Displacement to page pointer in the global offset table. */
412 HOWTO (R_MIPS_GOT_PAGE, /* type */
413 0, /* rightshift */
414 2, /* size (0 = byte, 1 = short, 2 = long) */
415 16, /* bitsize */
416 FALSE, /* pc_relative */
417 0, /* bitpos */
418 complain_overflow_signed, /* complain_on_overflow */
419 _bfd_mips_elf_generic_reloc, /* special_function */
420 "R_MIPS_GOT_PAGE", /* name */
421 TRUE, /* partial_inplace */
422 0x0000ffff, /* src_mask */
423 0x0000ffff, /* dst_mask */
424 FALSE), /* pcrel_offset */
426 /* Offset from page pointer in the global offset table. */
427 HOWTO (R_MIPS_GOT_OFST, /* type */
428 0, /* rightshift */
429 2, /* size (0 = byte, 1 = short, 2 = long) */
430 16, /* bitsize */
431 FALSE, /* pc_relative */
432 0, /* bitpos */
433 complain_overflow_signed, /* complain_on_overflow */
434 _bfd_mips_elf_generic_reloc, /* special_function */
435 "R_MIPS_GOT_OFST", /* name */
436 TRUE, /* partial_inplace */
437 0x0000ffff, /* src_mask */
438 0x0000ffff, /* dst_mask */
439 FALSE), /* pcrel_offset */
441 /* High 16 bits of displacement in global offset table. */
442 HOWTO (R_MIPS_GOT_HI16, /* type */
443 0, /* rightshift */
444 2, /* size (0 = byte, 1 = short, 2 = long) */
445 16, /* bitsize */
446 FALSE, /* pc_relative */
447 0, /* bitpos */
448 complain_overflow_dont, /* complain_on_overflow */
449 _bfd_mips_elf_generic_reloc, /* special_function */
450 "R_MIPS_GOT_HI16", /* name */
451 TRUE, /* partial_inplace */
452 0x0000ffff, /* src_mask */
453 0x0000ffff, /* dst_mask */
454 FALSE), /* pcrel_offset */
456 /* Low 16 bits of displacement in global offset table. */
457 HOWTO (R_MIPS_GOT_LO16, /* type */
458 0, /* rightshift */
459 2, /* size (0 = byte, 1 = short, 2 = long) */
460 16, /* bitsize */
461 FALSE, /* pc_relative */
462 0, /* bitpos */
463 complain_overflow_dont, /* complain_on_overflow */
464 _bfd_mips_elf_generic_reloc, /* special_function */
465 "R_MIPS_GOT_LO16", /* name */
466 TRUE, /* partial_inplace */
467 0x0000ffff, /* src_mask */
468 0x0000ffff, /* dst_mask */
469 FALSE), /* pcrel_offset */
471 /* 64 bit subtraction. */
472 HOWTO (R_MIPS_SUB, /* type */
473 0, /* rightshift */
474 4, /* size (0 = byte, 1 = short, 2 = long) */
475 64, /* bitsize */
476 FALSE, /* pc_relative */
477 0, /* bitpos */
478 complain_overflow_dont, /* complain_on_overflow */
479 _bfd_mips_elf_generic_reloc, /* special_function */
480 "R_MIPS_SUB", /* name */
481 TRUE, /* partial_inplace */
482 MINUS_ONE, /* src_mask */
483 MINUS_ONE, /* dst_mask */
484 FALSE), /* pcrel_offset */
486 /* Insert the addend as an instruction. */
487 /* FIXME: Not handled correctly. */
488 HOWTO (R_MIPS_INSERT_A, /* type */
489 0, /* rightshift */
490 2, /* size (0 = byte, 1 = short, 2 = long) */
491 32, /* bitsize */
492 FALSE, /* pc_relative */
493 0, /* bitpos */
494 complain_overflow_dont, /* complain_on_overflow */
495 _bfd_mips_elf_generic_reloc, /* special_function */
496 "R_MIPS_INSERT_A", /* name */
497 TRUE, /* partial_inplace */
498 0xffffffff, /* src_mask */
499 0xffffffff, /* dst_mask */
500 FALSE), /* pcrel_offset */
502 /* Insert the addend as an instruction, and change all relocations
503 to refer to the old instruction at the address. */
504 /* FIXME: Not handled correctly. */
505 HOWTO (R_MIPS_INSERT_B, /* type */
506 0, /* rightshift */
507 2, /* size (0 = byte, 1 = short, 2 = long) */
508 32, /* bitsize */
509 FALSE, /* pc_relative */
510 0, /* bitpos */
511 complain_overflow_dont, /* complain_on_overflow */
512 _bfd_mips_elf_generic_reloc, /* special_function */
513 "R_MIPS_INSERT_B", /* name */
514 TRUE, /* partial_inplace */
515 0xffffffff, /* src_mask */
516 0xffffffff, /* dst_mask */
517 FALSE), /* pcrel_offset */
519 /* Delete a 32 bit instruction. */
520 /* FIXME: Not handled correctly. */
521 HOWTO (R_MIPS_DELETE, /* type */
522 0, /* rightshift */
523 2, /* size (0 = byte, 1 = short, 2 = long) */
524 32, /* bitsize */
525 FALSE, /* pc_relative */
526 0, /* bitpos */
527 complain_overflow_dont, /* complain_on_overflow */
528 _bfd_mips_elf_generic_reloc, /* special_function */
529 "R_MIPS_DELETE", /* name */
530 TRUE, /* partial_inplace */
531 0xffffffff, /* src_mask */
532 0xffffffff, /* dst_mask */
533 FALSE), /* pcrel_offset */
535 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
536 We don't, because
537 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
538 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
539 fallable heuristics.
540 b) No other NewABI toolchain actually emits such relocations. */
541 EMPTY_HOWTO (R_MIPS_HIGHER),
542 EMPTY_HOWTO (R_MIPS_HIGHEST),
544 /* High 16 bits of displacement in global offset table. */
545 HOWTO (R_MIPS_CALL_HI16, /* type */
546 0, /* rightshift */
547 2, /* size (0 = byte, 1 = short, 2 = long) */
548 16, /* bitsize */
549 FALSE, /* pc_relative */
550 0, /* bitpos */
551 complain_overflow_dont, /* complain_on_overflow */
552 _bfd_mips_elf_generic_reloc, /* special_function */
553 "R_MIPS_CALL_HI16", /* name */
554 TRUE, /* partial_inplace */
555 0x0000ffff, /* src_mask */
556 0x0000ffff, /* dst_mask */
557 FALSE), /* pcrel_offset */
559 /* Low 16 bits of displacement in global offset table. */
560 HOWTO (R_MIPS_CALL_LO16, /* type */
561 0, /* rightshift */
562 2, /* size (0 = byte, 1 = short, 2 = long) */
563 16, /* bitsize */
564 FALSE, /* pc_relative */
565 0, /* bitpos */
566 complain_overflow_dont, /* complain_on_overflow */
567 _bfd_mips_elf_generic_reloc, /* special_function */
568 "R_MIPS_CALL_LO16", /* name */
569 TRUE, /* partial_inplace */
570 0x0000ffff, /* src_mask */
571 0x0000ffff, /* dst_mask */
572 FALSE), /* pcrel_offset */
574 /* Section displacement, used by an associated event location section. */
575 HOWTO (R_MIPS_SCN_DISP, /* type */
576 0, /* rightshift */
577 2, /* size (0 = byte, 1 = short, 2 = long) */
578 32, /* bitsize */
579 FALSE, /* pc_relative */
580 0, /* bitpos */
581 complain_overflow_dont, /* complain_on_overflow */
582 _bfd_mips_elf_generic_reloc, /* special_function */
583 "R_MIPS_SCN_DISP", /* name */
584 TRUE, /* partial_inplace */
585 0xffffffff, /* src_mask */
586 0xffffffff, /* dst_mask */
587 FALSE), /* pcrel_offset */
589 HOWTO (R_MIPS_REL16, /* type */
590 0, /* rightshift */
591 1, /* size (0 = byte, 1 = short, 2 = long) */
592 16, /* bitsize */
593 FALSE, /* pc_relative */
594 0, /* bitpos */
595 complain_overflow_signed, /* complain_on_overflow */
596 _bfd_mips_elf_generic_reloc, /* special_function */
597 "R_MIPS_REL16", /* name */
598 TRUE, /* partial_inplace */
599 0xffff, /* src_mask */
600 0xffff, /* dst_mask */
601 FALSE), /* pcrel_offset */
603 /* These two are obsolete. */
604 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
605 EMPTY_HOWTO (R_MIPS_PJUMP),
607 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
608 It must be used for multigot GOT's (and only there). */
609 HOWTO (R_MIPS_RELGOT, /* type */
610 0, /* rightshift */
611 2, /* size (0 = byte, 1 = short, 2 = long) */
612 32, /* bitsize */
613 FALSE, /* pc_relative */
614 0, /* bitpos */
615 complain_overflow_dont, /* complain_on_overflow */
616 _bfd_mips_elf_generic_reloc, /* special_function */
617 "R_MIPS_RELGOT", /* name */
618 TRUE, /* partial_inplace */
619 0xffffffff, /* src_mask */
620 0xffffffff, /* dst_mask */
621 FALSE), /* pcrel_offset */
623 /* Protected jump conversion. This is an optimization hint. No
624 relocation is required for correctness. */
625 HOWTO (R_MIPS_JALR, /* type */
626 0, /* rightshift */
627 2, /* size (0 = byte, 1 = short, 2 = long) */
628 32, /* bitsize */
629 FALSE, /* pc_relative */
630 0, /* bitpos */
631 complain_overflow_dont, /* complain_on_overflow */
632 _bfd_mips_elf_generic_reloc, /* special_function */
633 "R_MIPS_JALR", /* name */
634 FALSE, /* partial_inplace */
635 0, /* src_mask */
636 0x00000000, /* dst_mask */
637 FALSE), /* pcrel_offset */
639 /* TLS relocations. */
640 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
641 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
643 HOWTO (R_MIPS_TLS_DTPMOD64, /* type */
644 0, /* rightshift */
645 4, /* size (0 = byte, 1 = short, 2 = long) */
646 64, /* bitsize */
647 FALSE, /* pc_relative */
648 0, /* bitpos */
649 complain_overflow_dont, /* complain_on_overflow */
650 _bfd_mips_elf_generic_reloc, /* special_function */
651 "R_MIPS_TLS_DTPMOD64", /* name */
652 TRUE, /* partial_inplace */
653 MINUS_ONE, /* src_mask */
654 MINUS_ONE, /* dst_mask */
655 FALSE), /* pcrel_offset */
657 HOWTO (R_MIPS_TLS_DTPREL64, /* type */
658 0, /* rightshift */
659 4, /* size (0 = byte, 1 = short, 2 = long) */
660 64, /* bitsize */
661 FALSE, /* pc_relative */
662 0, /* bitpos */
663 complain_overflow_dont, /* complain_on_overflow */
664 _bfd_mips_elf_generic_reloc, /* special_function */
665 "R_MIPS_TLS_DTPREL64", /* name */
666 TRUE, /* partial_inplace */
667 MINUS_ONE, /* src_mask */
668 MINUS_ONE, /* dst_mask */
669 FALSE), /* pcrel_offset */
671 /* TLS general dynamic variable reference. */
672 HOWTO (R_MIPS_TLS_GD, /* type */
673 0, /* rightshift */
674 2, /* size (0 = byte, 1 = short, 2 = long) */
675 16, /* bitsize */
676 FALSE, /* pc_relative */
677 0, /* bitpos */
678 complain_overflow_signed, /* complain_on_overflow */
679 _bfd_mips_elf_generic_reloc, /* special_function */
680 "R_MIPS_TLS_GD", /* name */
681 TRUE, /* partial_inplace */
682 0x0000ffff, /* src_mask */
683 0x0000ffff, /* dst_mask */
684 FALSE), /* pcrel_offset */
686 /* TLS local dynamic variable reference. */
687 HOWTO (R_MIPS_TLS_LDM, /* type */
688 0, /* rightshift */
689 2, /* size (0 = byte, 1 = short, 2 = long) */
690 16, /* bitsize */
691 FALSE, /* pc_relative */
692 0, /* bitpos */
693 complain_overflow_signed, /* complain_on_overflow */
694 _bfd_mips_elf_generic_reloc, /* special_function */
695 "R_MIPS_TLS_LDM", /* name */
696 TRUE, /* partial_inplace */
697 0x0000ffff, /* src_mask */
698 0x0000ffff, /* dst_mask */
699 FALSE), /* pcrel_offset */
701 /* TLS local dynamic offset. */
702 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
703 0, /* rightshift */
704 2, /* size (0 = byte, 1 = short, 2 = long) */
705 16, /* bitsize */
706 FALSE, /* pc_relative */
707 0, /* bitpos */
708 complain_overflow_signed, /* complain_on_overflow */
709 _bfd_mips_elf_generic_reloc, /* special_function */
710 "R_MIPS_TLS_DTPREL_HI16", /* name */
711 TRUE, /* partial_inplace */
712 0x0000ffff, /* src_mask */
713 0x0000ffff, /* dst_mask */
714 FALSE), /* pcrel_offset */
716 /* TLS local dynamic offset. */
717 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
718 0, /* rightshift */
719 2, /* size (0 = byte, 1 = short, 2 = long) */
720 16, /* bitsize */
721 FALSE, /* pc_relative */
722 0, /* bitpos */
723 complain_overflow_signed, /* complain_on_overflow */
724 _bfd_mips_elf_generic_reloc, /* special_function */
725 "R_MIPS_TLS_DTPREL_LO16", /* name */
726 TRUE, /* partial_inplace */
727 0x0000ffff, /* src_mask */
728 0x0000ffff, /* dst_mask */
729 FALSE), /* pcrel_offset */
731 /* TLS thread pointer offset. */
732 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
733 0, /* rightshift */
734 2, /* size (0 = byte, 1 = short, 2 = long) */
735 16, /* bitsize */
736 FALSE, /* pc_relative */
737 0, /* bitpos */
738 complain_overflow_signed, /* complain_on_overflow */
739 _bfd_mips_elf_generic_reloc, /* special_function */
740 "R_MIPS_TLS_GOTTPREL", /* name */
741 TRUE, /* partial_inplace */
742 0x0000ffff, /* src_mask */
743 0x0000ffff, /* dst_mask */
744 FALSE), /* pcrel_offset */
746 /* TLS IE dynamic relocations. */
747 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
749 HOWTO (R_MIPS_TLS_TPREL64, /* type */
750 0, /* rightshift */
751 4, /* size (0 = byte, 1 = short, 2 = long) */
752 64, /* bitsize */
753 FALSE, /* pc_relative */
754 0, /* bitpos */
755 complain_overflow_dont, /* complain_on_overflow */
756 _bfd_mips_elf_generic_reloc, /* special_function */
757 "R_MIPS_TLS_TPREL64", /* name */
758 TRUE, /* partial_inplace */
759 MINUS_ONE, /* src_mask */
760 MINUS_ONE, /* dst_mask */
761 FALSE), /* pcrel_offset */
763 /* TLS thread pointer offset. */
764 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
765 0, /* rightshift */
766 2, /* size (0 = byte, 1 = short, 2 = long) */
767 16, /* bitsize */
768 FALSE, /* pc_relative */
769 0, /* bitpos */
770 complain_overflow_signed, /* complain_on_overflow */
771 _bfd_mips_elf_generic_reloc, /* special_function */
772 "R_MIPS_TLS_TPREL_HI16", /* name */
773 TRUE, /* partial_inplace */
774 0x0000ffff, /* src_mask */
775 0x0000ffff, /* dst_mask */
776 FALSE), /* pcrel_offset */
778 /* TLS thread pointer offset. */
779 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
780 0, /* rightshift */
781 2, /* size (0 = byte, 1 = short, 2 = long) */
782 16, /* bitsize */
783 FALSE, /* pc_relative */
784 0, /* bitpos */
785 complain_overflow_signed, /* complain_on_overflow */
786 _bfd_mips_elf_generic_reloc, /* special_function */
787 "R_MIPS_TLS_TPREL_LO16", /* name */
788 TRUE, /* partial_inplace */
789 0x0000ffff, /* src_mask */
790 0x0000ffff, /* dst_mask */
791 FALSE), /* pcrel_offset */
794 /* The relocation table used for SHT_RELA sections. */
796 static reloc_howto_type mips_elf64_howto_table_rela[] =
798 /* No relocation. */
799 HOWTO (R_MIPS_NONE, /* type */
800 0, /* rightshift */
801 0, /* size (0 = byte, 1 = short, 2 = long) */
802 0, /* bitsize */
803 FALSE, /* pc_relative */
804 0, /* bitpos */
805 complain_overflow_dont, /* complain_on_overflow */
806 _bfd_mips_elf_generic_reloc, /* special_function */
807 "R_MIPS_NONE", /* name */
808 FALSE, /* partial_inplace */
809 0, /* src_mask */
810 0, /* dst_mask */
811 FALSE), /* pcrel_offset */
813 /* 16 bit relocation. */
814 HOWTO (R_MIPS_16, /* type */
815 0, /* rightshift */
816 2, /* size (0 = byte, 1 = short, 2 = long) */
817 16, /* bitsize */
818 FALSE, /* pc_relative */
819 0, /* bitpos */
820 complain_overflow_signed, /* complain_on_overflow */
821 _bfd_mips_elf_generic_reloc, /* special_function */
822 "R_MIPS_16", /* name */
823 FALSE, /* partial_inplace */
824 0, /* src_mask */
825 0x0000ffff, /* dst_mask */
826 FALSE), /* pcrel_offset */
828 /* 32 bit relocation. */
829 HOWTO (R_MIPS_32, /* type */
830 0, /* rightshift */
831 2, /* size (0 = byte, 1 = short, 2 = long) */
832 32, /* bitsize */
833 FALSE, /* pc_relative */
834 0, /* bitpos */
835 complain_overflow_dont, /* complain_on_overflow */
836 _bfd_mips_elf_generic_reloc, /* special_function */
837 "R_MIPS_32", /* name */
838 FALSE, /* partial_inplace */
839 0, /* src_mask */
840 0xffffffff, /* dst_mask */
841 FALSE), /* pcrel_offset */
843 /* 32 bit symbol relative relocation. */
844 HOWTO (R_MIPS_REL32, /* type */
845 0, /* rightshift */
846 2, /* size (0 = byte, 1 = short, 2 = long) */
847 32, /* bitsize */
848 FALSE, /* pc_relative */
849 0, /* bitpos */
850 complain_overflow_dont, /* complain_on_overflow */
851 _bfd_mips_elf_generic_reloc, /* special_function */
852 "R_MIPS_REL32", /* name */
853 FALSE, /* partial_inplace */
854 0, /* src_mask */
855 0xffffffff, /* dst_mask */
856 FALSE), /* pcrel_offset */
858 /* 26 bit jump address. */
859 HOWTO (R_MIPS_26, /* type */
860 2, /* rightshift */
861 2, /* size (0 = byte, 1 = short, 2 = long) */
862 26, /* bitsize */
863 FALSE, /* pc_relative */
864 0, /* bitpos */
865 complain_overflow_dont, /* complain_on_overflow */
866 /* This needs complex overflow
867 detection, because the upper 36
868 bits must match the PC + 4. */
869 _bfd_mips_elf_generic_reloc, /* special_function */
870 "R_MIPS_26", /* name */
871 FALSE, /* partial_inplace */
872 0, /* src_mask */
873 0x03ffffff, /* dst_mask */
874 FALSE), /* pcrel_offset */
876 /* High 16 bits of symbol value. */
877 HOWTO (R_MIPS_HI16, /* type */
878 0, /* rightshift */
879 2, /* size (0 = byte, 1 = short, 2 = long) */
880 16, /* bitsize */
881 FALSE, /* pc_relative */
882 0, /* bitpos */
883 complain_overflow_dont, /* complain_on_overflow */
884 _bfd_mips_elf_generic_reloc, /* special_function */
885 "R_MIPS_HI16", /* name */
886 FALSE, /* partial_inplace */
887 0, /* src_mask */
888 0x0000ffff, /* dst_mask */
889 FALSE), /* pcrel_offset */
891 /* Low 16 bits of symbol value. */
892 HOWTO (R_MIPS_LO16, /* type */
893 0, /* rightshift */
894 2, /* size (0 = byte, 1 = short, 2 = long) */
895 16, /* bitsize */
896 FALSE, /* pc_relative */
897 0, /* bitpos */
898 complain_overflow_dont, /* complain_on_overflow */
899 _bfd_mips_elf_generic_reloc, /* special_function */
900 "R_MIPS_LO16", /* name */
901 FALSE, /* partial_inplace */
902 0, /* src_mask */
903 0x0000ffff, /* dst_mask */
904 FALSE), /* pcrel_offset */
906 /* GP relative reference. */
907 HOWTO (R_MIPS_GPREL16, /* type */
908 0, /* rightshift */
909 2, /* size (0 = byte, 1 = short, 2 = long) */
910 16, /* bitsize */
911 FALSE, /* pc_relative */
912 0, /* bitpos */
913 complain_overflow_signed, /* complain_on_overflow */
914 mips_elf64_gprel16_reloc, /* special_function */
915 "R_MIPS_GPREL16", /* name */
916 FALSE, /* partial_inplace */
917 0, /* src_mask */
918 0x0000ffff, /* dst_mask */
919 FALSE), /* pcrel_offset */
921 /* Reference to literal section. */
922 HOWTO (R_MIPS_LITERAL, /* type */
923 0, /* rightshift */
924 2, /* size (0 = byte, 1 = short, 2 = long) */
925 16, /* bitsize */
926 FALSE, /* pc_relative */
927 0, /* bitpos */
928 complain_overflow_signed, /* complain_on_overflow */
929 mips_elf64_literal_reloc, /* special_function */
930 "R_MIPS_LITERAL", /* name */
931 FALSE, /* partial_inplace */
932 0, /* src_mask */
933 0x0000ffff, /* dst_mask */
934 FALSE), /* pcrel_offset */
936 /* Reference to global offset table. */
937 HOWTO (R_MIPS_GOT16, /* type */
938 0, /* rightshift */
939 2, /* size (0 = byte, 1 = short, 2 = long) */
940 16, /* bitsize */
941 FALSE, /* pc_relative */
942 0, /* bitpos */
943 complain_overflow_signed, /* complain_on_overflow */
944 _bfd_mips_elf_generic_reloc, /* special_function */
945 "R_MIPS_GOT16", /* name */
946 FALSE, /* partial_inplace */
947 0, /* src_mask */
948 0x0000ffff, /* dst_mask */
949 FALSE), /* pcrel_offset */
951 /* 16 bit PC relative reference. */
952 HOWTO (R_MIPS_PC16, /* type */
953 0, /* rightshift */
954 2, /* size (0 = byte, 1 = short, 2 = long) */
955 16, /* bitsize */
956 TRUE, /* pc_relative */
957 0, /* bitpos */
958 complain_overflow_signed, /* complain_on_overflow */
959 _bfd_mips_elf_generic_reloc, /* special_function */
960 "R_MIPS_PC16", /* name */
961 FALSE, /* partial_inplace */
962 0, /* src_mask */
963 0x0000ffff, /* dst_mask */
964 TRUE), /* pcrel_offset */
966 /* 16 bit call through global offset table. */
967 HOWTO (R_MIPS_CALL16, /* type */
968 0, /* rightshift */
969 2, /* size (0 = byte, 1 = short, 2 = long) */
970 16, /* bitsize */
971 FALSE, /* pc_relative */
972 0, /* bitpos */
973 complain_overflow_signed, /* complain_on_overflow */
974 _bfd_mips_elf_generic_reloc, /* special_function */
975 "R_MIPS_CALL16", /* name */
976 FALSE, /* partial_inplace */
977 0, /* src_mask */
978 0x0000ffff, /* dst_mask */
979 FALSE), /* pcrel_offset */
981 /* 32 bit GP relative reference. */
982 HOWTO (R_MIPS_GPREL32, /* type */
983 0, /* rightshift */
984 2, /* size (0 = byte, 1 = short, 2 = long) */
985 32, /* bitsize */
986 FALSE, /* pc_relative */
987 0, /* bitpos */
988 complain_overflow_dont, /* complain_on_overflow */
989 mips_elf64_gprel32_reloc, /* special_function */
990 "R_MIPS_GPREL32", /* name */
991 FALSE, /* partial_inplace */
992 0, /* src_mask */
993 0xffffffff, /* dst_mask */
994 FALSE), /* pcrel_offset */
996 EMPTY_HOWTO (13),
997 EMPTY_HOWTO (14),
998 EMPTY_HOWTO (15),
1000 /* A 5 bit shift field. */
1001 HOWTO (R_MIPS_SHIFT5, /* type */
1002 0, /* rightshift */
1003 2, /* size (0 = byte, 1 = short, 2 = long) */
1004 5, /* bitsize */
1005 FALSE, /* pc_relative */
1006 6, /* bitpos */
1007 complain_overflow_bitfield, /* complain_on_overflow */
1008 _bfd_mips_elf_generic_reloc, /* special_function */
1009 "R_MIPS_SHIFT5", /* name */
1010 FALSE, /* partial_inplace */
1011 0, /* src_mask */
1012 0x000007c0, /* dst_mask */
1013 FALSE), /* pcrel_offset */
1015 /* A 6 bit shift field. */
1016 HOWTO (R_MIPS_SHIFT6, /* type */
1017 0, /* rightshift */
1018 2, /* size (0 = byte, 1 = short, 2 = long) */
1019 6, /* bitsize */
1020 FALSE, /* pc_relative */
1021 6, /* bitpos */
1022 complain_overflow_bitfield, /* complain_on_overflow */
1023 mips_elf64_shift6_reloc, /* special_function */
1024 "R_MIPS_SHIFT6", /* name */
1025 FALSE, /* partial_inplace */
1026 0, /* src_mask */
1027 0x000007c4, /* dst_mask */
1028 FALSE), /* pcrel_offset */
1030 /* 64 bit relocation. */
1031 HOWTO (R_MIPS_64, /* type */
1032 0, /* rightshift */
1033 4, /* size (0 = byte, 1 = short, 2 = long) */
1034 64, /* bitsize */
1035 FALSE, /* pc_relative */
1036 0, /* bitpos */
1037 complain_overflow_dont, /* complain_on_overflow */
1038 _bfd_mips_elf_generic_reloc, /* special_function */
1039 "R_MIPS_64", /* name */
1040 FALSE, /* partial_inplace */
1041 0, /* src_mask */
1042 MINUS_ONE, /* dst_mask */
1043 FALSE), /* pcrel_offset */
1045 /* Displacement in the global offset table. */
1046 HOWTO (R_MIPS_GOT_DISP, /* type */
1047 0, /* rightshift */
1048 2, /* size (0 = byte, 1 = short, 2 = long) */
1049 16, /* bitsize */
1050 FALSE, /* pc_relative */
1051 0, /* bitpos */
1052 complain_overflow_signed, /* complain_on_overflow */
1053 _bfd_mips_elf_generic_reloc, /* special_function */
1054 "R_MIPS_GOT_DISP", /* name */
1055 FALSE, /* partial_inplace */
1056 0, /* src_mask */
1057 0x0000ffff, /* dst_mask */
1058 FALSE), /* pcrel_offset */
1060 /* Displacement to page pointer in the global offset table. */
1061 HOWTO (R_MIPS_GOT_PAGE, /* type */
1062 0, /* rightshift */
1063 2, /* size (0 = byte, 1 = short, 2 = long) */
1064 16, /* bitsize */
1065 FALSE, /* pc_relative */
1066 0, /* bitpos */
1067 complain_overflow_signed, /* complain_on_overflow */
1068 _bfd_mips_elf_generic_reloc, /* special_function */
1069 "R_MIPS_GOT_PAGE", /* name */
1070 FALSE, /* partial_inplace */
1071 0, /* src_mask */
1072 0x0000ffff, /* dst_mask */
1073 FALSE), /* pcrel_offset */
1075 /* Offset from page pointer in the global offset table. */
1076 HOWTO (R_MIPS_GOT_OFST, /* type */
1077 0, /* rightshift */
1078 2, /* size (0 = byte, 1 = short, 2 = long) */
1079 16, /* bitsize */
1080 FALSE, /* pc_relative */
1081 0, /* bitpos */
1082 complain_overflow_signed, /* complain_on_overflow */
1083 _bfd_mips_elf_generic_reloc, /* special_function */
1084 "R_MIPS_GOT_OFST", /* name */
1085 FALSE, /* partial_inplace */
1086 0, /* src_mask */
1087 0x0000ffff, /* dst_mask */
1088 FALSE), /* pcrel_offset */
1090 /* High 16 bits of displacement in global offset table. */
1091 HOWTO (R_MIPS_GOT_HI16, /* type */
1092 0, /* rightshift */
1093 2, /* size (0 = byte, 1 = short, 2 = long) */
1094 16, /* bitsize */
1095 FALSE, /* pc_relative */
1096 0, /* bitpos */
1097 complain_overflow_dont, /* complain_on_overflow */
1098 _bfd_mips_elf_generic_reloc, /* special_function */
1099 "R_MIPS_GOT_HI16", /* name */
1100 FALSE, /* partial_inplace */
1101 0, /* src_mask */
1102 0x0000ffff, /* dst_mask */
1103 FALSE), /* pcrel_offset */
1105 /* Low 16 bits of displacement in global offset table. */
1106 HOWTO (R_MIPS_GOT_LO16, /* type */
1107 0, /* rightshift */
1108 2, /* size (0 = byte, 1 = short, 2 = long) */
1109 16, /* bitsize */
1110 FALSE, /* pc_relative */
1111 0, /* bitpos */
1112 complain_overflow_dont, /* complain_on_overflow */
1113 _bfd_mips_elf_generic_reloc, /* special_function */
1114 "R_MIPS_GOT_LO16", /* name */
1115 FALSE, /* partial_inplace */
1116 0, /* src_mask */
1117 0x0000ffff, /* dst_mask */
1118 FALSE), /* pcrel_offset */
1120 /* 64 bit subtraction. */
1121 HOWTO (R_MIPS_SUB, /* type */
1122 0, /* rightshift */
1123 4, /* size (0 = byte, 1 = short, 2 = long) */
1124 64, /* bitsize */
1125 FALSE, /* pc_relative */
1126 0, /* bitpos */
1127 complain_overflow_dont, /* complain_on_overflow */
1128 _bfd_mips_elf_generic_reloc, /* special_function */
1129 "R_MIPS_SUB", /* name */
1130 FALSE, /* partial_inplace */
1131 0, /* src_mask */
1132 MINUS_ONE, /* dst_mask */
1133 FALSE), /* pcrel_offset */
1135 /* Insert the addend as an instruction. */
1136 /* FIXME: Not handled correctly. */
1137 HOWTO (R_MIPS_INSERT_A, /* type */
1138 0, /* rightshift */
1139 2, /* size (0 = byte, 1 = short, 2 = long) */
1140 32, /* bitsize */
1141 FALSE, /* pc_relative */
1142 0, /* bitpos */
1143 complain_overflow_dont, /* complain_on_overflow */
1144 _bfd_mips_elf_generic_reloc, /* special_function */
1145 "R_MIPS_INSERT_A", /* name */
1146 FALSE, /* partial_inplace */
1147 0, /* src_mask */
1148 0xffffffff, /* dst_mask */
1149 FALSE), /* pcrel_offset */
1151 /* Insert the addend as an instruction, and change all relocations
1152 to refer to the old instruction at the address. */
1153 /* FIXME: Not handled correctly. */
1154 HOWTO (R_MIPS_INSERT_B, /* type */
1155 0, /* rightshift */
1156 2, /* size (0 = byte, 1 = short, 2 = long) */
1157 32, /* bitsize */
1158 FALSE, /* pc_relative */
1159 0, /* bitpos */
1160 complain_overflow_dont, /* complain_on_overflow */
1161 _bfd_mips_elf_generic_reloc, /* special_function */
1162 "R_MIPS_INSERT_B", /* name */
1163 FALSE, /* partial_inplace */
1164 0, /* src_mask */
1165 0xffffffff, /* dst_mask */
1166 FALSE), /* pcrel_offset */
1168 /* Delete a 32 bit instruction. */
1169 /* FIXME: Not handled correctly. */
1170 HOWTO (R_MIPS_DELETE, /* type */
1171 0, /* rightshift */
1172 2, /* size (0 = byte, 1 = short, 2 = long) */
1173 32, /* bitsize */
1174 FALSE, /* pc_relative */
1175 0, /* bitpos */
1176 complain_overflow_dont, /* complain_on_overflow */
1177 _bfd_mips_elf_generic_reloc, /* special_function */
1178 "R_MIPS_DELETE", /* name */
1179 FALSE, /* partial_inplace */
1180 0, /* src_mask */
1181 0xffffffff, /* dst_mask */
1182 FALSE), /* pcrel_offset */
1184 /* Get the higher value of a 64 bit addend. */
1185 HOWTO (R_MIPS_HIGHER, /* type */
1186 0, /* rightshift */
1187 2, /* size (0 = byte, 1 = short, 2 = long) */
1188 16, /* bitsize */
1189 FALSE, /* pc_relative */
1190 0, /* bitpos */
1191 complain_overflow_dont, /* complain_on_overflow */
1192 _bfd_mips_elf_generic_reloc, /* special_function */
1193 "R_MIPS_HIGHER", /* name */
1194 FALSE, /* partial_inplace */
1195 0, /* src_mask */
1196 0x0000ffff, /* dst_mask */
1197 FALSE), /* pcrel_offset */
1199 /* Get the highest value of a 64 bit addend. */
1200 HOWTO (R_MIPS_HIGHEST, /* type */
1201 0, /* rightshift */
1202 2, /* size (0 = byte, 1 = short, 2 = long) */
1203 16, /* bitsize */
1204 FALSE, /* pc_relative */
1205 0, /* bitpos */
1206 complain_overflow_dont, /* complain_on_overflow */
1207 _bfd_mips_elf_generic_reloc, /* special_function */
1208 "R_MIPS_HIGHEST", /* name */
1209 FALSE, /* partial_inplace */
1210 0, /* src_mask */
1211 0x0000ffff, /* dst_mask */
1212 FALSE), /* pcrel_offset */
1214 /* High 16 bits of displacement in global offset table. */
1215 HOWTO (R_MIPS_CALL_HI16, /* type */
1216 0, /* rightshift */
1217 2, /* size (0 = byte, 1 = short, 2 = long) */
1218 16, /* bitsize */
1219 FALSE, /* pc_relative */
1220 0, /* bitpos */
1221 complain_overflow_dont, /* complain_on_overflow */
1222 _bfd_mips_elf_generic_reloc, /* special_function */
1223 "R_MIPS_CALL_HI16", /* name */
1224 FALSE, /* partial_inplace */
1225 0, /* src_mask */
1226 0x0000ffff, /* dst_mask */
1227 FALSE), /* pcrel_offset */
1229 /* Low 16 bits of displacement in global offset table. */
1230 HOWTO (R_MIPS_CALL_LO16, /* type */
1231 0, /* rightshift */
1232 2, /* size (0 = byte, 1 = short, 2 = long) */
1233 16, /* bitsize */
1234 FALSE, /* pc_relative */
1235 0, /* bitpos */
1236 complain_overflow_dont, /* complain_on_overflow */
1237 _bfd_mips_elf_generic_reloc, /* special_function */
1238 "R_MIPS_CALL_LO16", /* name */
1239 FALSE, /* partial_inplace */
1240 0, /* src_mask */
1241 0x0000ffff, /* dst_mask */
1242 FALSE), /* pcrel_offset */
1244 /* Section displacement, used by an associated event location section. */
1245 HOWTO (R_MIPS_SCN_DISP, /* type */
1246 0, /* rightshift */
1247 2, /* size (0 = byte, 1 = short, 2 = long) */
1248 32, /* bitsize */
1249 FALSE, /* pc_relative */
1250 0, /* bitpos */
1251 complain_overflow_dont, /* complain_on_overflow */
1252 _bfd_mips_elf_generic_reloc, /* special_function */
1253 "R_MIPS_SCN_DISP", /* name */
1254 FALSE, /* partial_inplace */
1255 0, /* src_mask */
1256 0xffffffff, /* dst_mask */
1257 FALSE), /* pcrel_offset */
1259 HOWTO (R_MIPS_REL16, /* type */
1260 0, /* rightshift */
1261 1, /* size (0 = byte, 1 = short, 2 = long) */
1262 16, /* bitsize */
1263 FALSE, /* pc_relative */
1264 0, /* bitpos */
1265 complain_overflow_signed, /* complain_on_overflow */
1266 _bfd_mips_elf_generic_reloc, /* special_function */
1267 "R_MIPS_REL16", /* name */
1268 FALSE, /* partial_inplace */
1269 0, /* src_mask */
1270 0xffff, /* dst_mask */
1271 FALSE), /* pcrel_offset */
1273 /* These two are obsolete. */
1274 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1275 EMPTY_HOWTO (R_MIPS_PJUMP),
1277 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1278 It must be used for multigot GOT's (and only there). */
1279 HOWTO (R_MIPS_RELGOT, /* type */
1280 0, /* rightshift */
1281 2, /* size (0 = byte, 1 = short, 2 = long) */
1282 32, /* bitsize */
1283 FALSE, /* pc_relative */
1284 0, /* bitpos */
1285 complain_overflow_dont, /* complain_on_overflow */
1286 _bfd_mips_elf_generic_reloc, /* special_function */
1287 "R_MIPS_RELGOT", /* name */
1288 FALSE, /* partial_inplace */
1289 0, /* src_mask */
1290 0xffffffff, /* dst_mask */
1291 FALSE), /* pcrel_offset */
1293 /* Protected jump conversion. This is an optimization hint. No
1294 relocation is required for correctness. */
1295 HOWTO (R_MIPS_JALR, /* type */
1296 0, /* rightshift */
1297 2, /* size (0 = byte, 1 = short, 2 = long) */
1298 32, /* bitsize */
1299 FALSE, /* pc_relative */
1300 0, /* bitpos */
1301 complain_overflow_dont, /* complain_on_overflow */
1302 _bfd_mips_elf_generic_reloc, /* special_function */
1303 "R_MIPS_JALR", /* name */
1304 FALSE, /* partial_inplace */
1305 0, /* src_mask */
1306 0x00000000, /* dst_mask */
1307 FALSE), /* pcrel_offset */
1309 /* TLS relocations. */
1310 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
1311 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
1312 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
1313 EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
1315 /* TLS general dynamic variable reference. */
1316 HOWTO (R_MIPS_TLS_GD, /* type */
1317 0, /* rightshift */
1318 2, /* size (0 = byte, 1 = short, 2 = long) */
1319 16, /* bitsize */
1320 FALSE, /* pc_relative */
1321 0, /* bitpos */
1322 complain_overflow_signed, /* complain_on_overflow */
1323 _bfd_mips_elf_generic_reloc, /* special_function */
1324 "R_MIPS_TLS_GD", /* name */
1325 TRUE, /* partial_inplace */
1326 0x0000ffff, /* src_mask */
1327 0x0000ffff, /* dst_mask */
1328 FALSE), /* pcrel_offset */
1330 /* TLS local dynamic variable reference. */
1331 HOWTO (R_MIPS_TLS_LDM, /* type */
1332 0, /* rightshift */
1333 2, /* size (0 = byte, 1 = short, 2 = long) */
1334 16, /* bitsize */
1335 FALSE, /* pc_relative */
1336 0, /* bitpos */
1337 complain_overflow_signed, /* complain_on_overflow */
1338 _bfd_mips_elf_generic_reloc, /* special_function */
1339 "R_MIPS_TLS_LDM", /* name */
1340 TRUE, /* partial_inplace */
1341 0x0000ffff, /* src_mask */
1342 0x0000ffff, /* dst_mask */
1343 FALSE), /* pcrel_offset */
1345 /* TLS local dynamic offset. */
1346 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
1347 0, /* rightshift */
1348 2, /* size (0 = byte, 1 = short, 2 = long) */
1349 16, /* bitsize */
1350 FALSE, /* pc_relative */
1351 0, /* bitpos */
1352 complain_overflow_signed, /* complain_on_overflow */
1353 _bfd_mips_elf_generic_reloc, /* special_function */
1354 "R_MIPS_TLS_DTPREL_HI16", /* name */
1355 TRUE, /* partial_inplace */
1356 0x0000ffff, /* src_mask */
1357 0x0000ffff, /* dst_mask */
1358 FALSE), /* pcrel_offset */
1360 /* TLS local dynamic offset. */
1361 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
1362 0, /* rightshift */
1363 2, /* size (0 = byte, 1 = short, 2 = long) */
1364 16, /* bitsize */
1365 FALSE, /* pc_relative */
1366 0, /* bitpos */
1367 complain_overflow_signed, /* complain_on_overflow */
1368 _bfd_mips_elf_generic_reloc, /* special_function */
1369 "R_MIPS_TLS_DTPREL_LO16", /* name */
1370 TRUE, /* partial_inplace */
1371 0x0000ffff, /* src_mask */
1372 0x0000ffff, /* dst_mask */
1373 FALSE), /* pcrel_offset */
1375 /* TLS thread pointer offset. */
1376 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
1377 0, /* rightshift */
1378 2, /* size (0 = byte, 1 = short, 2 = long) */
1379 16, /* bitsize */
1380 FALSE, /* pc_relative */
1381 0, /* bitpos */
1382 complain_overflow_signed, /* complain_on_overflow */
1383 _bfd_mips_elf_generic_reloc, /* special_function */
1384 "R_MIPS_TLS_GOTTPREL", /* name */
1385 TRUE, /* partial_inplace */
1386 0x0000ffff, /* src_mask */
1387 0x0000ffff, /* dst_mask */
1388 FALSE), /* pcrel_offset */
1390 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
1391 EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
1393 /* TLS thread pointer offset. */
1394 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
1395 0, /* rightshift */
1396 2, /* size (0 = byte, 1 = short, 2 = long) */
1397 16, /* bitsize */
1398 FALSE, /* pc_relative */
1399 0, /* bitpos */
1400 complain_overflow_signed, /* complain_on_overflow */
1401 _bfd_mips_elf_generic_reloc, /* special_function */
1402 "R_MIPS_TLS_TPREL_HI16", /* name */
1403 TRUE, /* partial_inplace */
1404 0x0000ffff, /* src_mask */
1405 0x0000ffff, /* dst_mask */
1406 FALSE), /* pcrel_offset */
1408 /* TLS thread pointer offset. */
1409 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
1410 0, /* rightshift */
1411 2, /* size (0 = byte, 1 = short, 2 = long) */
1412 16, /* bitsize */
1413 FALSE, /* pc_relative */
1414 0, /* bitpos */
1415 complain_overflow_signed, /* complain_on_overflow */
1416 _bfd_mips_elf_generic_reloc, /* special_function */
1417 "R_MIPS_TLS_TPREL_LO16", /* name */
1418 TRUE, /* partial_inplace */
1419 0x0000ffff, /* src_mask */
1420 0x0000ffff, /* dst_mask */
1421 FALSE), /* pcrel_offset */
1424 static reloc_howto_type mips16_elf64_howto_table_rel[] =
1426 /* The reloc used for the mips16 jump instruction. */
1427 HOWTO (R_MIPS16_26, /* type */
1428 2, /* rightshift */
1429 2, /* size (0 = byte, 1 = short, 2 = long) */
1430 26, /* bitsize */
1431 FALSE, /* pc_relative */
1432 0, /* bitpos */
1433 complain_overflow_dont, /* complain_on_overflow */
1434 /* This needs complex overflow
1435 detection, because the upper four
1436 bits must match the PC. */
1437 mips16_jump_reloc, /* special_function */
1438 "R_MIPS16_26", /* name */
1439 TRUE, /* partial_inplace */
1440 0x3ffffff, /* src_mask */
1441 0x3ffffff, /* dst_mask */
1442 FALSE), /* pcrel_offset */
1444 /* The reloc used for the mips16 gprel instruction. */
1445 HOWTO (R_MIPS16_GPREL, /* type */
1446 0, /* rightshift */
1447 2, /* size (0 = byte, 1 = short, 2 = long) */
1448 16, /* bitsize */
1449 FALSE, /* pc_relative */
1450 0, /* bitpos */
1451 complain_overflow_signed, /* complain_on_overflow */
1452 mips16_gprel_reloc, /* special_function */
1453 "R_MIPS16_GPREL", /* name */
1454 TRUE, /* partial_inplace */
1455 0x0000ffff, /* src_mask */
1456 0x0000ffff, /* dst_mask */
1457 FALSE), /* pcrel_offset */
1459 /* A placeholder for MIPS16 reference to global offset table. */
1460 EMPTY_HOWTO (R_MIPS16_GOT16),
1462 /* A placeholder for MIPS16 16 bit call through global offset table. */
1463 EMPTY_HOWTO (R_MIPS16_CALL16),
1465 /* MIPS16 high 16 bits of symbol value. */
1466 HOWTO (R_MIPS16_HI16, /* type */
1467 16, /* rightshift */
1468 2, /* size (0 = byte, 1 = short, 2 = long) */
1469 16, /* bitsize */
1470 FALSE, /* pc_relative */
1471 0, /* bitpos */
1472 complain_overflow_dont, /* complain_on_overflow */
1473 _bfd_mips_elf_hi16_reloc, /* special_function */
1474 "R_MIPS16_HI16", /* name */
1475 TRUE, /* partial_inplace */
1476 0x0000ffff, /* src_mask */
1477 0x0000ffff, /* dst_mask */
1478 FALSE), /* pcrel_offset */
1480 /* MIPS16 low 16 bits of symbol value. */
1481 HOWTO (R_MIPS16_LO16, /* type */
1482 0, /* rightshift */
1483 2, /* size (0 = byte, 1 = short, 2 = long) */
1484 16, /* bitsize */
1485 FALSE, /* pc_relative */
1486 0, /* bitpos */
1487 complain_overflow_dont, /* complain_on_overflow */
1488 _bfd_mips_elf_lo16_reloc, /* special_function */
1489 "R_MIPS16_LO16", /* name */
1490 TRUE, /* partial_inplace */
1491 0x0000ffff, /* src_mask */
1492 0x0000ffff, /* dst_mask */
1493 FALSE), /* pcrel_offset */
1496 static reloc_howto_type mips16_elf64_howto_table_rela[] =
1498 /* The reloc used for the mips16 jump instruction. */
1499 HOWTO (R_MIPS16_26, /* type */
1500 2, /* rightshift */
1501 2, /* size (0 = byte, 1 = short, 2 = long) */
1502 26, /* bitsize */
1503 FALSE, /* pc_relative */
1504 0, /* bitpos */
1505 complain_overflow_dont, /* complain_on_overflow */
1506 /* This needs complex overflow
1507 detection, because the upper four
1508 bits must match the PC. */
1509 mips16_jump_reloc, /* special_function */
1510 "R_MIPS16_26", /* name */
1511 FALSE, /* partial_inplace */
1512 0x3ffffff, /* src_mask */
1513 0x3ffffff, /* dst_mask */
1514 FALSE), /* pcrel_offset */
1516 /* The reloc used for the mips16 gprel instruction. */
1517 HOWTO (R_MIPS16_GPREL, /* type */
1518 0, /* rightshift */
1519 2, /* size (0 = byte, 1 = short, 2 = long) */
1520 16, /* bitsize */
1521 FALSE, /* pc_relative */
1522 0, /* bitpos */
1523 complain_overflow_signed, /* complain_on_overflow */
1524 mips16_gprel_reloc, /* special_function */
1525 "R_MIPS16_GPREL", /* name */
1526 FALSE, /* partial_inplace */
1527 0x0000ffff, /* src_mask */
1528 0x0000ffff, /* dst_mask */
1529 FALSE), /* pcrel_offset */
1531 /* A placeholder for MIPS16 reference to global offset table. */
1532 EMPTY_HOWTO (R_MIPS16_GOT16),
1534 /* A placeholder for MIPS16 16 bit call through global offset table. */
1535 EMPTY_HOWTO (R_MIPS16_CALL16),
1537 /* MIPS16 high 16 bits of symbol value. */
1538 HOWTO (R_MIPS16_HI16, /* type */
1539 16, /* rightshift */
1540 2, /* size (0 = byte, 1 = short, 2 = long) */
1541 16, /* bitsize */
1542 FALSE, /* pc_relative */
1543 0, /* bitpos */
1544 complain_overflow_dont, /* complain_on_overflow */
1545 _bfd_mips_elf_hi16_reloc, /* special_function */
1546 "R_MIPS16_HI16", /* name */
1547 FALSE, /* partial_inplace */
1548 0x0000ffff, /* src_mask */
1549 0x0000ffff, /* dst_mask */
1550 FALSE), /* pcrel_offset */
1552 /* MIPS16 low 16 bits of symbol value. */
1553 HOWTO (R_MIPS16_LO16, /* type */
1554 0, /* rightshift */
1555 2, /* size (0 = byte, 1 = short, 2 = long) */
1556 16, /* bitsize */
1557 FALSE, /* pc_relative */
1558 0, /* bitpos */
1559 complain_overflow_dont, /* complain_on_overflow */
1560 _bfd_mips_elf_lo16_reloc, /* special_function */
1561 "R_MIPS16_LO16", /* name */
1562 FALSE, /* partial_inplace */
1563 0x0000ffff, /* src_mask */
1564 0x0000ffff, /* dst_mask */
1565 FALSE), /* pcrel_offset */
1568 /* GNU extension to record C++ vtable hierarchy */
1569 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
1570 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
1571 0, /* rightshift */
1572 2, /* size (0 = byte, 1 = short, 2 = long) */
1573 0, /* bitsize */
1574 FALSE, /* pc_relative */
1575 0, /* bitpos */
1576 complain_overflow_dont, /* complain_on_overflow */
1577 NULL, /* special_function */
1578 "R_MIPS_GNU_VTINHERIT", /* name */
1579 FALSE, /* partial_inplace */
1580 0, /* src_mask */
1581 0, /* dst_mask */
1582 FALSE); /* pcrel_offset */
1584 /* GNU extension to record C++ vtable member usage */
1585 static reloc_howto_type elf_mips_gnu_vtentry_howto =
1586 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
1587 0, /* rightshift */
1588 2, /* size (0 = byte, 1 = short, 2 = long) */
1589 0, /* bitsize */
1590 FALSE, /* pc_relative */
1591 0, /* bitpos */
1592 complain_overflow_dont, /* complain_on_overflow */
1593 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1594 "R_MIPS_GNU_VTENTRY", /* name */
1595 FALSE, /* partial_inplace */
1596 0, /* src_mask */
1597 0, /* dst_mask */
1598 FALSE); /* pcrel_offset */
1600 /* 16 bit offset for pc-relative branches. */
1601 static reloc_howto_type elf_mips_gnu_rel16_s2 =
1602 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
1603 2, /* rightshift */
1604 2, /* size (0 = byte, 1 = short, 2 = long) */
1605 16, /* bitsize */
1606 TRUE, /* pc_relative */
1607 0, /* bitpos */
1608 complain_overflow_signed, /* complain_on_overflow */
1609 _bfd_mips_elf_generic_reloc, /* special_function */
1610 "R_MIPS_GNU_REL16_S2", /* name */
1611 TRUE, /* partial_inplace */
1612 0x0000ffff, /* src_mask */
1613 0x0000ffff, /* dst_mask */
1614 TRUE); /* pcrel_offset */
1616 /* 16 bit offset for pc-relative branches. */
1617 static reloc_howto_type elf_mips_gnu_rela16_s2 =
1618 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
1619 2, /* rightshift */
1620 2, /* size (0 = byte, 1 = short, 2 = long) */
1621 16, /* bitsize */
1622 TRUE, /* pc_relative */
1623 0, /* bitpos */
1624 complain_overflow_signed, /* complain_on_overflow */
1625 _bfd_mips_elf_generic_reloc, /* special_function */
1626 "R_MIPS_GNU_REL16_S2", /* name */
1627 FALSE, /* partial_inplace */
1628 0, /* src_mask */
1629 0x0000ffff, /* dst_mask */
1630 TRUE); /* pcrel_offset */
1632 /* Swap in a MIPS 64-bit Rel reloc. */
1634 static void
1635 mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src,
1636 Elf64_Mips_Internal_Rela *dst)
1638 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1639 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1640 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1641 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1642 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1643 dst->r_type = H_GET_8 (abfd, src->r_type);
1644 dst->r_addend = 0;
1647 /* Swap in a MIPS 64-bit Rela reloc. */
1649 static void
1650 mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src,
1651 Elf64_Mips_Internal_Rela *dst)
1653 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1654 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1655 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1656 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1657 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1658 dst->r_type = H_GET_8 (abfd, src->r_type);
1659 dst->r_addend = H_GET_S64 (abfd, src->r_addend);
1662 /* Swap out a MIPS 64-bit Rel reloc. */
1664 static void
1665 mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1666 Elf64_Mips_External_Rel *dst)
1668 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1669 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1670 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1671 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1672 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1673 H_PUT_8 (abfd, src->r_type, dst->r_type);
1676 /* Swap out a MIPS 64-bit Rela reloc. */
1678 static void
1679 mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1680 Elf64_Mips_External_Rela *dst)
1682 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1683 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1684 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1685 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1686 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1687 H_PUT_8 (abfd, src->r_type, dst->r_type);
1688 H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
1691 /* Swap in a MIPS 64-bit Rel reloc. */
1693 static void
1694 mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src,
1695 Elf_Internal_Rela *dst)
1697 Elf64_Mips_Internal_Rela mirel;
1699 mips_elf64_swap_reloc_in (abfd,
1700 (const Elf64_Mips_External_Rel *) src,
1701 &mirel);
1703 dst[0].r_offset = mirel.r_offset;
1704 dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
1705 dst[0].r_addend = 0;
1706 dst[1].r_offset = mirel.r_offset;
1707 dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
1708 dst[1].r_addend = 0;
1709 dst[2].r_offset = mirel.r_offset;
1710 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
1711 dst[2].r_addend = 0;
1714 /* Swap in a MIPS 64-bit Rela reloc. */
1716 static void
1717 mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src,
1718 Elf_Internal_Rela *dst)
1720 Elf64_Mips_Internal_Rela mirela;
1722 mips_elf64_swap_reloca_in (abfd,
1723 (const Elf64_Mips_External_Rela *) src,
1724 &mirela);
1726 dst[0].r_offset = mirela.r_offset;
1727 dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
1728 dst[0].r_addend = mirela.r_addend;
1729 dst[1].r_offset = mirela.r_offset;
1730 dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
1731 dst[1].r_addend = 0;
1732 dst[2].r_offset = mirela.r_offset;
1733 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
1734 dst[2].r_addend = 0;
1737 /* Swap out a MIPS 64-bit Rel reloc. */
1739 static void
1740 mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src,
1741 bfd_byte *dst)
1743 Elf64_Mips_Internal_Rela mirel;
1745 mirel.r_offset = src[0].r_offset;
1746 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1748 mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1749 mirel.r_sym = ELF64_R_SYM (src[0].r_info);
1750 mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1751 mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1752 mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1754 mips_elf64_swap_reloc_out (abfd, &mirel,
1755 (Elf64_Mips_External_Rel *) dst);
1758 /* Swap out a MIPS 64-bit Rela reloc. */
1760 static void
1761 mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
1762 bfd_byte *dst)
1764 Elf64_Mips_Internal_Rela mirela;
1766 mirela.r_offset = src[0].r_offset;
1767 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1768 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
1770 mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1771 mirela.r_sym = ELF64_R_SYM (src[0].r_info);
1772 mirela.r_addend = src[0].r_addend;
1773 BFD_ASSERT(src[1].r_addend == 0);
1774 BFD_ASSERT(src[2].r_addend == 0);
1776 mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1777 mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1778 mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1780 mips_elf64_swap_reloca_out (abfd, &mirela,
1781 (Elf64_Mips_External_Rela *) dst);
1784 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1785 dangerous relocation. */
1787 static bfd_boolean
1788 mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp)
1790 unsigned int count;
1791 asymbol **sym;
1792 unsigned int i;
1794 /* If we've already figured out what GP will be, just return it. */
1795 *pgp = _bfd_get_gp_value (output_bfd);
1796 if (*pgp)
1797 return TRUE;
1799 count = bfd_get_symcount (output_bfd);
1800 sym = bfd_get_outsymbols (output_bfd);
1802 /* The linker script will have created a symbol named `_gp' with the
1803 appropriate value. */
1804 if (sym == NULL)
1805 i = count;
1806 else
1808 for (i = 0; i < count; i++, sym++)
1810 register const char *name;
1812 name = bfd_asymbol_name (*sym);
1813 if (*name == '_' && strcmp (name, "_gp") == 0)
1815 *pgp = bfd_asymbol_value (*sym);
1816 _bfd_set_gp_value (output_bfd, *pgp);
1817 break;
1822 if (i >= count)
1824 /* Only get the error once. */
1825 *pgp = 4;
1826 _bfd_set_gp_value (output_bfd, *pgp);
1827 return FALSE;
1830 return TRUE;
1833 /* We have to figure out the gp value, so that we can adjust the
1834 symbol value correctly. We look up the symbol _gp in the output
1835 BFD. If we can't find it, we're stuck. We cache it in the ELF
1836 target data. We don't need to adjust the symbol value for an
1837 external symbol if we are producing relocatable output. */
1839 static bfd_reloc_status_type
1840 mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
1841 char **error_message, bfd_vma *pgp)
1843 if (bfd_is_und_section (symbol->section)
1844 && ! relocatable)
1846 *pgp = 0;
1847 return bfd_reloc_undefined;
1850 *pgp = _bfd_get_gp_value (output_bfd);
1851 if (*pgp == 0
1852 && (! relocatable
1853 || (symbol->flags & BSF_SECTION_SYM) != 0))
1855 if (relocatable)
1857 /* Make up a value. */
1858 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
1859 _bfd_set_gp_value (output_bfd, *pgp);
1861 else if (!mips_elf64_assign_gp (output_bfd, pgp))
1863 *error_message =
1864 (char *) _("GP relative relocation when _gp not defined");
1865 return bfd_reloc_dangerous;
1869 return bfd_reloc_ok;
1872 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1873 become the offset from the gp register. */
1875 static bfd_reloc_status_type
1876 mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1877 void *data, asection *input_section, bfd *output_bfd,
1878 char **error_message)
1880 bfd_boolean relocatable;
1881 bfd_reloc_status_type ret;
1882 bfd_vma gp;
1884 /* If we're relocating, and this is an external symbol, we don't want
1885 to change anything. */
1886 if (output_bfd != NULL
1887 && (symbol->flags & BSF_SECTION_SYM) == 0
1888 && (symbol->flags & BSF_LOCAL) != 0)
1890 reloc_entry->address += input_section->output_offset;
1891 return bfd_reloc_ok;
1894 if (output_bfd != NULL)
1895 relocatable = TRUE;
1896 else
1898 relocatable = FALSE;
1899 output_bfd = symbol->section->output_section->owner;
1902 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
1903 &gp);
1904 if (ret != bfd_reloc_ok)
1905 return ret;
1907 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1908 input_section, relocatable,
1909 data, gp);
1912 /* Do a R_MIPS_LITERAL relocation. */
1914 static bfd_reloc_status_type
1915 mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1916 void *data, asection *input_section, bfd *output_bfd,
1917 char **error_message)
1919 bfd_boolean relocatable;
1920 bfd_reloc_status_type ret;
1921 bfd_vma gp;
1923 /* R_MIPS_LITERAL relocations are defined for local symbols only. */
1924 if (output_bfd != NULL
1925 && (symbol->flags & BSF_SECTION_SYM) == 0
1926 && (symbol->flags & BSF_LOCAL) != 0)
1928 *error_message = (char *)
1929 _("literal relocation occurs for an external symbol");
1930 return bfd_reloc_outofrange;
1933 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
1934 if (output_bfd != NULL)
1935 relocatable = TRUE;
1936 else
1938 relocatable = FALSE;
1939 output_bfd = symbol->section->output_section->owner;
1942 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
1943 &gp);
1944 if (ret != bfd_reloc_ok)
1945 return ret;
1947 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1948 input_section, relocatable,
1949 data, gp);
1952 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1953 become the offset from the gp register. */
1955 static bfd_reloc_status_type
1956 mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1957 void *data, asection *input_section, bfd *output_bfd,
1958 char **error_message)
1960 bfd_boolean relocatable;
1961 bfd_reloc_status_type ret;
1962 bfd_vma gp;
1963 bfd_vma relocation;
1964 bfd_vma val;
1966 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
1967 if (output_bfd != NULL
1968 && (symbol->flags & BSF_SECTION_SYM) == 0
1969 && (symbol->flags & BSF_LOCAL) != 0)
1971 *error_message = (char *)
1972 _("32bits gp relative relocation occurs for an external symbol");
1973 return bfd_reloc_outofrange;
1976 if (output_bfd != NULL)
1977 relocatable = TRUE;
1978 else
1980 relocatable = FALSE;
1981 output_bfd = symbol->section->output_section->owner;
1984 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
1985 error_message, &gp);
1986 if (ret != bfd_reloc_ok)
1987 return ret;
1989 if (bfd_is_com_section (symbol->section))
1990 relocation = 0;
1991 else
1992 relocation = symbol->value;
1994 relocation += symbol->section->output_section->vma;
1995 relocation += symbol->section->output_offset;
1997 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
1998 return bfd_reloc_outofrange;
2000 /* Set val to the offset into the section or symbol. */
2001 val = reloc_entry->addend;
2003 if (reloc_entry->howto->partial_inplace)
2004 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
2006 /* Adjust val for the final section location and GP value. If we
2007 are producing relocatable output, we don't want to do this for
2008 an external symbol. */
2009 if (! relocatable
2010 || (symbol->flags & BSF_SECTION_SYM) != 0)
2011 val += relocation - gp;
2013 if (reloc_entry->howto->partial_inplace)
2014 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
2015 else
2016 reloc_entry->addend = val;
2018 if (relocatable)
2019 reloc_entry->address += input_section->output_offset;
2021 return bfd_reloc_ok;
2024 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
2025 the rest is at bits 6-10. The bitpos already got right by the howto. */
2027 static bfd_reloc_status_type
2028 mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2029 void *data, asection *input_section, bfd *output_bfd,
2030 char **error_message)
2032 if (reloc_entry->howto->partial_inplace)
2034 reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
2035 | (reloc_entry->addend & 0x00000800) >> 9);
2038 return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
2039 input_section, output_bfd,
2040 error_message);
2043 /* Handle a mips16 jump. */
2045 static bfd_reloc_status_type
2046 mips16_jump_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
2047 asymbol *symbol, void *data ATTRIBUTE_UNUSED,
2048 asection *input_section, bfd *output_bfd,
2049 char **error_message ATTRIBUTE_UNUSED)
2051 if (output_bfd != NULL
2052 && (symbol->flags & BSF_SECTION_SYM) == 0
2053 && (! reloc_entry->howto->partial_inplace
2054 || reloc_entry->addend == 0))
2056 reloc_entry->address += input_section->output_offset;
2057 return bfd_reloc_ok;
2060 /* FIXME. */
2062 static bfd_boolean warned;
2064 if (! warned)
2065 (*_bfd_error_handler)
2066 (_("Linking mips16 objects into %s format is not supported"),
2067 bfd_get_target (input_section->output_section->owner));
2068 warned = TRUE;
2071 return bfd_reloc_undefined;
2074 /* Handle a mips16 GP relative reloc. */
2076 static bfd_reloc_status_type
2077 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2078 void *data, asection *input_section, bfd *output_bfd,
2079 char **error_message)
2081 bfd_boolean relocatable;
2082 bfd_reloc_status_type ret;
2083 bfd_byte *location;
2084 bfd_vma gp;
2086 /* If we're relocating, and this is an external symbol, we don't want
2087 to change anything. */
2088 if (output_bfd != NULL
2089 && (symbol->flags & BSF_SECTION_SYM) == 0
2090 && (symbol->flags & BSF_LOCAL) != 0)
2092 reloc_entry->address += input_section->output_offset;
2093 return bfd_reloc_ok;
2096 if (output_bfd != NULL)
2097 relocatable = TRUE;
2098 else
2100 relocatable = FALSE;
2101 output_bfd = symbol->section->output_section->owner;
2104 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
2105 &gp);
2106 if (ret != bfd_reloc_ok)
2107 return ret;
2109 location = (bfd_byte *) data + reloc_entry->address;
2110 _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
2111 location);
2112 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2113 input_section, relocatable,
2114 data, gp);
2115 _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
2116 location);
2118 return ret;
2121 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
2123 struct elf_reloc_map {
2124 bfd_reloc_code_real_type bfd_val;
2125 enum elf_mips_reloc_type elf_val;
2128 static const struct elf_reloc_map mips_reloc_map[] =
2130 { BFD_RELOC_NONE, R_MIPS_NONE },
2131 { BFD_RELOC_16, R_MIPS_16 },
2132 { BFD_RELOC_32, R_MIPS_32 },
2133 /* There is no BFD reloc for R_MIPS_REL32. */
2134 { BFD_RELOC_64, R_MIPS_64 },
2135 { BFD_RELOC_CTOR, R_MIPS_64 },
2136 { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
2137 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
2138 { BFD_RELOC_LO16, R_MIPS_LO16 },
2139 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
2140 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
2141 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
2142 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
2143 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
2144 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
2145 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
2146 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
2147 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
2148 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
2149 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
2150 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
2151 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
2152 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
2153 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
2154 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
2155 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
2156 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
2157 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
2158 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
2159 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
2160 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
2161 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
2162 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
2163 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
2164 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
2165 { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
2166 { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
2167 { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
2168 { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
2169 { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
2170 { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
2171 { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
2172 { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
2173 { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
2174 { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
2175 { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
2176 { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
2177 { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
2180 static const struct elf_reloc_map mips16_reloc_map[] =
2182 { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
2183 { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
2184 { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
2185 { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
2188 /* Given a BFD reloc type, return a howto structure. */
2190 static reloc_howto_type *
2191 bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
2192 bfd_reloc_code_real_type code)
2194 unsigned int i;
2195 /* FIXME: We default to RELA here instead of choosing the right
2196 relocation variant. */
2197 reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
2198 reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela;
2200 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
2201 i++)
2203 if (mips_reloc_map[i].bfd_val == code)
2204 return &howto_table[(int) mips_reloc_map[i].elf_val];
2207 for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
2208 i++)
2210 if (mips16_reloc_map[i].bfd_val == code)
2211 return &howto16_table[(int) mips16_reloc_map[i].elf_val];
2214 switch (code)
2216 case BFD_RELOC_VTABLE_INHERIT:
2217 return &elf_mips_gnu_vtinherit_howto;
2218 case BFD_RELOC_VTABLE_ENTRY:
2219 return &elf_mips_gnu_vtentry_howto;
2220 case BFD_RELOC_16_PCREL_S2:
2221 return &elf_mips_gnu_rela16_s2;
2222 default:
2223 bfd_set_error (bfd_error_bad_value);
2224 return NULL;
2228 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
2230 static reloc_howto_type *
2231 mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
2233 switch (r_type)
2235 case R_MIPS_GNU_VTINHERIT:
2236 return &elf_mips_gnu_vtinherit_howto;
2237 case R_MIPS_GNU_VTENTRY:
2238 return &elf_mips_gnu_vtentry_howto;
2239 case R_MIPS_GNU_REL16_S2:
2240 if (rela_p)
2241 return &elf_mips_gnu_rela16_s2;
2242 else
2243 return &elf_mips_gnu_rel16_s2;
2244 default:
2245 if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
2247 if (rela_p)
2248 return &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min];
2249 else
2250 return &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min];
2252 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
2253 if (rela_p)
2254 return &mips_elf64_howto_table_rela[r_type];
2255 else
2256 return &mips_elf64_howto_table_rel[r_type];
2257 break;
2261 /* Prevent relocation handling by bfd for MIPS ELF64. */
2263 static void
2264 mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
2265 arelent *cache_ptr ATTRIBUTE_UNUSED,
2266 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
2268 BFD_ASSERT (0);
2271 static void
2272 mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
2273 arelent *cache_ptr ATTRIBUTE_UNUSED,
2274 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
2276 BFD_ASSERT (0);
2279 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
2280 to three relocs, we must tell the user to allocate more space. */
2282 static long
2283 mips_elf64_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
2285 return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
2288 static long
2289 mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
2291 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
2294 /* We must also copy more relocations than the corresponding functions
2295 in elf.c would, so the two following functions are slightly
2296 modified from elf.c, that multiply the external relocation count by
2297 3 to obtain the internal relocation count. */
2299 static long
2300 mips_elf64_canonicalize_reloc (bfd *abfd, sec_ptr section,
2301 arelent **relptr, asymbol **symbols)
2303 arelent *tblptr;
2304 unsigned int i;
2305 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
2307 if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
2308 return -1;
2310 tblptr = section->relocation;
2311 for (i = 0; i < section->reloc_count * 3; i++)
2312 *relptr++ = tblptr++;
2314 *relptr = NULL;
2316 return section->reloc_count * 3;
2319 static long
2320 mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
2321 asymbol **syms)
2323 bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
2324 asection *s;
2325 long ret;
2327 if (elf_dynsymtab (abfd) == 0)
2329 bfd_set_error (bfd_error_invalid_operation);
2330 return -1;
2333 slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
2334 ret = 0;
2335 for (s = abfd->sections; s != NULL; s = s->next)
2337 if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
2338 && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
2339 || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
2341 arelent *p;
2342 long count, i;
2344 if (! (*slurp_relocs) (abfd, s, syms, TRUE))
2345 return -1;
2346 count = s->size / elf_section_data (s)->this_hdr.sh_entsize * 3;
2347 p = s->relocation;
2348 for (i = 0; i < count; i++)
2349 *storage++ = p++;
2350 ret += count;
2354 *storage = NULL;
2356 return ret;
2359 /* Read the relocations from one reloc section. This is mostly copied
2360 from elfcode.h, except for the changes to expand one external
2361 relocation to 3 internal ones. We must unfortunately set
2362 reloc_count to the number of external relocations, because a lot of
2363 generic code seems to depend on this. */
2365 static bfd_boolean
2366 mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
2367 Elf_Internal_Shdr *rel_hdr,
2368 bfd_size_type reloc_count,
2369 arelent *relents, asymbol **symbols,
2370 bfd_boolean dynamic)
2372 void *allocated;
2373 bfd_byte *native_relocs;
2374 arelent *relent;
2375 bfd_vma i;
2376 int entsize;
2377 bfd_boolean rela_p;
2379 allocated = bfd_malloc (rel_hdr->sh_size);
2380 if (allocated == NULL)
2381 return FALSE;
2383 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
2384 || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
2385 != rel_hdr->sh_size))
2386 goto error_return;
2388 native_relocs = allocated;
2390 entsize = rel_hdr->sh_entsize;
2391 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
2392 || entsize == sizeof (Elf64_Mips_External_Rela));
2394 if (entsize == sizeof (Elf64_Mips_External_Rel))
2395 rela_p = FALSE;
2396 else
2397 rela_p = TRUE;
2399 for (i = 0, relent = relents;
2400 i < reloc_count;
2401 i++, native_relocs += entsize)
2403 Elf64_Mips_Internal_Rela rela;
2404 bfd_boolean used_sym, used_ssym;
2405 int ir;
2407 if (entsize == sizeof (Elf64_Mips_External_Rela))
2408 mips_elf64_swap_reloca_in (abfd,
2409 (Elf64_Mips_External_Rela *) native_relocs,
2410 &rela);
2411 else
2412 mips_elf64_swap_reloc_in (abfd,
2413 (Elf64_Mips_External_Rel *) native_relocs,
2414 &rela);
2416 /* Each entry represents exactly three actual relocations. */
2418 used_sym = FALSE;
2419 used_ssym = FALSE;
2420 for (ir = 0; ir < 3; ir++)
2422 enum elf_mips_reloc_type type;
2424 switch (ir)
2426 default:
2427 abort ();
2428 case 0:
2429 type = (enum elf_mips_reloc_type) rela.r_type;
2430 break;
2431 case 1:
2432 type = (enum elf_mips_reloc_type) rela.r_type2;
2433 break;
2434 case 2:
2435 type = (enum elf_mips_reloc_type) rela.r_type3;
2436 break;
2439 /* Some types require symbols, whereas some do not. */
2440 switch (type)
2442 case R_MIPS_NONE:
2443 case R_MIPS_LITERAL:
2444 case R_MIPS_INSERT_A:
2445 case R_MIPS_INSERT_B:
2446 case R_MIPS_DELETE:
2447 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2448 break;
2450 default:
2451 if (! used_sym)
2453 if (rela.r_sym == 0)
2454 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2455 else
2457 asymbol **ps, *s;
2459 ps = symbols + rela.r_sym - 1;
2460 s = *ps;
2461 if ((s->flags & BSF_SECTION_SYM) == 0)
2462 relent->sym_ptr_ptr = ps;
2463 else
2464 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
2467 used_sym = TRUE;
2469 else if (! used_ssym)
2471 switch (rela.r_ssym)
2473 case RSS_UNDEF:
2474 relent->sym_ptr_ptr =
2475 bfd_abs_section_ptr->symbol_ptr_ptr;
2476 break;
2478 case RSS_GP:
2479 case RSS_GP0:
2480 case RSS_LOC:
2481 /* FIXME: I think these need to be handled using
2482 special howto structures. */
2483 BFD_ASSERT (0);
2484 break;
2486 default:
2487 BFD_ASSERT (0);
2488 break;
2491 used_ssym = TRUE;
2493 else
2494 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2496 break;
2499 /* The address of an ELF reloc is section relative for an
2500 object file, and absolute for an executable file or
2501 shared library. The address of a BFD reloc is always
2502 section relative. */
2503 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
2504 relent->address = rela.r_offset;
2505 else
2506 relent->address = rela.r_offset - asect->vma;
2508 relent->addend = rela.r_addend;
2510 relent->howto = mips_elf64_rtype_to_howto (type, rela_p);
2512 ++relent;
2516 asect->reloc_count += (relent - relents) / 3;
2518 if (allocated != NULL)
2519 free (allocated);
2521 return TRUE;
2523 error_return:
2524 if (allocated != NULL)
2525 free (allocated);
2526 return FALSE;
2529 /* Read the relocations. On Irix 6, there can be two reloc sections
2530 associated with a single data section. This is copied from
2531 elfcode.h as well, with changes as small as accounting for 3
2532 internal relocs per external reloc and resetting reloc_count to
2533 zero before processing the relocs of a section. */
2535 static bfd_boolean
2536 mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
2537 asymbol **symbols, bfd_boolean dynamic)
2539 struct bfd_elf_section_data * const d = elf_section_data (asect);
2540 Elf_Internal_Shdr *rel_hdr;
2541 Elf_Internal_Shdr *rel_hdr2;
2542 bfd_size_type reloc_count;
2543 bfd_size_type reloc_count2;
2544 arelent *relents;
2545 bfd_size_type amt;
2547 if (asect->relocation != NULL)
2548 return TRUE;
2550 if (! dynamic)
2552 if ((asect->flags & SEC_RELOC) == 0
2553 || asect->reloc_count == 0)
2554 return TRUE;
2556 rel_hdr = &d->rel_hdr;
2557 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2558 rel_hdr2 = d->rel_hdr2;
2559 reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
2561 BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
2562 BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
2563 || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
2566 else
2568 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
2569 case because relocations against this section may use the
2570 dynamic symbol table, and in that case bfd_section_from_shdr
2571 in elf.c does not update the RELOC_COUNT. */
2572 if (asect->size == 0)
2573 return TRUE;
2575 rel_hdr = &d->this_hdr;
2576 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2577 rel_hdr2 = NULL;
2578 reloc_count2 = 0;
2581 /* Allocate space for 3 arelent structures for each Rel structure. */
2582 amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
2583 relents = bfd_alloc (abfd, amt);
2584 if (relents == NULL)
2585 return FALSE;
2587 /* The slurp_one_reloc_table routine increments reloc_count. */
2588 asect->reloc_count = 0;
2590 if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2591 rel_hdr, reloc_count,
2592 relents,
2593 symbols, dynamic))
2594 return FALSE;
2595 if (d->rel_hdr2 != NULL)
2597 if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2598 rel_hdr2, reloc_count2,
2599 relents + reloc_count * 3,
2600 symbols, dynamic))
2601 return FALSE;
2604 asect->relocation = relents;
2605 return TRUE;
2608 /* Write out the relocations. */
2610 static void
2611 mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
2613 bfd_boolean *failedp = data;
2614 int count;
2615 Elf_Internal_Shdr *rel_hdr;
2616 unsigned int idx;
2618 /* If we have already failed, don't do anything. */
2619 if (*failedp)
2620 return;
2622 if ((sec->flags & SEC_RELOC) == 0)
2623 return;
2625 /* The linker backend writes the relocs out itself, and sets the
2626 reloc_count field to zero to inhibit writing them here. Also,
2627 sometimes the SEC_RELOC flag gets set even when there aren't any
2628 relocs. */
2629 if (sec->reloc_count == 0)
2630 return;
2632 /* We can combine up to three relocs that refer to the same address
2633 if the latter relocs have no associated symbol. */
2634 count = 0;
2635 for (idx = 0; idx < sec->reloc_count; idx++)
2637 bfd_vma addr;
2638 unsigned int i;
2640 ++count;
2642 addr = sec->orelocation[idx]->address;
2643 for (i = 0; i < 2; i++)
2645 arelent *r;
2647 if (idx + 1 >= sec->reloc_count)
2648 break;
2649 r = sec->orelocation[idx + 1];
2650 if (r->address != addr
2651 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2652 || (*r->sym_ptr_ptr)->value != 0)
2653 break;
2655 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2657 ++idx;
2661 rel_hdr = &elf_section_data (sec)->rel_hdr;
2663 /* Do the actual relocation. */
2665 if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
2666 mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
2667 else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
2668 mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
2669 else
2670 BFD_ASSERT (0);
2673 static void
2674 mips_elf64_write_rel (bfd *abfd, asection *sec,
2675 Elf_Internal_Shdr *rel_hdr,
2676 int *count, void *data)
2678 bfd_boolean *failedp = data;
2679 Elf64_Mips_External_Rel *ext_rel;
2680 unsigned int idx;
2681 asymbol *last_sym = 0;
2682 int last_sym_idx = 0;
2684 rel_hdr->sh_size = rel_hdr->sh_entsize * *count;
2685 rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size);
2686 if (rel_hdr->contents == NULL)
2688 *failedp = TRUE;
2689 return;
2692 ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
2693 for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
2695 arelent *ptr;
2696 Elf64_Mips_Internal_Rela int_rel;
2697 asymbol *sym;
2698 int n;
2699 unsigned int i;
2701 ptr = sec->orelocation[idx];
2703 /* The address of an ELF reloc is section relative for an object
2704 file, and absolute for an executable file or shared library.
2705 The address of a BFD reloc is always section relative. */
2706 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2707 int_rel.r_offset = ptr->address;
2708 else
2709 int_rel.r_offset = ptr->address + sec->vma;
2711 sym = *ptr->sym_ptr_ptr;
2712 if (sym == last_sym)
2713 n = last_sym_idx;
2714 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2715 n = STN_UNDEF;
2716 else
2718 last_sym = sym;
2719 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2720 if (n < 0)
2722 *failedp = TRUE;
2723 return;
2725 last_sym_idx = n;
2728 int_rel.r_sym = n;
2729 int_rel.r_ssym = RSS_UNDEF;
2731 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2732 && ! _bfd_elf_validate_reloc (abfd, ptr))
2734 *failedp = TRUE;
2735 return;
2738 int_rel.r_type = ptr->howto->type;
2739 int_rel.r_type2 = (int) R_MIPS_NONE;
2740 int_rel.r_type3 = (int) R_MIPS_NONE;
2742 for (i = 0; i < 2; i++)
2744 arelent *r;
2746 if (idx + 1 >= sec->reloc_count)
2747 break;
2748 r = sec->orelocation[idx + 1];
2749 if (r->address != ptr->address
2750 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2751 || (*r->sym_ptr_ptr)->value != 0)
2752 break;
2754 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2756 if (i == 0)
2757 int_rel.r_type2 = r->howto->type;
2758 else
2759 int_rel.r_type3 = r->howto->type;
2761 ++idx;
2764 mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
2767 BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
2768 == *count);
2771 static void
2772 mips_elf64_write_rela (bfd *abfd, asection *sec,
2773 Elf_Internal_Shdr *rela_hdr,
2774 int *count, void *data)
2776 bfd_boolean *failedp = data;
2777 Elf64_Mips_External_Rela *ext_rela;
2778 unsigned int idx;
2779 asymbol *last_sym = 0;
2780 int last_sym_idx = 0;
2782 rela_hdr->sh_size = rela_hdr->sh_entsize * *count;
2783 rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
2784 if (rela_hdr->contents == NULL)
2786 *failedp = TRUE;
2787 return;
2790 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
2791 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
2793 arelent *ptr;
2794 Elf64_Mips_Internal_Rela int_rela;
2795 asymbol *sym;
2796 int n;
2797 unsigned int i;
2799 ptr = sec->orelocation[idx];
2801 /* The address of an ELF reloc is section relative for an object
2802 file, and absolute for an executable file or shared library.
2803 The address of a BFD reloc is always section relative. */
2804 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2805 int_rela.r_offset = ptr->address;
2806 else
2807 int_rela.r_offset = ptr->address + sec->vma;
2809 sym = *ptr->sym_ptr_ptr;
2810 if (sym == last_sym)
2811 n = last_sym_idx;
2812 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2813 n = STN_UNDEF;
2814 else
2816 last_sym = sym;
2817 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2818 if (n < 0)
2820 *failedp = TRUE;
2821 return;
2823 last_sym_idx = n;
2826 int_rela.r_sym = n;
2827 int_rela.r_addend = ptr->addend;
2828 int_rela.r_ssym = RSS_UNDEF;
2830 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2831 && ! _bfd_elf_validate_reloc (abfd, ptr))
2833 *failedp = TRUE;
2834 return;
2837 int_rela.r_type = ptr->howto->type;
2838 int_rela.r_type2 = (int) R_MIPS_NONE;
2839 int_rela.r_type3 = (int) R_MIPS_NONE;
2841 for (i = 0; i < 2; i++)
2843 arelent *r;
2845 if (idx + 1 >= sec->reloc_count)
2846 break;
2847 r = sec->orelocation[idx + 1];
2848 if (r->address != ptr->address
2849 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2850 || (*r->sym_ptr_ptr)->value != 0)
2851 break;
2853 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2855 if (i == 0)
2856 int_rela.r_type2 = r->howto->type;
2857 else
2858 int_rela.r_type3 = r->howto->type;
2860 ++idx;
2863 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
2866 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
2867 == *count);
2870 /* Set the right machine number for a MIPS ELF file. */
2872 static bfd_boolean
2873 mips_elf64_object_p (bfd *abfd)
2875 unsigned long mach;
2877 /* Irix 6 is broken. Object file symbol tables are not always
2878 sorted correctly such that local symbols precede global symbols,
2879 and the sh_info field in the symbol table is not always right. */
2880 if (elf64_mips_irix_compat (abfd) != ict_none)
2881 elf_bad_symtab (abfd) = TRUE;
2883 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
2884 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
2885 return TRUE;
2888 /* Depending on the target vector we generate some version of Irix
2889 executables or "normal" MIPS ELF ABI executables. */
2890 static irix_compat_t
2891 elf64_mips_irix_compat (bfd *abfd)
2893 if ((abfd->xvec == &bfd_elf64_bigmips_vec)
2894 || (abfd->xvec == &bfd_elf64_littlemips_vec))
2895 return ict_irix6;
2896 else
2897 return ict_none;
2900 /* Support for core dump NOTE sections. */
2901 static bfd_boolean
2902 elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
2904 int offset;
2905 unsigned int size;
2907 switch (note->descsz)
2909 default:
2910 return FALSE;
2912 case 480: /* Linux/MIPS - N64 kernel */
2913 /* pr_cursig */
2914 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
2916 /* pr_pid */
2917 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 32);
2919 /* pr_reg */
2920 offset = 112;
2921 size = 360;
2923 break;
2926 /* Make a ".reg/999" section. */
2927 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
2928 size, note->descpos + offset);
2931 static bfd_boolean
2932 elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
2934 switch (note->descsz)
2936 default:
2937 return FALSE;
2939 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
2940 elf_tdata (abfd)->core_program
2941 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
2942 elf_tdata (abfd)->core_command
2943 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
2946 /* Note that for some reason, a spurious space is tacked
2947 onto the end of the args in some (at least one anyway)
2948 implementations, so strip it off if it exists. */
2951 char *command = elf_tdata (abfd)->core_command;
2952 int n = strlen (command);
2954 if (0 < n && command[n - 1] == ' ')
2955 command[n - 1] = '\0';
2958 return TRUE;
2961 /* ECOFF swapping routines. These are used when dealing with the
2962 .mdebug section, which is in the ECOFF debugging format. */
2963 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
2965 /* Symbol table magic number. */
2966 magicSym2,
2967 /* Alignment of debugging information. E.g., 4. */
2969 /* Sizes of external symbolic information. */
2970 sizeof (struct hdr_ext),
2971 sizeof (struct dnr_ext),
2972 sizeof (struct pdr_ext),
2973 sizeof (struct sym_ext),
2974 sizeof (struct opt_ext),
2975 sizeof (struct fdr_ext),
2976 sizeof (struct rfd_ext),
2977 sizeof (struct ext_ext),
2978 /* Functions to swap in external symbolic data. */
2979 ecoff_swap_hdr_in,
2980 ecoff_swap_dnr_in,
2981 ecoff_swap_pdr_in,
2982 ecoff_swap_sym_in,
2983 ecoff_swap_opt_in,
2984 ecoff_swap_fdr_in,
2985 ecoff_swap_rfd_in,
2986 ecoff_swap_ext_in,
2987 _bfd_ecoff_swap_tir_in,
2988 _bfd_ecoff_swap_rndx_in,
2989 /* Functions to swap out external symbolic data. */
2990 ecoff_swap_hdr_out,
2991 ecoff_swap_dnr_out,
2992 ecoff_swap_pdr_out,
2993 ecoff_swap_sym_out,
2994 ecoff_swap_opt_out,
2995 ecoff_swap_fdr_out,
2996 ecoff_swap_rfd_out,
2997 ecoff_swap_ext_out,
2998 _bfd_ecoff_swap_tir_out,
2999 _bfd_ecoff_swap_rndx_out,
3000 /* Function to read in symbolic data. */
3001 _bfd_mips_elf_read_ecoff_info
3004 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
3005 standard ELF. This structure is used to redirect the relocation
3006 handling routines. */
3008 const struct elf_size_info mips_elf64_size_info =
3010 sizeof (Elf64_External_Ehdr),
3011 sizeof (Elf64_External_Phdr),
3012 sizeof (Elf64_External_Shdr),
3013 sizeof (Elf64_Mips_External_Rel),
3014 sizeof (Elf64_Mips_External_Rela),
3015 sizeof (Elf64_External_Sym),
3016 sizeof (Elf64_External_Dyn),
3017 sizeof (Elf_External_Note),
3018 4, /* hash-table entry size */
3019 3, /* internal relocations per external relocations */
3020 64, /* arch_size */
3021 3, /* log_file_align */
3022 ELFCLASS64,
3023 EV_CURRENT,
3024 bfd_elf64_write_out_phdrs,
3025 bfd_elf64_write_shdrs_and_ehdr,
3026 mips_elf64_write_relocs,
3027 bfd_elf64_swap_symbol_in,
3028 bfd_elf64_swap_symbol_out,
3029 mips_elf64_slurp_reloc_table,
3030 bfd_elf64_slurp_symbol_table,
3031 bfd_elf64_swap_dyn_in,
3032 bfd_elf64_swap_dyn_out,
3033 mips_elf64_be_swap_reloc_in,
3034 mips_elf64_be_swap_reloc_out,
3035 mips_elf64_be_swap_reloca_in,
3036 mips_elf64_be_swap_reloca_out
3039 #define ELF_ARCH bfd_arch_mips
3040 #define ELF_MACHINE_CODE EM_MIPS
3042 #define elf_backend_collect TRUE
3043 #define elf_backend_type_change_ok TRUE
3044 #define elf_backend_can_gc_sections TRUE
3045 #define elf_info_to_howto mips_elf64_info_to_howto_rela
3046 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
3047 #define elf_backend_object_p mips_elf64_object_p
3048 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
3049 #define elf_backend_section_processing _bfd_mips_elf_section_processing
3050 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
3051 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
3052 #define elf_backend_section_from_bfd_section \
3053 _bfd_mips_elf_section_from_bfd_section
3054 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
3055 #define elf_backend_link_output_symbol_hook \
3056 _bfd_mips_elf_link_output_symbol_hook
3057 #define elf_backend_create_dynamic_sections \
3058 _bfd_mips_elf_create_dynamic_sections
3059 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
3060 #define elf_backend_adjust_dynamic_symbol \
3061 _bfd_mips_elf_adjust_dynamic_symbol
3062 #define elf_backend_always_size_sections \
3063 _bfd_mips_elf_always_size_sections
3064 #define elf_backend_size_dynamic_sections \
3065 _bfd_mips_elf_size_dynamic_sections
3066 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
3067 #define elf_backend_finish_dynamic_symbol \
3068 _bfd_mips_elf_finish_dynamic_symbol
3069 #define elf_backend_finish_dynamic_sections \
3070 _bfd_mips_elf_finish_dynamic_sections
3071 #define elf_backend_final_write_processing \
3072 _bfd_mips_elf_final_write_processing
3073 #define elf_backend_additional_program_headers \
3074 _bfd_mips_elf_additional_program_headers
3075 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
3076 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
3077 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
3078 #define elf_backend_copy_indirect_symbol \
3079 _bfd_mips_elf_copy_indirect_symbol
3080 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
3081 #define elf_backend_ignore_discarded_relocs \
3082 _bfd_mips_elf_ignore_discarded_relocs
3083 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
3084 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
3085 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
3086 #define elf_backend_size_info mips_elf64_size_info
3088 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus
3089 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo
3091 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
3093 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
3094 work better/work only in RELA, so we default to this. */
3095 #define elf_backend_may_use_rel_p 1
3096 #define elf_backend_may_use_rela_p 1
3097 #define elf_backend_default_use_rela_p 1
3099 #define elf_backend_write_section _bfd_mips_elf_write_section
3101 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
3102 MIPS-specific function only applies to IRIX5, which had no 64-bit
3103 ABI. */
3104 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
3105 #define bfd_elf64_find_inliner_info _bfd_mips_elf_find_inliner_info
3106 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
3107 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
3108 #define bfd_elf64_bfd_get_relocated_section_contents \
3109 _bfd_elf_mips_get_relocated_section_contents
3110 #define bfd_elf64_bfd_link_hash_table_create \
3111 _bfd_mips_elf_link_hash_table_create
3112 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
3113 #define bfd_elf64_bfd_merge_private_bfd_data \
3114 _bfd_mips_elf_merge_private_bfd_data
3115 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
3116 #define bfd_elf64_bfd_print_private_bfd_data \
3117 _bfd_mips_elf_print_private_bfd_data
3119 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
3120 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
3121 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
3122 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
3123 #define bfd_elf64_bfd_relax_section _bfd_mips_relax_section
3125 /* MIPS ELF64 archive functions. */
3126 #define bfd_elf64_archive_functions
3127 extern bfd_boolean bfd_elf64_archive_slurp_armap
3128 (bfd *);
3129 extern bfd_boolean bfd_elf64_archive_write_armap
3130 (bfd *, unsigned int, struct orl *, unsigned int, int);
3131 #define bfd_elf64_archive_slurp_extended_name_table \
3132 _bfd_archive_coff_slurp_extended_name_table
3133 #define bfd_elf64_archive_construct_extended_name_table \
3134 _bfd_archive_coff_construct_extended_name_table
3135 #define bfd_elf64_archive_truncate_arname \
3136 _bfd_archive_coff_truncate_arname
3137 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
3138 #define bfd_elf64_archive_openr_next_archived_file \
3139 _bfd_archive_coff_openr_next_archived_file
3140 #define bfd_elf64_archive_get_elt_at_index \
3141 _bfd_archive_coff_get_elt_at_index
3142 #define bfd_elf64_archive_generic_stat_arch_elt \
3143 _bfd_archive_coff_generic_stat_arch_elt
3144 #define bfd_elf64_archive_update_armap_timestamp \
3145 _bfd_archive_coff_update_armap_timestamp
3147 /* The SGI style (n)64 NewABI. */
3148 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
3149 #define TARGET_LITTLE_NAME "elf64-littlemips"
3150 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
3151 #define TARGET_BIG_NAME "elf64-bigmips"
3153 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
3154 a value of 0x1000, and we are compatible.
3155 FIXME: How does this affect NewABI? */
3156 #define ELF_MAXPAGESIZE 0x1000
3158 #include "elf64-target.h"
3160 /* The SYSV-style 'traditional' (n)64 NewABI. */
3161 #undef TARGET_LITTLE_SYM
3162 #undef TARGET_LITTLE_NAME
3163 #undef TARGET_BIG_SYM
3164 #undef TARGET_BIG_NAME
3166 #undef ELF_MAXPAGESIZE
3168 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
3169 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
3170 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
3171 #define TARGET_BIG_NAME "elf64-tradbigmips"
3173 /* The SVR4 MIPS ABI says that this should be 0x10000, and Linux uses
3174 page sizes of up to that limit, so we need to respect it. */
3175 #define ELF_MAXPAGESIZE 0x10000
3176 #define elf64_bed elf64_tradbed
3178 /* Include the target file again for this target. */
3179 #include "elf64-target.h"