* elf-bfd.h (_bfd_elf_maybe_strip_eh_frame_hdr): New prototype.
[deliverable/binutils-gdb.git] / bfd / elf64-mips.c
CommitLineData
252b5132 1/* MIPS-specific support for 64-bit ELF
7898deda
NC
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
252b5132 4 Ian Lance Taylor, Cygnus Support
103186c6
MM
5 Linker support added by Mark Mitchell, CodeSourcery, LLC.
6 <mark@codesourcery.com>
252b5132
RH
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
36b45482 28 writing the relocations here. */
252b5132
RH
29
30#include "bfd.h"
31#include "sysdep.h"
32#include "libbfd.h"
33#include "aout/ar.h"
34#include "bfdlink.h"
35#include "genlink.h"
36#include "elf-bfd.h"
37#include "elf/mips.h"
38
39/* Get the ECOFF swapping routines. The 64-bit ABI is not supposed to
40 use ECOFF. However, we support it anyhow for an easier changeover. */
41#include "coff/sym.h"
42#include "coff/symconst.h"
43#include "coff/internal.h"
44#include "coff/ecoff.h"
45/* The 64 bit versions of the mdebug data structures are in alpha.h. */
46#include "coff/alpha.h"
23e2c83b 47#define ECOFF_SIGNED_64
252b5132
RH
48#include "ecoffswap.h"
49
50static void mips_elf64_swap_reloc_in
51 PARAMS ((bfd *, const Elf64_Mips_External_Rel *,
52 Elf64_Mips_Internal_Rel *));
53static void mips_elf64_swap_reloca_in
54 PARAMS ((bfd *, const Elf64_Mips_External_Rela *,
55 Elf64_Mips_Internal_Rela *));
252b5132
RH
56static void mips_elf64_swap_reloc_out
57 PARAMS ((bfd *, const Elf64_Mips_Internal_Rel *,
58 Elf64_Mips_External_Rel *));
252b5132
RH
59static void mips_elf64_swap_reloca_out
60 PARAMS ((bfd *, const Elf64_Mips_Internal_Rela *,
61 Elf64_Mips_External_Rela *));
c7ac6ff8
MM
62static void mips_elf64_be_swap_reloc_in
63 PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rel *));
64static void mips_elf64_be_swap_reloc_out
65 PARAMS ((bfd *, const Elf_Internal_Rel *, bfd_byte *));
66static void mips_elf64_be_swap_reloca_in
67 PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *));
68static void mips_elf64_be_swap_reloca_out
69 PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *));
252b5132
RH
70static reloc_howto_type *mips_elf64_reloc_type_lookup
71 PARAMS ((bfd *, bfd_reloc_code_real_type));
72static long mips_elf64_get_reloc_upper_bound PARAMS ((bfd *, asection *));
73static boolean mips_elf64_slurp_one_reloc_table
74 PARAMS ((bfd *, asection *, asymbol **, const Elf_Internal_Shdr *));
75static boolean mips_elf64_slurp_reloc_table
76 PARAMS ((bfd *, asection *, asymbol **, boolean));
77static void mips_elf64_write_relocs PARAMS ((bfd *, asection *, PTR));
252b5132
RH
78
79/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
80 from smaller values. Start with zero, widen, *then* decrement. */
81#define MINUS_ONE (((bfd_vma)0) - 1)
82
103186c6
MM
83/* The number of local .got entries we reserve. */
84#define MIPS_RESERVED_GOTNO (2)
85
252b5132
RH
86/* The relocation table used for SHT_REL sections. */
87
5e572849
AM
88#define UNUSED_RELOC(num) { num, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
89
252b5132
RH
90static reloc_howto_type mips_elf64_howto_table_rel[] =
91{
92 /* No relocation. */
93 HOWTO (R_MIPS_NONE, /* type */
94 0, /* rightshift */
95 0, /* size (0 = byte, 1 = short, 2 = long) */
96 0, /* bitsize */
97 false, /* pc_relative */
98 0, /* bitpos */
99 complain_overflow_dont, /* complain_on_overflow */
100 bfd_elf_generic_reloc, /* special_function */
101 "R_MIPS_NONE", /* name */
102 false, /* partial_inplace */
103 0, /* src_mask */
104 0, /* dst_mask */
105 false), /* pcrel_offset */
106
107 /* 16 bit relocation. */
108 HOWTO (R_MIPS_16, /* type */
109 0, /* rightshift */
110 1, /* size (0 = byte, 1 = short, 2 = long) */
111 16, /* bitsize */
112 false, /* pc_relative */
113 0, /* bitpos */
114 complain_overflow_bitfield, /* complain_on_overflow */
115 bfd_elf_generic_reloc, /* special_function */
116 "R_MIPS_16", /* name */
117 true, /* partial_inplace */
118 0xffff, /* src_mask */
119 0xffff, /* dst_mask */
120 false), /* pcrel_offset */
121
122 /* 32 bit relocation. */
123 HOWTO (R_MIPS_32, /* type */
124 0, /* rightshift */
125 2, /* size (0 = byte, 1 = short, 2 = long) */
126 32, /* bitsize */
127 false, /* pc_relative */
128 0, /* bitpos */
77bfe34f 129 complain_overflow_dont, /* complain_on_overflow */
252b5132
RH
130 bfd_elf_generic_reloc, /* special_function */
131 "R_MIPS_32", /* name */
132 true, /* partial_inplace */
133 0xffffffff, /* src_mask */
134 0xffffffff, /* dst_mask */
135 false), /* pcrel_offset */
136
137 /* 32 bit symbol relative relocation. */
138 HOWTO (R_MIPS_REL32, /* type */
139 0, /* rightshift */
140 2, /* size (0 = byte, 1 = short, 2 = long) */
141 32, /* bitsize */
142 false, /* pc_relative */
143 0, /* bitpos */
77bfe34f 144 complain_overflow_dont, /* complain_on_overflow */
252b5132
RH
145 bfd_elf_generic_reloc, /* special_function */
146 "R_MIPS_REL32", /* name */
147 true, /* partial_inplace */
148 0xffffffff, /* src_mask */
149 0xffffffff, /* dst_mask */
150 false), /* pcrel_offset */
151
77bfe34f 152 /* 26 bit jump address. */
252b5132
RH
153 HOWTO (R_MIPS_26, /* type */
154 2, /* rightshift */
155 2, /* size (0 = byte, 1 = short, 2 = long) */
156 26, /* bitsize */
157 false, /* pc_relative */
158 0, /* bitpos */
159 complain_overflow_dont, /* complain_on_overflow */
56fc028e 160 /* This needs complex overflow
77bfe34f 161 detection, because the upper 36
b401d8e5 162 bits must match the PC + 4. */
252b5132
RH
163 bfd_elf_generic_reloc, /* special_function */
164 "R_MIPS_26", /* name */
165 true, /* partial_inplace */
166 0x3ffffff, /* src_mask */
167 0x3ffffff, /* dst_mask */
168 false), /* pcrel_offset */
169
170 /* High 16 bits of symbol value. */
171 HOWTO (R_MIPS_HI16, /* type */
172 0, /* rightshift */
173 2, /* size (0 = byte, 1 = short, 2 = long) */
174 16, /* bitsize */
175 false, /* pc_relative */
176 0, /* bitpos */
177 complain_overflow_dont, /* complain_on_overflow */
178 _bfd_mips_elf_hi16_reloc, /* special_function */
179 "R_MIPS_HI16", /* name */
180 true, /* partial_inplace */
181 0xffff, /* src_mask */
182 0xffff, /* dst_mask */
183 false), /* pcrel_offset */
184
185 /* Low 16 bits of symbol value. */
186 HOWTO (R_MIPS_LO16, /* type */
187 0, /* rightshift */
188 2, /* size (0 = byte, 1 = short, 2 = long) */
189 16, /* bitsize */
190 false, /* pc_relative */
191 0, /* bitpos */
192 complain_overflow_dont, /* complain_on_overflow */
193 _bfd_mips_elf_lo16_reloc, /* special_function */
194 "R_MIPS_LO16", /* name */
195 true, /* partial_inplace */
196 0xffff, /* src_mask */
197 0xffff, /* dst_mask */
198 false), /* pcrel_offset */
199
200 /* GP relative reference. */
201 HOWTO (R_MIPS_GPREL16, /* type */
202 0, /* rightshift */
203 2, /* size (0 = byte, 1 = short, 2 = long) */
204 16, /* bitsize */
205 false, /* pc_relative */
206 0, /* bitpos */
207 complain_overflow_signed, /* complain_on_overflow */
208 _bfd_mips_elf_gprel16_reloc, /* special_function */
209 "R_MIPS_GPREL16", /* name */
210 true, /* partial_inplace */
211 0xffff, /* src_mask */
212 0xffff, /* dst_mask */
213 false), /* pcrel_offset */
214
215 /* Reference to literal section. */
216 HOWTO (R_MIPS_LITERAL, /* type */
217 0, /* rightshift */
218 2, /* size (0 = byte, 1 = short, 2 = long) */
219 16, /* bitsize */
220 false, /* pc_relative */
221 0, /* bitpos */
222 complain_overflow_signed, /* complain_on_overflow */
223 _bfd_mips_elf_gprel16_reloc, /* special_function */
224 "R_MIPS_LITERAL", /* name */
225 true, /* partial_inplace */
226 0xffff, /* src_mask */
227 0xffff, /* dst_mask */
228 false), /* pcrel_offset */
229
230 /* Reference to global offset table. */
231 HOWTO (R_MIPS_GOT16, /* type */
232 0, /* rightshift */
233 2, /* size (0 = byte, 1 = short, 2 = long) */
234 16, /* bitsize */
235 false, /* pc_relative */
236 0, /* bitpos */
237 complain_overflow_signed, /* complain_on_overflow */
238 _bfd_mips_elf_got16_reloc, /* special_function */
239 "R_MIPS_GOT16", /* name */
240 false, /* partial_inplace */
241 0, /* src_mask */
242 0xffff, /* dst_mask */
243 false), /* pcrel_offset */
244
245 /* 16 bit PC relative reference. */
246 HOWTO (R_MIPS_PC16, /* type */
247 0, /* rightshift */
248 2, /* size (0 = byte, 1 = short, 2 = long) */
249 16, /* bitsize */
250 true, /* pc_relative */
251 0, /* bitpos */
252 complain_overflow_signed, /* complain_on_overflow */
253 bfd_elf_generic_reloc, /* special_function */
254 "R_MIPS_PC16", /* name */
255 true, /* partial_inplace */
256 0xffff, /* src_mask */
257 0xffff, /* dst_mask */
258 false), /* pcrel_offset */
259
260 /* 16 bit call through global offset table. */
261 /* FIXME: This is not handled correctly. */
262 HOWTO (R_MIPS_CALL16, /* type */
263 0, /* rightshift */
264 2, /* size (0 = byte, 1 = short, 2 = long) */
265 16, /* bitsize */
266 false, /* pc_relative */
267 0, /* bitpos */
268 complain_overflow_signed, /* complain_on_overflow */
269 bfd_elf_generic_reloc, /* special_function */
270 "R_MIPS_CALL16", /* name */
271 false, /* partial_inplace */
272 0, /* src_mask */
273 0xffff, /* dst_mask */
274 false), /* pcrel_offset */
275
276 /* 32 bit GP relative reference. */
277 HOWTO (R_MIPS_GPREL32, /* type */
278 0, /* rightshift */
279 2, /* size (0 = byte, 1 = short, 2 = long) */
280 32, /* bitsize */
281 false, /* pc_relative */
282 0, /* bitpos */
283 complain_overflow_bitfield, /* complain_on_overflow */
284 _bfd_mips_elf_gprel32_reloc, /* special_function */
285 "R_MIPS_GPREL32", /* name */
286 true, /* partial_inplace */
287 0xffffffff, /* src_mask */
288 0xffffffff, /* dst_mask */
289 false), /* pcrel_offset */
290
5e572849
AM
291 UNUSED_RELOC (13),
292 UNUSED_RELOC (14),
293 UNUSED_RELOC (15),
252b5132
RH
294
295 /* A 5 bit shift field. */
296 HOWTO (R_MIPS_SHIFT5, /* type */
297 0, /* rightshift */
298 2, /* size (0 = byte, 1 = short, 2 = long) */
299 5, /* bitsize */
300 false, /* pc_relative */
301 6, /* bitpos */
302 complain_overflow_bitfield, /* complain_on_overflow */
303 bfd_elf_generic_reloc, /* special_function */
304 "R_MIPS_SHIFT5", /* name */
305 true, /* partial_inplace */
306 0x000007c0, /* src_mask */
307 0x000007c0, /* dst_mask */
308 false), /* pcrel_offset */
309
310 /* A 6 bit shift field. */
311 /* FIXME: This is not handled correctly; a special function is
312 needed to put the most significant bit in the right place. */
313 HOWTO (R_MIPS_SHIFT6, /* type */
314 0, /* rightshift */
315 2, /* size (0 = byte, 1 = short, 2 = long) */
316 6, /* bitsize */
317 false, /* pc_relative */
318 6, /* bitpos */
319 complain_overflow_bitfield, /* complain_on_overflow */
320 bfd_elf_generic_reloc, /* special_function */
321 "R_MIPS_SHIFT6", /* name */
322 true, /* partial_inplace */
323 0x000007c4, /* src_mask */
324 0x000007c4, /* dst_mask */
325 false), /* pcrel_offset */
326
327 /* 64 bit relocation. */
328 HOWTO (R_MIPS_64, /* type */
329 0, /* rightshift */
330 4, /* size (0 = byte, 1 = short, 2 = long) */
331 64, /* bitsize */
332 false, /* pc_relative */
333 0, /* bitpos */
77bfe34f 334 complain_overflow_dont, /* complain_on_overflow */
252b5132
RH
335 bfd_elf_generic_reloc, /* special_function */
336 "R_MIPS_64", /* name */
337 true, /* partial_inplace */
338 MINUS_ONE, /* src_mask */
339 MINUS_ONE, /* dst_mask */
340 false), /* pcrel_offset */
341
342 /* Displacement in the global offset table. */
343 /* FIXME: Not handled correctly. */
344 HOWTO (R_MIPS_GOT_DISP, /* type */
345 0, /* rightshift */
346 2, /* size (0 = byte, 1 = short, 2 = long) */
347 16, /* bitsize */
348 false, /* pc_relative */
349 0, /* bitpos */
77bfe34f 350 complain_overflow_signed, /* complain_on_overflow */
252b5132
RH
351 bfd_elf_generic_reloc, /* special_function */
352 "R_MIPS_GOT_DISP", /* name */
77bfe34f 353 false, /* partial_inplace */
252b5132
RH
354 0x0000ffff, /* src_mask */
355 0x0000ffff, /* dst_mask */
356 false), /* pcrel_offset */
357
358 /* Displacement to page pointer in the global offset table. */
359 /* FIXME: Not handled correctly. */
360 HOWTO (R_MIPS_GOT_PAGE, /* type */
361 0, /* rightshift */
362 2, /* size (0 = byte, 1 = short, 2 = long) */
363 16, /* bitsize */
364 false, /* pc_relative */
365 0, /* bitpos */
77bfe34f 366 complain_overflow_signed, /* complain_on_overflow */
252b5132
RH
367 bfd_elf_generic_reloc, /* special_function */
368 "R_MIPS_GOT_PAGE", /* name */
77bfe34f 369 false, /* partial_inplace */
252b5132
RH
370 0x0000ffff, /* src_mask */
371 0x0000ffff, /* dst_mask */
372 false), /* pcrel_offset */
373
374 /* Offset from page pointer in the global offset table. */
375 /* FIXME: Not handled correctly. */
376 HOWTO (R_MIPS_GOT_OFST, /* type */
377 0, /* rightshift */
378 2, /* size (0 = byte, 1 = short, 2 = long) */
379 16, /* bitsize */
380 false, /* pc_relative */
381 0, /* bitpos */
77bfe34f 382 complain_overflow_signed, /* complain_on_overflow */
252b5132
RH
383 bfd_elf_generic_reloc, /* special_function */
384 "R_MIPS_GOT_OFST", /* name */
77bfe34f 385 false, /* partial_inplace */
252b5132
RH
386 0x0000ffff, /* src_mask */
387 0x0000ffff, /* dst_mask */
388 false), /* pcrel_offset */
389
390 /* High 16 bits of displacement in global offset table. */
391 /* FIXME: Not handled correctly. */
392 HOWTO (R_MIPS_GOT_HI16, /* type */
393 0, /* rightshift */
394 2, /* size (0 = byte, 1 = short, 2 = long) */
395 16, /* bitsize */
396 false, /* pc_relative */
397 0, /* bitpos */
398 complain_overflow_dont, /* complain_on_overflow */
399 bfd_elf_generic_reloc, /* special_function */
400 "R_MIPS_GOT_HI16", /* name */
77bfe34f 401 false, /* partial_inplace */
252b5132
RH
402 0x0000ffff, /* src_mask */
403 0x0000ffff, /* dst_mask */
404 false), /* pcrel_offset */
405
406 /* Low 16 bits of displacement in global offset table. */
407 /* FIXME: Not handled correctly. */
408 HOWTO (R_MIPS_GOT_LO16, /* type */
409 0, /* rightshift */
410 2, /* size (0 = byte, 1 = short, 2 = long) */
411 16, /* bitsize */
412 false, /* pc_relative */
413 0, /* bitpos */
414 complain_overflow_dont, /* complain_on_overflow */
415 bfd_elf_generic_reloc, /* special_function */
416 "R_MIPS_GOT_LO16", /* name */
77bfe34f 417 false, /* partial_inplace */
252b5132
RH
418 0x0000ffff, /* src_mask */
419 0x0000ffff, /* dst_mask */
420 false), /* pcrel_offset */
421
422 /* 64 bit substraction. */
423 /* FIXME: Not handled correctly. */
424 HOWTO (R_MIPS_SUB, /* type */
425 0, /* rightshift */
426 4, /* size (0 = byte, 1 = short, 2 = long) */
427 64, /* bitsize */
428 false, /* pc_relative */
429 0, /* bitpos */
77bfe34f 430 complain_overflow_dont, /* complain_on_overflow */
252b5132
RH
431 bfd_elf_generic_reloc, /* special_function */
432 "R_MIPS_SUB", /* name */
433 true, /* partial_inplace */
434 MINUS_ONE, /* src_mask */
435 MINUS_ONE, /* dst_mask */
436 false), /* pcrel_offset */
437
438 /* Insert the addend as an instruction. */
439 /* FIXME: Not handled correctly. */
440 HOWTO (R_MIPS_INSERT_A, /* type */
441 0, /* rightshift */
77bfe34f
TS
442 2, /* size (0 = byte, 1 = short, 2 = long) */
443 32, /* bitsize */
252b5132
RH
444 false, /* pc_relative */
445 0, /* bitpos */
446 complain_overflow_dont, /* complain_on_overflow */
447 bfd_elf_generic_reloc, /* special_function */
448 "R_MIPS_INSERT_A", /* name */
77bfe34f
TS
449 true, /* partial_inplace */
450 0xffffffff, /* src_mask */
451 0xffffffff, /* dst_mask */
252b5132
RH
452 false), /* pcrel_offset */
453
454 /* Insert the addend as an instruction, and change all relocations
455 to refer to the old instruction at the address. */
456 /* FIXME: Not handled correctly. */
457 HOWTO (R_MIPS_INSERT_B, /* type */
458 0, /* rightshift */
77bfe34f
TS
459 2, /* size (0 = byte, 1 = short, 2 = long) */
460 32, /* bitsize */
252b5132
RH
461 false, /* pc_relative */
462 0, /* bitpos */
463 complain_overflow_dont, /* complain_on_overflow */
464 bfd_elf_generic_reloc, /* special_function */
465 "R_MIPS_INSERT_B", /* name */
77bfe34f
TS
466 true, /* partial_inplace */
467 0xffffffff, /* src_mask */
468 0xffffffff, /* dst_mask */
252b5132
RH
469 false), /* pcrel_offset */
470
471 /* Delete a 32 bit instruction. */
472 /* FIXME: Not handled correctly. */
473 HOWTO (R_MIPS_DELETE, /* type */
474 0, /* rightshift */
77bfe34f
TS
475 2, /* size (0 = byte, 1 = short, 2 = long) */
476 32, /* bitsize */
252b5132
RH
477 false, /* pc_relative */
478 0, /* bitpos */
479 complain_overflow_dont, /* complain_on_overflow */
480 bfd_elf_generic_reloc, /* special_function */
481 "R_MIPS_DELETE", /* name */
77bfe34f
TS
482 true, /* partial_inplace */
483 0xffffffff, /* src_mask */
484 0xffffffff, /* dst_mask */
252b5132
RH
485 false), /* pcrel_offset */
486
487 /* Get the higher value of a 64 bit addend. */
252b5132
RH
488 HOWTO (R_MIPS_HIGHER, /* type */
489 0, /* rightshift */
490 2, /* size (0 = byte, 1 = short, 2 = long) */
491 16, /* bitsize */
492 false, /* pc_relative */
493 0, /* bitpos */
494 complain_overflow_dont, /* complain_on_overflow */
495 bfd_elf_generic_reloc, /* special_function */
496 "R_MIPS_HIGHER", /* name */
497 true, /* partial_inplace */
498 0xffff, /* src_mask */
499 0xffff, /* dst_mask */
500 false), /* pcrel_offset */
501
502 /* Get the highest value of a 64 bit addend. */
503 /* FIXME: Not handled correctly. */
504 HOWTO (R_MIPS_HIGHEST, /* type */
505 0, /* rightshift */
506 2, /* size (0 = byte, 1 = short, 2 = long) */
507 16, /* bitsize */
508 false, /* pc_relative */
509 0, /* bitpos */
510 complain_overflow_dont, /* complain_on_overflow */
511 bfd_elf_generic_reloc, /* special_function */
512 "R_MIPS_HIGHEST", /* name */
513 true, /* partial_inplace */
514 0xffff, /* src_mask */
515 0xffff, /* dst_mask */
516 false), /* pcrel_offset */
517
518 /* High 16 bits of displacement in global offset table. */
519 /* FIXME: Not handled correctly. */
520 HOWTO (R_MIPS_CALL_HI16, /* type */
521 0, /* rightshift */
522 2, /* size (0 = byte, 1 = short, 2 = long) */
523 16, /* bitsize */
524 false, /* pc_relative */
525 0, /* bitpos */
526 complain_overflow_dont, /* complain_on_overflow */
527 bfd_elf_generic_reloc, /* special_function */
528 "R_MIPS_CALL_HI16", /* name */
529 true, /* partial_inplace */
77bfe34f
TS
530 0xffff, /* src_mask */
531 0xffff, /* dst_mask */
252b5132
RH
532 false), /* pcrel_offset */
533
534 /* Low 16 bits of displacement in global offset table. */
535 /* FIXME: Not handled correctly. */
536 HOWTO (R_MIPS_CALL_LO16, /* type */
537 0, /* rightshift */
538 2, /* size (0 = byte, 1 = short, 2 = long) */
539 16, /* bitsize */
540 false, /* pc_relative */
541 0, /* bitpos */
542 complain_overflow_dont, /* complain_on_overflow */
543 bfd_elf_generic_reloc, /* special_function */
544 "R_MIPS_CALL_LO16", /* name */
545 true, /* partial_inplace */
77bfe34f
TS
546 0xffff, /* src_mask */
547 0xffff, /* dst_mask */
252b5132
RH
548 false), /* pcrel_offset */
549
550 /* I'm not sure what the remaining relocs are, but they are defined
551 on Irix 6. */
552
553 HOWTO (R_MIPS_SCN_DISP, /* type */
554 0, /* rightshift */
77bfe34f
TS
555 2, /* size (0 = byte, 1 = short, 2 = long) */
556 32, /* bitsize */
252b5132
RH
557 false, /* pc_relative */
558 0, /* bitpos */
559 complain_overflow_dont, /* complain_on_overflow */
560 bfd_elf_generic_reloc, /* special_function */
561 "R_MIPS_SCN_DISP", /* name */
77bfe34f
TS
562 true, /* partial_inplace */
563 0xffffffff, /* src_mask */
564 0xffffffff, /* dst_mask */
252b5132
RH
565 false), /* pcrel_offset */
566
567 HOWTO (R_MIPS_REL16, /* type */
568 0, /* rightshift */
77bfe34f
TS
569 1, /* size (0 = byte, 1 = short, 2 = long) */
570 16, /* bitsize */
252b5132
RH
571 false, /* pc_relative */
572 0, /* bitpos */
77bfe34f 573 complain_overflow_signed, /* complain_on_overflow */
252b5132
RH
574 bfd_elf_generic_reloc, /* special_function */
575 "R_MIPS_REL16", /* name */
77bfe34f
TS
576 true, /* partial_inplace */
577 0xffff, /* src_mask */
578 0xffff, /* dst_mask */
252b5132
RH
579 false), /* pcrel_offset */
580
77bfe34f
TS
581 /* These two are obsolete. */
582 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
583 EMPTY_HOWTO (R_MIPS_PJUMP),
252b5132
RH
584
585 HOWTO (R_MIPS_RELGOT, /* type */
586 0, /* rightshift */
77bfe34f
TS
587 2, /* size (0 = byte, 1 = short, 2 = long) */
588 32, /* bitsize */
252b5132
RH
589 false, /* pc_relative */
590 0, /* bitpos */
591 complain_overflow_dont, /* complain_on_overflow */
592 bfd_elf_generic_reloc, /* special_function */
593 "R_MIPS_RELGOT", /* name */
77bfe34f
TS
594 true, /* partial_inplace */
595 0xffffffff, /* src_mask */
596 0xffffffff, /* dst_mask */
d2905643
MM
597 false), /* pcrel_offset */
598
fe8bc63d 599 /* Protected jump conversion. This is an optimization hint. No
d2905643
MM
600 relocation is required for correctness. */
601 HOWTO (R_MIPS_JALR, /* type */
602 0, /* rightshift */
77bfe34f 603 2, /* size (0 = byte, 1 = short, 2 = long) */
d2905643
MM
604 0, /* bitsize */
605 false, /* pc_relative */
606 0, /* bitpos */
607 complain_overflow_dont, /* complain_on_overflow */
608 bfd_elf_generic_reloc, /* special_function */
609 "R_MIPS_JALR", /* name */
610 false, /* partial_inplace */
77bfe34f
TS
611 0, /* src_mask */
612 0, /* dst_mask */
d2905643 613 false), /* pcrel_offset */
252b5132
RH
614};
615
616/* The relocation table used for SHT_RELA sections. */
617
618static reloc_howto_type mips_elf64_howto_table_rela[] =
619{
620 /* No relocation. */
621 HOWTO (R_MIPS_NONE, /* type */
622 0, /* rightshift */
623 0, /* size (0 = byte, 1 = short, 2 = long) */
624 0, /* bitsize */
625 false, /* pc_relative */
626 0, /* bitpos */
627 complain_overflow_dont, /* complain_on_overflow */
628 bfd_elf_generic_reloc, /* special_function */
629 "R_MIPS_NONE", /* name */
630 false, /* partial_inplace */
631 0, /* src_mask */
632 0, /* dst_mask */
633 false), /* pcrel_offset */
634
635 /* 16 bit relocation. */
636 HOWTO (R_MIPS_16, /* type */
637 0, /* rightshift */
638 1, /* size (0 = byte, 1 = short, 2 = long) */
639 16, /* bitsize */
640 false, /* pc_relative */
641 0, /* bitpos */
642 complain_overflow_bitfield, /* complain_on_overflow */
643 bfd_elf_generic_reloc, /* special_function */
644 "R_MIPS_16", /* name */
77bfe34f 645 false, /* partial_inplace */
252b5132
RH
646 0, /* src_mask */
647 0xffff, /* dst_mask */
648 false), /* pcrel_offset */
649
650 /* 32 bit relocation. */
651 HOWTO (R_MIPS_32, /* type */
652 0, /* rightshift */
653 2, /* size (0 = byte, 1 = short, 2 = long) */
654 32, /* bitsize */
655 false, /* pc_relative */
656 0, /* bitpos */
77bfe34f 657 complain_overflow_dont, /* complain_on_overflow */
252b5132
RH
658 bfd_elf_generic_reloc, /* special_function */
659 "R_MIPS_32", /* name */
77bfe34f 660 false, /* partial_inplace */
252b5132
RH
661 0, /* src_mask */
662 0xffffffff, /* dst_mask */
663 false), /* pcrel_offset */
664
665 /* 32 bit symbol relative relocation. */
666 HOWTO (R_MIPS_REL32, /* type */
667 0, /* rightshift */
668 2, /* size (0 = byte, 1 = short, 2 = long) */
669 32, /* bitsize */
670 false, /* pc_relative */
671 0, /* bitpos */
77bfe34f 672 complain_overflow_dont, /* complain_on_overflow */
252b5132
RH
673 bfd_elf_generic_reloc, /* special_function */
674 "R_MIPS_REL32", /* name */
77bfe34f 675 false, /* partial_inplace */
252b5132
RH
676 0, /* src_mask */
677 0xffffffff, /* dst_mask */
678 false), /* pcrel_offset */
679
77bfe34f 680 /* 26 bit jump address. */
252b5132
RH
681 HOWTO (R_MIPS_26, /* type */
682 2, /* rightshift */
683 2, /* size (0 = byte, 1 = short, 2 = long) */
684 26, /* bitsize */
685 false, /* pc_relative */
686 0, /* bitpos */
687 complain_overflow_dont, /* complain_on_overflow */
56fc028e 688 /* This needs complex overflow
77bfe34f 689 detection, because the upper 36
b401d8e5 690 bits must match the PC + 4. */
252b5132
RH
691 bfd_elf_generic_reloc, /* special_function */
692 "R_MIPS_26", /* name */
77bfe34f 693 false, /* partial_inplace */
252b5132
RH
694 0, /* src_mask */
695 0x3ffffff, /* dst_mask */
696 false), /* pcrel_offset */
697
698 /* High 16 bits of symbol value. */
699 HOWTO (R_MIPS_HI16, /* type */
700 0, /* rightshift */
701 2, /* size (0 = byte, 1 = short, 2 = long) */
702 16, /* bitsize */
703 false, /* pc_relative */
704 0, /* bitpos */
705 complain_overflow_dont, /* complain_on_overflow */
706 bfd_elf_generic_reloc, /* special_function */
707 "R_MIPS_HI16", /* name */
77bfe34f 708 false, /* partial_inplace */
252b5132
RH
709 0, /* src_mask */
710 0xffff, /* dst_mask */
711 false), /* pcrel_offset */
712
713 /* Low 16 bits of symbol value. */
714 HOWTO (R_MIPS_LO16, /* type */
715 0, /* rightshift */
716 2, /* size (0 = byte, 1 = short, 2 = long) */
717 16, /* bitsize */
718 false, /* pc_relative */
719 0, /* bitpos */
720 complain_overflow_dont, /* complain_on_overflow */
721 bfd_elf_generic_reloc, /* special_function */
722 "R_MIPS_LO16", /* name */
77bfe34f 723 false, /* partial_inplace */
252b5132
RH
724 0, /* src_mask */
725 0xffff, /* dst_mask */
726 false), /* pcrel_offset */
727
728 /* GP relative reference. */
729 HOWTO (R_MIPS_GPREL16, /* type */
730 0, /* rightshift */
731 2, /* size (0 = byte, 1 = short, 2 = long) */
732 16, /* bitsize */
733 false, /* pc_relative */
734 0, /* bitpos */
735 complain_overflow_signed, /* complain_on_overflow */
736 _bfd_mips_elf_gprel16_reloc, /* special_function */
737 "R_MIPS_GPREL16", /* name */
738 true, /* partial_inplace */
739 0, /* src_mask */
740 0xffff, /* dst_mask */
741 false), /* pcrel_offset */
742
743 /* Reference to literal section. */
744 HOWTO (R_MIPS_LITERAL, /* type */
745 0, /* rightshift */
746 2, /* size (0 = byte, 1 = short, 2 = long) */
747 16, /* bitsize */
748 false, /* pc_relative */
749 0, /* bitpos */
750 complain_overflow_signed, /* complain_on_overflow */
751 _bfd_mips_elf_gprel16_reloc, /* special_function */
752 "R_MIPS_LITERAL", /* name */
753 true, /* partial_inplace */
754 0, /* src_mask */
755 0xffff, /* dst_mask */
756 false), /* pcrel_offset */
757
758 /* Reference to global offset table. */
759 /* FIXME: This is not handled correctly. */
760 HOWTO (R_MIPS_GOT16, /* type */
761 0, /* rightshift */
762 2, /* size (0 = byte, 1 = short, 2 = long) */
763 16, /* bitsize */
764 false, /* pc_relative */
765 0, /* bitpos */
766 complain_overflow_signed, /* complain_on_overflow */
77bfe34f 767 bfd_elf_generic_reloc, /* special_function */
252b5132
RH
768 "R_MIPS_GOT16", /* name */
769 false, /* partial_inplace */
770 0, /* src_mask */
771 0xffff, /* dst_mask */
772 false), /* pcrel_offset */
773
774 /* 16 bit PC relative reference. */
775 HOWTO (R_MIPS_PC16, /* type */
776 0, /* rightshift */
777 2, /* size (0 = byte, 1 = short, 2 = long) */
778 16, /* bitsize */
779 true, /* pc_relative */
780 0, /* bitpos */
781 complain_overflow_signed, /* complain_on_overflow */
782 bfd_elf_generic_reloc, /* special_function */
783 "R_MIPS_PC16", /* name */
77bfe34f 784 false, /* partial_inplace */
252b5132
RH
785 0, /* src_mask */
786 0xffff, /* dst_mask */
787 false), /* pcrel_offset */
788
789 /* 16 bit call through global offset table. */
790 /* FIXME: This is not handled correctly. */
791 HOWTO (R_MIPS_CALL16, /* 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 bfd_elf_generic_reloc, /* special_function */
799 "R_MIPS_CALL16", /* name */
800 false, /* partial_inplace */
801 0, /* src_mask */
802 0xffff, /* dst_mask */
803 false), /* pcrel_offset */
804
805 /* 32 bit GP relative reference. */
806 HOWTO (R_MIPS_GPREL32, /* type */
807 0, /* rightshift */
808 2, /* size (0 = byte, 1 = short, 2 = long) */
809 32, /* bitsize */
810 false, /* pc_relative */
811 0, /* bitpos */
812 complain_overflow_bitfield, /* complain_on_overflow */
813 _bfd_mips_elf_gprel32_reloc, /* special_function */
814 "R_MIPS_GPREL32", /* name */
815 true, /* partial_inplace */
816 0, /* src_mask */
817 0xffffffff, /* dst_mask */
818 false), /* pcrel_offset */
819
5e572849
AM
820 UNUSED_RELOC (13),
821 UNUSED_RELOC (14),
822 UNUSED_RELOC (15),
252b5132
RH
823
824 /* A 5 bit shift field. */
825 HOWTO (R_MIPS_SHIFT5, /* type */
826 0, /* rightshift */
827 2, /* size (0 = byte, 1 = short, 2 = long) */
828 5, /* bitsize */
829 false, /* pc_relative */
830 6, /* bitpos */
831 complain_overflow_bitfield, /* complain_on_overflow */
832 bfd_elf_generic_reloc, /* special_function */
833 "R_MIPS_SHIFT5", /* name */
77bfe34f 834 false, /* partial_inplace */
252b5132
RH
835 0, /* src_mask */
836 0x000007c0, /* dst_mask */
837 false), /* pcrel_offset */
838
839 /* A 6 bit shift field. */
840 /* FIXME: This is not handled correctly; a special function is
841 needed to put the most significant bit in the right place. */
842 HOWTO (R_MIPS_SHIFT6, /* type */
843 0, /* rightshift */
844 2, /* size (0 = byte, 1 = short, 2 = long) */
845 6, /* bitsize */
846 false, /* pc_relative */
847 6, /* bitpos */
848 complain_overflow_bitfield, /* complain_on_overflow */
849 bfd_elf_generic_reloc, /* special_function */
850 "R_MIPS_SHIFT6", /* name */
77bfe34f 851 false, /* partial_inplace */
252b5132
RH
852 0, /* src_mask */
853 0x000007c4, /* dst_mask */
854 false), /* pcrel_offset */
855
856 /* 64 bit relocation. */
857 HOWTO (R_MIPS_64, /* type */
858 0, /* rightshift */
859 4, /* size (0 = byte, 1 = short, 2 = long) */
860 64, /* bitsize */
861 false, /* pc_relative */
862 0, /* bitpos */
77bfe34f 863 complain_overflow_dont, /* complain_on_overflow */
252b5132
RH
864 bfd_elf_generic_reloc, /* special_function */
865 "R_MIPS_64", /* name */
77bfe34f 866 false, /* partial_inplace */
252b5132
RH
867 0, /* src_mask */
868 MINUS_ONE, /* dst_mask */
869 false), /* pcrel_offset */
870
871 /* Displacement in the global offset table. */
872 /* FIXME: Not handled correctly. */
873 HOWTO (R_MIPS_GOT_DISP, /* type */
874 0, /* rightshift */
875 2, /* size (0 = byte, 1 = short, 2 = long) */
876 16, /* bitsize */
877 false, /* pc_relative */
878 0, /* bitpos */
77bfe34f 879 complain_overflow_signed, /* complain_on_overflow */
252b5132
RH
880 bfd_elf_generic_reloc, /* special_function */
881 "R_MIPS_GOT_DISP", /* name */
77bfe34f 882 false, /* partial_inplace */
252b5132
RH
883 0, /* src_mask */
884 0x0000ffff, /* dst_mask */
885 false), /* pcrel_offset */
886
887 /* Displacement to page pointer in the global offset table. */
888 /* FIXME: Not handled correctly. */
889 HOWTO (R_MIPS_GOT_PAGE, /* type */
890 0, /* rightshift */
891 2, /* size (0 = byte, 1 = short, 2 = long) */
892 16, /* bitsize */
893 false, /* pc_relative */
894 0, /* bitpos */
77bfe34f 895 complain_overflow_signed, /* complain_on_overflow */
252b5132
RH
896 bfd_elf_generic_reloc, /* special_function */
897 "R_MIPS_GOT_PAGE", /* name */
77bfe34f 898 false, /* partial_inplace */
252b5132
RH
899 0, /* src_mask */
900 0x0000ffff, /* dst_mask */
901 false), /* pcrel_offset */
902
903 /* Offset from page pointer in the global offset table. */
904 /* FIXME: Not handled correctly. */
905 HOWTO (R_MIPS_GOT_OFST, /* type */
906 0, /* rightshift */
907 2, /* size (0 = byte, 1 = short, 2 = long) */
908 16, /* bitsize */
909 false, /* pc_relative */
910 0, /* bitpos */
77bfe34f 911 complain_overflow_signed, /* complain_on_overflow */
252b5132
RH
912 bfd_elf_generic_reloc, /* special_function */
913 "R_MIPS_GOT_OFST", /* name */
77bfe34f 914 false, /* partial_inplace */
252b5132
RH
915 0, /* src_mask */
916 0x0000ffff, /* dst_mask */
917 false), /* pcrel_offset */
918
919 /* High 16 bits of displacement in global offset table. */
920 /* FIXME: Not handled correctly. */
921 HOWTO (R_MIPS_GOT_HI16, /* type */
922 0, /* rightshift */
923 2, /* size (0 = byte, 1 = short, 2 = long) */
924 16, /* bitsize */
925 false, /* pc_relative */
926 0, /* bitpos */
927 complain_overflow_dont, /* complain_on_overflow */
928 bfd_elf_generic_reloc, /* special_function */
929 "R_MIPS_GOT_HI16", /* name */
77bfe34f 930 false, /* partial_inplace */
252b5132
RH
931 0, /* src_mask */
932 0x0000ffff, /* dst_mask */
933 false), /* pcrel_offset */
934
935 /* Low 16 bits of displacement in global offset table. */
936 /* FIXME: Not handled correctly. */
937 HOWTO (R_MIPS_GOT_LO16, /* type */
938 0, /* rightshift */
939 2, /* size (0 = byte, 1 = short, 2 = long) */
940 16, /* bitsize */
941 false, /* pc_relative */
942 0, /* bitpos */
943 complain_overflow_dont, /* complain_on_overflow */
944 bfd_elf_generic_reloc, /* special_function */
945 "R_MIPS_GOT_LO16", /* name */
77bfe34f 946 false, /* partial_inplace */
252b5132
RH
947 0, /* src_mask */
948 0x0000ffff, /* dst_mask */
949 false), /* pcrel_offset */
950
951 /* 64 bit substraction. */
952 /* FIXME: Not handled correctly. */
953 HOWTO (R_MIPS_SUB, /* type */
954 0, /* rightshift */
955 4, /* size (0 = byte, 1 = short, 2 = long) */
956 64, /* bitsize */
957 false, /* pc_relative */
958 0, /* bitpos */
77bfe34f 959 complain_overflow_dont, /* complain_on_overflow */
252b5132
RH
960 bfd_elf_generic_reloc, /* special_function */
961 "R_MIPS_SUB", /* name */
77bfe34f 962 false, /* partial_inplace */
252b5132
RH
963 0, /* src_mask */
964 MINUS_ONE, /* dst_mask */
965 false), /* pcrel_offset */
966
967 /* Insert the addend as an instruction. */
968 /* FIXME: Not handled correctly. */
969 HOWTO (R_MIPS_INSERT_A, /* type */
970 0, /* rightshift */
77bfe34f
TS
971 2, /* size (0 = byte, 1 = short, 2 = long) */
972 32, /* bitsize */
252b5132
RH
973 false, /* pc_relative */
974 0, /* bitpos */
975 complain_overflow_dont, /* complain_on_overflow */
976 bfd_elf_generic_reloc, /* special_function */
977 "R_MIPS_INSERT_A", /* name */
978 false, /* partial_inplace */
979 0, /* src_mask */
77bfe34f 980 0xffffffff, /* dst_mask */
252b5132
RH
981 false), /* pcrel_offset */
982
983 /* Insert the addend as an instruction, and change all relocations
984 to refer to the old instruction at the address. */
985 /* FIXME: Not handled correctly. */
986 HOWTO (R_MIPS_INSERT_B, /* type */
987 0, /* rightshift */
77bfe34f
TS
988 2, /* size (0 = byte, 1 = short, 2 = long) */
989 32, /* bitsize */
252b5132
RH
990 false, /* pc_relative */
991 0, /* bitpos */
992 complain_overflow_dont, /* complain_on_overflow */
993 bfd_elf_generic_reloc, /* special_function */
994 "R_MIPS_INSERT_B", /* name */
995 false, /* partial_inplace */
996 0, /* src_mask */
77bfe34f 997 0xffffffff, /* dst_mask */
252b5132
RH
998 false), /* pcrel_offset */
999
1000 /* Delete a 32 bit instruction. */
1001 /* FIXME: Not handled correctly. */
1002 HOWTO (R_MIPS_DELETE, /* type */
1003 0, /* rightshift */
77bfe34f
TS
1004 2, /* size (0 = byte, 1 = short, 2 = long) */
1005 32, /* bitsize */
252b5132
RH
1006 false, /* pc_relative */
1007 0, /* bitpos */
1008 complain_overflow_dont, /* complain_on_overflow */
1009 bfd_elf_generic_reloc, /* special_function */
1010 "R_MIPS_DELETE", /* name */
1011 false, /* partial_inplace */
1012 0, /* src_mask */
77bfe34f 1013 0xffffffff, /* dst_mask */
252b5132
RH
1014 false), /* pcrel_offset */
1015
1016 /* Get the higher value of a 64 bit addend. */
252b5132
RH
1017 HOWTO (R_MIPS_HIGHER, /* type */
1018 0, /* rightshift */
1019 2, /* size (0 = byte, 1 = short, 2 = long) */
1020 16, /* bitsize */
1021 false, /* pc_relative */
1022 0, /* bitpos */
1023 complain_overflow_dont, /* complain_on_overflow */
77bfe34f 1024 bfd_elf_generic_reloc, /* special_function */
252b5132 1025 "R_MIPS_HIGHER", /* name */
77bfe34f 1026 false, /* partial_inplace */
252b5132
RH
1027 0, /* src_mask */
1028 0xffff, /* dst_mask */
1029 false), /* pcrel_offset */
1030
1031 /* Get the highest value of a 64 bit addend. */
252b5132
RH
1032 HOWTO (R_MIPS_HIGHEST, /* type */
1033 0, /* rightshift */
1034 2, /* size (0 = byte, 1 = short, 2 = long) */
1035 16, /* bitsize */
1036 false, /* pc_relative */
1037 0, /* bitpos */
1038 complain_overflow_dont, /* complain_on_overflow */
77bfe34f 1039 bfd_elf_generic_reloc, /* special_function */
252b5132 1040 "R_MIPS_HIGHEST", /* name */
77bfe34f 1041 false, /* partial_inplace */
252b5132
RH
1042 0, /* src_mask */
1043 0xffff, /* dst_mask */
1044 false), /* pcrel_offset */
1045
1046 /* High 16 bits of displacement in global offset table. */
1047 /* FIXME: Not handled correctly. */
1048 HOWTO (R_MIPS_CALL_HI16, /* type */
1049 0, /* rightshift */
1050 2, /* size (0 = byte, 1 = short, 2 = long) */
1051 16, /* bitsize */
1052 false, /* pc_relative */
1053 0, /* bitpos */
1054 complain_overflow_dont, /* complain_on_overflow */
1055 bfd_elf_generic_reloc, /* special_function */
1056 "R_MIPS_CALL_HI16", /* name */
77bfe34f 1057 false, /* partial_inplace */
252b5132 1058 0, /* src_mask */
77bfe34f 1059 0xffff, /* dst_mask */
252b5132
RH
1060 false), /* pcrel_offset */
1061
1062 /* Low 16 bits of displacement in global offset table. */
1063 /* FIXME: Not handled correctly. */
1064 HOWTO (R_MIPS_CALL_LO16, /* type */
1065 0, /* rightshift */
1066 2, /* size (0 = byte, 1 = short, 2 = long) */
1067 16, /* bitsize */
1068 false, /* pc_relative */
1069 0, /* bitpos */
1070 complain_overflow_dont, /* complain_on_overflow */
1071 bfd_elf_generic_reloc, /* special_function */
1072 "R_MIPS_CALL_LO16", /* name */
77bfe34f 1073 false, /* partial_inplace */
252b5132 1074 0, /* src_mask */
77bfe34f 1075 0xffff, /* dst_mask */
252b5132
RH
1076 false), /* pcrel_offset */
1077
1078 /* I'm not sure what the remaining relocs are, but they are defined
1079 on Irix 6. */
1080
1081 HOWTO (R_MIPS_SCN_DISP, /* type */
1082 0, /* rightshift */
77bfe34f
TS
1083 2, /* size (0 = byte, 1 = short, 2 = long) */
1084 32, /* bitsize */
252b5132
RH
1085 false, /* pc_relative */
1086 0, /* bitpos */
1087 complain_overflow_dont, /* complain_on_overflow */
1088 bfd_elf_generic_reloc, /* special_function */
1089 "R_MIPS_SCN_DISP", /* name */
1090 false, /* partial_inplace */
1091 0, /* src_mask */
77bfe34f 1092 0xffffffff, /* dst_mask */
252b5132
RH
1093 false), /* pcrel_offset */
1094
1095 HOWTO (R_MIPS_REL16, /* type */
1096 0, /* rightshift */
77bfe34f
TS
1097 1, /* size (0 = byte, 1 = short, 2 = long) */
1098 16, /* bitsize */
252b5132
RH
1099 false, /* pc_relative */
1100 0, /* bitpos */
77bfe34f 1101 complain_overflow_signed, /* complain_on_overflow */
252b5132
RH
1102 bfd_elf_generic_reloc, /* special_function */
1103 "R_MIPS_REL16", /* name */
1104 false, /* partial_inplace */
1105 0, /* src_mask */
77bfe34f 1106 0xffff, /* dst_mask */
252b5132
RH
1107 false), /* pcrel_offset */
1108
77bfe34f
TS
1109 /* These two are obsolete. */
1110 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1111 EMPTY_HOWTO (R_MIPS_PJUMP),
252b5132
RH
1112
1113 HOWTO (R_MIPS_RELGOT, /* type */
1114 0, /* rightshift */
77bfe34f
TS
1115 2, /* size (0 = byte, 1 = short, 2 = long) */
1116 32, /* bitsize */
252b5132
RH
1117 false, /* pc_relative */
1118 0, /* bitpos */
1119 complain_overflow_dont, /* complain_on_overflow */
1120 bfd_elf_generic_reloc, /* special_function */
1121 "R_MIPS_RELGOT", /* name */
1122 false, /* partial_inplace */
1123 0, /* src_mask */
77bfe34f 1124 0xffffffff, /* dst_mask */
d2905643
MM
1125 false), /* pcrel_offset */
1126
fe8bc63d 1127 /* Protected jump conversion. This is an optimization hint. No
d2905643
MM
1128 relocation is required for correctness. */
1129 HOWTO (R_MIPS_JALR, /* type */
1130 0, /* rightshift */
77bfe34f 1131 2, /* size (0 = byte, 1 = short, 2 = long) */
d2905643
MM
1132 0, /* bitsize */
1133 false, /* pc_relative */
1134 0, /* bitpos */
1135 complain_overflow_dont, /* complain_on_overflow */
1136 bfd_elf_generic_reloc, /* special_function */
1137 "R_MIPS_JALR", /* name */
1138 false, /* partial_inplace */
77bfe34f
TS
1139 0, /* src_mask */
1140 0, /* dst_mask */
d2905643 1141 false), /* pcrel_offset */
252b5132
RH
1142};
1143
1144/* Swap in a MIPS 64-bit Rel reloc. */
1145
1146static void
1147mips_elf64_swap_reloc_in (abfd, src, dst)
1148 bfd *abfd;
1149 const Elf64_Mips_External_Rel *src;
1150 Elf64_Mips_Internal_Rel *dst;
1151{
dc810e39
AM
1152 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1153 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1154 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1155 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1156 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1157 dst->r_type = H_GET_8 (abfd, src->r_type);
252b5132
RH
1158}
1159
1160/* Swap in a MIPS 64-bit Rela reloc. */
1161
1162static void
1163mips_elf64_swap_reloca_in (abfd, src, dst)
1164 bfd *abfd;
1165 const Elf64_Mips_External_Rela *src;
1166 Elf64_Mips_Internal_Rela *dst;
1167{
dc810e39
AM
1168 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1169 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1170 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1171 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1172 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1173 dst->r_type = H_GET_8 (abfd, src->r_type);
1174 dst->r_addend = H_GET_S64 (abfd, src->r_addend);
252b5132
RH
1175}
1176
252b5132
RH
1177/* Swap out a MIPS 64-bit Rel reloc. */
1178
1179static void
1180mips_elf64_swap_reloc_out (abfd, src, dst)
1181 bfd *abfd;
1182 const Elf64_Mips_Internal_Rel *src;
1183 Elf64_Mips_External_Rel *dst;
1184{
dc810e39
AM
1185 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1186 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1187 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1188 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1189 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1190 H_PUT_8 (abfd, src->r_type, dst->r_type);
252b5132
RH
1191}
1192
252b5132
RH
1193/* Swap out a MIPS 64-bit Rela reloc. */
1194
1195static void
1196mips_elf64_swap_reloca_out (abfd, src, dst)
1197 bfd *abfd;
1198 const Elf64_Mips_Internal_Rela *src;
1199 Elf64_Mips_External_Rela *dst;
1200{
dc810e39
AM
1201 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1202 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1203 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1204 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1205 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1206 H_PUT_8 (abfd, src->r_type, dst->r_type);
1207 H_PUT_64 (abfd, src->r_addend, dst->r_addend);
252b5132
RH
1208}
1209
c7ac6ff8
MM
1210/* Swap in a MIPS 64-bit Rel reloc. */
1211
1212static void
1213mips_elf64_be_swap_reloc_in (abfd, src, dst)
1214 bfd *abfd;
1215 const bfd_byte *src;
1216 Elf_Internal_Rel *dst;
1217{
1218 Elf64_Mips_Internal_Rel mirel;
1219
fe8bc63d 1220 mips_elf64_swap_reloc_in (abfd,
c7ac6ff8
MM
1221 (const Elf64_Mips_External_Rel *) src,
1222 &mirel);
1223
1224 dst[0].r_offset = mirel.r_offset;
1225 dst[0].r_info = ELF32_R_INFO (mirel.r_sym, mirel.r_type);
1226 dst[1].r_offset = mirel.r_offset;
1227 dst[1].r_info = ELF32_R_INFO (mirel.r_ssym, mirel.r_type2);
1228 dst[2].r_offset = mirel.r_offset;
1229 dst[2].r_info = ELF32_R_INFO (STN_UNDEF, mirel.r_type3);
1230}
1231
1232/* Swap in a MIPS 64-bit Rela reloc. */
1233
1234static void
1235mips_elf64_be_swap_reloca_in (abfd, src, dst)
1236 bfd *abfd;
1237 const bfd_byte *src;
1238 Elf_Internal_Rela *dst;
1239{
1240 Elf64_Mips_Internal_Rela mirela;
1241
fe8bc63d 1242 mips_elf64_swap_reloca_in (abfd,
c7ac6ff8
MM
1243 (const Elf64_Mips_External_Rela *) src,
1244 &mirela);
1245
1246 dst[0].r_offset = mirela.r_offset;
1247 dst[0].r_info = ELF32_R_INFO (mirela.r_sym, mirela.r_type);
1248 dst[0].r_addend = mirela.r_addend;
1249 dst[1].r_offset = mirela.r_offset;
1250 dst[1].r_info = ELF32_R_INFO (mirela.r_ssym, mirela.r_type2);
1251 dst[1].r_addend = 0;
1252 dst[2].r_offset = mirela.r_offset;
1253 dst[2].r_info = ELF32_R_INFO (STN_UNDEF, mirela.r_type3);
1254 dst[2].r_addend = 0;
1255}
1256
1257/* Swap out a MIPS 64-bit Rel reloc. */
1258
1259static void
1260mips_elf64_be_swap_reloc_out (abfd, src, dst)
1261 bfd *abfd;
1262 const Elf_Internal_Rel *src;
1263 bfd_byte *dst;
1264{
1265 Elf64_Mips_Internal_Rel mirel;
1266
1267 mirel.r_offset = src->r_offset;
1268 mirel.r_type = ELF32_R_TYPE (src->r_info);
1269 mirel.r_sym = ELF32_R_SYM (src->r_info);
1270 mirel.r_type2 = R_MIPS_NONE;
1271 mirel.r_ssym = STN_UNDEF;
1272 mirel.r_type3 = R_MIPS_NONE;
1273
fe8bc63d 1274 mips_elf64_swap_reloc_out (abfd, &mirel,
c7ac6ff8
MM
1275 (Elf64_Mips_External_Rel *) dst);
1276}
1277
1278/* Swap out a MIPS 64-bit Rela reloc. */
1279
1280static void
1281mips_elf64_be_swap_reloca_out (abfd, src, dst)
1282 bfd *abfd;
1283 const Elf_Internal_Rela *src;
1284 bfd_byte *dst;
1285{
1286 Elf64_Mips_Internal_Rela mirela;
1287
1288 mirela.r_offset = src->r_offset;
1289 mirela.r_type = ELF32_R_TYPE (src->r_info);
1290 mirela.r_addend = src->r_addend;
1291 mirela.r_sym = ELF32_R_SYM (src->r_info);
1292 mirela.r_type2 = R_MIPS_NONE;
1293 mirela.r_ssym = STN_UNDEF;
1294 mirela.r_type3 = R_MIPS_NONE;
1295
fe8bc63d 1296 mips_elf64_swap_reloca_out (abfd, &mirela,
c7ac6ff8
MM
1297 (Elf64_Mips_External_Rela *) dst);
1298}
1299
252b5132
RH
1300/* A mapping from BFD reloc types to MIPS ELF reloc types. */
1301
1302struct elf_reloc_map
1303{
1304 bfd_reloc_code_real_type bfd_reloc_val;
1305 enum elf_mips_reloc_type elf_reloc_val;
1306};
1307
dc810e39 1308static const struct elf_reloc_map mips_reloc_map[] =
252b5132
RH
1309{
1310 { BFD_RELOC_NONE, R_MIPS_NONE, },
1311 { BFD_RELOC_16, R_MIPS_16 },
1312 { BFD_RELOC_32, R_MIPS_32 },
1313 { BFD_RELOC_64, R_MIPS_64 },
1314 { BFD_RELOC_CTOR, R_MIPS_64 },
1315 { BFD_RELOC_32_PCREL, R_MIPS_REL32 },
1316 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1317 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1318 { BFD_RELOC_LO16, R_MIPS_LO16 },
cdf6fd85 1319 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
252b5132
RH
1320 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1321 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1322 { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
1323 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
cdf6fd85 1324 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
252b5132
RH
1325 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1326 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1327 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
3f830999
MM
1328 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1329 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1330 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1331 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1332 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP }
252b5132
RH
1333};
1334
1335/* Given a BFD reloc type, return a howto structure. */
1336
1337static reloc_howto_type *
1338mips_elf64_reloc_type_lookup (abfd, code)
56fc028e 1339 bfd *abfd ATTRIBUTE_UNUSED;
252b5132
RH
1340 bfd_reloc_code_real_type code;
1341{
1342 unsigned int i;
1343
1344 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); i++)
1345 {
1346 if (mips_reloc_map[i].bfd_reloc_val == code)
1347 {
1348 int v;
1349
1350 v = (int) mips_reloc_map[i].elf_reloc_val;
1351 return &mips_elf64_howto_table_rel[v];
1352 }
1353 }
1354
1355 return NULL;
1356}
1357
1358/* Since each entry in an SHT_REL or SHT_RELA section can represent up
1359 to three relocs, we must tell the user to allocate more space. */
1360
1361static long
1362mips_elf64_get_reloc_upper_bound (abfd, sec)
56fc028e 1363 bfd *abfd ATTRIBUTE_UNUSED;
252b5132
RH
1364 asection *sec;
1365{
1366 return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
1367}
1368
1369/* Read the relocations from one reloc section. */
1370
1371static boolean
1372mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, rel_hdr)
1373 bfd *abfd;
1374 asection *asect;
1375 asymbol **symbols;
1376 const Elf_Internal_Shdr *rel_hdr;
1377{
1378 PTR allocated = NULL;
1379 bfd_byte *native_relocs;
1380 arelent *relents;
1381 arelent *relent;
1382 unsigned int count;
1383 unsigned int i;
1384 int entsize;
1385 reloc_howto_type *howto_table;
1386
1387 allocated = (PTR) bfd_malloc (rel_hdr->sh_size);
1388 if (allocated == NULL)
dc810e39 1389 return false;
252b5132
RH
1390
1391 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
dc810e39 1392 || (bfd_bread (allocated, rel_hdr->sh_size, abfd) != rel_hdr->sh_size))
252b5132
RH
1393 goto error_return;
1394
1395 native_relocs = (bfd_byte *) allocated;
1396
1397 relents = asect->relocation + asect->reloc_count;
1398
1399 entsize = rel_hdr->sh_entsize;
1400 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
1401 || entsize == sizeof (Elf64_Mips_External_Rela));
1402
1403 count = rel_hdr->sh_size / entsize;
1404
1405 if (entsize == sizeof (Elf64_Mips_External_Rel))
1406 howto_table = mips_elf64_howto_table_rel;
1407 else
1408 howto_table = mips_elf64_howto_table_rela;
1409
1410 relent = relents;
1411 for (i = 0; i < count; i++, native_relocs += entsize)
1412 {
1413 Elf64_Mips_Internal_Rela rela;
1414 boolean used_sym, used_ssym;
1415 int ir;
1416
1417 if (entsize == sizeof (Elf64_Mips_External_Rela))
1418 mips_elf64_swap_reloca_in (abfd,
1419 (Elf64_Mips_External_Rela *) native_relocs,
1420 &rela);
1421 else
1422 {
1423 Elf64_Mips_Internal_Rel rel;
1424
1425 mips_elf64_swap_reloc_in (abfd,
1426 (Elf64_Mips_External_Rel *) native_relocs,
1427 &rel);
1428 rela.r_offset = rel.r_offset;
1429 rela.r_sym = rel.r_sym;
1430 rela.r_ssym = rel.r_ssym;
1431 rela.r_type3 = rel.r_type3;
1432 rela.r_type2 = rel.r_type2;
1433 rela.r_type = rel.r_type;
1434 rela.r_addend = 0;
1435 }
1436
1437 /* Each entry represents up to three actual relocations. */
1438
1439 used_sym = false;
1440 used_ssym = false;
1441 for (ir = 0; ir < 3; ir++)
1442 {
1443 enum elf_mips_reloc_type type;
1444
1445 switch (ir)
1446 {
1447 default:
1448 abort ();
1449 case 0:
1450 type = (enum elf_mips_reloc_type) rela.r_type;
1451 break;
1452 case 1:
1453 type = (enum elf_mips_reloc_type) rela.r_type2;
1454 break;
1455 case 2:
1456 type = (enum elf_mips_reloc_type) rela.r_type3;
1457 break;
1458 }
1459
1460 if (type == R_MIPS_NONE)
1461 {
1462 /* There are no more relocations in this entry. If this
1463 is the first entry, we need to generate a dummy
1464 relocation so that the generic linker knows that
1465 there has been a break in the sequence of relocations
1466 applying to a particular address. */
1467 if (ir == 0)
1468 {
1469 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1470 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
1471 relent->address = rela.r_offset;
1472 else
1473 relent->address = rela.r_offset - asect->vma;
1474 relent->addend = 0;
1475 relent->howto = &howto_table[(int) R_MIPS_NONE];
1476 ++relent;
1477 }
1478 break;
1479 }
1480
1481 /* Some types require symbols, whereas some do not. */
1482 switch (type)
1483 {
1484 case R_MIPS_NONE:
1485 case R_MIPS_LITERAL:
1486 case R_MIPS_INSERT_A:
1487 case R_MIPS_INSERT_B:
1488 case R_MIPS_DELETE:
1489 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1490 break;
1491
1492 default:
1493 if (! used_sym)
1494 {
1495 if (rela.r_sym == 0)
1496 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1497 else
1498 {
1499 asymbol **ps, *s;
1500
1501 ps = symbols + rela.r_sym - 1;
1502 s = *ps;
1503 if ((s->flags & BSF_SECTION_SYM) == 0)
1504 relent->sym_ptr_ptr = ps;
1505 else
1506 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
1507 }
1508
1509 used_sym = true;
1510 }
1511 else if (! used_ssym)
1512 {
1513 switch (rela.r_ssym)
1514 {
1515 case RSS_UNDEF:
1516 relent->sym_ptr_ptr =
1517 bfd_abs_section_ptr->symbol_ptr_ptr;
1518 break;
1519
1520 case RSS_GP:
1521 case RSS_GP0:
1522 case RSS_LOC:
1523 /* FIXME: I think these need to be handled using
1524 special howto structures. */
1525 BFD_ASSERT (0);
1526 break;
1527
1528 default:
1529 BFD_ASSERT (0);
1530 break;
1531 }
1532
1533 used_ssym = true;
1534 }
1535 else
1536 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1537
1538 break;
1539 }
1540
1541 /* The address of an ELF reloc is section relative for an
1542 object file, and absolute for an executable file or
1543 shared library. The address of a BFD reloc is always
1544 section relative. */
1545 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
1546 relent->address = rela.r_offset;
1547 else
1548 relent->address = rela.r_offset - asect->vma;
1549
1550 relent->addend = rela.r_addend;
1551
1552 relent->howto = &howto_table[(int) type];
1553
1554 ++relent;
1555 }
1556 }
1557
1558 asect->reloc_count += relent - relents;
1559
1560 if (allocated != NULL)
1561 free (allocated);
1562
1563 return true;
1564
1565 error_return:
1566 if (allocated != NULL)
1567 free (allocated);
1568 return false;
1569}
1570
1571/* Read the relocations. On Irix 6, there can be two reloc sections
1572 associated with a single data section. */
1573
1574static boolean
1575mips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic)
1576 bfd *abfd;
1577 asection *asect;
1578 asymbol **symbols;
1579 boolean dynamic;
1580{
dc810e39 1581 bfd_size_type amt;
252b5132
RH
1582 struct bfd_elf_section_data * const d = elf_section_data (asect);
1583
1584 if (dynamic)
1585 {
1586 bfd_set_error (bfd_error_invalid_operation);
1587 return false;
1588 }
1589
1590 if (asect->relocation != NULL
1591 || (asect->flags & SEC_RELOC) == 0
1592 || asect->reloc_count == 0)
1593 return true;
1594
1595 /* Allocate space for 3 arelent structures for each Rel structure. */
dc810e39
AM
1596 amt = asect->reloc_count;
1597 amt *= 3 * sizeof (arelent);
1598 asect->relocation = (arelent *) bfd_alloc (abfd, amt);
252b5132
RH
1599 if (asect->relocation == NULL)
1600 return false;
1601
1602 /* The slurp_one_reloc_table routine increments reloc_count. */
1603 asect->reloc_count = 0;
1604
1605 if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, &d->rel_hdr))
1606 return false;
1607 if (d->rel_hdr2 != NULL)
1608 {
1609 if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols,
1610 d->rel_hdr2))
1611 return false;
1612 }
1613
1614 return true;
1615}
1616
1617/* Write out the relocations. */
1618
1619static void
1620mips_elf64_write_relocs (abfd, sec, data)
1621 bfd *abfd;
1622 asection *sec;
1623 PTR data;
1624{
1625 boolean *failedp = (boolean *) data;
1626 unsigned int count;
1627 Elf_Internal_Shdr *rela_hdr;
1628 Elf64_Mips_External_Rela *ext_rela;
1629 unsigned int idx;
1630 asymbol *last_sym = 0;
1631 int last_sym_idx = 0;
1632
1633 /* If we have already failed, don't do anything. */
1634 if (*failedp)
1635 return;
1636
1637 if ((sec->flags & SEC_RELOC) == 0)
1638 return;
1639
1640 /* The linker backend writes the relocs out itself, and sets the
1641 reloc_count field to zero to inhibit writing them here. Also,
1642 sometimes the SEC_RELOC flag gets set even when there aren't any
1643 relocs. */
1644 if (sec->reloc_count == 0)
1645 return;
1646
1647 /* We can combine up to three relocs that refer to the same address
1648 if the latter relocs have no associated symbol. */
1649 count = 0;
1650 for (idx = 0; idx < sec->reloc_count; idx++)
1651 {
1652 bfd_vma addr;
1653 unsigned int i;
1654
1655 ++count;
1656
1657 addr = sec->orelocation[idx]->address;
1658 for (i = 0; i < 2; i++)
1659 {
1660 arelent *r;
1661
1662 if (idx + 1 >= sec->reloc_count)
1663 break;
1664 r = sec->orelocation[idx + 1];
1665 if (r->address != addr
1666 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
1667 || (*r->sym_ptr_ptr)->value != 0)
1668 break;
1669
1670 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
1671
1672 ++idx;
1673 }
1674 }
1675
1676 rela_hdr = &elf_section_data (sec)->rel_hdr;
1677
1678 rela_hdr->sh_size = rela_hdr->sh_entsize * count;
1679 rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
1680 if (rela_hdr->contents == NULL)
1681 {
1682 *failedp = true;
1683 return;
1684 }
1685
1686 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
1687 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
1688 {
1689 arelent *ptr;
1690 Elf64_Mips_Internal_Rela int_rela;
1691 asymbol *sym;
1692 int n;
1693 unsigned int i;
1694
1695 ptr = sec->orelocation[idx];
1696
1697 /* The address of an ELF reloc is section relative for an object
1698 file, and absolute for an executable file or shared library.
1699 The address of a BFD reloc is always section relative. */
1700 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
1701 int_rela.r_offset = ptr->address;
1702 else
1703 int_rela.r_offset = ptr->address + sec->vma;
1704
1705 sym = *ptr->sym_ptr_ptr;
1706 if (sym == last_sym)
1707 n = last_sym_idx;
1708 else
1709 {
1710 last_sym = sym;
1711 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
1712 if (n < 0)
1713 {
1714 *failedp = true;
1715 return;
1716 }
1717 last_sym_idx = n;
1718 }
1719
1720 int_rela.r_sym = n;
1721
1722 int_rela.r_addend = ptr->addend;
1723
1724 int_rela.r_ssym = RSS_UNDEF;
1725
1726 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
1727 && ! _bfd_elf_validate_reloc (abfd, ptr))
1728 {
1729 *failedp = true;
1730 return;
1731 }
1732
1733 int_rela.r_type = ptr->howto->type;
1734 int_rela.r_type2 = (int) R_MIPS_NONE;
1735 int_rela.r_type3 = (int) R_MIPS_NONE;
1736
1737 for (i = 0; i < 2; i++)
1738 {
1739 arelent *r;
1740
1741 if (idx + 1 >= sec->reloc_count)
1742 break;
1743 r = sec->orelocation[idx + 1];
1744 if (r->address != ptr->address
1745 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
1746 || (*r->sym_ptr_ptr)->value != 0)
1747 break;
1748
1749 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
1750
1751 if (i == 0)
1752 int_rela.r_type2 = r->howto->type;
1753 else
1754 int_rela.r_type3 = r->howto->type;
1755
1756 ++idx;
1757 }
1758
1759 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
1760 }
1761
1762 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
5e572849 1763 == (int) count);
252b5132
RH
1764}
1765\f
252b5132
RH
1766/* ECOFF swapping routines. These are used when dealing with the
1767 .mdebug section, which is in the ECOFF debugging format. */
1768static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
1769{
1770 /* Symbol table magic number. */
1771 magicSym2,
1772 /* Alignment of debugging information. E.g., 4. */
1773 8,
1774 /* Sizes of external symbolic information. */
1775 sizeof (struct hdr_ext),
1776 sizeof (struct dnr_ext),
1777 sizeof (struct pdr_ext),
1778 sizeof (struct sym_ext),
1779 sizeof (struct opt_ext),
1780 sizeof (struct fdr_ext),
1781 sizeof (struct rfd_ext),
1782 sizeof (struct ext_ext),
1783 /* Functions to swap in external symbolic data. */
1784 ecoff_swap_hdr_in,
1785 ecoff_swap_dnr_in,
1786 ecoff_swap_pdr_in,
1787 ecoff_swap_sym_in,
1788 ecoff_swap_opt_in,
1789 ecoff_swap_fdr_in,
1790 ecoff_swap_rfd_in,
1791 ecoff_swap_ext_in,
1792 _bfd_ecoff_swap_tir_in,
1793 _bfd_ecoff_swap_rndx_in,
1794 /* Functions to swap out external symbolic data. */
1795 ecoff_swap_hdr_out,
1796 ecoff_swap_dnr_out,
1797 ecoff_swap_pdr_out,
1798 ecoff_swap_sym_out,
1799 ecoff_swap_opt_out,
1800 ecoff_swap_fdr_out,
1801 ecoff_swap_rfd_out,
1802 ecoff_swap_ext_out,
1803 _bfd_ecoff_swap_tir_out,
1804 _bfd_ecoff_swap_rndx_out,
1805 /* Function to read in symbolic data. */
1806 _bfd_mips_elf_read_ecoff_info
1807};
1808\f
1809/* Relocations in the 64 bit MIPS ELF ABI are more complex than in
1810 standard ELF. This structure is used to redirect the relocation
1811 handling routines. */
1812
1813const struct elf_size_info mips_elf64_size_info =
1814{
1815 sizeof (Elf64_External_Ehdr),
1816 sizeof (Elf64_External_Phdr),
1817 sizeof (Elf64_External_Shdr),
1818 sizeof (Elf64_Mips_External_Rel),
1819 sizeof (Elf64_Mips_External_Rela),
1820 sizeof (Elf64_External_Sym),
1821 sizeof (Elf64_External_Dyn),
1822 sizeof (Elf_External_Note),
c7ac6ff8
MM
1823 4, /* hash-table entry size */
1824 3, /* internal relocations per external relocations */
252b5132
RH
1825 64, /* arch_size */
1826 8, /* file_align */
1827 ELFCLASS64,
1828 EV_CURRENT,
1829 bfd_elf64_write_out_phdrs,
1830 bfd_elf64_write_shdrs_and_ehdr,
1831 mips_elf64_write_relocs,
1832 bfd_elf64_swap_symbol_out,
1833 mips_elf64_slurp_reloc_table,
1834 bfd_elf64_slurp_symbol_table,
c7ac6ff8
MM
1835 bfd_elf64_swap_dyn_in,
1836 bfd_elf64_swap_dyn_out,
1837 mips_elf64_be_swap_reloc_in,
1838 mips_elf64_be_swap_reloc_out,
1839 mips_elf64_be_swap_reloca_in,
1840 mips_elf64_be_swap_reloca_out
252b5132
RH
1841};
1842
1843#define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
1844#define TARGET_LITTLE_NAME "elf64-littlemips"
1845#define TARGET_BIG_SYM bfd_elf64_bigmips_vec
1846#define TARGET_BIG_NAME "elf64-bigmips"
1847#define ELF_ARCH bfd_arch_mips
1848#define ELF_MACHINE_CODE EM_MIPS
103186c6 1849
252b5132 1850#define ELF_MAXPAGESIZE 0x1000
103186c6
MM
1851
1852#define elf_backend_collect true
1853#define elf_backend_type_change_ok true
1854#define elf_backend_can_gc_sections true
252b5132
RH
1855#define elf_backend_size_info mips_elf64_size_info
1856#define elf_backend_object_p _bfd_mips_elf_object_p
103186c6 1857#define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
252b5132
RH
1858#define elf_backend_fake_sections _bfd_mips_elf_fake_sections
1859#define elf_backend_section_from_bfd_section \
1860 _bfd_mips_elf_section_from_bfd_section
103186c6 1861#define elf_backend_section_processing _bfd_mips_elf_section_processing
252b5132 1862#define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
103186c6
MM
1863#define elf_backend_additional_program_headers \
1864 _bfd_mips_elf_additional_program_headers
1865#define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
252b5132
RH
1866#define elf_backend_final_write_processing \
1867 _bfd_mips_elf_final_write_processing
1868#define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
103186c6
MM
1869#define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
1870#define elf_backend_create_dynamic_sections \
1871 _bfd_mips_elf_create_dynamic_sections
1872#define elf_backend_check_relocs _bfd_mips_elf_check_relocs
1873#define elf_backend_adjust_dynamic_symbol \
1874 _bfd_mips_elf_adjust_dynamic_symbol
1875#define elf_backend_always_size_sections \
1876 _bfd_mips_elf_always_size_sections
1877#define elf_backend_size_dynamic_sections \
1878 _bfd_mips_elf_size_dynamic_sections
1879#define elf_backend_relocate_section _bfd_mips_elf_relocate_section
1880#define elf_backend_link_output_symbol_hook \
1881 _bfd_mips_elf_link_output_symbol_hook
1882#define elf_backend_finish_dynamic_symbol \
1883 _bfd_mips_elf_finish_dynamic_symbol
1884#define elf_backend_finish_dynamic_sections \
1885 _bfd_mips_elf_finish_dynamic_sections
1886#define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
1887#define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
1888#define elf_backend_got_header_size (4*MIPS_RESERVED_GOTNO)
1889#define elf_backend_plt_header_size 0
1e2be829
TS
1890
1891/* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
1892 * work better/work only in RELA, so we default to this. */
1893#define elf_backend_may_use_rel_p 1
1894#define elf_backend_may_use_rela_p 1
1895#define elf_backend_default_use_rela_p 1
103186c6 1896
fe8bc63d 1897/* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
103186c6
MM
1898 MIPS-specific function only applies to IRIX5, which had no 64-bit
1899 ABI. */
252b5132 1900#define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
252b5132 1901#define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
103186c6
MM
1902#define bfd_elf64_bfd_link_hash_table_create \
1903 _bfd_mips_elf_link_hash_table_create
1904#define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
252b5132
RH
1905#define bfd_elf64_bfd_copy_private_bfd_data \
1906 _bfd_mips_elf_copy_private_bfd_data
1907#define bfd_elf64_bfd_merge_private_bfd_data \
1908 _bfd_mips_elf_merge_private_bfd_data
1909#define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
103186c6
MM
1910#define bfd_elf64_bfd_print_private_bfd_data \
1911 _bfd_mips_elf_print_private_bfd_data
252b5132 1912
103186c6
MM
1913#define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
1914#define bfd_elf64_bfd_reloc_type_lookup mips_elf64_reloc_type_lookup
252b5132 1915#define bfd_elf64_archive_functions
36b45482
TS
1916extern boolean bfd_elf64_archive_slurp_armap
1917 PARAMS((bfd *));
1918extern boolean bfd_elf64_archive_write_armap
1919 PARAMS((bfd *, unsigned int, struct orl *, unsigned int, int));
252b5132
RH
1920#define bfd_elf64_archive_slurp_extended_name_table \
1921 _bfd_archive_coff_slurp_extended_name_table
1922#define bfd_elf64_archive_construct_extended_name_table \
1923 _bfd_archive_coff_construct_extended_name_table
1924#define bfd_elf64_archive_truncate_arname \
1925 _bfd_archive_coff_truncate_arname
252b5132
RH
1926#define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
1927#define bfd_elf64_archive_openr_next_archived_file \
1928 _bfd_archive_coff_openr_next_archived_file
1929#define bfd_elf64_archive_get_elt_at_index \
1930 _bfd_archive_coff_get_elt_at_index
1931#define bfd_elf64_archive_generic_stat_arch_elt \
1932 _bfd_archive_coff_generic_stat_arch_elt
1933#define bfd_elf64_archive_update_armap_timestamp \
1934 _bfd_archive_coff_update_armap_timestamp
1935
1936#include "elf64-target.h"
fdbafa10
L
1937
1938/* Support for traditional mips targets */
1939
1940#define INCLUDED_TARGET_FILE /* More a type of flag */
1941
1942#undef TARGET_LITTLE_SYM
1943#undef TARGET_LITTLE_NAME
1944#undef TARGET_BIG_SYM
1945#undef TARGET_BIG_NAME
1946
1947#define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
1948#define TARGET_LITTLE_NAME "elf64-tradlittlemips"
1949#define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
1950#define TARGET_BIG_NAME "elf64-tradbigmips"
1951
1952/* Include the target file again for this target */
1953#include "elf64-target.h"
This page took 0.183024 seconds and 4 git commands to generate.