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