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