[binutils, ARM, 8/16] BFL infrastructure with new global reloc R_ARM_THM_BF18
[binutils-gdb.git] / bfd / elf64-mips.c
blob306710616d6395e92b047b491f1ba70a12397a20
1 /* MIPS-specific support for 64-bit ELF
2 Copyright (C) 1996-2019 Free Software Foundation, Inc.
3 Ian Lance Taylor, Cygnus Support
4 Linker support added by Mark Mitchell, CodeSourcery, LLC.
5 <mark@codesourcery.com>
7 This file is part of BFD, the Binary File Descriptor library.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
25 /* This file supports the 64-bit MIPS ELF ABI.
27 The MIPS 64-bit ELF ABI uses an unusual reloc format. This file
28 overrides the usual ELF reloc handling, and handles reading and
29 writing the relocations here. */
31 /* TODO: Many things are unsupported, even if there is some code for it
32 . (which was mostly stolen from elf32-mips.c and slightly adapted).
34 . - Relocation handling for REL relocs is wrong in many cases and
35 . generally untested.
36 . - Relocation handling for RELA relocs related to GOT support are
37 . also likely to be wrong.
38 . - Support for MIPS16 is untested.
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 "sysdep.h"
45 #include "bfd.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 (bfd *, const Elf64_Mips_External_Rel *, Elf64_Mips_Internal_Rela *);
67 static void mips_elf64_swap_reloca_in
68 (bfd *, const Elf64_Mips_External_Rela *, Elf64_Mips_Internal_Rela *);
69 static void mips_elf64_swap_reloc_out
70 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rel *);
71 static void mips_elf64_swap_reloca_out
72 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rela *);
73 static void mips_elf64_be_swap_reloc_in
74 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
75 static void mips_elf64_be_swap_reloc_out
76 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
77 static void mips_elf64_be_swap_reloca_in
78 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
79 static void mips_elf64_be_swap_reloca_out
80 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
81 static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup
82 (bfd *, bfd_reloc_code_real_type);
83 static bfd_boolean mips_elf64_info_to_howto_rela
84 (bfd *, arelent *, Elf_Internal_Rela *);
85 static long mips_elf64_get_dynamic_reloc_upper_bound
86 (bfd *);
87 static bfd_boolean mips_elf64_slurp_one_reloc_table
88 (bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type, arelent *,
89 asymbol **, bfd_boolean);
90 static bfd_boolean mips_elf64_slurp_reloc_table
91 (bfd *, asection *, asymbol **, bfd_boolean);
92 static void mips_elf64_write_relocs
93 (bfd *, asection *, void *);
94 static void mips_elf64_write_rel
95 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
96 static void mips_elf64_write_rela
97 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
98 static bfd_reloc_status_type mips_elf64_gprel16_reloc
99 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
100 static bfd_reloc_status_type mips_elf64_literal_reloc
101 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
102 static bfd_reloc_status_type mips_elf64_gprel32_reloc
103 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
104 static bfd_reloc_status_type mips_elf64_shift6_reloc
105 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
106 static bfd_reloc_status_type mips16_gprel_reloc
107 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
108 static bfd_boolean mips_elf64_assign_gp
109 (bfd *, bfd_vma *);
110 static bfd_reloc_status_type mips_elf64_final_gp
111 (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
112 static bfd_boolean mips_elf64_object_p
113 (bfd *);
114 static irix_compat_t elf64_mips_irix_compat
115 (bfd *);
116 static bfd_boolean elf64_mips_grok_prstatus
117 (bfd *, Elf_Internal_Note *);
118 static bfd_boolean elf64_mips_grok_psinfo
119 (bfd *, Elf_Internal_Note *);
121 extern const bfd_target mips_elf64_be_vec;
122 extern const bfd_target mips_elf64_le_vec;
124 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
125 from smaller values. Start with zero, widen, *then* decrement. */
126 #define MINUS_ONE (((bfd_vma)0) - 1)
128 /* The number of local .got entries we reserve. */
129 #define MIPS_RESERVED_GOTNO (2)
131 /* The relocation table used for SHT_REL sections. */
133 static reloc_howto_type mips_elf64_howto_table_rel[] =
135 /* No relocation. */
136 HOWTO (R_MIPS_NONE, /* type */
137 0, /* rightshift */
138 3, /* size (0 = byte, 1 = short, 2 = long) */
139 0, /* bitsize */
140 FALSE, /* pc_relative */
141 0, /* bitpos */
142 complain_overflow_dont, /* complain_on_overflow */
143 _bfd_mips_elf_generic_reloc, /* special_function */
144 "R_MIPS_NONE", /* name */
145 FALSE, /* partial_inplace */
146 0, /* src_mask */
147 0, /* dst_mask */
148 FALSE), /* pcrel_offset */
150 /* 16 bit relocation. */
151 HOWTO (R_MIPS_16, /* type */
152 0, /* rightshift */
153 2, /* size (0 = byte, 1 = short, 2 = long) */
154 16, /* bitsize */
155 FALSE, /* pc_relative */
156 0, /* bitpos */
157 complain_overflow_signed, /* complain_on_overflow */
158 _bfd_mips_elf_generic_reloc, /* special_function */
159 "R_MIPS_16", /* name */
160 TRUE, /* partial_inplace */
161 0x0000ffff, /* src_mask */
162 0x0000ffff, /* dst_mask */
163 FALSE), /* pcrel_offset */
165 /* 32 bit relocation. */
166 HOWTO (R_MIPS_32, /* type */
167 0, /* rightshift */
168 2, /* size (0 = byte, 1 = short, 2 = long) */
169 32, /* bitsize */
170 FALSE, /* pc_relative */
171 0, /* bitpos */
172 complain_overflow_dont, /* complain_on_overflow */
173 _bfd_mips_elf_generic_reloc, /* special_function */
174 "R_MIPS_32", /* name */
175 TRUE, /* partial_inplace */
176 0xffffffff, /* src_mask */
177 0xffffffff, /* dst_mask */
178 FALSE), /* pcrel_offset */
180 /* 32 bit symbol relative relocation. */
181 HOWTO (R_MIPS_REL32, /* type */
182 0, /* rightshift */
183 2, /* size (0 = byte, 1 = short, 2 = long) */
184 32, /* bitsize */
185 FALSE, /* pc_relative */
186 0, /* bitpos */
187 complain_overflow_dont, /* complain_on_overflow */
188 _bfd_mips_elf_generic_reloc, /* special_function */
189 "R_MIPS_REL32", /* name */
190 TRUE, /* partial_inplace */
191 0xffffffff, /* src_mask */
192 0xffffffff, /* dst_mask */
193 FALSE), /* pcrel_offset */
195 /* 26 bit jump address. */
196 HOWTO (R_MIPS_26, /* type */
197 2, /* rightshift */
198 2, /* size (0 = byte, 1 = short, 2 = long) */
199 26, /* bitsize */
200 FALSE, /* pc_relative */
201 0, /* bitpos */
202 complain_overflow_dont, /* complain_on_overflow */
203 /* This needs complex overflow
204 detection, because the upper 36
205 bits must match the PC + 4. */
206 _bfd_mips_elf_generic_reloc, /* special_function */
207 "R_MIPS_26", /* name */
208 TRUE, /* partial_inplace */
209 0x03ffffff, /* src_mask */
210 0x03ffffff, /* dst_mask */
211 FALSE), /* pcrel_offset */
213 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
214 However, the native IRIX6 tools use them, so we try our best. */
216 /* High 16 bits of symbol value. */
217 HOWTO (R_MIPS_HI16, /* type */
218 16, /* rightshift */
219 2, /* size (0 = byte, 1 = short, 2 = long) */
220 16, /* bitsize */
221 FALSE, /* pc_relative */
222 0, /* bitpos */
223 complain_overflow_dont, /* complain_on_overflow */
224 _bfd_mips_elf_hi16_reloc, /* special_function */
225 "R_MIPS_HI16", /* name */
226 TRUE, /* partial_inplace */
227 0x0000ffff, /* src_mask */
228 0x0000ffff, /* dst_mask */
229 FALSE), /* pcrel_offset */
231 /* Low 16 bits of symbol value. */
232 HOWTO (R_MIPS_LO16, /* type */
233 0, /* rightshift */
234 2, /* size (0 = byte, 1 = short, 2 = long) */
235 16, /* bitsize */
236 FALSE, /* pc_relative */
237 0, /* bitpos */
238 complain_overflow_dont, /* complain_on_overflow */
239 _bfd_mips_elf_lo16_reloc, /* special_function */
240 "R_MIPS_LO16", /* name */
241 TRUE, /* partial_inplace */
242 0x0000ffff, /* src_mask */
243 0x0000ffff, /* dst_mask */
244 FALSE), /* pcrel_offset */
246 /* GP relative reference. */
247 HOWTO (R_MIPS_GPREL16, /* type */
248 0, /* rightshift */
249 2, /* size (0 = byte, 1 = short, 2 = long) */
250 16, /* bitsize */
251 FALSE, /* pc_relative */
252 0, /* bitpos */
253 complain_overflow_signed, /* complain_on_overflow */
254 mips_elf64_gprel16_reloc, /* special_function */
255 "R_MIPS_GPREL16", /* name */
256 TRUE, /* partial_inplace */
257 0x0000ffff, /* src_mask */
258 0x0000ffff, /* dst_mask */
259 FALSE), /* pcrel_offset */
261 /* Reference to literal section. */
262 HOWTO (R_MIPS_LITERAL, /* type */
263 0, /* rightshift */
264 2, /* size (0 = byte, 1 = short, 2 = long) */
265 16, /* bitsize */
266 FALSE, /* pc_relative */
267 0, /* bitpos */
268 complain_overflow_signed, /* complain_on_overflow */
269 mips_elf64_literal_reloc, /* special_function */
270 "R_MIPS_LITERAL", /* name */
271 TRUE, /* partial_inplace */
272 0x0000ffff, /* src_mask */
273 0x0000ffff, /* dst_mask */
274 FALSE), /* pcrel_offset */
276 /* Reference to global offset table. */
277 HOWTO (R_MIPS_GOT16, /* type */
278 0, /* rightshift */
279 2, /* size (0 = byte, 1 = short, 2 = long) */
280 16, /* bitsize */
281 FALSE, /* pc_relative */
282 0, /* bitpos */
283 complain_overflow_signed, /* complain_on_overflow */
284 _bfd_mips_elf_got16_reloc, /* special_function */
285 "R_MIPS_GOT16", /* name */
286 TRUE, /* partial_inplace */
287 0x0000ffff, /* src_mask */
288 0x0000ffff, /* dst_mask */
289 FALSE), /* pcrel_offset */
291 /* 16 bit PC relative reference. Note that the ABI document has a typo
292 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
293 We do the right thing here. */
294 HOWTO (R_MIPS_PC16, /* type */
295 2, /* rightshift */
296 2, /* size (0 = byte, 1 = short, 2 = long) */
297 16, /* bitsize */
298 TRUE, /* pc_relative */
299 0, /* bitpos */
300 complain_overflow_signed, /* complain_on_overflow */
301 _bfd_mips_elf_generic_reloc, /* special_function */
302 "R_MIPS_PC16", /* name */
303 TRUE, /* partial_inplace */
304 0x0000ffff, /* src_mask */
305 0x0000ffff, /* dst_mask */
306 TRUE), /* pcrel_offset */
308 /* 16 bit call through global offset table. */
309 HOWTO (R_MIPS_CALL16, /* type */
310 0, /* rightshift */
311 2, /* size (0 = byte, 1 = short, 2 = long) */
312 16, /* bitsize */
313 FALSE, /* pc_relative */
314 0, /* bitpos */
315 complain_overflow_signed, /* complain_on_overflow */
316 _bfd_mips_elf_generic_reloc, /* special_function */
317 "R_MIPS_CALL16", /* name */
318 TRUE, /* partial_inplace */
319 0x0000ffff, /* src_mask */
320 0x0000ffff, /* dst_mask */
321 FALSE), /* pcrel_offset */
323 /* 32 bit GP relative reference. */
324 HOWTO (R_MIPS_GPREL32, /* type */
325 0, /* rightshift */
326 2, /* size (0 = byte, 1 = short, 2 = long) */
327 32, /* bitsize */
328 FALSE, /* pc_relative */
329 0, /* bitpos */
330 complain_overflow_dont, /* complain_on_overflow */
331 mips_elf64_gprel32_reloc, /* special_function */
332 "R_MIPS_GPREL32", /* name */
333 TRUE, /* partial_inplace */
334 0xffffffff, /* src_mask */
335 0xffffffff, /* dst_mask */
336 FALSE), /* pcrel_offset */
338 EMPTY_HOWTO (13),
339 EMPTY_HOWTO (14),
340 EMPTY_HOWTO (15),
342 /* A 5 bit shift field. */
343 HOWTO (R_MIPS_SHIFT5, /* type */
344 0, /* rightshift */
345 2, /* size (0 = byte, 1 = short, 2 = long) */
346 5, /* bitsize */
347 FALSE, /* pc_relative */
348 6, /* bitpos */
349 complain_overflow_bitfield, /* complain_on_overflow */
350 _bfd_mips_elf_generic_reloc, /* special_function */
351 "R_MIPS_SHIFT5", /* name */
352 TRUE, /* partial_inplace */
353 0x000007c0, /* src_mask */
354 0x000007c0, /* dst_mask */
355 FALSE), /* pcrel_offset */
357 /* A 6 bit shift field. */
358 HOWTO (R_MIPS_SHIFT6, /* type */
359 0, /* rightshift */
360 2, /* size (0 = byte, 1 = short, 2 = long) */
361 6, /* bitsize */
362 FALSE, /* pc_relative */
363 6, /* bitpos */
364 complain_overflow_bitfield, /* complain_on_overflow */
365 mips_elf64_shift6_reloc, /* special_function */
366 "R_MIPS_SHIFT6", /* name */
367 TRUE, /* partial_inplace */
368 0x000007c4, /* src_mask */
369 0x000007c4, /* dst_mask */
370 FALSE), /* pcrel_offset */
372 /* 64 bit relocation. */
373 HOWTO (R_MIPS_64, /* type */
374 0, /* rightshift */
375 4, /* size (0 = byte, 1 = short, 2 = long) */
376 64, /* bitsize */
377 FALSE, /* pc_relative */
378 0, /* bitpos */
379 complain_overflow_dont, /* complain_on_overflow */
380 _bfd_mips_elf_generic_reloc, /* special_function */
381 "R_MIPS_64", /* name */
382 TRUE, /* partial_inplace */
383 MINUS_ONE, /* src_mask */
384 MINUS_ONE, /* dst_mask */
385 FALSE), /* pcrel_offset */
387 /* Displacement in the global offset table. */
388 HOWTO (R_MIPS_GOT_DISP, /* type */
389 0, /* rightshift */
390 2, /* size (0 = byte, 1 = short, 2 = long) */
391 16, /* bitsize */
392 FALSE, /* pc_relative */
393 0, /* bitpos */
394 complain_overflow_signed, /* complain_on_overflow */
395 _bfd_mips_elf_generic_reloc, /* special_function */
396 "R_MIPS_GOT_DISP", /* name */
397 TRUE, /* partial_inplace */
398 0x0000ffff, /* src_mask */
399 0x0000ffff, /* dst_mask */
400 FALSE), /* pcrel_offset */
402 /* Displacement to page pointer in the global offset table. */
403 HOWTO (R_MIPS_GOT_PAGE, /* type */
404 0, /* rightshift */
405 2, /* size (0 = byte, 1 = short, 2 = long) */
406 16, /* bitsize */
407 FALSE, /* pc_relative */
408 0, /* bitpos */
409 complain_overflow_signed, /* complain_on_overflow */
410 _bfd_mips_elf_generic_reloc, /* special_function */
411 "R_MIPS_GOT_PAGE", /* name */
412 TRUE, /* partial_inplace */
413 0x0000ffff, /* src_mask */
414 0x0000ffff, /* dst_mask */
415 FALSE), /* pcrel_offset */
417 /* Offset from page pointer in the global offset table. */
418 HOWTO (R_MIPS_GOT_OFST, /* type */
419 0, /* rightshift */
420 2, /* size (0 = byte, 1 = short, 2 = long) */
421 16, /* bitsize */
422 FALSE, /* pc_relative */
423 0, /* bitpos */
424 complain_overflow_signed, /* complain_on_overflow */
425 _bfd_mips_elf_generic_reloc, /* special_function */
426 "R_MIPS_GOT_OFST", /* name */
427 TRUE, /* partial_inplace */
428 0x0000ffff, /* src_mask */
429 0x0000ffff, /* dst_mask */
430 FALSE), /* pcrel_offset */
432 /* High 16 bits of displacement in global offset table. */
433 HOWTO (R_MIPS_GOT_HI16, /* 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_dont, /* complain_on_overflow */
440 _bfd_mips_elf_generic_reloc, /* special_function */
441 "R_MIPS_GOT_HI16", /* name */
442 TRUE, /* partial_inplace */
443 0x0000ffff, /* src_mask */
444 0x0000ffff, /* dst_mask */
445 FALSE), /* pcrel_offset */
447 /* Low 16 bits of displacement in global offset table. */
448 HOWTO (R_MIPS_GOT_LO16, /* type */
449 0, /* rightshift */
450 2, /* size (0 = byte, 1 = short, 2 = long) */
451 16, /* bitsize */
452 FALSE, /* pc_relative */
453 0, /* bitpos */
454 complain_overflow_dont, /* complain_on_overflow */
455 _bfd_mips_elf_generic_reloc, /* special_function */
456 "R_MIPS_GOT_LO16", /* name */
457 TRUE, /* partial_inplace */
458 0x0000ffff, /* src_mask */
459 0x0000ffff, /* dst_mask */
460 FALSE), /* pcrel_offset */
462 /* 64 bit subtraction. */
463 HOWTO (R_MIPS_SUB, /* type */
464 0, /* rightshift */
465 4, /* size (0 = byte, 1 = short, 2 = long) */
466 64, /* bitsize */
467 FALSE, /* pc_relative */
468 0, /* bitpos */
469 complain_overflow_dont, /* complain_on_overflow */
470 _bfd_mips_elf_generic_reloc, /* special_function */
471 "R_MIPS_SUB", /* name */
472 TRUE, /* partial_inplace */
473 MINUS_ONE, /* src_mask */
474 MINUS_ONE, /* dst_mask */
475 FALSE), /* pcrel_offset */
477 /* Insert the addend as an instruction. */
478 /* FIXME: Not handled correctly. */
479 HOWTO (R_MIPS_INSERT_A, /* type */
480 0, /* rightshift */
481 2, /* size (0 = byte, 1 = short, 2 = long) */
482 32, /* bitsize */
483 FALSE, /* pc_relative */
484 0, /* bitpos */
485 complain_overflow_dont, /* complain_on_overflow */
486 _bfd_mips_elf_generic_reloc, /* special_function */
487 "R_MIPS_INSERT_A", /* name */
488 TRUE, /* partial_inplace */
489 0xffffffff, /* src_mask */
490 0xffffffff, /* dst_mask */
491 FALSE), /* pcrel_offset */
493 /* Insert the addend as an instruction, and change all relocations
494 to refer to the old instruction at the address. */
495 /* FIXME: Not handled correctly. */
496 HOWTO (R_MIPS_INSERT_B, /* type */
497 0, /* rightshift */
498 2, /* size (0 = byte, 1 = short, 2 = long) */
499 32, /* bitsize */
500 FALSE, /* pc_relative */
501 0, /* bitpos */
502 complain_overflow_dont, /* complain_on_overflow */
503 _bfd_mips_elf_generic_reloc, /* special_function */
504 "R_MIPS_INSERT_B", /* name */
505 TRUE, /* partial_inplace */
506 0xffffffff, /* src_mask */
507 0xffffffff, /* dst_mask */
508 FALSE), /* pcrel_offset */
510 /* Delete a 32 bit instruction. */
511 /* FIXME: Not handled correctly. */
512 HOWTO (R_MIPS_DELETE, /* type */
513 0, /* rightshift */
514 2, /* size (0 = byte, 1 = short, 2 = long) */
515 32, /* bitsize */
516 FALSE, /* pc_relative */
517 0, /* bitpos */
518 complain_overflow_dont, /* complain_on_overflow */
519 _bfd_mips_elf_generic_reloc, /* special_function */
520 "R_MIPS_DELETE", /* name */
521 TRUE, /* partial_inplace */
522 0xffffffff, /* src_mask */
523 0xffffffff, /* dst_mask */
524 FALSE), /* pcrel_offset */
526 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
527 We don't, because
528 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
529 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
530 fallable heuristics.
531 b) No other NewABI toolchain actually emits such relocations. */
532 EMPTY_HOWTO (R_MIPS_HIGHER),
533 EMPTY_HOWTO (R_MIPS_HIGHEST),
535 /* High 16 bits of displacement in global offset table. */
536 HOWTO (R_MIPS_CALL_HI16, /* type */
537 0, /* rightshift */
538 2, /* size (0 = byte, 1 = short, 2 = long) */
539 16, /* bitsize */
540 FALSE, /* pc_relative */
541 0, /* bitpos */
542 complain_overflow_dont, /* complain_on_overflow */
543 _bfd_mips_elf_generic_reloc, /* special_function */
544 "R_MIPS_CALL_HI16", /* name */
545 TRUE, /* partial_inplace */
546 0x0000ffff, /* src_mask */
547 0x0000ffff, /* dst_mask */
548 FALSE), /* pcrel_offset */
550 /* Low 16 bits of displacement in global offset table. */
551 HOWTO (R_MIPS_CALL_LO16, /* type */
552 0, /* rightshift */
553 2, /* size (0 = byte, 1 = short, 2 = long) */
554 16, /* bitsize */
555 FALSE, /* pc_relative */
556 0, /* bitpos */
557 complain_overflow_dont, /* complain_on_overflow */
558 _bfd_mips_elf_generic_reloc, /* special_function */
559 "R_MIPS_CALL_LO16", /* name */
560 TRUE, /* partial_inplace */
561 0x0000ffff, /* src_mask */
562 0x0000ffff, /* dst_mask */
563 FALSE), /* pcrel_offset */
565 /* Section displacement, used by an associated event location section. */
566 HOWTO (R_MIPS_SCN_DISP, /* type */
567 0, /* rightshift */
568 2, /* size (0 = byte, 1 = short, 2 = long) */
569 32, /* bitsize */
570 FALSE, /* pc_relative */
571 0, /* bitpos */
572 complain_overflow_dont, /* complain_on_overflow */
573 _bfd_mips_elf_generic_reloc, /* special_function */
574 "R_MIPS_SCN_DISP", /* name */
575 TRUE, /* partial_inplace */
576 0xffffffff, /* src_mask */
577 0xffffffff, /* dst_mask */
578 FALSE), /* pcrel_offset */
580 HOWTO (R_MIPS_REL16, /* type */
581 0, /* rightshift */
582 1, /* size (0 = byte, 1 = short, 2 = long) */
583 16, /* bitsize */
584 FALSE, /* pc_relative */
585 0, /* bitpos */
586 complain_overflow_signed, /* complain_on_overflow */
587 _bfd_mips_elf_generic_reloc, /* special_function */
588 "R_MIPS_REL16", /* name */
589 TRUE, /* partial_inplace */
590 0xffff, /* src_mask */
591 0xffff, /* dst_mask */
592 FALSE), /* pcrel_offset */
594 /* These two are obsolete. */
595 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
596 EMPTY_HOWTO (R_MIPS_PJUMP),
598 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
599 It must be used for multigot GOT's (and only there). */
600 HOWTO (R_MIPS_RELGOT, /* type */
601 0, /* rightshift */
602 2, /* size (0 = byte, 1 = short, 2 = long) */
603 32, /* bitsize */
604 FALSE, /* pc_relative */
605 0, /* bitpos */
606 complain_overflow_dont, /* complain_on_overflow */
607 _bfd_mips_elf_generic_reloc, /* special_function */
608 "R_MIPS_RELGOT", /* name */
609 TRUE, /* partial_inplace */
610 0xffffffff, /* src_mask */
611 0xffffffff, /* dst_mask */
612 FALSE), /* pcrel_offset */
614 /* Protected jump conversion. This is an optimization hint. No
615 relocation is required for correctness. */
616 HOWTO (R_MIPS_JALR, /* type */
617 0, /* rightshift */
618 2, /* size (0 = byte, 1 = short, 2 = long) */
619 32, /* bitsize */
620 FALSE, /* pc_relative */
621 0, /* bitpos */
622 complain_overflow_dont, /* complain_on_overflow */
623 _bfd_mips_elf_generic_reloc, /* special_function */
624 "R_MIPS_JALR", /* name */
625 FALSE, /* partial_inplace */
626 0, /* src_mask */
627 0x00000000, /* dst_mask */
628 FALSE), /* pcrel_offset */
630 /* TLS relocations. */
631 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
632 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
634 HOWTO (R_MIPS_TLS_DTPMOD64, /* type */
635 0, /* rightshift */
636 4, /* size (0 = byte, 1 = short, 2 = long) */
637 64, /* bitsize */
638 FALSE, /* pc_relative */
639 0, /* bitpos */
640 complain_overflow_dont, /* complain_on_overflow */
641 _bfd_mips_elf_generic_reloc, /* special_function */
642 "R_MIPS_TLS_DTPMOD64", /* name */
643 TRUE, /* partial_inplace */
644 MINUS_ONE, /* src_mask */
645 MINUS_ONE, /* dst_mask */
646 FALSE), /* pcrel_offset */
648 HOWTO (R_MIPS_TLS_DTPREL64, /* type */
649 0, /* rightshift */
650 4, /* size (0 = byte, 1 = short, 2 = long) */
651 64, /* bitsize */
652 FALSE, /* pc_relative */
653 0, /* bitpos */
654 complain_overflow_dont, /* complain_on_overflow */
655 _bfd_mips_elf_generic_reloc, /* special_function */
656 "R_MIPS_TLS_DTPREL64", /* name */
657 TRUE, /* partial_inplace */
658 MINUS_ONE, /* src_mask */
659 MINUS_ONE, /* dst_mask */
660 FALSE), /* pcrel_offset */
662 /* TLS general dynamic variable reference. */
663 HOWTO (R_MIPS_TLS_GD, /* type */
664 0, /* rightshift */
665 2, /* size (0 = byte, 1 = short, 2 = long) */
666 16, /* bitsize */
667 FALSE, /* pc_relative */
668 0, /* bitpos */
669 complain_overflow_signed, /* complain_on_overflow */
670 _bfd_mips_elf_generic_reloc, /* special_function */
671 "R_MIPS_TLS_GD", /* name */
672 TRUE, /* partial_inplace */
673 0x0000ffff, /* src_mask */
674 0x0000ffff, /* dst_mask */
675 FALSE), /* pcrel_offset */
677 /* TLS local dynamic variable reference. */
678 HOWTO (R_MIPS_TLS_LDM, /* type */
679 0, /* rightshift */
680 2, /* size (0 = byte, 1 = short, 2 = long) */
681 16, /* bitsize */
682 FALSE, /* pc_relative */
683 0, /* bitpos */
684 complain_overflow_signed, /* complain_on_overflow */
685 _bfd_mips_elf_generic_reloc, /* special_function */
686 "R_MIPS_TLS_LDM", /* name */
687 TRUE, /* partial_inplace */
688 0x0000ffff, /* src_mask */
689 0x0000ffff, /* dst_mask */
690 FALSE), /* pcrel_offset */
692 /* TLS local dynamic offset. */
693 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* 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_mips_elf_generic_reloc, /* special_function */
701 "R_MIPS_TLS_DTPREL_HI16", /* name */
702 TRUE, /* partial_inplace */
703 0x0000ffff, /* src_mask */
704 0x0000ffff, /* dst_mask */
705 FALSE), /* pcrel_offset */
707 /* TLS local dynamic offset. */
708 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
709 0, /* rightshift */
710 2, /* size (0 = byte, 1 = short, 2 = long) */
711 16, /* bitsize */
712 FALSE, /* pc_relative */
713 0, /* bitpos */
714 complain_overflow_signed, /* complain_on_overflow */
715 _bfd_mips_elf_generic_reloc, /* special_function */
716 "R_MIPS_TLS_DTPREL_LO16", /* name */
717 TRUE, /* partial_inplace */
718 0x0000ffff, /* src_mask */
719 0x0000ffff, /* dst_mask */
720 FALSE), /* pcrel_offset */
722 /* TLS thread pointer offset. */
723 HOWTO (R_MIPS_TLS_GOTTPREL, /* 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_signed, /* complain_on_overflow */
730 _bfd_mips_elf_generic_reloc, /* special_function */
731 "R_MIPS_TLS_GOTTPREL", /* name */
732 TRUE, /* partial_inplace */
733 0x0000ffff, /* src_mask */
734 0x0000ffff, /* dst_mask */
735 FALSE), /* pcrel_offset */
737 /* TLS IE dynamic relocations. */
738 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
740 HOWTO (R_MIPS_TLS_TPREL64, /* type */
741 0, /* rightshift */
742 4, /* size (0 = byte, 1 = short, 2 = long) */
743 64, /* bitsize */
744 FALSE, /* pc_relative */
745 0, /* bitpos */
746 complain_overflow_dont, /* complain_on_overflow */
747 _bfd_mips_elf_generic_reloc, /* special_function */
748 "R_MIPS_TLS_TPREL64", /* name */
749 TRUE, /* partial_inplace */
750 MINUS_ONE, /* src_mask */
751 MINUS_ONE, /* dst_mask */
752 FALSE), /* pcrel_offset */
754 /* TLS thread pointer offset. */
755 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
756 0, /* rightshift */
757 2, /* size (0 = byte, 1 = short, 2 = long) */
758 16, /* bitsize */
759 FALSE, /* pc_relative */
760 0, /* bitpos */
761 complain_overflow_signed, /* complain_on_overflow */
762 _bfd_mips_elf_generic_reloc, /* special_function */
763 "R_MIPS_TLS_TPREL_HI16", /* name */
764 TRUE, /* partial_inplace */
765 0x0000ffff, /* src_mask */
766 0x0000ffff, /* dst_mask */
767 FALSE), /* pcrel_offset */
769 /* TLS thread pointer offset. */
770 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
771 0, /* rightshift */
772 2, /* size (0 = byte, 1 = short, 2 = long) */
773 16, /* bitsize */
774 FALSE, /* pc_relative */
775 0, /* bitpos */
776 complain_overflow_signed, /* complain_on_overflow */
777 _bfd_mips_elf_generic_reloc, /* special_function */
778 "R_MIPS_TLS_TPREL_LO16", /* name */
779 TRUE, /* partial_inplace */
780 0x0000ffff, /* src_mask */
781 0x0000ffff, /* dst_mask */
782 FALSE), /* pcrel_offset */
784 /* 32 bit relocation with no addend. */
785 HOWTO (R_MIPS_GLOB_DAT, /* type */
786 0, /* rightshift */
787 2, /* size (0 = byte, 1 = short, 2 = long) */
788 32, /* bitsize */
789 FALSE, /* pc_relative */
790 0, /* bitpos */
791 complain_overflow_dont, /* complain_on_overflow */
792 _bfd_mips_elf_generic_reloc, /* special_function */
793 "R_MIPS_GLOB_DAT", /* name */
794 FALSE, /* partial_inplace */
795 0x0, /* src_mask */
796 0xffffffff, /* dst_mask */
797 FALSE), /* pcrel_offset */
799 EMPTY_HOWTO (52),
800 EMPTY_HOWTO (53),
801 EMPTY_HOWTO (54),
802 EMPTY_HOWTO (55),
803 EMPTY_HOWTO (56),
804 EMPTY_HOWTO (57),
805 EMPTY_HOWTO (58),
806 EMPTY_HOWTO (59),
808 HOWTO (R_MIPS_PC21_S2, /* type */
809 2, /* rightshift */
810 2, /* size (0 = byte, 1 = short, 2 = long) */
811 21, /* bitsize */
812 TRUE, /* pc_relative */
813 0, /* bitpos */
814 complain_overflow_signed, /* complain_on_overflow */
815 _bfd_mips_elf_generic_reloc, /* special_function */
816 "R_MIPS_PC21_S2", /* name */
817 TRUE, /* partial_inplace */
818 0x001fffff, /* src_mask */
819 0x001fffff, /* dst_mask */
820 TRUE), /* pcrel_offset */
822 HOWTO (R_MIPS_PC26_S2, /* type */
823 2, /* rightshift */
824 2, /* size (0 = byte, 1 = short, 2 = long) */
825 26, /* bitsize */
826 TRUE, /* pc_relative */
827 0, /* bitpos */
828 complain_overflow_signed, /* complain_on_overflow */
829 _bfd_mips_elf_generic_reloc, /* special_function */
830 "R_MIPS_PC26_S2", /* name */
831 TRUE, /* partial_inplace */
832 0x03ffffff, /* src_mask */
833 0x03ffffff, /* dst_mask */
834 TRUE), /* pcrel_offset */
836 HOWTO (R_MIPS_PC18_S3, /* type */
837 3, /* rightshift */
838 2, /* size (0 = byte, 1 = short, 2 = long) */
839 18, /* bitsize */
840 TRUE, /* pc_relative */
841 0, /* bitpos */
842 complain_overflow_signed, /* complain_on_overflow */
843 _bfd_mips_elf_generic_reloc, /* special_function */
844 "R_MIPS_PC18_S3", /* name */
845 TRUE, /* partial_inplace */
846 0x0003ffff, /* src_mask */
847 0x0003ffff, /* dst_mask */
848 TRUE), /* pcrel_offset */
850 HOWTO (R_MIPS_PC19_S2, /* type */
851 2, /* rightshift */
852 2, /* size (0 = byte, 1 = short, 2 = long) */
853 19, /* bitsize */
854 TRUE, /* pc_relative */
855 0, /* bitpos */
856 complain_overflow_signed, /* complain_on_overflow */
857 _bfd_mips_elf_generic_reloc, /* special_function */
858 "R_MIPS_PC19_S2", /* name */
859 TRUE, /* partial_inplace */
860 0x0007ffff, /* src_mask */
861 0x0007ffff, /* dst_mask */
862 TRUE), /* pcrel_offset */
864 HOWTO (R_MIPS_PCHI16, /* type */
865 16, /* rightshift */
866 2, /* size (0 = byte, 1 = short, 2 = long) */
867 16, /* bitsize */
868 TRUE, /* pc_relative */
869 0, /* bitpos */
870 complain_overflow_signed, /* complain_on_overflow */
871 _bfd_mips_elf_generic_reloc, /* special_function */
872 "R_MIPS_PCHI16", /* name */
873 TRUE, /* partial_inplace */
874 0x0000ffff, /* src_mask */
875 0x0000ffff, /* dst_mask */
876 TRUE), /* pcrel_offset */
878 HOWTO (R_MIPS_PCLO16, /* type */
879 0, /* rightshift */
880 2, /* size (0 = byte, 1 = short, 2 = long) */
881 16, /* bitsize */
882 TRUE, /* pc_relative */
883 0, /* bitpos */
884 complain_overflow_dont, /* complain_on_overflow */
885 _bfd_mips_elf_generic_reloc, /* special_function */
886 "R_MIPS_PCLO16", /* name */
887 TRUE, /* partial_inplace */
888 0x0000ffff, /* src_mask */
889 0x0000ffff, /* dst_mask */
890 TRUE), /* pcrel_offset */
894 /* The relocation table used for SHT_RELA sections. */
896 static reloc_howto_type mips_elf64_howto_table_rela[] =
898 /* No relocation. */
899 HOWTO (R_MIPS_NONE, /* type */
900 0, /* rightshift */
901 3, /* size (0 = byte, 1 = short, 2 = long) */
902 0, /* bitsize */
903 FALSE, /* pc_relative */
904 0, /* bitpos */
905 complain_overflow_dont, /* complain_on_overflow */
906 _bfd_mips_elf_generic_reloc, /* special_function */
907 "R_MIPS_NONE", /* name */
908 FALSE, /* partial_inplace */
909 0, /* src_mask */
910 0, /* dst_mask */
911 FALSE), /* pcrel_offset */
913 /* 16 bit relocation. */
914 HOWTO (R_MIPS_16, /* type */
915 0, /* rightshift */
916 2, /* size (0 = byte, 1 = short, 2 = long) */
917 16, /* bitsize */
918 FALSE, /* pc_relative */
919 0, /* bitpos */
920 complain_overflow_signed, /* complain_on_overflow */
921 _bfd_mips_elf_generic_reloc, /* special_function */
922 "R_MIPS_16", /* name */
923 FALSE, /* partial_inplace */
924 0, /* src_mask */
925 0x0000ffff, /* dst_mask */
926 FALSE), /* pcrel_offset */
928 /* 32 bit relocation. */
929 HOWTO (R_MIPS_32, /* type */
930 0, /* rightshift */
931 2, /* size (0 = byte, 1 = short, 2 = long) */
932 32, /* bitsize */
933 FALSE, /* pc_relative */
934 0, /* bitpos */
935 complain_overflow_dont, /* complain_on_overflow */
936 _bfd_mips_elf_generic_reloc, /* special_function */
937 "R_MIPS_32", /* name */
938 FALSE, /* partial_inplace */
939 0, /* src_mask */
940 0xffffffff, /* dst_mask */
941 FALSE), /* pcrel_offset */
943 /* 32 bit symbol relative relocation. */
944 HOWTO (R_MIPS_REL32, /* type */
945 0, /* rightshift */
946 2, /* size (0 = byte, 1 = short, 2 = long) */
947 32, /* bitsize */
948 FALSE, /* pc_relative */
949 0, /* bitpos */
950 complain_overflow_dont, /* complain_on_overflow */
951 _bfd_mips_elf_generic_reloc, /* special_function */
952 "R_MIPS_REL32", /* name */
953 FALSE, /* partial_inplace */
954 0, /* src_mask */
955 0xffffffff, /* dst_mask */
956 FALSE), /* pcrel_offset */
958 /* 26 bit jump address. */
959 HOWTO (R_MIPS_26, /* type */
960 2, /* rightshift */
961 2, /* size (0 = byte, 1 = short, 2 = long) */
962 26, /* bitsize */
963 FALSE, /* pc_relative */
964 0, /* bitpos */
965 complain_overflow_dont, /* complain_on_overflow */
966 /* This needs complex overflow
967 detection, because the upper 36
968 bits must match the PC + 4. */
969 _bfd_mips_elf_generic_reloc, /* special_function */
970 "R_MIPS_26", /* name */
971 FALSE, /* partial_inplace */
972 0, /* src_mask */
973 0x03ffffff, /* dst_mask */
974 FALSE), /* pcrel_offset */
976 /* High 16 bits of symbol value. */
977 HOWTO (R_MIPS_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_mips_elf_generic_reloc, /* special_function */
985 "R_MIPS_HI16", /* name */
986 FALSE, /* partial_inplace */
987 0, /* src_mask */
988 0x0000ffff, /* dst_mask */
989 FALSE), /* pcrel_offset */
991 /* Low 16 bits of symbol value. */
992 HOWTO (R_MIPS_LO16, /* type */
993 0, /* rightshift */
994 2, /* size (0 = byte, 1 = short, 2 = long) */
995 16, /* bitsize */
996 FALSE, /* pc_relative */
997 0, /* bitpos */
998 complain_overflow_dont, /* complain_on_overflow */
999 _bfd_mips_elf_generic_reloc, /* special_function */
1000 "R_MIPS_LO16", /* name */
1001 FALSE, /* partial_inplace */
1002 0, /* src_mask */
1003 0x0000ffff, /* dst_mask */
1004 FALSE), /* pcrel_offset */
1006 /* GP relative reference. */
1007 HOWTO (R_MIPS_GPREL16, /* type */
1008 0, /* rightshift */
1009 2, /* size (0 = byte, 1 = short, 2 = long) */
1010 16, /* bitsize */
1011 FALSE, /* pc_relative */
1012 0, /* bitpos */
1013 complain_overflow_signed, /* complain_on_overflow */
1014 mips_elf64_gprel16_reloc, /* special_function */
1015 "R_MIPS_GPREL16", /* name */
1016 FALSE, /* partial_inplace */
1017 0, /* src_mask */
1018 0x0000ffff, /* dst_mask */
1019 FALSE), /* pcrel_offset */
1021 /* Reference to literal section. */
1022 HOWTO (R_MIPS_LITERAL, /* type */
1023 0, /* rightshift */
1024 2, /* size (0 = byte, 1 = short, 2 = long) */
1025 16, /* bitsize */
1026 FALSE, /* pc_relative */
1027 0, /* bitpos */
1028 complain_overflow_signed, /* complain_on_overflow */
1029 mips_elf64_literal_reloc, /* special_function */
1030 "R_MIPS_LITERAL", /* name */
1031 FALSE, /* partial_inplace */
1032 0, /* src_mask */
1033 0x0000ffff, /* dst_mask */
1034 FALSE), /* pcrel_offset */
1036 /* Reference to global offset table. */
1037 HOWTO (R_MIPS_GOT16, /* type */
1038 0, /* rightshift */
1039 2, /* size (0 = byte, 1 = short, 2 = long) */
1040 16, /* bitsize */
1041 FALSE, /* pc_relative */
1042 0, /* bitpos */
1043 complain_overflow_signed, /* complain_on_overflow */
1044 _bfd_mips_elf_generic_reloc, /* special_function */
1045 "R_MIPS_GOT16", /* name */
1046 FALSE, /* partial_inplace */
1047 0, /* src_mask */
1048 0x0000ffff, /* dst_mask */
1049 FALSE), /* pcrel_offset */
1051 /* 16 bit PC relative reference. Note that the ABI document has a typo
1052 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
1053 We do the right thing here. */
1054 HOWTO (R_MIPS_PC16, /* type */
1055 2, /* rightshift */
1056 2, /* size (0 = byte, 1 = short, 2 = long) */
1057 16, /* bitsize */
1058 TRUE, /* pc_relative */
1059 0, /* bitpos */
1060 complain_overflow_signed, /* complain_on_overflow */
1061 _bfd_mips_elf_generic_reloc, /* special_function */
1062 "R_MIPS_PC16", /* name */
1063 FALSE, /* partial_inplace */
1064 0, /* src_mask */
1065 0x0000ffff, /* dst_mask */
1066 TRUE), /* pcrel_offset */
1068 /* 16 bit call through global offset table. */
1069 HOWTO (R_MIPS_CALL16, /* type */
1070 0, /* rightshift */
1071 2, /* size (0 = byte, 1 = short, 2 = long) */
1072 16, /* bitsize */
1073 FALSE, /* pc_relative */
1074 0, /* bitpos */
1075 complain_overflow_signed, /* complain_on_overflow */
1076 _bfd_mips_elf_generic_reloc, /* special_function */
1077 "R_MIPS_CALL16", /* name */
1078 FALSE, /* partial_inplace */
1079 0, /* src_mask */
1080 0x0000ffff, /* dst_mask */
1081 FALSE), /* pcrel_offset */
1083 /* 32 bit GP relative reference. */
1084 HOWTO (R_MIPS_GPREL32, /* type */
1085 0, /* rightshift */
1086 2, /* size (0 = byte, 1 = short, 2 = long) */
1087 32, /* bitsize */
1088 FALSE, /* pc_relative */
1089 0, /* bitpos */
1090 complain_overflow_dont, /* complain_on_overflow */
1091 mips_elf64_gprel32_reloc, /* special_function */
1092 "R_MIPS_GPREL32", /* name */
1093 FALSE, /* partial_inplace */
1094 0, /* src_mask */
1095 0xffffffff, /* dst_mask */
1096 FALSE), /* pcrel_offset */
1098 EMPTY_HOWTO (13),
1099 EMPTY_HOWTO (14),
1100 EMPTY_HOWTO (15),
1102 /* A 5 bit shift field. */
1103 HOWTO (R_MIPS_SHIFT5, /* type */
1104 0, /* rightshift */
1105 2, /* size (0 = byte, 1 = short, 2 = long) */
1106 5, /* bitsize */
1107 FALSE, /* pc_relative */
1108 6, /* bitpos */
1109 complain_overflow_bitfield, /* complain_on_overflow */
1110 _bfd_mips_elf_generic_reloc, /* special_function */
1111 "R_MIPS_SHIFT5", /* name */
1112 FALSE, /* partial_inplace */
1113 0, /* src_mask */
1114 0x000007c0, /* dst_mask */
1115 FALSE), /* pcrel_offset */
1117 /* A 6 bit shift field. */
1118 HOWTO (R_MIPS_SHIFT6, /* type */
1119 0, /* rightshift */
1120 2, /* size (0 = byte, 1 = short, 2 = long) */
1121 6, /* bitsize */
1122 FALSE, /* pc_relative */
1123 6, /* bitpos */
1124 complain_overflow_bitfield, /* complain_on_overflow */
1125 mips_elf64_shift6_reloc, /* special_function */
1126 "R_MIPS_SHIFT6", /* name */
1127 FALSE, /* partial_inplace */
1128 0, /* src_mask */
1129 0x000007c4, /* dst_mask */
1130 FALSE), /* pcrel_offset */
1132 /* 64 bit relocation. */
1133 HOWTO (R_MIPS_64, /* type */
1134 0, /* rightshift */
1135 4, /* size (0 = byte, 1 = short, 2 = long) */
1136 64, /* bitsize */
1137 FALSE, /* pc_relative */
1138 0, /* bitpos */
1139 complain_overflow_dont, /* complain_on_overflow */
1140 _bfd_mips_elf_generic_reloc, /* special_function */
1141 "R_MIPS_64", /* name */
1142 FALSE, /* partial_inplace */
1143 0, /* src_mask */
1144 MINUS_ONE, /* dst_mask */
1145 FALSE), /* pcrel_offset */
1147 /* Displacement in the global offset table. */
1148 HOWTO (R_MIPS_GOT_DISP, /* type */
1149 0, /* rightshift */
1150 2, /* size (0 = byte, 1 = short, 2 = long) */
1151 16, /* bitsize */
1152 FALSE, /* pc_relative */
1153 0, /* bitpos */
1154 complain_overflow_signed, /* complain_on_overflow */
1155 _bfd_mips_elf_generic_reloc, /* special_function */
1156 "R_MIPS_GOT_DISP", /* name */
1157 FALSE, /* partial_inplace */
1158 0, /* src_mask */
1159 0x0000ffff, /* dst_mask */
1160 FALSE), /* pcrel_offset */
1162 /* Displacement to page pointer in the global offset table. */
1163 HOWTO (R_MIPS_GOT_PAGE, /* type */
1164 0, /* rightshift */
1165 2, /* size (0 = byte, 1 = short, 2 = long) */
1166 16, /* bitsize */
1167 FALSE, /* pc_relative */
1168 0, /* bitpos */
1169 complain_overflow_signed, /* complain_on_overflow */
1170 _bfd_mips_elf_generic_reloc, /* special_function */
1171 "R_MIPS_GOT_PAGE", /* name */
1172 FALSE, /* partial_inplace */
1173 0, /* src_mask */
1174 0x0000ffff, /* dst_mask */
1175 FALSE), /* pcrel_offset */
1177 /* Offset from page pointer in the global offset table. */
1178 HOWTO (R_MIPS_GOT_OFST, /* type */
1179 0, /* rightshift */
1180 2, /* size (0 = byte, 1 = short, 2 = long) */
1181 16, /* bitsize */
1182 FALSE, /* pc_relative */
1183 0, /* bitpos */
1184 complain_overflow_signed, /* complain_on_overflow */
1185 _bfd_mips_elf_generic_reloc, /* special_function */
1186 "R_MIPS_GOT_OFST", /* name */
1187 FALSE, /* partial_inplace */
1188 0, /* src_mask */
1189 0x0000ffff, /* dst_mask */
1190 FALSE), /* pcrel_offset */
1192 /* High 16 bits of displacement in global offset table. */
1193 HOWTO (R_MIPS_GOT_HI16, /* type */
1194 0, /* rightshift */
1195 2, /* size (0 = byte, 1 = short, 2 = long) */
1196 16, /* bitsize */
1197 FALSE, /* pc_relative */
1198 0, /* bitpos */
1199 complain_overflow_dont, /* complain_on_overflow */
1200 _bfd_mips_elf_generic_reloc, /* special_function */
1201 "R_MIPS_GOT_HI16", /* name */
1202 FALSE, /* partial_inplace */
1203 0, /* src_mask */
1204 0x0000ffff, /* dst_mask */
1205 FALSE), /* pcrel_offset */
1207 /* Low 16 bits of displacement in global offset table. */
1208 HOWTO (R_MIPS_GOT_LO16, /* type */
1209 0, /* rightshift */
1210 2, /* size (0 = byte, 1 = short, 2 = long) */
1211 16, /* bitsize */
1212 FALSE, /* pc_relative */
1213 0, /* bitpos */
1214 complain_overflow_dont, /* complain_on_overflow */
1215 _bfd_mips_elf_generic_reloc, /* special_function */
1216 "R_MIPS_GOT_LO16", /* name */
1217 FALSE, /* partial_inplace */
1218 0, /* src_mask */
1219 0x0000ffff, /* dst_mask */
1220 FALSE), /* pcrel_offset */
1222 /* 64 bit subtraction. */
1223 HOWTO (R_MIPS_SUB, /* type */
1224 0, /* rightshift */
1225 4, /* size (0 = byte, 1 = short, 2 = long) */
1226 64, /* bitsize */
1227 FALSE, /* pc_relative */
1228 0, /* bitpos */
1229 complain_overflow_dont, /* complain_on_overflow */
1230 _bfd_mips_elf_generic_reloc, /* special_function */
1231 "R_MIPS_SUB", /* name */
1232 FALSE, /* partial_inplace */
1233 0, /* src_mask */
1234 MINUS_ONE, /* dst_mask */
1235 FALSE), /* pcrel_offset */
1237 /* Insert the addend as an instruction. */
1238 /* FIXME: Not handled correctly. */
1239 HOWTO (R_MIPS_INSERT_A, /* type */
1240 0, /* rightshift */
1241 2, /* size (0 = byte, 1 = short, 2 = long) */
1242 32, /* bitsize */
1243 FALSE, /* pc_relative */
1244 0, /* bitpos */
1245 complain_overflow_dont, /* complain_on_overflow */
1246 _bfd_mips_elf_generic_reloc, /* special_function */
1247 "R_MIPS_INSERT_A", /* name */
1248 FALSE, /* partial_inplace */
1249 0, /* src_mask */
1250 0xffffffff, /* dst_mask */
1251 FALSE), /* pcrel_offset */
1253 /* Insert the addend as an instruction, and change all relocations
1254 to refer to the old instruction at the address. */
1255 /* FIXME: Not handled correctly. */
1256 HOWTO (R_MIPS_INSERT_B, /* type */
1257 0, /* rightshift */
1258 2, /* size (0 = byte, 1 = short, 2 = long) */
1259 32, /* bitsize */
1260 FALSE, /* pc_relative */
1261 0, /* bitpos */
1262 complain_overflow_dont, /* complain_on_overflow */
1263 _bfd_mips_elf_generic_reloc, /* special_function */
1264 "R_MIPS_INSERT_B", /* name */
1265 FALSE, /* partial_inplace */
1266 0, /* src_mask */
1267 0xffffffff, /* dst_mask */
1268 FALSE), /* pcrel_offset */
1270 /* Delete a 32 bit instruction. */
1271 /* FIXME: Not handled correctly. */
1272 HOWTO (R_MIPS_DELETE, /* type */
1273 0, /* rightshift */
1274 2, /* size (0 = byte, 1 = short, 2 = long) */
1275 32, /* bitsize */
1276 FALSE, /* pc_relative */
1277 0, /* bitpos */
1278 complain_overflow_dont, /* complain_on_overflow */
1279 _bfd_mips_elf_generic_reloc, /* special_function */
1280 "R_MIPS_DELETE", /* name */
1281 FALSE, /* partial_inplace */
1282 0, /* src_mask */
1283 0xffffffff, /* dst_mask */
1284 FALSE), /* pcrel_offset */
1286 /* Get the higher value of a 64 bit addend. */
1287 HOWTO (R_MIPS_HIGHER, /* type */
1288 0, /* rightshift */
1289 2, /* size (0 = byte, 1 = short, 2 = long) */
1290 16, /* bitsize */
1291 FALSE, /* pc_relative */
1292 0, /* bitpos */
1293 complain_overflow_dont, /* complain_on_overflow */
1294 _bfd_mips_elf_generic_reloc, /* special_function */
1295 "R_MIPS_HIGHER", /* name */
1296 FALSE, /* partial_inplace */
1297 0, /* src_mask */
1298 0x0000ffff, /* dst_mask */
1299 FALSE), /* pcrel_offset */
1301 /* Get the highest value of a 64 bit addend. */
1302 HOWTO (R_MIPS_HIGHEST, /* type */
1303 0, /* rightshift */
1304 2, /* size (0 = byte, 1 = short, 2 = long) */
1305 16, /* bitsize */
1306 FALSE, /* pc_relative */
1307 0, /* bitpos */
1308 complain_overflow_dont, /* complain_on_overflow */
1309 _bfd_mips_elf_generic_reloc, /* special_function */
1310 "R_MIPS_HIGHEST", /* name */
1311 FALSE, /* partial_inplace */
1312 0, /* src_mask */
1313 0x0000ffff, /* dst_mask */
1314 FALSE), /* pcrel_offset */
1316 /* High 16 bits of displacement in global offset table. */
1317 HOWTO (R_MIPS_CALL_HI16, /* type */
1318 0, /* rightshift */
1319 2, /* size (0 = byte, 1 = short, 2 = long) */
1320 16, /* bitsize */
1321 FALSE, /* pc_relative */
1322 0, /* bitpos */
1323 complain_overflow_dont, /* complain_on_overflow */
1324 _bfd_mips_elf_generic_reloc, /* special_function */
1325 "R_MIPS_CALL_HI16", /* name */
1326 FALSE, /* partial_inplace */
1327 0, /* src_mask */
1328 0x0000ffff, /* dst_mask */
1329 FALSE), /* pcrel_offset */
1331 /* Low 16 bits of displacement in global offset table. */
1332 HOWTO (R_MIPS_CALL_LO16, /* type */
1333 0, /* rightshift */
1334 2, /* size (0 = byte, 1 = short, 2 = long) */
1335 16, /* bitsize */
1336 FALSE, /* pc_relative */
1337 0, /* bitpos */
1338 complain_overflow_dont, /* complain_on_overflow */
1339 _bfd_mips_elf_generic_reloc, /* special_function */
1340 "R_MIPS_CALL_LO16", /* name */
1341 FALSE, /* partial_inplace */
1342 0, /* src_mask */
1343 0x0000ffff, /* dst_mask */
1344 FALSE), /* pcrel_offset */
1346 /* Section displacement, used by an associated event location section. */
1347 HOWTO (R_MIPS_SCN_DISP, /* type */
1348 0, /* rightshift */
1349 2, /* size (0 = byte, 1 = short, 2 = long) */
1350 32, /* bitsize */
1351 FALSE, /* pc_relative */
1352 0, /* bitpos */
1353 complain_overflow_dont, /* complain_on_overflow */
1354 _bfd_mips_elf_generic_reloc, /* special_function */
1355 "R_MIPS_SCN_DISP", /* name */
1356 FALSE, /* partial_inplace */
1357 0, /* src_mask */
1358 0xffffffff, /* dst_mask */
1359 FALSE), /* pcrel_offset */
1361 HOWTO (R_MIPS_REL16, /* type */
1362 0, /* rightshift */
1363 1, /* size (0 = byte, 1 = short, 2 = long) */
1364 16, /* bitsize */
1365 FALSE, /* pc_relative */
1366 0, /* bitpos */
1367 complain_overflow_signed, /* complain_on_overflow */
1368 _bfd_mips_elf_generic_reloc, /* special_function */
1369 "R_MIPS_REL16", /* name */
1370 FALSE, /* partial_inplace */
1371 0, /* src_mask */
1372 0xffff, /* dst_mask */
1373 FALSE), /* pcrel_offset */
1375 /* These two are obsolete. */
1376 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1377 EMPTY_HOWTO (R_MIPS_PJUMP),
1379 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1380 It must be used for multigot GOT's (and only there). */
1381 HOWTO (R_MIPS_RELGOT, /* type */
1382 0, /* rightshift */
1383 2, /* size (0 = byte, 1 = short, 2 = long) */
1384 32, /* bitsize */
1385 FALSE, /* pc_relative */
1386 0, /* bitpos */
1387 complain_overflow_dont, /* complain_on_overflow */
1388 _bfd_mips_elf_generic_reloc, /* special_function */
1389 "R_MIPS_RELGOT", /* name */
1390 FALSE, /* partial_inplace */
1391 0, /* src_mask */
1392 0xffffffff, /* dst_mask */
1393 FALSE), /* pcrel_offset */
1395 /* Protected jump conversion. This is an optimization hint. No
1396 relocation is required for correctness. */
1397 HOWTO (R_MIPS_JALR, /* type */
1398 0, /* rightshift */
1399 2, /* size (0 = byte, 1 = short, 2 = long) */
1400 32, /* bitsize */
1401 FALSE, /* pc_relative */
1402 0, /* bitpos */
1403 complain_overflow_dont, /* complain_on_overflow */
1404 _bfd_mips_elf_generic_reloc, /* special_function */
1405 "R_MIPS_JALR", /* name */
1406 FALSE, /* partial_inplace */
1407 0, /* src_mask */
1408 0x00000000, /* dst_mask */
1409 FALSE), /* pcrel_offset */
1411 /* TLS relocations. */
1412 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
1413 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
1415 HOWTO (R_MIPS_TLS_DTPMOD64, /* type */
1416 0, /* rightshift */
1417 4, /* size (0 = byte, 1 = short, 2 = long) */
1418 64, /* bitsize */
1419 FALSE, /* pc_relative */
1420 0, /* bitpos */
1421 complain_overflow_dont, /* complain_on_overflow */
1422 _bfd_mips_elf_generic_reloc, /* special_function */
1423 "R_MIPS_TLS_DTPMOD64", /* name */
1424 FALSE, /* partial_inplace */
1425 0, /* src_mask */
1426 MINUS_ONE, /* dst_mask */
1427 FALSE), /* pcrel_offset */
1429 HOWTO (R_MIPS_TLS_DTPREL64, /* type */
1430 0, /* rightshift */
1431 4, /* size (0 = byte, 1 = short, 2 = long) */
1432 64, /* bitsize */
1433 FALSE, /* pc_relative */
1434 0, /* bitpos */
1435 complain_overflow_dont, /* complain_on_overflow */
1436 _bfd_mips_elf_generic_reloc, /* special_function */
1437 "R_MIPS_TLS_DTPREL64", /* name */
1438 FALSE, /* partial_inplace */
1439 0, /* src_mask */
1440 MINUS_ONE, /* dst_mask */
1441 FALSE), /* pcrel_offset */
1443 /* TLS general dynamic variable reference. */
1444 HOWTO (R_MIPS_TLS_GD, /* type */
1445 0, /* rightshift */
1446 2, /* size (0 = byte, 1 = short, 2 = long) */
1447 16, /* bitsize */
1448 FALSE, /* pc_relative */
1449 0, /* bitpos */
1450 complain_overflow_signed, /* complain_on_overflow */
1451 _bfd_mips_elf_generic_reloc, /* special_function */
1452 "R_MIPS_TLS_GD", /* name */
1453 FALSE, /* partial_inplace */
1454 0, /* src_mask */
1455 0x0000ffff, /* dst_mask */
1456 FALSE), /* pcrel_offset */
1458 /* TLS local dynamic variable reference. */
1459 HOWTO (R_MIPS_TLS_LDM, /* type */
1460 0, /* rightshift */
1461 2, /* size (0 = byte, 1 = short, 2 = long) */
1462 16, /* bitsize */
1463 FALSE, /* pc_relative */
1464 0, /* bitpos */
1465 complain_overflow_signed, /* complain_on_overflow */
1466 _bfd_mips_elf_generic_reloc, /* special_function */
1467 "R_MIPS_TLS_LDM", /* name */
1468 FALSE, /* partial_inplace */
1469 0, /* src_mask */
1470 0x0000ffff, /* dst_mask */
1471 FALSE), /* pcrel_offset */
1473 /* TLS local dynamic offset. */
1474 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
1475 0, /* rightshift */
1476 2, /* size (0 = byte, 1 = short, 2 = long) */
1477 16, /* bitsize */
1478 FALSE, /* pc_relative */
1479 0, /* bitpos */
1480 complain_overflow_signed, /* complain_on_overflow */
1481 _bfd_mips_elf_generic_reloc, /* special_function */
1482 "R_MIPS_TLS_DTPREL_HI16", /* name */
1483 FALSE, /* partial_inplace */
1484 0, /* src_mask */
1485 0x0000ffff, /* dst_mask */
1486 FALSE), /* pcrel_offset */
1488 /* TLS local dynamic offset. */
1489 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
1490 0, /* rightshift */
1491 2, /* size (0 = byte, 1 = short, 2 = long) */
1492 16, /* bitsize */
1493 FALSE, /* pc_relative */
1494 0, /* bitpos */
1495 complain_overflow_signed, /* complain_on_overflow */
1496 _bfd_mips_elf_generic_reloc, /* special_function */
1497 "R_MIPS_TLS_DTPREL_LO16", /* name */
1498 FALSE, /* partial_inplace */
1499 0, /* src_mask */
1500 0x0000ffff, /* dst_mask */
1501 FALSE), /* pcrel_offset */
1503 /* TLS thread pointer offset. */
1504 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
1505 0, /* rightshift */
1506 2, /* size (0 = byte, 1 = short, 2 = long) */
1507 16, /* bitsize */
1508 FALSE, /* pc_relative */
1509 0, /* bitpos */
1510 complain_overflow_signed, /* complain_on_overflow */
1511 _bfd_mips_elf_generic_reloc, /* special_function */
1512 "R_MIPS_TLS_GOTTPREL", /* name */
1513 FALSE, /* partial_inplace */
1514 0, /* src_mask */
1515 0x0000ffff, /* dst_mask */
1516 FALSE), /* pcrel_offset */
1518 /* TLS IE dynamic relocations. */
1519 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
1521 HOWTO (R_MIPS_TLS_TPREL64, /* type */
1522 0, /* rightshift */
1523 4, /* size (0 = byte, 1 = short, 2 = long) */
1524 64, /* bitsize */
1525 FALSE, /* pc_relative */
1526 0, /* bitpos */
1527 complain_overflow_dont, /* complain_on_overflow */
1528 _bfd_mips_elf_generic_reloc, /* special_function */
1529 "R_MIPS_TLS_TPREL64", /* name */
1530 FALSE, /* partial_inplace */
1531 0, /* src_mask */
1532 MINUS_ONE, /* dst_mask */
1533 FALSE), /* pcrel_offset */
1535 /* TLS thread pointer offset. */
1536 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
1537 0, /* rightshift */
1538 2, /* size (0 = byte, 1 = short, 2 = long) */
1539 16, /* bitsize */
1540 FALSE, /* pc_relative */
1541 0, /* bitpos */
1542 complain_overflow_signed, /* complain_on_overflow */
1543 _bfd_mips_elf_generic_reloc, /* special_function */
1544 "R_MIPS_TLS_TPREL_HI16", /* name */
1545 FALSE, /* partial_inplace */
1546 0, /* src_mask */
1547 0x0000ffff, /* dst_mask */
1548 FALSE), /* pcrel_offset */
1550 /* TLS thread pointer offset. */
1551 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
1552 0, /* rightshift */
1553 2, /* size (0 = byte, 1 = short, 2 = long) */
1554 16, /* bitsize */
1555 FALSE, /* pc_relative */
1556 0, /* bitpos */
1557 complain_overflow_signed, /* complain_on_overflow */
1558 _bfd_mips_elf_generic_reloc, /* special_function */
1559 "R_MIPS_TLS_TPREL_LO16", /* name */
1560 FALSE, /* partial_inplace */
1561 0, /* src_mask */
1562 0x0000ffff, /* dst_mask */
1563 FALSE), /* pcrel_offset */
1565 /* 32 bit relocation with no addend. */
1566 HOWTO (R_MIPS_GLOB_DAT, /* type */
1567 0, /* rightshift */
1568 2, /* size (0 = byte, 1 = short, 2 = long) */
1569 32, /* bitsize */
1570 FALSE, /* pc_relative */
1571 0, /* bitpos */
1572 complain_overflow_dont, /* complain_on_overflow */
1573 _bfd_mips_elf_generic_reloc, /* special_function */
1574 "R_MIPS_GLOB_DAT", /* name */
1575 FALSE, /* partial_inplace */
1576 0x0, /* src_mask */
1577 0xffffffff, /* dst_mask */
1578 FALSE), /* pcrel_offset */
1580 EMPTY_HOWTO (52),
1581 EMPTY_HOWTO (53),
1582 EMPTY_HOWTO (54),
1583 EMPTY_HOWTO (55),
1584 EMPTY_HOWTO (56),
1585 EMPTY_HOWTO (57),
1586 EMPTY_HOWTO (58),
1587 EMPTY_HOWTO (59),
1589 HOWTO (R_MIPS_PC21_S2, /* type */
1590 2, /* rightshift */
1591 2, /* size (0 = byte, 1 = short, 2 = long) */
1592 21, /* bitsize */
1593 TRUE, /* pc_relative */
1594 0, /* bitpos */
1595 complain_overflow_signed, /* complain_on_overflow */
1596 _bfd_mips_elf_generic_reloc, /* special_function */
1597 "R_MIPS_PC21_S2", /* name */
1598 FALSE, /* partial_inplace */
1599 0, /* src_mask */
1600 0x001fffff, /* dst_mask */
1601 TRUE), /* pcrel_offset */
1603 HOWTO (R_MIPS_PC26_S2, /* type */
1604 2, /* rightshift */
1605 2, /* size (0 = byte, 1 = short, 2 = long) */
1606 26, /* bitsize */
1607 TRUE, /* pc_relative */
1608 0, /* bitpos */
1609 complain_overflow_signed, /* complain_on_overflow */
1610 _bfd_mips_elf_generic_reloc, /* special_function */
1611 "R_MIPS_PC26_S2", /* name */
1612 FALSE, /* partial_inplace */
1613 0, /* src_mask */
1614 0x03ffffff, /* dst_mask */
1615 TRUE), /* pcrel_offset */
1617 HOWTO (R_MIPS_PC18_S3, /* type */
1618 3, /* rightshift */
1619 2, /* size (0 = byte, 1 = short, 2 = long) */
1620 18, /* bitsize */
1621 TRUE, /* pc_relative */
1622 0, /* bitpos */
1623 complain_overflow_signed, /* complain_on_overflow */
1624 _bfd_mips_elf_generic_reloc, /* special_function */
1625 "R_MIPS_PC18_S3", /* name */
1626 FALSE, /* partial_inplace */
1627 0, /* src_mask */
1628 0x0003ffff, /* dst_mask */
1629 TRUE), /* pcrel_offset */
1631 HOWTO (R_MIPS_PC19_S2, /* type */
1632 2, /* rightshift */
1633 2, /* size (0 = byte, 1 = short, 2 = long) */
1634 19, /* bitsize */
1635 TRUE, /* pc_relative */
1636 0, /* bitpos */
1637 complain_overflow_signed, /* complain_on_overflow */
1638 _bfd_mips_elf_generic_reloc, /* special_function */
1639 "R_MIPS_PC19_S2", /* name */
1640 FALSE, /* partial_inplace */
1641 0, /* src_mask */
1642 0x0007ffff, /* dst_mask */
1643 TRUE), /* pcrel_offset */
1645 HOWTO (R_MIPS_PCHI16, /* type */
1646 16, /* rightshift */
1647 2, /* size (0 = byte, 1 = short, 2 = long) */
1648 16, /* bitsize */
1649 TRUE, /* pc_relative */
1650 0, /* bitpos */
1651 complain_overflow_signed, /* complain_on_overflow */
1652 _bfd_mips_elf_generic_reloc, /* special_function */
1653 "R_MIPS_PCHI16", /* name */
1654 FALSE, /* partial_inplace */
1655 0, /* src_mask */
1656 0x0000ffff, /* dst_mask */
1657 TRUE), /* pcrel_offset */
1659 HOWTO (R_MIPS_PCLO16, /* type */
1660 0, /* rightshift */
1661 2, /* size (0 = byte, 1 = short, 2 = long) */
1662 16, /* bitsize */
1663 TRUE, /* pc_relative */
1664 0, /* bitpos */
1665 complain_overflow_dont, /* complain_on_overflow */
1666 _bfd_mips_elf_generic_reloc, /* special_function */
1667 "R_MIPS_PCLO16", /* name */
1668 FALSE, /* partial_inplace */
1669 0, /* src_mask */
1670 0x0000ffff, /* dst_mask */
1671 TRUE), /* pcrel_offset */
1675 static reloc_howto_type mips16_elf64_howto_table_rel[] =
1677 /* The reloc used for the mips16 jump instruction. */
1678 HOWTO (R_MIPS16_26, /* type */
1679 2, /* rightshift */
1680 2, /* size (0 = byte, 1 = short, 2 = long) */
1681 26, /* bitsize */
1682 FALSE, /* pc_relative */
1683 0, /* bitpos */
1684 complain_overflow_dont, /* complain_on_overflow */
1685 /* This needs complex overflow
1686 detection, because the upper four
1687 bits must match the PC. */
1688 _bfd_mips_elf_generic_reloc, /* special_function */
1689 "R_MIPS16_26", /* name */
1690 TRUE, /* partial_inplace */
1691 0x3ffffff, /* src_mask */
1692 0x3ffffff, /* dst_mask */
1693 FALSE), /* pcrel_offset */
1695 /* The reloc used for the mips16 gprel instruction. */
1696 HOWTO (R_MIPS16_GPREL, /* type */
1697 0, /* rightshift */
1698 2, /* size (0 = byte, 1 = short, 2 = long) */
1699 16, /* bitsize */
1700 FALSE, /* pc_relative */
1701 0, /* bitpos */
1702 complain_overflow_signed, /* complain_on_overflow */
1703 mips16_gprel_reloc, /* special_function */
1704 "R_MIPS16_GPREL", /* name */
1705 TRUE, /* partial_inplace */
1706 0x0000ffff, /* src_mask */
1707 0x0000ffff, /* dst_mask */
1708 FALSE), /* pcrel_offset */
1710 /* A MIPS16 reference to the global offset table. */
1711 HOWTO (R_MIPS16_GOT16, /* type */
1712 0, /* rightshift */
1713 2, /* size (0 = byte, 1 = short, 2 = long) */
1714 16, /* bitsize */
1715 FALSE, /* pc_relative */
1716 0, /* bitpos */
1717 complain_overflow_dont, /* complain_on_overflow */
1718 _bfd_mips_elf_got16_reloc, /* special_function */
1719 "R_MIPS16_GOT16", /* name */
1720 TRUE, /* partial_inplace */
1721 0x0000ffff, /* src_mask */
1722 0x0000ffff, /* dst_mask */
1723 FALSE), /* pcrel_offset */
1725 /* A MIPS16 call through the global offset table. */
1726 HOWTO (R_MIPS16_CALL16, /* type */
1727 0, /* rightshift */
1728 2, /* size (0 = byte, 1 = short, 2 = long) */
1729 16, /* bitsize */
1730 FALSE, /* pc_relative */
1731 0, /* bitpos */
1732 complain_overflow_dont, /* complain_on_overflow */
1733 _bfd_mips_elf_generic_reloc, /* special_function */
1734 "R_MIPS16_CALL16", /* name */
1735 TRUE, /* partial_inplace */
1736 0x0000ffff, /* src_mask */
1737 0x0000ffff, /* dst_mask */
1738 FALSE), /* pcrel_offset */
1740 /* MIPS16 high 16 bits of symbol value. */
1741 HOWTO (R_MIPS16_HI16, /* type */
1742 16, /* rightshift */
1743 2, /* size (0 = byte, 1 = short, 2 = long) */
1744 16, /* bitsize */
1745 FALSE, /* pc_relative */
1746 0, /* bitpos */
1747 complain_overflow_dont, /* complain_on_overflow */
1748 _bfd_mips_elf_hi16_reloc, /* special_function */
1749 "R_MIPS16_HI16", /* name */
1750 TRUE, /* partial_inplace */
1751 0x0000ffff, /* src_mask */
1752 0x0000ffff, /* dst_mask */
1753 FALSE), /* pcrel_offset */
1755 /* MIPS16 low 16 bits of symbol value. */
1756 HOWTO (R_MIPS16_LO16, /* type */
1757 0, /* rightshift */
1758 2, /* size (0 = byte, 1 = short, 2 = long) */
1759 16, /* bitsize */
1760 FALSE, /* pc_relative */
1761 0, /* bitpos */
1762 complain_overflow_dont, /* complain_on_overflow */
1763 _bfd_mips_elf_lo16_reloc, /* special_function */
1764 "R_MIPS16_LO16", /* name */
1765 TRUE, /* partial_inplace */
1766 0x0000ffff, /* src_mask */
1767 0x0000ffff, /* dst_mask */
1768 FALSE), /* pcrel_offset */
1770 /* MIPS16 TLS general dynamic variable reference. */
1771 HOWTO (R_MIPS16_TLS_GD, /* type */
1772 0, /* rightshift */
1773 2, /* size (0 = byte, 1 = short, 2 = long) */
1774 16, /* bitsize */
1775 FALSE, /* pc_relative */
1776 0, /* bitpos */
1777 complain_overflow_signed, /* complain_on_overflow */
1778 _bfd_mips_elf_generic_reloc, /* special_function */
1779 "R_MIPS16_TLS_GD", /* name */
1780 TRUE, /* partial_inplace */
1781 0x0000ffff, /* src_mask */
1782 0x0000ffff, /* dst_mask */
1783 FALSE), /* pcrel_offset */
1785 /* MIPS16 TLS local dynamic variable reference. */
1786 HOWTO (R_MIPS16_TLS_LDM, /* type */
1787 0, /* rightshift */
1788 2, /* size (0 = byte, 1 = short, 2 = long) */
1789 16, /* bitsize */
1790 FALSE, /* pc_relative */
1791 0, /* bitpos */
1792 complain_overflow_signed, /* complain_on_overflow */
1793 _bfd_mips_elf_generic_reloc, /* special_function */
1794 "R_MIPS16_TLS_LDM", /* name */
1795 TRUE, /* partial_inplace */
1796 0x0000ffff, /* src_mask */
1797 0x0000ffff, /* dst_mask */
1798 FALSE), /* pcrel_offset */
1800 /* MIPS16 TLS local dynamic offset. */
1801 HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */
1802 0, /* rightshift */
1803 2, /* size (0 = byte, 1 = short, 2 = long) */
1804 16, /* bitsize */
1805 FALSE, /* pc_relative */
1806 0, /* bitpos */
1807 complain_overflow_signed, /* complain_on_overflow */
1808 _bfd_mips_elf_generic_reloc, /* special_function */
1809 "R_MIPS16_TLS_DTPREL_HI16", /* name */
1810 TRUE, /* partial_inplace */
1811 0x0000ffff, /* src_mask */
1812 0x0000ffff, /* dst_mask */
1813 FALSE), /* pcrel_offset */
1815 /* MIPS16 TLS local dynamic offset. */
1816 HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */
1817 0, /* rightshift */
1818 2, /* size (0 = byte, 1 = short, 2 = long) */
1819 16, /* bitsize */
1820 FALSE, /* pc_relative */
1821 0, /* bitpos */
1822 complain_overflow_signed, /* complain_on_overflow */
1823 _bfd_mips_elf_generic_reloc, /* special_function */
1824 "R_MIPS16_TLS_DTPREL_LO16", /* name */
1825 TRUE, /* partial_inplace */
1826 0x0000ffff, /* src_mask */
1827 0x0000ffff, /* dst_mask */
1828 FALSE), /* pcrel_offset */
1830 /* MIPS16 TLS thread pointer offset. */
1831 HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
1832 0, /* rightshift */
1833 2, /* size (0 = byte, 1 = short, 2 = long) */
1834 16, /* bitsize */
1835 FALSE, /* pc_relative */
1836 0, /* bitpos */
1837 complain_overflow_signed, /* complain_on_overflow */
1838 _bfd_mips_elf_generic_reloc, /* special_function */
1839 "R_MIPS16_TLS_GOTTPREL", /* name */
1840 TRUE, /* partial_inplace */
1841 0x0000ffff, /* src_mask */
1842 0x0000ffff, /* dst_mask */
1843 FALSE), /* pcrel_offset */
1845 /* MIPS16 TLS thread pointer offset. */
1846 HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */
1847 0, /* rightshift */
1848 2, /* size (0 = byte, 1 = short, 2 = long) */
1849 16, /* bitsize */
1850 FALSE, /* pc_relative */
1851 0, /* bitpos */
1852 complain_overflow_signed, /* complain_on_overflow */
1853 _bfd_mips_elf_generic_reloc, /* special_function */
1854 "R_MIPS16_TLS_TPREL_HI16", /* name */
1855 TRUE, /* partial_inplace */
1856 0x0000ffff, /* src_mask */
1857 0x0000ffff, /* dst_mask */
1858 FALSE), /* pcrel_offset */
1860 /* MIPS16 TLS thread pointer offset. */
1861 HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */
1862 0, /* rightshift */
1863 2, /* size (0 = byte, 1 = short, 2 = long) */
1864 16, /* bitsize */
1865 FALSE, /* pc_relative */
1866 0, /* bitpos */
1867 complain_overflow_signed, /* complain_on_overflow */
1868 _bfd_mips_elf_generic_reloc, /* special_function */
1869 "R_MIPS16_TLS_TPREL_LO16", /* name */
1870 TRUE, /* partial_inplace */
1871 0x0000ffff, /* src_mask */
1872 0x0000ffff, /* dst_mask */
1873 FALSE), /* pcrel_offset */
1875 /* MIPS16 16-bit PC-relative branch offset. */
1876 HOWTO (R_MIPS16_PC16_S1, /* type */
1877 1, /* rightshift */
1878 2, /* size (0 = byte, 1 = short, 2 = long) */
1879 16, /* bitsize */
1880 TRUE, /* pc_relative */
1881 0, /* bitpos */
1882 complain_overflow_signed, /* complain_on_overflow */
1883 _bfd_mips_elf_generic_reloc, /* special_function */
1884 "R_MIPS16_PC16_S1", /* name */
1885 TRUE, /* partial_inplace */
1886 0x0000ffff, /* src_mask */
1887 0x0000ffff, /* dst_mask */
1888 TRUE), /* pcrel_offset */
1891 static reloc_howto_type mips16_elf64_howto_table_rela[] =
1893 /* The reloc used for the mips16 jump instruction. */
1894 HOWTO (R_MIPS16_26, /* type */
1895 2, /* rightshift */
1896 2, /* size (0 = byte, 1 = short, 2 = long) */
1897 26, /* bitsize */
1898 FALSE, /* pc_relative */
1899 0, /* bitpos */
1900 complain_overflow_dont, /* complain_on_overflow */
1901 /* This needs complex overflow
1902 detection, because the upper four
1903 bits must match the PC. */
1904 _bfd_mips_elf_generic_reloc, /* special_function */
1905 "R_MIPS16_26", /* name */
1906 FALSE, /* partial_inplace */
1907 0, /* src_mask */
1908 0x3ffffff, /* dst_mask */
1909 FALSE), /* pcrel_offset */
1911 /* The reloc used for the mips16 gprel instruction. */
1912 HOWTO (R_MIPS16_GPREL, /* type */
1913 0, /* rightshift */
1914 2, /* size (0 = byte, 1 = short, 2 = long) */
1915 16, /* bitsize */
1916 FALSE, /* pc_relative */
1917 0, /* bitpos */
1918 complain_overflow_signed, /* complain_on_overflow */
1919 mips16_gprel_reloc, /* special_function */
1920 "R_MIPS16_GPREL", /* name */
1921 FALSE, /* partial_inplace */
1922 0, /* src_mask */
1923 0x0000ffff, /* dst_mask */
1924 FALSE), /* pcrel_offset */
1926 /* A MIPS16 reference to the global offset table. */
1927 HOWTO (R_MIPS16_GOT16, /* type */
1928 0, /* rightshift */
1929 2, /* size (0 = byte, 1 = short, 2 = long) */
1930 16, /* bitsize */
1931 FALSE, /* pc_relative */
1932 0, /* bitpos */
1933 complain_overflow_dont, /* complain_on_overflow */
1934 _bfd_mips_elf_got16_reloc, /* special_function */
1935 "R_MIPS16_GOT16", /* name */
1936 FALSE, /* partial_inplace */
1937 0, /* src_mask */
1938 0x0000ffff, /* dst_mask */
1939 FALSE), /* pcrel_offset */
1941 /* A MIPS16 call through the global offset table. */
1942 HOWTO (R_MIPS16_CALL16, /* type */
1943 0, /* rightshift */
1944 2, /* size (0 = byte, 1 = short, 2 = long) */
1945 16, /* bitsize */
1946 FALSE, /* pc_relative */
1947 0, /* bitpos */
1948 complain_overflow_dont, /* complain_on_overflow */
1949 _bfd_mips_elf_generic_reloc, /* special_function */
1950 "R_MIPS16_CALL16", /* name */
1951 FALSE, /* partial_inplace */
1952 0, /* src_mask */
1953 0x0000ffff, /* dst_mask */
1954 FALSE), /* pcrel_offset */
1956 /* MIPS16 high 16 bits of symbol value. */
1957 HOWTO (R_MIPS16_HI16, /* type */
1958 16, /* rightshift */
1959 2, /* size (0 = byte, 1 = short, 2 = long) */
1960 16, /* bitsize */
1961 FALSE, /* pc_relative */
1962 0, /* bitpos */
1963 complain_overflow_dont, /* complain_on_overflow */
1964 _bfd_mips_elf_hi16_reloc, /* special_function */
1965 "R_MIPS16_HI16", /* name */
1966 FALSE, /* partial_inplace */
1967 0, /* src_mask */
1968 0x0000ffff, /* dst_mask */
1969 FALSE), /* pcrel_offset */
1971 /* MIPS16 low 16 bits of symbol value. */
1972 HOWTO (R_MIPS16_LO16, /* type */
1973 0, /* rightshift */
1974 2, /* size (0 = byte, 1 = short, 2 = long) */
1975 16, /* bitsize */
1976 FALSE, /* pc_relative */
1977 0, /* bitpos */
1978 complain_overflow_dont, /* complain_on_overflow */
1979 _bfd_mips_elf_lo16_reloc, /* special_function */
1980 "R_MIPS16_LO16", /* name */
1981 FALSE, /* partial_inplace */
1982 0, /* src_mask */
1983 0x0000ffff, /* dst_mask */
1984 FALSE), /* pcrel_offset */
1986 /* MIPS16 TLS general dynamic variable reference. */
1987 HOWTO (R_MIPS16_TLS_GD, /* type */
1988 0, /* rightshift */
1989 2, /* size (0 = byte, 1 = short, 2 = long) */
1990 16, /* bitsize */
1991 FALSE, /* pc_relative */
1992 0, /* bitpos */
1993 complain_overflow_signed, /* complain_on_overflow */
1994 _bfd_mips_elf_generic_reloc, /* special_function */
1995 "R_MIPS16_TLS_GD", /* name */
1996 FALSE, /* partial_inplace */
1997 0, /* src_mask */
1998 0x0000ffff, /* dst_mask */
1999 FALSE), /* pcrel_offset */
2001 /* MIPS16 TLS local dynamic variable reference. */
2002 HOWTO (R_MIPS16_TLS_LDM, /* type */
2003 0, /* rightshift */
2004 2, /* size (0 = byte, 1 = short, 2 = long) */
2005 16, /* bitsize */
2006 FALSE, /* pc_relative */
2007 0, /* bitpos */
2008 complain_overflow_signed, /* complain_on_overflow */
2009 _bfd_mips_elf_generic_reloc, /* special_function */
2010 "R_MIPS16_TLS_LDM", /* name */
2011 FALSE, /* partial_inplace */
2012 0, /* src_mask */
2013 0x0000ffff, /* dst_mask */
2014 FALSE), /* pcrel_offset */
2016 /* MIPS16 TLS local dynamic offset. */
2017 HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */
2018 0, /* rightshift */
2019 2, /* size (0 = byte, 1 = short, 2 = long) */
2020 16, /* bitsize */
2021 FALSE, /* pc_relative */
2022 0, /* bitpos */
2023 complain_overflow_signed, /* complain_on_overflow */
2024 _bfd_mips_elf_generic_reloc, /* special_function */
2025 "R_MIPS16_TLS_DTPREL_HI16", /* name */
2026 FALSE, /* partial_inplace */
2027 0, /* src_mask */
2028 0x0000ffff, /* dst_mask */
2029 FALSE), /* pcrel_offset */
2031 /* MIPS16 TLS local dynamic offset. */
2032 HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */
2033 0, /* rightshift */
2034 2, /* size (0 = byte, 1 = short, 2 = long) */
2035 16, /* bitsize */
2036 FALSE, /* pc_relative */
2037 0, /* bitpos */
2038 complain_overflow_signed, /* complain_on_overflow */
2039 _bfd_mips_elf_generic_reloc, /* special_function */
2040 "R_MIPS16_TLS_DTPREL_LO16", /* name */
2041 FALSE, /* partial_inplace */
2042 0, /* src_mask */
2043 0x0000ffff, /* dst_mask */
2044 FALSE), /* pcrel_offset */
2046 /* MIPS16 TLS thread pointer offset. */
2047 HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
2048 0, /* rightshift */
2049 2, /* size (0 = byte, 1 = short, 2 = long) */
2050 16, /* bitsize */
2051 FALSE, /* pc_relative */
2052 0, /* bitpos */
2053 complain_overflow_signed, /* complain_on_overflow */
2054 _bfd_mips_elf_generic_reloc, /* special_function */
2055 "R_MIPS16_TLS_GOTTPREL", /* name */
2056 FALSE, /* partial_inplace */
2057 0, /* src_mask */
2058 0x0000ffff, /* dst_mask */
2059 FALSE), /* pcrel_offset */
2061 /* MIPS16 TLS thread pointer offset. */
2062 HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */
2063 0, /* rightshift */
2064 2, /* size (0 = byte, 1 = short, 2 = long) */
2065 16, /* bitsize */
2066 FALSE, /* pc_relative */
2067 0, /* bitpos */
2068 complain_overflow_signed, /* complain_on_overflow */
2069 _bfd_mips_elf_generic_reloc, /* special_function */
2070 "R_MIPS16_TLS_TPREL_HI16", /* name */
2071 FALSE, /* partial_inplace */
2072 0, /* src_mask */
2073 0x0000ffff, /* dst_mask */
2074 FALSE), /* pcrel_offset */
2076 /* MIPS16 TLS thread pointer offset. */
2077 HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */
2078 0, /* rightshift */
2079 2, /* size (0 = byte, 1 = short, 2 = long) */
2080 16, /* bitsize */
2081 FALSE, /* pc_relative */
2082 0, /* bitpos */
2083 complain_overflow_signed, /* complain_on_overflow */
2084 _bfd_mips_elf_generic_reloc, /* special_function */
2085 "R_MIPS16_TLS_TPREL_LO16", /* name */
2086 FALSE, /* partial_inplace */
2087 0, /* src_mask */
2088 0x0000ffff, /* dst_mask */
2089 FALSE), /* pcrel_offset */
2091 /* MIPS16 16-bit PC-relative branch offset. */
2092 HOWTO (R_MIPS16_PC16_S1, /* type */
2093 1, /* rightshift */
2094 2, /* size (0 = byte, 1 = short, 2 = long) */
2095 16, /* bitsize */
2096 TRUE, /* pc_relative */
2097 0, /* bitpos */
2098 complain_overflow_signed, /* complain_on_overflow */
2099 _bfd_mips_elf_generic_reloc, /* special_function */
2100 "R_MIPS16_PC16_S1", /* name */
2101 FALSE, /* partial_inplace */
2102 0, /* src_mask */
2103 0x0000ffff, /* dst_mask */
2104 TRUE), /* pcrel_offset */
2107 static reloc_howto_type micromips_elf64_howto_table_rel[] =
2109 EMPTY_HOWTO (130),
2110 EMPTY_HOWTO (131),
2111 EMPTY_HOWTO (132),
2113 /* 26 bit jump address. */
2114 HOWTO (R_MICROMIPS_26_S1, /* type */
2115 1, /* rightshift */
2116 2, /* size (0 = byte, 1 = short, 2 = long) */
2117 26, /* bitsize */
2118 FALSE, /* pc_relative */
2119 0, /* bitpos */
2120 complain_overflow_dont, /* complain_on_overflow */
2121 /* This needs complex overflow
2122 detection, because the upper four
2123 bits must match the PC. */
2124 _bfd_mips_elf_generic_reloc, /* special_function */
2125 "R_MICROMIPS_26_S1", /* name */
2126 TRUE, /* partial_inplace */
2127 0x3ffffff, /* src_mask */
2128 0x3ffffff, /* dst_mask */
2129 FALSE), /* pcrel_offset */
2131 /* High 16 bits of symbol value. */
2132 HOWTO (R_MICROMIPS_HI16, /* type */
2133 16, /* rightshift */
2134 2, /* size (0 = byte, 1 = short, 2 = long) */
2135 16, /* bitsize */
2136 FALSE, /* pc_relative */
2137 0, /* bitpos */
2138 complain_overflow_dont, /* complain_on_overflow */
2139 _bfd_mips_elf_hi16_reloc, /* special_function */
2140 "R_MICROMIPS_HI16", /* name */
2141 TRUE, /* partial_inplace */
2142 0x0000ffff, /* src_mask */
2143 0x0000ffff, /* dst_mask */
2144 FALSE), /* pcrel_offset */
2146 /* Low 16 bits of symbol value. */
2147 HOWTO (R_MICROMIPS_LO16, /* type */
2148 0, /* rightshift */
2149 2, /* size (0 = byte, 1 = short, 2 = long) */
2150 16, /* bitsize */
2151 FALSE, /* pc_relative */
2152 0, /* bitpos */
2153 complain_overflow_dont, /* complain_on_overflow */
2154 _bfd_mips_elf_lo16_reloc, /* special_function */
2155 "R_MICROMIPS_LO16", /* name */
2156 TRUE, /* partial_inplace */
2157 0x0000ffff, /* src_mask */
2158 0x0000ffff, /* dst_mask */
2159 FALSE), /* pcrel_offset */
2161 /* GP relative reference. */
2162 HOWTO (R_MICROMIPS_GPREL16, /* type */
2163 0, /* rightshift */
2164 2, /* size (0 = byte, 1 = short, 2 = long) */
2165 16, /* bitsize */
2166 FALSE, /* pc_relative */
2167 0, /* bitpos */
2168 complain_overflow_signed, /* complain_on_overflow */
2169 _bfd_mips_elf32_gprel16_reloc, /* special_function */
2170 "R_MICROMIPS_GPREL16", /* name */
2171 TRUE, /* partial_inplace */
2172 0x0000ffff, /* src_mask */
2173 0x0000ffff, /* dst_mask */
2174 FALSE), /* pcrel_offset */
2176 /* Reference to literal section. */
2177 HOWTO (R_MICROMIPS_LITERAL, /* type */
2178 0, /* rightshift */
2179 2, /* size (0 = byte, 1 = short, 2 = long) */
2180 16, /* bitsize */
2181 FALSE, /* pc_relative */
2182 0, /* bitpos */
2183 complain_overflow_signed, /* complain_on_overflow */
2184 _bfd_mips_elf32_gprel16_reloc, /* special_function */
2185 "R_MICROMIPS_LITERAL", /* name */
2186 TRUE, /* partial_inplace */
2187 0x0000ffff, /* src_mask */
2188 0x0000ffff, /* dst_mask */
2189 FALSE), /* pcrel_offset */
2191 /* Reference to global offset table. */
2192 HOWTO (R_MICROMIPS_GOT16, /* type */
2193 0, /* rightshift */
2194 2, /* size (0 = byte, 1 = short, 2 = long) */
2195 16, /* bitsize */
2196 FALSE, /* pc_relative */
2197 0, /* bitpos */
2198 complain_overflow_signed, /* complain_on_overflow */
2199 _bfd_mips_elf_got16_reloc, /* special_function */
2200 "R_MICROMIPS_GOT16", /* name */
2201 TRUE, /* partial_inplace */
2202 0x0000ffff, /* src_mask */
2203 0x0000ffff, /* dst_mask */
2204 FALSE), /* pcrel_offset */
2206 /* This is for microMIPS branches. */
2207 HOWTO (R_MICROMIPS_PC7_S1, /* type */
2208 1, /* rightshift */
2209 1, /* size (0 = byte, 1 = short, 2 = long) */
2210 7, /* bitsize */
2211 TRUE, /* pc_relative */
2212 0, /* bitpos */
2213 complain_overflow_signed, /* complain_on_overflow */
2214 _bfd_mips_elf_generic_reloc, /* special_function */
2215 "R_MICROMIPS_PC7_S1", /* name */
2216 TRUE, /* partial_inplace */
2217 0x0000007f, /* src_mask */
2218 0x0000007f, /* dst_mask */
2219 TRUE), /* pcrel_offset */
2221 HOWTO (R_MICROMIPS_PC10_S1, /* type */
2222 1, /* rightshift */
2223 1, /* size (0 = byte, 1 = short, 2 = long) */
2224 10, /* bitsize */
2225 TRUE, /* pc_relative */
2226 0, /* bitpos */
2227 complain_overflow_signed, /* complain_on_overflow */
2228 _bfd_mips_elf_generic_reloc, /* special_function */
2229 "R_MICROMIPS_PC10_S1", /* name */
2230 TRUE, /* partial_inplace */
2231 0x000003ff, /* src_mask */
2232 0x000003ff, /* dst_mask */
2233 TRUE), /* pcrel_offset */
2235 HOWTO (R_MICROMIPS_PC16_S1, /* type */
2236 1, /* rightshift */
2237 2, /* size (0 = byte, 1 = short, 2 = long) */
2238 16, /* bitsize */
2239 TRUE, /* pc_relative */
2240 0, /* bitpos */
2241 complain_overflow_signed, /* complain_on_overflow */
2242 _bfd_mips_elf_generic_reloc, /* special_function */
2243 "R_MICROMIPS_PC16_S1", /* name */
2244 TRUE, /* partial_inplace */
2245 0x0000ffff, /* src_mask */
2246 0x0000ffff, /* dst_mask */
2247 TRUE), /* pcrel_offset */
2249 /* 16 bit call through global offset table. */
2250 HOWTO (R_MICROMIPS_CALL16, /* type */
2251 0, /* rightshift */
2252 2, /* size (0 = byte, 1 = short, 2 = long) */
2253 16, /* bitsize */
2254 FALSE, /* pc_relative */
2255 0, /* bitpos */
2256 complain_overflow_signed, /* complain_on_overflow */
2257 _bfd_mips_elf_generic_reloc, /* special_function */
2258 "R_MICROMIPS_CALL16", /* name */
2259 TRUE, /* partial_inplace */
2260 0x0000ffff, /* src_mask */
2261 0x0000ffff, /* dst_mask */
2262 FALSE), /* pcrel_offset */
2264 EMPTY_HOWTO (143),
2265 EMPTY_HOWTO (144),
2267 /* Displacement in the global offset table. */
2268 HOWTO (R_MICROMIPS_GOT_DISP, /* type */
2269 0, /* rightshift */
2270 2, /* size (0 = byte, 1 = short, 2 = long) */
2271 16, /* bitsize */
2272 FALSE, /* pc_relative */
2273 0, /* bitpos */
2274 complain_overflow_signed, /* complain_on_overflow */
2275 _bfd_mips_elf_generic_reloc, /* special_function */
2276 "R_MICROMIPS_GOT_DISP",/* name */
2277 TRUE, /* partial_inplace */
2278 0x0000ffff, /* src_mask */
2279 0x0000ffff, /* dst_mask */
2280 FALSE), /* pcrel_offset */
2282 /* Displacement to page pointer in the global offset table. */
2283 HOWTO (R_MICROMIPS_GOT_PAGE, /* type */
2284 0, /* rightshift */
2285 2, /* size (0 = byte, 1 = short, 2 = long) */
2286 16, /* bitsize */
2287 FALSE, /* pc_relative */
2288 0, /* bitpos */
2289 complain_overflow_signed, /* complain_on_overflow */
2290 _bfd_mips_elf_generic_reloc, /* special_function */
2291 "R_MICROMIPS_GOT_PAGE",/* name */
2292 TRUE, /* partial_inplace */
2293 0x0000ffff, /* src_mask */
2294 0x0000ffff, /* dst_mask */
2295 FALSE), /* pcrel_offset */
2297 /* Offset from page pointer in the global offset table. */
2298 HOWTO (R_MICROMIPS_GOT_OFST, /* type */
2299 0, /* rightshift */
2300 2, /* size (0 = byte, 1 = short, 2 = long) */
2301 16, /* bitsize */
2302 FALSE, /* pc_relative */
2303 0, /* bitpos */
2304 complain_overflow_signed, /* complain_on_overflow */
2305 _bfd_mips_elf_generic_reloc, /* special_function */
2306 "R_MICROMIPS_GOT_OFST",/* name */
2307 TRUE, /* partial_inplace */
2308 0x0000ffff, /* src_mask */
2309 0x0000ffff, /* dst_mask */
2310 FALSE), /* pcrel_offset */
2312 /* High 16 bits of displacement in global offset table. */
2313 HOWTO (R_MICROMIPS_GOT_HI16, /* type */
2314 0, /* rightshift */
2315 2, /* size (0 = byte, 1 = short, 2 = long) */
2316 16, /* bitsize */
2317 FALSE, /* pc_relative */
2318 0, /* bitpos */
2319 complain_overflow_dont, /* complain_on_overflow */
2320 _bfd_mips_elf_generic_reloc, /* special_function */
2321 "R_MICROMIPS_GOT_HI16",/* name */
2322 TRUE, /* partial_inplace */
2323 0x0000ffff, /* src_mask */
2324 0x0000ffff, /* dst_mask */
2325 FALSE), /* pcrel_offset */
2327 /* Low 16 bits of displacement in global offset table. */
2328 HOWTO (R_MICROMIPS_GOT_LO16, /* type */
2329 0, /* rightshift */
2330 2, /* size (0 = byte, 1 = short, 2 = long) */
2331 16, /* bitsize */
2332 FALSE, /* pc_relative */
2333 0, /* bitpos */
2334 complain_overflow_dont, /* complain_on_overflow */
2335 _bfd_mips_elf_generic_reloc, /* special_function */
2336 "R_MICROMIPS_GOT_LO16",/* name */
2337 TRUE, /* partial_inplace */
2338 0x0000ffff, /* src_mask */
2339 0x0000ffff, /* dst_mask */
2340 FALSE), /* pcrel_offset */
2342 /* 64 bit subtraction. Used in the N32 ABI. */
2343 HOWTO (R_MICROMIPS_SUB, /* type */
2344 0, /* rightshift */
2345 4, /* size (0 = byte, 1 = short, 2 = long) */
2346 64, /* bitsize */
2347 FALSE, /* pc_relative */
2348 0, /* bitpos */
2349 complain_overflow_dont, /* complain_on_overflow */
2350 _bfd_mips_elf_generic_reloc, /* special_function */
2351 "R_MICROMIPS_SUB", /* name */
2352 TRUE, /* partial_inplace */
2353 MINUS_ONE, /* src_mask */
2354 MINUS_ONE, /* dst_mask */
2355 FALSE), /* pcrel_offset */
2357 /* We don't support these for REL relocations, because it means building
2358 the addend from a R_MICROMIPS_HIGHEST/R_MICROMIPS_HIGHER/
2359 R_MICROMIPS_HI16/R_MICROMIPS_LO16 sequence with varying ordering,
2360 using fallable heuristics. */
2361 EMPTY_HOWTO (R_MICROMIPS_HIGHER),
2362 EMPTY_HOWTO (R_MICROMIPS_HIGHEST),
2364 /* High 16 bits of displacement in global offset table. */
2365 HOWTO (R_MICROMIPS_CALL_HI16, /* type */
2366 0, /* rightshift */
2367 2, /* size (0 = byte, 1 = short, 2 = long) */
2368 16, /* bitsize */
2369 FALSE, /* pc_relative */
2370 0, /* bitpos */
2371 complain_overflow_dont, /* complain_on_overflow */
2372 _bfd_mips_elf_generic_reloc, /* special_function */
2373 "R_MICROMIPS_CALL_HI16",/* name */
2374 TRUE, /* partial_inplace */
2375 0x0000ffff, /* src_mask */
2376 0x0000ffff, /* dst_mask */
2377 FALSE), /* pcrel_offset */
2379 /* Low 16 bits of displacement in global offset table. */
2380 HOWTO (R_MICROMIPS_CALL_LO16, /* type */
2381 0, /* rightshift */
2382 2, /* size (0 = byte, 1 = short, 2 = long) */
2383 16, /* bitsize */
2384 FALSE, /* pc_relative */
2385 0, /* bitpos */
2386 complain_overflow_dont, /* complain_on_overflow */
2387 _bfd_mips_elf_generic_reloc, /* special_function */
2388 "R_MICROMIPS_CALL_LO16",/* name */
2389 TRUE, /* partial_inplace */
2390 0x0000ffff, /* src_mask */
2391 0x0000ffff, /* dst_mask */
2392 FALSE), /* pcrel_offset */
2394 /* Section displacement. */
2395 HOWTO (R_MICROMIPS_SCN_DISP, /* type */
2396 0, /* rightshift */
2397 2, /* size (0 = byte, 1 = short, 2 = long) */
2398 32, /* bitsize */
2399 FALSE, /* pc_relative */
2400 0, /* bitpos */
2401 complain_overflow_dont, /* complain_on_overflow */
2402 _bfd_mips_elf_generic_reloc, /* special_function */
2403 "R_MICROMIPS_SCN_DISP", /* name */
2404 TRUE, /* partial_inplace */
2405 0xffffffff, /* src_mask */
2406 0xffffffff, /* dst_mask */
2407 FALSE), /* pcrel_offset */
2409 /* Protected jump conversion. This is an optimization hint. No
2410 relocation is required for correctness. */
2411 HOWTO (R_MICROMIPS_JALR, /* type */
2412 0, /* rightshift */
2413 2, /* size (0 = byte, 1 = short, 2 = long) */
2414 32, /* bitsize */
2415 FALSE, /* pc_relative */
2416 0, /* bitpos */
2417 complain_overflow_dont, /* complain_on_overflow */
2418 _bfd_mips_elf_generic_reloc, /* special_function */
2419 "R_MICROMIPS_JALR", /* name */
2420 FALSE, /* partial_inplace */
2421 0, /* src_mask */
2422 0x00000000, /* dst_mask */
2423 FALSE), /* pcrel_offset */
2425 /* Low 16 bits of symbol value. Note that the high 16 bits of symbol values
2426 must be zero. This is used for relaxation. */
2427 HOWTO (R_MICROMIPS_HI0_LO16, /* type */
2428 0, /* rightshift */
2429 2, /* size (0 = byte, 1 = short, 2 = long) */
2430 16, /* bitsize */
2431 FALSE, /* pc_relative */
2432 0, /* bitpos */
2433 complain_overflow_dont, /* complain_on_overflow */
2434 _bfd_mips_elf_generic_reloc, /* special_function */
2435 "R_MICROMIPS_HI0_LO16",/* name */
2436 TRUE, /* partial_inplace */
2437 0x0000ffff, /* src_mask */
2438 0x0000ffff, /* dst_mask */
2439 FALSE), /* pcrel_offset */
2441 EMPTY_HOWTO (158),
2442 EMPTY_HOWTO (159),
2443 EMPTY_HOWTO (160),
2444 EMPTY_HOWTO (161),
2446 /* TLS general dynamic variable reference. */
2447 HOWTO (R_MICROMIPS_TLS_GD, /* type */
2448 0, /* rightshift */
2449 2, /* size (0 = byte, 1 = short, 2 = long) */
2450 16, /* bitsize */
2451 FALSE, /* pc_relative */
2452 0, /* bitpos */
2453 complain_overflow_signed, /* complain_on_overflow */
2454 _bfd_mips_elf_generic_reloc, /* special_function */
2455 "R_MICROMIPS_TLS_GD", /* name */
2456 TRUE, /* partial_inplace */
2457 0x0000ffff, /* src_mask */
2458 0x0000ffff, /* dst_mask */
2459 FALSE), /* pcrel_offset */
2461 /* TLS local dynamic variable reference. */
2462 HOWTO (R_MICROMIPS_TLS_LDM, /* type */
2463 0, /* rightshift */
2464 2, /* size (0 = byte, 1 = short, 2 = long) */
2465 16, /* bitsize */
2466 FALSE, /* pc_relative */
2467 0, /* bitpos */
2468 complain_overflow_signed, /* complain_on_overflow */
2469 _bfd_mips_elf_generic_reloc, /* special_function */
2470 "R_MICROMIPS_TLS_LDM", /* name */
2471 TRUE, /* partial_inplace */
2472 0x0000ffff, /* src_mask */
2473 0x0000ffff, /* dst_mask */
2474 FALSE), /* pcrel_offset */
2476 /* TLS local dynamic offset. */
2477 HOWTO (R_MICROMIPS_TLS_DTPREL_HI16, /* type */
2478 0, /* rightshift */
2479 2, /* size (0 = byte, 1 = short, 2 = long) */
2480 16, /* bitsize */
2481 FALSE, /* pc_relative */
2482 0, /* bitpos */
2483 complain_overflow_signed, /* complain_on_overflow */
2484 _bfd_mips_elf_generic_reloc, /* special_function */
2485 "R_MICROMIPS_TLS_DTPREL_HI16", /* name */
2486 TRUE, /* partial_inplace */
2487 0x0000ffff, /* src_mask */
2488 0x0000ffff, /* dst_mask */
2489 FALSE), /* pcrel_offset */
2491 /* TLS local dynamic offset. */
2492 HOWTO (R_MICROMIPS_TLS_DTPREL_LO16, /* type */
2493 0, /* rightshift */
2494 2, /* size (0 = byte, 1 = short, 2 = long) */
2495 16, /* bitsize */
2496 FALSE, /* pc_relative */
2497 0, /* bitpos */
2498 complain_overflow_signed, /* complain_on_overflow */
2499 _bfd_mips_elf_generic_reloc, /* special_function */
2500 "R_MICROMIPS_TLS_DTPREL_LO16", /* name */
2501 TRUE, /* partial_inplace */
2502 0x0000ffff, /* src_mask */
2503 0x0000ffff, /* dst_mask */
2504 FALSE), /* pcrel_offset */
2506 /* TLS thread pointer offset. */
2507 HOWTO (R_MICROMIPS_TLS_GOTTPREL, /* type */
2508 0, /* rightshift */
2509 2, /* size (0 = byte, 1 = short, 2 = long) */
2510 16, /* bitsize */
2511 FALSE, /* pc_relative */
2512 0, /* bitpos */
2513 complain_overflow_signed, /* complain_on_overflow */
2514 _bfd_mips_elf_generic_reloc, /* special_function */
2515 "R_MICROMIPS_TLS_GOTTPREL", /* name */
2516 TRUE, /* partial_inplace */
2517 0x0000ffff, /* src_mask */
2518 0x0000ffff, /* dst_mask */
2519 FALSE), /* pcrel_offset */
2521 EMPTY_HOWTO (167),
2522 EMPTY_HOWTO (168),
2524 /* TLS thread pointer offset. */
2525 HOWTO (R_MICROMIPS_TLS_TPREL_HI16, /* type */
2526 0, /* rightshift */
2527 2, /* size (0 = byte, 1 = short, 2 = long) */
2528 16, /* bitsize */
2529 FALSE, /* pc_relative */
2530 0, /* bitpos */
2531 complain_overflow_signed, /* complain_on_overflow */
2532 _bfd_mips_elf_generic_reloc, /* special_function */
2533 "R_MICROMIPS_TLS_TPREL_HI16", /* name */
2534 TRUE, /* partial_inplace */
2535 0x0000ffff, /* src_mask */
2536 0x0000ffff, /* dst_mask */
2537 FALSE), /* pcrel_offset */
2539 /* TLS thread pointer offset. */
2540 HOWTO (R_MICROMIPS_TLS_TPREL_LO16, /* type */
2541 0, /* rightshift */
2542 2, /* size (0 = byte, 1 = short, 2 = long) */
2543 16, /* bitsize */
2544 FALSE, /* pc_relative */
2545 0, /* bitpos */
2546 complain_overflow_signed, /* complain_on_overflow */
2547 _bfd_mips_elf_generic_reloc, /* special_function */
2548 "R_MICROMIPS_TLS_TPREL_LO16", /* name */
2549 TRUE, /* partial_inplace */
2550 0x0000ffff, /* src_mask */
2551 0x0000ffff, /* dst_mask */
2552 FALSE), /* pcrel_offset */
2554 EMPTY_HOWTO (171),
2556 /* GP- and PC-relative relocations. */
2557 HOWTO (R_MICROMIPS_GPREL7_S2, /* type */
2558 2, /* rightshift */
2559 1, /* size (0 = byte, 1 = short, 2 = long) */
2560 7, /* bitsize */
2561 FALSE, /* pc_relative */
2562 0, /* bitpos */
2563 complain_overflow_signed, /* complain_on_overflow */
2564 _bfd_mips_elf32_gprel16_reloc, /* special_function */
2565 "R_MICROMIPS_GPREL7_S2", /* name */
2566 TRUE, /* partial_inplace */
2567 0x0000007f, /* src_mask */
2568 0x0000007f, /* dst_mask */
2569 FALSE), /* pcrel_offset */
2571 HOWTO (R_MICROMIPS_PC23_S2, /* type */
2572 2, /* rightshift */
2573 2, /* size (0 = byte, 1 = short, 2 = long) */
2574 23, /* bitsize */
2575 TRUE, /* pc_relative */
2576 0, /* bitpos */
2577 complain_overflow_signed, /* complain_on_overflow */
2578 _bfd_mips_elf_generic_reloc, /* special_function */
2579 "R_MICROMIPS_PC23_S2", /* name */
2580 TRUE, /* partial_inplace */
2581 0x007fffff, /* src_mask */
2582 0x007fffff, /* dst_mask */
2583 TRUE), /* pcrel_offset */
2586 static reloc_howto_type micromips_elf64_howto_table_rela[] =
2588 EMPTY_HOWTO (130),
2589 EMPTY_HOWTO (131),
2590 EMPTY_HOWTO (132),
2592 /* 26 bit jump address. */
2593 HOWTO (R_MICROMIPS_26_S1, /* type */
2594 1, /* rightshift */
2595 2, /* size (0 = byte, 1 = short, 2 = long) */
2596 26, /* bitsize */
2597 FALSE, /* pc_relative */
2598 0, /* bitpos */
2599 complain_overflow_dont, /* complain_on_overflow */
2600 /* This needs complex overflow
2601 detection, because the upper four
2602 bits must match the PC. */
2603 _bfd_mips_elf_generic_reloc, /* special_function */
2604 "R_MICROMIPS_26_S1", /* name */
2605 FALSE, /* partial_inplace */
2606 0, /* src_mask */
2607 0x3ffffff, /* dst_mask */
2608 FALSE), /* pcrel_offset */
2610 /* High 16 bits of symbol value. */
2611 HOWTO (R_MICROMIPS_HI16, /* type */
2612 16, /* rightshift */
2613 2, /* size (0 = byte, 1 = short, 2 = long) */
2614 16, /* bitsize */
2615 FALSE, /* pc_relative */
2616 0, /* bitpos */
2617 complain_overflow_dont, /* complain_on_overflow */
2618 _bfd_mips_elf_hi16_reloc, /* special_function */
2619 "R_MICROMIPS_HI16", /* name */
2620 FALSE, /* partial_inplace */
2621 0, /* src_mask */
2622 0x0000ffff, /* dst_mask */
2623 FALSE), /* pcrel_offset */
2625 /* Low 16 bits of symbol value. */
2626 HOWTO (R_MICROMIPS_LO16, /* type */
2627 0, /* rightshift */
2628 2, /* size (0 = byte, 1 = short, 2 = long) */
2629 16, /* bitsize */
2630 FALSE, /* pc_relative */
2631 0, /* bitpos */
2632 complain_overflow_dont, /* complain_on_overflow */
2633 _bfd_mips_elf_lo16_reloc, /* special_function */
2634 "R_MICROMIPS_LO16", /* name */
2635 FALSE, /* partial_inplace */
2636 0, /* src_mask */
2637 0x0000ffff, /* dst_mask */
2638 FALSE), /* pcrel_offset */
2640 /* GP relative reference. */
2641 HOWTO (R_MICROMIPS_GPREL16, /* type */
2642 0, /* rightshift */
2643 2, /* size (0 = byte, 1 = short, 2 = long) */
2644 16, /* bitsize */
2645 FALSE, /* pc_relative */
2646 0, /* bitpos */
2647 complain_overflow_signed, /* complain_on_overflow */
2648 _bfd_mips_elf32_gprel16_reloc, /* special_function */
2649 "R_MICROMIPS_GPREL16", /* name */
2650 FALSE, /* partial_inplace */
2651 0, /* src_mask */
2652 0x0000ffff, /* dst_mask */
2653 FALSE), /* pcrel_offset */
2655 /* Reference to literal section. */
2656 HOWTO (R_MICROMIPS_LITERAL, /* type */
2657 0, /* rightshift */
2658 2, /* size (0 = byte, 1 = short, 2 = long) */
2659 16, /* bitsize */
2660 FALSE, /* pc_relative */
2661 0, /* bitpos */
2662 complain_overflow_signed, /* complain_on_overflow */
2663 _bfd_mips_elf32_gprel16_reloc, /* special_function */
2664 "R_MICROMIPS_LITERAL", /* name */
2665 FALSE, /* partial_inplace */
2666 0, /* src_mask */
2667 0x0000ffff, /* dst_mask */
2668 FALSE), /* pcrel_offset */
2670 /* Reference to global offset table. */
2671 HOWTO (R_MICROMIPS_GOT16, /* type */
2672 0, /* rightshift */
2673 2, /* size (0 = byte, 1 = short, 2 = long) */
2674 16, /* bitsize */
2675 FALSE, /* pc_relative */
2676 0, /* bitpos */
2677 complain_overflow_signed, /* complain_on_overflow */
2678 _bfd_mips_elf_got16_reloc, /* special_function */
2679 "R_MICROMIPS_GOT16", /* name */
2680 FALSE, /* partial_inplace */
2681 0, /* src_mask */
2682 0x0000ffff, /* dst_mask */
2683 FALSE), /* pcrel_offset */
2685 /* This is for microMIPS branches. */
2686 HOWTO (R_MICROMIPS_PC7_S1, /* type */
2687 1, /* rightshift */
2688 1, /* size (0 = byte, 1 = short, 2 = long) */
2689 7, /* bitsize */
2690 TRUE, /* pc_relative */
2691 0, /* bitpos */
2692 complain_overflow_signed, /* complain_on_overflow */
2693 _bfd_mips_elf_generic_reloc, /* special_function */
2694 "R_MICROMIPS_PC7_S1", /* name */
2695 FALSE, /* partial_inplace */
2696 0, /* src_mask */
2697 0x0000007f, /* dst_mask */
2698 TRUE), /* pcrel_offset */
2700 HOWTO (R_MICROMIPS_PC10_S1, /* type */
2701 1, /* rightshift */
2702 1, /* size (0 = byte, 1 = short, 2 = long) */
2703 10, /* bitsize */
2704 TRUE, /* pc_relative */
2705 0, /* bitpos */
2706 complain_overflow_signed, /* complain_on_overflow */
2707 _bfd_mips_elf_generic_reloc, /* special_function */
2708 "R_MICROMIPS_PC10_S1", /* name */
2709 FALSE, /* partial_inplace */
2710 0, /* src_mask */
2711 0x000003ff, /* dst_mask */
2712 TRUE), /* pcrel_offset */
2714 HOWTO (R_MICROMIPS_PC16_S1, /* type */
2715 1, /* rightshift */
2716 2, /* size (0 = byte, 1 = short, 2 = long) */
2717 16, /* bitsize */
2718 TRUE, /* pc_relative */
2719 0, /* bitpos */
2720 complain_overflow_signed, /* complain_on_overflow */
2721 _bfd_mips_elf_generic_reloc, /* special_function */
2722 "R_MICROMIPS_PC16_S1", /* name */
2723 FALSE, /* partial_inplace */
2724 0, /* src_mask */
2725 0x0000ffff, /* dst_mask */
2726 TRUE), /* pcrel_offset */
2728 /* 16 bit call through global offset table. */
2729 HOWTO (R_MICROMIPS_CALL16, /* type */
2730 0, /* rightshift */
2731 2, /* size (0 = byte, 1 = short, 2 = long) */
2732 16, /* bitsize */
2733 FALSE, /* pc_relative */
2734 0, /* bitpos */
2735 complain_overflow_signed, /* complain_on_overflow */
2736 _bfd_mips_elf_generic_reloc, /* special_function */
2737 "R_MICROMIPS_CALL16", /* name */
2738 FALSE, /* partial_inplace */
2739 0, /* src_mask */
2740 0x0000ffff, /* dst_mask */
2741 FALSE), /* pcrel_offset */
2743 EMPTY_HOWTO (143),
2744 EMPTY_HOWTO (144),
2746 /* Displacement in the global offset table. */
2747 HOWTO (R_MICROMIPS_GOT_DISP, /* type */
2748 0, /* rightshift */
2749 2, /* size (0 = byte, 1 = short, 2 = long) */
2750 16, /* bitsize */
2751 FALSE, /* pc_relative */
2752 0, /* bitpos */
2753 complain_overflow_signed, /* complain_on_overflow */
2754 _bfd_mips_elf_generic_reloc, /* special_function */
2755 "R_MICROMIPS_GOT_DISP",/* name */
2756 FALSE, /* partial_inplace */
2757 0, /* src_mask */
2758 0x0000ffff, /* dst_mask */
2759 FALSE), /* pcrel_offset */
2761 /* Displacement to page pointer in the global offset table. */
2762 HOWTO (R_MICROMIPS_GOT_PAGE, /* type */
2763 0, /* rightshift */
2764 2, /* size (0 = byte, 1 = short, 2 = long) */
2765 16, /* bitsize */
2766 FALSE, /* pc_relative */
2767 0, /* bitpos */
2768 complain_overflow_signed, /* complain_on_overflow */
2769 _bfd_mips_elf_generic_reloc, /* special_function */
2770 "R_MICROMIPS_GOT_PAGE",/* name */
2771 FALSE, /* partial_inplace */
2772 0, /* src_mask */
2773 0x0000ffff, /* dst_mask */
2774 FALSE), /* pcrel_offset */
2776 /* Offset from page pointer in the global offset table. */
2777 HOWTO (R_MICROMIPS_GOT_OFST, /* type */
2778 0, /* rightshift */
2779 2, /* size (0 = byte, 1 = short, 2 = long) */
2780 16, /* bitsize */
2781 FALSE, /* pc_relative */
2782 0, /* bitpos */
2783 complain_overflow_signed, /* complain_on_overflow */
2784 _bfd_mips_elf_generic_reloc, /* special_function */
2785 "R_MICROMIPS_GOT_OFST",/* name */
2786 FALSE, /* partial_inplace */
2787 0, /* src_mask */
2788 0x0000ffff, /* dst_mask */
2789 FALSE), /* pcrel_offset */
2791 /* High 16 bits of displacement in global offset table. */
2792 HOWTO (R_MICROMIPS_GOT_HI16, /* type */
2793 0, /* rightshift */
2794 2, /* size (0 = byte, 1 = short, 2 = long) */
2795 16, /* bitsize */
2796 FALSE, /* pc_relative */
2797 0, /* bitpos */
2798 complain_overflow_dont, /* complain_on_overflow */
2799 _bfd_mips_elf_generic_reloc, /* special_function */
2800 "R_MICROMIPS_GOT_HI16",/* name */
2801 FALSE, /* partial_inplace */
2802 0, /* src_mask */
2803 0x0000ffff, /* dst_mask */
2804 FALSE), /* pcrel_offset */
2806 /* Low 16 bits of displacement in global offset table. */
2807 HOWTO (R_MICROMIPS_GOT_LO16, /* type */
2808 0, /* rightshift */
2809 2, /* size (0 = byte, 1 = short, 2 = long) */
2810 16, /* bitsize */
2811 FALSE, /* pc_relative */
2812 0, /* bitpos */
2813 complain_overflow_dont, /* complain_on_overflow */
2814 _bfd_mips_elf_generic_reloc, /* special_function */
2815 "R_MICROMIPS_GOT_LO16",/* name */
2816 FALSE, /* partial_inplace */
2817 0, /* src_mask */
2818 0x0000ffff, /* dst_mask */
2819 FALSE), /* pcrel_offset */
2821 /* 64 bit subtraction. Used in the N32 ABI. */
2822 HOWTO (R_MICROMIPS_SUB, /* type */
2823 0, /* rightshift */
2824 4, /* size (0 = byte, 1 = short, 2 = long) */
2825 64, /* bitsize */
2826 FALSE, /* pc_relative */
2827 0, /* bitpos */
2828 complain_overflow_dont, /* complain_on_overflow */
2829 _bfd_mips_elf_generic_reloc, /* special_function */
2830 "R_MICROMIPS_SUB", /* name */
2831 FALSE, /* partial_inplace */
2832 0, /* src_mask */
2833 MINUS_ONE, /* dst_mask */
2834 FALSE), /* pcrel_offset */
2836 /* Get the higher value of a 64 bit addend. */
2837 HOWTO (R_MICROMIPS_HIGHER, /* type */
2838 0, /* rightshift */
2839 2, /* size (0 = byte, 1 = short, 2 = long) */
2840 16, /* bitsize */
2841 FALSE, /* pc_relative */
2842 0, /* bitpos */
2843 complain_overflow_dont, /* complain_on_overflow */
2844 _bfd_mips_elf_generic_reloc, /* special_function */
2845 "R_MICROMIPS_HIGHER", /* name */
2846 FALSE, /* partial_inplace */
2847 0, /* src_mask */
2848 0x0000ffff, /* dst_mask */
2849 FALSE), /* pcrel_offset */
2851 /* Get the highest value of a 64 bit addend. */
2852 HOWTO (R_MICROMIPS_HIGHEST, /* type */
2853 0, /* rightshift */
2854 2, /* size (0 = byte, 1 = short, 2 = long) */
2855 16, /* bitsize */
2856 FALSE, /* pc_relative */
2857 0, /* bitpos */
2858 complain_overflow_dont, /* complain_on_overflow */
2859 _bfd_mips_elf_generic_reloc, /* special_function */
2860 "R_MICROMIPS_HIGHEST", /* name */
2861 FALSE, /* partial_inplace */
2862 0, /* src_mask */
2863 0x0000ffff, /* dst_mask */
2864 FALSE), /* pcrel_offset */
2866 /* High 16 bits of displacement in global offset table. */
2867 HOWTO (R_MICROMIPS_CALL_HI16, /* type */
2868 0, /* rightshift */
2869 2, /* size (0 = byte, 1 = short, 2 = long) */
2870 16, /* bitsize */
2871 FALSE, /* pc_relative */
2872 0, /* bitpos */
2873 complain_overflow_dont, /* complain_on_overflow */
2874 _bfd_mips_elf_generic_reloc, /* special_function */
2875 "R_MICROMIPS_CALL_HI16",/* name */
2876 FALSE, /* partial_inplace */
2877 0, /* src_mask */
2878 0x0000ffff, /* dst_mask */
2879 FALSE), /* pcrel_offset */
2881 /* Low 16 bits of displacement in global offset table. */
2882 HOWTO (R_MICROMIPS_CALL_LO16, /* type */
2883 0, /* rightshift */
2884 2, /* size (0 = byte, 1 = short, 2 = long) */
2885 16, /* bitsize */
2886 FALSE, /* pc_relative */
2887 0, /* bitpos */
2888 complain_overflow_dont, /* complain_on_overflow */
2889 _bfd_mips_elf_generic_reloc, /* special_function */
2890 "R_MICROMIPS_CALL_LO16",/* name */
2891 FALSE, /* partial_inplace */
2892 0, /* src_mask */
2893 0x0000ffff, /* dst_mask */
2894 FALSE), /* pcrel_offset */
2896 /* Section displacement. */
2897 HOWTO (R_MICROMIPS_SCN_DISP, /* type */
2898 0, /* rightshift */
2899 2, /* size (0 = byte, 1 = short, 2 = long) */
2900 32, /* bitsize */
2901 FALSE, /* pc_relative */
2902 0, /* bitpos */
2903 complain_overflow_dont, /* complain_on_overflow */
2904 _bfd_mips_elf_generic_reloc, /* special_function */
2905 "R_MICROMIPS_SCN_DISP", /* name */
2906 FALSE, /* partial_inplace */
2907 0, /* src_mask */
2908 0xffffffff, /* dst_mask */
2909 FALSE), /* pcrel_offset */
2911 /* Protected jump conversion. This is an optimization hint. No
2912 relocation is required for correctness. */
2913 HOWTO (R_MICROMIPS_JALR, /* type */
2914 0, /* rightshift */
2915 2, /* size (0 = byte, 1 = short, 2 = long) */
2916 32, /* bitsize */
2917 FALSE, /* pc_relative */
2918 0, /* bitpos */
2919 complain_overflow_dont, /* complain_on_overflow */
2920 _bfd_mips_elf_generic_reloc, /* special_function */
2921 "R_MICROMIPS_JALR", /* name */
2922 FALSE, /* partial_inplace */
2923 0, /* src_mask */
2924 0x00000000, /* dst_mask */
2925 FALSE), /* pcrel_offset */
2927 /* Low 16 bits of symbol value. Note that the high 16 bits of symbol values
2928 must be zero. This is used for relaxation. */
2929 HOWTO (R_MICROMIPS_HI0_LO16, /* type */
2930 0, /* rightshift */
2931 2, /* size (0 = byte, 1 = short, 2 = long) */
2932 16, /* bitsize */
2933 FALSE, /* pc_relative */
2934 0, /* bitpos */
2935 complain_overflow_dont, /* complain_on_overflow */
2936 _bfd_mips_elf_generic_reloc, /* special_function */
2937 "R_MICROMIPS_HI0_LO16",/* name */
2938 FALSE, /* partial_inplace */
2939 0, /* src_mask */
2940 0x0000ffff, /* dst_mask */
2941 FALSE), /* pcrel_offset */
2943 EMPTY_HOWTO (158),
2944 EMPTY_HOWTO (159),
2945 EMPTY_HOWTO (160),
2946 EMPTY_HOWTO (161),
2948 /* TLS general dynamic variable reference. */
2949 HOWTO (R_MICROMIPS_TLS_GD, /* type */
2950 0, /* rightshift */
2951 2, /* size (0 = byte, 1 = short, 2 = long) */
2952 16, /* bitsize */
2953 FALSE, /* pc_relative */
2954 0, /* bitpos */
2955 complain_overflow_signed, /* complain_on_overflow */
2956 _bfd_mips_elf_generic_reloc, /* special_function */
2957 "R_MICROMIPS_TLS_GD", /* name */
2958 FALSE, /* partial_inplace */
2959 0, /* src_mask */
2960 0x0000ffff, /* dst_mask */
2961 FALSE), /* pcrel_offset */
2963 /* TLS local dynamic variable reference. */
2964 HOWTO (R_MICROMIPS_TLS_LDM, /* type */
2965 0, /* rightshift */
2966 2, /* size (0 = byte, 1 = short, 2 = long) */
2967 16, /* bitsize */
2968 FALSE, /* pc_relative */
2969 0, /* bitpos */
2970 complain_overflow_signed, /* complain_on_overflow */
2971 _bfd_mips_elf_generic_reloc, /* special_function */
2972 "R_MICROMIPS_TLS_LDM", /* name */
2973 FALSE, /* partial_inplace */
2974 0, /* src_mask */
2975 0x0000ffff, /* dst_mask */
2976 FALSE), /* pcrel_offset */
2978 /* TLS local dynamic offset. */
2979 HOWTO (R_MICROMIPS_TLS_DTPREL_HI16, /* type */
2980 0, /* rightshift */
2981 2, /* size (0 = byte, 1 = short, 2 = long) */
2982 16, /* bitsize */
2983 FALSE, /* pc_relative */
2984 0, /* bitpos */
2985 complain_overflow_signed, /* complain_on_overflow */
2986 _bfd_mips_elf_generic_reloc, /* special_function */
2987 "R_MICROMIPS_TLS_DTPREL_HI16", /* name */
2988 FALSE, /* partial_inplace */
2989 0, /* src_mask */
2990 0x0000ffff, /* dst_mask */
2991 FALSE), /* pcrel_offset */
2993 /* TLS local dynamic offset. */
2994 HOWTO (R_MICROMIPS_TLS_DTPREL_LO16, /* type */
2995 0, /* rightshift */
2996 2, /* size (0 = byte, 1 = short, 2 = long) */
2997 16, /* bitsize */
2998 FALSE, /* pc_relative */
2999 0, /* bitpos */
3000 complain_overflow_signed, /* complain_on_overflow */
3001 _bfd_mips_elf_generic_reloc, /* special_function */
3002 "R_MICROMIPS_TLS_DTPREL_LO16", /* name */
3003 FALSE, /* partial_inplace */
3004 0, /* src_mask */
3005 0x0000ffff, /* dst_mask */
3006 FALSE), /* pcrel_offset */
3008 /* TLS thread pointer offset. */
3009 HOWTO (R_MICROMIPS_TLS_GOTTPREL, /* type */
3010 0, /* rightshift */
3011 2, /* size (0 = byte, 1 = short, 2 = long) */
3012 16, /* bitsize */
3013 FALSE, /* pc_relative */
3014 0, /* bitpos */
3015 complain_overflow_signed, /* complain_on_overflow */
3016 _bfd_mips_elf_generic_reloc, /* special_function */
3017 "R_MICROMIPS_TLS_GOTTPREL", /* name */
3018 FALSE, /* partial_inplace */
3019 0, /* src_mask */
3020 0x0000ffff, /* dst_mask */
3021 FALSE), /* pcrel_offset */
3023 EMPTY_HOWTO (167),
3024 EMPTY_HOWTO (168),
3026 /* TLS thread pointer offset. */
3027 HOWTO (R_MICROMIPS_TLS_TPREL_HI16, /* type */
3028 0, /* rightshift */
3029 2, /* size (0 = byte, 1 = short, 2 = long) */
3030 16, /* bitsize */
3031 FALSE, /* pc_relative */
3032 0, /* bitpos */
3033 complain_overflow_signed, /* complain_on_overflow */
3034 _bfd_mips_elf_generic_reloc, /* special_function */
3035 "R_MICROMIPS_TLS_TPREL_HI16", /* name */
3036 FALSE, /* partial_inplace */
3037 0, /* src_mask */
3038 0x0000ffff, /* dst_mask */
3039 FALSE), /* pcrel_offset */
3041 /* TLS thread pointer offset. */
3042 HOWTO (R_MICROMIPS_TLS_TPREL_LO16, /* type */
3043 0, /* rightshift */
3044 2, /* size (0 = byte, 1 = short, 2 = long) */
3045 16, /* bitsize */
3046 FALSE, /* pc_relative */
3047 0, /* bitpos */
3048 complain_overflow_signed, /* complain_on_overflow */
3049 _bfd_mips_elf_generic_reloc, /* special_function */
3050 "R_MICROMIPS_TLS_TPREL_LO16", /* name */
3051 FALSE, /* partial_inplace */
3052 0, /* src_mask */
3053 0x0000ffff, /* dst_mask */
3054 FALSE), /* pcrel_offset */
3056 EMPTY_HOWTO (171),
3058 /* GP- and PC-relative relocations. */
3059 HOWTO (R_MICROMIPS_GPREL7_S2, /* type */
3060 2, /* rightshift */
3061 1, /* size (0 = byte, 1 = short, 2 = long) */
3062 7, /* bitsize */
3063 FALSE, /* pc_relative */
3064 0, /* bitpos */
3065 complain_overflow_signed, /* complain_on_overflow */
3066 _bfd_mips_elf32_gprel16_reloc, /* special_function */
3067 "R_MICROMIPS_GPREL7_S2", /* name */
3068 FALSE, /* partial_inplace */
3069 0, /* src_mask */
3070 0x0000007f, /* dst_mask */
3071 FALSE), /* pcrel_offset */
3073 HOWTO (R_MICROMIPS_PC23_S2, /* type */
3074 2, /* rightshift */
3075 2, /* size (0 = byte, 1 = short, 2 = long) */
3076 23, /* bitsize */
3077 TRUE, /* pc_relative */
3078 0, /* bitpos */
3079 complain_overflow_signed, /* complain_on_overflow */
3080 _bfd_mips_elf_generic_reloc, /* special_function */
3081 "R_MICROMIPS_PC23_S2", /* name */
3082 FALSE, /* partial_inplace */
3083 0, /* src_mask */
3084 0x007fffff, /* dst_mask */
3085 TRUE), /* pcrel_offset */
3088 /* GNU extension to record C++ vtable hierarchy */
3089 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
3090 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
3091 0, /* rightshift */
3092 2, /* size (0 = byte, 1 = short, 2 = long) */
3093 0, /* bitsize */
3094 FALSE, /* pc_relative */
3095 0, /* bitpos */
3096 complain_overflow_dont, /* complain_on_overflow */
3097 NULL, /* special_function */
3098 "R_MIPS_GNU_VTINHERIT", /* name */
3099 FALSE, /* partial_inplace */
3100 0, /* src_mask */
3101 0, /* dst_mask */
3102 FALSE); /* pcrel_offset */
3104 /* GNU extension to record C++ vtable member usage */
3105 static reloc_howto_type elf_mips_gnu_vtentry_howto =
3106 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
3107 0, /* rightshift */
3108 2, /* size (0 = byte, 1 = short, 2 = long) */
3109 0, /* bitsize */
3110 FALSE, /* pc_relative */
3111 0, /* bitpos */
3112 complain_overflow_dont, /* complain_on_overflow */
3113 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
3114 "R_MIPS_GNU_VTENTRY", /* name */
3115 FALSE, /* partial_inplace */
3116 0, /* src_mask */
3117 0, /* dst_mask */
3118 FALSE); /* pcrel_offset */
3120 /* 16 bit offset for pc-relative branches. */
3121 static reloc_howto_type elf_mips_gnu_rel16_s2 =
3122 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
3123 2, /* rightshift */
3124 2, /* size (0 = byte, 1 = short, 2 = long) */
3125 16, /* bitsize */
3126 TRUE, /* pc_relative */
3127 0, /* bitpos */
3128 complain_overflow_signed, /* complain_on_overflow */
3129 _bfd_mips_elf_generic_reloc, /* special_function */
3130 "R_MIPS_GNU_REL16_S2", /* name */
3131 TRUE, /* partial_inplace */
3132 0x0000ffff, /* src_mask */
3133 0x0000ffff, /* dst_mask */
3134 TRUE); /* pcrel_offset */
3136 /* 16 bit offset for pc-relative branches. */
3137 static reloc_howto_type elf_mips_gnu_rela16_s2 =
3138 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
3139 2, /* rightshift */
3140 2, /* size (0 = byte, 1 = short, 2 = long) */
3141 16, /* bitsize */
3142 TRUE, /* pc_relative */
3143 0, /* bitpos */
3144 complain_overflow_signed, /* complain_on_overflow */
3145 _bfd_mips_elf_generic_reloc, /* special_function */
3146 "R_MIPS_GNU_REL16_S2", /* name */
3147 FALSE, /* partial_inplace */
3148 0, /* src_mask */
3149 0x0000ffff, /* dst_mask */
3150 TRUE); /* pcrel_offset */
3152 /* 32 bit pc-relative. Used for compact EH tables. */
3153 static reloc_howto_type elf_mips_gnu_pcrel32 =
3154 HOWTO (R_MIPS_PC32, /* type */
3155 0, /* rightshift */
3156 2, /* size (0 = byte, 1 = short, 2 = long) */
3157 32, /* bitsize */
3158 TRUE, /* pc_relative */
3159 0, /* bitpos */
3160 complain_overflow_signed, /* complain_on_overflow */
3161 _bfd_mips_elf_generic_reloc, /* special_function */
3162 "R_MIPS_PC32", /* name */
3163 TRUE, /* partial_inplace */
3164 0xffffffff, /* src_mask */
3165 0xffffffff, /* dst_mask */
3166 TRUE); /* pcrel_offset */
3169 /* Originally a VxWorks extension, but now used for other systems too. */
3170 static reloc_howto_type elf_mips_copy_howto =
3171 HOWTO (R_MIPS_COPY, /* type */
3172 0, /* rightshift */
3173 0, /* this one is variable size */
3174 0, /* bitsize */
3175 FALSE, /* pc_relative */
3176 0, /* bitpos */
3177 complain_overflow_bitfield, /* complain_on_overflow */
3178 _bfd_mips_elf_generic_reloc, /* special_function */
3179 "R_MIPS_COPY", /* name */
3180 FALSE, /* partial_inplace */
3181 0x0, /* src_mask */
3182 0x0, /* dst_mask */
3183 FALSE); /* pcrel_offset */
3185 /* Originally a VxWorks extension, but now used for other systems too. */
3186 static reloc_howto_type elf_mips_jump_slot_howto =
3187 HOWTO (R_MIPS_JUMP_SLOT, /* type */
3188 0, /* rightshift */
3189 4, /* size (0 = byte, 1 = short, 2 = long) */
3190 64, /* bitsize */
3191 FALSE, /* pc_relative */
3192 0, /* bitpos */
3193 complain_overflow_bitfield, /* complain_on_overflow */
3194 _bfd_mips_elf_generic_reloc, /* special_function */
3195 "R_MIPS_JUMP_SLOT", /* name */
3196 FALSE, /* partial_inplace */
3197 0x0, /* src_mask */
3198 0x0, /* dst_mask */
3199 FALSE); /* pcrel_offset */
3201 /* Used in EH tables. */
3202 static reloc_howto_type elf_mips_eh_howto =
3203 HOWTO (R_MIPS_EH, /* type */
3204 0, /* rightshift */
3205 2, /* size (0 = byte, 1 = short, 2 = long) */
3206 32, /* bitsize */
3207 FALSE, /* pc_relative */
3208 0, /* bitpos */
3209 complain_overflow_signed, /* complain_on_overflow */
3210 _bfd_mips_elf_generic_reloc, /* special_function */
3211 "R_MIPS_EH", /* name */
3212 TRUE, /* partial_inplace */
3213 0xffffffff, /* src_mask */
3214 0xffffffff, /* dst_mask */
3215 FALSE); /* pcrel_offset */
3218 /* Swap in a MIPS 64-bit Rel reloc. */
3220 static void
3221 mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src,
3222 Elf64_Mips_Internal_Rela *dst)
3224 dst->r_offset = H_GET_64 (abfd, src->r_offset);
3225 dst->r_sym = H_GET_32 (abfd, src->r_sym);
3226 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
3227 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
3228 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
3229 dst->r_type = H_GET_8 (abfd, src->r_type);
3230 dst->r_addend = 0;
3233 /* Swap in a MIPS 64-bit Rela reloc. */
3235 static void
3236 mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src,
3237 Elf64_Mips_Internal_Rela *dst)
3239 dst->r_offset = H_GET_64 (abfd, src->r_offset);
3240 dst->r_sym = H_GET_32 (abfd, src->r_sym);
3241 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
3242 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
3243 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
3244 dst->r_type = H_GET_8 (abfd, src->r_type);
3245 dst->r_addend = H_GET_S64 (abfd, src->r_addend);
3248 /* Swap out a MIPS 64-bit Rel reloc. */
3250 static void
3251 mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
3252 Elf64_Mips_External_Rel *dst)
3254 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
3255 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
3256 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
3257 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
3258 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
3259 H_PUT_8 (abfd, src->r_type, dst->r_type);
3262 /* Swap out a MIPS 64-bit Rela reloc. */
3264 static void
3265 mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
3266 Elf64_Mips_External_Rela *dst)
3268 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
3269 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
3270 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
3271 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
3272 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
3273 H_PUT_8 (abfd, src->r_type, dst->r_type);
3274 H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
3277 /* Swap in a MIPS 64-bit Rel reloc. */
3279 static void
3280 mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src,
3281 Elf_Internal_Rela *dst)
3283 Elf64_Mips_Internal_Rela mirel;
3285 mips_elf64_swap_reloc_in (abfd,
3286 (const Elf64_Mips_External_Rel *) src,
3287 &mirel);
3289 dst[0].r_offset = mirel.r_offset;
3290 dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
3291 dst[0].r_addend = 0;
3292 dst[1].r_offset = mirel.r_offset;
3293 dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
3294 dst[1].r_addend = 0;
3295 dst[2].r_offset = mirel.r_offset;
3296 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
3297 dst[2].r_addend = 0;
3300 /* Swap in a MIPS 64-bit Rela reloc. */
3302 static void
3303 mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src,
3304 Elf_Internal_Rela *dst)
3306 Elf64_Mips_Internal_Rela mirela;
3308 mips_elf64_swap_reloca_in (abfd,
3309 (const Elf64_Mips_External_Rela *) src,
3310 &mirela);
3312 dst[0].r_offset = mirela.r_offset;
3313 dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
3314 dst[0].r_addend = mirela.r_addend;
3315 dst[1].r_offset = mirela.r_offset;
3316 dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
3317 dst[1].r_addend = 0;
3318 dst[2].r_offset = mirela.r_offset;
3319 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
3320 dst[2].r_addend = 0;
3323 /* Swap out a MIPS 64-bit Rel reloc. */
3325 static void
3326 mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src,
3327 bfd_byte *dst)
3329 Elf64_Mips_Internal_Rela mirel;
3331 mirel.r_offset = src[0].r_offset;
3332 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
3333 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
3335 mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
3336 mirel.r_sym = ELF64_R_SYM (src[0].r_info);
3337 mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
3338 mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
3339 mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
3341 mips_elf64_swap_reloc_out (abfd, &mirel,
3342 (Elf64_Mips_External_Rel *) dst);
3345 /* Swap out a MIPS 64-bit Rela reloc. */
3347 static void
3348 mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
3349 bfd_byte *dst)
3351 Elf64_Mips_Internal_Rela mirela;
3353 mirela.r_offset = src[0].r_offset;
3354 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
3355 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
3357 mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
3358 mirela.r_sym = ELF64_R_SYM (src[0].r_info);
3359 mirela.r_addend = src[0].r_addend;
3360 BFD_ASSERT(src[1].r_addend == 0);
3361 BFD_ASSERT(src[2].r_addend == 0);
3363 mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
3364 mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
3365 mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
3367 mips_elf64_swap_reloca_out (abfd, &mirela,
3368 (Elf64_Mips_External_Rela *) dst);
3371 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
3372 dangerous relocation. */
3374 static bfd_boolean
3375 mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp)
3377 unsigned int count;
3378 asymbol **sym;
3379 unsigned int i;
3381 /* If we've already figured out what GP will be, just return it. */
3382 *pgp = _bfd_get_gp_value (output_bfd);
3383 if (*pgp)
3384 return TRUE;
3386 count = bfd_get_symcount (output_bfd);
3387 sym = bfd_get_outsymbols (output_bfd);
3389 /* The linker script will have created a symbol named `_gp' with the
3390 appropriate value. */
3391 if (sym == NULL)
3392 i = count;
3393 else
3395 for (i = 0; i < count; i++, sym++)
3397 register const char *name;
3399 name = bfd_asymbol_name (*sym);
3400 if (*name == '_' && strcmp (name, "_gp") == 0)
3402 *pgp = bfd_asymbol_value (*sym);
3403 _bfd_set_gp_value (output_bfd, *pgp);
3404 break;
3409 if (i >= count)
3411 /* Only get the error once. */
3412 *pgp = 4;
3413 _bfd_set_gp_value (output_bfd, *pgp);
3414 return FALSE;
3417 return TRUE;
3420 /* We have to figure out the gp value, so that we can adjust the
3421 symbol value correctly. We look up the symbol _gp in the output
3422 BFD. If we can't find it, we're stuck. We cache it in the ELF
3423 target data. We don't need to adjust the symbol value for an
3424 external symbol if we are producing relocatable output. */
3426 static bfd_reloc_status_type
3427 mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
3428 char **error_message, bfd_vma *pgp)
3430 if (bfd_is_und_section (symbol->section)
3431 && ! relocatable)
3433 *pgp = 0;
3434 return bfd_reloc_undefined;
3437 *pgp = _bfd_get_gp_value (output_bfd);
3438 if (*pgp == 0
3439 && (! relocatable
3440 || (symbol->flags & BSF_SECTION_SYM) != 0))
3442 if (relocatable)
3444 /* Make up a value. */
3445 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
3446 _bfd_set_gp_value (output_bfd, *pgp);
3448 else if (!mips_elf64_assign_gp (output_bfd, pgp))
3450 *error_message =
3451 (char *) _("GP relative relocation when _gp not defined");
3452 return bfd_reloc_dangerous;
3456 return bfd_reloc_ok;
3459 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
3460 become the offset from the gp register. */
3462 static bfd_reloc_status_type
3463 mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3464 void *data, asection *input_section, bfd *output_bfd,
3465 char **error_message)
3467 bfd_boolean relocatable;
3468 bfd_reloc_status_type ret;
3469 bfd_vma gp;
3471 /* If we're relocating, and this is an external symbol, we don't want
3472 to change anything. */
3473 if (output_bfd != NULL
3474 && (symbol->flags & BSF_SECTION_SYM) == 0
3475 && (symbol->flags & BSF_LOCAL) != 0)
3477 reloc_entry->address += input_section->output_offset;
3478 return bfd_reloc_ok;
3481 if (output_bfd != NULL)
3482 relocatable = TRUE;
3483 else
3485 relocatable = FALSE;
3486 output_bfd = symbol->section->output_section->owner;
3489 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
3490 &gp);
3491 if (ret != bfd_reloc_ok)
3492 return ret;
3494 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
3495 input_section, relocatable,
3496 data, gp);
3499 /* Do a R_MIPS_LITERAL relocation. */
3501 static bfd_reloc_status_type
3502 mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3503 void *data, asection *input_section, bfd *output_bfd,
3504 char **error_message)
3506 bfd_boolean relocatable;
3507 bfd_reloc_status_type ret;
3508 bfd_vma gp;
3510 /* R_MIPS_LITERAL relocations are defined for local symbols only. */
3511 if (output_bfd != NULL
3512 && (symbol->flags & BSF_SECTION_SYM) == 0
3513 && (symbol->flags & BSF_LOCAL) != 0)
3515 *error_message = (char *)
3516 _("literal relocation occurs for an external symbol");
3517 return bfd_reloc_outofrange;
3520 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
3521 if (output_bfd != NULL)
3522 relocatable = TRUE;
3523 else
3525 relocatable = FALSE;
3526 output_bfd = symbol->section->output_section->owner;
3529 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
3530 &gp);
3531 if (ret != bfd_reloc_ok)
3532 return ret;
3534 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
3535 input_section, relocatable,
3536 data, gp);
3539 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
3540 become the offset from the gp register. */
3542 static bfd_reloc_status_type
3543 mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3544 void *data, asection *input_section, bfd *output_bfd,
3545 char **error_message)
3547 bfd_boolean relocatable;
3548 bfd_reloc_status_type ret;
3549 bfd_vma gp;
3550 bfd_vma relocation;
3551 bfd_vma val;
3553 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
3554 if (output_bfd != NULL
3555 && (symbol->flags & BSF_SECTION_SYM) == 0
3556 && (symbol->flags & BSF_LOCAL) != 0)
3558 *error_message = (char *)
3559 _("32bits gp relative relocation occurs for an external symbol");
3560 return bfd_reloc_outofrange;
3563 if (output_bfd != NULL)
3564 relocatable = TRUE;
3565 else
3567 relocatable = FALSE;
3568 output_bfd = symbol->section->output_section->owner;
3571 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
3572 error_message, &gp);
3573 if (ret != bfd_reloc_ok)
3574 return ret;
3576 if (bfd_is_com_section (symbol->section))
3577 relocation = 0;
3578 else
3579 relocation = symbol->value;
3581 relocation += symbol->section->output_section->vma;
3582 relocation += symbol->section->output_offset;
3584 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
3585 return bfd_reloc_outofrange;
3587 /* Set val to the offset into the section or symbol. */
3588 val = reloc_entry->addend;
3590 if (reloc_entry->howto->partial_inplace)
3591 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
3593 /* Adjust val for the final section location and GP value. If we
3594 are producing relocatable output, we don't want to do this for
3595 an external symbol. */
3596 if (! relocatable
3597 || (symbol->flags & BSF_SECTION_SYM) != 0)
3598 val += relocation - gp;
3600 if (reloc_entry->howto->partial_inplace)
3601 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
3602 else
3603 reloc_entry->addend = val;
3605 if (relocatable)
3606 reloc_entry->address += input_section->output_offset;
3608 return bfd_reloc_ok;
3611 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
3612 the rest is at bits 6-10. The bitpos already got right by the howto. */
3614 static bfd_reloc_status_type
3615 mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3616 void *data, asection *input_section, bfd *output_bfd,
3617 char **error_message)
3619 if (reloc_entry->howto->partial_inplace)
3621 reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
3622 | (reloc_entry->addend & 0x00000800) >> 9);
3625 return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
3626 input_section, output_bfd,
3627 error_message);
3630 /* Handle a mips16 GP relative reloc. */
3632 static bfd_reloc_status_type
3633 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3634 void *data, asection *input_section, bfd *output_bfd,
3635 char **error_message)
3637 bfd_boolean relocatable;
3638 bfd_reloc_status_type ret;
3639 bfd_byte *location;
3640 bfd_vma gp;
3642 /* If we're relocating, and this is an external symbol, we don't want
3643 to change anything. */
3644 if (output_bfd != NULL
3645 && (symbol->flags & BSF_SECTION_SYM) == 0
3646 && (symbol->flags & BSF_LOCAL) != 0)
3648 reloc_entry->address += input_section->output_offset;
3649 return bfd_reloc_ok;
3652 if (output_bfd != NULL)
3653 relocatable = TRUE;
3654 else
3656 relocatable = FALSE;
3657 output_bfd = symbol->section->output_section->owner;
3660 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
3661 &gp);
3662 if (ret != bfd_reloc_ok)
3663 return ret;
3665 location = (bfd_byte *) data + reloc_entry->address;
3666 _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
3667 location);
3668 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
3669 input_section, relocatable,
3670 data, gp);
3671 _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
3672 location);
3674 return ret;
3677 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
3679 struct elf_reloc_map {
3680 bfd_reloc_code_real_type bfd_val;
3681 enum elf_mips_reloc_type elf_val;
3684 static const struct elf_reloc_map mips_reloc_map[] =
3686 { BFD_RELOC_NONE, R_MIPS_NONE },
3687 { BFD_RELOC_16, R_MIPS_16 },
3688 { BFD_RELOC_32, R_MIPS_32 },
3689 /* There is no BFD reloc for R_MIPS_REL32. */
3690 { BFD_RELOC_64, R_MIPS_64 },
3691 { BFD_RELOC_CTOR, R_MIPS_64 },
3692 { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
3693 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
3694 { BFD_RELOC_LO16, R_MIPS_LO16 },
3695 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
3696 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
3697 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
3698 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
3699 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
3700 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
3701 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
3702 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
3703 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
3704 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
3705 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
3706 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
3707 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
3708 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
3709 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
3710 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
3711 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
3712 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
3713 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
3714 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
3715 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
3716 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
3717 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
3718 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
3719 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
3720 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
3721 { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
3722 { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
3723 { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
3724 { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
3725 { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
3726 { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
3727 { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
3728 { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
3729 { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
3730 { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
3731 { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
3732 { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
3733 { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 },
3734 { BFD_RELOC_MIPS_21_PCREL_S2, R_MIPS_PC21_S2 },
3735 { BFD_RELOC_MIPS_26_PCREL_S2, R_MIPS_PC26_S2 },
3736 { BFD_RELOC_MIPS_18_PCREL_S3, R_MIPS_PC18_S3 },
3737 { BFD_RELOC_MIPS_19_PCREL_S2, R_MIPS_PC19_S2 },
3738 { BFD_RELOC_HI16_S_PCREL, R_MIPS_PCHI16 },
3739 { BFD_RELOC_LO16_PCREL, R_MIPS_PCLO16 }
3742 static const struct elf_reloc_map mips16_reloc_map[] =
3744 { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
3745 { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
3746 { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
3747 { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
3748 { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
3749 { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
3750 { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
3751 { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
3752 { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
3753 R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
3754 { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
3755 R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
3756 { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
3757 { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
3758 { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min },
3759 { BFD_RELOC_MIPS16_16_PCREL_S1, R_MIPS16_PC16_S1 - R_MIPS16_min }
3762 static const struct elf_reloc_map micromips_reloc_map[] =
3764 { BFD_RELOC_MICROMIPS_JMP, R_MICROMIPS_26_S1 - R_MICROMIPS_min },
3765 { BFD_RELOC_MICROMIPS_HI16_S, R_MICROMIPS_HI16 - R_MICROMIPS_min },
3766 { BFD_RELOC_MICROMIPS_LO16, R_MICROMIPS_LO16 - R_MICROMIPS_min },
3767 { BFD_RELOC_MICROMIPS_GPREL16, R_MICROMIPS_GPREL16 - R_MICROMIPS_min },
3768 { BFD_RELOC_MICROMIPS_LITERAL, R_MICROMIPS_LITERAL - R_MICROMIPS_min },
3769 { BFD_RELOC_MICROMIPS_GOT16, R_MICROMIPS_GOT16 - R_MICROMIPS_min },
3770 { BFD_RELOC_MICROMIPS_7_PCREL_S1, R_MICROMIPS_PC7_S1 - R_MICROMIPS_min },
3771 { BFD_RELOC_MICROMIPS_10_PCREL_S1, R_MICROMIPS_PC10_S1 - R_MICROMIPS_min },
3772 { BFD_RELOC_MICROMIPS_16_PCREL_S1, R_MICROMIPS_PC16_S1 - R_MICROMIPS_min },
3773 { BFD_RELOC_MICROMIPS_CALL16, R_MICROMIPS_CALL16 - R_MICROMIPS_min },
3774 { BFD_RELOC_MICROMIPS_GOT_DISP, R_MICROMIPS_GOT_DISP - R_MICROMIPS_min },
3775 { BFD_RELOC_MICROMIPS_GOT_PAGE, R_MICROMIPS_GOT_PAGE - R_MICROMIPS_min },
3776 { BFD_RELOC_MICROMIPS_GOT_OFST, R_MICROMIPS_GOT_OFST - R_MICROMIPS_min },
3777 { BFD_RELOC_MICROMIPS_GOT_HI16, R_MICROMIPS_GOT_HI16 - R_MICROMIPS_min },
3778 { BFD_RELOC_MICROMIPS_GOT_LO16, R_MICROMIPS_GOT_LO16 - R_MICROMIPS_min },
3779 { BFD_RELOC_MICROMIPS_SUB, R_MICROMIPS_SUB - R_MICROMIPS_min },
3780 { BFD_RELOC_MICROMIPS_HIGHER, R_MICROMIPS_HIGHER - R_MICROMIPS_min },
3781 { BFD_RELOC_MICROMIPS_HIGHEST, R_MICROMIPS_HIGHEST - R_MICROMIPS_min },
3782 { BFD_RELOC_MICROMIPS_CALL_HI16, R_MICROMIPS_CALL_HI16 - R_MICROMIPS_min },
3783 { BFD_RELOC_MICROMIPS_CALL_LO16, R_MICROMIPS_CALL_LO16 - R_MICROMIPS_min },
3784 { BFD_RELOC_MICROMIPS_SCN_DISP, R_MICROMIPS_SCN_DISP - R_MICROMIPS_min },
3785 { BFD_RELOC_MICROMIPS_JALR, R_MICROMIPS_JALR - R_MICROMIPS_min },
3786 /* There is no BFD reloc for R_MICROMIPS_HI0_LO16. */
3787 { BFD_RELOC_MICROMIPS_TLS_GD, R_MICROMIPS_TLS_GD - R_MICROMIPS_min },
3788 { BFD_RELOC_MICROMIPS_TLS_LDM, R_MICROMIPS_TLS_LDM - R_MICROMIPS_min },
3789 { BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16,
3790 R_MICROMIPS_TLS_DTPREL_HI16 - R_MICROMIPS_min },
3791 { BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16,
3792 R_MICROMIPS_TLS_DTPREL_LO16 - R_MICROMIPS_min },
3793 { BFD_RELOC_MICROMIPS_TLS_GOTTPREL,
3794 R_MICROMIPS_TLS_GOTTPREL - R_MICROMIPS_min },
3795 { BFD_RELOC_MICROMIPS_TLS_TPREL_HI16,
3796 R_MICROMIPS_TLS_TPREL_HI16 - R_MICROMIPS_min },
3797 { BFD_RELOC_MICROMIPS_TLS_TPREL_LO16,
3798 R_MICROMIPS_TLS_TPREL_LO16 - R_MICROMIPS_min },
3799 /* There is no BFD reloc for R_MICROMIPS_GPREL7_S2. */
3800 /* There is no BFD reloc for R_MICROMIPS_PC23_S2. */
3802 /* Given a BFD reloc type, return a howto structure. */
3804 static reloc_howto_type *
3805 bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3806 bfd_reloc_code_real_type code)
3808 unsigned int i;
3809 /* FIXME: We default to RELA here instead of choosing the right
3810 relocation variant. */
3811 reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
3812 reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela;
3813 reloc_howto_type *howto_micromips_table = micromips_elf64_howto_table_rela;
3815 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
3816 i++)
3818 if (mips_reloc_map[i].bfd_val == code)
3819 return &howto_table[(int) mips_reloc_map[i].elf_val];
3822 for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
3823 i++)
3825 if (mips16_reloc_map[i].bfd_val == code)
3826 return &howto16_table[(int) mips16_reloc_map[i].elf_val];
3829 for (i = 0; i < sizeof (micromips_reloc_map) / sizeof (struct elf_reloc_map);
3830 i++)
3832 if (micromips_reloc_map[i].bfd_val == code)
3833 return &howto_micromips_table[(int) micromips_reloc_map[i].elf_val];
3836 switch (code)
3838 case BFD_RELOC_VTABLE_INHERIT:
3839 return &elf_mips_gnu_vtinherit_howto;
3840 case BFD_RELOC_VTABLE_ENTRY:
3841 return &elf_mips_gnu_vtentry_howto;
3842 case BFD_RELOC_32_PCREL:
3843 return &elf_mips_gnu_pcrel32;
3844 case BFD_RELOC_MIPS_EH:
3845 return &elf_mips_eh_howto;
3846 case BFD_RELOC_MIPS_COPY:
3847 return &elf_mips_copy_howto;
3848 case BFD_RELOC_MIPS_JUMP_SLOT:
3849 return &elf_mips_jump_slot_howto;
3850 default:
3851 bfd_set_error (bfd_error_bad_value);
3852 return NULL;
3856 static reloc_howto_type *
3857 bfd_elf64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3858 const char *r_name)
3860 unsigned int i;
3862 for (i = 0;
3863 i < (sizeof (mips_elf64_howto_table_rela)
3864 / sizeof (mips_elf64_howto_table_rela[0])); i++)
3865 if (mips_elf64_howto_table_rela[i].name != NULL
3866 && strcasecmp (mips_elf64_howto_table_rela[i].name, r_name) == 0)
3867 return &mips_elf64_howto_table_rela[i];
3869 for (i = 0;
3870 i < (sizeof (mips16_elf64_howto_table_rela)
3871 / sizeof (mips16_elf64_howto_table_rela[0]));
3872 i++)
3873 if (mips16_elf64_howto_table_rela[i].name != NULL
3874 && strcasecmp (mips16_elf64_howto_table_rela[i].name, r_name) == 0)
3875 return &mips16_elf64_howto_table_rela[i];
3877 for (i = 0;
3878 i < (sizeof (micromips_elf64_howto_table_rela)
3879 / sizeof (micromips_elf64_howto_table_rela[0]));
3880 i++)
3881 if (micromips_elf64_howto_table_rela[i].name != NULL
3882 && strcasecmp (micromips_elf64_howto_table_rela[i].name, r_name) == 0)
3883 return &micromips_elf64_howto_table_rela[i];
3885 if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
3886 return &elf_mips_gnu_vtinherit_howto;
3887 if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
3888 return &elf_mips_gnu_vtentry_howto;
3889 if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
3890 return &elf_mips_gnu_rel16_s2;
3891 if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
3892 return &elf_mips_gnu_rela16_s2;
3893 if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
3894 return &elf_mips_gnu_pcrel32;
3895 if (strcasecmp (elf_mips_eh_howto.name, r_name) == 0)
3896 return &elf_mips_eh_howto;
3897 if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
3898 return &elf_mips_copy_howto;
3899 if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
3900 return &elf_mips_jump_slot_howto;
3902 return NULL;
3905 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
3907 static reloc_howto_type *
3908 mips_elf64_rtype_to_howto (bfd *abfd, unsigned int r_type, bfd_boolean rela_p)
3910 reloc_howto_type *howto = NULL;
3912 switch (r_type)
3914 case R_MIPS_GNU_VTINHERIT:
3915 return &elf_mips_gnu_vtinherit_howto;
3916 case R_MIPS_GNU_VTENTRY:
3917 return &elf_mips_gnu_vtentry_howto;
3918 case R_MIPS_GNU_REL16_S2:
3919 if (rela_p)
3920 return &elf_mips_gnu_rela16_s2;
3921 else
3922 return &elf_mips_gnu_rel16_s2;
3923 case R_MIPS_PC32:
3924 return &elf_mips_gnu_pcrel32;
3925 case R_MIPS_EH:
3926 return &elf_mips_eh_howto;
3927 case R_MIPS_COPY:
3928 return &elf_mips_copy_howto;
3929 case R_MIPS_JUMP_SLOT:
3930 return &elf_mips_jump_slot_howto;
3931 default:
3932 if (r_type >= R_MICROMIPS_min && r_type < R_MICROMIPS_max)
3934 if (rela_p)
3935 howto
3936 = &micromips_elf64_howto_table_rela[r_type - R_MICROMIPS_min];
3937 else
3938 howto
3939 = &micromips_elf64_howto_table_rel[r_type - R_MICROMIPS_min];
3941 if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
3943 if (rela_p)
3944 howto = &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min];
3945 else
3946 howto = &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min];
3948 if (r_type < R_MIPS_max)
3950 if (rela_p)
3951 howto = &mips_elf64_howto_table_rela[r_type];
3952 else
3953 howto = &mips_elf64_howto_table_rel[r_type];
3955 if (howto != NULL && howto->name != NULL)
3956 return howto;
3958 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
3959 abfd, r_type);
3960 bfd_set_error (bfd_error_bad_value);
3961 return NULL;
3965 /* Prevent relocation handling by bfd for MIPS ELF64. */
3967 static bfd_boolean
3968 mips_elf64_info_to_howto_rela (bfd *abfd,
3969 arelent *cache_ptr ATTRIBUTE_UNUSED,
3970 Elf_Internal_Rela *dst)
3972 unsigned int r_type = ELF32_R_TYPE (dst->r_info);
3973 /* xgettext:c-format */
3974 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
3975 abfd, r_type);
3976 bfd_set_error (bfd_error_bad_value);
3977 return FALSE;
3980 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
3981 to three relocs, we must tell the user to allocate more space. */
3983 static long
3984 mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
3986 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
3989 /* Read the relocations from one reloc section. This is mostly copied
3990 from elfcode.h, except for the changes to expand one external
3991 relocation to 3 internal ones. To reduce processing effort we
3992 could discard those R_MIPS_NONE relocations that occupy the second
3993 and the third entry of a triplet, as `mips_elf64_write_rel' and
3994 `mips_elf64_write_rela' recreate them in output automagically,
3995 however that would also remove them from `objdump -r' output,
3996 breaking a long-established tradition and likely confusing people. */
3998 static bfd_boolean
3999 mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
4000 Elf_Internal_Shdr *rel_hdr,
4001 bfd_size_type reloc_count,
4002 arelent *relents, asymbol **symbols,
4003 bfd_boolean dynamic)
4005 void *allocated;
4006 bfd_byte *native_relocs;
4007 unsigned int symcount;
4008 arelent *relent;
4009 bfd_vma i;
4010 int entsize;
4011 bfd_boolean rela_p;
4013 allocated = bfd_malloc (rel_hdr->sh_size);
4014 if (allocated == NULL)
4015 return FALSE;
4017 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
4018 || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
4019 != rel_hdr->sh_size))
4020 goto error_return;
4022 native_relocs = allocated;
4024 entsize = rel_hdr->sh_entsize;
4025 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
4026 || entsize == sizeof (Elf64_Mips_External_Rela));
4028 if (entsize == sizeof (Elf64_Mips_External_Rel))
4029 rela_p = FALSE;
4030 else
4031 rela_p = TRUE;
4033 if (dynamic)
4034 symcount = bfd_get_dynamic_symcount (abfd);
4035 else
4036 symcount = bfd_get_symcount (abfd);
4038 for (i = 0, relent = relents;
4039 i < reloc_count;
4040 i++, native_relocs += entsize)
4042 Elf64_Mips_Internal_Rela rela;
4043 bfd_boolean used_sym, used_ssym;
4044 int ir;
4046 if (entsize == sizeof (Elf64_Mips_External_Rela))
4047 mips_elf64_swap_reloca_in (abfd,
4048 (Elf64_Mips_External_Rela *) native_relocs,
4049 &rela);
4050 else
4051 mips_elf64_swap_reloc_in (abfd,
4052 (Elf64_Mips_External_Rel *) native_relocs,
4053 &rela);
4055 /* Each entry represents exactly three actual relocations. */
4057 used_sym = FALSE;
4058 used_ssym = FALSE;
4059 for (ir = 0; ir < 3; ir++)
4061 enum elf_mips_reloc_type type;
4063 switch (ir)
4065 default:
4066 abort ();
4067 case 0:
4068 type = (enum elf_mips_reloc_type) rela.r_type;
4069 break;
4070 case 1:
4071 type = (enum elf_mips_reloc_type) rela.r_type2;
4072 break;
4073 case 2:
4074 type = (enum elf_mips_reloc_type) rela.r_type3;
4075 break;
4078 /* Some types require symbols, whereas some do not. */
4079 switch (type)
4081 case R_MIPS_NONE:
4082 case R_MIPS_LITERAL:
4083 case R_MIPS_INSERT_A:
4084 case R_MIPS_INSERT_B:
4085 case R_MIPS_DELETE:
4086 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
4087 break;
4089 default:
4090 if (! used_sym)
4092 if (rela.r_sym == STN_UNDEF)
4093 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
4094 else if (rela.r_sym > symcount)
4096 _bfd_error_handler
4097 /* xgettext:c-format */
4098 (_("%pB(%pA): relocation %" PRIu64
4099 " has invalid symbol index %ld"),
4100 abfd, asect, (uint64_t) i, rela.r_sym);
4101 bfd_set_error (bfd_error_bad_value);
4102 relent->sym_ptr_ptr
4103 = bfd_abs_section_ptr->symbol_ptr_ptr;
4105 else
4107 asymbol **ps, *s;
4109 ps = symbols + rela.r_sym - 1;
4110 s = *ps;
4111 if ((s->flags & BSF_SECTION_SYM) == 0)
4112 relent->sym_ptr_ptr = ps;
4113 else
4114 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
4117 used_sym = TRUE;
4119 else if (! used_ssym)
4121 switch (rela.r_ssym)
4123 case RSS_UNDEF:
4124 relent->sym_ptr_ptr =
4125 bfd_abs_section_ptr->symbol_ptr_ptr;
4126 break;
4128 case RSS_GP:
4129 case RSS_GP0:
4130 case RSS_LOC:
4131 /* FIXME: I think these need to be handled using
4132 special howto structures. */
4133 BFD_ASSERT (0);
4134 break;
4136 default:
4137 BFD_ASSERT (0);
4138 break;
4141 used_ssym = TRUE;
4143 else
4144 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
4146 break;
4149 /* The address of an ELF reloc is section relative for an
4150 object file, and absolute for an executable file or
4151 shared library. The address of a BFD reloc is always
4152 section relative. */
4153 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
4154 relent->address = rela.r_offset;
4155 else
4156 relent->address = rela.r_offset - asect->vma;
4158 relent->addend = rela.r_addend;
4160 relent->howto = mips_elf64_rtype_to_howto (abfd, type, rela_p);
4161 if (relent->howto == NULL)
4162 goto error_return;
4164 ++relent;
4168 if (allocated != NULL)
4169 free (allocated);
4171 return TRUE;
4173 error_return:
4174 if (allocated != NULL)
4175 free (allocated);
4176 return FALSE;
4179 /* Read the relocations. On Irix 6, there can be two reloc sections
4180 associated with a single data section. This is copied from
4181 elfcode.h as well, with changes as small as accounting for 3
4182 internal relocs per external reloc. */
4184 static bfd_boolean
4185 mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
4186 asymbol **symbols, bfd_boolean dynamic)
4188 struct bfd_elf_section_data * const d = elf_section_data (asect);
4189 Elf_Internal_Shdr *rel_hdr;
4190 Elf_Internal_Shdr *rel_hdr2;
4191 bfd_size_type reloc_count;
4192 bfd_size_type reloc_count2;
4193 arelent *relents;
4194 bfd_size_type amt;
4196 if (asect->relocation != NULL)
4197 return TRUE;
4199 if (! dynamic)
4201 if ((asect->flags & SEC_RELOC) == 0
4202 || asect->reloc_count == 0)
4203 return TRUE;
4205 rel_hdr = d->rel.hdr;
4206 reloc_count = rel_hdr ? NUM_SHDR_ENTRIES (rel_hdr) : 0;
4207 rel_hdr2 = d->rela.hdr;
4208 reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
4210 BFD_ASSERT (asect->reloc_count == 3 * (reloc_count + reloc_count2));
4211 BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
4212 || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
4215 else
4217 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
4218 case because relocations against this section may use the
4219 dynamic symbol table, and in that case bfd_section_from_shdr
4220 in elf.c does not update the RELOC_COUNT. */
4221 if (asect->size == 0)
4222 return TRUE;
4224 rel_hdr = &d->this_hdr;
4225 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
4226 rel_hdr2 = NULL;
4227 reloc_count2 = 0;
4230 /* Allocate space for 3 arelent structures for each Rel structure. */
4231 amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
4232 relents = bfd_alloc (abfd, amt);
4233 if (relents == NULL)
4234 return FALSE;
4236 if (rel_hdr != NULL
4237 && ! mips_elf64_slurp_one_reloc_table (abfd, asect,
4238 rel_hdr, reloc_count,
4239 relents,
4240 symbols, dynamic))
4241 return FALSE;
4242 if (rel_hdr2 != NULL
4243 && ! mips_elf64_slurp_one_reloc_table (abfd, asect,
4244 rel_hdr2, reloc_count2,
4245 relents + reloc_count * 3,
4246 symbols, dynamic))
4247 return FALSE;
4249 asect->relocation = relents;
4250 return TRUE;
4253 /* Write out the relocations. */
4255 static void
4256 mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
4258 bfd_boolean *failedp = data;
4259 int count;
4260 Elf_Internal_Shdr *rel_hdr;
4261 unsigned int idx;
4263 /* If we have already failed, don't do anything. */
4264 if (*failedp)
4265 return;
4267 if ((sec->flags & SEC_RELOC) == 0)
4268 return;
4270 /* The linker backend writes the relocs out itself, and sets the
4271 reloc_count field to zero to inhibit writing them here. Also,
4272 sometimes the SEC_RELOC flag gets set even when there aren't any
4273 relocs. */
4274 if (sec->reloc_count == 0)
4275 return;
4277 /* We can combine up to three relocs that refer to the same address
4278 if the latter relocs have no associated symbol. */
4279 count = 0;
4280 for (idx = 0; idx < sec->reloc_count; idx++)
4282 bfd_vma addr;
4283 unsigned int i;
4285 ++count;
4287 addr = sec->orelocation[idx]->address;
4288 for (i = 0; i < 2; i++)
4290 arelent *r;
4292 if (idx + 1 >= sec->reloc_count)
4293 break;
4294 r = sec->orelocation[idx + 1];
4295 if (r->address != addr
4296 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
4297 || (*r->sym_ptr_ptr)->value != 0)
4298 break;
4300 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
4302 ++idx;
4306 rel_hdr = _bfd_elf_single_rel_hdr (sec);
4308 /* Do the actual relocation. */
4310 if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
4311 mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
4312 else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
4313 mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
4314 else
4315 BFD_ASSERT (0);
4318 static void
4319 mips_elf64_write_rel (bfd *abfd, asection *sec,
4320 Elf_Internal_Shdr *rel_hdr,
4321 int *count, void *data)
4323 bfd_boolean *failedp = data;
4324 Elf64_Mips_External_Rel *ext_rel;
4325 unsigned int idx;
4326 asymbol *last_sym = 0;
4327 int last_sym_idx = 0;
4329 rel_hdr->sh_size = rel_hdr->sh_entsize * *count;
4330 rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size);
4331 if (rel_hdr->contents == NULL)
4333 *failedp = TRUE;
4334 return;
4337 ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
4338 for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
4340 arelent *ptr;
4341 Elf64_Mips_Internal_Rela int_rel;
4342 asymbol *sym;
4343 int n;
4344 unsigned int i;
4346 ptr = sec->orelocation[idx];
4348 /* The address of an ELF reloc is section relative for an object
4349 file, and absolute for an executable file or shared library.
4350 The address of a BFD reloc is always section relative. */
4351 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
4352 int_rel.r_offset = ptr->address;
4353 else
4354 int_rel.r_offset = ptr->address + sec->vma;
4356 sym = *ptr->sym_ptr_ptr;
4357 if (sym == last_sym)
4358 n = last_sym_idx;
4359 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
4360 n = STN_UNDEF;
4361 else
4363 last_sym = sym;
4364 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
4365 if (n < 0)
4367 *failedp = TRUE;
4368 return;
4370 last_sym_idx = n;
4373 int_rel.r_sym = n;
4374 int_rel.r_ssym = RSS_UNDEF;
4376 if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
4377 && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
4378 && ! _bfd_elf_validate_reloc (abfd, ptr))
4380 *failedp = TRUE;
4381 return;
4384 int_rel.r_type = ptr->howto->type;
4385 int_rel.r_type2 = (int) R_MIPS_NONE;
4386 int_rel.r_type3 = (int) R_MIPS_NONE;
4388 for (i = 0; i < 2; i++)
4390 arelent *r;
4392 if (idx + 1 >= sec->reloc_count)
4393 break;
4394 r = sec->orelocation[idx + 1];
4395 if (r->address != ptr->address
4396 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
4397 || (*r->sym_ptr_ptr)->value != 0)
4398 break;
4400 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
4402 if (i == 0)
4403 int_rel.r_type2 = r->howto->type;
4404 else
4405 int_rel.r_type3 = r->howto->type;
4407 ++idx;
4410 mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
4413 BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
4414 == *count);
4417 static void
4418 mips_elf64_write_rela (bfd *abfd, asection *sec,
4419 Elf_Internal_Shdr *rela_hdr,
4420 int *count, void *data)
4422 bfd_boolean *failedp = data;
4423 Elf64_Mips_External_Rela *ext_rela;
4424 unsigned int idx;
4425 asymbol *last_sym = 0;
4426 int last_sym_idx = 0;
4428 rela_hdr->sh_size = rela_hdr->sh_entsize * *count;
4429 rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
4430 if (rela_hdr->contents == NULL)
4432 *failedp = TRUE;
4433 return;
4436 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
4437 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
4439 arelent *ptr;
4440 Elf64_Mips_Internal_Rela int_rela;
4441 asymbol *sym;
4442 int n;
4443 unsigned int i;
4445 ptr = sec->orelocation[idx];
4447 /* The address of an ELF reloc is section relative for an object
4448 file, and absolute for an executable file or shared library.
4449 The address of a BFD reloc is always section relative. */
4450 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
4451 int_rela.r_offset = ptr->address;
4452 else
4453 int_rela.r_offset = ptr->address + sec->vma;
4455 sym = *ptr->sym_ptr_ptr;
4456 if (sym == last_sym)
4457 n = last_sym_idx;
4458 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
4459 n = STN_UNDEF;
4460 else
4462 last_sym = sym;
4463 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
4464 if (n < 0)
4466 *failedp = TRUE;
4467 return;
4469 last_sym_idx = n;
4472 int_rela.r_sym = n;
4473 int_rela.r_addend = ptr->addend;
4474 int_rela.r_ssym = RSS_UNDEF;
4476 if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
4477 && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
4478 && ! _bfd_elf_validate_reloc (abfd, ptr))
4480 *failedp = TRUE;
4481 return;
4484 int_rela.r_type = ptr->howto->type;
4485 int_rela.r_type2 = (int) R_MIPS_NONE;
4486 int_rela.r_type3 = (int) R_MIPS_NONE;
4488 for (i = 0; i < 2; i++)
4490 arelent *r;
4492 if (idx + 1 >= sec->reloc_count)
4493 break;
4494 r = sec->orelocation[idx + 1];
4495 if (r->address != ptr->address
4496 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
4497 || (*r->sym_ptr_ptr)->value != 0)
4498 break;
4500 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
4502 if (i == 0)
4503 int_rela.r_type2 = r->howto->type;
4504 else
4505 int_rela.r_type3 = r->howto->type;
4507 ++idx;
4510 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
4513 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
4514 == *count);
4517 /* Set the right machine number for a MIPS ELF file. */
4519 static bfd_boolean
4520 mips_elf64_object_p (bfd *abfd)
4522 unsigned long mach;
4524 /* Irix 6 is broken. Object file symbol tables are not always
4525 sorted correctly such that local symbols precede global symbols,
4526 and the sh_info field in the symbol table is not always right. */
4527 if (elf64_mips_irix_compat (abfd) != ict_none)
4528 elf_bad_symtab (abfd) = TRUE;
4530 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
4531 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
4532 return TRUE;
4535 /* Depending on the target vector we generate some version of Irix
4536 executables or "normal" MIPS ELF ABI executables. */
4537 static irix_compat_t
4538 elf64_mips_irix_compat (bfd *abfd)
4540 if ((abfd->xvec == &mips_elf64_be_vec)
4541 || (abfd->xvec == &mips_elf64_le_vec))
4542 return ict_irix6;
4543 else
4544 return ict_none;
4547 /* Support for core dump NOTE sections. */
4548 static bfd_boolean
4549 elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
4551 int offset;
4552 unsigned int size;
4554 switch (note->descsz)
4556 default:
4557 return FALSE;
4559 case 480: /* Linux/MIPS - N64 kernel */
4560 /* pr_cursig */
4561 elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
4563 /* pr_pid */
4564 elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 32);
4566 /* pr_reg */
4567 offset = 112;
4568 size = 360;
4570 break;
4573 /* Make a ".reg/999" section. */
4574 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
4575 size, note->descpos + offset);
4578 static bfd_boolean
4579 elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
4581 switch (note->descsz)
4583 default:
4584 return FALSE;
4586 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
4587 elf_tdata (abfd)->core->pid
4588 = bfd_get_32 (abfd, note->descdata + 24);
4589 elf_tdata (abfd)->core->program
4590 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
4591 elf_tdata (abfd)->core->command
4592 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
4595 /* Note that for some reason, a spurious space is tacked
4596 onto the end of the args in some (at least one anyway)
4597 implementations, so strip it off if it exists. */
4600 char *command = elf_tdata (abfd)->core->command;
4601 int n = strlen (command);
4603 if (0 < n && command[n - 1] == ' ')
4604 command[n - 1] = '\0';
4607 return TRUE;
4610 /* Write Linux core PRSTATUS note into core file. */
4612 static char *
4613 elf64_mips_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
4614 ...)
4616 switch (note_type)
4618 default:
4619 return NULL;
4621 case NT_PRPSINFO:
4622 BFD_FAIL ();
4623 return NULL;
4625 case NT_PRSTATUS:
4627 char data[480];
4628 va_list ap;
4629 long pid;
4630 int cursig;
4631 const void *greg;
4633 va_start (ap, note_type);
4634 memset (data, 0, 112);
4635 pid = va_arg (ap, long);
4636 bfd_put_32 (abfd, pid, data + 32);
4637 cursig = va_arg (ap, int);
4638 bfd_put_16 (abfd, cursig, data + 12);
4639 greg = va_arg (ap, const void *);
4640 memcpy (data + 112, greg, 360);
4641 memset (data + 472, 0, 8);
4642 va_end (ap);
4643 return elfcore_write_note (abfd, buf, bufsiz,
4644 "CORE", note_type, data, sizeof (data));
4649 /* ECOFF swapping routines. These are used when dealing with the
4650 .mdebug section, which is in the ECOFF debugging format. */
4651 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
4653 /* Symbol table magic number. */
4654 magicSym2,
4655 /* Alignment of debugging information. E.g., 4. */
4657 /* Sizes of external symbolic information. */
4658 sizeof (struct hdr_ext),
4659 sizeof (struct dnr_ext),
4660 sizeof (struct pdr_ext),
4661 sizeof (struct sym_ext),
4662 sizeof (struct opt_ext),
4663 sizeof (struct fdr_ext),
4664 sizeof (struct rfd_ext),
4665 sizeof (struct ext_ext),
4666 /* Functions to swap in external symbolic data. */
4667 ecoff_swap_hdr_in,
4668 ecoff_swap_dnr_in,
4669 ecoff_swap_pdr_in,
4670 ecoff_swap_sym_in,
4671 ecoff_swap_opt_in,
4672 ecoff_swap_fdr_in,
4673 ecoff_swap_rfd_in,
4674 ecoff_swap_ext_in,
4675 _bfd_ecoff_swap_tir_in,
4676 _bfd_ecoff_swap_rndx_in,
4677 /* Functions to swap out external symbolic data. */
4678 ecoff_swap_hdr_out,
4679 ecoff_swap_dnr_out,
4680 ecoff_swap_pdr_out,
4681 ecoff_swap_sym_out,
4682 ecoff_swap_opt_out,
4683 ecoff_swap_fdr_out,
4684 ecoff_swap_rfd_out,
4685 ecoff_swap_ext_out,
4686 _bfd_ecoff_swap_tir_out,
4687 _bfd_ecoff_swap_rndx_out,
4688 /* Function to read in symbolic data. */
4689 _bfd_mips_elf_read_ecoff_info
4692 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
4693 standard ELF. This structure is used to redirect the relocation
4694 handling routines. */
4696 const struct elf_size_info mips_elf64_size_info =
4698 sizeof (Elf64_External_Ehdr),
4699 sizeof (Elf64_External_Phdr),
4700 sizeof (Elf64_External_Shdr),
4701 sizeof (Elf64_Mips_External_Rel),
4702 sizeof (Elf64_Mips_External_Rela),
4703 sizeof (Elf64_External_Sym),
4704 sizeof (Elf64_External_Dyn),
4705 sizeof (Elf_External_Note),
4706 4, /* hash-table entry size */
4707 3, /* internal relocations per external relocations */
4708 64, /* arch_size */
4709 3, /* log_file_align */
4710 ELFCLASS64,
4711 EV_CURRENT,
4712 bfd_elf64_write_out_phdrs,
4713 bfd_elf64_write_shdrs_and_ehdr,
4714 bfd_elf64_checksum_contents,
4715 mips_elf64_write_relocs,
4716 bfd_elf64_swap_symbol_in,
4717 bfd_elf64_swap_symbol_out,
4718 mips_elf64_slurp_reloc_table,
4719 bfd_elf64_slurp_symbol_table,
4720 bfd_elf64_swap_dyn_in,
4721 bfd_elf64_swap_dyn_out,
4722 mips_elf64_be_swap_reloc_in,
4723 mips_elf64_be_swap_reloc_out,
4724 mips_elf64_be_swap_reloca_in,
4725 mips_elf64_be_swap_reloca_out
4728 #define ELF_ARCH bfd_arch_mips
4729 #define ELF_TARGET_ID MIPS_ELF_DATA
4730 #define ELF_MACHINE_CODE EM_MIPS
4732 #define elf_backend_collect TRUE
4733 #define elf_backend_type_change_ok TRUE
4734 #define elf_backend_can_gc_sections TRUE
4735 #define elf_backend_gc_mark_extra_sections \
4736 _bfd_mips_elf_gc_mark_extra_sections
4737 #define elf_info_to_howto mips_elf64_info_to_howto_rela
4738 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rela
4739 #define elf_backend_object_p mips_elf64_object_p
4740 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
4741 #define elf_backend_section_processing _bfd_mips_elf_section_processing
4742 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
4743 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
4744 #define elf_backend_section_from_bfd_section \
4745 _bfd_mips_elf_section_from_bfd_section
4746 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
4747 #define elf_backend_link_output_symbol_hook \
4748 _bfd_mips_elf_link_output_symbol_hook
4749 #define elf_backend_create_dynamic_sections \
4750 _bfd_mips_elf_create_dynamic_sections
4751 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
4752 #define elf_backend_merge_symbol_attribute \
4753 _bfd_mips_elf_merge_symbol_attribute
4754 #define elf_backend_get_target_dtag _bfd_mips_elf_get_target_dtag
4755 #define elf_backend_adjust_dynamic_symbol \
4756 _bfd_mips_elf_adjust_dynamic_symbol
4757 #define elf_backend_always_size_sections \
4758 _bfd_mips_elf_always_size_sections
4759 #define elf_backend_size_dynamic_sections \
4760 _bfd_mips_elf_size_dynamic_sections
4761 #define elf_backend_init_index_section _bfd_elf_init_1_index_section
4762 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
4763 #define elf_backend_finish_dynamic_symbol \
4764 _bfd_mips_elf_finish_dynamic_symbol
4765 #define elf_backend_finish_dynamic_sections \
4766 _bfd_mips_elf_finish_dynamic_sections
4767 #define elf_backend_final_write_processing \
4768 _bfd_mips_elf_final_write_processing
4769 #define elf_backend_additional_program_headers \
4770 _bfd_mips_elf_additional_program_headers
4771 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
4772 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
4773 #define elf_backend_copy_indirect_symbol \
4774 _bfd_mips_elf_copy_indirect_symbol
4775 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
4776 #define elf_backend_ignore_discarded_relocs \
4777 _bfd_mips_elf_ignore_discarded_relocs
4778 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
4779 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
4780 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
4781 #define elf_backend_size_info mips_elf64_size_info
4783 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus
4784 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo
4786 #define elf_backend_got_header_size (8 * MIPS_RESERVED_GOTNO)
4787 #define elf_backend_want_dynrelro 1
4789 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
4790 work better/work only in RELA, so we default to this. */
4791 #define elf_backend_may_use_rel_p 1
4792 #define elf_backend_may_use_rela_p 1
4793 #define elf_backend_default_use_rela_p 1
4794 #define elf_backend_rela_plts_and_copies_p 0
4795 #define elf_backend_plt_readonly 1
4796 #define elf_backend_plt_sym_val _bfd_mips_elf_plt_sym_val
4798 #define elf_backend_sign_extend_vma TRUE
4800 #define elf_backend_write_section _bfd_mips_elf_write_section
4801 #define elf_backend_sort_relocs_p _bfd_mips_elf_sort_relocs_p
4803 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
4804 MIPS-specific function only applies to IRIX5, which had no 64-bit
4805 ABI. */
4806 #define bfd_elf64_bfd_is_target_special_symbol \
4807 _bfd_mips_elf_is_target_special_symbol
4808 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
4809 #define bfd_elf64_find_inliner_info _bfd_mips_elf_find_inliner_info
4810 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
4811 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
4812 #define bfd_elf64_bfd_get_relocated_section_contents \
4813 _bfd_elf_mips_get_relocated_section_contents
4814 #define bfd_elf64_bfd_link_hash_table_create \
4815 _bfd_mips_elf_link_hash_table_create
4816 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
4817 #define bfd_elf64_bfd_merge_private_bfd_data \
4818 _bfd_mips_elf_merge_private_bfd_data
4819 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
4820 #define bfd_elf64_bfd_print_private_bfd_data \
4821 _bfd_mips_elf_print_private_bfd_data
4823 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
4824 #define bfd_elf64_mkobject _bfd_mips_elf_mkobject
4826 /* The SGI style (n)64 NewABI. */
4827 #define TARGET_LITTLE_SYM mips_elf64_le_vec
4828 #define TARGET_LITTLE_NAME "elf64-littlemips"
4829 #define TARGET_BIG_SYM mips_elf64_be_vec
4830 #define TARGET_BIG_NAME "elf64-bigmips"
4832 #define ELF_MAXPAGESIZE 0x10000
4833 #define ELF_COMMONPAGESIZE 0x1000
4835 #include "elf64-target.h"
4837 /* The SYSV-style 'traditional' (n)64 NewABI. */
4838 #undef TARGET_LITTLE_SYM
4839 #undef TARGET_LITTLE_NAME
4840 #undef TARGET_BIG_SYM
4841 #undef TARGET_BIG_NAME
4843 #undef ELF_MAXPAGESIZE
4844 #undef ELF_COMMONPAGESIZE
4846 #define TARGET_LITTLE_SYM mips_elf64_trad_le_vec
4847 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
4848 #define TARGET_BIG_SYM mips_elf64_trad_be_vec
4849 #define TARGET_BIG_NAME "elf64-tradbigmips"
4851 #define ELF_MAXPAGESIZE 0x10000
4852 #define ELF_COMMONPAGESIZE 0x1000
4853 #define elf64_bed elf64_tradbed
4855 #undef elf_backend_write_core_note
4856 #define elf_backend_write_core_note elf64_mips_write_core_note
4858 /* Include the target file again for this target. */
4859 #include "elf64-target.h"
4862 /* FreeBSD support. */
4864 #undef TARGET_LITTLE_SYM
4865 #undef TARGET_LITTLE_NAME
4866 #undef TARGET_BIG_SYM
4867 #undef TARGET_BIG_NAME
4869 #define TARGET_LITTLE_SYM mips_elf64_tradfbsd_le_vec
4870 #define TARGET_LITTLE_NAME "elf64-tradlittlemips-freebsd"
4871 #define TARGET_BIG_SYM mips_elf64_tradfbsd_be_vec
4872 #define TARGET_BIG_NAME "elf64-tradbigmips-freebsd"
4874 #undef ELF_OSABI
4875 #define ELF_OSABI ELFOSABI_FREEBSD
4877 #undef elf64_bed
4878 #define elf64_bed elf64_fbsd_tradbed
4880 #undef elf64_mips_write_core_note
4882 #include "elf64-target.h"