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