]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - bfd/elf64-mips.c
bfd/
[thirdparty/binutils-gdb.git] / bfd / elf64-mips.c
1 /* MIPS-specific support for 64-bit ELF
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 2007 Free Software Foundation, Inc.
4 Ian Lance Taylor, Cygnus Support
5 Linker support added by Mark Mitchell, CodeSourcery, LLC.
6 <mark@codesourcery.com>
7
8 This file is part of BFD, the Binary File Descriptor library.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23 MA 02110-1301, USA. */
24
25
26 /* This file supports the 64-bit MIPS ELF ABI.
27
28 The MIPS 64-bit ELF ABI uses an unusual reloc format. This file
29 overrides the usual ELF reloc handling, and handles reading and
30 writing the relocations here. */
31
32 /* TODO: Many things are unsupported, even if there is some code for it
33 . (which was mostly stolen from elf32-mips.c and slightly adapted).
34 .
35 . - Relocation handling for REL relocs is wrong in many cases and
36 . generally untested.
37 . - Relocation handling for RELA relocs related to GOT support are
38 . also likely to be wrong.
39 . - Support for MIPS16 is untested.
40 . - Combined relocs with RSS_* entries are unsupported.
41 . - The whole GOT handling for NewABI is missing, some parts of
42 . the OldABI version is still lying around and should be removed.
43 */
44
45 #include "sysdep.h"
46 #include "bfd.h"
47 #include "libbfd.h"
48 #include "aout/ar.h"
49 #include "bfdlink.h"
50 #include "genlink.h"
51 #include "elf-bfd.h"
52 #include "elfxx-mips.h"
53 #include "elf/mips.h"
54
55 /* Get the ECOFF swapping routines. The 64-bit ABI is not supposed to
56 use ECOFF. However, we support it anyhow for an easier changeover. */
57 #include "coff/sym.h"
58 #include "coff/symconst.h"
59 #include "coff/internal.h"
60 #include "coff/ecoff.h"
61 /* The 64 bit versions of the mdebug data structures are in alpha.h. */
62 #include "coff/alpha.h"
63 #define ECOFF_SIGNED_64
64 #include "ecoffswap.h"
65
66 static void mips_elf64_swap_reloc_in
67 (bfd *, const Elf64_Mips_External_Rel *, Elf64_Mips_Internal_Rela *);
68 static void mips_elf64_swap_reloca_in
69 (bfd *, const Elf64_Mips_External_Rela *, Elf64_Mips_Internal_Rela *);
70 static void mips_elf64_swap_reloc_out
71 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rel *);
72 static void mips_elf64_swap_reloca_out
73 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rela *);
74 static void mips_elf64_be_swap_reloc_in
75 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
76 static void mips_elf64_be_swap_reloc_out
77 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
78 static void mips_elf64_be_swap_reloca_in
79 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
80 static void mips_elf64_be_swap_reloca_out
81 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
82 static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup
83 (bfd *, bfd_reloc_code_real_type);
84 static reloc_howto_type *mips_elf64_rtype_to_howto
85 (unsigned int, bfd_boolean);
86 static void mips_elf64_info_to_howto_rel
87 (bfd *, arelent *, Elf_Internal_Rela *);
88 static void mips_elf64_info_to_howto_rela
89 (bfd *, arelent *, Elf_Internal_Rela *);
90 static long mips_elf64_get_reloc_upper_bound
91 (bfd *, asection *);
92 static long mips_elf64_canonicalize_reloc
93 (bfd *, asection *, arelent **, asymbol **);
94 static long mips_elf64_get_dynamic_reloc_upper_bound
95 (bfd *);
96 static long mips_elf64_canonicalize_dynamic_reloc
97 (bfd *, arelent **, asymbol **);
98 static bfd_boolean mips_elf64_slurp_one_reloc_table
99 (bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type, arelent *,
100 asymbol **, bfd_boolean);
101 static bfd_boolean mips_elf64_slurp_reloc_table
102 (bfd *, asection *, asymbol **, bfd_boolean);
103 static void mips_elf64_write_relocs
104 (bfd *, asection *, void *);
105 static void mips_elf64_write_rel
106 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
107 static void mips_elf64_write_rela
108 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
109 static bfd_reloc_status_type mips_elf64_gprel16_reloc
110 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
111 static bfd_reloc_status_type mips_elf64_literal_reloc
112 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
113 static bfd_reloc_status_type mips_elf64_gprel32_reloc
114 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
115 static bfd_reloc_status_type mips_elf64_shift6_reloc
116 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
117 static bfd_reloc_status_type mips16_gprel_reloc
118 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
119 static bfd_boolean mips_elf64_assign_gp
120 (bfd *, bfd_vma *);
121 static bfd_reloc_status_type mips_elf64_final_gp
122 (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
123 static bfd_boolean mips_elf64_object_p
124 (bfd *);
125 static irix_compat_t elf64_mips_irix_compat
126 (bfd *);
127 static bfd_boolean elf64_mips_grok_prstatus
128 (bfd *, Elf_Internal_Note *);
129 static bfd_boolean elf64_mips_grok_psinfo
130 (bfd *, Elf_Internal_Note *);
131
132 extern const bfd_target bfd_elf64_bigmips_vec;
133 extern const bfd_target bfd_elf64_littlemips_vec;
134
135 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
136 from smaller values. Start with zero, widen, *then* decrement. */
137 #define MINUS_ONE (((bfd_vma)0) - 1)
138
139 /* The number of local .got entries we reserve. */
140 #define MIPS_RESERVED_GOTNO (2)
141 \f
142 /* The relocation table used for SHT_REL sections. */
143
144 static reloc_howto_type mips_elf64_howto_table_rel[] =
145 {
146 /* No relocation. */
147 HOWTO (R_MIPS_NONE, /* type */
148 0, /* rightshift */
149 0, /* size (0 = byte, 1 = short, 2 = long) */
150 0, /* bitsize */
151 FALSE, /* pc_relative */
152 0, /* bitpos */
153 complain_overflow_dont, /* complain_on_overflow */
154 _bfd_mips_elf_generic_reloc, /* special_function */
155 "R_MIPS_NONE", /* name */
156 FALSE, /* partial_inplace */
157 0, /* src_mask */
158 0, /* dst_mask */
159 FALSE), /* pcrel_offset */
160
161 /* 16 bit relocation. */
162 HOWTO (R_MIPS_16, /* type */
163 0, /* rightshift */
164 2, /* size (0 = byte, 1 = short, 2 = long) */
165 16, /* bitsize */
166 FALSE, /* pc_relative */
167 0, /* bitpos */
168 complain_overflow_signed, /* complain_on_overflow */
169 _bfd_mips_elf_generic_reloc, /* special_function */
170 "R_MIPS_16", /* name */
171 TRUE, /* partial_inplace */
172 0x0000ffff, /* src_mask */
173 0x0000ffff, /* dst_mask */
174 FALSE), /* pcrel_offset */
175
176 /* 32 bit relocation. */
177 HOWTO (R_MIPS_32, /* type */
178 0, /* rightshift */
179 2, /* size (0 = byte, 1 = short, 2 = long) */
180 32, /* bitsize */
181 FALSE, /* pc_relative */
182 0, /* bitpos */
183 complain_overflow_dont, /* complain_on_overflow */
184 _bfd_mips_elf_generic_reloc, /* special_function */
185 "R_MIPS_32", /* name */
186 TRUE, /* partial_inplace */
187 0xffffffff, /* src_mask */
188 0xffffffff, /* dst_mask */
189 FALSE), /* pcrel_offset */
190
191 /* 32 bit symbol relative relocation. */
192 HOWTO (R_MIPS_REL32, /* type */
193 0, /* rightshift */
194 2, /* size (0 = byte, 1 = short, 2 = long) */
195 32, /* bitsize */
196 FALSE, /* pc_relative */
197 0, /* bitpos */
198 complain_overflow_dont, /* complain_on_overflow */
199 _bfd_mips_elf_generic_reloc, /* special_function */
200 "R_MIPS_REL32", /* name */
201 TRUE, /* partial_inplace */
202 0xffffffff, /* src_mask */
203 0xffffffff, /* dst_mask */
204 FALSE), /* pcrel_offset */
205
206 /* 26 bit jump address. */
207 HOWTO (R_MIPS_26, /* type */
208 2, /* rightshift */
209 2, /* size (0 = byte, 1 = short, 2 = long) */
210 26, /* bitsize */
211 FALSE, /* pc_relative */
212 0, /* bitpos */
213 complain_overflow_dont, /* complain_on_overflow */
214 /* This needs complex overflow
215 detection, because the upper 36
216 bits must match the PC + 4. */
217 _bfd_mips_elf_generic_reloc, /* special_function */
218 "R_MIPS_26", /* name */
219 TRUE, /* partial_inplace */
220 0x03ffffff, /* src_mask */
221 0x03ffffff, /* dst_mask */
222 FALSE), /* pcrel_offset */
223
224 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
225 However, the native IRIX6 tools use them, so we try our best. */
226
227 /* High 16 bits of symbol value. */
228 HOWTO (R_MIPS_HI16, /* type */
229 16, /* rightshift */
230 2, /* size (0 = byte, 1 = short, 2 = long) */
231 16, /* bitsize */
232 FALSE, /* pc_relative */
233 0, /* bitpos */
234 complain_overflow_dont, /* complain_on_overflow */
235 _bfd_mips_elf_hi16_reloc, /* special_function */
236 "R_MIPS_HI16", /* name */
237 TRUE, /* partial_inplace */
238 0x0000ffff, /* src_mask */
239 0x0000ffff, /* dst_mask */
240 FALSE), /* pcrel_offset */
241
242 /* Low 16 bits of symbol value. */
243 HOWTO (R_MIPS_LO16, /* type */
244 0, /* rightshift */
245 2, /* size (0 = byte, 1 = short, 2 = long) */
246 16, /* bitsize */
247 FALSE, /* pc_relative */
248 0, /* bitpos */
249 complain_overflow_dont, /* complain_on_overflow */
250 _bfd_mips_elf_lo16_reloc, /* special_function */
251 "R_MIPS_LO16", /* name */
252 TRUE, /* partial_inplace */
253 0x0000ffff, /* src_mask */
254 0x0000ffff, /* dst_mask */
255 FALSE), /* pcrel_offset */
256
257 /* GP relative reference. */
258 HOWTO (R_MIPS_GPREL16, /* type */
259 0, /* rightshift */
260 2, /* size (0 = byte, 1 = short, 2 = long) */
261 16, /* bitsize */
262 FALSE, /* pc_relative */
263 0, /* bitpos */
264 complain_overflow_signed, /* complain_on_overflow */
265 mips_elf64_gprel16_reloc, /* special_function */
266 "R_MIPS_GPREL16", /* name */
267 TRUE, /* partial_inplace */
268 0x0000ffff, /* src_mask */
269 0x0000ffff, /* dst_mask */
270 FALSE), /* pcrel_offset */
271
272 /* Reference to literal section. */
273 HOWTO (R_MIPS_LITERAL, /* type */
274 0, /* rightshift */
275 2, /* size (0 = byte, 1 = short, 2 = long) */
276 16, /* bitsize */
277 FALSE, /* pc_relative */
278 0, /* bitpos */
279 complain_overflow_signed, /* complain_on_overflow */
280 mips_elf64_literal_reloc, /* special_function */
281 "R_MIPS_LITERAL", /* name */
282 TRUE, /* partial_inplace */
283 0x0000ffff, /* src_mask */
284 0x0000ffff, /* dst_mask */
285 FALSE), /* pcrel_offset */
286
287 /* Reference to global offset table. */
288 HOWTO (R_MIPS_GOT16, /* type */
289 0, /* rightshift */
290 2, /* size (0 = byte, 1 = short, 2 = long) */
291 16, /* bitsize */
292 FALSE, /* pc_relative */
293 0, /* bitpos */
294 complain_overflow_signed, /* complain_on_overflow */
295 _bfd_mips_elf_got16_reloc, /* special_function */
296 "R_MIPS_GOT16", /* name */
297 TRUE, /* partial_inplace */
298 0x0000ffff, /* src_mask */
299 0x0000ffff, /* dst_mask */
300 FALSE), /* pcrel_offset */
301
302 /* 16 bit PC relative reference. Note that the ABI document has a typo
303 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
304 We do the right thing here. */
305 HOWTO (R_MIPS_PC16, /* type */
306 2, /* rightshift */
307 2, /* size (0 = byte, 1 = short, 2 = long) */
308 16, /* bitsize */
309 TRUE, /* pc_relative */
310 0, /* bitpos */
311 complain_overflow_signed, /* complain_on_overflow */
312 _bfd_mips_elf_generic_reloc, /* special_function */
313 "R_MIPS_PC16", /* name */
314 TRUE, /* partial_inplace */
315 0x0000ffff, /* src_mask */
316 0x0000ffff, /* dst_mask */
317 TRUE), /* pcrel_offset */
318
319 /* 16 bit call through global offset table. */
320 HOWTO (R_MIPS_CALL16, /* type */
321 0, /* rightshift */
322 2, /* size (0 = byte, 1 = short, 2 = long) */
323 16, /* bitsize */
324 FALSE, /* pc_relative */
325 0, /* bitpos */
326 complain_overflow_signed, /* complain_on_overflow */
327 _bfd_mips_elf_generic_reloc, /* special_function */
328 "R_MIPS_CALL16", /* name */
329 TRUE, /* partial_inplace */
330 0x0000ffff, /* src_mask */
331 0x0000ffff, /* dst_mask */
332 FALSE), /* pcrel_offset */
333
334 /* 32 bit GP relative reference. */
335 HOWTO (R_MIPS_GPREL32, /* type */
336 0, /* rightshift */
337 2, /* size (0 = byte, 1 = short, 2 = long) */
338 32, /* bitsize */
339 FALSE, /* pc_relative */
340 0, /* bitpos */
341 complain_overflow_dont, /* complain_on_overflow */
342 mips_elf64_gprel32_reloc, /* special_function */
343 "R_MIPS_GPREL32", /* name */
344 TRUE, /* partial_inplace */
345 0xffffffff, /* src_mask */
346 0xffffffff, /* dst_mask */
347 FALSE), /* pcrel_offset */
348
349 EMPTY_HOWTO (13),
350 EMPTY_HOWTO (14),
351 EMPTY_HOWTO (15),
352
353 /* A 5 bit shift field. */
354 HOWTO (R_MIPS_SHIFT5, /* type */
355 0, /* rightshift */
356 2, /* size (0 = byte, 1 = short, 2 = long) */
357 5, /* bitsize */
358 FALSE, /* pc_relative */
359 6, /* bitpos */
360 complain_overflow_bitfield, /* complain_on_overflow */
361 _bfd_mips_elf_generic_reloc, /* special_function */
362 "R_MIPS_SHIFT5", /* name */
363 TRUE, /* partial_inplace */
364 0x000007c0, /* src_mask */
365 0x000007c0, /* dst_mask */
366 FALSE), /* pcrel_offset */
367
368 /* A 6 bit shift field. */
369 HOWTO (R_MIPS_SHIFT6, /* type */
370 0, /* rightshift */
371 2, /* size (0 = byte, 1 = short, 2 = long) */
372 6, /* bitsize */
373 FALSE, /* pc_relative */
374 6, /* bitpos */
375 complain_overflow_bitfield, /* complain_on_overflow */
376 mips_elf64_shift6_reloc, /* special_function */
377 "R_MIPS_SHIFT6", /* name */
378 TRUE, /* partial_inplace */
379 0x000007c4, /* src_mask */
380 0x000007c4, /* dst_mask */
381 FALSE), /* pcrel_offset */
382
383 /* 64 bit relocation. */
384 HOWTO (R_MIPS_64, /* type */
385 0, /* rightshift */
386 4, /* size (0 = byte, 1 = short, 2 = long) */
387 64, /* bitsize */
388 FALSE, /* pc_relative */
389 0, /* bitpos */
390 complain_overflow_dont, /* complain_on_overflow */
391 _bfd_mips_elf_generic_reloc, /* special_function */
392 "R_MIPS_64", /* name */
393 TRUE, /* partial_inplace */
394 MINUS_ONE, /* src_mask */
395 MINUS_ONE, /* dst_mask */
396 FALSE), /* pcrel_offset */
397
398 /* Displacement in the global offset table. */
399 HOWTO (R_MIPS_GOT_DISP, /* type */
400 0, /* rightshift */
401 2, /* size (0 = byte, 1 = short, 2 = long) */
402 16, /* bitsize */
403 FALSE, /* pc_relative */
404 0, /* bitpos */
405 complain_overflow_signed, /* complain_on_overflow */
406 _bfd_mips_elf_generic_reloc, /* special_function */
407 "R_MIPS_GOT_DISP", /* name */
408 TRUE, /* partial_inplace */
409 0x0000ffff, /* src_mask */
410 0x0000ffff, /* dst_mask */
411 FALSE), /* pcrel_offset */
412
413 /* Displacement to page pointer in the global offset table. */
414 HOWTO (R_MIPS_GOT_PAGE, /* type */
415 0, /* rightshift */
416 2, /* size (0 = byte, 1 = short, 2 = long) */
417 16, /* bitsize */
418 FALSE, /* pc_relative */
419 0, /* bitpos */
420 complain_overflow_signed, /* complain_on_overflow */
421 _bfd_mips_elf_generic_reloc, /* special_function */
422 "R_MIPS_GOT_PAGE", /* name */
423 TRUE, /* partial_inplace */
424 0x0000ffff, /* src_mask */
425 0x0000ffff, /* dst_mask */
426 FALSE), /* pcrel_offset */
427
428 /* Offset from page pointer in the global offset table. */
429 HOWTO (R_MIPS_GOT_OFST, /* type */
430 0, /* rightshift */
431 2, /* size (0 = byte, 1 = short, 2 = long) */
432 16, /* bitsize */
433 FALSE, /* pc_relative */
434 0, /* bitpos */
435 complain_overflow_signed, /* complain_on_overflow */
436 _bfd_mips_elf_generic_reloc, /* special_function */
437 "R_MIPS_GOT_OFST", /* name */
438 TRUE, /* partial_inplace */
439 0x0000ffff, /* src_mask */
440 0x0000ffff, /* dst_mask */
441 FALSE), /* pcrel_offset */
442
443 /* High 16 bits of displacement in global offset table. */
444 HOWTO (R_MIPS_GOT_HI16, /* type */
445 0, /* rightshift */
446 2, /* size (0 = byte, 1 = short, 2 = long) */
447 16, /* bitsize */
448 FALSE, /* pc_relative */
449 0, /* bitpos */
450 complain_overflow_dont, /* complain_on_overflow */
451 _bfd_mips_elf_generic_reloc, /* special_function */
452 "R_MIPS_GOT_HI16", /* name */
453 TRUE, /* partial_inplace */
454 0x0000ffff, /* src_mask */
455 0x0000ffff, /* dst_mask */
456 FALSE), /* pcrel_offset */
457
458 /* Low 16 bits of displacement in global offset table. */
459 HOWTO (R_MIPS_GOT_LO16, /* type */
460 0, /* rightshift */
461 2, /* size (0 = byte, 1 = short, 2 = long) */
462 16, /* bitsize */
463 FALSE, /* pc_relative */
464 0, /* bitpos */
465 complain_overflow_dont, /* complain_on_overflow */
466 _bfd_mips_elf_generic_reloc, /* special_function */
467 "R_MIPS_GOT_LO16", /* name */
468 TRUE, /* partial_inplace */
469 0x0000ffff, /* src_mask */
470 0x0000ffff, /* dst_mask */
471 FALSE), /* pcrel_offset */
472
473 /* 64 bit subtraction. */
474 HOWTO (R_MIPS_SUB, /* type */
475 0, /* rightshift */
476 4, /* size (0 = byte, 1 = short, 2 = long) */
477 64, /* bitsize */
478 FALSE, /* pc_relative */
479 0, /* bitpos */
480 complain_overflow_dont, /* complain_on_overflow */
481 _bfd_mips_elf_generic_reloc, /* special_function */
482 "R_MIPS_SUB", /* name */
483 TRUE, /* partial_inplace */
484 MINUS_ONE, /* src_mask */
485 MINUS_ONE, /* dst_mask */
486 FALSE), /* pcrel_offset */
487
488 /* Insert the addend as an instruction. */
489 /* FIXME: Not handled correctly. */
490 HOWTO (R_MIPS_INSERT_A, /* type */
491 0, /* rightshift */
492 2, /* size (0 = byte, 1 = short, 2 = long) */
493 32, /* bitsize */
494 FALSE, /* pc_relative */
495 0, /* bitpos */
496 complain_overflow_dont, /* complain_on_overflow */
497 _bfd_mips_elf_generic_reloc, /* special_function */
498 "R_MIPS_INSERT_A", /* name */
499 TRUE, /* partial_inplace */
500 0xffffffff, /* src_mask */
501 0xffffffff, /* dst_mask */
502 FALSE), /* pcrel_offset */
503
504 /* Insert the addend as an instruction, and change all relocations
505 to refer to the old instruction at the address. */
506 /* FIXME: Not handled correctly. */
507 HOWTO (R_MIPS_INSERT_B, /* type */
508 0, /* rightshift */
509 2, /* size (0 = byte, 1 = short, 2 = long) */
510 32, /* bitsize */
511 FALSE, /* pc_relative */
512 0, /* bitpos */
513 complain_overflow_dont, /* complain_on_overflow */
514 _bfd_mips_elf_generic_reloc, /* special_function */
515 "R_MIPS_INSERT_B", /* name */
516 TRUE, /* partial_inplace */
517 0xffffffff, /* src_mask */
518 0xffffffff, /* dst_mask */
519 FALSE), /* pcrel_offset */
520
521 /* Delete a 32 bit instruction. */
522 /* FIXME: Not handled correctly. */
523 HOWTO (R_MIPS_DELETE, /* type */
524 0, /* rightshift */
525 2, /* size (0 = byte, 1 = short, 2 = long) */
526 32, /* bitsize */
527 FALSE, /* pc_relative */
528 0, /* bitpos */
529 complain_overflow_dont, /* complain_on_overflow */
530 _bfd_mips_elf_generic_reloc, /* special_function */
531 "R_MIPS_DELETE", /* name */
532 TRUE, /* partial_inplace */
533 0xffffffff, /* src_mask */
534 0xffffffff, /* dst_mask */
535 FALSE), /* pcrel_offset */
536
537 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
538 We don't, because
539 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
540 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
541 fallable heuristics.
542 b) No other NewABI toolchain actually emits such relocations. */
543 EMPTY_HOWTO (R_MIPS_HIGHER),
544 EMPTY_HOWTO (R_MIPS_HIGHEST),
545
546 /* High 16 bits of displacement in global offset table. */
547 HOWTO (R_MIPS_CALL_HI16, /* type */
548 0, /* rightshift */
549 2, /* size (0 = byte, 1 = short, 2 = long) */
550 16, /* bitsize */
551 FALSE, /* pc_relative */
552 0, /* bitpos */
553 complain_overflow_dont, /* complain_on_overflow */
554 _bfd_mips_elf_generic_reloc, /* special_function */
555 "R_MIPS_CALL_HI16", /* name */
556 TRUE, /* partial_inplace */
557 0x0000ffff, /* src_mask */
558 0x0000ffff, /* dst_mask */
559 FALSE), /* pcrel_offset */
560
561 /* Low 16 bits of displacement in global offset table. */
562 HOWTO (R_MIPS_CALL_LO16, /* type */
563 0, /* rightshift */
564 2, /* size (0 = byte, 1 = short, 2 = long) */
565 16, /* bitsize */
566 FALSE, /* pc_relative */
567 0, /* bitpos */
568 complain_overflow_dont, /* complain_on_overflow */
569 _bfd_mips_elf_generic_reloc, /* special_function */
570 "R_MIPS_CALL_LO16", /* name */
571 TRUE, /* partial_inplace */
572 0x0000ffff, /* src_mask */
573 0x0000ffff, /* dst_mask */
574 FALSE), /* pcrel_offset */
575
576 /* Section displacement, used by an associated event location section. */
577 HOWTO (R_MIPS_SCN_DISP, /* type */
578 0, /* rightshift */
579 2, /* size (0 = byte, 1 = short, 2 = long) */
580 32, /* bitsize */
581 FALSE, /* pc_relative */
582 0, /* bitpos */
583 complain_overflow_dont, /* complain_on_overflow */
584 _bfd_mips_elf_generic_reloc, /* special_function */
585 "R_MIPS_SCN_DISP", /* name */
586 TRUE, /* partial_inplace */
587 0xffffffff, /* src_mask */
588 0xffffffff, /* dst_mask */
589 FALSE), /* pcrel_offset */
590
591 HOWTO (R_MIPS_REL16, /* type */
592 0, /* rightshift */
593 1, /* size (0 = byte, 1 = short, 2 = long) */
594 16, /* bitsize */
595 FALSE, /* pc_relative */
596 0, /* bitpos */
597 complain_overflow_signed, /* complain_on_overflow */
598 _bfd_mips_elf_generic_reloc, /* special_function */
599 "R_MIPS_REL16", /* name */
600 TRUE, /* partial_inplace */
601 0xffff, /* src_mask */
602 0xffff, /* dst_mask */
603 FALSE), /* pcrel_offset */
604
605 /* These two are obsolete. */
606 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
607 EMPTY_HOWTO (R_MIPS_PJUMP),
608
609 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
610 It must be used for multigot GOT's (and only there). */
611 HOWTO (R_MIPS_RELGOT, /* type */
612 0, /* rightshift */
613 2, /* size (0 = byte, 1 = short, 2 = long) */
614 32, /* bitsize */
615 FALSE, /* pc_relative */
616 0, /* bitpos */
617 complain_overflow_dont, /* complain_on_overflow */
618 _bfd_mips_elf_generic_reloc, /* special_function */
619 "R_MIPS_RELGOT", /* name */
620 TRUE, /* partial_inplace */
621 0xffffffff, /* src_mask */
622 0xffffffff, /* dst_mask */
623 FALSE), /* pcrel_offset */
624
625 /* Protected jump conversion. This is an optimization hint. No
626 relocation is required for correctness. */
627 HOWTO (R_MIPS_JALR, /* type */
628 0, /* rightshift */
629 2, /* size (0 = byte, 1 = short, 2 = long) */
630 32, /* bitsize */
631 FALSE, /* pc_relative */
632 0, /* bitpos */
633 complain_overflow_dont, /* complain_on_overflow */
634 _bfd_mips_elf_generic_reloc, /* special_function */
635 "R_MIPS_JALR", /* name */
636 FALSE, /* partial_inplace */
637 0, /* src_mask */
638 0x00000000, /* dst_mask */
639 FALSE), /* pcrel_offset */
640
641 /* TLS relocations. */
642 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
643 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
644
645 HOWTO (R_MIPS_TLS_DTPMOD64, /* type */
646 0, /* rightshift */
647 4, /* size (0 = byte, 1 = short, 2 = long) */
648 64, /* bitsize */
649 FALSE, /* pc_relative */
650 0, /* bitpos */
651 complain_overflow_dont, /* complain_on_overflow */
652 _bfd_mips_elf_generic_reloc, /* special_function */
653 "R_MIPS_TLS_DTPMOD64", /* name */
654 TRUE, /* partial_inplace */
655 MINUS_ONE, /* src_mask */
656 MINUS_ONE, /* dst_mask */
657 FALSE), /* pcrel_offset */
658
659 HOWTO (R_MIPS_TLS_DTPREL64, /* type */
660 0, /* rightshift */
661 4, /* size (0 = byte, 1 = short, 2 = long) */
662 64, /* bitsize */
663 FALSE, /* pc_relative */
664 0, /* bitpos */
665 complain_overflow_dont, /* complain_on_overflow */
666 _bfd_mips_elf_generic_reloc, /* special_function */
667 "R_MIPS_TLS_DTPREL64", /* name */
668 TRUE, /* partial_inplace */
669 MINUS_ONE, /* src_mask */
670 MINUS_ONE, /* dst_mask */
671 FALSE), /* pcrel_offset */
672
673 /* TLS general dynamic variable reference. */
674 HOWTO (R_MIPS_TLS_GD, /* type */
675 0, /* rightshift */
676 2, /* size (0 = byte, 1 = short, 2 = long) */
677 16, /* bitsize */
678 FALSE, /* pc_relative */
679 0, /* bitpos */
680 complain_overflow_signed, /* complain_on_overflow */
681 _bfd_mips_elf_generic_reloc, /* special_function */
682 "R_MIPS_TLS_GD", /* name */
683 TRUE, /* partial_inplace */
684 0x0000ffff, /* src_mask */
685 0x0000ffff, /* dst_mask */
686 FALSE), /* pcrel_offset */
687
688 /* TLS local dynamic variable reference. */
689 HOWTO (R_MIPS_TLS_LDM, /* type */
690 0, /* rightshift */
691 2, /* size (0 = byte, 1 = short, 2 = long) */
692 16, /* bitsize */
693 FALSE, /* pc_relative */
694 0, /* bitpos */
695 complain_overflow_signed, /* complain_on_overflow */
696 _bfd_mips_elf_generic_reloc, /* special_function */
697 "R_MIPS_TLS_LDM", /* name */
698 TRUE, /* partial_inplace */
699 0x0000ffff, /* src_mask */
700 0x0000ffff, /* dst_mask */
701 FALSE), /* pcrel_offset */
702
703 /* TLS local dynamic offset. */
704 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
705 0, /* rightshift */
706 2, /* size (0 = byte, 1 = short, 2 = long) */
707 16, /* bitsize */
708 FALSE, /* pc_relative */
709 0, /* bitpos */
710 complain_overflow_signed, /* complain_on_overflow */
711 _bfd_mips_elf_generic_reloc, /* special_function */
712 "R_MIPS_TLS_DTPREL_HI16", /* name */
713 TRUE, /* partial_inplace */
714 0x0000ffff, /* src_mask */
715 0x0000ffff, /* dst_mask */
716 FALSE), /* pcrel_offset */
717
718 /* TLS local dynamic offset. */
719 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
720 0, /* rightshift */
721 2, /* size (0 = byte, 1 = short, 2 = long) */
722 16, /* bitsize */
723 FALSE, /* pc_relative */
724 0, /* bitpos */
725 complain_overflow_signed, /* complain_on_overflow */
726 _bfd_mips_elf_generic_reloc, /* special_function */
727 "R_MIPS_TLS_DTPREL_LO16", /* name */
728 TRUE, /* partial_inplace */
729 0x0000ffff, /* src_mask */
730 0x0000ffff, /* dst_mask */
731 FALSE), /* pcrel_offset */
732
733 /* TLS thread pointer offset. */
734 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
735 0, /* rightshift */
736 2, /* size (0 = byte, 1 = short, 2 = long) */
737 16, /* bitsize */
738 FALSE, /* pc_relative */
739 0, /* bitpos */
740 complain_overflow_signed, /* complain_on_overflow */
741 _bfd_mips_elf_generic_reloc, /* special_function */
742 "R_MIPS_TLS_GOTTPREL", /* name */
743 TRUE, /* partial_inplace */
744 0x0000ffff, /* src_mask */
745 0x0000ffff, /* dst_mask */
746 FALSE), /* pcrel_offset */
747
748 /* TLS IE dynamic relocations. */
749 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
750
751 HOWTO (R_MIPS_TLS_TPREL64, /* type */
752 0, /* rightshift */
753 4, /* size (0 = byte, 1 = short, 2 = long) */
754 64, /* bitsize */
755 FALSE, /* pc_relative */
756 0, /* bitpos */
757 complain_overflow_dont, /* complain_on_overflow */
758 _bfd_mips_elf_generic_reloc, /* special_function */
759 "R_MIPS_TLS_TPREL64", /* name */
760 TRUE, /* partial_inplace */
761 MINUS_ONE, /* src_mask */
762 MINUS_ONE, /* dst_mask */
763 FALSE), /* pcrel_offset */
764
765 /* TLS thread pointer offset. */
766 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
767 0, /* rightshift */
768 2, /* size (0 = byte, 1 = short, 2 = long) */
769 16, /* bitsize */
770 FALSE, /* pc_relative */
771 0, /* bitpos */
772 complain_overflow_signed, /* complain_on_overflow */
773 _bfd_mips_elf_generic_reloc, /* special_function */
774 "R_MIPS_TLS_TPREL_HI16", /* name */
775 TRUE, /* partial_inplace */
776 0x0000ffff, /* src_mask */
777 0x0000ffff, /* dst_mask */
778 FALSE), /* pcrel_offset */
779
780 /* TLS thread pointer offset. */
781 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
782 0, /* rightshift */
783 2, /* size (0 = byte, 1 = short, 2 = long) */
784 16, /* bitsize */
785 FALSE, /* pc_relative */
786 0, /* bitpos */
787 complain_overflow_signed, /* complain_on_overflow */
788 _bfd_mips_elf_generic_reloc, /* special_function */
789 "R_MIPS_TLS_TPREL_LO16", /* name */
790 TRUE, /* partial_inplace */
791 0x0000ffff, /* src_mask */
792 0x0000ffff, /* dst_mask */
793 FALSE), /* pcrel_offset */
794
795 /* 32 bit relocation with no addend. */
796 HOWTO (R_MIPS_GLOB_DAT, /* type */
797 0, /* rightshift */
798 2, /* size (0 = byte, 1 = short, 2 = long) */
799 32, /* bitsize */
800 FALSE, /* pc_relative */
801 0, /* bitpos */
802 complain_overflow_dont, /* complain_on_overflow */
803 _bfd_mips_elf_generic_reloc, /* special_function */
804 "R_MIPS_GLOB_DAT", /* name */
805 FALSE, /* partial_inplace */
806 0x0, /* src_mask */
807 0xffffffff, /* dst_mask */
808 FALSE), /* pcrel_offset */
809 };
810
811 /* The relocation table used for SHT_RELA sections. */
812
813 static reloc_howto_type mips_elf64_howto_table_rela[] =
814 {
815 /* No relocation. */
816 HOWTO (R_MIPS_NONE, /* type */
817 0, /* rightshift */
818 0, /* size (0 = byte, 1 = short, 2 = long) */
819 0, /* bitsize */
820 FALSE, /* pc_relative */
821 0, /* bitpos */
822 complain_overflow_dont, /* complain_on_overflow */
823 _bfd_mips_elf_generic_reloc, /* special_function */
824 "R_MIPS_NONE", /* name */
825 FALSE, /* partial_inplace */
826 0, /* src_mask */
827 0, /* dst_mask */
828 FALSE), /* pcrel_offset */
829
830 /* 16 bit relocation. */
831 HOWTO (R_MIPS_16, /* type */
832 0, /* rightshift */
833 2, /* size (0 = byte, 1 = short, 2 = long) */
834 16, /* bitsize */
835 FALSE, /* pc_relative */
836 0, /* bitpos */
837 complain_overflow_signed, /* complain_on_overflow */
838 _bfd_mips_elf_generic_reloc, /* special_function */
839 "R_MIPS_16", /* name */
840 FALSE, /* partial_inplace */
841 0, /* src_mask */
842 0x0000ffff, /* dst_mask */
843 FALSE), /* pcrel_offset */
844
845 /* 32 bit relocation. */
846 HOWTO (R_MIPS_32, /* type */
847 0, /* rightshift */
848 2, /* size (0 = byte, 1 = short, 2 = long) */
849 32, /* bitsize */
850 FALSE, /* pc_relative */
851 0, /* bitpos */
852 complain_overflow_dont, /* complain_on_overflow */
853 _bfd_mips_elf_generic_reloc, /* special_function */
854 "R_MIPS_32", /* name */
855 FALSE, /* partial_inplace */
856 0, /* src_mask */
857 0xffffffff, /* dst_mask */
858 FALSE), /* pcrel_offset */
859
860 /* 32 bit symbol relative relocation. */
861 HOWTO (R_MIPS_REL32, /* type */
862 0, /* rightshift */
863 2, /* size (0 = byte, 1 = short, 2 = long) */
864 32, /* bitsize */
865 FALSE, /* pc_relative */
866 0, /* bitpos */
867 complain_overflow_dont, /* complain_on_overflow */
868 _bfd_mips_elf_generic_reloc, /* special_function */
869 "R_MIPS_REL32", /* name */
870 FALSE, /* partial_inplace */
871 0, /* src_mask */
872 0xffffffff, /* dst_mask */
873 FALSE), /* pcrel_offset */
874
875 /* 26 bit jump address. */
876 HOWTO (R_MIPS_26, /* type */
877 2, /* rightshift */
878 2, /* size (0 = byte, 1 = short, 2 = long) */
879 26, /* bitsize */
880 FALSE, /* pc_relative */
881 0, /* bitpos */
882 complain_overflow_dont, /* complain_on_overflow */
883 /* This needs complex overflow
884 detection, because the upper 36
885 bits must match the PC + 4. */
886 _bfd_mips_elf_generic_reloc, /* special_function */
887 "R_MIPS_26", /* name */
888 FALSE, /* partial_inplace */
889 0, /* src_mask */
890 0x03ffffff, /* dst_mask */
891 FALSE), /* pcrel_offset */
892
893 /* High 16 bits of symbol value. */
894 HOWTO (R_MIPS_HI16, /* type */
895 0, /* rightshift */
896 2, /* size (0 = byte, 1 = short, 2 = long) */
897 16, /* bitsize */
898 FALSE, /* pc_relative */
899 0, /* bitpos */
900 complain_overflow_dont, /* complain_on_overflow */
901 _bfd_mips_elf_generic_reloc, /* special_function */
902 "R_MIPS_HI16", /* name */
903 FALSE, /* partial_inplace */
904 0, /* src_mask */
905 0x0000ffff, /* dst_mask */
906 FALSE), /* pcrel_offset */
907
908 /* Low 16 bits of symbol value. */
909 HOWTO (R_MIPS_LO16, /* type */
910 0, /* rightshift */
911 2, /* size (0 = byte, 1 = short, 2 = long) */
912 16, /* bitsize */
913 FALSE, /* pc_relative */
914 0, /* bitpos */
915 complain_overflow_dont, /* complain_on_overflow */
916 _bfd_mips_elf_generic_reloc, /* special_function */
917 "R_MIPS_LO16", /* name */
918 FALSE, /* partial_inplace */
919 0, /* src_mask */
920 0x0000ffff, /* dst_mask */
921 FALSE), /* pcrel_offset */
922
923 /* GP relative reference. */
924 HOWTO (R_MIPS_GPREL16, /* type */
925 0, /* rightshift */
926 2, /* size (0 = byte, 1 = short, 2 = long) */
927 16, /* bitsize */
928 FALSE, /* pc_relative */
929 0, /* bitpos */
930 complain_overflow_signed, /* complain_on_overflow */
931 mips_elf64_gprel16_reloc, /* special_function */
932 "R_MIPS_GPREL16", /* name */
933 FALSE, /* partial_inplace */
934 0, /* src_mask */
935 0x0000ffff, /* dst_mask */
936 FALSE), /* pcrel_offset */
937
938 /* Reference to literal section. */
939 HOWTO (R_MIPS_LITERAL, /* type */
940 0, /* rightshift */
941 2, /* size (0 = byte, 1 = short, 2 = long) */
942 16, /* bitsize */
943 FALSE, /* pc_relative */
944 0, /* bitpos */
945 complain_overflow_signed, /* complain_on_overflow */
946 mips_elf64_literal_reloc, /* special_function */
947 "R_MIPS_LITERAL", /* name */
948 FALSE, /* partial_inplace */
949 0, /* src_mask */
950 0x0000ffff, /* dst_mask */
951 FALSE), /* pcrel_offset */
952
953 /* Reference to global offset table. */
954 HOWTO (R_MIPS_GOT16, /* type */
955 0, /* rightshift */
956 2, /* size (0 = byte, 1 = short, 2 = long) */
957 16, /* bitsize */
958 FALSE, /* pc_relative */
959 0, /* bitpos */
960 complain_overflow_signed, /* complain_on_overflow */
961 _bfd_mips_elf_generic_reloc, /* special_function */
962 "R_MIPS_GOT16", /* name */
963 FALSE, /* partial_inplace */
964 0, /* src_mask */
965 0x0000ffff, /* dst_mask */
966 FALSE), /* pcrel_offset */
967
968 /* 16 bit PC relative reference. Note that the ABI document has a typo
969 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
970 We do the right thing here. */
971 HOWTO (R_MIPS_PC16, /* type */
972 2, /* rightshift */
973 2, /* size (0 = byte, 1 = short, 2 = long) */
974 16, /* bitsize */
975 TRUE, /* pc_relative */
976 0, /* bitpos */
977 complain_overflow_signed, /* complain_on_overflow */
978 _bfd_mips_elf_generic_reloc, /* special_function */
979 "R_MIPS_PC16", /* name */
980 FALSE, /* partial_inplace */
981 0, /* src_mask */
982 0x0000ffff, /* dst_mask */
983 TRUE), /* pcrel_offset */
984
985 /* 16 bit call through global offset table. */
986 HOWTO (R_MIPS_CALL16, /* type */
987 0, /* rightshift */
988 2, /* size (0 = byte, 1 = short, 2 = long) */
989 16, /* bitsize */
990 FALSE, /* pc_relative */
991 0, /* bitpos */
992 complain_overflow_signed, /* complain_on_overflow */
993 _bfd_mips_elf_generic_reloc, /* special_function */
994 "R_MIPS_CALL16", /* name */
995 FALSE, /* partial_inplace */
996 0, /* src_mask */
997 0x0000ffff, /* dst_mask */
998 FALSE), /* pcrel_offset */
999
1000 /* 32 bit GP relative reference. */
1001 HOWTO (R_MIPS_GPREL32, /* type */
1002 0, /* rightshift */
1003 2, /* size (0 = byte, 1 = short, 2 = long) */
1004 32, /* bitsize */
1005 FALSE, /* pc_relative */
1006 0, /* bitpos */
1007 complain_overflow_dont, /* complain_on_overflow */
1008 mips_elf64_gprel32_reloc, /* special_function */
1009 "R_MIPS_GPREL32", /* name */
1010 FALSE, /* partial_inplace */
1011 0, /* src_mask */
1012 0xffffffff, /* dst_mask */
1013 FALSE), /* pcrel_offset */
1014
1015 EMPTY_HOWTO (13),
1016 EMPTY_HOWTO (14),
1017 EMPTY_HOWTO (15),
1018
1019 /* A 5 bit shift field. */
1020 HOWTO (R_MIPS_SHIFT5, /* type */
1021 0, /* rightshift */
1022 2, /* size (0 = byte, 1 = short, 2 = long) */
1023 5, /* bitsize */
1024 FALSE, /* pc_relative */
1025 6, /* bitpos */
1026 complain_overflow_bitfield, /* complain_on_overflow */
1027 _bfd_mips_elf_generic_reloc, /* special_function */
1028 "R_MIPS_SHIFT5", /* name */
1029 FALSE, /* partial_inplace */
1030 0, /* src_mask */
1031 0x000007c0, /* dst_mask */
1032 FALSE), /* pcrel_offset */
1033
1034 /* A 6 bit shift field. */
1035 HOWTO (R_MIPS_SHIFT6, /* type */
1036 0, /* rightshift */
1037 2, /* size (0 = byte, 1 = short, 2 = long) */
1038 6, /* bitsize */
1039 FALSE, /* pc_relative */
1040 6, /* bitpos */
1041 complain_overflow_bitfield, /* complain_on_overflow */
1042 mips_elf64_shift6_reloc, /* special_function */
1043 "R_MIPS_SHIFT6", /* name */
1044 FALSE, /* partial_inplace */
1045 0, /* src_mask */
1046 0x000007c4, /* dst_mask */
1047 FALSE), /* pcrel_offset */
1048
1049 /* 64 bit relocation. */
1050 HOWTO (R_MIPS_64, /* type */
1051 0, /* rightshift */
1052 4, /* size (0 = byte, 1 = short, 2 = long) */
1053 64, /* bitsize */
1054 FALSE, /* pc_relative */
1055 0, /* bitpos */
1056 complain_overflow_dont, /* complain_on_overflow */
1057 _bfd_mips_elf_generic_reloc, /* special_function */
1058 "R_MIPS_64", /* name */
1059 FALSE, /* partial_inplace */
1060 0, /* src_mask */
1061 MINUS_ONE, /* dst_mask */
1062 FALSE), /* pcrel_offset */
1063
1064 /* Displacement in the global offset table. */
1065 HOWTO (R_MIPS_GOT_DISP, /* type */
1066 0, /* rightshift */
1067 2, /* size (0 = byte, 1 = short, 2 = long) */
1068 16, /* bitsize */
1069 FALSE, /* pc_relative */
1070 0, /* bitpos */
1071 complain_overflow_signed, /* complain_on_overflow */
1072 _bfd_mips_elf_generic_reloc, /* special_function */
1073 "R_MIPS_GOT_DISP", /* name */
1074 FALSE, /* partial_inplace */
1075 0, /* src_mask */
1076 0x0000ffff, /* dst_mask */
1077 FALSE), /* pcrel_offset */
1078
1079 /* Displacement to page pointer in the global offset table. */
1080 HOWTO (R_MIPS_GOT_PAGE, /* type */
1081 0, /* rightshift */
1082 2, /* size (0 = byte, 1 = short, 2 = long) */
1083 16, /* bitsize */
1084 FALSE, /* pc_relative */
1085 0, /* bitpos */
1086 complain_overflow_signed, /* complain_on_overflow */
1087 _bfd_mips_elf_generic_reloc, /* special_function */
1088 "R_MIPS_GOT_PAGE", /* name */
1089 FALSE, /* partial_inplace */
1090 0, /* src_mask */
1091 0x0000ffff, /* dst_mask */
1092 FALSE), /* pcrel_offset */
1093
1094 /* Offset from page pointer in the global offset table. */
1095 HOWTO (R_MIPS_GOT_OFST, /* type */
1096 0, /* rightshift */
1097 2, /* size (0 = byte, 1 = short, 2 = long) */
1098 16, /* bitsize */
1099 FALSE, /* pc_relative */
1100 0, /* bitpos */
1101 complain_overflow_signed, /* complain_on_overflow */
1102 _bfd_mips_elf_generic_reloc, /* special_function */
1103 "R_MIPS_GOT_OFST", /* name */
1104 FALSE, /* partial_inplace */
1105 0, /* src_mask */
1106 0x0000ffff, /* dst_mask */
1107 FALSE), /* pcrel_offset */
1108
1109 /* High 16 bits of displacement in global offset table. */
1110 HOWTO (R_MIPS_GOT_HI16, /* type */
1111 0, /* rightshift */
1112 2, /* size (0 = byte, 1 = short, 2 = long) */
1113 16, /* bitsize */
1114 FALSE, /* pc_relative */
1115 0, /* bitpos */
1116 complain_overflow_dont, /* complain_on_overflow */
1117 _bfd_mips_elf_generic_reloc, /* special_function */
1118 "R_MIPS_GOT_HI16", /* name */
1119 FALSE, /* partial_inplace */
1120 0, /* src_mask */
1121 0x0000ffff, /* dst_mask */
1122 FALSE), /* pcrel_offset */
1123
1124 /* Low 16 bits of displacement in global offset table. */
1125 HOWTO (R_MIPS_GOT_LO16, /* type */
1126 0, /* rightshift */
1127 2, /* size (0 = byte, 1 = short, 2 = long) */
1128 16, /* bitsize */
1129 FALSE, /* pc_relative */
1130 0, /* bitpos */
1131 complain_overflow_dont, /* complain_on_overflow */
1132 _bfd_mips_elf_generic_reloc, /* special_function */
1133 "R_MIPS_GOT_LO16", /* name */
1134 FALSE, /* partial_inplace */
1135 0, /* src_mask */
1136 0x0000ffff, /* dst_mask */
1137 FALSE), /* pcrel_offset */
1138
1139 /* 64 bit subtraction. */
1140 HOWTO (R_MIPS_SUB, /* type */
1141 0, /* rightshift */
1142 4, /* size (0 = byte, 1 = short, 2 = long) */
1143 64, /* bitsize */
1144 FALSE, /* pc_relative */
1145 0, /* bitpos */
1146 complain_overflow_dont, /* complain_on_overflow */
1147 _bfd_mips_elf_generic_reloc, /* special_function */
1148 "R_MIPS_SUB", /* name */
1149 FALSE, /* partial_inplace */
1150 0, /* src_mask */
1151 MINUS_ONE, /* dst_mask */
1152 FALSE), /* pcrel_offset */
1153
1154 /* Insert the addend as an instruction. */
1155 /* FIXME: Not handled correctly. */
1156 HOWTO (R_MIPS_INSERT_A, /* type */
1157 0, /* rightshift */
1158 2, /* size (0 = byte, 1 = short, 2 = long) */
1159 32, /* bitsize */
1160 FALSE, /* pc_relative */
1161 0, /* bitpos */
1162 complain_overflow_dont, /* complain_on_overflow */
1163 _bfd_mips_elf_generic_reloc, /* special_function */
1164 "R_MIPS_INSERT_A", /* name */
1165 FALSE, /* partial_inplace */
1166 0, /* src_mask */
1167 0xffffffff, /* dst_mask */
1168 FALSE), /* pcrel_offset */
1169
1170 /* Insert the addend as an instruction, and change all relocations
1171 to refer to the old instruction at the address. */
1172 /* FIXME: Not handled correctly. */
1173 HOWTO (R_MIPS_INSERT_B, /* type */
1174 0, /* rightshift */
1175 2, /* size (0 = byte, 1 = short, 2 = long) */
1176 32, /* bitsize */
1177 FALSE, /* pc_relative */
1178 0, /* bitpos */
1179 complain_overflow_dont, /* complain_on_overflow */
1180 _bfd_mips_elf_generic_reloc, /* special_function */
1181 "R_MIPS_INSERT_B", /* name */
1182 FALSE, /* partial_inplace */
1183 0, /* src_mask */
1184 0xffffffff, /* dst_mask */
1185 FALSE), /* pcrel_offset */
1186
1187 /* Delete a 32 bit instruction. */
1188 /* FIXME: Not handled correctly. */
1189 HOWTO (R_MIPS_DELETE, /* type */
1190 0, /* rightshift */
1191 2, /* size (0 = byte, 1 = short, 2 = long) */
1192 32, /* bitsize */
1193 FALSE, /* pc_relative */
1194 0, /* bitpos */
1195 complain_overflow_dont, /* complain_on_overflow */
1196 _bfd_mips_elf_generic_reloc, /* special_function */
1197 "R_MIPS_DELETE", /* name */
1198 FALSE, /* partial_inplace */
1199 0, /* src_mask */
1200 0xffffffff, /* dst_mask */
1201 FALSE), /* pcrel_offset */
1202
1203 /* Get the higher value of a 64 bit addend. */
1204 HOWTO (R_MIPS_HIGHER, /* type */
1205 0, /* rightshift */
1206 2, /* size (0 = byte, 1 = short, 2 = long) */
1207 16, /* bitsize */
1208 FALSE, /* pc_relative */
1209 0, /* bitpos */
1210 complain_overflow_dont, /* complain_on_overflow */
1211 _bfd_mips_elf_generic_reloc, /* special_function */
1212 "R_MIPS_HIGHER", /* name */
1213 FALSE, /* partial_inplace */
1214 0, /* src_mask */
1215 0x0000ffff, /* dst_mask */
1216 FALSE), /* pcrel_offset */
1217
1218 /* Get the highest value of a 64 bit addend. */
1219 HOWTO (R_MIPS_HIGHEST, /* type */
1220 0, /* rightshift */
1221 2, /* size (0 = byte, 1 = short, 2 = long) */
1222 16, /* bitsize */
1223 FALSE, /* pc_relative */
1224 0, /* bitpos */
1225 complain_overflow_dont, /* complain_on_overflow */
1226 _bfd_mips_elf_generic_reloc, /* special_function */
1227 "R_MIPS_HIGHEST", /* name */
1228 FALSE, /* partial_inplace */
1229 0, /* src_mask */
1230 0x0000ffff, /* dst_mask */
1231 FALSE), /* pcrel_offset */
1232
1233 /* High 16 bits of displacement in global offset table. */
1234 HOWTO (R_MIPS_CALL_HI16, /* type */
1235 0, /* rightshift */
1236 2, /* size (0 = byte, 1 = short, 2 = long) */
1237 16, /* bitsize */
1238 FALSE, /* pc_relative */
1239 0, /* bitpos */
1240 complain_overflow_dont, /* complain_on_overflow */
1241 _bfd_mips_elf_generic_reloc, /* special_function */
1242 "R_MIPS_CALL_HI16", /* name */
1243 FALSE, /* partial_inplace */
1244 0, /* src_mask */
1245 0x0000ffff, /* dst_mask */
1246 FALSE), /* pcrel_offset */
1247
1248 /* Low 16 bits of displacement in global offset table. */
1249 HOWTO (R_MIPS_CALL_LO16, /* type */
1250 0, /* rightshift */
1251 2, /* size (0 = byte, 1 = short, 2 = long) */
1252 16, /* bitsize */
1253 FALSE, /* pc_relative */
1254 0, /* bitpos */
1255 complain_overflow_dont, /* complain_on_overflow */
1256 _bfd_mips_elf_generic_reloc, /* special_function */
1257 "R_MIPS_CALL_LO16", /* name */
1258 FALSE, /* partial_inplace */
1259 0, /* src_mask */
1260 0x0000ffff, /* dst_mask */
1261 FALSE), /* pcrel_offset */
1262
1263 /* Section displacement, used by an associated event location section. */
1264 HOWTO (R_MIPS_SCN_DISP, /* type */
1265 0, /* rightshift */
1266 2, /* size (0 = byte, 1 = short, 2 = long) */
1267 32, /* bitsize */
1268 FALSE, /* pc_relative */
1269 0, /* bitpos */
1270 complain_overflow_dont, /* complain_on_overflow */
1271 _bfd_mips_elf_generic_reloc, /* special_function */
1272 "R_MIPS_SCN_DISP", /* name */
1273 FALSE, /* partial_inplace */
1274 0, /* src_mask */
1275 0xffffffff, /* dst_mask */
1276 FALSE), /* pcrel_offset */
1277
1278 HOWTO (R_MIPS_REL16, /* type */
1279 0, /* rightshift */
1280 1, /* size (0 = byte, 1 = short, 2 = long) */
1281 16, /* bitsize */
1282 FALSE, /* pc_relative */
1283 0, /* bitpos */
1284 complain_overflow_signed, /* complain_on_overflow */
1285 _bfd_mips_elf_generic_reloc, /* special_function */
1286 "R_MIPS_REL16", /* name */
1287 FALSE, /* partial_inplace */
1288 0, /* src_mask */
1289 0xffff, /* dst_mask */
1290 FALSE), /* pcrel_offset */
1291
1292 /* These two are obsolete. */
1293 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1294 EMPTY_HOWTO (R_MIPS_PJUMP),
1295
1296 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1297 It must be used for multigot GOT's (and only there). */
1298 HOWTO (R_MIPS_RELGOT, /* type */
1299 0, /* rightshift */
1300 2, /* size (0 = byte, 1 = short, 2 = long) */
1301 32, /* bitsize */
1302 FALSE, /* pc_relative */
1303 0, /* bitpos */
1304 complain_overflow_dont, /* complain_on_overflow */
1305 _bfd_mips_elf_generic_reloc, /* special_function */
1306 "R_MIPS_RELGOT", /* name */
1307 FALSE, /* partial_inplace */
1308 0, /* src_mask */
1309 0xffffffff, /* dst_mask */
1310 FALSE), /* pcrel_offset */
1311
1312 /* Protected jump conversion. This is an optimization hint. No
1313 relocation is required for correctness. */
1314 HOWTO (R_MIPS_JALR, /* type */
1315 0, /* rightshift */
1316 2, /* size (0 = byte, 1 = short, 2 = long) */
1317 32, /* bitsize */
1318 FALSE, /* pc_relative */
1319 0, /* bitpos */
1320 complain_overflow_dont, /* complain_on_overflow */
1321 _bfd_mips_elf_generic_reloc, /* special_function */
1322 "R_MIPS_JALR", /* name */
1323 FALSE, /* partial_inplace */
1324 0, /* src_mask */
1325 0x00000000, /* dst_mask */
1326 FALSE), /* pcrel_offset */
1327
1328 /* TLS relocations. */
1329 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
1330 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
1331 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
1332
1333 HOWTO (R_MIPS_TLS_DTPREL64, /* type */
1334 0, /* rightshift */
1335 4, /* size (0 = byte, 1 = short, 2 = long) */
1336 64, /* bitsize */
1337 FALSE, /* pc_relative */
1338 0, /* bitpos */
1339 complain_overflow_dont, /* complain_on_overflow */
1340 _bfd_mips_elf_generic_reloc, /* special_function */
1341 "R_MIPS_TLS_DTPREL64", /* name */
1342 TRUE, /* partial_inplace */
1343 MINUS_ONE, /* src_mask */
1344 MINUS_ONE, /* dst_mask */
1345 FALSE), /* pcrel_offset */
1346
1347 /* TLS general dynamic variable reference. */
1348 HOWTO (R_MIPS_TLS_GD, /* type */
1349 0, /* rightshift */
1350 2, /* size (0 = byte, 1 = short, 2 = long) */
1351 16, /* bitsize */
1352 FALSE, /* pc_relative */
1353 0, /* bitpos */
1354 complain_overflow_signed, /* complain_on_overflow */
1355 _bfd_mips_elf_generic_reloc, /* special_function */
1356 "R_MIPS_TLS_GD", /* name */
1357 TRUE, /* partial_inplace */
1358 0x0000ffff, /* src_mask */
1359 0x0000ffff, /* dst_mask */
1360 FALSE), /* pcrel_offset */
1361
1362 /* TLS local dynamic variable reference. */
1363 HOWTO (R_MIPS_TLS_LDM, /* type */
1364 0, /* rightshift */
1365 2, /* size (0 = byte, 1 = short, 2 = long) */
1366 16, /* bitsize */
1367 FALSE, /* pc_relative */
1368 0, /* bitpos */
1369 complain_overflow_signed, /* complain_on_overflow */
1370 _bfd_mips_elf_generic_reloc, /* special_function */
1371 "R_MIPS_TLS_LDM", /* name */
1372 TRUE, /* partial_inplace */
1373 0x0000ffff, /* src_mask */
1374 0x0000ffff, /* dst_mask */
1375 FALSE), /* pcrel_offset */
1376
1377 /* TLS local dynamic offset. */
1378 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
1379 0, /* rightshift */
1380 2, /* size (0 = byte, 1 = short, 2 = long) */
1381 16, /* bitsize */
1382 FALSE, /* pc_relative */
1383 0, /* bitpos */
1384 complain_overflow_signed, /* complain_on_overflow */
1385 _bfd_mips_elf_generic_reloc, /* special_function */
1386 "R_MIPS_TLS_DTPREL_HI16", /* name */
1387 TRUE, /* partial_inplace */
1388 0x0000ffff, /* src_mask */
1389 0x0000ffff, /* dst_mask */
1390 FALSE), /* pcrel_offset */
1391
1392 /* TLS local dynamic offset. */
1393 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
1394 0, /* rightshift */
1395 2, /* size (0 = byte, 1 = short, 2 = long) */
1396 16, /* bitsize */
1397 FALSE, /* pc_relative */
1398 0, /* bitpos */
1399 complain_overflow_signed, /* complain_on_overflow */
1400 _bfd_mips_elf_generic_reloc, /* special_function */
1401 "R_MIPS_TLS_DTPREL_LO16", /* name */
1402 TRUE, /* partial_inplace */
1403 0x0000ffff, /* src_mask */
1404 0x0000ffff, /* dst_mask */
1405 FALSE), /* pcrel_offset */
1406
1407 /* TLS thread pointer offset. */
1408 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
1409 0, /* rightshift */
1410 2, /* size (0 = byte, 1 = short, 2 = long) */
1411 16, /* bitsize */
1412 FALSE, /* pc_relative */
1413 0, /* bitpos */
1414 complain_overflow_signed, /* complain_on_overflow */
1415 _bfd_mips_elf_generic_reloc, /* special_function */
1416 "R_MIPS_TLS_GOTTPREL", /* name */
1417 TRUE, /* partial_inplace */
1418 0x0000ffff, /* src_mask */
1419 0x0000ffff, /* dst_mask */
1420 FALSE), /* pcrel_offset */
1421
1422 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
1423 EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
1424
1425 /* TLS thread pointer offset. */
1426 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
1427 0, /* rightshift */
1428 2, /* size (0 = byte, 1 = short, 2 = long) */
1429 16, /* bitsize */
1430 FALSE, /* pc_relative */
1431 0, /* bitpos */
1432 complain_overflow_signed, /* complain_on_overflow */
1433 _bfd_mips_elf_generic_reloc, /* special_function */
1434 "R_MIPS_TLS_TPREL_HI16", /* name */
1435 TRUE, /* partial_inplace */
1436 0x0000ffff, /* src_mask */
1437 0x0000ffff, /* dst_mask */
1438 FALSE), /* pcrel_offset */
1439
1440 /* TLS thread pointer offset. */
1441 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
1442 0, /* rightshift */
1443 2, /* size (0 = byte, 1 = short, 2 = long) */
1444 16, /* bitsize */
1445 FALSE, /* pc_relative */
1446 0, /* bitpos */
1447 complain_overflow_signed, /* complain_on_overflow */
1448 _bfd_mips_elf_generic_reloc, /* special_function */
1449 "R_MIPS_TLS_TPREL_LO16", /* name */
1450 TRUE, /* partial_inplace */
1451 0x0000ffff, /* src_mask */
1452 0x0000ffff, /* dst_mask */
1453 FALSE), /* pcrel_offset */
1454
1455 /* 32 bit relocation with no addend. */
1456 HOWTO (R_MIPS_GLOB_DAT, /* type */
1457 0, /* rightshift */
1458 2, /* size (0 = byte, 1 = short, 2 = long) */
1459 32, /* bitsize */
1460 FALSE, /* pc_relative */
1461 0, /* bitpos */
1462 complain_overflow_dont, /* complain_on_overflow */
1463 _bfd_mips_elf_generic_reloc, /* special_function */
1464 "R_MIPS_GLOB_DAT", /* name */
1465 FALSE, /* partial_inplace */
1466 0x0, /* src_mask */
1467 0xffffffff, /* dst_mask */
1468 FALSE), /* pcrel_offset */
1469 };
1470
1471 static reloc_howto_type mips16_elf64_howto_table_rel[] =
1472 {
1473 /* The reloc used for the mips16 jump instruction. */
1474 HOWTO (R_MIPS16_26, /* type */
1475 2, /* rightshift */
1476 2, /* size (0 = byte, 1 = short, 2 = long) */
1477 26, /* bitsize */
1478 FALSE, /* pc_relative */
1479 0, /* bitpos */
1480 complain_overflow_dont, /* complain_on_overflow */
1481 /* This needs complex overflow
1482 detection, because the upper four
1483 bits must match the PC. */
1484 _bfd_mips_elf_generic_reloc, /* special_function */
1485 "R_MIPS16_26", /* name */
1486 TRUE, /* partial_inplace */
1487 0x3ffffff, /* src_mask */
1488 0x3ffffff, /* dst_mask */
1489 FALSE), /* pcrel_offset */
1490
1491 /* The reloc used for the mips16 gprel instruction. */
1492 HOWTO (R_MIPS16_GPREL, /* type */
1493 0, /* rightshift */
1494 2, /* size (0 = byte, 1 = short, 2 = long) */
1495 16, /* bitsize */
1496 FALSE, /* pc_relative */
1497 0, /* bitpos */
1498 complain_overflow_signed, /* complain_on_overflow */
1499 mips16_gprel_reloc, /* special_function */
1500 "R_MIPS16_GPREL", /* name */
1501 TRUE, /* partial_inplace */
1502 0x0000ffff, /* src_mask */
1503 0x0000ffff, /* dst_mask */
1504 FALSE), /* pcrel_offset */
1505
1506 /* A MIPS16 reference to the global offset table. */
1507 HOWTO (R_MIPS16_GOT16, /* type */
1508 0, /* rightshift */
1509 2, /* size (0 = byte, 1 = short, 2 = long) */
1510 16, /* bitsize */
1511 FALSE, /* pc_relative */
1512 0, /* bitpos */
1513 complain_overflow_dont, /* complain_on_overflow */
1514 _bfd_mips_elf_got16_reloc, /* special_function */
1515 "R_MIPS16_GOT16", /* name */
1516 TRUE, /* partial_inplace */
1517 0x0000ffff, /* src_mask */
1518 0x0000ffff, /* dst_mask */
1519 FALSE), /* pcrel_offset */
1520
1521 /* A MIPS16 call through the global offset table. */
1522 HOWTO (R_MIPS16_CALL16, /* type */
1523 0, /* rightshift */
1524 2, /* size (0 = byte, 1 = short, 2 = long) */
1525 16, /* bitsize */
1526 FALSE, /* pc_relative */
1527 0, /* bitpos */
1528 complain_overflow_dont, /* complain_on_overflow */
1529 _bfd_mips_elf_generic_reloc, /* special_function */
1530 "R_MIPS16_CALL16", /* name */
1531 TRUE, /* partial_inplace */
1532 0x0000ffff, /* src_mask */
1533 0x0000ffff, /* dst_mask */
1534 FALSE), /* pcrel_offset */
1535
1536 /* MIPS16 high 16 bits of symbol value. */
1537 HOWTO (R_MIPS16_HI16, /* type */
1538 16, /* rightshift */
1539 2, /* size (0 = byte, 1 = short, 2 = long) */
1540 16, /* bitsize */
1541 FALSE, /* pc_relative */
1542 0, /* bitpos */
1543 complain_overflow_dont, /* complain_on_overflow */
1544 _bfd_mips_elf_hi16_reloc, /* special_function */
1545 "R_MIPS16_HI16", /* name */
1546 TRUE, /* partial_inplace */
1547 0x0000ffff, /* src_mask */
1548 0x0000ffff, /* dst_mask */
1549 FALSE), /* pcrel_offset */
1550
1551 /* MIPS16 low 16 bits of symbol value. */
1552 HOWTO (R_MIPS16_LO16, /* type */
1553 0, /* rightshift */
1554 2, /* size (0 = byte, 1 = short, 2 = long) */
1555 16, /* bitsize */
1556 FALSE, /* pc_relative */
1557 0, /* bitpos */
1558 complain_overflow_dont, /* complain_on_overflow */
1559 _bfd_mips_elf_lo16_reloc, /* special_function */
1560 "R_MIPS16_LO16", /* name */
1561 TRUE, /* partial_inplace */
1562 0x0000ffff, /* src_mask */
1563 0x0000ffff, /* dst_mask */
1564 FALSE), /* pcrel_offset */
1565 };
1566
1567 static reloc_howto_type mips16_elf64_howto_table_rela[] =
1568 {
1569 /* The reloc used for the mips16 jump instruction. */
1570 HOWTO (R_MIPS16_26, /* type */
1571 2, /* rightshift */
1572 2, /* size (0 = byte, 1 = short, 2 = long) */
1573 26, /* bitsize */
1574 FALSE, /* pc_relative */
1575 0, /* bitpos */
1576 complain_overflow_dont, /* complain_on_overflow */
1577 /* This needs complex overflow
1578 detection, because the upper four
1579 bits must match the PC. */
1580 _bfd_mips_elf_generic_reloc, /* special_function */
1581 "R_MIPS16_26", /* name */
1582 FALSE, /* partial_inplace */
1583 0x3ffffff, /* src_mask */
1584 0x3ffffff, /* dst_mask */
1585 FALSE), /* pcrel_offset */
1586
1587 /* The reloc used for the mips16 gprel instruction. */
1588 HOWTO (R_MIPS16_GPREL, /* type */
1589 0, /* rightshift */
1590 2, /* size (0 = byte, 1 = short, 2 = long) */
1591 16, /* bitsize */
1592 FALSE, /* pc_relative */
1593 0, /* bitpos */
1594 complain_overflow_signed, /* complain_on_overflow */
1595 mips16_gprel_reloc, /* special_function */
1596 "R_MIPS16_GPREL", /* name */
1597 FALSE, /* partial_inplace */
1598 0x0000ffff, /* src_mask */
1599 0x0000ffff, /* dst_mask */
1600 FALSE), /* pcrel_offset */
1601
1602 /* A MIPS16 reference to the global offset table. */
1603 HOWTO (R_MIPS16_GOT16, /* type */
1604 0, /* rightshift */
1605 2, /* size (0 = byte, 1 = short, 2 = long) */
1606 16, /* bitsize */
1607 FALSE, /* pc_relative */
1608 0, /* bitpos */
1609 complain_overflow_dont, /* complain_on_overflow */
1610 _bfd_mips_elf_got16_reloc, /* special_function */
1611 "R_MIPS16_GOT16", /* name */
1612 FALSE, /* partial_inplace */
1613 0x0000ffff, /* src_mask */
1614 0x0000ffff, /* dst_mask */
1615 FALSE), /* pcrel_offset */
1616
1617 /* A MIPS16 call through the global offset table. */
1618 HOWTO (R_MIPS16_CALL16, /* type */
1619 0, /* rightshift */
1620 2, /* size (0 = byte, 1 = short, 2 = long) */
1621 16, /* bitsize */
1622 FALSE, /* pc_relative */
1623 0, /* bitpos */
1624 complain_overflow_dont, /* complain_on_overflow */
1625 _bfd_mips_elf_generic_reloc, /* special_function */
1626 "R_MIPS16_CALL16", /* name */
1627 FALSE, /* partial_inplace */
1628 0x0000ffff, /* src_mask */
1629 0x0000ffff, /* dst_mask */
1630 FALSE), /* pcrel_offset */
1631
1632 /* MIPS16 high 16 bits of symbol value. */
1633 HOWTO (R_MIPS16_HI16, /* type */
1634 16, /* rightshift */
1635 2, /* size (0 = byte, 1 = short, 2 = long) */
1636 16, /* bitsize */
1637 FALSE, /* pc_relative */
1638 0, /* bitpos */
1639 complain_overflow_dont, /* complain_on_overflow */
1640 _bfd_mips_elf_hi16_reloc, /* special_function */
1641 "R_MIPS16_HI16", /* name */
1642 FALSE, /* partial_inplace */
1643 0x0000ffff, /* src_mask */
1644 0x0000ffff, /* dst_mask */
1645 FALSE), /* pcrel_offset */
1646
1647 /* MIPS16 low 16 bits of symbol value. */
1648 HOWTO (R_MIPS16_LO16, /* type */
1649 0, /* rightshift */
1650 2, /* size (0 = byte, 1 = short, 2 = long) */
1651 16, /* bitsize */
1652 FALSE, /* pc_relative */
1653 0, /* bitpos */
1654 complain_overflow_dont, /* complain_on_overflow */
1655 _bfd_mips_elf_lo16_reloc, /* special_function */
1656 "R_MIPS16_LO16", /* name */
1657 FALSE, /* partial_inplace */
1658 0x0000ffff, /* src_mask */
1659 0x0000ffff, /* dst_mask */
1660 FALSE), /* pcrel_offset */
1661 };
1662
1663 /* GNU extension to record C++ vtable hierarchy */
1664 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
1665 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
1666 0, /* rightshift */
1667 2, /* size (0 = byte, 1 = short, 2 = long) */
1668 0, /* bitsize */
1669 FALSE, /* pc_relative */
1670 0, /* bitpos */
1671 complain_overflow_dont, /* complain_on_overflow */
1672 NULL, /* special_function */
1673 "R_MIPS_GNU_VTINHERIT", /* name */
1674 FALSE, /* partial_inplace */
1675 0, /* src_mask */
1676 0, /* dst_mask */
1677 FALSE); /* pcrel_offset */
1678
1679 /* GNU extension to record C++ vtable member usage */
1680 static reloc_howto_type elf_mips_gnu_vtentry_howto =
1681 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
1682 0, /* rightshift */
1683 2, /* size (0 = byte, 1 = short, 2 = long) */
1684 0, /* bitsize */
1685 FALSE, /* pc_relative */
1686 0, /* bitpos */
1687 complain_overflow_dont, /* complain_on_overflow */
1688 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1689 "R_MIPS_GNU_VTENTRY", /* name */
1690 FALSE, /* partial_inplace */
1691 0, /* src_mask */
1692 0, /* dst_mask */
1693 FALSE); /* pcrel_offset */
1694 \f
1695 /* 16 bit offset for pc-relative branches. */
1696 static reloc_howto_type elf_mips_gnu_rel16_s2 =
1697 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
1698 2, /* rightshift */
1699 2, /* size (0 = byte, 1 = short, 2 = long) */
1700 16, /* bitsize */
1701 TRUE, /* pc_relative */
1702 0, /* bitpos */
1703 complain_overflow_signed, /* complain_on_overflow */
1704 _bfd_mips_elf_generic_reloc, /* special_function */
1705 "R_MIPS_GNU_REL16_S2", /* name */
1706 TRUE, /* partial_inplace */
1707 0x0000ffff, /* src_mask */
1708 0x0000ffff, /* dst_mask */
1709 TRUE); /* pcrel_offset */
1710
1711 /* 16 bit offset for pc-relative branches. */
1712 static reloc_howto_type elf_mips_gnu_rela16_s2 =
1713 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
1714 2, /* rightshift */
1715 2, /* size (0 = byte, 1 = short, 2 = long) */
1716 16, /* bitsize */
1717 TRUE, /* pc_relative */
1718 0, /* bitpos */
1719 complain_overflow_signed, /* complain_on_overflow */
1720 _bfd_mips_elf_generic_reloc, /* special_function */
1721 "R_MIPS_GNU_REL16_S2", /* name */
1722 FALSE, /* partial_inplace */
1723 0, /* src_mask */
1724 0x0000ffff, /* dst_mask */
1725 TRUE); /* pcrel_offset */
1726 \f
1727 /* Swap in a MIPS 64-bit Rel reloc. */
1728
1729 static void
1730 mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src,
1731 Elf64_Mips_Internal_Rela *dst)
1732 {
1733 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1734 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1735 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1736 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1737 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1738 dst->r_type = H_GET_8 (abfd, src->r_type);
1739 dst->r_addend = 0;
1740 }
1741
1742 /* Swap in a MIPS 64-bit Rela reloc. */
1743
1744 static void
1745 mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src,
1746 Elf64_Mips_Internal_Rela *dst)
1747 {
1748 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1749 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1750 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1751 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1752 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1753 dst->r_type = H_GET_8 (abfd, src->r_type);
1754 dst->r_addend = H_GET_S64 (abfd, src->r_addend);
1755 }
1756
1757 /* Swap out a MIPS 64-bit Rel reloc. */
1758
1759 static void
1760 mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1761 Elf64_Mips_External_Rel *dst)
1762 {
1763 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1764 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1765 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1766 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1767 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1768 H_PUT_8 (abfd, src->r_type, dst->r_type);
1769 }
1770
1771 /* Swap out a MIPS 64-bit Rela reloc. */
1772
1773 static void
1774 mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1775 Elf64_Mips_External_Rela *dst)
1776 {
1777 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1778 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1779 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1780 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1781 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1782 H_PUT_8 (abfd, src->r_type, dst->r_type);
1783 H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
1784 }
1785
1786 /* Swap in a MIPS 64-bit Rel reloc. */
1787
1788 static void
1789 mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src,
1790 Elf_Internal_Rela *dst)
1791 {
1792 Elf64_Mips_Internal_Rela mirel;
1793
1794 mips_elf64_swap_reloc_in (abfd,
1795 (const Elf64_Mips_External_Rel *) src,
1796 &mirel);
1797
1798 dst[0].r_offset = mirel.r_offset;
1799 dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
1800 dst[0].r_addend = 0;
1801 dst[1].r_offset = mirel.r_offset;
1802 dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
1803 dst[1].r_addend = 0;
1804 dst[2].r_offset = mirel.r_offset;
1805 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
1806 dst[2].r_addend = 0;
1807 }
1808
1809 /* Swap in a MIPS 64-bit Rela reloc. */
1810
1811 static void
1812 mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src,
1813 Elf_Internal_Rela *dst)
1814 {
1815 Elf64_Mips_Internal_Rela mirela;
1816
1817 mips_elf64_swap_reloca_in (abfd,
1818 (const Elf64_Mips_External_Rela *) src,
1819 &mirela);
1820
1821 dst[0].r_offset = mirela.r_offset;
1822 dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
1823 dst[0].r_addend = mirela.r_addend;
1824 dst[1].r_offset = mirela.r_offset;
1825 dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
1826 dst[1].r_addend = 0;
1827 dst[2].r_offset = mirela.r_offset;
1828 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
1829 dst[2].r_addend = 0;
1830 }
1831
1832 /* Swap out a MIPS 64-bit Rel reloc. */
1833
1834 static void
1835 mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src,
1836 bfd_byte *dst)
1837 {
1838 Elf64_Mips_Internal_Rela mirel;
1839
1840 mirel.r_offset = src[0].r_offset;
1841 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1842
1843 mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1844 mirel.r_sym = ELF64_R_SYM (src[0].r_info);
1845 mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1846 mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1847 mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1848
1849 mips_elf64_swap_reloc_out (abfd, &mirel,
1850 (Elf64_Mips_External_Rel *) dst);
1851 }
1852
1853 /* Swap out a MIPS 64-bit Rela reloc. */
1854
1855 static void
1856 mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
1857 bfd_byte *dst)
1858 {
1859 Elf64_Mips_Internal_Rela mirela;
1860
1861 mirela.r_offset = src[0].r_offset;
1862 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1863 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
1864
1865 mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1866 mirela.r_sym = ELF64_R_SYM (src[0].r_info);
1867 mirela.r_addend = src[0].r_addend;
1868 BFD_ASSERT(src[1].r_addend == 0);
1869 BFD_ASSERT(src[2].r_addend == 0);
1870
1871 mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1872 mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1873 mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1874
1875 mips_elf64_swap_reloca_out (abfd, &mirela,
1876 (Elf64_Mips_External_Rela *) dst);
1877 }
1878 \f
1879 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1880 dangerous relocation. */
1881
1882 static bfd_boolean
1883 mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp)
1884 {
1885 unsigned int count;
1886 asymbol **sym;
1887 unsigned int i;
1888
1889 /* If we've already figured out what GP will be, just return it. */
1890 *pgp = _bfd_get_gp_value (output_bfd);
1891 if (*pgp)
1892 return TRUE;
1893
1894 count = bfd_get_symcount (output_bfd);
1895 sym = bfd_get_outsymbols (output_bfd);
1896
1897 /* The linker script will have created a symbol named `_gp' with the
1898 appropriate value. */
1899 if (sym == NULL)
1900 i = count;
1901 else
1902 {
1903 for (i = 0; i < count; i++, sym++)
1904 {
1905 register const char *name;
1906
1907 name = bfd_asymbol_name (*sym);
1908 if (*name == '_' && strcmp (name, "_gp") == 0)
1909 {
1910 *pgp = bfd_asymbol_value (*sym);
1911 _bfd_set_gp_value (output_bfd, *pgp);
1912 break;
1913 }
1914 }
1915 }
1916
1917 if (i >= count)
1918 {
1919 /* Only get the error once. */
1920 *pgp = 4;
1921 _bfd_set_gp_value (output_bfd, *pgp);
1922 return FALSE;
1923 }
1924
1925 return TRUE;
1926 }
1927
1928 /* We have to figure out the gp value, so that we can adjust the
1929 symbol value correctly. We look up the symbol _gp in the output
1930 BFD. If we can't find it, we're stuck. We cache it in the ELF
1931 target data. We don't need to adjust the symbol value for an
1932 external symbol if we are producing relocatable output. */
1933
1934 static bfd_reloc_status_type
1935 mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
1936 char **error_message, bfd_vma *pgp)
1937 {
1938 if (bfd_is_und_section (symbol->section)
1939 && ! relocatable)
1940 {
1941 *pgp = 0;
1942 return bfd_reloc_undefined;
1943 }
1944
1945 *pgp = _bfd_get_gp_value (output_bfd);
1946 if (*pgp == 0
1947 && (! relocatable
1948 || (symbol->flags & BSF_SECTION_SYM) != 0))
1949 {
1950 if (relocatable)
1951 {
1952 /* Make up a value. */
1953 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
1954 _bfd_set_gp_value (output_bfd, *pgp);
1955 }
1956 else if (!mips_elf64_assign_gp (output_bfd, pgp))
1957 {
1958 *error_message =
1959 (char *) _("GP relative relocation when _gp not defined");
1960 return bfd_reloc_dangerous;
1961 }
1962 }
1963
1964 return bfd_reloc_ok;
1965 }
1966
1967 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1968 become the offset from the gp register. */
1969
1970 static bfd_reloc_status_type
1971 mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1972 void *data, asection *input_section, bfd *output_bfd,
1973 char **error_message)
1974 {
1975 bfd_boolean relocatable;
1976 bfd_reloc_status_type ret;
1977 bfd_vma gp;
1978
1979 /* If we're relocating, and this is an external symbol, we don't want
1980 to change anything. */
1981 if (output_bfd != NULL
1982 && (symbol->flags & BSF_SECTION_SYM) == 0
1983 && (symbol->flags & BSF_LOCAL) != 0)
1984 {
1985 reloc_entry->address += input_section->output_offset;
1986 return bfd_reloc_ok;
1987 }
1988
1989 if (output_bfd != NULL)
1990 relocatable = TRUE;
1991 else
1992 {
1993 relocatable = FALSE;
1994 output_bfd = symbol->section->output_section->owner;
1995 }
1996
1997 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
1998 &gp);
1999 if (ret != bfd_reloc_ok)
2000 return ret;
2001
2002 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2003 input_section, relocatable,
2004 data, gp);
2005 }
2006
2007 /* Do a R_MIPS_LITERAL relocation. */
2008
2009 static bfd_reloc_status_type
2010 mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2011 void *data, asection *input_section, bfd *output_bfd,
2012 char **error_message)
2013 {
2014 bfd_boolean relocatable;
2015 bfd_reloc_status_type ret;
2016 bfd_vma gp;
2017
2018 /* R_MIPS_LITERAL relocations are defined for local symbols only. */
2019 if (output_bfd != NULL
2020 && (symbol->flags & BSF_SECTION_SYM) == 0
2021 && (symbol->flags & BSF_LOCAL) != 0)
2022 {
2023 *error_message = (char *)
2024 _("literal relocation occurs for an external symbol");
2025 return bfd_reloc_outofrange;
2026 }
2027
2028 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
2029 if (output_bfd != NULL)
2030 relocatable = TRUE;
2031 else
2032 {
2033 relocatable = FALSE;
2034 output_bfd = symbol->section->output_section->owner;
2035 }
2036
2037 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
2038 &gp);
2039 if (ret != bfd_reloc_ok)
2040 return ret;
2041
2042 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2043 input_section, relocatable,
2044 data, gp);
2045 }
2046
2047 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
2048 become the offset from the gp register. */
2049
2050 static bfd_reloc_status_type
2051 mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2052 void *data, asection *input_section, bfd *output_bfd,
2053 char **error_message)
2054 {
2055 bfd_boolean relocatable;
2056 bfd_reloc_status_type ret;
2057 bfd_vma gp;
2058 bfd_vma relocation;
2059 bfd_vma val;
2060
2061 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
2062 if (output_bfd != NULL
2063 && (symbol->flags & BSF_SECTION_SYM) == 0
2064 && (symbol->flags & BSF_LOCAL) != 0)
2065 {
2066 *error_message = (char *)
2067 _("32bits gp relative relocation occurs for an external symbol");
2068 return bfd_reloc_outofrange;
2069 }
2070
2071 if (output_bfd != NULL)
2072 relocatable = TRUE;
2073 else
2074 {
2075 relocatable = FALSE;
2076 output_bfd = symbol->section->output_section->owner;
2077 }
2078
2079 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
2080 error_message, &gp);
2081 if (ret != bfd_reloc_ok)
2082 return ret;
2083
2084 if (bfd_is_com_section (symbol->section))
2085 relocation = 0;
2086 else
2087 relocation = symbol->value;
2088
2089 relocation += symbol->section->output_section->vma;
2090 relocation += symbol->section->output_offset;
2091
2092 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
2093 return bfd_reloc_outofrange;
2094
2095 /* Set val to the offset into the section or symbol. */
2096 val = reloc_entry->addend;
2097
2098 if (reloc_entry->howto->partial_inplace)
2099 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
2100
2101 /* Adjust val for the final section location and GP value. If we
2102 are producing relocatable output, we don't want to do this for
2103 an external symbol. */
2104 if (! relocatable
2105 || (symbol->flags & BSF_SECTION_SYM) != 0)
2106 val += relocation - gp;
2107
2108 if (reloc_entry->howto->partial_inplace)
2109 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
2110 else
2111 reloc_entry->addend = val;
2112
2113 if (relocatable)
2114 reloc_entry->address += input_section->output_offset;
2115
2116 return bfd_reloc_ok;
2117 }
2118
2119 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
2120 the rest is at bits 6-10. The bitpos already got right by the howto. */
2121
2122 static bfd_reloc_status_type
2123 mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2124 void *data, asection *input_section, bfd *output_bfd,
2125 char **error_message)
2126 {
2127 if (reloc_entry->howto->partial_inplace)
2128 {
2129 reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
2130 | (reloc_entry->addend & 0x00000800) >> 9);
2131 }
2132
2133 return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
2134 input_section, output_bfd,
2135 error_message);
2136 }
2137
2138 /* Handle a mips16 GP relative reloc. */
2139
2140 static bfd_reloc_status_type
2141 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2142 void *data, asection *input_section, bfd *output_bfd,
2143 char **error_message)
2144 {
2145 bfd_boolean relocatable;
2146 bfd_reloc_status_type ret;
2147 bfd_byte *location;
2148 bfd_vma gp;
2149
2150 /* If we're relocating, and this is an external symbol, we don't want
2151 to change anything. */
2152 if (output_bfd != NULL
2153 && (symbol->flags & BSF_SECTION_SYM) == 0
2154 && (symbol->flags & BSF_LOCAL) != 0)
2155 {
2156 reloc_entry->address += input_section->output_offset;
2157 return bfd_reloc_ok;
2158 }
2159
2160 if (output_bfd != NULL)
2161 relocatable = TRUE;
2162 else
2163 {
2164 relocatable = FALSE;
2165 output_bfd = symbol->section->output_section->owner;
2166 }
2167
2168 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
2169 &gp);
2170 if (ret != bfd_reloc_ok)
2171 return ret;
2172
2173 location = (bfd_byte *) data + reloc_entry->address;
2174 _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
2175 location);
2176 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2177 input_section, relocatable,
2178 data, gp);
2179 _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
2180 location);
2181
2182 return ret;
2183 }
2184 \f
2185 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
2186
2187 struct elf_reloc_map {
2188 bfd_reloc_code_real_type bfd_val;
2189 enum elf_mips_reloc_type elf_val;
2190 };
2191
2192 static const struct elf_reloc_map mips_reloc_map[] =
2193 {
2194 { BFD_RELOC_NONE, R_MIPS_NONE },
2195 { BFD_RELOC_16, R_MIPS_16 },
2196 { BFD_RELOC_32, R_MIPS_32 },
2197 /* There is no BFD reloc for R_MIPS_REL32. */
2198 { BFD_RELOC_64, R_MIPS_64 },
2199 { BFD_RELOC_CTOR, R_MIPS_64 },
2200 { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
2201 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
2202 { BFD_RELOC_LO16, R_MIPS_LO16 },
2203 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
2204 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
2205 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
2206 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
2207 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
2208 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
2209 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
2210 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
2211 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
2212 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
2213 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
2214 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
2215 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
2216 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
2217 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
2218 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
2219 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
2220 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
2221 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
2222 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
2223 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
2224 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
2225 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
2226 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
2227 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
2228 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
2229 { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
2230 { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
2231 { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
2232 { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
2233 { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
2234 { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
2235 { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
2236 { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
2237 { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
2238 { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
2239 { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
2240 { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
2241 { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
2242 };
2243
2244 static const struct elf_reloc_map mips16_reloc_map[] =
2245 {
2246 { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
2247 { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
2248 { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
2249 { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
2250 { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
2251 { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
2252 };
2253
2254 /* Given a BFD reloc type, return a howto structure. */
2255
2256 static reloc_howto_type *
2257 bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
2258 bfd_reloc_code_real_type code)
2259 {
2260 unsigned int i;
2261 /* FIXME: We default to RELA here instead of choosing the right
2262 relocation variant. */
2263 reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
2264 reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela;
2265
2266 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
2267 i++)
2268 {
2269 if (mips_reloc_map[i].bfd_val == code)
2270 return &howto_table[(int) mips_reloc_map[i].elf_val];
2271 }
2272
2273 for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
2274 i++)
2275 {
2276 if (mips16_reloc_map[i].bfd_val == code)
2277 return &howto16_table[(int) mips16_reloc_map[i].elf_val];
2278 }
2279
2280 switch (code)
2281 {
2282 case BFD_RELOC_VTABLE_INHERIT:
2283 return &elf_mips_gnu_vtinherit_howto;
2284 case BFD_RELOC_VTABLE_ENTRY:
2285 return &elf_mips_gnu_vtentry_howto;
2286 default:
2287 bfd_set_error (bfd_error_bad_value);
2288 return NULL;
2289 }
2290 }
2291
2292 static reloc_howto_type *
2293 bfd_elf64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
2294 const char *r_name)
2295 {
2296 unsigned int i;
2297
2298 for (i = 0;
2299 i < (sizeof (mips_elf64_howto_table_rela)
2300 / sizeof (mips_elf64_howto_table_rela[0])); i++)
2301 if (mips_elf64_howto_table_rela[i].name != NULL
2302 && strcasecmp (mips_elf64_howto_table_rela[i].name, r_name) == 0)
2303 return &mips_elf64_howto_table_rela[i];
2304
2305 for (i = 0;
2306 i < (sizeof (mips16_elf64_howto_table_rela)
2307 / sizeof (mips16_elf64_howto_table_rela[0]));
2308 i++)
2309 if (mips16_elf64_howto_table_rela[i].name != NULL
2310 && strcasecmp (mips16_elf64_howto_table_rela[i].name, r_name) == 0)
2311 return &mips16_elf64_howto_table_rela[i];
2312
2313 if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
2314 return &elf_mips_gnu_vtinherit_howto;
2315 if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
2316 return &elf_mips_gnu_vtentry_howto;
2317 if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
2318 return &elf_mips_gnu_rel16_s2;
2319 if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
2320 return &elf_mips_gnu_rela16_s2;
2321
2322 return NULL;
2323 }
2324
2325 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
2326
2327 static reloc_howto_type *
2328 mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
2329 {
2330 switch (r_type)
2331 {
2332 case R_MIPS_GNU_VTINHERIT:
2333 return &elf_mips_gnu_vtinherit_howto;
2334 case R_MIPS_GNU_VTENTRY:
2335 return &elf_mips_gnu_vtentry_howto;
2336 case R_MIPS_GNU_REL16_S2:
2337 if (rela_p)
2338 return &elf_mips_gnu_rela16_s2;
2339 else
2340 return &elf_mips_gnu_rel16_s2;
2341 default:
2342 if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
2343 {
2344 if (rela_p)
2345 return &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min];
2346 else
2347 return &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min];
2348 }
2349 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
2350 if (rela_p)
2351 return &mips_elf64_howto_table_rela[r_type];
2352 else
2353 return &mips_elf64_howto_table_rel[r_type];
2354 break;
2355 }
2356 }
2357
2358 /* Prevent relocation handling by bfd for MIPS ELF64. */
2359
2360 static void
2361 mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
2362 arelent *cache_ptr ATTRIBUTE_UNUSED,
2363 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
2364 {
2365 BFD_ASSERT (0);
2366 }
2367
2368 static void
2369 mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
2370 arelent *cache_ptr ATTRIBUTE_UNUSED,
2371 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
2372 {
2373 BFD_ASSERT (0);
2374 }
2375
2376 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
2377 to three relocs, we must tell the user to allocate more space. */
2378
2379 static long
2380 mips_elf64_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
2381 {
2382 return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
2383 }
2384
2385 static long
2386 mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
2387 {
2388 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
2389 }
2390
2391 /* We must also copy more relocations than the corresponding functions
2392 in elf.c would, so the two following functions are slightly
2393 modified from elf.c, that multiply the external relocation count by
2394 3 to obtain the internal relocation count. */
2395
2396 static long
2397 mips_elf64_canonicalize_reloc (bfd *abfd, sec_ptr section,
2398 arelent **relptr, asymbol **symbols)
2399 {
2400 arelent *tblptr;
2401 unsigned int i;
2402 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
2403
2404 if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
2405 return -1;
2406
2407 tblptr = section->relocation;
2408 for (i = 0; i < section->reloc_count * 3; i++)
2409 *relptr++ = tblptr++;
2410
2411 *relptr = NULL;
2412
2413 return section->reloc_count * 3;
2414 }
2415
2416 static long
2417 mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
2418 asymbol **syms)
2419 {
2420 bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
2421 asection *s;
2422 long ret;
2423
2424 if (elf_dynsymtab (abfd) == 0)
2425 {
2426 bfd_set_error (bfd_error_invalid_operation);
2427 return -1;
2428 }
2429
2430 slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
2431 ret = 0;
2432 for (s = abfd->sections; s != NULL; s = s->next)
2433 {
2434 if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
2435 && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
2436 || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
2437 {
2438 arelent *p;
2439 long count, i;
2440
2441 if (! (*slurp_relocs) (abfd, s, syms, TRUE))
2442 return -1;
2443 count = s->size / elf_section_data (s)->this_hdr.sh_entsize * 3;
2444 p = s->relocation;
2445 for (i = 0; i < count; i++)
2446 *storage++ = p++;
2447 ret += count;
2448 }
2449 }
2450
2451 *storage = NULL;
2452
2453 return ret;
2454 }
2455
2456 /* Read the relocations from one reloc section. This is mostly copied
2457 from elfcode.h, except for the changes to expand one external
2458 relocation to 3 internal ones. We must unfortunately set
2459 reloc_count to the number of external relocations, because a lot of
2460 generic code seems to depend on this. */
2461
2462 static bfd_boolean
2463 mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
2464 Elf_Internal_Shdr *rel_hdr,
2465 bfd_size_type reloc_count,
2466 arelent *relents, asymbol **symbols,
2467 bfd_boolean dynamic)
2468 {
2469 void *allocated;
2470 bfd_byte *native_relocs;
2471 arelent *relent;
2472 bfd_vma i;
2473 int entsize;
2474 bfd_boolean rela_p;
2475
2476 allocated = bfd_malloc (rel_hdr->sh_size);
2477 if (allocated == NULL)
2478 return FALSE;
2479
2480 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
2481 || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
2482 != rel_hdr->sh_size))
2483 goto error_return;
2484
2485 native_relocs = allocated;
2486
2487 entsize = rel_hdr->sh_entsize;
2488 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
2489 || entsize == sizeof (Elf64_Mips_External_Rela));
2490
2491 if (entsize == sizeof (Elf64_Mips_External_Rel))
2492 rela_p = FALSE;
2493 else
2494 rela_p = TRUE;
2495
2496 for (i = 0, relent = relents;
2497 i < reloc_count;
2498 i++, native_relocs += entsize)
2499 {
2500 Elf64_Mips_Internal_Rela rela;
2501 bfd_boolean used_sym, used_ssym;
2502 int ir;
2503
2504 if (entsize == sizeof (Elf64_Mips_External_Rela))
2505 mips_elf64_swap_reloca_in (abfd,
2506 (Elf64_Mips_External_Rela *) native_relocs,
2507 &rela);
2508 else
2509 mips_elf64_swap_reloc_in (abfd,
2510 (Elf64_Mips_External_Rel *) native_relocs,
2511 &rela);
2512
2513 /* Each entry represents exactly three actual relocations. */
2514
2515 used_sym = FALSE;
2516 used_ssym = FALSE;
2517 for (ir = 0; ir < 3; ir++)
2518 {
2519 enum elf_mips_reloc_type type;
2520
2521 switch (ir)
2522 {
2523 default:
2524 abort ();
2525 case 0:
2526 type = (enum elf_mips_reloc_type) rela.r_type;
2527 break;
2528 case 1:
2529 type = (enum elf_mips_reloc_type) rela.r_type2;
2530 break;
2531 case 2:
2532 type = (enum elf_mips_reloc_type) rela.r_type3;
2533 break;
2534 }
2535
2536 /* Some types require symbols, whereas some do not. */
2537 switch (type)
2538 {
2539 case R_MIPS_NONE:
2540 case R_MIPS_LITERAL:
2541 case R_MIPS_INSERT_A:
2542 case R_MIPS_INSERT_B:
2543 case R_MIPS_DELETE:
2544 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2545 break;
2546
2547 default:
2548 if (! used_sym)
2549 {
2550 if (rela.r_sym == 0)
2551 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2552 else
2553 {
2554 asymbol **ps, *s;
2555
2556 ps = symbols + rela.r_sym - 1;
2557 s = *ps;
2558 if ((s->flags & BSF_SECTION_SYM) == 0)
2559 relent->sym_ptr_ptr = ps;
2560 else
2561 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
2562 }
2563
2564 used_sym = TRUE;
2565 }
2566 else if (! used_ssym)
2567 {
2568 switch (rela.r_ssym)
2569 {
2570 case RSS_UNDEF:
2571 relent->sym_ptr_ptr =
2572 bfd_abs_section_ptr->symbol_ptr_ptr;
2573 break;
2574
2575 case RSS_GP:
2576 case RSS_GP0:
2577 case RSS_LOC:
2578 /* FIXME: I think these need to be handled using
2579 special howto structures. */
2580 BFD_ASSERT (0);
2581 break;
2582
2583 default:
2584 BFD_ASSERT (0);
2585 break;
2586 }
2587
2588 used_ssym = TRUE;
2589 }
2590 else
2591 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2592
2593 break;
2594 }
2595
2596 /* The address of an ELF reloc is section relative for an
2597 object file, and absolute for an executable file or
2598 shared library. The address of a BFD reloc is always
2599 section relative. */
2600 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
2601 relent->address = rela.r_offset;
2602 else
2603 relent->address = rela.r_offset - asect->vma;
2604
2605 relent->addend = rela.r_addend;
2606
2607 relent->howto = mips_elf64_rtype_to_howto (type, rela_p);
2608
2609 ++relent;
2610 }
2611 }
2612
2613 asect->reloc_count += (relent - relents) / 3;
2614
2615 if (allocated != NULL)
2616 free (allocated);
2617
2618 return TRUE;
2619
2620 error_return:
2621 if (allocated != NULL)
2622 free (allocated);
2623 return FALSE;
2624 }
2625
2626 /* Read the relocations. On Irix 6, there can be two reloc sections
2627 associated with a single data section. This is copied from
2628 elfcode.h as well, with changes as small as accounting for 3
2629 internal relocs per external reloc and resetting reloc_count to
2630 zero before processing the relocs of a section. */
2631
2632 static bfd_boolean
2633 mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
2634 asymbol **symbols, bfd_boolean dynamic)
2635 {
2636 struct bfd_elf_section_data * const d = elf_section_data (asect);
2637 Elf_Internal_Shdr *rel_hdr;
2638 Elf_Internal_Shdr *rel_hdr2;
2639 bfd_size_type reloc_count;
2640 bfd_size_type reloc_count2;
2641 arelent *relents;
2642 bfd_size_type amt;
2643
2644 if (asect->relocation != NULL)
2645 return TRUE;
2646
2647 if (! dynamic)
2648 {
2649 if ((asect->flags & SEC_RELOC) == 0
2650 || asect->reloc_count == 0)
2651 return TRUE;
2652
2653 rel_hdr = &d->rel_hdr;
2654 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2655 rel_hdr2 = d->rel_hdr2;
2656 reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
2657
2658 BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
2659 BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
2660 || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
2661
2662 }
2663 else
2664 {
2665 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
2666 case because relocations against this section may use the
2667 dynamic symbol table, and in that case bfd_section_from_shdr
2668 in elf.c does not update the RELOC_COUNT. */
2669 if (asect->size == 0)
2670 return TRUE;
2671
2672 rel_hdr = &d->this_hdr;
2673 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2674 rel_hdr2 = NULL;
2675 reloc_count2 = 0;
2676 }
2677
2678 /* Allocate space for 3 arelent structures for each Rel structure. */
2679 amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
2680 relents = bfd_alloc (abfd, amt);
2681 if (relents == NULL)
2682 return FALSE;
2683
2684 /* The slurp_one_reloc_table routine increments reloc_count. */
2685 asect->reloc_count = 0;
2686
2687 if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2688 rel_hdr, reloc_count,
2689 relents,
2690 symbols, dynamic))
2691 return FALSE;
2692 if (d->rel_hdr2 != NULL)
2693 {
2694 if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2695 rel_hdr2, reloc_count2,
2696 relents + reloc_count * 3,
2697 symbols, dynamic))
2698 return FALSE;
2699 }
2700
2701 asect->relocation = relents;
2702 return TRUE;
2703 }
2704
2705 /* Write out the relocations. */
2706
2707 static void
2708 mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
2709 {
2710 bfd_boolean *failedp = data;
2711 int count;
2712 Elf_Internal_Shdr *rel_hdr;
2713 unsigned int idx;
2714
2715 /* If we have already failed, don't do anything. */
2716 if (*failedp)
2717 return;
2718
2719 if ((sec->flags & SEC_RELOC) == 0)
2720 return;
2721
2722 /* The linker backend writes the relocs out itself, and sets the
2723 reloc_count field to zero to inhibit writing them here. Also,
2724 sometimes the SEC_RELOC flag gets set even when there aren't any
2725 relocs. */
2726 if (sec->reloc_count == 0)
2727 return;
2728
2729 /* We can combine up to three relocs that refer to the same address
2730 if the latter relocs have no associated symbol. */
2731 count = 0;
2732 for (idx = 0; idx < sec->reloc_count; idx++)
2733 {
2734 bfd_vma addr;
2735 unsigned int i;
2736
2737 ++count;
2738
2739 addr = sec->orelocation[idx]->address;
2740 for (i = 0; i < 2; i++)
2741 {
2742 arelent *r;
2743
2744 if (idx + 1 >= sec->reloc_count)
2745 break;
2746 r = sec->orelocation[idx + 1];
2747 if (r->address != addr
2748 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2749 || (*r->sym_ptr_ptr)->value != 0)
2750 break;
2751
2752 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2753
2754 ++idx;
2755 }
2756 }
2757
2758 rel_hdr = &elf_section_data (sec)->rel_hdr;
2759
2760 /* Do the actual relocation. */
2761
2762 if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
2763 mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
2764 else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
2765 mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
2766 else
2767 BFD_ASSERT (0);
2768 }
2769
2770 static void
2771 mips_elf64_write_rel (bfd *abfd, asection *sec,
2772 Elf_Internal_Shdr *rel_hdr,
2773 int *count, void *data)
2774 {
2775 bfd_boolean *failedp = data;
2776 Elf64_Mips_External_Rel *ext_rel;
2777 unsigned int idx;
2778 asymbol *last_sym = 0;
2779 int last_sym_idx = 0;
2780
2781 rel_hdr->sh_size = rel_hdr->sh_entsize * *count;
2782 rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size);
2783 if (rel_hdr->contents == NULL)
2784 {
2785 *failedp = TRUE;
2786 return;
2787 }
2788
2789 ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
2790 for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
2791 {
2792 arelent *ptr;
2793 Elf64_Mips_Internal_Rela int_rel;
2794 asymbol *sym;
2795 int n;
2796 unsigned int i;
2797
2798 ptr = sec->orelocation[idx];
2799
2800 /* The address of an ELF reloc is section relative for an object
2801 file, and absolute for an executable file or shared library.
2802 The address of a BFD reloc is always section relative. */
2803 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2804 int_rel.r_offset = ptr->address;
2805 else
2806 int_rel.r_offset = ptr->address + sec->vma;
2807
2808 sym = *ptr->sym_ptr_ptr;
2809 if (sym == last_sym)
2810 n = last_sym_idx;
2811 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2812 n = STN_UNDEF;
2813 else
2814 {
2815 last_sym = sym;
2816 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2817 if (n < 0)
2818 {
2819 *failedp = TRUE;
2820 return;
2821 }
2822 last_sym_idx = n;
2823 }
2824
2825 int_rel.r_sym = n;
2826 int_rel.r_ssym = RSS_UNDEF;
2827
2828 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2829 && ! _bfd_elf_validate_reloc (abfd, ptr))
2830 {
2831 *failedp = TRUE;
2832 return;
2833 }
2834
2835 int_rel.r_type = ptr->howto->type;
2836 int_rel.r_type2 = (int) R_MIPS_NONE;
2837 int_rel.r_type3 = (int) R_MIPS_NONE;
2838
2839 for (i = 0; i < 2; i++)
2840 {
2841 arelent *r;
2842
2843 if (idx + 1 >= sec->reloc_count)
2844 break;
2845 r = sec->orelocation[idx + 1];
2846 if (r->address != ptr->address
2847 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2848 || (*r->sym_ptr_ptr)->value != 0)
2849 break;
2850
2851 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2852
2853 if (i == 0)
2854 int_rel.r_type2 = r->howto->type;
2855 else
2856 int_rel.r_type3 = r->howto->type;
2857
2858 ++idx;
2859 }
2860
2861 mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
2862 }
2863
2864 BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
2865 == *count);
2866 }
2867
2868 static void
2869 mips_elf64_write_rela (bfd *abfd, asection *sec,
2870 Elf_Internal_Shdr *rela_hdr,
2871 int *count, void *data)
2872 {
2873 bfd_boolean *failedp = data;
2874 Elf64_Mips_External_Rela *ext_rela;
2875 unsigned int idx;
2876 asymbol *last_sym = 0;
2877 int last_sym_idx = 0;
2878
2879 rela_hdr->sh_size = rela_hdr->sh_entsize * *count;
2880 rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
2881 if (rela_hdr->contents == NULL)
2882 {
2883 *failedp = TRUE;
2884 return;
2885 }
2886
2887 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
2888 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
2889 {
2890 arelent *ptr;
2891 Elf64_Mips_Internal_Rela int_rela;
2892 asymbol *sym;
2893 int n;
2894 unsigned int i;
2895
2896 ptr = sec->orelocation[idx];
2897
2898 /* The address of an ELF reloc is section relative for an object
2899 file, and absolute for an executable file or shared library.
2900 The address of a BFD reloc is always section relative. */
2901 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2902 int_rela.r_offset = ptr->address;
2903 else
2904 int_rela.r_offset = ptr->address + sec->vma;
2905
2906 sym = *ptr->sym_ptr_ptr;
2907 if (sym == last_sym)
2908 n = last_sym_idx;
2909 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2910 n = STN_UNDEF;
2911 else
2912 {
2913 last_sym = sym;
2914 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2915 if (n < 0)
2916 {
2917 *failedp = TRUE;
2918 return;
2919 }
2920 last_sym_idx = n;
2921 }
2922
2923 int_rela.r_sym = n;
2924 int_rela.r_addend = ptr->addend;
2925 int_rela.r_ssym = RSS_UNDEF;
2926
2927 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2928 && ! _bfd_elf_validate_reloc (abfd, ptr))
2929 {
2930 *failedp = TRUE;
2931 return;
2932 }
2933
2934 int_rela.r_type = ptr->howto->type;
2935 int_rela.r_type2 = (int) R_MIPS_NONE;
2936 int_rela.r_type3 = (int) R_MIPS_NONE;
2937
2938 for (i = 0; i < 2; i++)
2939 {
2940 arelent *r;
2941
2942 if (idx + 1 >= sec->reloc_count)
2943 break;
2944 r = sec->orelocation[idx + 1];
2945 if (r->address != ptr->address
2946 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2947 || (*r->sym_ptr_ptr)->value != 0)
2948 break;
2949
2950 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2951
2952 if (i == 0)
2953 int_rela.r_type2 = r->howto->type;
2954 else
2955 int_rela.r_type3 = r->howto->type;
2956
2957 ++idx;
2958 }
2959
2960 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
2961 }
2962
2963 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
2964 == *count);
2965 }
2966 \f
2967 /* Set the right machine number for a MIPS ELF file. */
2968
2969 static bfd_boolean
2970 mips_elf64_object_p (bfd *abfd)
2971 {
2972 unsigned long mach;
2973
2974 /* Irix 6 is broken. Object file symbol tables are not always
2975 sorted correctly such that local symbols precede global symbols,
2976 and the sh_info field in the symbol table is not always right. */
2977 if (elf64_mips_irix_compat (abfd) != ict_none)
2978 elf_bad_symtab (abfd) = TRUE;
2979
2980 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
2981 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
2982 return TRUE;
2983 }
2984
2985 /* Depending on the target vector we generate some version of Irix
2986 executables or "normal" MIPS ELF ABI executables. */
2987 static irix_compat_t
2988 elf64_mips_irix_compat (bfd *abfd)
2989 {
2990 if ((abfd->xvec == &bfd_elf64_bigmips_vec)
2991 || (abfd->xvec == &bfd_elf64_littlemips_vec))
2992 return ict_irix6;
2993 else
2994 return ict_none;
2995 }
2996 \f
2997 /* Support for core dump NOTE sections. */
2998 static bfd_boolean
2999 elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3000 {
3001 int offset;
3002 unsigned int size;
3003
3004 switch (note->descsz)
3005 {
3006 default:
3007 return FALSE;
3008
3009 case 480: /* Linux/MIPS - N64 kernel */
3010 /* pr_cursig */
3011 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
3012
3013 /* pr_pid */
3014 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 32);
3015
3016 /* pr_reg */
3017 offset = 112;
3018 size = 360;
3019
3020 break;
3021 }
3022
3023 /* Make a ".reg/999" section. */
3024 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
3025 size, note->descpos + offset);
3026 }
3027
3028 static bfd_boolean
3029 elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3030 {
3031 switch (note->descsz)
3032 {
3033 default:
3034 return FALSE;
3035
3036 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
3037 elf_tdata (abfd)->core_program
3038 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
3039 elf_tdata (abfd)->core_command
3040 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
3041 }
3042
3043 /* Note that for some reason, a spurious space is tacked
3044 onto the end of the args in some (at least one anyway)
3045 implementations, so strip it off if it exists. */
3046
3047 {
3048 char *command = elf_tdata (abfd)->core_command;
3049 int n = strlen (command);
3050
3051 if (0 < n && command[n - 1] == ' ')
3052 command[n - 1] = '\0';
3053 }
3054
3055 return TRUE;
3056 }
3057 \f
3058 /* ECOFF swapping routines. These are used when dealing with the
3059 .mdebug section, which is in the ECOFF debugging format. */
3060 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
3061 {
3062 /* Symbol table magic number. */
3063 magicSym2,
3064 /* Alignment of debugging information. E.g., 4. */
3065 8,
3066 /* Sizes of external symbolic information. */
3067 sizeof (struct hdr_ext),
3068 sizeof (struct dnr_ext),
3069 sizeof (struct pdr_ext),
3070 sizeof (struct sym_ext),
3071 sizeof (struct opt_ext),
3072 sizeof (struct fdr_ext),
3073 sizeof (struct rfd_ext),
3074 sizeof (struct ext_ext),
3075 /* Functions to swap in external symbolic data. */
3076 ecoff_swap_hdr_in,
3077 ecoff_swap_dnr_in,
3078 ecoff_swap_pdr_in,
3079 ecoff_swap_sym_in,
3080 ecoff_swap_opt_in,
3081 ecoff_swap_fdr_in,
3082 ecoff_swap_rfd_in,
3083 ecoff_swap_ext_in,
3084 _bfd_ecoff_swap_tir_in,
3085 _bfd_ecoff_swap_rndx_in,
3086 /* Functions to swap out external symbolic data. */
3087 ecoff_swap_hdr_out,
3088 ecoff_swap_dnr_out,
3089 ecoff_swap_pdr_out,
3090 ecoff_swap_sym_out,
3091 ecoff_swap_opt_out,
3092 ecoff_swap_fdr_out,
3093 ecoff_swap_rfd_out,
3094 ecoff_swap_ext_out,
3095 _bfd_ecoff_swap_tir_out,
3096 _bfd_ecoff_swap_rndx_out,
3097 /* Function to read in symbolic data. */
3098 _bfd_mips_elf_read_ecoff_info
3099 };
3100 \f
3101 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
3102 standard ELF. This structure is used to redirect the relocation
3103 handling routines. */
3104
3105 const struct elf_size_info mips_elf64_size_info =
3106 {
3107 sizeof (Elf64_External_Ehdr),
3108 sizeof (Elf64_External_Phdr),
3109 sizeof (Elf64_External_Shdr),
3110 sizeof (Elf64_Mips_External_Rel),
3111 sizeof (Elf64_Mips_External_Rela),
3112 sizeof (Elf64_External_Sym),
3113 sizeof (Elf64_External_Dyn),
3114 sizeof (Elf_External_Note),
3115 4, /* hash-table entry size */
3116 3, /* internal relocations per external relocations */
3117 64, /* arch_size */
3118 3, /* log_file_align */
3119 ELFCLASS64,
3120 EV_CURRENT,
3121 bfd_elf64_write_out_phdrs,
3122 bfd_elf64_write_shdrs_and_ehdr,
3123 bfd_elf64_checksum_contents,
3124 mips_elf64_write_relocs,
3125 bfd_elf64_swap_symbol_in,
3126 bfd_elf64_swap_symbol_out,
3127 mips_elf64_slurp_reloc_table,
3128 bfd_elf64_slurp_symbol_table,
3129 bfd_elf64_swap_dyn_in,
3130 bfd_elf64_swap_dyn_out,
3131 mips_elf64_be_swap_reloc_in,
3132 mips_elf64_be_swap_reloc_out,
3133 mips_elf64_be_swap_reloca_in,
3134 mips_elf64_be_swap_reloca_out
3135 };
3136
3137 #define ELF_ARCH bfd_arch_mips
3138 #define ELF_MACHINE_CODE EM_MIPS
3139
3140 #define elf_backend_collect TRUE
3141 #define elf_backend_type_change_ok TRUE
3142 #define elf_backend_can_gc_sections TRUE
3143 #define elf_info_to_howto mips_elf64_info_to_howto_rela
3144 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
3145 #define elf_backend_object_p mips_elf64_object_p
3146 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
3147 #define elf_backend_section_processing _bfd_mips_elf_section_processing
3148 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
3149 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
3150 #define elf_backend_section_from_bfd_section \
3151 _bfd_mips_elf_section_from_bfd_section
3152 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
3153 #define elf_backend_link_output_symbol_hook \
3154 _bfd_mips_elf_link_output_symbol_hook
3155 #define elf_backend_create_dynamic_sections \
3156 _bfd_mips_elf_create_dynamic_sections
3157 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
3158 #define elf_backend_merge_symbol_attribute \
3159 _bfd_mips_elf_merge_symbol_attribute
3160 #define elf_backend_get_target_dtag _bfd_mips_elf_get_target_dtag
3161 #define elf_backend_adjust_dynamic_symbol \
3162 _bfd_mips_elf_adjust_dynamic_symbol
3163 #define elf_backend_always_size_sections \
3164 _bfd_mips_elf_always_size_sections
3165 #define elf_backend_size_dynamic_sections \
3166 _bfd_mips_elf_size_dynamic_sections
3167 #define elf_backend_init_index_section _bfd_elf_init_1_index_section
3168 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
3169 #define elf_backend_finish_dynamic_symbol \
3170 _bfd_mips_elf_finish_dynamic_symbol
3171 #define elf_backend_finish_dynamic_sections \
3172 _bfd_mips_elf_finish_dynamic_sections
3173 #define elf_backend_final_write_processing \
3174 _bfd_mips_elf_final_write_processing
3175 #define elf_backend_additional_program_headers \
3176 _bfd_mips_elf_additional_program_headers
3177 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
3178 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
3179 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
3180 #define elf_backend_copy_indirect_symbol \
3181 _bfd_mips_elf_copy_indirect_symbol
3182 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
3183 #define elf_backend_ignore_discarded_relocs \
3184 _bfd_mips_elf_ignore_discarded_relocs
3185 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
3186 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
3187 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
3188 #define elf_backend_size_info mips_elf64_size_info
3189
3190 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus
3191 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo
3192
3193 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
3194
3195 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
3196 work better/work only in RELA, so we default to this. */
3197 #define elf_backend_may_use_rel_p 1
3198 #define elf_backend_may_use_rela_p 1
3199 #define elf_backend_default_use_rela_p 1
3200
3201 #define elf_backend_sign_extend_vma TRUE
3202
3203 #define elf_backend_write_section _bfd_mips_elf_write_section
3204
3205 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
3206 MIPS-specific function only applies to IRIX5, which had no 64-bit
3207 ABI. */
3208 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
3209 #define bfd_elf64_find_inliner_info _bfd_mips_elf_find_inliner_info
3210 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
3211 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
3212 #define bfd_elf64_bfd_get_relocated_section_contents \
3213 _bfd_elf_mips_get_relocated_section_contents
3214 #define bfd_elf64_bfd_link_hash_table_create \
3215 _bfd_mips_elf_link_hash_table_create
3216 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
3217 #define bfd_elf64_bfd_merge_private_bfd_data \
3218 _bfd_mips_elf_merge_private_bfd_data
3219 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
3220 #define bfd_elf64_bfd_print_private_bfd_data \
3221 _bfd_mips_elf_print_private_bfd_data
3222
3223 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
3224 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
3225 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
3226 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
3227 #define bfd_elf64_bfd_relax_section _bfd_mips_relax_section
3228
3229 /* MIPS ELF64 archive functions. */
3230 #define bfd_elf64_archive_functions
3231 extern bfd_boolean bfd_elf64_archive_slurp_armap
3232 (bfd *);
3233 extern bfd_boolean bfd_elf64_archive_write_armap
3234 (bfd *, unsigned int, struct orl *, unsigned int, int);
3235 #define bfd_elf64_archive_slurp_extended_name_table \
3236 _bfd_archive_coff_slurp_extended_name_table
3237 #define bfd_elf64_archive_construct_extended_name_table \
3238 _bfd_archive_coff_construct_extended_name_table
3239 #define bfd_elf64_archive_truncate_arname \
3240 _bfd_archive_coff_truncate_arname
3241 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
3242 #define bfd_elf64_archive_openr_next_archived_file \
3243 _bfd_archive_coff_openr_next_archived_file
3244 #define bfd_elf64_archive_get_elt_at_index \
3245 _bfd_archive_coff_get_elt_at_index
3246 #define bfd_elf64_archive_generic_stat_arch_elt \
3247 _bfd_archive_coff_generic_stat_arch_elt
3248 #define bfd_elf64_archive_update_armap_timestamp \
3249 _bfd_archive_coff_update_armap_timestamp
3250
3251 /* The SGI style (n)64 NewABI. */
3252 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
3253 #define TARGET_LITTLE_NAME "elf64-littlemips"
3254 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
3255 #define TARGET_BIG_NAME "elf64-bigmips"
3256
3257 #define ELF_MAXPAGESIZE 0x10000
3258 #define ELF_COMMONPAGESIZE 0x1000
3259
3260 #include "elf64-target.h"
3261
3262 /* The SYSV-style 'traditional' (n)64 NewABI. */
3263 #undef TARGET_LITTLE_SYM
3264 #undef TARGET_LITTLE_NAME
3265 #undef TARGET_BIG_SYM
3266 #undef TARGET_BIG_NAME
3267
3268 #undef ELF_MAXPAGESIZE
3269 #undef ELF_COMMONPAGESIZE
3270
3271 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
3272 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
3273 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
3274 #define TARGET_BIG_NAME "elf64-tradbigmips"
3275
3276 #define ELF_MAXPAGESIZE 0x10000
3277 #define ELF_COMMONPAGESIZE 0x1000
3278 #define elf64_bed elf64_tradbed
3279
3280 /* Include the target file again for this target. */
3281 #include "elf64-target.h"