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