* elf32-mips.c (_bfd_mips_elf32_gprel16_reloc): Reject
[binutils.git] / bfd / elf64-mips.c
blobb36743562fa94d4bab4955a2c4c0d2d1179e0b38
1 /* MIPS-specific support for 64-bit ELF
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 */
640 /* The relocation table used for SHT_RELA sections. */
642 static reloc_howto_type mips_elf64_howto_table_rela[] =
644 /* No relocation. */
645 HOWTO (R_MIPS_NONE, /* type */
646 0, /* rightshift */
647 0, /* size (0 = byte, 1 = short, 2 = long) */
648 0, /* bitsize */
649 FALSE, /* pc_relative */
650 0, /* bitpos */
651 complain_overflow_dont, /* complain_on_overflow */
652 _bfd_mips_elf_generic_reloc, /* special_function */
653 "R_MIPS_NONE", /* name */
654 FALSE, /* partial_inplace */
655 0, /* src_mask */
656 0, /* dst_mask */
657 FALSE), /* pcrel_offset */
659 /* 16 bit relocation. */
660 HOWTO (R_MIPS_16, /* type */
661 0, /* rightshift */
662 2, /* size (0 = byte, 1 = short, 2 = long) */
663 16, /* bitsize */
664 FALSE, /* pc_relative */
665 0, /* bitpos */
666 complain_overflow_signed, /* complain_on_overflow */
667 _bfd_mips_elf_generic_reloc, /* special_function */
668 "R_MIPS_16", /* name */
669 FALSE, /* partial_inplace */
670 0, /* src_mask */
671 0x0000ffff, /* dst_mask */
672 FALSE), /* pcrel_offset */
674 /* 32 bit relocation. */
675 HOWTO (R_MIPS_32, /* type */
676 0, /* rightshift */
677 2, /* size (0 = byte, 1 = short, 2 = long) */
678 32, /* bitsize */
679 FALSE, /* pc_relative */
680 0, /* bitpos */
681 complain_overflow_dont, /* complain_on_overflow */
682 _bfd_mips_elf_generic_reloc, /* special_function */
683 "R_MIPS_32", /* name */
684 FALSE, /* partial_inplace */
685 0, /* src_mask */
686 0xffffffff, /* dst_mask */
687 FALSE), /* pcrel_offset */
689 /* 32 bit symbol relative relocation. */
690 HOWTO (R_MIPS_REL32, /* type */
691 0, /* rightshift */
692 2, /* size (0 = byte, 1 = short, 2 = long) */
693 32, /* bitsize */
694 FALSE, /* pc_relative */
695 0, /* bitpos */
696 complain_overflow_dont, /* complain_on_overflow */
697 _bfd_mips_elf_generic_reloc, /* special_function */
698 "R_MIPS_REL32", /* name */
699 FALSE, /* partial_inplace */
700 0, /* src_mask */
701 0xffffffff, /* dst_mask */
702 FALSE), /* pcrel_offset */
704 /* 26 bit jump address. */
705 HOWTO (R_MIPS_26, /* type */
706 2, /* rightshift */
707 2, /* size (0 = byte, 1 = short, 2 = long) */
708 26, /* bitsize */
709 FALSE, /* pc_relative */
710 0, /* bitpos */
711 complain_overflow_dont, /* complain_on_overflow */
712 /* This needs complex overflow
713 detection, because the upper 36
714 bits must match the PC + 4. */
715 _bfd_mips_elf_generic_reloc, /* special_function */
716 "R_MIPS_26", /* name */
717 FALSE, /* partial_inplace */
718 0, /* src_mask */
719 0x03ffffff, /* dst_mask */
720 FALSE), /* pcrel_offset */
722 /* High 16 bits of symbol value. */
723 HOWTO (R_MIPS_HI16, /* type */
724 0, /* rightshift */
725 2, /* size (0 = byte, 1 = short, 2 = long) */
726 16, /* bitsize */
727 FALSE, /* pc_relative */
728 0, /* bitpos */
729 complain_overflow_dont, /* complain_on_overflow */
730 _bfd_mips_elf_generic_reloc, /* special_function */
731 "R_MIPS_HI16", /* name */
732 FALSE, /* partial_inplace */
733 0, /* src_mask */
734 0x0000ffff, /* dst_mask */
735 FALSE), /* pcrel_offset */
737 /* Low 16 bits of symbol value. */
738 HOWTO (R_MIPS_LO16, /* type */
739 0, /* rightshift */
740 2, /* size (0 = byte, 1 = short, 2 = long) */
741 16, /* bitsize */
742 FALSE, /* pc_relative */
743 0, /* bitpos */
744 complain_overflow_dont, /* complain_on_overflow */
745 _bfd_mips_elf_generic_reloc, /* special_function */
746 "R_MIPS_LO16", /* name */
747 FALSE, /* partial_inplace */
748 0, /* src_mask */
749 0x0000ffff, /* dst_mask */
750 FALSE), /* pcrel_offset */
752 /* GP relative reference. */
753 HOWTO (R_MIPS_GPREL16, /* type */
754 0, /* rightshift */
755 2, /* size (0 = byte, 1 = short, 2 = long) */
756 16, /* bitsize */
757 FALSE, /* pc_relative */
758 0, /* bitpos */
759 complain_overflow_signed, /* complain_on_overflow */
760 mips_elf64_gprel16_reloc, /* special_function */
761 "R_MIPS_GPREL16", /* name */
762 FALSE, /* partial_inplace */
763 0, /* src_mask */
764 0x0000ffff, /* dst_mask */
765 FALSE), /* pcrel_offset */
767 /* Reference to literal section. */
768 HOWTO (R_MIPS_LITERAL, /* type */
769 0, /* rightshift */
770 2, /* size (0 = byte, 1 = short, 2 = long) */
771 16, /* bitsize */
772 FALSE, /* pc_relative */
773 0, /* bitpos */
774 complain_overflow_signed, /* complain_on_overflow */
775 mips_elf64_literal_reloc, /* special_function */
776 "R_MIPS_LITERAL", /* name */
777 FALSE, /* partial_inplace */
778 0, /* src_mask */
779 0x0000ffff, /* dst_mask */
780 FALSE), /* pcrel_offset */
782 /* Reference to global offset table. */
783 HOWTO (R_MIPS_GOT16, /* type */
784 0, /* rightshift */
785 2, /* size (0 = byte, 1 = short, 2 = long) */
786 16, /* bitsize */
787 FALSE, /* pc_relative */
788 0, /* bitpos */
789 complain_overflow_signed, /* complain_on_overflow */
790 _bfd_mips_elf_generic_reloc, /* special_function */
791 "R_MIPS_GOT16", /* name */
792 FALSE, /* partial_inplace */
793 0, /* src_mask */
794 0x0000ffff, /* dst_mask */
795 FALSE), /* pcrel_offset */
797 /* 16 bit PC relative reference. */
798 HOWTO (R_MIPS_PC16, /* type */
799 0, /* rightshift */
800 2, /* size (0 = byte, 1 = short, 2 = long) */
801 16, /* bitsize */
802 TRUE, /* pc_relative */
803 0, /* bitpos */
804 complain_overflow_signed, /* complain_on_overflow */
805 _bfd_mips_elf_generic_reloc, /* special_function */
806 "R_MIPS_PC16", /* name */
807 FALSE, /* partial_inplace */
808 0, /* src_mask */
809 0x0000ffff, /* dst_mask */
810 TRUE), /* pcrel_offset */
812 /* 16 bit call through global offset table. */
813 HOWTO (R_MIPS_CALL16, /* type */
814 0, /* rightshift */
815 2, /* size (0 = byte, 1 = short, 2 = long) */
816 16, /* bitsize */
817 FALSE, /* pc_relative */
818 0, /* bitpos */
819 complain_overflow_signed, /* complain_on_overflow */
820 _bfd_mips_elf_generic_reloc, /* special_function */
821 "R_MIPS_CALL16", /* name */
822 FALSE, /* partial_inplace */
823 0, /* src_mask */
824 0x0000ffff, /* dst_mask */
825 FALSE), /* pcrel_offset */
827 /* 32 bit GP relative reference. */
828 HOWTO (R_MIPS_GPREL32, /* type */
829 0, /* rightshift */
830 2, /* size (0 = byte, 1 = short, 2 = long) */
831 32, /* bitsize */
832 FALSE, /* pc_relative */
833 0, /* bitpos */
834 complain_overflow_dont, /* complain_on_overflow */
835 mips_elf64_gprel32_reloc, /* special_function */
836 "R_MIPS_GPREL32", /* name */
837 FALSE, /* partial_inplace */
838 0, /* src_mask */
839 0xffffffff, /* dst_mask */
840 FALSE), /* pcrel_offset */
842 EMPTY_HOWTO (13),
843 EMPTY_HOWTO (14),
844 EMPTY_HOWTO (15),
846 /* A 5 bit shift field. */
847 HOWTO (R_MIPS_SHIFT5, /* type */
848 0, /* rightshift */
849 2, /* size (0 = byte, 1 = short, 2 = long) */
850 5, /* bitsize */
851 FALSE, /* pc_relative */
852 6, /* bitpos */
853 complain_overflow_bitfield, /* complain_on_overflow */
854 _bfd_mips_elf_generic_reloc, /* special_function */
855 "R_MIPS_SHIFT5", /* name */
856 FALSE, /* partial_inplace */
857 0, /* src_mask */
858 0x000007c0, /* dst_mask */
859 FALSE), /* pcrel_offset */
861 /* A 6 bit shift field. */
862 HOWTO (R_MIPS_SHIFT6, /* type */
863 0, /* rightshift */
864 2, /* size (0 = byte, 1 = short, 2 = long) */
865 6, /* bitsize */
866 FALSE, /* pc_relative */
867 6, /* bitpos */
868 complain_overflow_bitfield, /* complain_on_overflow */
869 mips_elf64_shift6_reloc, /* special_function */
870 "R_MIPS_SHIFT6", /* name */
871 FALSE, /* partial_inplace */
872 0, /* src_mask */
873 0x000007c4, /* dst_mask */
874 FALSE), /* pcrel_offset */
876 /* 64 bit relocation. */
877 HOWTO (R_MIPS_64, /* type */
878 0, /* rightshift */
879 4, /* size (0 = byte, 1 = short, 2 = long) */
880 64, /* 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_64", /* name */
886 FALSE, /* partial_inplace */
887 0, /* src_mask */
888 MINUS_ONE, /* dst_mask */
889 FALSE), /* pcrel_offset */
891 /* Displacement in the global offset table. */
892 HOWTO (R_MIPS_GOT_DISP, /* 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_signed, /* complain_on_overflow */
899 _bfd_mips_elf_generic_reloc, /* special_function */
900 "R_MIPS_GOT_DISP", /* name */
901 FALSE, /* partial_inplace */
902 0, /* src_mask */
903 0x0000ffff, /* dst_mask */
904 FALSE), /* pcrel_offset */
906 /* Displacement to page pointer in the global offset table. */
907 HOWTO (R_MIPS_GOT_PAGE, /* 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 _bfd_mips_elf_generic_reloc, /* special_function */
915 "R_MIPS_GOT_PAGE", /* name */
916 FALSE, /* partial_inplace */
917 0, /* src_mask */
918 0x0000ffff, /* dst_mask */
919 FALSE), /* pcrel_offset */
921 /* Offset from page pointer in the global offset table. */
922 HOWTO (R_MIPS_GOT_OFST, /* 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 _bfd_mips_elf_generic_reloc, /* special_function */
930 "R_MIPS_GOT_OFST", /* name */
931 FALSE, /* partial_inplace */
932 0, /* src_mask */
933 0x0000ffff, /* dst_mask */
934 FALSE), /* pcrel_offset */
936 /* High 16 bits of displacement in global offset table. */
937 HOWTO (R_MIPS_GOT_HI16, /* 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_dont, /* complain_on_overflow */
944 _bfd_mips_elf_generic_reloc, /* special_function */
945 "R_MIPS_GOT_HI16", /* name */
946 FALSE, /* partial_inplace */
947 0, /* src_mask */
948 0x0000ffff, /* dst_mask */
949 FALSE), /* pcrel_offset */
951 /* Low 16 bits of displacement in global offset table. */
952 HOWTO (R_MIPS_GOT_LO16, /* type */
953 0, /* rightshift */
954 2, /* size (0 = byte, 1 = short, 2 = long) */
955 16, /* bitsize */
956 FALSE, /* pc_relative */
957 0, /* bitpos */
958 complain_overflow_dont, /* complain_on_overflow */
959 _bfd_mips_elf_generic_reloc, /* special_function */
960 "R_MIPS_GOT_LO16", /* name */
961 FALSE, /* partial_inplace */
962 0, /* src_mask */
963 0x0000ffff, /* dst_mask */
964 FALSE), /* pcrel_offset */
966 /* 64 bit subtraction. */
967 HOWTO (R_MIPS_SUB, /* type */
968 0, /* rightshift */
969 4, /* size (0 = byte, 1 = short, 2 = long) */
970 64, /* bitsize */
971 FALSE, /* pc_relative */
972 0, /* bitpos */
973 complain_overflow_dont, /* complain_on_overflow */
974 _bfd_mips_elf_generic_reloc, /* special_function */
975 "R_MIPS_SUB", /* name */
976 FALSE, /* partial_inplace */
977 0, /* src_mask */
978 MINUS_ONE, /* dst_mask */
979 FALSE), /* pcrel_offset */
981 /* Insert the addend as an instruction. */
982 /* FIXME: Not handled correctly. */
983 HOWTO (R_MIPS_INSERT_A, /* type */
984 0, /* rightshift */
985 2, /* size (0 = byte, 1 = short, 2 = long) */
986 32, /* bitsize */
987 FALSE, /* pc_relative */
988 0, /* bitpos */
989 complain_overflow_dont, /* complain_on_overflow */
990 _bfd_mips_elf_generic_reloc, /* special_function */
991 "R_MIPS_INSERT_A", /* name */
992 FALSE, /* partial_inplace */
993 0, /* src_mask */
994 0xffffffff, /* dst_mask */
995 FALSE), /* pcrel_offset */
997 /* Insert the addend as an instruction, and change all relocations
998 to refer to the old instruction at the address. */
999 /* FIXME: Not handled correctly. */
1000 HOWTO (R_MIPS_INSERT_B, /* type */
1001 0, /* rightshift */
1002 2, /* size (0 = byte, 1 = short, 2 = long) */
1003 32, /* bitsize */
1004 FALSE, /* pc_relative */
1005 0, /* bitpos */
1006 complain_overflow_dont, /* complain_on_overflow */
1007 _bfd_mips_elf_generic_reloc, /* special_function */
1008 "R_MIPS_INSERT_B", /* name */
1009 FALSE, /* partial_inplace */
1010 0, /* src_mask */
1011 0xffffffff, /* dst_mask */
1012 FALSE), /* pcrel_offset */
1014 /* Delete a 32 bit instruction. */
1015 /* FIXME: Not handled correctly. */
1016 HOWTO (R_MIPS_DELETE, /* type */
1017 0, /* rightshift */
1018 2, /* size (0 = byte, 1 = short, 2 = long) */
1019 32, /* bitsize */
1020 FALSE, /* pc_relative */
1021 0, /* bitpos */
1022 complain_overflow_dont, /* complain_on_overflow */
1023 _bfd_mips_elf_generic_reloc, /* special_function */
1024 "R_MIPS_DELETE", /* name */
1025 FALSE, /* partial_inplace */
1026 0, /* src_mask */
1027 0xffffffff, /* dst_mask */
1028 FALSE), /* pcrel_offset */
1030 /* Get the higher value of a 64 bit addend. */
1031 HOWTO (R_MIPS_HIGHER, /* type */
1032 0, /* rightshift */
1033 2, /* size (0 = byte, 1 = short, 2 = long) */
1034 16, /* 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_HIGHER", /* name */
1040 FALSE, /* partial_inplace */
1041 0, /* src_mask */
1042 0x0000ffff, /* dst_mask */
1043 FALSE), /* pcrel_offset */
1045 /* Get the highest value of a 64 bit addend. */
1046 HOWTO (R_MIPS_HIGHEST, /* 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_dont, /* complain_on_overflow */
1053 _bfd_mips_elf_generic_reloc, /* special_function */
1054 "R_MIPS_HIGHEST", /* name */
1055 FALSE, /* partial_inplace */
1056 0, /* src_mask */
1057 0x0000ffff, /* dst_mask */
1058 FALSE), /* pcrel_offset */
1060 /* High 16 bits of displacement in global offset table. */
1061 HOWTO (R_MIPS_CALL_HI16, /* 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_dont, /* complain_on_overflow */
1068 _bfd_mips_elf_generic_reloc, /* special_function */
1069 "R_MIPS_CALL_HI16", /* name */
1070 FALSE, /* partial_inplace */
1071 0, /* src_mask */
1072 0x0000ffff, /* dst_mask */
1073 FALSE), /* pcrel_offset */
1075 /* Low 16 bits of displacement in global offset table. */
1076 HOWTO (R_MIPS_CALL_LO16, /* 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_dont, /* complain_on_overflow */
1083 _bfd_mips_elf_generic_reloc, /* special_function */
1084 "R_MIPS_CALL_LO16", /* name */
1085 FALSE, /* partial_inplace */
1086 0, /* src_mask */
1087 0x0000ffff, /* dst_mask */
1088 FALSE), /* pcrel_offset */
1090 /* Section displacement, used by an associated event location section. */
1091 HOWTO (R_MIPS_SCN_DISP, /* type */
1092 0, /* rightshift */
1093 2, /* size (0 = byte, 1 = short, 2 = long) */
1094 32, /* 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_SCN_DISP", /* name */
1100 FALSE, /* partial_inplace */
1101 0, /* src_mask */
1102 0xffffffff, /* dst_mask */
1103 FALSE), /* pcrel_offset */
1105 HOWTO (R_MIPS_REL16, /* type */
1106 0, /* rightshift */
1107 1, /* size (0 = byte, 1 = short, 2 = long) */
1108 16, /* bitsize */
1109 FALSE, /* pc_relative */
1110 0, /* bitpos */
1111 complain_overflow_signed, /* complain_on_overflow */
1112 _bfd_mips_elf_generic_reloc, /* special_function */
1113 "R_MIPS_REL16", /* name */
1114 FALSE, /* partial_inplace */
1115 0, /* src_mask */
1116 0xffff, /* dst_mask */
1117 FALSE), /* pcrel_offset */
1119 /* These two are obsolete. */
1120 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1121 EMPTY_HOWTO (R_MIPS_PJUMP),
1123 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1124 It must be used for multigot GOT's (and only there). */
1125 HOWTO (R_MIPS_RELGOT, /* type */
1126 0, /* rightshift */
1127 2, /* size (0 = byte, 1 = short, 2 = long) */
1128 32, /* bitsize */
1129 FALSE, /* pc_relative */
1130 0, /* bitpos */
1131 complain_overflow_dont, /* complain_on_overflow */
1132 _bfd_mips_elf_generic_reloc, /* special_function */
1133 "R_MIPS_RELGOT", /* name */
1134 FALSE, /* partial_inplace */
1135 0, /* src_mask */
1136 0xffffffff, /* dst_mask */
1137 FALSE), /* pcrel_offset */
1139 /* Protected jump conversion. This is an optimization hint. No
1140 relocation is required for correctness. */
1141 HOWTO (R_MIPS_JALR, /* type */
1142 0, /* rightshift */
1143 2, /* size (0 = byte, 1 = short, 2 = long) */
1144 32, /* bitsize */
1145 FALSE, /* pc_relative */
1146 0, /* bitpos */
1147 complain_overflow_dont, /* complain_on_overflow */
1148 _bfd_mips_elf_generic_reloc, /* special_function */
1149 "R_MIPS_JALR", /* name */
1150 FALSE, /* partial_inplace */
1151 0, /* src_mask */
1152 0x00000000, /* dst_mask */
1153 FALSE), /* pcrel_offset */
1156 /* The reloc used for the mips16 jump instruction. */
1157 static reloc_howto_type elf_mips16_jump_howto =
1158 HOWTO (R_MIPS16_26, /* type */
1159 2, /* rightshift */
1160 2, /* size (0 = byte, 1 = short, 2 = long) */
1161 26, /* bitsize */
1162 FALSE, /* pc_relative */
1163 0, /* bitpos */
1164 complain_overflow_dont, /* complain_on_overflow */
1165 /* This needs complex overflow
1166 detection, because the upper four
1167 bits must match the PC. */
1168 mips16_jump_reloc, /* special_function */
1169 "R_MIPS16_26", /* name */
1170 TRUE, /* partial_inplace */
1171 0x3ffffff, /* src_mask */
1172 0x3ffffff, /* dst_mask */
1173 FALSE); /* pcrel_offset */
1175 /* The reloc used for the mips16 gprel instruction. */
1176 static reloc_howto_type elf_mips16_gprel_howto =
1177 HOWTO (R_MIPS16_GPREL, /* type */
1178 0, /* rightshift */
1179 2, /* size (0 = byte, 1 = short, 2 = long) */
1180 16, /* bitsize */
1181 FALSE, /* pc_relative */
1182 0, /* bitpos */
1183 complain_overflow_signed, /* complain_on_overflow */
1184 mips16_gprel_reloc, /* special_function */
1185 "R_MIPS16_GPREL", /* name */
1186 TRUE, /* partial_inplace */
1187 0x07ff001f, /* src_mask */
1188 0x07ff001f, /* dst_mask */
1189 FALSE); /* pcrel_offset */
1191 /* GNU extension to record C++ vtable hierarchy */
1192 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
1193 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
1194 0, /* rightshift */
1195 2, /* size (0 = byte, 1 = short, 2 = long) */
1196 0, /* bitsize */
1197 FALSE, /* pc_relative */
1198 0, /* bitpos */
1199 complain_overflow_dont, /* complain_on_overflow */
1200 NULL, /* special_function */
1201 "R_MIPS_GNU_VTINHERIT", /* name */
1202 FALSE, /* partial_inplace */
1203 0, /* src_mask */
1204 0, /* dst_mask */
1205 FALSE); /* pcrel_offset */
1207 /* GNU extension to record C++ vtable member usage */
1208 static reloc_howto_type elf_mips_gnu_vtentry_howto =
1209 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
1210 0, /* rightshift */
1211 2, /* size (0 = byte, 1 = short, 2 = long) */
1212 0, /* bitsize */
1213 FALSE, /* pc_relative */
1214 0, /* bitpos */
1215 complain_overflow_dont, /* complain_on_overflow */
1216 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1217 "R_MIPS_GNU_VTENTRY", /* name */
1218 FALSE, /* partial_inplace */
1219 0, /* src_mask */
1220 0, /* dst_mask */
1221 FALSE); /* pcrel_offset */
1223 /* 16 bit offset for pc-relative branches. */
1224 static reloc_howto_type elf_mips_gnu_rel16_s2 =
1225 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
1226 2, /* rightshift */
1227 2, /* size (0 = byte, 1 = short, 2 = long) */
1228 16, /* bitsize */
1229 TRUE, /* pc_relative */
1230 0, /* bitpos */
1231 complain_overflow_signed, /* complain_on_overflow */
1232 _bfd_mips_elf_generic_reloc, /* special_function */
1233 "R_MIPS_GNU_REL16_S2", /* name */
1234 TRUE, /* partial_inplace */
1235 0x0000ffff, /* src_mask */
1236 0x0000ffff, /* dst_mask */
1237 TRUE); /* pcrel_offset */
1239 /* 16 bit offset for pc-relative branches. */
1240 static reloc_howto_type elf_mips_gnu_rela16_s2 =
1241 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
1242 2, /* rightshift */
1243 2, /* size (0 = byte, 1 = short, 2 = long) */
1244 16, /* bitsize */
1245 TRUE, /* pc_relative */
1246 0, /* bitpos */
1247 complain_overflow_signed, /* complain_on_overflow */
1248 _bfd_mips_elf_generic_reloc, /* special_function */
1249 "R_MIPS_GNU_REL16_S2", /* name */
1250 FALSE, /* partial_inplace */
1251 0, /* src_mask */
1252 0x0000ffff, /* dst_mask */
1253 TRUE); /* pcrel_offset */
1255 /* Swap in a MIPS 64-bit Rel reloc. */
1257 static void
1258 mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src,
1259 Elf64_Mips_Internal_Rela *dst)
1261 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1262 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1263 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1264 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1265 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1266 dst->r_type = H_GET_8 (abfd, src->r_type);
1267 dst->r_addend = 0;
1270 /* Swap in a MIPS 64-bit Rela reloc. */
1272 static void
1273 mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src,
1274 Elf64_Mips_Internal_Rela *dst)
1276 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1277 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1278 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1279 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1280 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1281 dst->r_type = H_GET_8 (abfd, src->r_type);
1282 dst->r_addend = H_GET_S64 (abfd, src->r_addend);
1285 /* Swap out a MIPS 64-bit Rel reloc. */
1287 static void
1288 mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1289 Elf64_Mips_External_Rel *dst)
1291 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1292 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1293 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1294 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1295 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1296 H_PUT_8 (abfd, src->r_type, dst->r_type);
1299 /* Swap out a MIPS 64-bit Rela reloc. */
1301 static void
1302 mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1303 Elf64_Mips_External_Rela *dst)
1305 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1306 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1307 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1308 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1309 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1310 H_PUT_8 (abfd, src->r_type, dst->r_type);
1311 H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
1314 /* Swap in a MIPS 64-bit Rel reloc. */
1316 static void
1317 mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src,
1318 Elf_Internal_Rela *dst)
1320 Elf64_Mips_Internal_Rela mirel;
1322 mips_elf64_swap_reloc_in (abfd,
1323 (const Elf64_Mips_External_Rel *) src,
1324 &mirel);
1326 dst[0].r_offset = mirel.r_offset;
1327 dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
1328 dst[0].r_addend = 0;
1329 dst[1].r_offset = mirel.r_offset;
1330 dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
1331 dst[1].r_addend = 0;
1332 dst[2].r_offset = mirel.r_offset;
1333 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
1334 dst[2].r_addend = 0;
1337 /* Swap in a MIPS 64-bit Rela reloc. */
1339 static void
1340 mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src,
1341 Elf_Internal_Rela *dst)
1343 Elf64_Mips_Internal_Rela mirela;
1345 mips_elf64_swap_reloca_in (abfd,
1346 (const Elf64_Mips_External_Rela *) src,
1347 &mirela);
1349 dst[0].r_offset = mirela.r_offset;
1350 dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
1351 dst[0].r_addend = mirela.r_addend;
1352 dst[1].r_offset = mirela.r_offset;
1353 dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
1354 dst[1].r_addend = 0;
1355 dst[2].r_offset = mirela.r_offset;
1356 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
1357 dst[2].r_addend = 0;
1360 /* Swap out a MIPS 64-bit Rel reloc. */
1362 static void
1363 mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src,
1364 bfd_byte *dst)
1366 Elf64_Mips_Internal_Rela mirel;
1368 mirel.r_offset = src[0].r_offset;
1369 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1371 mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1372 mirel.r_sym = ELF64_R_SYM (src[0].r_info);
1373 mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1374 mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1375 mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1377 mips_elf64_swap_reloc_out (abfd, &mirel,
1378 (Elf64_Mips_External_Rel *) dst);
1381 /* Swap out a MIPS 64-bit Rela reloc. */
1383 static void
1384 mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
1385 bfd_byte *dst)
1387 Elf64_Mips_Internal_Rela mirela;
1389 mirela.r_offset = src[0].r_offset;
1390 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1391 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
1393 mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1394 mirela.r_sym = ELF64_R_SYM (src[0].r_info);
1395 mirela.r_addend = src[0].r_addend;
1396 BFD_ASSERT(src[1].r_addend == 0);
1397 BFD_ASSERT(src[2].r_addend == 0);
1399 mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1400 mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1401 mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1403 mips_elf64_swap_reloca_out (abfd, &mirela,
1404 (Elf64_Mips_External_Rela *) dst);
1407 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1408 dangerous relocation. */
1410 static bfd_boolean
1411 mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp)
1413 unsigned int count;
1414 asymbol **sym;
1415 unsigned int i;
1417 /* If we've already figured out what GP will be, just return it. */
1418 *pgp = _bfd_get_gp_value (output_bfd);
1419 if (*pgp)
1420 return TRUE;
1422 count = bfd_get_symcount (output_bfd);
1423 sym = bfd_get_outsymbols (output_bfd);
1425 /* The linker script will have created a symbol named `_gp' with the
1426 appropriate value. */
1427 if (sym == NULL)
1428 i = count;
1429 else
1431 for (i = 0; i < count; i++, sym++)
1433 register const char *name;
1435 name = bfd_asymbol_name (*sym);
1436 if (*name == '_' && strcmp (name, "_gp") == 0)
1438 *pgp = bfd_asymbol_value (*sym);
1439 _bfd_set_gp_value (output_bfd, *pgp);
1440 break;
1445 if (i >= count)
1447 /* Only get the error once. */
1448 *pgp = 4;
1449 _bfd_set_gp_value (output_bfd, *pgp);
1450 return FALSE;
1453 return TRUE;
1456 /* We have to figure out the gp value, so that we can adjust the
1457 symbol value correctly. We look up the symbol _gp in the output
1458 BFD. If we can't find it, we're stuck. We cache it in the ELF
1459 target data. We don't need to adjust the symbol value for an
1460 external symbol if we are producing relocatable output. */
1462 static bfd_reloc_status_type
1463 mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
1464 char **error_message, bfd_vma *pgp)
1466 if (bfd_is_und_section (symbol->section)
1467 && ! relocatable)
1469 *pgp = 0;
1470 return bfd_reloc_undefined;
1473 *pgp = _bfd_get_gp_value (output_bfd);
1474 if (*pgp == 0
1475 && (! relocatable
1476 || (symbol->flags & BSF_SECTION_SYM) != 0))
1478 if (relocatable)
1480 /* Make up a value. */
1481 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
1482 _bfd_set_gp_value (output_bfd, *pgp);
1484 else if (!mips_elf64_assign_gp (output_bfd, pgp))
1486 *error_message =
1487 (char *) _("GP relative relocation when _gp not defined");
1488 return bfd_reloc_dangerous;
1492 return bfd_reloc_ok;
1495 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1496 become the offset from the gp register. */
1498 static bfd_reloc_status_type
1499 mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1500 void *data, asection *input_section, bfd *output_bfd,
1501 char **error_message)
1503 bfd_boolean relocatable;
1504 bfd_reloc_status_type ret;
1505 bfd_vma gp;
1507 /* If we're relocating, and this is an external symbol, we don't want
1508 to change anything. */
1509 if (output_bfd != NULL
1510 && (symbol->flags & BSF_SECTION_SYM) == 0
1511 && (symbol->flags & BSF_LOCAL) != 0)
1513 reloc_entry->address += input_section->output_offset;
1514 return bfd_reloc_ok;
1517 if (output_bfd != NULL)
1518 relocatable = TRUE;
1519 else
1521 relocatable = FALSE;
1522 output_bfd = symbol->section->output_section->owner;
1525 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
1526 &gp);
1527 if (ret != bfd_reloc_ok)
1528 return ret;
1530 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1531 input_section, relocatable,
1532 data, gp);
1535 /* Do a R_MIPS_LITERAL relocation. */
1537 static bfd_reloc_status_type
1538 mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1539 void *data, asection *input_section, bfd *output_bfd,
1540 char **error_message)
1542 bfd_boolean relocatable;
1543 bfd_reloc_status_type ret;
1544 bfd_vma gp;
1546 /* R_MIPS_LITERAL relocations are defined for local symbols only. */
1547 if (output_bfd != NULL
1548 && (symbol->flags & BSF_SECTION_SYM) == 0
1549 && (symbol->flags & BSF_LOCAL) != 0)
1551 *error_message = (char *)
1552 _("literal relocation occurs for an external symbol");
1553 return bfd_reloc_outofrange;
1556 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
1557 if (output_bfd != NULL)
1558 relocatable = TRUE;
1559 else
1561 relocatable = FALSE;
1562 output_bfd = symbol->section->output_section->owner;
1565 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
1566 &gp);
1567 if (ret != bfd_reloc_ok)
1568 return ret;
1570 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1571 input_section, relocatable,
1572 data, gp);
1575 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1576 become the offset from the gp register. */
1578 static bfd_reloc_status_type
1579 mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1580 void *data, asection *input_section, bfd *output_bfd,
1581 char **error_message)
1583 bfd_boolean relocatable;
1584 bfd_reloc_status_type ret;
1585 bfd_vma gp;
1586 bfd_vma relocation;
1587 bfd_vma val;
1589 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
1590 if (output_bfd != NULL
1591 && (symbol->flags & BSF_SECTION_SYM) == 0
1592 && (symbol->flags & BSF_LOCAL) != 0)
1594 *error_message = (char *)
1595 _("32bits gp relative relocation occurs for an external symbol");
1596 return bfd_reloc_outofrange;
1599 if (output_bfd != NULL)
1600 relocatable = TRUE;
1601 else
1603 relocatable = FALSE;
1604 output_bfd = symbol->section->output_section->owner;
1607 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
1608 error_message, &gp);
1609 if (ret != bfd_reloc_ok)
1610 return ret;
1612 if (bfd_is_com_section (symbol->section))
1613 relocation = 0;
1614 else
1615 relocation = symbol->value;
1617 relocation += symbol->section->output_section->vma;
1618 relocation += symbol->section->output_offset;
1620 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
1621 return bfd_reloc_outofrange;
1623 /* Set val to the offset into the section or symbol. */
1624 val = reloc_entry->addend;
1626 if (reloc_entry->howto->partial_inplace)
1627 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1629 /* Adjust val for the final section location and GP value. If we
1630 are producing relocatable output, we don't want to do this for
1631 an external symbol. */
1632 if (! relocatable
1633 || (symbol->flags & BSF_SECTION_SYM) != 0)
1634 val += relocation - gp;
1636 if (reloc_entry->howto->partial_inplace)
1637 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
1638 else
1639 reloc_entry->addend = val;
1641 if (relocatable)
1642 reloc_entry->address += input_section->output_offset;
1644 return bfd_reloc_ok;
1647 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
1648 the rest is at bits 6-10. The bitpos already got right by the howto. */
1650 static bfd_reloc_status_type
1651 mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1652 void *data, asection *input_section, bfd *output_bfd,
1653 char **error_message)
1655 if (reloc_entry->howto->partial_inplace)
1657 reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
1658 | (reloc_entry->addend & 0x00000800) >> 9);
1661 return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
1662 input_section, output_bfd,
1663 error_message);
1666 /* Handle a mips16 jump. */
1668 static bfd_reloc_status_type
1669 mips16_jump_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
1670 asymbol *symbol, void *data ATTRIBUTE_UNUSED,
1671 asection *input_section, bfd *output_bfd,
1672 char **error_message ATTRIBUTE_UNUSED)
1674 if (output_bfd != NULL
1675 && (symbol->flags & BSF_SECTION_SYM) == 0
1676 && (! reloc_entry->howto->partial_inplace
1677 || reloc_entry->addend == 0))
1679 reloc_entry->address += input_section->output_offset;
1680 return bfd_reloc_ok;
1683 /* FIXME. */
1685 static bfd_boolean warned;
1687 if (! warned)
1688 (*_bfd_error_handler)
1689 (_("Linking mips16 objects into %s format is not supported"),
1690 bfd_get_target (input_section->output_section->owner));
1691 warned = TRUE;
1694 return bfd_reloc_undefined;
1697 /* Handle a mips16 GP relative reloc. */
1699 static bfd_reloc_status_type
1700 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1701 void *data, asection *input_section, bfd *output_bfd,
1702 char **error_message)
1704 bfd_boolean relocatable;
1705 bfd_reloc_status_type ret;
1706 bfd_vma gp;
1707 unsigned short extend = 0;
1708 unsigned short insn = 0;
1709 bfd_signed_vma val;
1710 bfd_vma relocation;
1712 /* If we're relocating, and this is an external symbol, we don't want
1713 to change anything. */
1714 if (output_bfd != NULL
1715 && (symbol->flags & BSF_SECTION_SYM) == 0
1716 && (symbol->flags & BSF_LOCAL) != 0)
1718 reloc_entry->address += input_section->output_offset;
1719 return bfd_reloc_ok;
1722 if (output_bfd != NULL)
1723 relocatable = TRUE;
1724 else
1726 relocatable = FALSE;
1727 output_bfd = symbol->section->output_section->owner;
1730 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
1731 &gp);
1732 if (ret != bfd_reloc_ok)
1733 return ret;
1735 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
1736 return bfd_reloc_outofrange;
1738 if (bfd_is_com_section (symbol->section))
1739 relocation = 0;
1740 else
1741 relocation = symbol->value;
1743 relocation += symbol->section->output_section->vma;
1744 relocation += symbol->section->output_offset;
1746 /* Set val to the offset into the section or symbol. */
1747 val = reloc_entry->addend;
1749 if (reloc_entry->howto->partial_inplace)
1751 /* Pick up the mips16 extend instruction and the real instruction. */
1752 extend = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);
1753 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address + 2);
1754 val += ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
1757 _bfd_mips_elf_sign_extend(val, 16);
1759 /* Adjust val for the final section location and GP value. If we
1760 are producing relocatable output, we don't want to do this for
1761 an external symbol. */
1762 if (! relocatable
1763 || (symbol->flags & BSF_SECTION_SYM) != 0)
1764 val += relocation - gp;
1766 if (reloc_entry->howto->partial_inplace)
1768 bfd_put_16 (abfd,
1769 (extend & 0xf800) | ((val >> 11) & 0x1f) | (val & 0x7e0),
1770 (bfd_byte *) data + reloc_entry->address);
1771 bfd_put_16 (abfd,
1772 (insn & 0xffe0) | (val & 0x1f),
1773 (bfd_byte *) data + reloc_entry->address + 2);
1775 else
1776 reloc_entry->addend = val;
1778 if (relocatable)
1779 reloc_entry->address += input_section->output_offset;
1780 else if (((val & ~0xffff) != ~0xffff) && ((val & ~0xffff) != 0))
1781 return bfd_reloc_overflow;
1783 return bfd_reloc_ok;
1786 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
1788 struct elf_reloc_map {
1789 bfd_reloc_code_real_type bfd_val;
1790 enum elf_mips_reloc_type elf_val;
1793 static const struct elf_reloc_map mips_reloc_map[] =
1795 { BFD_RELOC_NONE, R_MIPS_NONE },
1796 { BFD_RELOC_16, R_MIPS_16 },
1797 { BFD_RELOC_32, R_MIPS_32 },
1798 /* There is no BFD reloc for R_MIPS_REL32. */
1799 { BFD_RELOC_64, R_MIPS_64 },
1800 { BFD_RELOC_CTOR, R_MIPS_64 },
1801 { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
1802 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1803 { BFD_RELOC_LO16, R_MIPS_LO16 },
1804 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
1805 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
1806 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1807 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1808 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1809 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1810 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
1811 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
1812 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
1813 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1814 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1815 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1816 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1817 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1818 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
1819 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
1820 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
1821 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
1822 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
1823 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
1824 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1825 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
1826 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
1827 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
1828 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
1829 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR }
1832 /* Given a BFD reloc type, return a howto structure. */
1834 static reloc_howto_type *
1835 bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1836 bfd_reloc_code_real_type code)
1838 unsigned int i;
1839 /* FIXME: We default to RELA here instead of choosing the right
1840 relocation variant. */
1841 reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
1843 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
1844 i++)
1846 if (mips_reloc_map[i].bfd_val == code)
1847 return &howto_table[(int) mips_reloc_map[i].elf_val];
1850 switch (code)
1852 case BFD_RELOC_MIPS16_JMP:
1853 return &elf_mips16_jump_howto;
1854 case BFD_RELOC_MIPS16_GPREL:
1855 return &elf_mips16_gprel_howto;
1856 case BFD_RELOC_VTABLE_INHERIT:
1857 return &elf_mips_gnu_vtinherit_howto;
1858 case BFD_RELOC_VTABLE_ENTRY:
1859 return &elf_mips_gnu_vtentry_howto;
1860 case BFD_RELOC_16_PCREL_S2:
1861 return &elf_mips_gnu_rela16_s2;
1862 default:
1863 bfd_set_error (bfd_error_bad_value);
1864 return NULL;
1868 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
1870 static reloc_howto_type *
1871 mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
1873 switch (r_type)
1875 case R_MIPS16_26:
1876 return &elf_mips16_jump_howto;
1877 case R_MIPS16_GPREL:
1878 return &elf_mips16_gprel_howto;
1879 case R_MIPS_GNU_VTINHERIT:
1880 return &elf_mips_gnu_vtinherit_howto;
1881 case R_MIPS_GNU_VTENTRY:
1882 return &elf_mips_gnu_vtentry_howto;
1883 case R_MIPS_GNU_REL16_S2:
1884 if (rela_p)
1885 return &elf_mips_gnu_rela16_s2;
1886 else
1887 return &elf_mips_gnu_rel16_s2;
1888 default:
1889 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
1890 if (rela_p)
1891 return &mips_elf64_howto_table_rela[r_type];
1892 else
1893 return &mips_elf64_howto_table_rel[r_type];
1894 break;
1898 /* Prevent relocation handling by bfd for MIPS ELF64. */
1900 static void
1901 mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
1902 arelent *cache_ptr ATTRIBUTE_UNUSED,
1903 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
1905 BFD_ASSERT (0);
1908 static void
1909 mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
1910 arelent *cache_ptr ATTRIBUTE_UNUSED,
1911 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
1913 BFD_ASSERT (0);
1916 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
1917 to three relocs, we must tell the user to allocate more space. */
1919 static long
1920 mips_elf64_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
1922 return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
1925 static long
1926 mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
1928 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
1931 /* We must also copy more relocations than the corresponding functions
1932 in elf.c would, so the two following functions are slightly
1933 modified from elf.c, that multiply the external relocation count by
1934 3 to obtain the internal relocation count. */
1936 static long
1937 mips_elf64_canonicalize_reloc (bfd *abfd, sec_ptr section,
1938 arelent **relptr, asymbol **symbols)
1940 arelent *tblptr;
1941 unsigned int i;
1942 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
1944 if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
1945 return -1;
1947 tblptr = section->relocation;
1948 for (i = 0; i < section->reloc_count * 3; i++)
1949 *relptr++ = tblptr++;
1951 *relptr = NULL;
1953 return section->reloc_count * 3;
1956 static long
1957 mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
1958 asymbol **syms)
1960 bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
1961 asection *s;
1962 long ret;
1964 if (elf_dynsymtab (abfd) == 0)
1966 bfd_set_error (bfd_error_invalid_operation);
1967 return -1;
1970 slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
1971 ret = 0;
1972 for (s = abfd->sections; s != NULL; s = s->next)
1974 if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
1975 && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
1976 || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
1978 arelent *p;
1979 long count, i;
1981 if (! (*slurp_relocs) (abfd, s, syms, TRUE))
1982 return -1;
1983 count = s->size / elf_section_data (s)->this_hdr.sh_entsize * 3;
1984 p = s->relocation;
1985 for (i = 0; i < count; i++)
1986 *storage++ = p++;
1987 ret += count;
1991 *storage = NULL;
1993 return ret;
1996 /* Read the relocations from one reloc section. This is mostly copied
1997 from elfcode.h, except for the changes to expand one external
1998 relocation to 3 internal ones. We must unfortunately set
1999 reloc_count to the number of external relocations, because a lot of
2000 generic code seems to depend on this. */
2002 static bfd_boolean
2003 mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
2004 Elf_Internal_Shdr *rel_hdr,
2005 bfd_size_type reloc_count,
2006 arelent *relents, asymbol **symbols,
2007 bfd_boolean dynamic)
2009 void *allocated;
2010 bfd_byte *native_relocs;
2011 arelent *relent;
2012 bfd_vma i;
2013 int entsize;
2014 bfd_boolean rela_p;
2016 allocated = bfd_malloc (rel_hdr->sh_size);
2017 if (allocated == NULL)
2018 return FALSE;
2020 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
2021 || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
2022 != rel_hdr->sh_size))
2023 goto error_return;
2025 native_relocs = allocated;
2027 entsize = rel_hdr->sh_entsize;
2028 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
2029 || entsize == sizeof (Elf64_Mips_External_Rela));
2031 if (entsize == sizeof (Elf64_Mips_External_Rel))
2032 rela_p = FALSE;
2033 else
2034 rela_p = TRUE;
2036 for (i = 0, relent = relents;
2037 i < reloc_count;
2038 i++, native_relocs += entsize)
2040 Elf64_Mips_Internal_Rela rela;
2041 bfd_boolean used_sym, used_ssym;
2042 int ir;
2044 if (entsize == sizeof (Elf64_Mips_External_Rela))
2045 mips_elf64_swap_reloca_in (abfd,
2046 (Elf64_Mips_External_Rela *) native_relocs,
2047 &rela);
2048 else
2049 mips_elf64_swap_reloc_in (abfd,
2050 (Elf64_Mips_External_Rel *) native_relocs,
2051 &rela);
2053 /* Each entry represents exactly three actual relocations. */
2055 used_sym = FALSE;
2056 used_ssym = FALSE;
2057 for (ir = 0; ir < 3; ir++)
2059 enum elf_mips_reloc_type type;
2061 switch (ir)
2063 default:
2064 abort ();
2065 case 0:
2066 type = (enum elf_mips_reloc_type) rela.r_type;
2067 break;
2068 case 1:
2069 type = (enum elf_mips_reloc_type) rela.r_type2;
2070 break;
2071 case 2:
2072 type = (enum elf_mips_reloc_type) rela.r_type3;
2073 break;
2076 /* Some types require symbols, whereas some do not. */
2077 switch (type)
2079 case R_MIPS_NONE:
2080 case R_MIPS_LITERAL:
2081 case R_MIPS_INSERT_A:
2082 case R_MIPS_INSERT_B:
2083 case R_MIPS_DELETE:
2084 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2085 break;
2087 default:
2088 if (! used_sym)
2090 if (rela.r_sym == 0)
2091 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2092 else
2094 asymbol **ps, *s;
2096 ps = symbols + rela.r_sym - 1;
2097 s = *ps;
2098 if ((s->flags & BSF_SECTION_SYM) == 0)
2099 relent->sym_ptr_ptr = ps;
2100 else
2101 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
2104 used_sym = TRUE;
2106 else if (! used_ssym)
2108 switch (rela.r_ssym)
2110 case RSS_UNDEF:
2111 relent->sym_ptr_ptr =
2112 bfd_abs_section_ptr->symbol_ptr_ptr;
2113 break;
2115 case RSS_GP:
2116 case RSS_GP0:
2117 case RSS_LOC:
2118 /* FIXME: I think these need to be handled using
2119 special howto structures. */
2120 BFD_ASSERT (0);
2121 break;
2123 default:
2124 BFD_ASSERT (0);
2125 break;
2128 used_ssym = TRUE;
2130 else
2131 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2133 break;
2136 /* The address of an ELF reloc is section relative for an
2137 object file, and absolute for an executable file or
2138 shared library. The address of a BFD reloc is always
2139 section relative. */
2140 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
2141 relent->address = rela.r_offset;
2142 else
2143 relent->address = rela.r_offset - asect->vma;
2145 relent->addend = rela.r_addend;
2147 relent->howto = mips_elf64_rtype_to_howto (type, rela_p);
2149 ++relent;
2153 asect->reloc_count += (relent - relents) / 3;
2155 if (allocated != NULL)
2156 free (allocated);
2158 return TRUE;
2160 error_return:
2161 if (allocated != NULL)
2162 free (allocated);
2163 return FALSE;
2166 /* Read the relocations. On Irix 6, there can be two reloc sections
2167 associated with a single data section. This is copied from
2168 elfcode.h as well, with changes as small as accounting for 3
2169 internal relocs per external reloc and resetting reloc_count to
2170 zero before processing the relocs of a section. */
2172 static bfd_boolean
2173 mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
2174 asymbol **symbols, bfd_boolean dynamic)
2176 struct bfd_elf_section_data * const d = elf_section_data (asect);
2177 Elf_Internal_Shdr *rel_hdr;
2178 Elf_Internal_Shdr *rel_hdr2;
2179 bfd_size_type reloc_count;
2180 bfd_size_type reloc_count2;
2181 arelent *relents;
2182 bfd_size_type amt;
2184 if (asect->relocation != NULL)
2185 return TRUE;
2187 if (! dynamic)
2189 if ((asect->flags & SEC_RELOC) == 0
2190 || asect->reloc_count == 0)
2191 return TRUE;
2193 rel_hdr = &d->rel_hdr;
2194 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2195 rel_hdr2 = d->rel_hdr2;
2196 reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
2198 BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
2199 BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
2200 || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
2203 else
2205 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
2206 case because relocations against this section may use the
2207 dynamic symbol table, and in that case bfd_section_from_shdr
2208 in elf.c does not update the RELOC_COUNT. */
2209 if (asect->size == 0)
2210 return TRUE;
2212 rel_hdr = &d->this_hdr;
2213 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2214 rel_hdr2 = NULL;
2215 reloc_count2 = 0;
2218 /* Allocate space for 3 arelent structures for each Rel structure. */
2219 amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
2220 relents = bfd_alloc (abfd, amt);
2221 if (relents == NULL)
2222 return FALSE;
2224 /* The slurp_one_reloc_table routine increments reloc_count. */
2225 asect->reloc_count = 0;
2227 if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2228 rel_hdr, reloc_count,
2229 relents,
2230 symbols, dynamic))
2231 return FALSE;
2232 if (d->rel_hdr2 != NULL)
2234 if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2235 rel_hdr2, reloc_count2,
2236 relents + reloc_count * 3,
2237 symbols, dynamic))
2238 return FALSE;
2241 asect->relocation = relents;
2242 return TRUE;
2245 /* Write out the relocations. */
2247 static void
2248 mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
2250 bfd_boolean *failedp = data;
2251 int count;
2252 Elf_Internal_Shdr *rel_hdr;
2253 unsigned int idx;
2255 /* If we have already failed, don't do anything. */
2256 if (*failedp)
2257 return;
2259 if ((sec->flags & SEC_RELOC) == 0)
2260 return;
2262 /* The linker backend writes the relocs out itself, and sets the
2263 reloc_count field to zero to inhibit writing them here. Also,
2264 sometimes the SEC_RELOC flag gets set even when there aren't any
2265 relocs. */
2266 if (sec->reloc_count == 0)
2267 return;
2269 /* We can combine up to three relocs that refer to the same address
2270 if the latter relocs have no associated symbol. */
2271 count = 0;
2272 for (idx = 0; idx < sec->reloc_count; idx++)
2274 bfd_vma addr;
2275 unsigned int i;
2277 ++count;
2279 addr = sec->orelocation[idx]->address;
2280 for (i = 0; i < 2; i++)
2282 arelent *r;
2284 if (idx + 1 >= sec->reloc_count)
2285 break;
2286 r = sec->orelocation[idx + 1];
2287 if (r->address != addr
2288 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2289 || (*r->sym_ptr_ptr)->value != 0)
2290 break;
2292 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2294 ++idx;
2298 rel_hdr = &elf_section_data (sec)->rel_hdr;
2300 /* Do the actual relocation. */
2302 if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
2303 mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
2304 else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
2305 mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
2306 else
2307 BFD_ASSERT (0);
2310 static void
2311 mips_elf64_write_rel (bfd *abfd, asection *sec,
2312 Elf_Internal_Shdr *rel_hdr,
2313 int *count, void *data)
2315 bfd_boolean *failedp = data;
2316 Elf64_Mips_External_Rel *ext_rel;
2317 unsigned int idx;
2318 asymbol *last_sym = 0;
2319 int last_sym_idx = 0;
2321 rel_hdr->sh_size = rel_hdr->sh_entsize * *count;
2322 rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size);
2323 if (rel_hdr->contents == NULL)
2325 *failedp = TRUE;
2326 return;
2329 ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
2330 for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
2332 arelent *ptr;
2333 Elf64_Mips_Internal_Rela int_rel;
2334 asymbol *sym;
2335 int n;
2336 unsigned int i;
2338 ptr = sec->orelocation[idx];
2340 /* The address of an ELF reloc is section relative for an object
2341 file, and absolute for an executable file or shared library.
2342 The address of a BFD reloc is always section relative. */
2343 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2344 int_rel.r_offset = ptr->address;
2345 else
2346 int_rel.r_offset = ptr->address + sec->vma;
2348 sym = *ptr->sym_ptr_ptr;
2349 if (sym == last_sym)
2350 n = last_sym_idx;
2351 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2352 n = STN_UNDEF;
2353 else
2355 last_sym = sym;
2356 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2357 if (n < 0)
2359 *failedp = TRUE;
2360 return;
2362 last_sym_idx = n;
2365 int_rel.r_sym = n;
2366 int_rel.r_ssym = RSS_UNDEF;
2368 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2369 && ! _bfd_elf_validate_reloc (abfd, ptr))
2371 *failedp = TRUE;
2372 return;
2375 int_rel.r_type = ptr->howto->type;
2376 int_rel.r_type2 = (int) R_MIPS_NONE;
2377 int_rel.r_type3 = (int) R_MIPS_NONE;
2379 for (i = 0; i < 2; i++)
2381 arelent *r;
2383 if (idx + 1 >= sec->reloc_count)
2384 break;
2385 r = sec->orelocation[idx + 1];
2386 if (r->address != ptr->address
2387 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2388 || (*r->sym_ptr_ptr)->value != 0)
2389 break;
2391 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2393 if (i == 0)
2394 int_rel.r_type2 = r->howto->type;
2395 else
2396 int_rel.r_type3 = r->howto->type;
2398 ++idx;
2401 mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
2404 BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
2405 == *count);
2408 static void
2409 mips_elf64_write_rela (bfd *abfd, asection *sec,
2410 Elf_Internal_Shdr *rela_hdr,
2411 int *count, void *data)
2413 bfd_boolean *failedp = data;
2414 Elf64_Mips_External_Rela *ext_rela;
2415 unsigned int idx;
2416 asymbol *last_sym = 0;
2417 int last_sym_idx = 0;
2419 rela_hdr->sh_size = rela_hdr->sh_entsize * *count;
2420 rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
2421 if (rela_hdr->contents == NULL)
2423 *failedp = TRUE;
2424 return;
2427 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
2428 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
2430 arelent *ptr;
2431 Elf64_Mips_Internal_Rela int_rela;
2432 asymbol *sym;
2433 int n;
2434 unsigned int i;
2436 ptr = sec->orelocation[idx];
2438 /* The address of an ELF reloc is section relative for an object
2439 file, and absolute for an executable file or shared library.
2440 The address of a BFD reloc is always section relative. */
2441 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2442 int_rela.r_offset = ptr->address;
2443 else
2444 int_rela.r_offset = ptr->address + sec->vma;
2446 sym = *ptr->sym_ptr_ptr;
2447 if (sym == last_sym)
2448 n = last_sym_idx;
2449 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2450 n = STN_UNDEF;
2451 else
2453 last_sym = sym;
2454 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2455 if (n < 0)
2457 *failedp = TRUE;
2458 return;
2460 last_sym_idx = n;
2463 int_rela.r_sym = n;
2464 int_rela.r_addend = ptr->addend;
2465 int_rela.r_ssym = RSS_UNDEF;
2467 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2468 && ! _bfd_elf_validate_reloc (abfd, ptr))
2470 *failedp = TRUE;
2471 return;
2474 int_rela.r_type = ptr->howto->type;
2475 int_rela.r_type2 = (int) R_MIPS_NONE;
2476 int_rela.r_type3 = (int) R_MIPS_NONE;
2478 for (i = 0; i < 2; i++)
2480 arelent *r;
2482 if (idx + 1 >= sec->reloc_count)
2483 break;
2484 r = sec->orelocation[idx + 1];
2485 if (r->address != ptr->address
2486 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2487 || (*r->sym_ptr_ptr)->value != 0)
2488 break;
2490 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2492 if (i == 0)
2493 int_rela.r_type2 = r->howto->type;
2494 else
2495 int_rela.r_type3 = r->howto->type;
2497 ++idx;
2500 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
2503 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
2504 == *count);
2507 /* Set the right machine number for a MIPS ELF file. */
2509 static bfd_boolean
2510 mips_elf64_object_p (bfd *abfd)
2512 unsigned long mach;
2514 /* Irix 6 is broken. Object file symbol tables are not always
2515 sorted correctly such that local symbols precede global symbols,
2516 and the sh_info field in the symbol table is not always right. */
2517 if (elf64_mips_irix_compat (abfd) != ict_none)
2518 elf_bad_symtab (abfd) = TRUE;
2520 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
2521 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
2522 return TRUE;
2525 /* Depending on the target vector we generate some version of Irix
2526 executables or "normal" MIPS ELF ABI executables. */
2527 static irix_compat_t
2528 elf64_mips_irix_compat (bfd *abfd)
2530 if ((abfd->xvec == &bfd_elf64_bigmips_vec)
2531 || (abfd->xvec == &bfd_elf64_littlemips_vec))
2532 return ict_irix6;
2533 else
2534 return ict_none;
2537 /* Support for core dump NOTE sections. */
2538 static bfd_boolean
2539 elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
2541 int offset;
2542 unsigned int size;
2544 switch (note->descsz)
2546 default:
2547 return FALSE;
2549 case 480: /* Linux/MIPS - N64 kernel */
2550 /* pr_cursig */
2551 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
2553 /* pr_pid */
2554 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 32);
2556 /* pr_reg */
2557 offset = 112;
2558 size = 360;
2560 break;
2563 /* Make a ".reg/999" section. */
2564 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
2565 size, note->descpos + offset);
2568 static bfd_boolean
2569 elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
2571 switch (note->descsz)
2573 default:
2574 return FALSE;
2576 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
2577 elf_tdata (abfd)->core_program
2578 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
2579 elf_tdata (abfd)->core_command
2580 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
2583 /* Note that for some reason, a spurious space is tacked
2584 onto the end of the args in some (at least one anyway)
2585 implementations, so strip it off if it exists. */
2588 char *command = elf_tdata (abfd)->core_command;
2589 int n = strlen (command);
2591 if (0 < n && command[n - 1] == ' ')
2592 command[n - 1] = '\0';
2595 return TRUE;
2598 /* ECOFF swapping routines. These are used when dealing with the
2599 .mdebug section, which is in the ECOFF debugging format. */
2600 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
2602 /* Symbol table magic number. */
2603 magicSym2,
2604 /* Alignment of debugging information. E.g., 4. */
2606 /* Sizes of external symbolic information. */
2607 sizeof (struct hdr_ext),
2608 sizeof (struct dnr_ext),
2609 sizeof (struct pdr_ext),
2610 sizeof (struct sym_ext),
2611 sizeof (struct opt_ext),
2612 sizeof (struct fdr_ext),
2613 sizeof (struct rfd_ext),
2614 sizeof (struct ext_ext),
2615 /* Functions to swap in external symbolic data. */
2616 ecoff_swap_hdr_in,
2617 ecoff_swap_dnr_in,
2618 ecoff_swap_pdr_in,
2619 ecoff_swap_sym_in,
2620 ecoff_swap_opt_in,
2621 ecoff_swap_fdr_in,
2622 ecoff_swap_rfd_in,
2623 ecoff_swap_ext_in,
2624 _bfd_ecoff_swap_tir_in,
2625 _bfd_ecoff_swap_rndx_in,
2626 /* Functions to swap out external symbolic data. */
2627 ecoff_swap_hdr_out,
2628 ecoff_swap_dnr_out,
2629 ecoff_swap_pdr_out,
2630 ecoff_swap_sym_out,
2631 ecoff_swap_opt_out,
2632 ecoff_swap_fdr_out,
2633 ecoff_swap_rfd_out,
2634 ecoff_swap_ext_out,
2635 _bfd_ecoff_swap_tir_out,
2636 _bfd_ecoff_swap_rndx_out,
2637 /* Function to read in symbolic data. */
2638 _bfd_mips_elf_read_ecoff_info
2641 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
2642 standard ELF. This structure is used to redirect the relocation
2643 handling routines. */
2645 const struct elf_size_info mips_elf64_size_info =
2647 sizeof (Elf64_External_Ehdr),
2648 sizeof (Elf64_External_Phdr),
2649 sizeof (Elf64_External_Shdr),
2650 sizeof (Elf64_Mips_External_Rel),
2651 sizeof (Elf64_Mips_External_Rela),
2652 sizeof (Elf64_External_Sym),
2653 sizeof (Elf64_External_Dyn),
2654 sizeof (Elf_External_Note),
2655 4, /* hash-table entry size */
2656 3, /* internal relocations per external relocations */
2657 64, /* arch_size */
2658 3, /* log_file_align */
2659 ELFCLASS64,
2660 EV_CURRENT,
2661 bfd_elf64_write_out_phdrs,
2662 bfd_elf64_write_shdrs_and_ehdr,
2663 mips_elf64_write_relocs,
2664 bfd_elf64_swap_symbol_in,
2665 bfd_elf64_swap_symbol_out,
2666 mips_elf64_slurp_reloc_table,
2667 bfd_elf64_slurp_symbol_table,
2668 bfd_elf64_swap_dyn_in,
2669 bfd_elf64_swap_dyn_out,
2670 mips_elf64_be_swap_reloc_in,
2671 mips_elf64_be_swap_reloc_out,
2672 mips_elf64_be_swap_reloca_in,
2673 mips_elf64_be_swap_reloca_out
2676 #define ELF_ARCH bfd_arch_mips
2677 #define ELF_MACHINE_CODE EM_MIPS
2679 #define elf_backend_collect TRUE
2680 #define elf_backend_type_change_ok TRUE
2681 #define elf_backend_can_gc_sections TRUE
2682 #define elf_info_to_howto mips_elf64_info_to_howto_rela
2683 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
2684 #define elf_backend_object_p mips_elf64_object_p
2685 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
2686 #define elf_backend_section_processing _bfd_mips_elf_section_processing
2687 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
2688 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
2689 #define elf_backend_section_from_bfd_section \
2690 _bfd_mips_elf_section_from_bfd_section
2691 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
2692 #define elf_backend_link_output_symbol_hook \
2693 _bfd_mips_elf_link_output_symbol_hook
2694 #define elf_backend_create_dynamic_sections \
2695 _bfd_mips_elf_create_dynamic_sections
2696 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
2697 #define elf_backend_adjust_dynamic_symbol \
2698 _bfd_mips_elf_adjust_dynamic_symbol
2699 #define elf_backend_always_size_sections \
2700 _bfd_mips_elf_always_size_sections
2701 #define elf_backend_size_dynamic_sections \
2702 _bfd_mips_elf_size_dynamic_sections
2703 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
2704 #define elf_backend_finish_dynamic_symbol \
2705 _bfd_mips_elf_finish_dynamic_symbol
2706 #define elf_backend_finish_dynamic_sections \
2707 _bfd_mips_elf_finish_dynamic_sections
2708 #define elf_backend_final_write_processing \
2709 _bfd_mips_elf_final_write_processing
2710 #define elf_backend_additional_program_headers \
2711 _bfd_mips_elf_additional_program_headers
2712 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
2713 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
2714 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
2715 #define elf_backend_copy_indirect_symbol \
2716 _bfd_mips_elf_copy_indirect_symbol
2717 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
2718 #define elf_backend_ignore_discarded_relocs \
2719 _bfd_mips_elf_ignore_discarded_relocs
2720 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
2721 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
2722 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
2723 #define elf_backend_size_info mips_elf64_size_info
2725 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus
2726 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo
2728 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
2730 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
2731 work better/work only in RELA, so we default to this. */
2732 #define elf_backend_may_use_rel_p 1
2733 #define elf_backend_may_use_rela_p 1
2734 #define elf_backend_default_use_rela_p 1
2736 #define elf_backend_write_section _bfd_mips_elf_write_section
2738 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
2739 MIPS-specific function only applies to IRIX5, which had no 64-bit
2740 ABI. */
2741 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
2742 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
2743 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
2744 #define bfd_elf64_bfd_get_relocated_section_contents \
2745 _bfd_elf_mips_get_relocated_section_contents
2746 #define bfd_elf64_bfd_link_hash_table_create \
2747 _bfd_mips_elf_link_hash_table_create
2748 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
2749 #define bfd_elf64_bfd_merge_private_bfd_data \
2750 _bfd_mips_elf_merge_private_bfd_data
2751 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
2752 #define bfd_elf64_bfd_print_private_bfd_data \
2753 _bfd_mips_elf_print_private_bfd_data
2755 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
2756 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
2757 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
2758 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
2759 #define bfd_elf64_bfd_relax_section _bfd_mips_relax_section
2761 /* MIPS ELF64 archive functions. */
2762 #define bfd_elf64_archive_functions
2763 extern bfd_boolean bfd_elf64_archive_slurp_armap
2764 (bfd *);
2765 extern bfd_boolean bfd_elf64_archive_write_armap
2766 (bfd *, unsigned int, struct orl *, unsigned int, int);
2767 #define bfd_elf64_archive_slurp_extended_name_table \
2768 _bfd_archive_coff_slurp_extended_name_table
2769 #define bfd_elf64_archive_construct_extended_name_table \
2770 _bfd_archive_coff_construct_extended_name_table
2771 #define bfd_elf64_archive_truncate_arname \
2772 _bfd_archive_coff_truncate_arname
2773 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
2774 #define bfd_elf64_archive_openr_next_archived_file \
2775 _bfd_archive_coff_openr_next_archived_file
2776 #define bfd_elf64_archive_get_elt_at_index \
2777 _bfd_archive_coff_get_elt_at_index
2778 #define bfd_elf64_archive_generic_stat_arch_elt \
2779 _bfd_archive_coff_generic_stat_arch_elt
2780 #define bfd_elf64_archive_update_armap_timestamp \
2781 _bfd_archive_coff_update_armap_timestamp
2783 /* The SGI style (n)64 NewABI. */
2784 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
2785 #define TARGET_LITTLE_NAME "elf64-littlemips"
2786 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
2787 #define TARGET_BIG_NAME "elf64-bigmips"
2789 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
2790 a value of 0x1000, and we are compatible.
2791 FIXME: How does this affect NewABI? */
2792 #define ELF_MAXPAGESIZE 0x1000
2794 #include "elf64-target.h"
2796 /* The SYSV-style 'traditional' (n)64 NewABI. */
2797 #undef TARGET_LITTLE_SYM
2798 #undef TARGET_LITTLE_NAME
2799 #undef TARGET_BIG_SYM
2800 #undef TARGET_BIG_NAME
2802 #undef ELF_MAXPAGESIZE
2804 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
2805 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
2806 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
2807 #define TARGET_BIG_NAME "elf64-tradbigmips"
2809 /* The SVR4 MIPS ABI says that this should be 0x10000, and Linux uses
2810 page sizes of up to that limit, so we need to respect it. */
2811 #define ELF_MAXPAGESIZE 0x10000
2812 #define elf64_bed elf64_tradbed
2814 /* Include the target file again for this target. */
2815 #include "elf64-target.h"