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