19990502 sourceware import
[deliverable/binutils-gdb.git] / bfd / elf64-mips.c
CommitLineData
252b5132
RH
1/* MIPS-specific support for 64-bit ELF
2 Copyright 1996, 1997, 1998 Free Software Foundation, Inc.
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 },
1258 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 }
1259};
1260
1261/* Given a BFD reloc type, return a howto structure. */
1262
1263static reloc_howto_type *
1264mips_elf64_reloc_type_lookup (abfd, code)
1265 bfd *abfd;
1266 bfd_reloc_code_real_type code;
1267{
1268 unsigned int i;
1269
1270 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); i++)
1271 {
1272 if (mips_reloc_map[i].bfd_reloc_val == code)
1273 {
1274 int v;
1275
1276 v = (int) mips_reloc_map[i].elf_reloc_val;
1277 return &mips_elf64_howto_table_rel[v];
1278 }
1279 }
1280
1281 return NULL;
1282}
1283
1284/* Since each entry in an SHT_REL or SHT_RELA section can represent up
1285 to three relocs, we must tell the user to allocate more space. */
1286
1287static long
1288mips_elf64_get_reloc_upper_bound (abfd, sec)
1289 bfd *abfd;
1290 asection *sec;
1291{
1292 return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
1293}
1294
1295/* Read the relocations from one reloc section. */
1296
1297static boolean
1298mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, rel_hdr)
1299 bfd *abfd;
1300 asection *asect;
1301 asymbol **symbols;
1302 const Elf_Internal_Shdr *rel_hdr;
1303{
1304 PTR allocated = NULL;
1305 bfd_byte *native_relocs;
1306 arelent *relents;
1307 arelent *relent;
1308 unsigned int count;
1309 unsigned int i;
1310 int entsize;
1311 reloc_howto_type *howto_table;
1312
1313 allocated = (PTR) bfd_malloc (rel_hdr->sh_size);
1314 if (allocated == NULL)
1315 goto error_return;
1316
1317 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
1318 || (bfd_read (allocated, 1, rel_hdr->sh_size, abfd) != rel_hdr->sh_size))
1319 goto error_return;
1320
1321 native_relocs = (bfd_byte *) allocated;
1322
1323 relents = asect->relocation + asect->reloc_count;
1324
1325 entsize = rel_hdr->sh_entsize;
1326 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
1327 || entsize == sizeof (Elf64_Mips_External_Rela));
1328
1329 count = rel_hdr->sh_size / entsize;
1330
1331 if (entsize == sizeof (Elf64_Mips_External_Rel))
1332 howto_table = mips_elf64_howto_table_rel;
1333 else
1334 howto_table = mips_elf64_howto_table_rela;
1335
1336 relent = relents;
1337 for (i = 0; i < count; i++, native_relocs += entsize)
1338 {
1339 Elf64_Mips_Internal_Rela rela;
1340 boolean used_sym, used_ssym;
1341 int ir;
1342
1343 if (entsize == sizeof (Elf64_Mips_External_Rela))
1344 mips_elf64_swap_reloca_in (abfd,
1345 (Elf64_Mips_External_Rela *) native_relocs,
1346 &rela);
1347 else
1348 {
1349 Elf64_Mips_Internal_Rel rel;
1350
1351 mips_elf64_swap_reloc_in (abfd,
1352 (Elf64_Mips_External_Rel *) native_relocs,
1353 &rel);
1354 rela.r_offset = rel.r_offset;
1355 rela.r_sym = rel.r_sym;
1356 rela.r_ssym = rel.r_ssym;
1357 rela.r_type3 = rel.r_type3;
1358 rela.r_type2 = rel.r_type2;
1359 rela.r_type = rel.r_type;
1360 rela.r_addend = 0;
1361 }
1362
1363 /* Each entry represents up to three actual relocations. */
1364
1365 used_sym = false;
1366 used_ssym = false;
1367 for (ir = 0; ir < 3; ir++)
1368 {
1369 enum elf_mips_reloc_type type;
1370
1371 switch (ir)
1372 {
1373 default:
1374 abort ();
1375 case 0:
1376 type = (enum elf_mips_reloc_type) rela.r_type;
1377 break;
1378 case 1:
1379 type = (enum elf_mips_reloc_type) rela.r_type2;
1380 break;
1381 case 2:
1382 type = (enum elf_mips_reloc_type) rela.r_type3;
1383 break;
1384 }
1385
1386 if (type == R_MIPS_NONE)
1387 {
1388 /* There are no more relocations in this entry. If this
1389 is the first entry, we need to generate a dummy
1390 relocation so that the generic linker knows that
1391 there has been a break in the sequence of relocations
1392 applying to a particular address. */
1393 if (ir == 0)
1394 {
1395 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1396 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
1397 relent->address = rela.r_offset;
1398 else
1399 relent->address = rela.r_offset - asect->vma;
1400 relent->addend = 0;
1401 relent->howto = &howto_table[(int) R_MIPS_NONE];
1402 ++relent;
1403 }
1404 break;
1405 }
1406
1407 /* Some types require symbols, whereas some do not. */
1408 switch (type)
1409 {
1410 case R_MIPS_NONE:
1411 case R_MIPS_LITERAL:
1412 case R_MIPS_INSERT_A:
1413 case R_MIPS_INSERT_B:
1414 case R_MIPS_DELETE:
1415 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1416 break;
1417
1418 default:
1419 if (! used_sym)
1420 {
1421 if (rela.r_sym == 0)
1422 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1423 else
1424 {
1425 asymbol **ps, *s;
1426
1427 ps = symbols + rela.r_sym - 1;
1428 s = *ps;
1429 if ((s->flags & BSF_SECTION_SYM) == 0)
1430 relent->sym_ptr_ptr = ps;
1431 else
1432 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
1433 }
1434
1435 used_sym = true;
1436 }
1437 else if (! used_ssym)
1438 {
1439 switch (rela.r_ssym)
1440 {
1441 case RSS_UNDEF:
1442 relent->sym_ptr_ptr =
1443 bfd_abs_section_ptr->symbol_ptr_ptr;
1444 break;
1445
1446 case RSS_GP:
1447 case RSS_GP0:
1448 case RSS_LOC:
1449 /* FIXME: I think these need to be handled using
1450 special howto structures. */
1451 BFD_ASSERT (0);
1452 break;
1453
1454 default:
1455 BFD_ASSERT (0);
1456 break;
1457 }
1458
1459 used_ssym = true;
1460 }
1461 else
1462 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1463
1464 break;
1465 }
1466
1467 /* The address of an ELF reloc is section relative for an
1468 object file, and absolute for an executable file or
1469 shared library. The address of a BFD reloc is always
1470 section relative. */
1471 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
1472 relent->address = rela.r_offset;
1473 else
1474 relent->address = rela.r_offset - asect->vma;
1475
1476 relent->addend = rela.r_addend;
1477
1478 relent->howto = &howto_table[(int) type];
1479
1480 ++relent;
1481 }
1482 }
1483
1484 asect->reloc_count += relent - relents;
1485
1486 if (allocated != NULL)
1487 free (allocated);
1488
1489 return true;
1490
1491 error_return:
1492 if (allocated != NULL)
1493 free (allocated);
1494 return false;
1495}
1496
1497/* Read the relocations. On Irix 6, there can be two reloc sections
1498 associated with a single data section. */
1499
1500static boolean
1501mips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic)
1502 bfd *abfd;
1503 asection *asect;
1504 asymbol **symbols;
1505 boolean dynamic;
1506{
1507 struct bfd_elf_section_data * const d = elf_section_data (asect);
1508
1509 if (dynamic)
1510 {
1511 bfd_set_error (bfd_error_invalid_operation);
1512 return false;
1513 }
1514
1515 if (asect->relocation != NULL
1516 || (asect->flags & SEC_RELOC) == 0
1517 || asect->reloc_count == 0)
1518 return true;
1519
1520 /* Allocate space for 3 arelent structures for each Rel structure. */
1521 asect->relocation = ((arelent *)
1522 bfd_alloc (abfd,
1523 asect->reloc_count * 3 * sizeof (arelent)));
1524 if (asect->relocation == NULL)
1525 return false;
1526
1527 /* The slurp_one_reloc_table routine increments reloc_count. */
1528 asect->reloc_count = 0;
1529
1530 if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, &d->rel_hdr))
1531 return false;
1532 if (d->rel_hdr2 != NULL)
1533 {
1534 if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols,
1535 d->rel_hdr2))
1536 return false;
1537 }
1538
1539 return true;
1540}
1541
1542/* Write out the relocations. */
1543
1544static void
1545mips_elf64_write_relocs (abfd, sec, data)
1546 bfd *abfd;
1547 asection *sec;
1548 PTR data;
1549{
1550 boolean *failedp = (boolean *) data;
1551 unsigned int count;
1552 Elf_Internal_Shdr *rela_hdr;
1553 Elf64_Mips_External_Rela *ext_rela;
1554 unsigned int idx;
1555 asymbol *last_sym = 0;
1556 int last_sym_idx = 0;
1557
1558 /* If we have already failed, don't do anything. */
1559 if (*failedp)
1560 return;
1561
1562 if ((sec->flags & SEC_RELOC) == 0)
1563 return;
1564
1565 /* The linker backend writes the relocs out itself, and sets the
1566 reloc_count field to zero to inhibit writing them here. Also,
1567 sometimes the SEC_RELOC flag gets set even when there aren't any
1568 relocs. */
1569 if (sec->reloc_count == 0)
1570 return;
1571
1572 /* We can combine up to three relocs that refer to the same address
1573 if the latter relocs have no associated symbol. */
1574 count = 0;
1575 for (idx = 0; idx < sec->reloc_count; idx++)
1576 {
1577 bfd_vma addr;
1578 unsigned int i;
1579
1580 ++count;
1581
1582 addr = sec->orelocation[idx]->address;
1583 for (i = 0; i < 2; i++)
1584 {
1585 arelent *r;
1586
1587 if (idx + 1 >= sec->reloc_count)
1588 break;
1589 r = sec->orelocation[idx + 1];
1590 if (r->address != addr
1591 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
1592 || (*r->sym_ptr_ptr)->value != 0)
1593 break;
1594
1595 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
1596
1597 ++idx;
1598 }
1599 }
1600
1601 rela_hdr = &elf_section_data (sec)->rel_hdr;
1602
1603 rela_hdr->sh_size = rela_hdr->sh_entsize * count;
1604 rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
1605 if (rela_hdr->contents == NULL)
1606 {
1607 *failedp = true;
1608 return;
1609 }
1610
1611 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
1612 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
1613 {
1614 arelent *ptr;
1615 Elf64_Mips_Internal_Rela int_rela;
1616 asymbol *sym;
1617 int n;
1618 unsigned int i;
1619
1620 ptr = sec->orelocation[idx];
1621
1622 /* The address of an ELF reloc is section relative for an object
1623 file, and absolute for an executable file or shared library.
1624 The address of a BFD reloc is always section relative. */
1625 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
1626 int_rela.r_offset = ptr->address;
1627 else
1628 int_rela.r_offset = ptr->address + sec->vma;
1629
1630 sym = *ptr->sym_ptr_ptr;
1631 if (sym == last_sym)
1632 n = last_sym_idx;
1633 else
1634 {
1635 last_sym = sym;
1636 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
1637 if (n < 0)
1638 {
1639 *failedp = true;
1640 return;
1641 }
1642 last_sym_idx = n;
1643 }
1644
1645 int_rela.r_sym = n;
1646
1647 int_rela.r_addend = ptr->addend;
1648
1649 int_rela.r_ssym = RSS_UNDEF;
1650
1651 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
1652 && ! _bfd_elf_validate_reloc (abfd, ptr))
1653 {
1654 *failedp = true;
1655 return;
1656 }
1657
1658 int_rela.r_type = ptr->howto->type;
1659 int_rela.r_type2 = (int) R_MIPS_NONE;
1660 int_rela.r_type3 = (int) R_MIPS_NONE;
1661
1662 for (i = 0; i < 2; i++)
1663 {
1664 arelent *r;
1665
1666 if (idx + 1 >= sec->reloc_count)
1667 break;
1668 r = sec->orelocation[idx + 1];
1669 if (r->address != ptr->address
1670 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
1671 || (*r->sym_ptr_ptr)->value != 0)
1672 break;
1673
1674 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
1675
1676 if (i == 0)
1677 int_rela.r_type2 = r->howto->type;
1678 else
1679 int_rela.r_type3 = r->howto->type;
1680
1681 ++idx;
1682 }
1683
1684 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
1685 }
1686
1687 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
1688 == count);
1689}
1690\f
1691/* Handle a 64-bit MIPS ELF specific section. */
1692
1693static boolean
1694mips_elf64_section_from_shdr (abfd, hdr, name)
1695 bfd *abfd;
1696 Elf_Internal_Shdr *hdr;
1697 char *name;
1698{
1699 if (! _bfd_mips_elf_section_from_shdr (abfd, hdr, name))
1700 return false;
1701
1702 /* For a SHT_MIPS_OPTIONS section, look for a ODK_REGINFO entry, and
1703 set the gp value based on what we find. We may see both
1704 SHT_MIPS_REGINFO and SHT_MIPS_OPTIONS/ODK_REGINFO; in that case,
1705 they should agree. */
1706 if (hdr->sh_type == SHT_MIPS_OPTIONS)
1707 {
1708 bfd_byte *contents, *l, *lend;
1709
1710 contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
1711 if (contents == NULL)
1712 return false;
1713 if (! bfd_get_section_contents (abfd, hdr->bfd_section, contents,
1714 (file_ptr) 0, hdr->sh_size))
1715 {
1716 free (contents);
1717 return false;
1718 }
1719 l = contents;
1720 lend = contents + hdr->sh_size;
1721 while (l + sizeof (Elf_External_Options) <= lend)
1722 {
1723 Elf_Internal_Options intopt;
1724
1725 bfd_mips_elf_swap_options_in (abfd, (Elf_External_Options *) l,
1726 &intopt);
1727 if (intopt.kind == ODK_REGINFO)
1728 {
1729 Elf64_Internal_RegInfo intreg;
1730
1731 bfd_mips_elf64_swap_reginfo_in
1732 (abfd,
1733 ((Elf64_External_RegInfo *)
1734 (l + sizeof (Elf_External_Options))),
1735 &intreg);
1736 elf_gp (abfd) = intreg.ri_gp_value;
1737 }
1738 l += intopt.size;
1739 }
1740 free (contents);
1741 }
1742
1743 return true;
1744}
1745
1746/* Work over a section just before writing it out. We update the GP
1747 value in the SHT_MIPS_OPTIONS section based on the value we are
1748 using. */
1749
1750static boolean
1751mips_elf64_section_processing (abfd, hdr)
1752 bfd *abfd;
1753 Elf_Internal_Shdr *hdr;
1754{
1755 if (hdr->sh_type == SHT_MIPS_OPTIONS
1756 && hdr->bfd_section != NULL
1757 && elf_section_data (hdr->bfd_section) != NULL
1758 && elf_section_data (hdr->bfd_section)->tdata != NULL)
1759 {
1760 bfd_byte *contents, *l, *lend;
1761
1762 /* We stored the section contents in the elf_section_data tdata
1763 field in the set_section_contents routine. We save the
1764 section contents so that we don't have to read them again.
1765 At this point we know that elf_gp is set, so we can look
1766 through the section contents to see if there is an
1767 ODK_REGINFO structure. */
1768
1769 contents = (bfd_byte *) elf_section_data (hdr->bfd_section)->tdata;
1770 l = contents;
1771 lend = contents + hdr->sh_size;
1772 while (l + sizeof (Elf_External_Options) <= lend)
1773 {
1774 Elf_Internal_Options intopt;
1775
1776 bfd_mips_elf_swap_options_in (abfd, (Elf_External_Options *) l,
1777 &intopt);
1778 if (intopt.kind == ODK_REGINFO)
1779 {
1780 bfd_byte buf[8];
1781
1782 if (bfd_seek (abfd,
1783 (hdr->sh_offset
1784 + (l - contents)
1785 + sizeof (Elf_External_Options)
1786 + (sizeof (Elf64_External_RegInfo) - 8)),
1787 SEEK_SET) == -1)
1788 return false;
1789 bfd_h_put_64 (abfd, elf_gp (abfd), buf);
1790 if (bfd_write (buf, 1, 8, abfd) != 8)
1791 return false;
1792 }
1793 l += intopt.size;
1794 }
1795 }
1796
1797 return _bfd_mips_elf_section_processing (abfd, hdr);
1798}
1799\f
1800/* Irix 6 defines a brand new archive map format, so that they can
1801 have archives more than 4 GB in size. */
1802
1803/* Read an Irix 6 armap. */
1804
1805static boolean
1806mips_elf64_slurp_armap (abfd)
1807 bfd *abfd;
1808{
1809 struct artdata *ardata = bfd_ardata (abfd);
1810 char nextname[17];
1811 file_ptr arhdrpos;
1812 bfd_size_type i, parsed_size, nsymz, stringsize, carsym_size, ptrsize;
1813 struct areltdata *mapdata;
1814 bfd_byte int_buf[8];
1815 char *stringbase;
1816 bfd_byte *raw_armap = NULL;
1817 carsym *carsyms;
1818
1819 ardata->symdefs = NULL;
1820
1821 /* Get the name of the first element. */
1822 arhdrpos = bfd_tell (abfd);
1823 i = bfd_read ((PTR) nextname, 1, 16, abfd);
1824 if (i == 0)
1825 return true;
1826 if (i != 16)
1827 return false;
1828
1829 if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0)
1830 return false;
1831
1832 /* Archives with traditional armaps are still permitted. */
1833 if (strncmp (nextname, "/ ", 16) == 0)
1834 return bfd_slurp_armap (abfd);
1835
1836 if (strncmp (nextname, "/SYM64/ ", 16) != 0)
1837 {
1838 bfd_has_map (abfd) = false;
1839 return true;
1840 }
1841
1842 mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
1843 if (mapdata == NULL)
1844 return false;
1845 parsed_size = mapdata->parsed_size;
1846 bfd_release (abfd, (PTR) mapdata);
1847
1848 if (bfd_read (int_buf, 1, 8, abfd) != 8)
1849 {
1850 if (bfd_get_error () != bfd_error_system_call)
1851 bfd_set_error (bfd_error_malformed_archive);
1852 return false;
1853 }
1854
1855 nsymz = bfd_getb64 (int_buf);
1856 stringsize = parsed_size - 8 * nsymz - 8;
1857
1858 carsym_size = nsymz * sizeof (carsym);
1859 ptrsize = 8 * nsymz;
1860
1861 ardata->symdefs = (carsym *) bfd_zalloc (abfd, carsym_size + stringsize + 1);
1862 if (ardata->symdefs == NULL)
1863 return false;
1864 carsyms = ardata->symdefs;
1865 stringbase = ((char *) ardata->symdefs) + carsym_size;
1866
1867 raw_armap = (bfd_byte *) bfd_alloc (abfd, ptrsize);
1868 if (raw_armap == NULL)
1869 goto error_return;
1870
1871 if (bfd_read (raw_armap, 1, ptrsize, abfd) != ptrsize
1872 || bfd_read (stringbase, 1, stringsize, abfd) != stringsize)
1873 {
1874 if (bfd_get_error () != bfd_error_system_call)
1875 bfd_set_error (bfd_error_malformed_archive);
1876 goto error_return;
1877 }
1878
1879 for (i = 0; i < nsymz; i++)
1880 {
1881 carsyms->file_offset = bfd_getb64 (raw_armap + i * 8);
1882 carsyms->name = stringbase;
1883 stringbase += strlen (stringbase) + 1;
1884 ++carsyms;
1885 }
1886 *stringbase = '\0';
1887
1888 ardata->symdef_count = nsymz;
1889 ardata->first_file_filepos = arhdrpos + sizeof (struct ar_hdr) + parsed_size;
1890
1891 bfd_has_map (abfd) = true;
1892 bfd_release (abfd, raw_armap);
1893
1894 return true;
1895
1896 error_return:
1897 if (raw_armap != NULL)
1898 bfd_release (abfd, raw_armap);
1899 if (ardata->symdefs != NULL)
1900 bfd_release (abfd, ardata->symdefs);
1901 return false;
1902}
1903
1904/* Write out an Irix 6 armap. The Irix 6 tools are supposed to be
1905 able to handle ordinary ELF armaps, but at least on Irix 6.2 the
1906 linker crashes. */
1907
1908static boolean
1909mips_elf64_write_armap (arch, elength, map, symbol_count, stridx)
1910 bfd *arch;
1911 unsigned int elength;
1912 struct orl *map;
1913 unsigned int symbol_count;
1914 int stridx;
1915{
1916 unsigned int ranlibsize = (symbol_count * 8) + 8;
1917 unsigned int stringsize = stridx;
1918 unsigned int mapsize = stringsize + ranlibsize;
1919 file_ptr archive_member_file_ptr;
1920 bfd *current = arch->archive_head;
1921 unsigned int count;
1922 struct ar_hdr hdr;
1923 unsigned int i;
1924 int padding;
1925 bfd_byte buf[8];
1926
1927 padding = BFD_ALIGN (mapsize, 8) - mapsize;
1928 mapsize += padding;
1929
1930 /* work out where the first object file will go in the archive */
1931 archive_member_file_ptr = (mapsize
1932 + elength
1933 + sizeof (struct ar_hdr)
1934 + SARMAG);
1935
1936 memset ((char *) (&hdr), 0, sizeof (struct ar_hdr));
1937 strcpy (hdr.ar_name, "/SYM64/");
1938 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1939 sprintf (hdr.ar_date, "%ld", (long) time (NULL));
1940 /* This, at least, is what Intel coff sets the values to.: */
1941 sprintf ((hdr.ar_uid), "%d", 0);
1942 sprintf ((hdr.ar_gid), "%d", 0);
1943 sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0);
1944 strncpy (hdr.ar_fmag, ARFMAG, 2);
1945
1946 for (i = 0; i < sizeof (struct ar_hdr); i++)
1947 if (((char *) (&hdr))[i] == '\0')
1948 (((char *) (&hdr))[i]) = ' ';
1949
1950 /* Write the ar header for this item and the number of symbols */
1951
1952 if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), arch)
1953 != sizeof (struct ar_hdr))
1954 return false;
1955
1956 bfd_putb64 (symbol_count, buf);
1957 if (bfd_write (buf, 1, 8, arch) != 8)
1958 return false;
1959
1960 /* Two passes, first write the file offsets for each symbol -
1961 remembering that each offset is on a two byte boundary. */
1962
1963 /* Write out the file offset for the file associated with each
1964 symbol, and remember to keep the offsets padded out. */
1965
1966 current = arch->archive_head;
1967 count = 0;
1968 while (current != (bfd *) NULL && count < symbol_count)
1969 {
1970 /* For each symbol which is used defined in this object, write out
1971 the object file's address in the archive */
1972
1973 while (((bfd *) (map[count]).pos) == current)
1974 {
1975 bfd_putb64 (archive_member_file_ptr, buf);
1976 if (bfd_write (buf, 1, 8, arch) != 8)
1977 return false;
1978 count++;
1979 }
1980 /* Add size of this archive entry */
1981 archive_member_file_ptr += (arelt_size (current)
1982 + sizeof (struct ar_hdr));
1983 /* remember about the even alignment */
1984 archive_member_file_ptr += archive_member_file_ptr % 2;
1985 current = current->next;
1986 }
1987
1988 /* now write the strings themselves */
1989 for (count = 0; count < symbol_count; count++)
1990 {
1991 size_t len = strlen (*map[count].name) + 1;
1992
1993 if (bfd_write (*map[count].name, 1, len, arch) != len)
1994 return false;
1995 }
1996
1997 /* The spec says that this should be padded to an 8 byte boundary.
1998 However, the Irix 6.2 tools do not appear to do this. */
1999 while (padding != 0)
2000 {
2001 if (bfd_write ("", 1, 1, arch) != 1)
2002 return false;
2003 --padding;
2004 }
2005
2006 return true;
2007}
2008\f
2009/* ECOFF swapping routines. These are used when dealing with the
2010 .mdebug section, which is in the ECOFF debugging format. */
2011static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
2012{
2013 /* Symbol table magic number. */
2014 magicSym2,
2015 /* Alignment of debugging information. E.g., 4. */
2016 8,
2017 /* Sizes of external symbolic information. */
2018 sizeof (struct hdr_ext),
2019 sizeof (struct dnr_ext),
2020 sizeof (struct pdr_ext),
2021 sizeof (struct sym_ext),
2022 sizeof (struct opt_ext),
2023 sizeof (struct fdr_ext),
2024 sizeof (struct rfd_ext),
2025 sizeof (struct ext_ext),
2026 /* Functions to swap in external symbolic data. */
2027 ecoff_swap_hdr_in,
2028 ecoff_swap_dnr_in,
2029 ecoff_swap_pdr_in,
2030 ecoff_swap_sym_in,
2031 ecoff_swap_opt_in,
2032 ecoff_swap_fdr_in,
2033 ecoff_swap_rfd_in,
2034 ecoff_swap_ext_in,
2035 _bfd_ecoff_swap_tir_in,
2036 _bfd_ecoff_swap_rndx_in,
2037 /* Functions to swap out external symbolic data. */
2038 ecoff_swap_hdr_out,
2039 ecoff_swap_dnr_out,
2040 ecoff_swap_pdr_out,
2041 ecoff_swap_sym_out,
2042 ecoff_swap_opt_out,
2043 ecoff_swap_fdr_out,
2044 ecoff_swap_rfd_out,
2045 ecoff_swap_ext_out,
2046 _bfd_ecoff_swap_tir_out,
2047 _bfd_ecoff_swap_rndx_out,
2048 /* Function to read in symbolic data. */
2049 _bfd_mips_elf_read_ecoff_info
2050};
2051\f
2052/* Relocations in the 64 bit MIPS ELF ABI are more complex than in
2053 standard ELF. This structure is used to redirect the relocation
2054 handling routines. */
2055
2056const struct elf_size_info mips_elf64_size_info =
2057{
2058 sizeof (Elf64_External_Ehdr),
2059 sizeof (Elf64_External_Phdr),
2060 sizeof (Elf64_External_Shdr),
2061 sizeof (Elf64_Mips_External_Rel),
2062 sizeof (Elf64_Mips_External_Rela),
2063 sizeof (Elf64_External_Sym),
2064 sizeof (Elf64_External_Dyn),
2065 sizeof (Elf_External_Note),
2066 64, /* arch_size */
2067 8, /* file_align */
2068 ELFCLASS64,
2069 EV_CURRENT,
2070 bfd_elf64_write_out_phdrs,
2071 bfd_elf64_write_shdrs_and_ehdr,
2072 mips_elf64_write_relocs,
2073 bfd_elf64_swap_symbol_out,
2074 mips_elf64_slurp_reloc_table,
2075 bfd_elf64_slurp_symbol_table,
2076 bfd_elf64_swap_dyn_in
2077};
2078
2079#define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
2080#define TARGET_LITTLE_NAME "elf64-littlemips"
2081#define TARGET_BIG_SYM bfd_elf64_bigmips_vec
2082#define TARGET_BIG_NAME "elf64-bigmips"
2083#define ELF_ARCH bfd_arch_mips
2084#define ELF_MACHINE_CODE EM_MIPS
2085#define ELF_MAXPAGESIZE 0x1000
2086#define elf_backend_size_info mips_elf64_size_info
2087#define elf_backend_object_p _bfd_mips_elf_object_p
2088#define elf_backend_section_from_shdr mips_elf64_section_from_shdr
2089#define elf_backend_fake_sections _bfd_mips_elf_fake_sections
2090#define elf_backend_section_from_bfd_section \
2091 _bfd_mips_elf_section_from_bfd_section
2092#define elf_backend_section_processing mips_elf64_section_processing
2093#define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
2094#define elf_backend_final_write_processing \
2095 _bfd_mips_elf_final_write_processing
2096#define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
2097
2098#define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
2099#define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
2100#define bfd_elf64_bfd_reloc_type_lookup mips_elf64_reloc_type_lookup
2101#define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
2102#define bfd_elf64_bfd_copy_private_bfd_data \
2103 _bfd_mips_elf_copy_private_bfd_data
2104#define bfd_elf64_bfd_merge_private_bfd_data \
2105 _bfd_mips_elf_merge_private_bfd_data
2106#define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
2107
2108#define bfd_elf64_archive_functions
2109#define bfd_elf64_archive_slurp_armap mips_elf64_slurp_armap
2110#define bfd_elf64_archive_slurp_extended_name_table \
2111 _bfd_archive_coff_slurp_extended_name_table
2112#define bfd_elf64_archive_construct_extended_name_table \
2113 _bfd_archive_coff_construct_extended_name_table
2114#define bfd_elf64_archive_truncate_arname \
2115 _bfd_archive_coff_truncate_arname
2116#define bfd_elf64_archive_write_armap mips_elf64_write_armap
2117#define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
2118#define bfd_elf64_archive_openr_next_archived_file \
2119 _bfd_archive_coff_openr_next_archived_file
2120#define bfd_elf64_archive_get_elt_at_index \
2121 _bfd_archive_coff_get_elt_at_index
2122#define bfd_elf64_archive_generic_stat_arch_elt \
2123 _bfd_archive_coff_generic_stat_arch_elt
2124#define bfd_elf64_archive_update_armap_timestamp \
2125 _bfd_archive_coff_update_armap_timestamp
2126
2127#include "elf64-target.h"
This page took 0.109255 seconds and 4 git commands to generate.