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