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