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