1 /* MIPS-specific support for 64-bit ELF
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3 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 2 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, MA 02110-1301, USA. */
23
24 /* This file supports the 64-bit MIPS ELF ABI.
25
26 The MIPS 64-bit ELF ABI uses an unusual reloc format. This file
27 overrides the usual ELF reloc handling, and handles reading and
28 writing the relocations here. */
29
30 /* TODO: Many things are unsupported, even if there is some code for it
31 . (which was mostly stolen from elf32-mips.c and slightly adapted).
32 .
33 . - Relocation handling for REL relocs is wrong in many cases and
34 . generally untested.
35 . - Relocation handling for RELA relocs related to GOT support are
36 . also likely to be wrong.
37 . - Support for MIPS16 is untested.
38 . - Combined relocs with RSS_* entries are unsupported.
39 . - The whole GOT handling for NewABI is missing, some parts of
40 . the OldABI version is still lying around and should be removed.
41 */
42
43 #include "bfd.h"
44 #include "sysdep.h"
45 #include "libbfd.h"
46 #include "aout/ar.h"
47 #include "bfdlink.h"
48 #include "genlink.h"
49 #include "elf-bfd.h"
50 #include "elfxx-mips.h"
51 #include "elf/mips.h"
52
53 /* Get the ECOFF swapping routines. The 64-bit ABI is not supposed to
54 use ECOFF. However, we support it anyhow for an easier changeover. */
55 #include "coff/sym.h"
56 #include "coff/symconst.h"
57 #include "coff/internal.h"
58 #include "coff/ecoff.h"
59 /* The 64 bit versions of the mdebug data structures are in alpha.h. */
60 #include "coff/alpha.h"
61 #define ECOFF_SIGNED_64
62 #include "ecoffswap.h"
63
64 static void mips_elf64_swap_reloc_in
65 (bfd *, const Elf64_Mips_External_Rel *, Elf64_Mips_Internal_Rela *);
66 static void mips_elf64_swap_reloca_in
67 (bfd *, const Elf64_Mips_External_Rela *, Elf64_Mips_Internal_Rela *);
68 static void mips_elf64_swap_reloc_out
69 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rel *);
70 static void mips_elf64_swap_reloca_out
71 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rela *);
72 static void mips_elf64_be_swap_reloc_in
73 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
74 static void mips_elf64_be_swap_reloc_out
75 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
76 static void mips_elf64_be_swap_reloca_in
77 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
78 static void mips_elf64_be_swap_reloca_out
79 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
80 static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup
81 (bfd *, bfd_reloc_code_real_type);
82 static reloc_howto_type *mips_elf64_rtype_to_howto
83 (unsigned int, bfd_boolean);
84 static void mips_elf64_info_to_howto_rel
85 (bfd *, arelent *, Elf_Internal_Rela *);
86 static void mips_elf64_info_to_howto_rela
87 (bfd *, arelent *, Elf_Internal_Rela *);
88 static long mips_elf64_get_reloc_upper_bound
89 (bfd *, asection *);
90 static long mips_elf64_canonicalize_reloc
91 (bfd *, asection *, arelent **, asymbol **);
92 static long mips_elf64_get_dynamic_reloc_upper_bound
93 (bfd *);
94 static long mips_elf64_canonicalize_dynamic_reloc
95 (bfd *, arelent **, asymbol **);
96 static bfd_boolean mips_elf64_slurp_one_reloc_table
97 (bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type, arelent *,
98 asymbol **, bfd_boolean);
99 static bfd_boolean mips_elf64_slurp_reloc_table
100 (bfd *, asection *, asymbol **, bfd_boolean);
101 static void mips_elf64_write_relocs
102 (bfd *, asection *, void *);
103 static void mips_elf64_write_rel
104 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
105 static void mips_elf64_write_rela
106 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
107 static bfd_reloc_status_type mips_elf64_gprel16_reloc
108 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
109 static bfd_reloc_status_type mips_elf64_literal_reloc
110 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
111 static bfd_reloc_status_type mips_elf64_gprel32_reloc
112 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
113 static bfd_reloc_status_type mips_elf64_shift6_reloc
114 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
115 static bfd_reloc_status_type mips16_jump_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
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
796 /* The relocation table used for SHT_RELA sections. */
797
798 static reloc_howto_type mips_elf64_howto_table_rela[] =
799 {
800 /* No relocation. */
801 HOWTO (R_MIPS_NONE, /* type */
802 0, /* rightshift */
803 0, /* size (0 = byte, 1 = short, 2 = long) */
804 0, /* bitsize */
805 FALSE, /* pc_relative */
806 0, /* bitpos */
807 complain_overflow_dont, /* complain_on_overflow */
808 _bfd_mips_elf_generic_reloc, /* special_function */
809 "R_MIPS_NONE", /* name */
810 FALSE, /* partial_inplace */
811 0, /* src_mask */
812 0, /* dst_mask */
813 FALSE), /* pcrel_offset */
814
815 /* 16 bit relocation. */
816 HOWTO (R_MIPS_16, /* type */
817 0, /* rightshift */
818 2, /* size (0 = byte, 1 = short, 2 = long) */
819 16, /* bitsize */
820 FALSE, /* pc_relative */
821 0, /* bitpos */
822 complain_overflow_signed, /* complain_on_overflow */
823 _bfd_mips_elf_generic_reloc, /* special_function */
824 "R_MIPS_16", /* name */
825 FALSE, /* partial_inplace */
826 0, /* src_mask */
827 0x0000ffff, /* dst_mask */
828 FALSE), /* pcrel_offset */
829
830 /* 32 bit relocation. */
831 HOWTO (R_MIPS_32, /* type */
832 0, /* rightshift */
833 2, /* size (0 = byte, 1 = short, 2 = long) */
834 32, /* bitsize */
835 FALSE, /* pc_relative */
836 0, /* bitpos */
837 complain_overflow_dont, /* complain_on_overflow */
838 _bfd_mips_elf_generic_reloc, /* special_function */
839 "R_MIPS_32", /* name */
840 FALSE, /* partial_inplace */
841 0, /* src_mask */
842 0xffffffff, /* dst_mask */
843 FALSE), /* pcrel_offset */
844
845 /* 32 bit symbol relative relocation. */
846 HOWTO (R_MIPS_REL32, /* 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_REL32", /* name */
855 FALSE, /* partial_inplace */
856 0, /* src_mask */
857 0xffffffff, /* dst_mask */
858 FALSE), /* pcrel_offset */
859
860 /* 26 bit jump address. */
861 HOWTO (R_MIPS_26, /* type */
862 2, /* rightshift */
863 2, /* size (0 = byte, 1 = short, 2 = long) */
864 26, /* bitsize */
865 FALSE, /* pc_relative */
866 0, /* bitpos */
867 complain_overflow_dont, /* complain_on_overflow */
868 /* This needs complex overflow
869 detection, because the upper 36
870 bits must match the PC + 4. */
871 _bfd_mips_elf_generic_reloc, /* special_function */
872 "R_MIPS_26", /* name */
873 FALSE, /* partial_inplace */
874 0, /* src_mask */
875 0x03ffffff, /* dst_mask */
876 FALSE), /* pcrel_offset */
877
878 /* High 16 bits of symbol value. */
879 HOWTO (R_MIPS_HI16, /* type */
880 0, /* rightshift */
881 2, /* size (0 = byte, 1 = short, 2 = long) */
882 16, /* bitsize */
883 FALSE, /* pc_relative */
884 0, /* bitpos */
885 complain_overflow_dont, /* complain_on_overflow */
886 _bfd_mips_elf_generic_reloc, /* special_function */
887 "R_MIPS_HI16", /* name */
888 FALSE, /* partial_inplace */
889 0, /* src_mask */
890 0x0000ffff, /* dst_mask */
891 FALSE), /* pcrel_offset */
892
893 /* Low 16 bits of symbol value. */
894 HOWTO (R_MIPS_LO16, /* 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_LO16", /* name */
903 FALSE, /* partial_inplace */
904 0, /* src_mask */
905 0x0000ffff, /* dst_mask */
906 FALSE), /* pcrel_offset */
907
908 /* GP relative reference. */
909 HOWTO (R_MIPS_GPREL16, /* 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_signed, /* complain_on_overflow */
916 mips_elf64_gprel16_reloc, /* special_function */
917 "R_MIPS_GPREL16", /* name */
918 FALSE, /* partial_inplace */
919 0, /* src_mask */
920 0x0000ffff, /* dst_mask */
921 FALSE), /* pcrel_offset */
922
923 /* Reference to literal section. */
924 HOWTO (R_MIPS_LITERAL, /* 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_literal_reloc, /* special_function */
932 "R_MIPS_LITERAL", /* name */
933 FALSE, /* partial_inplace */
934 0, /* src_mask */
935 0x0000ffff, /* dst_mask */
936 FALSE), /* pcrel_offset */
937
938 /* Reference to global offset table. */
939 HOWTO (R_MIPS_GOT16, /* 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 _bfd_mips_elf_generic_reloc, /* special_function */
947 "R_MIPS_GOT16", /* name */
948 FALSE, /* partial_inplace */
949 0, /* src_mask */
950 0x0000ffff, /* dst_mask */
951 FALSE), /* pcrel_offset */
952
953 /* 16 bit PC relative reference. Note that the ABI document has a typo
954 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
955 We do the right thing here. */
956 HOWTO (R_MIPS_PC16, /* type */
957 2, /* rightshift */
958 2, /* size (0 = byte, 1 = short, 2 = long) */
959 16, /* bitsize */
960 TRUE, /* pc_relative */
961 0, /* bitpos */
962 complain_overflow_signed, /* complain_on_overflow */
963 _bfd_mips_elf_generic_reloc, /* special_function */
964 "R_MIPS_PC16", /* name */
965 FALSE, /* partial_inplace */
966 0, /* src_mask */
967 0x0000ffff, /* dst_mask */
968 TRUE), /* pcrel_offset */
969
970 /* 16 bit call through global offset table. */
971 HOWTO (R_MIPS_CALL16, /* type */
972 0, /* rightshift */
973 2, /* size (0 = byte, 1 = short, 2 = long) */
974 16, /* bitsize */
975 FALSE, /* pc_relative */
976 0, /* bitpos */
977 complain_overflow_signed, /* complain_on_overflow */
978 _bfd_mips_elf_generic_reloc, /* special_function */
979 "R_MIPS_CALL16", /* name */
980 FALSE, /* partial_inplace */
981 0, /* src_mask */
982 0x0000ffff, /* dst_mask */
983 FALSE), /* pcrel_offset */
984
985 /* 32 bit GP relative reference. */
986 HOWTO (R_MIPS_GPREL32, /* type */
987 0, /* rightshift */
988 2, /* size (0 = byte, 1 = short, 2 = long) */
989 32, /* bitsize */
990 FALSE, /* pc_relative */
991 0, /* bitpos */
992 complain_overflow_dont, /* complain_on_overflow */
993 mips_elf64_gprel32_reloc, /* special_function */
994 "R_MIPS_GPREL32", /* name */
995 FALSE, /* partial_inplace */
996 0, /* src_mask */
997 0xffffffff, /* dst_mask */
998 FALSE), /* pcrel_offset */
999
1000 EMPTY_HOWTO (13),
1001 EMPTY_HOWTO (14),
1002 EMPTY_HOWTO (15),
1003
1004 /* A 5 bit shift field. */
1005 HOWTO (R_MIPS_SHIFT5, /* type */
1006 0, /* rightshift */
1007 2, /* size (0 = byte, 1 = short, 2 = long) */
1008 5, /* bitsize */
1009 FALSE, /* pc_relative */
1010 6, /* bitpos */
1011 complain_overflow_bitfield, /* complain_on_overflow */
1012 _bfd_mips_elf_generic_reloc, /* special_function */
1013 "R_MIPS_SHIFT5", /* name */
1014 FALSE, /* partial_inplace */
1015 0, /* src_mask */
1016 0x000007c0, /* dst_mask */
1017 FALSE), /* pcrel_offset */
1018
1019 /* A 6 bit shift field. */
1020 HOWTO (R_MIPS_SHIFT6, /* type */
1021 0, /* rightshift */
1022 2, /* size (0 = byte, 1 = short, 2 = long) */
1023 6, /* bitsize */
1024 FALSE, /* pc_relative */
1025 6, /* bitpos */
1026 complain_overflow_bitfield, /* complain_on_overflow */
1027 mips_elf64_shift6_reloc, /* special_function */
1028 "R_MIPS_SHIFT6", /* name */
1029 FALSE, /* partial_inplace */
1030 0, /* src_mask */
1031 0x000007c4, /* dst_mask */
1032 FALSE), /* pcrel_offset */
1033
1034 /* 64 bit relocation. */
1035 HOWTO (R_MIPS_64, /* type */
1036 0, /* rightshift */
1037 4, /* size (0 = byte, 1 = short, 2 = long) */
1038 64, /* bitsize */
1039 FALSE, /* pc_relative */
1040 0, /* bitpos */
1041 complain_overflow_dont, /* complain_on_overflow */
1042 _bfd_mips_elf_generic_reloc, /* special_function */
1043 "R_MIPS_64", /* name */
1044 FALSE, /* partial_inplace */
1045 0, /* src_mask */
1046 MINUS_ONE, /* dst_mask */
1047 FALSE), /* pcrel_offset */
1048
1049 /* Displacement in the global offset table. */
1050 HOWTO (R_MIPS_GOT_DISP, /* type */
1051 0, /* rightshift */
1052 2, /* size (0 = byte, 1 = short, 2 = long) */
1053 16, /* bitsize */
1054 FALSE, /* pc_relative */
1055 0, /* bitpos */
1056 complain_overflow_signed, /* complain_on_overflow */
1057 _bfd_mips_elf_generic_reloc, /* special_function */
1058 "R_MIPS_GOT_DISP", /* name */
1059 FALSE, /* partial_inplace */
1060 0, /* src_mask */
1061 0x0000ffff, /* dst_mask */
1062 FALSE), /* pcrel_offset */
1063
1064 /* Displacement to page pointer in the global offset table. */
1065 HOWTO (R_MIPS_GOT_PAGE, /* 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_PAGE", /* name */
1074 FALSE, /* partial_inplace */
1075 0, /* src_mask */
1076 0x0000ffff, /* dst_mask */
1077 FALSE), /* pcrel_offset */
1078
1079 /* Offset from page pointer in the global offset table. */
1080 HOWTO (R_MIPS_GOT_OFST, /* 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_OFST", /* name */
1089 FALSE, /* partial_inplace */
1090 0, /* src_mask */
1091 0x0000ffff, /* dst_mask */
1092 FALSE), /* pcrel_offset */
1093
1094 /* High 16 bits of displacement in global offset table. */
1095 HOWTO (R_MIPS_GOT_HI16, /* 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_dont, /* complain_on_overflow */
1102 _bfd_mips_elf_generic_reloc, /* special_function */
1103 "R_MIPS_GOT_HI16", /* name */
1104 FALSE, /* partial_inplace */
1105 0, /* src_mask */
1106 0x0000ffff, /* dst_mask */
1107 FALSE), /* pcrel_offset */
1108
1109 /* Low 16 bits of displacement in global offset table. */
1110 HOWTO (R_MIPS_GOT_LO16, /* 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_LO16", /* name */
1119 FALSE, /* partial_inplace */
1120 0, /* src_mask */
1121 0x0000ffff, /* dst_mask */
1122 FALSE), /* pcrel_offset */
1123
1124 /* 64 bit subtraction. */
1125 HOWTO (R_MIPS_SUB, /* type */
1126 0, /* rightshift */
1127 4, /* size (0 = byte, 1 = short, 2 = long) */
1128 64, /* 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_SUB", /* name */
1134 FALSE, /* partial_inplace */
1135 0, /* src_mask */
1136 MINUS_ONE, /* dst_mask */
1137 FALSE), /* pcrel_offset */
1138
1139 /* Insert the addend as an instruction. */
1140 /* FIXME: Not handled correctly. */
1141 HOWTO (R_MIPS_INSERT_A, /* type */
1142 0, /* rightshift */
1143 2, /* size (0 = byte, 1 = short, 2 = long) */
1144 32, /* bitsize */
1145 FALSE, /* pc_relative */
1146 0, /* bitpos */
1147 complain_overflow_dont, /* complain_on_overflow */
1148 _bfd_mips_elf_generic_reloc, /* special_function */
1149 "R_MIPS_INSERT_A", /* name */
1150 FALSE, /* partial_inplace */
1151 0, /* src_mask */
1152 0xffffffff, /* dst_mask */
1153 FALSE), /* pcrel_offset */
1154
1155 /* Insert the addend as an instruction, and change all relocations
1156 to refer to the old instruction at the address. */
1157 /* FIXME: Not handled correctly. */
1158 HOWTO (R_MIPS_INSERT_B, /* type */
1159 0, /* rightshift */
1160 2, /* size (0 = byte, 1 = short, 2 = long) */
1161 32, /* bitsize */
1162 FALSE, /* pc_relative */
1163 0, /* bitpos */
1164 complain_overflow_dont, /* complain_on_overflow */
1165 _bfd_mips_elf_generic_reloc, /* special_function */
1166 "R_MIPS_INSERT_B", /* name */
1167 FALSE, /* partial_inplace */
1168 0, /* src_mask */
1169 0xffffffff, /* dst_mask */
1170 FALSE), /* pcrel_offset */
1171
1172 /* Delete a 32 bit instruction. */
1173 /* FIXME: Not handled correctly. */
1174 HOWTO (R_MIPS_DELETE, /* type */
1175 0, /* rightshift */
1176 2, /* size (0 = byte, 1 = short, 2 = long) */
1177 32, /* bitsize */
1178 FALSE, /* pc_relative */
1179 0, /* bitpos */
1180 complain_overflow_dont, /* complain_on_overflow */
1181 _bfd_mips_elf_generic_reloc, /* special_function */
1182 "R_MIPS_DELETE", /* name */
1183 FALSE, /* partial_inplace */
1184 0, /* src_mask */
1185 0xffffffff, /* dst_mask */
1186 FALSE), /* pcrel_offset */
1187
1188 /* Get the higher value of a 64 bit addend. */
1189 HOWTO (R_MIPS_HIGHER, /* type */
1190 0, /* rightshift */
1191 2, /* size (0 = byte, 1 = short, 2 = long) */
1192 16, /* 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_HIGHER", /* name */
1198 FALSE, /* partial_inplace */
1199 0, /* src_mask */
1200 0x0000ffff, /* dst_mask */
1201 FALSE), /* pcrel_offset */
1202
1203 /* Get the highest value of a 64 bit addend. */
1204 HOWTO (R_MIPS_HIGHEST, /* 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_HIGHEST", /* name */
1213 FALSE, /* partial_inplace */
1214 0, /* src_mask */
1215 0x0000ffff, /* dst_mask */
1216 FALSE), /* pcrel_offset */
1217
1218 /* High 16 bits of displacement in global offset table. */
1219 HOWTO (R_MIPS_CALL_HI16, /* 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_CALL_HI16", /* name */
1228 FALSE, /* partial_inplace */
1229 0, /* src_mask */
1230 0x0000ffff, /* dst_mask */
1231 FALSE), /* pcrel_offset */
1232
1233 /* Low 16 bits of displacement in global offset table. */
1234 HOWTO (R_MIPS_CALL_LO16, /* 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_LO16", /* name */
1243 FALSE, /* partial_inplace */
1244 0, /* src_mask */
1245 0x0000ffff, /* dst_mask */
1246 FALSE), /* pcrel_offset */
1247
1248 /* Section displacement, used by an associated event location section. */
1249 HOWTO (R_MIPS_SCN_DISP, /* type */
1250 0, /* rightshift */
1251 2, /* size (0 = byte, 1 = short, 2 = long) */
1252 32, /* 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_SCN_DISP", /* name */
1258 FALSE, /* partial_inplace */
1259 0, /* src_mask */
1260 0xffffffff, /* dst_mask */
1261 FALSE), /* pcrel_offset */
1262
1263 HOWTO (R_MIPS_REL16, /* type */
1264 0, /* rightshift */
1265 1, /* size (0 = byte, 1 = short, 2 = long) */
1266 16, /* bitsize */
1267 FALSE, /* pc_relative */
1268 0, /* bitpos */
1269 complain_overflow_signed, /* complain_on_overflow */
1270 _bfd_mips_elf_generic_reloc, /* special_function */
1271 "R_MIPS_REL16", /* name */
1272 FALSE, /* partial_inplace */
1273 0, /* src_mask */
1274 0xffff, /* dst_mask */
1275 FALSE), /* pcrel_offset */
1276
1277 /* These two are obsolete. */
1278 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1279 EMPTY_HOWTO (R_MIPS_PJUMP),
1280
1281 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1282 It must be used for multigot GOT's (and only there). */
1283 HOWTO (R_MIPS_RELGOT, /* type */
1284 0, /* rightshift */
1285 2, /* size (0 = byte, 1 = short, 2 = long) */
1286 32, /* bitsize */
1287 FALSE, /* pc_relative */
1288 0, /* bitpos */
1289 complain_overflow_dont, /* complain_on_overflow */
1290 _bfd_mips_elf_generic_reloc, /* special_function */
1291 "R_MIPS_RELGOT", /* name */
1292 FALSE, /* partial_inplace */
1293 0, /* src_mask */
1294 0xffffffff, /* dst_mask */
1295 FALSE), /* pcrel_offset */
1296
1297 /* Protected jump conversion. This is an optimization hint. No
1298 relocation is required for correctness. */
1299 HOWTO (R_MIPS_JALR, /* type */
1300 0, /* rightshift */
1301 2, /* size (0 = byte, 1 = short, 2 = long) */
1302 32, /* bitsize */
1303 FALSE, /* pc_relative */
1304 0, /* bitpos */
1305 complain_overflow_dont, /* complain_on_overflow */
1306 _bfd_mips_elf_generic_reloc, /* special_function */
1307 "R_MIPS_JALR", /* name */
1308 FALSE, /* partial_inplace */
1309 0, /* src_mask */
1310 0x00000000, /* dst_mask */
1311 FALSE), /* pcrel_offset */
1312
1313 /* TLS relocations. */
1314 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
1315 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
1316 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
1317 EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
1318
1319 /* TLS general dynamic variable reference. */
1320 HOWTO (R_MIPS_TLS_GD, /* type */
1321 0, /* rightshift */
1322 2, /* size (0 = byte, 1 = short, 2 = long) */
1323 16, /* bitsize */
1324 FALSE, /* pc_relative */
1325 0, /* bitpos */
1326 complain_overflow_signed, /* complain_on_overflow */
1327 _bfd_mips_elf_generic_reloc, /* special_function */
1328 "R_MIPS_TLS_GD", /* name */
1329 TRUE, /* partial_inplace */
1330 0x0000ffff, /* src_mask */
1331 0x0000ffff, /* dst_mask */
1332 FALSE), /* pcrel_offset */
1333
1334 /* TLS local dynamic variable reference. */
1335 HOWTO (R_MIPS_TLS_LDM, /* type */
1336 0, /* rightshift */
1337 2, /* size (0 = byte, 1 = short, 2 = long) */
1338 16, /* bitsize */
1339 FALSE, /* pc_relative */
1340 0, /* bitpos */
1341 complain_overflow_signed, /* complain_on_overflow */
1342 _bfd_mips_elf_generic_reloc, /* special_function */
1343 "R_MIPS_TLS_LDM", /* name */
1344 TRUE, /* partial_inplace */
1345 0x0000ffff, /* src_mask */
1346 0x0000ffff, /* dst_mask */
1347 FALSE), /* pcrel_offset */
1348
1349 /* TLS local dynamic offset. */
1350 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
1351 0, /* rightshift */
1352 2, /* size (0 = byte, 1 = short, 2 = long) */
1353 16, /* bitsize */
1354 FALSE, /* pc_relative */
1355 0, /* bitpos */
1356 complain_overflow_signed, /* complain_on_overflow */
1357 _bfd_mips_elf_generic_reloc, /* special_function */
1358 "R_MIPS_TLS_DTPREL_HI16", /* name */
1359 TRUE, /* partial_inplace */
1360 0x0000ffff, /* src_mask */
1361 0x0000ffff, /* dst_mask */
1362 FALSE), /* pcrel_offset */
1363
1364 /* TLS local dynamic offset. */
1365 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
1366 0, /* rightshift */
1367 2, /* size (0 = byte, 1 = short, 2 = long) */
1368 16, /* bitsize */
1369 FALSE, /* pc_relative */
1370 0, /* bitpos */
1371 complain_overflow_signed, /* complain_on_overflow */
1372 _bfd_mips_elf_generic_reloc, /* special_function */
1373 "R_MIPS_TLS_DTPREL_LO16", /* name */
1374 TRUE, /* partial_inplace */
1375 0x0000ffff, /* src_mask */
1376 0x0000ffff, /* dst_mask */
1377 FALSE), /* pcrel_offset */
1378
1379 /* TLS thread pointer offset. */
1380 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
1381 0, /* rightshift */
1382 2, /* size (0 = byte, 1 = short, 2 = long) */
1383 16, /* bitsize */
1384 FALSE, /* pc_relative */
1385 0, /* bitpos */
1386 complain_overflow_signed, /* complain_on_overflow */
1387 _bfd_mips_elf_generic_reloc, /* special_function */
1388 "R_MIPS_TLS_GOTTPREL", /* name */
1389 TRUE, /* partial_inplace */
1390 0x0000ffff, /* src_mask */
1391 0x0000ffff, /* dst_mask */
1392 FALSE), /* pcrel_offset */
1393
1394 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
1395 EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
1396
1397 /* TLS thread pointer offset. */
1398 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
1399 0, /* rightshift */
1400 2, /* size (0 = byte, 1 = short, 2 = long) */
1401 16, /* bitsize */
1402 FALSE, /* pc_relative */
1403 0, /* bitpos */
1404 complain_overflow_signed, /* complain_on_overflow */
1405 _bfd_mips_elf_generic_reloc, /* special_function */
1406 "R_MIPS_TLS_TPREL_HI16", /* name */
1407 TRUE, /* partial_inplace */
1408 0x0000ffff, /* src_mask */
1409 0x0000ffff, /* dst_mask */
1410 FALSE), /* pcrel_offset */
1411
1412 /* TLS thread pointer offset. */
1413 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
1414 0, /* rightshift */
1415 2, /* size (0 = byte, 1 = short, 2 = long) */
1416 16, /* bitsize */
1417 FALSE, /* pc_relative */
1418 0, /* bitpos */
1419 complain_overflow_signed, /* complain_on_overflow */
1420 _bfd_mips_elf_generic_reloc, /* special_function */
1421 "R_MIPS_TLS_TPREL_LO16", /* name */
1422 TRUE, /* partial_inplace */
1423 0x0000ffff, /* src_mask */
1424 0x0000ffff, /* dst_mask */
1425 FALSE), /* pcrel_offset */
1426 };
1427
1428 static reloc_howto_type mips16_elf64_howto_table_rel[] =
1429 {
1430 /* The reloc used for the mips16 jump instruction. */
1431 HOWTO (R_MIPS16_26, /* type */
1432 2, /* rightshift */
1433 2, /* size (0 = byte, 1 = short, 2 = long) */
1434 26, /* bitsize */
1435 FALSE, /* pc_relative */
1436 0, /* bitpos */
1437 complain_overflow_dont, /* complain_on_overflow */
1438 /* This needs complex overflow
1439 detection, because the upper four
1440 bits must match the PC. */
1441 mips16_jump_reloc, /* special_function */
1442 "R_MIPS16_26", /* name */
1443 TRUE, /* partial_inplace */
1444 0x3ffffff, /* src_mask */
1445 0x3ffffff, /* dst_mask */
1446 FALSE), /* pcrel_offset */
1447
1448 /* The reloc used for the mips16 gprel instruction. */
1449 HOWTO (R_MIPS16_GPREL, /* type */
1450 0, /* rightshift */
1451 2, /* size (0 = byte, 1 = short, 2 = long) */
1452 16, /* bitsize */
1453 FALSE, /* pc_relative */
1454 0, /* bitpos */
1455 complain_overflow_signed, /* complain_on_overflow */
1456 mips16_gprel_reloc, /* special_function */
1457 "R_MIPS16_GPREL", /* name */
1458 TRUE, /* partial_inplace */
1459 0x0000ffff, /* src_mask */
1460 0x0000ffff, /* dst_mask */
1461 FALSE), /* pcrel_offset */
1462
1463 /* A placeholder for MIPS16 reference to global offset table. */
1464 EMPTY_HOWTO (R_MIPS16_GOT16),
1465
1466 /* A placeholder for MIPS16 16 bit call through global offset table. */
1467 EMPTY_HOWTO (R_MIPS16_CALL16),
1468
1469 /* MIPS16 high 16 bits of symbol value. */
1470 HOWTO (R_MIPS16_HI16, /* type */
1471 16, /* rightshift */
1472 2, /* size (0 = byte, 1 = short, 2 = long) */
1473 16, /* bitsize */
1474 FALSE, /* pc_relative */
1475 0, /* bitpos */
1476 complain_overflow_dont, /* complain_on_overflow */
1477 _bfd_mips_elf_hi16_reloc, /* special_function */
1478 "R_MIPS16_HI16", /* name */
1479 TRUE, /* partial_inplace */
1480 0x0000ffff, /* src_mask */
1481 0x0000ffff, /* dst_mask */
1482 FALSE), /* pcrel_offset */
1483
1484 /* MIPS16 low 16 bits of symbol value. */
1485 HOWTO (R_MIPS16_LO16, /* type */
1486 0, /* rightshift */
1487 2, /* size (0 = byte, 1 = short, 2 = long) */
1488 16, /* bitsize */
1489 FALSE, /* pc_relative */
1490 0, /* bitpos */
1491 complain_overflow_dont, /* complain_on_overflow */
1492 _bfd_mips_elf_lo16_reloc, /* special_function */
1493 "R_MIPS16_LO16", /* name */
1494 TRUE, /* partial_inplace */
1495 0x0000ffff, /* src_mask */
1496 0x0000ffff, /* dst_mask */
1497 FALSE), /* pcrel_offset */
1498 };
1499
1500 static reloc_howto_type mips16_elf64_howto_table_rela[] =
1501 {
1502 /* The reloc used for the mips16 jump instruction. */
1503 HOWTO (R_MIPS16_26, /* type */
1504 2, /* rightshift */
1505 2, /* size (0 = byte, 1 = short, 2 = long) */
1506 26, /* bitsize */
1507 FALSE, /* pc_relative */
1508 0, /* bitpos */
1509 complain_overflow_dont, /* complain_on_overflow */
1510 /* This needs complex overflow
1511 detection, because the upper four
1512 bits must match the PC. */
1513 mips16_jump_reloc, /* special_function */
1514 "R_MIPS16_26", /* name */
1515 FALSE, /* partial_inplace */
1516 0x3ffffff, /* src_mask */
1517 0x3ffffff, /* dst_mask */
1518 FALSE), /* pcrel_offset */
1519
1520 /* The reloc used for the mips16 gprel instruction. */
1521 HOWTO (R_MIPS16_GPREL, /* type */
1522 0, /* rightshift */
1523 2, /* size (0 = byte, 1 = short, 2 = long) */
1524 16, /* bitsize */
1525 FALSE, /* pc_relative */
1526 0, /* bitpos */
1527 complain_overflow_signed, /* complain_on_overflow */
1528 mips16_gprel_reloc, /* special_function */
1529 "R_MIPS16_GPREL", /* name */
1530 FALSE, /* partial_inplace */
1531 0x0000ffff, /* src_mask */
1532 0x0000ffff, /* dst_mask */
1533 FALSE), /* pcrel_offset */
1534
1535 /* A placeholder for MIPS16 reference to global offset table. */
1536 EMPTY_HOWTO (R_MIPS16_GOT16),
1537
1538 /* A placeholder for MIPS16 16 bit call through global offset table. */
1539 EMPTY_HOWTO (R_MIPS16_CALL16),
1540
1541 /* MIPS16 high 16 bits of symbol value. */
1542 HOWTO (R_MIPS16_HI16, /* type */
1543 16, /* rightshift */
1544 2, /* size (0 = byte, 1 = short, 2 = long) */
1545 16, /* bitsize */
1546 FALSE, /* pc_relative */
1547 0, /* bitpos */
1548 complain_overflow_dont, /* complain_on_overflow */
1549 _bfd_mips_elf_hi16_reloc, /* special_function */
1550 "R_MIPS16_HI16", /* name */
1551 FALSE, /* partial_inplace */
1552 0x0000ffff, /* src_mask */
1553 0x0000ffff, /* dst_mask */
1554 FALSE), /* pcrel_offset */
1555
1556 /* MIPS16 low 16 bits of symbol value. */
1557 HOWTO (R_MIPS16_LO16, /* type */
1558 0, /* rightshift */
1559 2, /* size (0 = byte, 1 = short, 2 = long) */
1560 16, /* bitsize */
1561 FALSE, /* pc_relative */
1562 0, /* bitpos */
1563 complain_overflow_dont, /* complain_on_overflow */
1564 _bfd_mips_elf_lo16_reloc, /* special_function */
1565 "R_MIPS16_LO16", /* name */
1566 FALSE, /* partial_inplace */
1567 0x0000ffff, /* src_mask */
1568 0x0000ffff, /* dst_mask */
1569 FALSE), /* pcrel_offset */
1570 };
1571
1572 /* GNU extension to record C++ vtable hierarchy */
1573 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
1574 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
1575 0, /* rightshift */
1576 2, /* size (0 = byte, 1 = short, 2 = long) */
1577 0, /* bitsize */
1578 FALSE, /* pc_relative */
1579 0, /* bitpos */
1580 complain_overflow_dont, /* complain_on_overflow */
1581 NULL, /* special_function */
1582 "R_MIPS_GNU_VTINHERIT", /* name */
1583 FALSE, /* partial_inplace */
1584 0, /* src_mask */
1585 0, /* dst_mask */
1586 FALSE); /* pcrel_offset */
1587
1588 /* GNU extension to record C++ vtable member usage */
1589 static reloc_howto_type elf_mips_gnu_vtentry_howto =
1590 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
1591 0, /* rightshift */
1592 2, /* size (0 = byte, 1 = short, 2 = long) */
1593 0, /* bitsize */
1594 FALSE, /* pc_relative */
1595 0, /* bitpos */
1596 complain_overflow_dont, /* complain_on_overflow */
1597 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1598 "R_MIPS_GNU_VTENTRY", /* name */
1599 FALSE, /* partial_inplace */
1600 0, /* src_mask */
1601 0, /* dst_mask */
1602 FALSE); /* pcrel_offset */
1603
1604 /* 16 bit offset for pc-relative branches. */
1605 static reloc_howto_type elf_mips_gnu_rel16_s2 =
1606 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
1607 2, /* rightshift */
1608 2, /* size (0 = byte, 1 = short, 2 = long) */
1609 16, /* bitsize */
1610 TRUE, /* pc_relative */
1611 0, /* bitpos */
1612 complain_overflow_signed, /* complain_on_overflow */
1613 _bfd_mips_elf_generic_reloc, /* special_function */
1614 "R_MIPS_GNU_REL16_S2", /* name */
1615 TRUE, /* partial_inplace */
1616 0x0000ffff, /* src_mask */
1617 0x0000ffff, /* dst_mask */
1618 TRUE); /* pcrel_offset */
1619
1620 /* 16 bit offset for pc-relative branches. */
1621 static reloc_howto_type elf_mips_gnu_rela16_s2 =
1622 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
1623 2, /* rightshift */
1624 2, /* size (0 = byte, 1 = short, 2 = long) */
1625 16, /* bitsize */
1626 TRUE, /* pc_relative */
1627 0, /* bitpos */
1628 complain_overflow_signed, /* complain_on_overflow */
1629 _bfd_mips_elf_generic_reloc, /* special_function */
1630 "R_MIPS_GNU_REL16_S2", /* name */
1631 FALSE, /* partial_inplace */
1632 0, /* src_mask */
1633 0x0000ffff, /* dst_mask */
1634 TRUE); /* pcrel_offset */
1635
1636 /* 32 bit pc-relative. */
1637 static reloc_howto_type elf_mips_gnu_pcrel32 =
1638 HOWTO (R_MIPS_PC32, /* type */
1639 0, /* rightshift */
1640 2, /* size (0 = byte, 1 = short, 2 = long) */
1641 32, /* bitsize */
1642 TRUE, /* pc_relative */
1643 0, /* bitpos */
1644 complain_overflow_signed, /* complain_on_overflow */
1645 _bfd_mips_elf_generic_reloc, /* special_function */
1646 "R_MIPS_PC32", /* name */
1647 TRUE, /* partial_inplace */
1648 0xffffffff, /* src_mask */
1649 0xffffffff, /* dst_mask */
1650 TRUE); /* pcrel_offset */
1651
1652 /* Swap in a MIPS 64-bit Rel reloc. */
1653
1654 static void
mips_elf64_swap_reloc_in(bfd * abfd,const Elf64_Mips_External_Rel * src,Elf64_Mips_Internal_Rela * dst)1655 mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src,
1656 Elf64_Mips_Internal_Rela *dst)
1657 {
1658 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1659 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1660 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1661 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1662 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1663 dst->r_type = H_GET_8 (abfd, src->r_type);
1664 dst->r_addend = 0;
1665 }
1666
1667 /* Swap in a MIPS 64-bit Rela reloc. */
1668
1669 static void
mips_elf64_swap_reloca_in(bfd * abfd,const Elf64_Mips_External_Rela * src,Elf64_Mips_Internal_Rela * dst)1670 mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src,
1671 Elf64_Mips_Internal_Rela *dst)
1672 {
1673 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1674 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1675 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1676 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1677 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1678 dst->r_type = H_GET_8 (abfd, src->r_type);
1679 dst->r_addend = H_GET_S64 (abfd, src->r_addend);
1680 }
1681
1682 /* Swap out a MIPS 64-bit Rel reloc. */
1683
1684 static void
mips_elf64_swap_reloc_out(bfd * abfd,const Elf64_Mips_Internal_Rela * src,Elf64_Mips_External_Rel * dst)1685 mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1686 Elf64_Mips_External_Rel *dst)
1687 {
1688 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1689 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1690 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1691 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1692 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1693 H_PUT_8 (abfd, src->r_type, dst->r_type);
1694 }
1695
1696 /* Swap out a MIPS 64-bit Rela reloc. */
1697
1698 static void
mips_elf64_swap_reloca_out(bfd * abfd,const Elf64_Mips_Internal_Rela * src,Elf64_Mips_External_Rela * dst)1699 mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1700 Elf64_Mips_External_Rela *dst)
1701 {
1702 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1703 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1704 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1705 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1706 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1707 H_PUT_8 (abfd, src->r_type, dst->r_type);
1708 H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
1709 }
1710
1711 /* Swap in a MIPS 64-bit Rel reloc. */
1712
1713 static void
mips_elf64_be_swap_reloc_in(bfd * abfd,const bfd_byte * src,Elf_Internal_Rela * dst)1714 mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src,
1715 Elf_Internal_Rela *dst)
1716 {
1717 Elf64_Mips_Internal_Rela mirel;
1718
1719 mips_elf64_swap_reloc_in (abfd,
1720 (const Elf64_Mips_External_Rel *) src,
1721 &mirel);
1722
1723 dst[0].r_offset = mirel.r_offset;
1724 dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
1725 dst[0].r_addend = 0;
1726 dst[1].r_offset = mirel.r_offset;
1727 dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
1728 dst[1].r_addend = 0;
1729 dst[2].r_offset = mirel.r_offset;
1730 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
1731 dst[2].r_addend = 0;
1732 }
1733
1734 /* Swap in a MIPS 64-bit Rela reloc. */
1735
1736 static void
mips_elf64_be_swap_reloca_in(bfd * abfd,const bfd_byte * src,Elf_Internal_Rela * dst)1737 mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src,
1738 Elf_Internal_Rela *dst)
1739 {
1740 Elf64_Mips_Internal_Rela mirela;
1741
1742 mips_elf64_swap_reloca_in (abfd,
1743 (const Elf64_Mips_External_Rela *) src,
1744 &mirela);
1745
1746 dst[0].r_offset = mirela.r_offset;
1747 dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
1748 dst[0].r_addend = mirela.r_addend;
1749 dst[1].r_offset = mirela.r_offset;
1750 dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
1751 dst[1].r_addend = 0;
1752 dst[2].r_offset = mirela.r_offset;
1753 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
1754 dst[2].r_addend = 0;
1755 }
1756
1757 /* Swap out a MIPS 64-bit Rel reloc. */
1758
1759 static void
mips_elf64_be_swap_reloc_out(bfd * abfd,const Elf_Internal_Rela * src,bfd_byte * dst)1760 mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src,
1761 bfd_byte *dst)
1762 {
1763 Elf64_Mips_Internal_Rela mirel;
1764
1765 mirel.r_offset = src[0].r_offset;
1766 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1767
1768 mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1769 mirel.r_sym = ELF64_R_SYM (src[0].r_info);
1770 mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1771 mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1772 mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1773
1774 mips_elf64_swap_reloc_out (abfd, &mirel,
1775 (Elf64_Mips_External_Rel *) dst);
1776 }
1777
1778 /* Swap out a MIPS 64-bit Rela reloc. */
1779
1780 static void
mips_elf64_be_swap_reloca_out(bfd * abfd,const Elf_Internal_Rela * src,bfd_byte * dst)1781 mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
1782 bfd_byte *dst)
1783 {
1784 Elf64_Mips_Internal_Rela mirela;
1785
1786 mirela.r_offset = src[0].r_offset;
1787 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1788 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
1789
1790 mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1791 mirela.r_sym = ELF64_R_SYM (src[0].r_info);
1792 mirela.r_addend = src[0].r_addend;
1793 BFD_ASSERT(src[1].r_addend == 0);
1794 BFD_ASSERT(src[2].r_addend == 0);
1795
1796 mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1797 mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1798 mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1799
1800 mips_elf64_swap_reloca_out (abfd, &mirela,
1801 (Elf64_Mips_External_Rela *) dst);
1802 }
1803
1804 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1805 dangerous relocation. */
1806
1807 static bfd_boolean
mips_elf64_assign_gp(bfd * output_bfd,bfd_vma * pgp)1808 mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp)
1809 {
1810 unsigned int count;
1811 asymbol **sym;
1812 unsigned int i;
1813
1814 /* If we've already figured out what GP will be, just return it. */
1815 *pgp = _bfd_get_gp_value (output_bfd);
1816 if (*pgp)
1817 return TRUE;
1818
1819 count = bfd_get_symcount (output_bfd);
1820 sym = bfd_get_outsymbols (output_bfd);
1821
1822 /* The linker script will have created a symbol named `_gp' with the
1823 appropriate value. */
1824 if (sym == NULL)
1825 i = count;
1826 else
1827 {
1828 for (i = 0; i < count; i++, sym++)
1829 {
1830 register const char *name;
1831
1832 name = bfd_asymbol_name (*sym);
1833 if (*name == '_' && strcmp (name, "_gp") == 0)
1834 {
1835 *pgp = bfd_asymbol_value (*sym);
1836 _bfd_set_gp_value (output_bfd, *pgp);
1837 break;
1838 }
1839 }
1840 }
1841
1842 if (i >= count)
1843 {
1844 /* Only get the error once. */
1845 *pgp = 4;
1846 _bfd_set_gp_value (output_bfd, *pgp);
1847 return FALSE;
1848 }
1849
1850 return TRUE;
1851 }
1852
1853 /* We have to figure out the gp value, so that we can adjust the
1854 symbol value correctly. We look up the symbol _gp in the output
1855 BFD. If we can't find it, we're stuck. We cache it in the ELF
1856 target data. We don't need to adjust the symbol value for an
1857 external symbol if we are producing relocatable output. */
1858
1859 static bfd_reloc_status_type
mips_elf64_final_gp(bfd * output_bfd,asymbol * symbol,bfd_boolean relocatable,char ** error_message,bfd_vma * pgp)1860 mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
1861 char **error_message, bfd_vma *pgp)
1862 {
1863 if (bfd_is_und_section (symbol->section)
1864 && ! relocatable)
1865 {
1866 *pgp = 0;
1867 return bfd_reloc_undefined;
1868 }
1869
1870 *pgp = _bfd_get_gp_value (output_bfd);
1871 if (*pgp == 0
1872 && (! relocatable
1873 || (symbol->flags & BSF_SECTION_SYM) != 0))
1874 {
1875 if (relocatable)
1876 {
1877 /* Make up a value. */
1878 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
1879 _bfd_set_gp_value (output_bfd, *pgp);
1880 }
1881 else if (!mips_elf64_assign_gp (output_bfd, pgp))
1882 {
1883 *error_message =
1884 (char *) _("GP relative relocation when _gp not defined");
1885 return bfd_reloc_dangerous;
1886 }
1887 }
1888
1889 return bfd_reloc_ok;
1890 }
1891
1892 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1893 become the offset from the gp register. */
1894
1895 static bfd_reloc_status_type
mips_elf64_gprel16_reloc(bfd * abfd,arelent * reloc_entry,asymbol * symbol,void * data,asection * input_section,bfd * output_bfd,char ** error_message)1896 mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1897 void *data, asection *input_section, bfd *output_bfd,
1898 char **error_message)
1899 {
1900 bfd_boolean relocatable;
1901 bfd_reloc_status_type ret;
1902 bfd_vma gp;
1903
1904 /* If we're relocating, and this is an external symbol, we don't want
1905 to change anything. */
1906 if (output_bfd != NULL
1907 && (symbol->flags & BSF_SECTION_SYM) == 0
1908 && (symbol->flags & BSF_LOCAL) != 0)
1909 {
1910 reloc_entry->address += input_section->output_offset;
1911 return bfd_reloc_ok;
1912 }
1913
1914 if (output_bfd != NULL)
1915 relocatable = TRUE;
1916 else
1917 {
1918 relocatable = FALSE;
1919 output_bfd = symbol->section->output_section->owner;
1920 }
1921
1922 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
1923 &gp);
1924 if (ret != bfd_reloc_ok)
1925 return ret;
1926
1927 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1928 input_section, relocatable,
1929 data, gp);
1930 }
1931
1932 /* Do a R_MIPS_LITERAL relocation. */
1933
1934 static bfd_reloc_status_type
mips_elf64_literal_reloc(bfd * abfd,arelent * reloc_entry,asymbol * symbol,void * data,asection * input_section,bfd * output_bfd,char ** error_message)1935 mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1936 void *data, asection *input_section, bfd *output_bfd,
1937 char **error_message)
1938 {
1939 bfd_boolean relocatable;
1940 bfd_reloc_status_type ret;
1941 bfd_vma gp;
1942
1943 /* R_MIPS_LITERAL relocations are defined for local symbols only. */
1944 if (output_bfd != NULL
1945 && (symbol->flags & BSF_SECTION_SYM) == 0
1946 && (symbol->flags & BSF_LOCAL) != 0)
1947 {
1948 *error_message = (char *)
1949 _("literal relocation occurs for an external symbol");
1950 return bfd_reloc_outofrange;
1951 }
1952
1953 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
1954 if (output_bfd != NULL)
1955 relocatable = TRUE;
1956 else
1957 {
1958 relocatable = FALSE;
1959 output_bfd = symbol->section->output_section->owner;
1960 }
1961
1962 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
1963 &gp);
1964 if (ret != bfd_reloc_ok)
1965 return ret;
1966
1967 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1968 input_section, relocatable,
1969 data, gp);
1970 }
1971
1972 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1973 become the offset from the gp register. */
1974
1975 static bfd_reloc_status_type
mips_elf64_gprel32_reloc(bfd * abfd,arelent * reloc_entry,asymbol * symbol,void * data,asection * input_section,bfd * output_bfd,char ** error_message)1976 mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1977 void *data, asection *input_section, bfd *output_bfd,
1978 char **error_message)
1979 {
1980 bfd_boolean relocatable;
1981 bfd_reloc_status_type ret;
1982 bfd_vma gp;
1983 bfd_vma relocation;
1984 bfd_vma val;
1985
1986 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
1987 if (output_bfd != NULL
1988 && (symbol->flags & BSF_SECTION_SYM) == 0
1989 && (symbol->flags & BSF_LOCAL) != 0)
1990 {
1991 *error_message = (char *)
1992 _("32bits gp relative relocation occurs for an external symbol");
1993 return bfd_reloc_outofrange;
1994 }
1995
1996 if (output_bfd != NULL)
1997 relocatable = TRUE;
1998 else
1999 {
2000 relocatable = FALSE;
2001 output_bfd = symbol->section->output_section->owner;
2002 }
2003
2004 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
2005 error_message, &gp);
2006 if (ret != bfd_reloc_ok)
2007 return ret;
2008
2009 if (bfd_is_com_section (symbol->section))
2010 relocation = 0;
2011 else
2012 relocation = symbol->value;
2013
2014 relocation += symbol->section->output_section->vma;
2015 relocation += symbol->section->output_offset;
2016
2017 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
2018 return bfd_reloc_outofrange;
2019
2020 /* Set val to the offset into the section or symbol. */
2021 val = reloc_entry->addend;
2022
2023 if (reloc_entry->howto->partial_inplace)
2024 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
2025
2026 /* Adjust val for the final section location and GP value. If we
2027 are producing relocatable output, we don't want to do this for
2028 an external symbol. */
2029 if (! relocatable
2030 || (symbol->flags & BSF_SECTION_SYM) != 0)
2031 val += relocation - gp;
2032
2033 if (reloc_entry->howto->partial_inplace)
2034 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
2035 else
2036 reloc_entry->addend = val;
2037
2038 if (relocatable)
2039 reloc_entry->address += input_section->output_offset;
2040
2041 return bfd_reloc_ok;
2042 }
2043
2044 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
2045 the rest is at bits 6-10. The bitpos already got right by the howto. */
2046
2047 static bfd_reloc_status_type
mips_elf64_shift6_reloc(bfd * abfd,arelent * reloc_entry,asymbol * symbol,void * data,asection * input_section,bfd * output_bfd,char ** error_message)2048 mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2049 void *data, asection *input_section, bfd *output_bfd,
2050 char **error_message)
2051 {
2052 if (reloc_entry->howto->partial_inplace)
2053 {
2054 reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
2055 | (reloc_entry->addend & 0x00000800) >> 9);
2056 }
2057
2058 return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
2059 input_section, output_bfd,
2060 error_message);
2061 }
2062
2063 /* Handle a mips16 jump. */
2064
2065 static bfd_reloc_status_type
mips16_jump_reloc(bfd * abfd ATTRIBUTE_UNUSED,arelent * reloc_entry,asymbol * symbol,void * data ATTRIBUTE_UNUSED,asection * input_section,bfd * output_bfd,char ** error_message ATTRIBUTE_UNUSED)2066 mips16_jump_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
2067 asymbol *symbol, void *data ATTRIBUTE_UNUSED,
2068 asection *input_section, bfd *output_bfd,
2069 char **error_message ATTRIBUTE_UNUSED)
2070 {
2071 if (output_bfd != NULL
2072 && (symbol->flags & BSF_SECTION_SYM) == 0
2073 && (! reloc_entry->howto->partial_inplace
2074 || reloc_entry->addend == 0))
2075 {
2076 reloc_entry->address += input_section->output_offset;
2077 return bfd_reloc_ok;
2078 }
2079
2080 /* FIXME. */
2081 {
2082 static bfd_boolean warned;
2083
2084 if (! warned)
2085 (*_bfd_error_handler)
2086 (_("Linking mips16 objects into %s format is not supported"),
2087 bfd_get_target (input_section->output_section->owner));
2088 warned = TRUE;
2089 }
2090
2091 return bfd_reloc_undefined;
2092 }
2093
2094 /* Handle a mips16 GP relative reloc. */
2095
2096 static bfd_reloc_status_type
mips16_gprel_reloc(bfd * abfd,arelent * reloc_entry,asymbol * symbol,void * data,asection * input_section,bfd * output_bfd,char ** error_message)2097 mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2098 void *data, asection *input_section, bfd *output_bfd,
2099 char **error_message)
2100 {
2101 bfd_boolean relocatable;
2102 bfd_reloc_status_type ret;
2103 bfd_byte *location;
2104 bfd_vma gp;
2105
2106 /* If we're relocating, and this is an external symbol, we don't want
2107 to change anything. */
2108 if (output_bfd != NULL
2109 && (symbol->flags & BSF_SECTION_SYM) == 0
2110 && (symbol->flags & BSF_LOCAL) != 0)
2111 {
2112 reloc_entry->address += input_section->output_offset;
2113 return bfd_reloc_ok;
2114 }
2115
2116 if (output_bfd != NULL)
2117 relocatable = TRUE;
2118 else
2119 {
2120 relocatable = FALSE;
2121 output_bfd = symbol->section->output_section->owner;
2122 }
2123
2124 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
2125 &gp);
2126 if (ret != bfd_reloc_ok)
2127 return ret;
2128
2129 location = (bfd_byte *) data + reloc_entry->address;
2130 _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
2131 location);
2132 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2133 input_section, relocatable,
2134 data, gp);
2135 _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
2136 location);
2137
2138 return ret;
2139 }
2140
2141 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
2142
2143 struct elf_reloc_map {
2144 bfd_reloc_code_real_type bfd_val;
2145 enum elf_mips_reloc_type elf_val;
2146 };
2147
2148 static const struct elf_reloc_map mips_reloc_map[] =
2149 {
2150 { BFD_RELOC_NONE, R_MIPS_NONE },
2151 { BFD_RELOC_16, R_MIPS_16 },
2152 { BFD_RELOC_32, R_MIPS_32 },
2153 /* There is no BFD reloc for R_MIPS_REL32. */
2154 { BFD_RELOC_64, R_MIPS_64 },
2155 { BFD_RELOC_CTOR, R_MIPS_64 },
2156 { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
2157 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
2158 { BFD_RELOC_LO16, R_MIPS_LO16 },
2159 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
2160 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
2161 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
2162 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
2163 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
2164 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
2165 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
2166 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
2167 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
2168 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
2169 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
2170 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
2171 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
2172 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
2173 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
2174 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
2175 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
2176 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
2177 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
2178 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
2179 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
2180 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
2181 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
2182 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
2183 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
2184 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
2185 { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
2186 { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
2187 { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
2188 { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
2189 { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
2190 { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
2191 { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
2192 { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
2193 { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
2194 { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
2195 { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
2196 { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
2197 { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
2198 };
2199
2200 static const struct elf_reloc_map mips16_reloc_map[] =
2201 {
2202 { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
2203 { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
2204 { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
2205 { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
2206 };
2207
2208 /* Given a BFD reloc type, return a howto structure. */
2209
2210 static reloc_howto_type *
bfd_elf64_bfd_reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)2211 bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
2212 bfd_reloc_code_real_type code)
2213 {
2214 unsigned int i;
2215 /* FIXME: We default to RELA here instead of choosing the right
2216 relocation variant. */
2217 reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
2218 reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela;
2219
2220 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
2221 i++)
2222 {
2223 if (mips_reloc_map[i].bfd_val == code)
2224 return &howto_table[(int) mips_reloc_map[i].elf_val];
2225 }
2226
2227 for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
2228 i++)
2229 {
2230 if (mips16_reloc_map[i].bfd_val == code)
2231 return &howto16_table[(int) mips16_reloc_map[i].elf_val];
2232 }
2233
2234 switch (code)
2235 {
2236 case BFD_RELOC_VTABLE_INHERIT:
2237 return &elf_mips_gnu_vtinherit_howto;
2238 case BFD_RELOC_VTABLE_ENTRY:
2239 return &elf_mips_gnu_vtentry_howto;
2240 case BFD_RELOC_32_PCREL:
2241 return &elf_mips_gnu_pcrel32;
2242 default:
2243 bfd_set_error (bfd_error_bad_value);
2244 return NULL;
2245 }
2246 }
2247
2248 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
2249
2250 static reloc_howto_type *
mips_elf64_rtype_to_howto(unsigned int r_type,bfd_boolean rela_p)2251 mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
2252 {
2253 switch (r_type)
2254 {
2255 case R_MIPS_GNU_VTINHERIT:
2256 return &elf_mips_gnu_vtinherit_howto;
2257 case R_MIPS_GNU_VTENTRY:
2258 return &elf_mips_gnu_vtentry_howto;
2259 case R_MIPS_GNU_REL16_S2:
2260 if (rela_p)
2261 return &elf_mips_gnu_rela16_s2;
2262 else
2263 return &elf_mips_gnu_rel16_s2;
2264 case R_MIPS_PC32:
2265 return &elf_mips_gnu_pcrel32;
2266 default:
2267 if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
2268 {
2269 if (rela_p)
2270 return &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min];
2271 else
2272 return &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min];
2273 }
2274 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
2275 if (rela_p)
2276 return &mips_elf64_howto_table_rela[r_type];
2277 else
2278 return &mips_elf64_howto_table_rel[r_type];
2279 break;
2280 }
2281 }
2282
2283 /* Prevent relocation handling by bfd for MIPS ELF64. */
2284
2285 static void
mips_elf64_info_to_howto_rel(bfd * abfd ATTRIBUTE_UNUSED,arelent * cache_ptr ATTRIBUTE_UNUSED,Elf_Internal_Rela * dst ATTRIBUTE_UNUSED)2286 mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
2287 arelent *cache_ptr ATTRIBUTE_UNUSED,
2288 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
2289 {
2290 BFD_ASSERT (0);
2291 }
2292
2293 static void
mips_elf64_info_to_howto_rela(bfd * abfd ATTRIBUTE_UNUSED,arelent * cache_ptr ATTRIBUTE_UNUSED,Elf_Internal_Rela * dst ATTRIBUTE_UNUSED)2294 mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
2295 arelent *cache_ptr ATTRIBUTE_UNUSED,
2296 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
2297 {
2298 BFD_ASSERT (0);
2299 }
2300
2301 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
2302 to three relocs, we must tell the user to allocate more space. */
2303
2304 static long
mips_elf64_get_reloc_upper_bound(bfd * abfd ATTRIBUTE_UNUSED,asection * sec)2305 mips_elf64_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
2306 {
2307 return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
2308 }
2309
2310 static long
mips_elf64_get_dynamic_reloc_upper_bound(bfd * abfd)2311 mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
2312 {
2313 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
2314 }
2315
2316 /* We must also copy more relocations than the corresponding functions
2317 in elf.c would, so the two following functions are slightly
2318 modified from elf.c, that multiply the external relocation count by
2319 3 to obtain the internal relocation count. */
2320
2321 static long
mips_elf64_canonicalize_reloc(bfd * abfd,sec_ptr section,arelent ** relptr,asymbol ** symbols)2322 mips_elf64_canonicalize_reloc (bfd *abfd, sec_ptr section,
2323 arelent **relptr, asymbol **symbols)
2324 {
2325 arelent *tblptr;
2326 unsigned int i;
2327 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
2328
2329 if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
2330 return -1;
2331
2332 tblptr = section->relocation;
2333 for (i = 0; i < section->reloc_count * 3; i++)
2334 *relptr++ = tblptr++;
2335
2336 *relptr = NULL;
2337
2338 return section->reloc_count * 3;
2339 }
2340
2341 static long
mips_elf64_canonicalize_dynamic_reloc(bfd * abfd,arelent ** storage,asymbol ** syms)2342 mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
2343 asymbol **syms)
2344 {
2345 bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
2346 asection *s;
2347 long ret;
2348
2349 if (elf_dynsymtab (abfd) == 0)
2350 {
2351 bfd_set_error (bfd_error_invalid_operation);
2352 return -1;
2353 }
2354
2355 slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
2356 ret = 0;
2357 for (s = abfd->sections; s != NULL; s = s->next)
2358 {
2359 if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
2360 && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
2361 || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
2362 {
2363 arelent *p;
2364 long count, i;
2365
2366 if (! (*slurp_relocs) (abfd, s, syms, TRUE))
2367 return -1;
2368 count = s->size / elf_section_data (s)->this_hdr.sh_entsize * 3;
2369 p = s->relocation;
2370 for (i = 0; i < count; i++)
2371 *storage++ = p++;
2372 ret += count;
2373 }
2374 }
2375
2376 *storage = NULL;
2377
2378 return ret;
2379 }
2380
2381 /* Read the relocations from one reloc section. This is mostly copied
2382 from elfcode.h, except for the changes to expand one external
2383 relocation to 3 internal ones. We must unfortunately set
2384 reloc_count to the number of external relocations, because a lot of
2385 generic code seems to depend on this. */
2386
2387 static bfd_boolean
mips_elf64_slurp_one_reloc_table(bfd * abfd,asection * asect,Elf_Internal_Shdr * rel_hdr,bfd_size_type reloc_count,arelent * relents,asymbol ** symbols,bfd_boolean dynamic)2388 mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
2389 Elf_Internal_Shdr *rel_hdr,
2390 bfd_size_type reloc_count,
2391 arelent *relents, asymbol **symbols,
2392 bfd_boolean dynamic)
2393 {
2394 void *allocated;
2395 bfd_byte *native_relocs;
2396 arelent *relent;
2397 bfd_vma i;
2398 int entsize;
2399 bfd_boolean rela_p;
2400
2401 allocated = bfd_malloc (rel_hdr->sh_size);
2402 if (allocated == NULL)
2403 return FALSE;
2404
2405 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
2406 || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
2407 != rel_hdr->sh_size))
2408 goto error_return;
2409
2410 native_relocs = allocated;
2411
2412 entsize = rel_hdr->sh_entsize;
2413 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
2414 || entsize == sizeof (Elf64_Mips_External_Rela));
2415
2416 if (entsize == sizeof (Elf64_Mips_External_Rel))
2417 rela_p = FALSE;
2418 else
2419 rela_p = TRUE;
2420
2421 for (i = 0, relent = relents;
2422 i < reloc_count;
2423 i++, native_relocs += entsize)
2424 {
2425 Elf64_Mips_Internal_Rela rela;
2426 bfd_boolean used_sym, used_ssym;
2427 int ir;
2428
2429 if (entsize == sizeof (Elf64_Mips_External_Rela))
2430 mips_elf64_swap_reloca_in (abfd,
2431 (Elf64_Mips_External_Rela *) native_relocs,
2432 &rela);
2433 else
2434 mips_elf64_swap_reloc_in (abfd,
2435 (Elf64_Mips_External_Rel *) native_relocs,
2436 &rela);
2437
2438 /* Each entry represents exactly three actual relocations. */
2439
2440 used_sym = FALSE;
2441 used_ssym = FALSE;
2442 for (ir = 0; ir < 3; ir++)
2443 {
2444 enum elf_mips_reloc_type type;
2445
2446 switch (ir)
2447 {
2448 default:
2449 abort ();
2450 case 0:
2451 type = (enum elf_mips_reloc_type) rela.r_type;
2452 break;
2453 case 1:
2454 type = (enum elf_mips_reloc_type) rela.r_type2;
2455 break;
2456 case 2:
2457 type = (enum elf_mips_reloc_type) rela.r_type3;
2458 break;
2459 }
2460
2461 /* Some types require symbols, whereas some do not. */
2462 switch (type)
2463 {
2464 case R_MIPS_NONE:
2465 case R_MIPS_LITERAL:
2466 case R_MIPS_INSERT_A:
2467 case R_MIPS_INSERT_B:
2468 case R_MIPS_DELETE:
2469 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2470 break;
2471
2472 default:
2473 if (! used_sym)
2474 {
2475 if (rela.r_sym == 0)
2476 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2477 else
2478 {
2479 asymbol **ps, *s;
2480
2481 ps = symbols + rela.r_sym - 1;
2482 s = *ps;
2483 if ((s->flags & BSF_SECTION_SYM) == 0)
2484 relent->sym_ptr_ptr = ps;
2485 else
2486 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
2487 }
2488
2489 used_sym = TRUE;
2490 }
2491 else if (! used_ssym)
2492 {
2493 switch (rela.r_ssym)
2494 {
2495 case RSS_UNDEF:
2496 relent->sym_ptr_ptr =
2497 bfd_abs_section_ptr->symbol_ptr_ptr;
2498 break;
2499
2500 case RSS_GP:
2501 case RSS_GP0:
2502 case RSS_LOC:
2503 /* FIXME: I think these need to be handled using
2504 special howto structures. */
2505 BFD_ASSERT (0);
2506 break;
2507
2508 default:
2509 BFD_ASSERT (0);
2510 break;
2511 }
2512
2513 used_ssym = TRUE;
2514 }
2515 else
2516 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2517
2518 break;
2519 }
2520
2521 /* The address of an ELF reloc is section relative for an
2522 object file, and absolute for an executable file or
2523 shared library. The address of a BFD reloc is always
2524 section relative. */
2525 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
2526 relent->address = rela.r_offset;
2527 else
2528 relent->address = rela.r_offset - asect->vma;
2529
2530 relent->addend = rela.r_addend;
2531
2532 relent->howto = mips_elf64_rtype_to_howto (type, rela_p);
2533
2534 ++relent;
2535 }
2536 }
2537
2538 asect->reloc_count += (relent - relents) / 3;
2539
2540 if (allocated != NULL)
2541 free (allocated);
2542
2543 return TRUE;
2544
2545 error_return:
2546 if (allocated != NULL)
2547 free (allocated);
2548 return FALSE;
2549 }
2550
2551 /* Read the relocations. On Irix 6, there can be two reloc sections
2552 associated with a single data section. This is copied from
2553 elfcode.h as well, with changes as small as accounting for 3
2554 internal relocs per external reloc and resetting reloc_count to
2555 zero before processing the relocs of a section. */
2556
2557 static bfd_boolean
mips_elf64_slurp_reloc_table(bfd * abfd,asection * asect,asymbol ** symbols,bfd_boolean dynamic)2558 mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
2559 asymbol **symbols, bfd_boolean dynamic)
2560 {
2561 struct bfd_elf_section_data * const d = elf_section_data (asect);
2562 Elf_Internal_Shdr *rel_hdr;
2563 Elf_Internal_Shdr *rel_hdr2;
2564 bfd_size_type reloc_count;
2565 bfd_size_type reloc_count2;
2566 arelent *relents;
2567 bfd_size_type amt;
2568
2569 if (asect->relocation != NULL)
2570 return TRUE;
2571
2572 if (! dynamic)
2573 {
2574 if ((asect->flags & SEC_RELOC) == 0
2575 || asect->reloc_count == 0)
2576 return TRUE;
2577
2578 rel_hdr = &d->rel_hdr;
2579 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2580 rel_hdr2 = d->rel_hdr2;
2581 reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
2582
2583 BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
2584 BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
2585 || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
2586
2587 }
2588 else
2589 {
2590 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
2591 case because relocations against this section may use the
2592 dynamic symbol table, and in that case bfd_section_from_shdr
2593 in elf.c does not update the RELOC_COUNT. */
2594 if (asect->size == 0)
2595 return TRUE;
2596
2597 rel_hdr = &d->this_hdr;
2598 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2599 rel_hdr2 = NULL;
2600 reloc_count2 = 0;
2601 }
2602
2603 /* Allocate space for 3 arelent structures for each Rel structure. */
2604 amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
2605 relents = bfd_alloc (abfd, amt);
2606 if (relents == NULL)
2607 return FALSE;
2608
2609 /* The slurp_one_reloc_table routine increments reloc_count. */
2610 asect->reloc_count = 0;
2611
2612 if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2613 rel_hdr, reloc_count,
2614 relents,
2615 symbols, dynamic))
2616 return FALSE;
2617 if (d->rel_hdr2 != NULL)
2618 {
2619 if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2620 rel_hdr2, reloc_count2,
2621 relents + reloc_count * 3,
2622 symbols, dynamic))
2623 return FALSE;
2624 }
2625
2626 asect->relocation = relents;
2627 return TRUE;
2628 }
2629
2630 /* Write out the relocations. */
2631
2632 static void
mips_elf64_write_relocs(bfd * abfd,asection * sec,void * data)2633 mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
2634 {
2635 bfd_boolean *failedp = data;
2636 int count;
2637 Elf_Internal_Shdr *rel_hdr;
2638 unsigned int idx;
2639
2640 /* If we have already failed, don't do anything. */
2641 if (*failedp)
2642 return;
2643
2644 if ((sec->flags & SEC_RELOC) == 0)
2645 return;
2646
2647 /* The linker backend writes the relocs out itself, and sets the
2648 reloc_count field to zero to inhibit writing them here. Also,
2649 sometimes the SEC_RELOC flag gets set even when there aren't any
2650 relocs. */
2651 if (sec->reloc_count == 0)
2652 return;
2653
2654 /* We can combine up to three relocs that refer to the same address
2655 if the latter relocs have no associated symbol. */
2656 count = 0;
2657 for (idx = 0; idx < sec->reloc_count; idx++)
2658 {
2659 bfd_vma addr;
2660 unsigned int i;
2661
2662 ++count;
2663
2664 addr = sec->orelocation[idx]->address;
2665 for (i = 0; i < 2; i++)
2666 {
2667 arelent *r;
2668
2669 if (idx + 1 >= sec->reloc_count)
2670 break;
2671 r = sec->orelocation[idx + 1];
2672 if (r->address != addr
2673 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2674 || (*r->sym_ptr_ptr)->value != 0)
2675 break;
2676
2677 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2678
2679 ++idx;
2680 }
2681 }
2682
2683 rel_hdr = &elf_section_data (sec)->rel_hdr;
2684
2685 /* Do the actual relocation. */
2686
2687 if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
2688 mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
2689 else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
2690 mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
2691 else
2692 BFD_ASSERT (0);
2693 }
2694
2695 static void
mips_elf64_write_rel(bfd * abfd,asection * sec,Elf_Internal_Shdr * rel_hdr,int * count,void * data)2696 mips_elf64_write_rel (bfd *abfd, asection *sec,
2697 Elf_Internal_Shdr *rel_hdr,
2698 int *count, void *data)
2699 {
2700 bfd_boolean *failedp = data;
2701 Elf64_Mips_External_Rel *ext_rel;
2702 unsigned int idx;
2703 asymbol *last_sym = 0;
2704 int last_sym_idx = 0;
2705
2706 rel_hdr->sh_size = rel_hdr->sh_entsize * *count;
2707 rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size);
2708 if (rel_hdr->contents == NULL)
2709 {
2710 *failedp = TRUE;
2711 return;
2712 }
2713
2714 ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
2715 for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
2716 {
2717 arelent *ptr;
2718 Elf64_Mips_Internal_Rela int_rel;
2719 asymbol *sym;
2720 int n;
2721 unsigned int i;
2722
2723 ptr = sec->orelocation[idx];
2724
2725 /* The address of an ELF reloc is section relative for an object
2726 file, and absolute for an executable file or shared library.
2727 The address of a BFD reloc is always section relative. */
2728 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2729 int_rel.r_offset = ptr->address;
2730 else
2731 int_rel.r_offset = ptr->address + sec->vma;
2732
2733 sym = *ptr->sym_ptr_ptr;
2734 if (sym == last_sym)
2735 n = last_sym_idx;
2736 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2737 n = STN_UNDEF;
2738 else
2739 {
2740 last_sym = sym;
2741 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2742 if (n < 0)
2743 {
2744 *failedp = TRUE;
2745 return;
2746 }
2747 last_sym_idx = n;
2748 }
2749
2750 int_rel.r_sym = n;
2751 int_rel.r_ssym = RSS_UNDEF;
2752
2753 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2754 && ! _bfd_elf_validate_reloc (abfd, ptr))
2755 {
2756 *failedp = TRUE;
2757 return;
2758 }
2759
2760 int_rel.r_type = ptr->howto->type;
2761 int_rel.r_type2 = (int) R_MIPS_NONE;
2762 int_rel.r_type3 = (int) R_MIPS_NONE;
2763
2764 for (i = 0; i < 2; i++)
2765 {
2766 arelent *r;
2767
2768 if (idx + 1 >= sec->reloc_count)
2769 break;
2770 r = sec->orelocation[idx + 1];
2771 if (r->address != ptr->address
2772 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2773 || (*r->sym_ptr_ptr)->value != 0)
2774 break;
2775
2776 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2777
2778 if (i == 0)
2779 int_rel.r_type2 = r->howto->type;
2780 else
2781 int_rel.r_type3 = r->howto->type;
2782
2783 ++idx;
2784 }
2785
2786 mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
2787 }
2788
2789 BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
2790 == *count);
2791 }
2792
2793 static void
mips_elf64_write_rela(bfd * abfd,asection * sec,Elf_Internal_Shdr * rela_hdr,int * count,void * data)2794 mips_elf64_write_rela (bfd *abfd, asection *sec,
2795 Elf_Internal_Shdr *rela_hdr,
2796 int *count, void *data)
2797 {
2798 bfd_boolean *failedp = data;
2799 Elf64_Mips_External_Rela *ext_rela;
2800 unsigned int idx;
2801 asymbol *last_sym = 0;
2802 int last_sym_idx = 0;
2803
2804 rela_hdr->sh_size = rela_hdr->sh_entsize * *count;
2805 rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
2806 if (rela_hdr->contents == NULL)
2807 {
2808 *failedp = TRUE;
2809 return;
2810 }
2811
2812 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
2813 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
2814 {
2815 arelent *ptr;
2816 Elf64_Mips_Internal_Rela int_rela;
2817 asymbol *sym;
2818 int n;
2819 unsigned int i;
2820
2821 ptr = sec->orelocation[idx];
2822
2823 /* The address of an ELF reloc is section relative for an object
2824 file, and absolute for an executable file or shared library.
2825 The address of a BFD reloc is always section relative. */
2826 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2827 int_rela.r_offset = ptr->address;
2828 else
2829 int_rela.r_offset = ptr->address + sec->vma;
2830
2831 sym = *ptr->sym_ptr_ptr;
2832 if (sym == last_sym)
2833 n = last_sym_idx;
2834 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2835 n = STN_UNDEF;
2836 else
2837 {
2838 last_sym = sym;
2839 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2840 if (n < 0)
2841 {
2842 *failedp = TRUE;
2843 return;
2844 }
2845 last_sym_idx = n;
2846 }
2847
2848 int_rela.r_sym = n;
2849 int_rela.r_addend = ptr->addend;
2850 int_rela.r_ssym = RSS_UNDEF;
2851
2852 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2853 && ! _bfd_elf_validate_reloc (abfd, ptr))
2854 {
2855 *failedp = TRUE;
2856 return;
2857 }
2858
2859 int_rela.r_type = ptr->howto->type;
2860 int_rela.r_type2 = (int) R_MIPS_NONE;
2861 int_rela.r_type3 = (int) R_MIPS_NONE;
2862
2863 for (i = 0; i < 2; i++)
2864 {
2865 arelent *r;
2866
2867 if (idx + 1 >= sec->reloc_count)
2868 break;
2869 r = sec->orelocation[idx + 1];
2870 if (r->address != ptr->address
2871 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2872 || (*r->sym_ptr_ptr)->value != 0)
2873 break;
2874
2875 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2876
2877 if (i == 0)
2878 int_rela.r_type2 = r->howto->type;
2879 else
2880 int_rela.r_type3 = r->howto->type;
2881
2882 ++idx;
2883 }
2884
2885 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
2886 }
2887
2888 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
2889 == *count);
2890 }
2891
2892 /* Set the right machine number for a MIPS ELF file. */
2893
2894 static bfd_boolean
mips_elf64_object_p(bfd * abfd)2895 mips_elf64_object_p (bfd *abfd)
2896 {
2897 unsigned long mach;
2898
2899 /* Irix 6 is broken. Object file symbol tables are not always
2900 sorted correctly such that local symbols precede global symbols,
2901 and the sh_info field in the symbol table is not always right. */
2902 if (elf64_mips_irix_compat (abfd) != ict_none)
2903 elf_bad_symtab (abfd) = TRUE;
2904
2905 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
2906 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
2907 return TRUE;
2908 }
2909
2910 /* Depending on the target vector we generate some version of Irix
2911 executables or "normal" MIPS ELF ABI executables. */
2912 static irix_compat_t
elf64_mips_irix_compat(bfd * abfd)2913 elf64_mips_irix_compat (bfd *abfd)
2914 {
2915 if ((abfd->xvec == &bfd_elf64_bigmips_vec)
2916 || (abfd->xvec == &bfd_elf64_littlemips_vec))
2917 return ict_irix6;
2918 else
2919 return ict_none;
2920 }
2921
2922 /* Support for core dump NOTE sections. */
2923 static bfd_boolean
elf64_mips_grok_prstatus(bfd * abfd,Elf_Internal_Note * note)2924 elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
2925 {
2926 int offset;
2927 unsigned int size;
2928
2929 switch (note->descsz)
2930 {
2931 default:
2932 return FALSE;
2933
2934 case 480: /* Linux/MIPS - N64 kernel */
2935 /* pr_cursig */
2936 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
2937
2938 /* pr_pid */
2939 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 32);
2940
2941 /* pr_reg */
2942 offset = 112;
2943 size = 360;
2944
2945 break;
2946 }
2947
2948 /* Make a ".reg/999" section. */
2949 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
2950 size, note->descpos + offset);
2951 }
2952
2953 static bfd_boolean
elf64_mips_grok_psinfo(bfd * abfd,Elf_Internal_Note * note)2954 elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
2955 {
2956 switch (note->descsz)
2957 {
2958 default:
2959 return FALSE;
2960
2961 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
2962 elf_tdata (abfd)->core_program
2963 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
2964 elf_tdata (abfd)->core_command
2965 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
2966 }
2967
2968 /* Note that for some reason, a spurious space is tacked
2969 onto the end of the args in some (at least one anyway)
2970 implementations, so strip it off if it exists. */
2971
2972 {
2973 char *command = elf_tdata (abfd)->core_command;
2974 int n = strlen (command);
2975
2976 if (0 < n && command[n - 1] == ' ')
2977 command[n - 1] = '\0';
2978 }
2979
2980 return TRUE;
2981 }
2982
2983 /* ECOFF swapping routines. These are used when dealing with the
2984 .mdebug section, which is in the ECOFF debugging format. */
2985 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
2986 {
2987 /* Symbol table magic number. */
2988 magicSym2,
2989 /* Alignment of debugging information. E.g., 4. */
2990 8,
2991 /* Sizes of external symbolic information. */
2992 sizeof (struct hdr_ext),
2993 sizeof (struct dnr_ext),
2994 sizeof (struct pdr_ext),
2995 sizeof (struct sym_ext),
2996 sizeof (struct opt_ext),
2997 sizeof (struct fdr_ext),
2998 sizeof (struct rfd_ext),
2999 sizeof (struct ext_ext),
3000 /* Functions to swap in external symbolic data. */
3001 ecoff_swap_hdr_in,
3002 ecoff_swap_dnr_in,
3003 ecoff_swap_pdr_in,
3004 ecoff_swap_sym_in,
3005 ecoff_swap_opt_in,
3006 ecoff_swap_fdr_in,
3007 ecoff_swap_rfd_in,
3008 ecoff_swap_ext_in,
3009 _bfd_ecoff_swap_tir_in,
3010 _bfd_ecoff_swap_rndx_in,
3011 /* Functions to swap out external symbolic data. */
3012 ecoff_swap_hdr_out,
3013 ecoff_swap_dnr_out,
3014 ecoff_swap_pdr_out,
3015 ecoff_swap_sym_out,
3016 ecoff_swap_opt_out,
3017 ecoff_swap_fdr_out,
3018 ecoff_swap_rfd_out,
3019 ecoff_swap_ext_out,
3020 _bfd_ecoff_swap_tir_out,
3021 _bfd_ecoff_swap_rndx_out,
3022 /* Function to read in symbolic data. */
3023 _bfd_mips_elf_read_ecoff_info
3024 };
3025
3026 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
3027 standard ELF. This structure is used to redirect the relocation
3028 handling routines. */
3029
3030 const struct elf_size_info mips_elf64_size_info =
3031 {
3032 sizeof (Elf64_External_Ehdr),
3033 sizeof (Elf64_External_Phdr),
3034 sizeof (Elf64_External_Shdr),
3035 sizeof (Elf64_Mips_External_Rel),
3036 sizeof (Elf64_Mips_External_Rela),
3037 sizeof (Elf64_External_Sym),
3038 sizeof (Elf64_External_Dyn),
3039 sizeof (Elf_External_Note),
3040 4, /* hash-table entry size */
3041 3, /* internal relocations per external relocations */
3042 64, /* arch_size */
3043 3, /* log_file_align */
3044 ELFCLASS64,
3045 EV_CURRENT,
3046 bfd_elf64_write_out_phdrs,
3047 bfd_elf64_write_shdrs_and_ehdr,
3048 mips_elf64_write_relocs,
3049 bfd_elf64_swap_symbol_in,
3050 bfd_elf64_swap_symbol_out,
3051 mips_elf64_slurp_reloc_table,
3052 bfd_elf64_slurp_symbol_table,
3053 bfd_elf64_swap_dyn_in,
3054 bfd_elf64_swap_dyn_out,
3055 mips_elf64_be_swap_reloc_in,
3056 mips_elf64_be_swap_reloc_out,
3057 mips_elf64_be_swap_reloca_in,
3058 mips_elf64_be_swap_reloca_out
3059 };
3060
3061 #define ELF_ARCH bfd_arch_mips
3062 #define ELF_MACHINE_CODE EM_MIPS
3063
3064 #define elf_backend_collect TRUE
3065 #define elf_backend_type_change_ok TRUE
3066 #define elf_backend_can_gc_sections TRUE
3067 #define elf_info_to_howto mips_elf64_info_to_howto_rela
3068 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
3069 #define elf_backend_object_p mips_elf64_object_p
3070 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
3071 #define elf_backend_section_processing _bfd_mips_elf_section_processing
3072 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
3073 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
3074 #define elf_backend_section_from_bfd_section \
3075 _bfd_mips_elf_section_from_bfd_section
3076 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
3077 #define elf_backend_link_output_symbol_hook \
3078 _bfd_mips_elf_link_output_symbol_hook
3079 #define elf_backend_create_dynamic_sections \
3080 _bfd_mips_elf_create_dynamic_sections
3081 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
3082 #define elf_backend_adjust_dynamic_symbol \
3083 _bfd_mips_elf_adjust_dynamic_symbol
3084 #define elf_backend_always_size_sections \
3085 _bfd_mips_elf_always_size_sections
3086 #define elf_backend_size_dynamic_sections \
3087 _bfd_mips_elf_size_dynamic_sections
3088 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
3089 #define elf_backend_finish_dynamic_symbol \
3090 _bfd_mips_elf_finish_dynamic_symbol
3091 #define elf_backend_finish_dynamic_sections \
3092 _bfd_mips_elf_finish_dynamic_sections
3093 #define elf_backend_final_write_processing \
3094 _bfd_mips_elf_final_write_processing
3095 #define elf_backend_additional_program_headers \
3096 _bfd_mips_elf_additional_program_headers
3097 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
3098 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
3099 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
3100 #define elf_backend_copy_indirect_symbol \
3101 _bfd_mips_elf_copy_indirect_symbol
3102 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
3103 #define elf_backend_ignore_discarded_relocs \
3104 _bfd_mips_elf_ignore_discarded_relocs
3105 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
3106 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
3107 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
3108 #define elf_backend_size_info mips_elf64_size_info
3109
3110 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus
3111 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo
3112
3113 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
3114
3115 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
3116 work better/work only in RELA, so we default to this. */
3117 #define elf_backend_may_use_rel_p 1
3118 #define elf_backend_may_use_rela_p 1
3119 #define elf_backend_default_use_rela_p 1
3120
3121 #define elf_backend_write_section _bfd_mips_elf_write_section
3122
3123 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
3124 MIPS-specific function only applies to IRIX5, which had no 64-bit
3125 ABI. */
3126 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
3127 #define bfd_elf64_find_inliner_info _bfd_mips_elf_find_inliner_info
3128 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
3129 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
3130 #define bfd_elf64_bfd_get_relocated_section_contents \
3131 _bfd_elf_mips_get_relocated_section_contents
3132 #define bfd_elf64_bfd_link_hash_table_create \
3133 _bfd_mips_elf_link_hash_table_create
3134 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
3135 #define bfd_elf64_bfd_merge_private_bfd_data \
3136 _bfd_mips_elf_merge_private_bfd_data
3137 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
3138 #define bfd_elf64_bfd_print_private_bfd_data \
3139 _bfd_mips_elf_print_private_bfd_data
3140
3141 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
3142 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
3143 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
3144 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
3145 #define bfd_elf64_bfd_relax_section _bfd_mips_relax_section
3146
3147 /* MIPS ELF64 archive functions. */
3148 #define bfd_elf64_archive_functions
3149 extern bfd_boolean bfd_elf64_archive_slurp_armap
3150 (bfd *);
3151 extern bfd_boolean bfd_elf64_archive_write_armap
3152 (bfd *, unsigned int, struct orl *, unsigned int, int);
3153 #define bfd_elf64_archive_slurp_extended_name_table \
3154 _bfd_archive_coff_slurp_extended_name_table
3155 #define bfd_elf64_archive_construct_extended_name_table \
3156 _bfd_archive_coff_construct_extended_name_table
3157 #define bfd_elf64_archive_truncate_arname \
3158 _bfd_archive_coff_truncate_arname
3159 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
3160 #define bfd_elf64_archive_openr_next_archived_file \
3161 _bfd_archive_coff_openr_next_archived_file
3162 #define bfd_elf64_archive_get_elt_at_index \
3163 _bfd_archive_coff_get_elt_at_index
3164 #define bfd_elf64_archive_generic_stat_arch_elt \
3165 _bfd_archive_coff_generic_stat_arch_elt
3166 #define bfd_elf64_archive_update_armap_timestamp \
3167 _bfd_archive_coff_update_armap_timestamp
3168
3169 /* The SGI style (n)64 NewABI. */
3170 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
3171 #define TARGET_LITTLE_NAME "elf64-littlemips"
3172 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
3173 #define TARGET_BIG_NAME "elf64-bigmips"
3174
3175 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
3176 a value of 0x1000, and we are compatible.
3177 FIXME: How does this affect NewABI? */
3178 #define ELF_MAXPAGESIZE 0x1000
3179
3180 #include "elf64-target.h"
3181
3182 /* The SYSV-style 'traditional' (n)64 NewABI. */
3183 #undef TARGET_LITTLE_SYM
3184 #undef TARGET_LITTLE_NAME
3185 #undef TARGET_BIG_SYM
3186 #undef TARGET_BIG_NAME
3187
3188 #undef ELF_MAXPAGESIZE
3189
3190 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
3191 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
3192 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
3193 #define TARGET_BIG_NAME "elf64-tradbigmips"
3194
3195 /* The SVR4 MIPS ABI says that this should be 0x10000, and Linux uses
3196 page sizes of up to that limit, so we need to respect it. */
3197 #define ELF_MAXPAGESIZE 0x10000
3198 #define elf64_bed elf64_tradbed
3199
3200 /* Include the target file again for this target. */
3201 #include "elf64-target.h"
3202