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