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