* elf32-mips.c (elf_mips_howto_table): Add R_MIPS_JALR.
[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 */
617 false) /* pcrel_offset */
618};
619
620/* The relocation table used for SHT_RELA sections. */
621
622static reloc_howto_type mips_elf64_howto_table_rela[] =
623{
624 /* No relocation. */
625 HOWTO (R_MIPS_NONE, /* type */
626 0, /* rightshift */
627 0, /* size (0 = byte, 1 = short, 2 = long) */
628 0, /* bitsize */
629 false, /* pc_relative */
630 0, /* bitpos */
631 complain_overflow_dont, /* complain_on_overflow */
632 bfd_elf_generic_reloc, /* special_function */
633 "R_MIPS_NONE", /* name */
634 false, /* partial_inplace */
635 0, /* src_mask */
636 0, /* dst_mask */
637 false), /* pcrel_offset */
638
639 /* 16 bit relocation. */
640 HOWTO (R_MIPS_16, /* type */
641 0, /* rightshift */
642 1, /* size (0 = byte, 1 = short, 2 = long) */
643 16, /* bitsize */
644 false, /* pc_relative */
645 0, /* bitpos */
646 complain_overflow_bitfield, /* complain_on_overflow */
647 bfd_elf_generic_reloc, /* special_function */
648 "R_MIPS_16", /* name */
649 true, /* partial_inplace */
650 0, /* src_mask */
651 0xffff, /* dst_mask */
652 false), /* pcrel_offset */
653
654 /* 32 bit relocation. */
655 HOWTO (R_MIPS_32, /* type */
656 0, /* rightshift */
657 2, /* size (0 = byte, 1 = short, 2 = long) */
658 32, /* bitsize */
659 false, /* pc_relative */
660 0, /* bitpos */
661 complain_overflow_bitfield, /* complain_on_overflow */
662 bfd_elf_generic_reloc, /* special_function */
663 "R_MIPS_32", /* name */
664 true, /* partial_inplace */
665 0, /* src_mask */
666 0xffffffff, /* dst_mask */
667 false), /* pcrel_offset */
668
669 /* 32 bit symbol relative relocation. */
670 HOWTO (R_MIPS_REL32, /* type */
671 0, /* rightshift */
672 2, /* size (0 = byte, 1 = short, 2 = long) */
673 32, /* bitsize */
674 false, /* pc_relative */
675 0, /* bitpos */
676 complain_overflow_bitfield, /* complain_on_overflow */
677 bfd_elf_generic_reloc, /* special_function */
678 "R_MIPS_REL32", /* name */
679 true, /* partial_inplace */
680 0, /* src_mask */
681 0xffffffff, /* dst_mask */
682 false), /* pcrel_offset */
683
684 /* 26 bit branch address. */
685 HOWTO (R_MIPS_26, /* type */
686 2, /* rightshift */
687 2, /* size (0 = byte, 1 = short, 2 = long) */
688 26, /* bitsize */
689 false, /* pc_relative */
690 0, /* bitpos */
691 complain_overflow_dont, /* complain_on_overflow */
692 /* This needs complex overflow
693 detection, because the upper four
694 bits must match the PC. */
695 bfd_elf_generic_reloc, /* special_function */
696 "R_MIPS_26", /* name */
697 true, /* partial_inplace */
698 0, /* src_mask */
699 0x3ffffff, /* dst_mask */
700 false), /* pcrel_offset */
701
702 /* High 16 bits of symbol value. */
703 HOWTO (R_MIPS_HI16, /* type */
704 0, /* rightshift */
705 2, /* size (0 = byte, 1 = short, 2 = long) */
706 16, /* bitsize */
707 false, /* pc_relative */
708 0, /* bitpos */
709 complain_overflow_dont, /* complain_on_overflow */
710 bfd_elf_generic_reloc, /* special_function */
711 "R_MIPS_HI16", /* name */
712 true, /* partial_inplace */
713 0, /* src_mask */
714 0xffff, /* dst_mask */
715 false), /* pcrel_offset */
716
717 /* Low 16 bits of symbol value. */
718 HOWTO (R_MIPS_LO16, /* type */
719 0, /* rightshift */
720 2, /* size (0 = byte, 1 = short, 2 = long) */
721 16, /* bitsize */
722 false, /* pc_relative */
723 0, /* bitpos */
724 complain_overflow_dont, /* complain_on_overflow */
725 bfd_elf_generic_reloc, /* special_function */
726 "R_MIPS_LO16", /* name */
727 true, /* partial_inplace */
728 0, /* src_mask */
729 0xffff, /* dst_mask */
730 false), /* pcrel_offset */
731
732 /* GP relative reference. */
733 HOWTO (R_MIPS_GPREL16, /* type */
734 0, /* rightshift */
735 2, /* size (0 = byte, 1 = short, 2 = long) */
736 16, /* bitsize */
737 false, /* pc_relative */
738 0, /* bitpos */
739 complain_overflow_signed, /* complain_on_overflow */
740 _bfd_mips_elf_gprel16_reloc, /* special_function */
741 "R_MIPS_GPREL16", /* name */
742 true, /* partial_inplace */
743 0, /* src_mask */
744 0xffff, /* dst_mask */
745 false), /* pcrel_offset */
746
747 /* Reference to literal section. */
748 HOWTO (R_MIPS_LITERAL, /* type */
749 0, /* rightshift */
750 2, /* size (0 = byte, 1 = short, 2 = long) */
751 16, /* bitsize */
752 false, /* pc_relative */
753 0, /* bitpos */
754 complain_overflow_signed, /* complain_on_overflow */
755 _bfd_mips_elf_gprel16_reloc, /* special_function */
756 "R_MIPS_LITERAL", /* name */
757 true, /* partial_inplace */
758 0, /* src_mask */
759 0xffff, /* dst_mask */
760 false), /* pcrel_offset */
761
762 /* Reference to global offset table. */
763 /* FIXME: This is not handled correctly. */
764 HOWTO (R_MIPS_GOT16, /* 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_elf_generic_reloc, /* special_function */
772 "R_MIPS_GOT16", /* name */
773 false, /* partial_inplace */
774 0, /* src_mask */
775 0xffff, /* dst_mask */
776 false), /* pcrel_offset */
777
778 /* 16 bit PC relative reference. */
779 HOWTO (R_MIPS_PC16, /* type */
780 0, /* rightshift */
781 2, /* size (0 = byte, 1 = short, 2 = long) */
782 16, /* bitsize */
783 true, /* pc_relative */
784 0, /* bitpos */
785 complain_overflow_signed, /* complain_on_overflow */
786 bfd_elf_generic_reloc, /* special_function */
787 "R_MIPS_PC16", /* name */
788 true, /* partial_inplace */
789 0, /* src_mask */
790 0xffff, /* dst_mask */
791 false), /* pcrel_offset */
792
793 /* 16 bit call through global offset table. */
794 /* FIXME: This is not handled correctly. */
795 HOWTO (R_MIPS_CALL16, /* type */
796 0, /* rightshift */
797 2, /* size (0 = byte, 1 = short, 2 = long) */
798 16, /* bitsize */
799 false, /* pc_relative */
800 0, /* bitpos */
801 complain_overflow_signed, /* complain_on_overflow */
802 bfd_elf_generic_reloc, /* special_function */
803 "R_MIPS_CALL16", /* name */
804 false, /* partial_inplace */
805 0, /* src_mask */
806 0xffff, /* dst_mask */
807 false), /* pcrel_offset */
808
809 /* 32 bit GP relative reference. */
810 HOWTO (R_MIPS_GPREL32, /* type */
811 0, /* rightshift */
812 2, /* size (0 = byte, 1 = short, 2 = long) */
813 32, /* bitsize */
814 false, /* pc_relative */
815 0, /* bitpos */
816 complain_overflow_bitfield, /* complain_on_overflow */
817 _bfd_mips_elf_gprel32_reloc, /* special_function */
818 "R_MIPS_GPREL32", /* name */
819 true, /* partial_inplace */
820 0, /* src_mask */
821 0xffffffff, /* dst_mask */
822 false), /* pcrel_offset */
823
824 { 13 },
825 { 14 },
826 { 15 },
827
828 /* A 5 bit shift field. */
829 HOWTO (R_MIPS_SHIFT5, /* type */
830 0, /* rightshift */
831 2, /* size (0 = byte, 1 = short, 2 = long) */
832 5, /* bitsize */
833 false, /* pc_relative */
834 6, /* bitpos */
835 complain_overflow_bitfield, /* complain_on_overflow */
836 bfd_elf_generic_reloc, /* special_function */
837 "R_MIPS_SHIFT5", /* name */
838 true, /* partial_inplace */
839 0, /* src_mask */
840 0x000007c0, /* dst_mask */
841 false), /* pcrel_offset */
842
843 /* A 6 bit shift field. */
844 /* FIXME: This is not handled correctly; a special function is
845 needed to put the most significant bit in the right place. */
846 HOWTO (R_MIPS_SHIFT6, /* type */
847 0, /* rightshift */
848 2, /* size (0 = byte, 1 = short, 2 = long) */
849 6, /* bitsize */
850 false, /* pc_relative */
851 6, /* bitpos */
852 complain_overflow_bitfield, /* complain_on_overflow */
853 bfd_elf_generic_reloc, /* special_function */
854 "R_MIPS_SHIFT6", /* name */
855 true, /* partial_inplace */
856 0, /* src_mask */
857 0x000007c4, /* dst_mask */
858 false), /* pcrel_offset */
859
860 /* 64 bit relocation. */
861 HOWTO (R_MIPS_64, /* type */
862 0, /* rightshift */
863 4, /* size (0 = byte, 1 = short, 2 = long) */
864 64, /* bitsize */
865 false, /* pc_relative */
866 0, /* bitpos */
867 complain_overflow_bitfield, /* complain_on_overflow */
868 bfd_elf_generic_reloc, /* special_function */
869 "R_MIPS_64", /* name */
870 true, /* partial_inplace */
871 0, /* src_mask */
872 MINUS_ONE, /* dst_mask */
873 false), /* pcrel_offset */
874
875 /* Displacement in the global offset table. */
876 /* FIXME: Not handled correctly. */
877 HOWTO (R_MIPS_GOT_DISP, /* type */
878 0, /* rightshift */
879 2, /* size (0 = byte, 1 = short, 2 = long) */
880 16, /* 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_GOT_DISP", /* name */
886 true, /* partial_inplace */
887 0, /* src_mask */
888 0x0000ffff, /* dst_mask */
889 false), /* pcrel_offset */
890
891 /* Displacement to page pointer in the global offset table. */
892 /* FIXME: Not handled correctly. */
893 HOWTO (R_MIPS_GOT_PAGE, /* 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_PAGE", /* name */
902 true, /* partial_inplace */
903 0, /* src_mask */
904 0x0000ffff, /* dst_mask */
905 false), /* pcrel_offset */
906
907 /* Offset from page pointer in the global offset table. */
908 /* FIXME: Not handled correctly. */
909 HOWTO (R_MIPS_GOT_OFST, /* 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_OFST", /* name */
918 true, /* partial_inplace */
919 0, /* src_mask */
920 0x0000ffff, /* dst_mask */
921 false), /* pcrel_offset */
922
923 /* High 16 bits of displacement in global offset table. */
924 /* FIXME: Not handled correctly. */
925 HOWTO (R_MIPS_GOT_HI16, /* 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_dont, /* complain_on_overflow */
932 bfd_elf_generic_reloc, /* special_function */
933 "R_MIPS_GOT_HI16", /* name */
934 true, /* partial_inplace */
935 0, /* src_mask */
936 0x0000ffff, /* dst_mask */
937 false), /* pcrel_offset */
938
939 /* Low 16 bits of displacement in global offset table. */
940 /* FIXME: Not handled correctly. */
941 HOWTO (R_MIPS_GOT_LO16, /* 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_LO16", /* name */
950 true, /* partial_inplace */
951 0, /* src_mask */
952 0x0000ffff, /* dst_mask */
953 false), /* pcrel_offset */
954
955 /* 64 bit substraction. */
956 /* FIXME: Not handled correctly. */
957 HOWTO (R_MIPS_SUB, /* type */
958 0, /* rightshift */
959 4, /* size (0 = byte, 1 = short, 2 = long) */
960 64, /* bitsize */
961 false, /* pc_relative */
962 0, /* bitpos */
963 complain_overflow_bitfield, /* complain_on_overflow */
964 bfd_elf_generic_reloc, /* special_function */
965 "R_MIPS_SUB", /* name */
966 true, /* partial_inplace */
967 0, /* src_mask */
968 MINUS_ONE, /* dst_mask */
969 false), /* pcrel_offset */
970
971 /* Insert the addend as an instruction. */
972 /* FIXME: Not handled correctly. */
973 HOWTO (R_MIPS_INSERT_A, /* type */
974 0, /* rightshift */
975 0, /* size (0 = byte, 1 = short, 2 = long) */
976 0, /* bitsize */
977 false, /* pc_relative */
978 0, /* bitpos */
979 complain_overflow_dont, /* complain_on_overflow */
980 bfd_elf_generic_reloc, /* special_function */
981 "R_MIPS_INSERT_A", /* name */
982 false, /* partial_inplace */
983 0, /* src_mask */
984 0, /* dst_mask */
985 false), /* pcrel_offset */
986
987 /* Insert the addend as an instruction, and change all relocations
988 to refer to the old instruction at the address. */
989 /* FIXME: Not handled correctly. */
990 HOWTO (R_MIPS_INSERT_B, /* type */
991 0, /* rightshift */
992 0, /* size (0 = byte, 1 = short, 2 = long) */
993 0, /* bitsize */
994 false, /* pc_relative */
995 0, /* bitpos */
996 complain_overflow_dont, /* complain_on_overflow */
997 bfd_elf_generic_reloc, /* special_function */
998 "R_MIPS_INSERT_B", /* name */
999 false, /* partial_inplace */
1000 0, /* src_mask */
1001 0, /* dst_mask */
1002 false), /* pcrel_offset */
1003
1004 /* Delete a 32 bit instruction. */
1005 /* FIXME: Not handled correctly. */
1006 HOWTO (R_MIPS_DELETE, /* 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_DELETE", /* name */
1015 false, /* partial_inplace */
1016 0, /* src_mask */
1017 0, /* dst_mask */
1018 false), /* pcrel_offset */
1019
1020 /* Get the higher value of a 64 bit addend. */
1021 /* FIXME: Not handled correctly. */
1022 HOWTO (R_MIPS_HIGHER, /* type */
1023 0, /* rightshift */
1024 2, /* size (0 = byte, 1 = short, 2 = long) */
1025 16, /* 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_HIGHER", /* name */
1031 true, /* partial_inplace */
1032 0, /* src_mask */
1033 0xffff, /* dst_mask */
1034 false), /* pcrel_offset */
1035
1036 /* Get the highest value of a 64 bit addend. */
1037 /* FIXME: Not handled correctly. */
1038 HOWTO (R_MIPS_HIGHEST, /* 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_HIGHEST", /* name */
1047 true, /* partial_inplace */
1048 0, /* src_mask */
1049 0xffff, /* dst_mask */
1050 false), /* pcrel_offset */
1051
1052 /* High 16 bits of displacement in global offset table. */
1053 /* FIXME: Not handled correctly. */
1054 HOWTO (R_MIPS_CALL_HI16, /* 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_CALL_HI16", /* name */
1063 true, /* partial_inplace */
1064 0, /* src_mask */
1065 0x0000ffff, /* dst_mask */
1066 false), /* pcrel_offset */
1067
1068 /* Low 16 bits of displacement in global offset table. */
1069 /* FIXME: Not handled correctly. */
1070 HOWTO (R_MIPS_CALL_LO16, /* 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_LO16", /* name */
1079 true, /* partial_inplace */
1080 0, /* src_mask */
1081 0x0000ffff, /* dst_mask */
1082 false), /* pcrel_offset */
1083
1084 /* I'm not sure what the remaining relocs are, but they are defined
1085 on Irix 6. */
1086
1087 HOWTO (R_MIPS_SCN_DISP, /* type */
1088 0, /* rightshift */
1089 0, /* size (0 = byte, 1 = short, 2 = long) */
1090 0, /* bitsize */
1091 false, /* pc_relative */
1092 0, /* bitpos */
1093 complain_overflow_dont, /* complain_on_overflow */
1094 bfd_elf_generic_reloc, /* special_function */
1095 "R_MIPS_SCN_DISP", /* name */
1096 false, /* partial_inplace */
1097 0, /* src_mask */
1098 0, /* dst_mask */
1099 false), /* pcrel_offset */
1100
1101 HOWTO (R_MIPS_REL16, /* type */
1102 0, /* rightshift */
1103 0, /* size (0 = byte, 1 = short, 2 = long) */
1104 0, /* bitsize */
1105 false, /* pc_relative */
1106 0, /* bitpos */
1107 complain_overflow_dont, /* complain_on_overflow */
1108 bfd_elf_generic_reloc, /* special_function */
1109 "R_MIPS_REL16", /* name */
1110 false, /* partial_inplace */
1111 0, /* src_mask */
1112 0, /* dst_mask */
1113 false), /* pcrel_offset */
1114
1115 HOWTO (R_MIPS_ADD_IMMEDIATE, /* type */
1116 0, /* rightshift */
1117 0, /* size (0 = byte, 1 = short, 2 = long) */
1118 0, /* bitsize */
1119 false, /* pc_relative */
1120 0, /* bitpos */
1121 complain_overflow_dont, /* complain_on_overflow */
1122 bfd_elf_generic_reloc, /* special_function */
1123 "R_MIPS_ADD_IMMEDIATE", /* name */
1124 false, /* partial_inplace */
1125 0, /* src_mask */
1126 0, /* dst_mask */
1127 false), /* pcrel_offset */
1128
1129 HOWTO (R_MIPS_PJUMP, /* type */
1130 0, /* rightshift */
1131 0, /* size (0 = byte, 1 = short, 2 = long) */
1132 0, /* bitsize */
1133 false, /* pc_relative */
1134 0, /* bitpos */
1135 complain_overflow_dont, /* complain_on_overflow */
1136 bfd_elf_generic_reloc, /* special_function */
1137 "R_MIPS_PJUMP", /* name */
1138 false, /* partial_inplace */
1139 0, /* src_mask */
1140 0, /* dst_mask */
1141 false), /* pcrel_offset */
1142
1143 HOWTO (R_MIPS_RELGOT, /* type */
1144 0, /* rightshift */
1145 0, /* size (0 = byte, 1 = short, 2 = long) */
1146 0, /* bitsize */
1147 false, /* pc_relative */
1148 0, /* bitpos */
1149 complain_overflow_dont, /* complain_on_overflow */
1150 bfd_elf_generic_reloc, /* special_function */
1151 "R_MIPS_RELGOT", /* name */
1152 false, /* partial_inplace */
1153 0, /* src_mask */
1154 0, /* dst_mask */
1155 false) /* pcrel_offset */
1156};
1157
1158/* Swap in a MIPS 64-bit Rel reloc. */
1159
1160static void
1161mips_elf64_swap_reloc_in (abfd, src, dst)
1162 bfd *abfd;
1163 const Elf64_Mips_External_Rel *src;
1164 Elf64_Mips_Internal_Rel *dst;
1165{
1166 dst->r_offset = bfd_h_get_64 (abfd, (bfd_byte *) src->r_offset);
1167 dst->r_sym = bfd_h_get_32 (abfd, (bfd_byte *) src->r_sym);
1168 dst->r_ssym = bfd_h_get_8 (abfd, (bfd_byte *) src->r_ssym);
1169 dst->r_type3 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type3);
1170 dst->r_type2 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type2);
1171 dst->r_type = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type);
1172}
1173
1174/* Swap in a MIPS 64-bit Rela reloc. */
1175
1176static void
1177mips_elf64_swap_reloca_in (abfd, src, dst)
1178 bfd *abfd;
1179 const Elf64_Mips_External_Rela *src;
1180 Elf64_Mips_Internal_Rela *dst;
1181{
1182 dst->r_offset = bfd_h_get_64 (abfd, (bfd_byte *) src->r_offset);
1183 dst->r_sym = bfd_h_get_32 (abfd, (bfd_byte *) src->r_sym);
1184 dst->r_ssym = bfd_h_get_8 (abfd, (bfd_byte *) src->r_ssym);
1185 dst->r_type3 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type3);
1186 dst->r_type2 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type2);
1187 dst->r_type = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type);
1188 dst->r_addend = bfd_h_get_signed_64 (abfd, (bfd_byte *) src->r_addend);
1189}
1190
1191#if 0
1192
1193/* This is not currently used. */
1194
1195/* Swap out a MIPS 64-bit Rel reloc. */
1196
1197static void
1198mips_elf64_swap_reloc_out (abfd, src, dst)
1199 bfd *abfd;
1200 const Elf64_Mips_Internal_Rel *src;
1201 Elf64_Mips_External_Rel *dst;
1202{
1203 bfd_h_put_64 (abfd, src->r_offset, (bfd_byte *) dst->r_offset);
1204 bfd_h_put_32 (abfd, src->r_sym, (bfd_byte *) dst->r_sym);
1205 bfd_h_put_8 (abfd, src->r_ssym, (bfd_byte *) dst->r_ssym);
1206 bfd_h_put_8 (abfd, src->r_type3, (bfd_byte *) dst->r_type3);
1207 bfd_h_put_8 (abfd, src->r_type2, (bfd_byte *) dst->r_type2);
1208 bfd_h_put_8 (abfd, src->r_type, (bfd_byte *) dst->r_type);
1209}
1210
1211#endif /* 0 */
1212
1213/* Swap out a MIPS 64-bit Rela reloc. */
1214
1215static void
1216mips_elf64_swap_reloca_out (abfd, src, dst)
1217 bfd *abfd;
1218 const Elf64_Mips_Internal_Rela *src;
1219 Elf64_Mips_External_Rela *dst;
1220{
1221 bfd_h_put_64 (abfd, src->r_offset, (bfd_byte *) dst->r_offset);
1222 bfd_h_put_32 (abfd, src->r_sym, (bfd_byte *) dst->r_sym);
1223 bfd_h_put_8 (abfd, src->r_ssym, (bfd_byte *) dst->r_ssym);
1224 bfd_h_put_8 (abfd, src->r_type3, (bfd_byte *) dst->r_type3);
1225 bfd_h_put_8 (abfd, src->r_type2, (bfd_byte *) dst->r_type2);
1226 bfd_h_put_8 (abfd, src->r_type, (bfd_byte *) dst->r_type);
1227 bfd_h_put_64 (abfd, src->r_addend, (bfd_byte *) dst->r_addend);
1228}
1229
1230/* A mapping from BFD reloc types to MIPS ELF reloc types. */
1231
1232struct elf_reloc_map
1233{
1234 bfd_reloc_code_real_type bfd_reloc_val;
1235 enum elf_mips_reloc_type elf_reloc_val;
1236};
1237
1238static CONST struct elf_reloc_map mips_reloc_map[] =
1239{
1240 { BFD_RELOC_NONE, R_MIPS_NONE, },
1241 { BFD_RELOC_16, R_MIPS_16 },
1242 { BFD_RELOC_32, R_MIPS_32 },
1243 { BFD_RELOC_64, R_MIPS_64 },
1244 { BFD_RELOC_CTOR, R_MIPS_64 },
1245 { BFD_RELOC_32_PCREL, R_MIPS_REL32 },
1246 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1247 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1248 { BFD_RELOC_LO16, R_MIPS_LO16 },
1249 { BFD_RELOC_MIPS_GPREL, R_MIPS_GPREL16 },
1250 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1251 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1252 { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
1253 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1254 { BFD_RELOC_MIPS_GPREL32, R_MIPS_GPREL32 },
1255 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1256 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1257 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
3f830999
MM
1258 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1259 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1260 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1261 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1262 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP }
252b5132
RH
1263};
1264
1265/* Given a BFD reloc type, return a howto structure. */
1266
1267static reloc_howto_type *
1268mips_elf64_reloc_type_lookup (abfd, code)
1269 bfd *abfd;
1270 bfd_reloc_code_real_type code;
1271{
1272 unsigned int i;
1273
1274 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); i++)
1275 {
1276 if (mips_reloc_map[i].bfd_reloc_val == code)
1277 {
1278 int v;
1279
1280 v = (int) mips_reloc_map[i].elf_reloc_val;
1281 return &mips_elf64_howto_table_rel[v];
1282 }
1283 }
1284
1285 return NULL;
1286}
1287
1288/* Since each entry in an SHT_REL or SHT_RELA section can represent up
1289 to three relocs, we must tell the user to allocate more space. */
1290
1291static long
1292mips_elf64_get_reloc_upper_bound (abfd, sec)
1293 bfd *abfd;
1294 asection *sec;
1295{
1296 return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
1297}
1298
1299/* Read the relocations from one reloc section. */
1300
1301static boolean
1302mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, rel_hdr)
1303 bfd *abfd;
1304 asection *asect;
1305 asymbol **symbols;
1306 const Elf_Internal_Shdr *rel_hdr;
1307{
1308 PTR allocated = NULL;
1309 bfd_byte *native_relocs;
1310 arelent *relents;
1311 arelent *relent;
1312 unsigned int count;
1313 unsigned int i;
1314 int entsize;
1315 reloc_howto_type *howto_table;
1316
1317 allocated = (PTR) bfd_malloc (rel_hdr->sh_size);
1318 if (allocated == NULL)
1319 goto error_return;
1320
1321 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
1322 || (bfd_read (allocated, 1, rel_hdr->sh_size, abfd) != rel_hdr->sh_size))
1323 goto error_return;
1324
1325 native_relocs = (bfd_byte *) allocated;
1326
1327 relents = asect->relocation + asect->reloc_count;
1328
1329 entsize = rel_hdr->sh_entsize;
1330 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
1331 || entsize == sizeof (Elf64_Mips_External_Rela));
1332
1333 count = rel_hdr->sh_size / entsize;
1334
1335 if (entsize == sizeof (Elf64_Mips_External_Rel))
1336 howto_table = mips_elf64_howto_table_rel;
1337 else
1338 howto_table = mips_elf64_howto_table_rela;
1339
1340 relent = relents;
1341 for (i = 0; i < count; i++, native_relocs += entsize)
1342 {
1343 Elf64_Mips_Internal_Rela rela;
1344 boolean used_sym, used_ssym;
1345 int ir;
1346
1347 if (entsize == sizeof (Elf64_Mips_External_Rela))
1348 mips_elf64_swap_reloca_in (abfd,
1349 (Elf64_Mips_External_Rela *) native_relocs,
1350 &rela);
1351 else
1352 {
1353 Elf64_Mips_Internal_Rel rel;
1354
1355 mips_elf64_swap_reloc_in (abfd,
1356 (Elf64_Mips_External_Rel *) native_relocs,
1357 &rel);
1358 rela.r_offset = rel.r_offset;
1359 rela.r_sym = rel.r_sym;
1360 rela.r_ssym = rel.r_ssym;
1361 rela.r_type3 = rel.r_type3;
1362 rela.r_type2 = rel.r_type2;
1363 rela.r_type = rel.r_type;
1364 rela.r_addend = 0;
1365 }
1366
1367 /* Each entry represents up to three actual relocations. */
1368
1369 used_sym = false;
1370 used_ssym = false;
1371 for (ir = 0; ir < 3; ir++)
1372 {
1373 enum elf_mips_reloc_type type;
1374
1375 switch (ir)
1376 {
1377 default:
1378 abort ();
1379 case 0:
1380 type = (enum elf_mips_reloc_type) rela.r_type;
1381 break;
1382 case 1:
1383 type = (enum elf_mips_reloc_type) rela.r_type2;
1384 break;
1385 case 2:
1386 type = (enum elf_mips_reloc_type) rela.r_type3;
1387 break;
1388 }
1389
1390 if (type == R_MIPS_NONE)
1391 {
1392 /* There are no more relocations in this entry. If this
1393 is the first entry, we need to generate a dummy
1394 relocation so that the generic linker knows that
1395 there has been a break in the sequence of relocations
1396 applying to a particular address. */
1397 if (ir == 0)
1398 {
1399 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1400 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
1401 relent->address = rela.r_offset;
1402 else
1403 relent->address = rela.r_offset - asect->vma;
1404 relent->addend = 0;
1405 relent->howto = &howto_table[(int) R_MIPS_NONE];
1406 ++relent;
1407 }
1408 break;
1409 }
1410
1411 /* Some types require symbols, whereas some do not. */
1412 switch (type)
1413 {
1414 case R_MIPS_NONE:
1415 case R_MIPS_LITERAL:
1416 case R_MIPS_INSERT_A:
1417 case R_MIPS_INSERT_B:
1418 case R_MIPS_DELETE:
1419 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1420 break;
1421
1422 default:
1423 if (! used_sym)
1424 {
1425 if (rela.r_sym == 0)
1426 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1427 else
1428 {
1429 asymbol **ps, *s;
1430
1431 ps = symbols + rela.r_sym - 1;
1432 s = *ps;
1433 if ((s->flags & BSF_SECTION_SYM) == 0)
1434 relent->sym_ptr_ptr = ps;
1435 else
1436 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
1437 }
1438
1439 used_sym = true;
1440 }
1441 else if (! used_ssym)
1442 {
1443 switch (rela.r_ssym)
1444 {
1445 case RSS_UNDEF:
1446 relent->sym_ptr_ptr =
1447 bfd_abs_section_ptr->symbol_ptr_ptr;
1448 break;
1449
1450 case RSS_GP:
1451 case RSS_GP0:
1452 case RSS_LOC:
1453 /* FIXME: I think these need to be handled using
1454 special howto structures. */
1455 BFD_ASSERT (0);
1456 break;
1457
1458 default:
1459 BFD_ASSERT (0);
1460 break;
1461 }
1462
1463 used_ssym = true;
1464 }
1465 else
1466 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1467
1468 break;
1469 }
1470
1471 /* The address of an ELF reloc is section relative for an
1472 object file, and absolute for an executable file or
1473 shared library. The address of a BFD reloc is always
1474 section relative. */
1475 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
1476 relent->address = rela.r_offset;
1477 else
1478 relent->address = rela.r_offset - asect->vma;
1479
1480 relent->addend = rela.r_addend;
1481
1482 relent->howto = &howto_table[(int) type];
1483
1484 ++relent;
1485 }
1486 }
1487
1488 asect->reloc_count += relent - relents;
1489
1490 if (allocated != NULL)
1491 free (allocated);
1492
1493 return true;
1494
1495 error_return:
1496 if (allocated != NULL)
1497 free (allocated);
1498 return false;
1499}
1500
1501/* Read the relocations. On Irix 6, there can be two reloc sections
1502 associated with a single data section. */
1503
1504static boolean
1505mips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic)
1506 bfd *abfd;
1507 asection *asect;
1508 asymbol **symbols;
1509 boolean dynamic;
1510{
1511 struct bfd_elf_section_data * const d = elf_section_data (asect);
1512
1513 if (dynamic)
1514 {
1515 bfd_set_error (bfd_error_invalid_operation);
1516 return false;
1517 }
1518
1519 if (asect->relocation != NULL
1520 || (asect->flags & SEC_RELOC) == 0
1521 || asect->reloc_count == 0)
1522 return true;
1523
1524 /* Allocate space for 3 arelent structures for each Rel structure. */
1525 asect->relocation = ((arelent *)
1526 bfd_alloc (abfd,
1527 asect->reloc_count * 3 * sizeof (arelent)));
1528 if (asect->relocation == NULL)
1529 return false;
1530
1531 /* The slurp_one_reloc_table routine increments reloc_count. */
1532 asect->reloc_count = 0;
1533
1534 if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, &d->rel_hdr))
1535 return false;
1536 if (d->rel_hdr2 != NULL)
1537 {
1538 if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols,
1539 d->rel_hdr2))
1540 return false;
1541 }
1542
1543 return true;
1544}
1545
1546/* Write out the relocations. */
1547
1548static void
1549mips_elf64_write_relocs (abfd, sec, data)
1550 bfd *abfd;
1551 asection *sec;
1552 PTR data;
1553{
1554 boolean *failedp = (boolean *) data;
1555 unsigned int count;
1556 Elf_Internal_Shdr *rela_hdr;
1557 Elf64_Mips_External_Rela *ext_rela;
1558 unsigned int idx;
1559 asymbol *last_sym = 0;
1560 int last_sym_idx = 0;
1561
1562 /* If we have already failed, don't do anything. */
1563 if (*failedp)
1564 return;
1565
1566 if ((sec->flags & SEC_RELOC) == 0)
1567 return;
1568
1569 /* The linker backend writes the relocs out itself, and sets the
1570 reloc_count field to zero to inhibit writing them here. Also,
1571 sometimes the SEC_RELOC flag gets set even when there aren't any
1572 relocs. */
1573 if (sec->reloc_count == 0)
1574 return;
1575
1576 /* We can combine up to three relocs that refer to the same address
1577 if the latter relocs have no associated symbol. */
1578 count = 0;
1579 for (idx = 0; idx < sec->reloc_count; idx++)
1580 {
1581 bfd_vma addr;
1582 unsigned int i;
1583
1584 ++count;
1585
1586 addr = sec->orelocation[idx]->address;
1587 for (i = 0; i < 2; i++)
1588 {
1589 arelent *r;
1590
1591 if (idx + 1 >= sec->reloc_count)
1592 break;
1593 r = sec->orelocation[idx + 1];
1594 if (r->address != addr
1595 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
1596 || (*r->sym_ptr_ptr)->value != 0)
1597 break;
1598
1599 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
1600
1601 ++idx;
1602 }
1603 }
1604
1605 rela_hdr = &elf_section_data (sec)->rel_hdr;
1606
1607 rela_hdr->sh_size = rela_hdr->sh_entsize * count;
1608 rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
1609 if (rela_hdr->contents == NULL)
1610 {
1611 *failedp = true;
1612 return;
1613 }
1614
1615 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
1616 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
1617 {
1618 arelent *ptr;
1619 Elf64_Mips_Internal_Rela int_rela;
1620 asymbol *sym;
1621 int n;
1622 unsigned int i;
1623
1624 ptr = sec->orelocation[idx];
1625
1626 /* The address of an ELF reloc is section relative for an object
1627 file, and absolute for an executable file or shared library.
1628 The address of a BFD reloc is always section relative. */
1629 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
1630 int_rela.r_offset = ptr->address;
1631 else
1632 int_rela.r_offset = ptr->address + sec->vma;
1633
1634 sym = *ptr->sym_ptr_ptr;
1635 if (sym == last_sym)
1636 n = last_sym_idx;
1637 else
1638 {
1639 last_sym = sym;
1640 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
1641 if (n < 0)
1642 {
1643 *failedp = true;
1644 return;
1645 }
1646 last_sym_idx = n;
1647 }
1648
1649 int_rela.r_sym = n;
1650
1651 int_rela.r_addend = ptr->addend;
1652
1653 int_rela.r_ssym = RSS_UNDEF;
1654
1655 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
1656 && ! _bfd_elf_validate_reloc (abfd, ptr))
1657 {
1658 *failedp = true;
1659 return;
1660 }
1661
1662 int_rela.r_type = ptr->howto->type;
1663 int_rela.r_type2 = (int) R_MIPS_NONE;
1664 int_rela.r_type3 = (int) R_MIPS_NONE;
1665
1666 for (i = 0; i < 2; i++)
1667 {
1668 arelent *r;
1669
1670 if (idx + 1 >= sec->reloc_count)
1671 break;
1672 r = sec->orelocation[idx + 1];
1673 if (r->address != ptr->address
1674 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
1675 || (*r->sym_ptr_ptr)->value != 0)
1676 break;
1677
1678 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
1679
1680 if (i == 0)
1681 int_rela.r_type2 = r->howto->type;
1682 else
1683 int_rela.r_type3 = r->howto->type;
1684
1685 ++idx;
1686 }
1687
1688 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
1689 }
1690
1691 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
1692 == count);
1693}
1694\f
1695/* Handle a 64-bit MIPS ELF specific section. */
1696
1697static boolean
1698mips_elf64_section_from_shdr (abfd, hdr, name)
1699 bfd *abfd;
1700 Elf_Internal_Shdr *hdr;
1701 char *name;
1702{
1703 if (! _bfd_mips_elf_section_from_shdr (abfd, hdr, name))
1704 return false;
1705
1706 /* For a SHT_MIPS_OPTIONS section, look for a ODK_REGINFO entry, and
1707 set the gp value based on what we find. We may see both
1708 SHT_MIPS_REGINFO and SHT_MIPS_OPTIONS/ODK_REGINFO; in that case,
1709 they should agree. */
1710 if (hdr->sh_type == SHT_MIPS_OPTIONS)
1711 {
1712 bfd_byte *contents, *l, *lend;
1713
1714 contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
1715 if (contents == NULL)
1716 return false;
1717 if (! bfd_get_section_contents (abfd, hdr->bfd_section, contents,
1718 (file_ptr) 0, hdr->sh_size))
1719 {
1720 free (contents);
1721 return false;
1722 }
1723 l = contents;
1724 lend = contents + hdr->sh_size;
1725 while (l + sizeof (Elf_External_Options) <= lend)
1726 {
1727 Elf_Internal_Options intopt;
1728
1729 bfd_mips_elf_swap_options_in (abfd, (Elf_External_Options *) l,
1730 &intopt);
1731 if (intopt.kind == ODK_REGINFO)
1732 {
1733 Elf64_Internal_RegInfo intreg;
1734
1735 bfd_mips_elf64_swap_reginfo_in
1736 (abfd,
1737 ((Elf64_External_RegInfo *)
1738 (l + sizeof (Elf_External_Options))),
1739 &intreg);
1740 elf_gp (abfd) = intreg.ri_gp_value;
1741 }
1742 l += intopt.size;
1743 }
1744 free (contents);
1745 }
1746
1747 return true;
1748}
1749
1750/* Work over a section just before writing it out. We update the GP
1751 value in the SHT_MIPS_OPTIONS section based on the value we are
1752 using. */
1753
1754static boolean
1755mips_elf64_section_processing (abfd, hdr)
1756 bfd *abfd;
1757 Elf_Internal_Shdr *hdr;
1758{
1759 if (hdr->sh_type == SHT_MIPS_OPTIONS
1760 && hdr->bfd_section != NULL
1761 && elf_section_data (hdr->bfd_section) != NULL
1762 && elf_section_data (hdr->bfd_section)->tdata != NULL)
1763 {
1764 bfd_byte *contents, *l, *lend;
1765
1766 /* We stored the section contents in the elf_section_data tdata
1767 field in the set_section_contents routine. We save the
1768 section contents so that we don't have to read them again.
1769 At this point we know that elf_gp is set, so we can look
1770 through the section contents to see if there is an
1771 ODK_REGINFO structure. */
1772
1773 contents = (bfd_byte *) elf_section_data (hdr->bfd_section)->tdata;
1774 l = contents;
1775 lend = contents + hdr->sh_size;
1776 while (l + sizeof (Elf_External_Options) <= lend)
1777 {
1778 Elf_Internal_Options intopt;
1779
1780 bfd_mips_elf_swap_options_in (abfd, (Elf_External_Options *) l,
1781 &intopt);
1782 if (intopt.kind == ODK_REGINFO)
1783 {
1784 bfd_byte buf[8];
1785
1786 if (bfd_seek (abfd,
1787 (hdr->sh_offset
1788 + (l - contents)
1789 + sizeof (Elf_External_Options)
1790 + (sizeof (Elf64_External_RegInfo) - 8)),
1791 SEEK_SET) == -1)
1792 return false;
1793 bfd_h_put_64 (abfd, elf_gp (abfd), buf);
1794 if (bfd_write (buf, 1, 8, abfd) != 8)
1795 return false;
1796 }
1797 l += intopt.size;
1798 }
1799 }
1800
1801 return _bfd_mips_elf_section_processing (abfd, hdr);
1802}
1803\f
1804/* Irix 6 defines a brand new archive map format, so that they can
1805 have archives more than 4 GB in size. */
1806
1807/* Read an Irix 6 armap. */
1808
1809static boolean
1810mips_elf64_slurp_armap (abfd)
1811 bfd *abfd;
1812{
1813 struct artdata *ardata = bfd_ardata (abfd);
1814 char nextname[17];
1815 file_ptr arhdrpos;
1816 bfd_size_type i, parsed_size, nsymz, stringsize, carsym_size, ptrsize;
1817 struct areltdata *mapdata;
1818 bfd_byte int_buf[8];
1819 char *stringbase;
1820 bfd_byte *raw_armap = NULL;
1821 carsym *carsyms;
1822
1823 ardata->symdefs = NULL;
1824
1825 /* Get the name of the first element. */
1826 arhdrpos = bfd_tell (abfd);
1827 i = bfd_read ((PTR) nextname, 1, 16, abfd);
1828 if (i == 0)
1829 return true;
1830 if (i != 16)
1831 return false;
1832
1833 if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0)
1834 return false;
1835
1836 /* Archives with traditional armaps are still permitted. */
1837 if (strncmp (nextname, "/ ", 16) == 0)
1838 return bfd_slurp_armap (abfd);
1839
1840 if (strncmp (nextname, "/SYM64/ ", 16) != 0)
1841 {
1842 bfd_has_map (abfd) = false;
1843 return true;
1844 }
1845
1846 mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
1847 if (mapdata == NULL)
1848 return false;
1849 parsed_size = mapdata->parsed_size;
1850 bfd_release (abfd, (PTR) mapdata);
1851
1852 if (bfd_read (int_buf, 1, 8, abfd) != 8)
1853 {
1854 if (bfd_get_error () != bfd_error_system_call)
1855 bfd_set_error (bfd_error_malformed_archive);
1856 return false;
1857 }
1858
1859 nsymz = bfd_getb64 (int_buf);
1860 stringsize = parsed_size - 8 * nsymz - 8;
1861
1862 carsym_size = nsymz * sizeof (carsym);
1863 ptrsize = 8 * nsymz;
1864
1865 ardata->symdefs = (carsym *) bfd_zalloc (abfd, carsym_size + stringsize + 1);
1866 if (ardata->symdefs == NULL)
1867 return false;
1868 carsyms = ardata->symdefs;
1869 stringbase = ((char *) ardata->symdefs) + carsym_size;
1870
1871 raw_armap = (bfd_byte *) bfd_alloc (abfd, ptrsize);
1872 if (raw_armap == NULL)
1873 goto error_return;
1874
1875 if (bfd_read (raw_armap, 1, ptrsize, abfd) != ptrsize
1876 || bfd_read (stringbase, 1, stringsize, abfd) != stringsize)
1877 {
1878 if (bfd_get_error () != bfd_error_system_call)
1879 bfd_set_error (bfd_error_malformed_archive);
1880 goto error_return;
1881 }
1882
1883 for (i = 0; i < nsymz; i++)
1884 {
1885 carsyms->file_offset = bfd_getb64 (raw_armap + i * 8);
1886 carsyms->name = stringbase;
1887 stringbase += strlen (stringbase) + 1;
1888 ++carsyms;
1889 }
1890 *stringbase = '\0';
1891
1892 ardata->symdef_count = nsymz;
1893 ardata->first_file_filepos = arhdrpos + sizeof (struct ar_hdr) + parsed_size;
1894
1895 bfd_has_map (abfd) = true;
1896 bfd_release (abfd, raw_armap);
1897
1898 return true;
1899
1900 error_return:
1901 if (raw_armap != NULL)
1902 bfd_release (abfd, raw_armap);
1903 if (ardata->symdefs != NULL)
1904 bfd_release (abfd, ardata->symdefs);
1905 return false;
1906}
1907
1908/* Write out an Irix 6 armap. The Irix 6 tools are supposed to be
1909 able to handle ordinary ELF armaps, but at least on Irix 6.2 the
1910 linker crashes. */
1911
1912static boolean
1913mips_elf64_write_armap (arch, elength, map, symbol_count, stridx)
1914 bfd *arch;
1915 unsigned int elength;
1916 struct orl *map;
1917 unsigned int symbol_count;
1918 int stridx;
1919{
1920 unsigned int ranlibsize = (symbol_count * 8) + 8;
1921 unsigned int stringsize = stridx;
1922 unsigned int mapsize = stringsize + ranlibsize;
1923 file_ptr archive_member_file_ptr;
1924 bfd *current = arch->archive_head;
1925 unsigned int count;
1926 struct ar_hdr hdr;
1927 unsigned int i;
1928 int padding;
1929 bfd_byte buf[8];
1930
1931 padding = BFD_ALIGN (mapsize, 8) - mapsize;
1932 mapsize += padding;
1933
1934 /* work out where the first object file will go in the archive */
1935 archive_member_file_ptr = (mapsize
1936 + elength
1937 + sizeof (struct ar_hdr)
1938 + SARMAG);
1939
1940 memset ((char *) (&hdr), 0, sizeof (struct ar_hdr));
1941 strcpy (hdr.ar_name, "/SYM64/");
1942 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1943 sprintf (hdr.ar_date, "%ld", (long) time (NULL));
1944 /* This, at least, is what Intel coff sets the values to.: */
1945 sprintf ((hdr.ar_uid), "%d", 0);
1946 sprintf ((hdr.ar_gid), "%d", 0);
1947 sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0);
1948 strncpy (hdr.ar_fmag, ARFMAG, 2);
1949
1950 for (i = 0; i < sizeof (struct ar_hdr); i++)
1951 if (((char *) (&hdr))[i] == '\0')
1952 (((char *) (&hdr))[i]) = ' ';
1953
1954 /* Write the ar header for this item and the number of symbols */
1955
1956 if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), arch)
1957 != sizeof (struct ar_hdr))
1958 return false;
1959
1960 bfd_putb64 (symbol_count, buf);
1961 if (bfd_write (buf, 1, 8, arch) != 8)
1962 return false;
1963
1964 /* Two passes, first write the file offsets for each symbol -
1965 remembering that each offset is on a two byte boundary. */
1966
1967 /* Write out the file offset for the file associated with each
1968 symbol, and remember to keep the offsets padded out. */
1969
1970 current = arch->archive_head;
1971 count = 0;
1972 while (current != (bfd *) NULL && count < symbol_count)
1973 {
1974 /* For each symbol which is used defined in this object, write out
1975 the object file's address in the archive */
1976
1977 while (((bfd *) (map[count]).pos) == current)
1978 {
1979 bfd_putb64 (archive_member_file_ptr, buf);
1980 if (bfd_write (buf, 1, 8, arch) != 8)
1981 return false;
1982 count++;
1983 }
1984 /* Add size of this archive entry */
1985 archive_member_file_ptr += (arelt_size (current)
1986 + sizeof (struct ar_hdr));
1987 /* remember about the even alignment */
1988 archive_member_file_ptr += archive_member_file_ptr % 2;
1989 current = current->next;
1990 }
1991
1992 /* now write the strings themselves */
1993 for (count = 0; count < symbol_count; count++)
1994 {
1995 size_t len = strlen (*map[count].name) + 1;
1996
1997 if (bfd_write (*map[count].name, 1, len, arch) != len)
1998 return false;
1999 }
2000
2001 /* The spec says that this should be padded to an 8 byte boundary.
2002 However, the Irix 6.2 tools do not appear to do this. */
2003 while (padding != 0)
2004 {
2005 if (bfd_write ("", 1, 1, arch) != 1)
2006 return false;
2007 --padding;
2008 }
2009
2010 return true;
2011}
2012\f
2013/* ECOFF swapping routines. These are used when dealing with the
2014 .mdebug section, which is in the ECOFF debugging format. */
2015static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
2016{
2017 /* Symbol table magic number. */
2018 magicSym2,
2019 /* Alignment of debugging information. E.g., 4. */
2020 8,
2021 /* Sizes of external symbolic information. */
2022 sizeof (struct hdr_ext),
2023 sizeof (struct dnr_ext),
2024 sizeof (struct pdr_ext),
2025 sizeof (struct sym_ext),
2026 sizeof (struct opt_ext),
2027 sizeof (struct fdr_ext),
2028 sizeof (struct rfd_ext),
2029 sizeof (struct ext_ext),
2030 /* Functions to swap in external symbolic data. */
2031 ecoff_swap_hdr_in,
2032 ecoff_swap_dnr_in,
2033 ecoff_swap_pdr_in,
2034 ecoff_swap_sym_in,
2035 ecoff_swap_opt_in,
2036 ecoff_swap_fdr_in,
2037 ecoff_swap_rfd_in,
2038 ecoff_swap_ext_in,
2039 _bfd_ecoff_swap_tir_in,
2040 _bfd_ecoff_swap_rndx_in,
2041 /* Functions to swap out external symbolic data. */
2042 ecoff_swap_hdr_out,
2043 ecoff_swap_dnr_out,
2044 ecoff_swap_pdr_out,
2045 ecoff_swap_sym_out,
2046 ecoff_swap_opt_out,
2047 ecoff_swap_fdr_out,
2048 ecoff_swap_rfd_out,
2049 ecoff_swap_ext_out,
2050 _bfd_ecoff_swap_tir_out,
2051 _bfd_ecoff_swap_rndx_out,
2052 /* Function to read in symbolic data. */
2053 _bfd_mips_elf_read_ecoff_info
2054};
2055\f
2056/* Relocations in the 64 bit MIPS ELF ABI are more complex than in
2057 standard ELF. This structure is used to redirect the relocation
2058 handling routines. */
2059
2060const struct elf_size_info mips_elf64_size_info =
2061{
2062 sizeof (Elf64_External_Ehdr),
2063 sizeof (Elf64_External_Phdr),
2064 sizeof (Elf64_External_Shdr),
2065 sizeof (Elf64_Mips_External_Rel),
2066 sizeof (Elf64_Mips_External_Rela),
2067 sizeof (Elf64_External_Sym),
2068 sizeof (Elf64_External_Dyn),
2069 sizeof (Elf_External_Note),
2070 64, /* arch_size */
2071 8, /* file_align */
2072 ELFCLASS64,
2073 EV_CURRENT,
2074 bfd_elf64_write_out_phdrs,
2075 bfd_elf64_write_shdrs_and_ehdr,
2076 mips_elf64_write_relocs,
2077 bfd_elf64_swap_symbol_out,
2078 mips_elf64_slurp_reloc_table,
2079 bfd_elf64_slurp_symbol_table,
2080 bfd_elf64_swap_dyn_in
2081};
2082
2083#define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
2084#define TARGET_LITTLE_NAME "elf64-littlemips"
2085#define TARGET_BIG_SYM bfd_elf64_bigmips_vec
2086#define TARGET_BIG_NAME "elf64-bigmips"
2087#define ELF_ARCH bfd_arch_mips
2088#define ELF_MACHINE_CODE EM_MIPS
2089#define ELF_MAXPAGESIZE 0x1000
2090#define elf_backend_size_info mips_elf64_size_info
2091#define elf_backend_object_p _bfd_mips_elf_object_p
2092#define elf_backend_section_from_shdr mips_elf64_section_from_shdr
2093#define elf_backend_fake_sections _bfd_mips_elf_fake_sections
2094#define elf_backend_section_from_bfd_section \
2095 _bfd_mips_elf_section_from_bfd_section
2096#define elf_backend_section_processing mips_elf64_section_processing
2097#define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
2098#define elf_backend_final_write_processing \
2099 _bfd_mips_elf_final_write_processing
2100#define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
2101
2102#define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
2103#define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
2104#define bfd_elf64_bfd_reloc_type_lookup mips_elf64_reloc_type_lookup
2105#define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
2106#define bfd_elf64_bfd_copy_private_bfd_data \
2107 _bfd_mips_elf_copy_private_bfd_data
2108#define bfd_elf64_bfd_merge_private_bfd_data \
2109 _bfd_mips_elf_merge_private_bfd_data
2110#define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
2111
2112#define bfd_elf64_archive_functions
2113#define bfd_elf64_archive_slurp_armap mips_elf64_slurp_armap
2114#define bfd_elf64_archive_slurp_extended_name_table \
2115 _bfd_archive_coff_slurp_extended_name_table
2116#define bfd_elf64_archive_construct_extended_name_table \
2117 _bfd_archive_coff_construct_extended_name_table
2118#define bfd_elf64_archive_truncate_arname \
2119 _bfd_archive_coff_truncate_arname
2120#define bfd_elf64_archive_write_armap mips_elf64_write_armap
2121#define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
2122#define bfd_elf64_archive_openr_next_archived_file \
2123 _bfd_archive_coff_openr_next_archived_file
2124#define bfd_elf64_archive_get_elt_at_index \
2125 _bfd_archive_coff_get_elt_at_index
2126#define bfd_elf64_archive_generic_stat_arch_elt \
2127 _bfd_archive_coff_generic_stat_arch_elt
2128#define bfd_elf64_archive_update_armap_timestamp \
2129 _bfd_archive_coff_update_armap_timestamp
2130
2131#include "elf64-target.h"
This page took 0.124237 seconds and 4 git commands to generate.