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