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