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