source: branches/libc-0.6/src/binutils/bfd/elf64-mips.c

Last change on this file was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

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