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