]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - bfd/elf64-mips.c
Correct spelling of "relocatable".
[thirdparty/binutils-gdb.git] / bfd / elf64-mips.c
1 /* MIPS-specific support for 64-bit ELF
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
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 /* TODO: Many things are unsupported, even if there is some code for it
31 . (which was mostly stolen from elf32-mips.c and slightly adapted).
32 .
33 . - Relocation handling for REL relocs is wrong in many cases and
34 . generally untested.
35 . - Relocation handling for RELA relocs related to GOT support are
36 . also likely to be wrong.
37 . - Support for MIPS16 is untested.
38 . - Combined relocs with RSS_* entries are unsupported.
39 . - The whole GOT handling for NewABI is missing, some parts of
40 . the OldABI version is still lying around and should be removed.
41 */
42
43 #include "bfd.h"
44 #include "sysdep.h"
45 #include "libbfd.h"
46 #include "aout/ar.h"
47 #include "bfdlink.h"
48 #include "genlink.h"
49 #include "elf-bfd.h"
50 #include "elfxx-mips.h"
51 #include "elf/mips.h"
52
53 /* Get the ECOFF swapping routines. The 64-bit ABI is not supposed to
54 use ECOFF. However, we support it anyhow for an easier changeover. */
55 #include "coff/sym.h"
56 #include "coff/symconst.h"
57 #include "coff/internal.h"
58 #include "coff/ecoff.h"
59 /* The 64 bit versions of the mdebug data structures are in alpha.h. */
60 #include "coff/alpha.h"
61 #define ECOFF_SIGNED_64
62 #include "ecoffswap.h"
63
64 static void mips_elf64_swap_reloc_in
65 PARAMS ((bfd *, const Elf64_Mips_External_Rel *,
66 Elf64_Mips_Internal_Rela *));
67 static void mips_elf64_swap_reloca_in
68 PARAMS ((bfd *, const Elf64_Mips_External_Rela *,
69 Elf64_Mips_Internal_Rela *));
70 static void mips_elf64_swap_reloc_out
71 PARAMS ((bfd *, const Elf64_Mips_Internal_Rela *,
72 Elf64_Mips_External_Rel *));
73 static void mips_elf64_swap_reloca_out
74 PARAMS ((bfd *, const Elf64_Mips_Internal_Rela *,
75 Elf64_Mips_External_Rela *));
76 static void mips_elf64_be_swap_reloc_in
77 PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *));
78 static void mips_elf64_be_swap_reloc_out
79 PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *));
80 static void mips_elf64_be_swap_reloca_in
81 PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *));
82 static void mips_elf64_be_swap_reloca_out
83 PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *));
84 static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup
85 PARAMS ((bfd *, bfd_reloc_code_real_type));
86 static reloc_howto_type *mips_elf64_rtype_to_howto
87 PARAMS ((unsigned int, bfd_boolean));
88 static void mips_elf64_info_to_howto_rel
89 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
90 static void mips_elf64_info_to_howto_rela
91 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
92 static long mips_elf64_get_reloc_upper_bound
93 PARAMS ((bfd *, asection *));
94 static long mips_elf64_canonicalize_reloc
95 PARAMS ((bfd *, asection *, arelent **, asymbol **));
96 static long mips_elf64_get_dynamic_reloc_upper_bound PARAMS ((bfd *));
97 static long mips_elf64_canonicalize_dynamic_reloc
98 PARAMS ((bfd *, arelent **, asymbol **));
99 static bfd_boolean mips_elf64_slurp_one_reloc_table
100 PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type,
101 arelent *, asymbol **, bfd_boolean));
102 static bfd_boolean mips_elf64_slurp_reloc_table
103 PARAMS ((bfd *, asection *, asymbol **, bfd_boolean));
104 static void mips_elf64_write_relocs
105 PARAMS ((bfd *, asection *, PTR));
106 static void mips_elf64_write_rel
107 PARAMS((bfd *, asection *, Elf_Internal_Shdr *, int *, PTR));
108 static void mips_elf64_write_rela
109 PARAMS((bfd *, asection *, Elf_Internal_Shdr *, int *, PTR));
110 static bfd_reloc_status_type mips_elf64_hi16_reloc
111 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
112 static bfd_reloc_status_type mips_elf64_gprel16_reloc
113 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
114 static bfd_reloc_status_type mips_elf64_literal_reloc
115 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
116 static bfd_reloc_status_type mips_elf64_gprel32_reloc
117 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
118 static bfd_reloc_status_type mips_elf64_shift6_reloc
119 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
120 static bfd_reloc_status_type mips_elf64_got16_reloc
121 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
122 static bfd_reloc_status_type mips16_jump_reloc
123 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
124 static bfd_reloc_status_type mips16_gprel_reloc
125 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
126 static bfd_boolean mips_elf64_assign_gp
127 PARAMS ((bfd *, bfd_vma *));
128 static bfd_reloc_status_type mips_elf64_final_gp
129 PARAMS ((bfd *, asymbol *, bfd_boolean, char **, bfd_vma *));
130 static bfd_boolean mips_elf64_object_p
131 PARAMS ((bfd *));
132 static irix_compat_t elf64_mips_irix_compat
133 PARAMS ((bfd *));
134 static bfd_boolean elf64_mips_grok_prstatus
135 PARAMS ((bfd *, Elf_Internal_Note *));
136 static bfd_boolean elf64_mips_grok_psinfo
137 PARAMS ((bfd *, Elf_Internal_Note *));
138
139 extern const bfd_target bfd_elf64_bigmips_vec;
140 extern const bfd_target bfd_elf64_littlemips_vec;
141
142 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value
143 from smaller values. Start with zero, widen, *then* decrement. */
144 #define MINUS_ONE (((bfd_vma)0) - 1)
145
146 /* The number of local .got entries we reserve. */
147 #define MIPS_RESERVED_GOTNO (2)
148 \f
149 /* The relocation table used for SHT_REL sections. */
150
151 static reloc_howto_type mips_elf64_howto_table_rel[] =
152 {
153 /* No relocation. */
154 HOWTO (R_MIPS_NONE, /* type */
155 0, /* rightshift */
156 0, /* size (0 = byte, 1 = short, 2 = long) */
157 0, /* bitsize */
158 FALSE, /* pc_relative */
159 0, /* bitpos */
160 complain_overflow_dont, /* complain_on_overflow */
161 bfd_elf_generic_reloc, /* special_function */
162 "R_MIPS_NONE", /* name */
163 FALSE, /* partial_inplace */
164 0, /* src_mask */
165 0, /* dst_mask */
166 FALSE), /* pcrel_offset */
167
168 /* 16 bit relocation. */
169 HOWTO (R_MIPS_16, /* type */
170 0, /* rightshift */
171 2, /* size (0 = byte, 1 = short, 2 = long) */
172 16, /* bitsize */
173 FALSE, /* pc_relative */
174 0, /* bitpos */
175 complain_overflow_signed, /* complain_on_overflow */
176 bfd_elf_generic_reloc, /* special_function */
177 "R_MIPS_16", /* name */
178 TRUE, /* partial_inplace */
179 0x0000ffff, /* src_mask */
180 0x0000ffff, /* dst_mask */
181 FALSE), /* pcrel_offset */
182
183 /* 32 bit relocation. */
184 HOWTO (R_MIPS_32, /* type */
185 0, /* rightshift */
186 2, /* size (0 = byte, 1 = short, 2 = long) */
187 32, /* bitsize */
188 FALSE, /* pc_relative */
189 0, /* bitpos */
190 complain_overflow_dont, /* complain_on_overflow */
191 bfd_elf_generic_reloc, /* special_function */
192 "R_MIPS_32", /* name */
193 TRUE, /* partial_inplace */
194 0xffffffff, /* src_mask */
195 0xffffffff, /* dst_mask */
196 FALSE), /* pcrel_offset */
197
198 /* 32 bit symbol relative relocation. */
199 HOWTO (R_MIPS_REL32, /* type */
200 0, /* rightshift */
201 2, /* size (0 = byte, 1 = short, 2 = long) */
202 32, /* bitsize */
203 FALSE, /* pc_relative */
204 0, /* bitpos */
205 complain_overflow_dont, /* complain_on_overflow */
206 bfd_elf_generic_reloc, /* special_function */
207 "R_MIPS_REL32", /* name */
208 TRUE, /* partial_inplace */
209 0xffffffff, /* src_mask */
210 0xffffffff, /* dst_mask */
211 FALSE), /* pcrel_offset */
212
213 /* 26 bit jump address. */
214 HOWTO (R_MIPS_26, /* type */
215 2, /* rightshift */
216 2, /* size (0 = byte, 1 = short, 2 = long) */
217 26, /* bitsize */
218 FALSE, /* pc_relative */
219 0, /* bitpos */
220 complain_overflow_dont, /* complain_on_overflow */
221 /* This needs complex overflow
222 detection, because the upper 36
223 bits must match the PC + 4. */
224 bfd_elf_generic_reloc, /* special_function */
225 "R_MIPS_26", /* name */
226 TRUE, /* partial_inplace */
227 0x03ffffff, /* src_mask */
228 0x03ffffff, /* dst_mask */
229 FALSE), /* pcrel_offset */
230
231 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
232 However, the native IRIX6 tools use them, so we try our best. */
233
234 /* High 16 bits of symbol value. */
235 HOWTO (R_MIPS_HI16, /* type */
236 0, /* rightshift */
237 2, /* size (0 = byte, 1 = short, 2 = long) */
238 16, /* bitsize */
239 FALSE, /* pc_relative */
240 0, /* bitpos */
241 complain_overflow_dont, /* complain_on_overflow */
242 mips_elf64_hi16_reloc, /* special_function */
243 "R_MIPS_HI16", /* name */
244 TRUE, /* partial_inplace */
245 0x0000ffff, /* src_mask */
246 0x0000ffff, /* dst_mask */
247 FALSE), /* pcrel_offset */
248
249 /* Low 16 bits of symbol value. */
250 HOWTO (R_MIPS_LO16, /* type */
251 0, /* rightshift */
252 2, /* size (0 = byte, 1 = short, 2 = long) */
253 16, /* bitsize */
254 FALSE, /* pc_relative */
255 0, /* bitpos */
256 complain_overflow_dont, /* complain_on_overflow */
257 bfd_elf_generic_reloc, /* special_function */
258 "R_MIPS_LO16", /* name */
259 TRUE, /* partial_inplace */
260 0x0000ffff, /* src_mask */
261 0x0000ffff, /* dst_mask */
262 FALSE), /* pcrel_offset */
263
264 /* GP relative reference. */
265 HOWTO (R_MIPS_GPREL16, /* type */
266 0, /* rightshift */
267 2, /* size (0 = byte, 1 = short, 2 = long) */
268 16, /* bitsize */
269 FALSE, /* pc_relative */
270 0, /* bitpos */
271 complain_overflow_signed, /* complain_on_overflow */
272 mips_elf64_gprel16_reloc, /* special_function */
273 "R_MIPS_GPREL16", /* name */
274 TRUE, /* partial_inplace */
275 0x0000ffff, /* src_mask */
276 0x0000ffff, /* dst_mask */
277 FALSE), /* pcrel_offset */
278
279 /* Reference to literal section. */
280 HOWTO (R_MIPS_LITERAL, /* type */
281 0, /* rightshift */
282 2, /* size (0 = byte, 1 = short, 2 = long) */
283 16, /* bitsize */
284 FALSE, /* pc_relative */
285 0, /* bitpos */
286 complain_overflow_signed, /* complain_on_overflow */
287 mips_elf64_literal_reloc, /* special_function */
288 "R_MIPS_LITERAL", /* name */
289 TRUE, /* partial_inplace */
290 0x0000ffff, /* src_mask */
291 0x0000ffff, /* dst_mask */
292 FALSE), /* pcrel_offset */
293
294 /* Reference to global offset table. */
295 HOWTO (R_MIPS_GOT16, /* type */
296 0, /* rightshift */
297 2, /* size (0 = byte, 1 = short, 2 = long) */
298 16, /* bitsize */
299 FALSE, /* pc_relative */
300 0, /* bitpos */
301 complain_overflow_signed, /* complain_on_overflow */
302 mips_elf64_got16_reloc, /* special_function */
303 "R_MIPS_GOT16", /* name */
304 TRUE, /* partial_inplace */
305 0x0000ffff, /* src_mask */
306 0x0000ffff, /* dst_mask */
307 FALSE), /* pcrel_offset */
308
309 /* 16 bit PC relative reference. */
310 HOWTO (R_MIPS_PC16, /* type */
311 0, /* rightshift */
312 2, /* size (0 = byte, 1 = short, 2 = long) */
313 16, /* bitsize */
314 TRUE, /* pc_relative */
315 0, /* bitpos */
316 complain_overflow_signed, /* complain_on_overflow */
317 bfd_elf_generic_reloc, /* special_function */
318 "R_MIPS_PC16", /* name */
319 TRUE, /* partial_inplace */
320 0x0000ffff, /* src_mask */
321 0x0000ffff, /* dst_mask */
322 TRUE), /* pcrel_offset */
323
324 /* 16 bit call through global offset table. */
325 HOWTO (R_MIPS_CALL16, /* type */
326 0, /* rightshift */
327 2, /* size (0 = byte, 1 = short, 2 = long) */
328 16, /* bitsize */
329 FALSE, /* pc_relative */
330 0, /* bitpos */
331 complain_overflow_signed, /* complain_on_overflow */
332 bfd_elf_generic_reloc, /* special_function */
333 "R_MIPS_CALL16", /* name */
334 TRUE, /* partial_inplace */
335 0x0000ffff, /* src_mask */
336 0x0000ffff, /* dst_mask */
337 FALSE), /* pcrel_offset */
338
339 /* 32 bit GP relative reference. */
340 HOWTO (R_MIPS_GPREL32, /* type */
341 0, /* rightshift */
342 2, /* size (0 = byte, 1 = short, 2 = long) */
343 32, /* bitsize */
344 FALSE, /* pc_relative */
345 0, /* bitpos */
346 complain_overflow_dont, /* complain_on_overflow */
347 mips_elf64_gprel32_reloc, /* special_function */
348 "R_MIPS_GPREL32", /* name */
349 TRUE, /* partial_inplace */
350 0xffffffff, /* src_mask */
351 0xffffffff, /* dst_mask */
352 FALSE), /* pcrel_offset */
353
354 EMPTY_HOWTO (13),
355 EMPTY_HOWTO (14),
356 EMPTY_HOWTO (15),
357
358 /* A 5 bit shift field. */
359 HOWTO (R_MIPS_SHIFT5, /* type */
360 0, /* rightshift */
361 2, /* size (0 = byte, 1 = short, 2 = long) */
362 5, /* bitsize */
363 FALSE, /* pc_relative */
364 6, /* bitpos */
365 complain_overflow_bitfield, /* complain_on_overflow */
366 bfd_elf_generic_reloc, /* special_function */
367 "R_MIPS_SHIFT5", /* name */
368 TRUE, /* partial_inplace */
369 0x000007c0, /* src_mask */
370 0x000007c0, /* dst_mask */
371 FALSE), /* pcrel_offset */
372
373 /* A 6 bit shift field. */
374 HOWTO (R_MIPS_SHIFT6, /* type */
375 0, /* rightshift */
376 2, /* size (0 = byte, 1 = short, 2 = long) */
377 6, /* bitsize */
378 FALSE, /* pc_relative */
379 6, /* bitpos */
380 complain_overflow_bitfield, /* complain_on_overflow */
381 mips_elf64_shift6_reloc, /* special_function */
382 "R_MIPS_SHIFT6", /* name */
383 TRUE, /* partial_inplace */
384 0x000007c4, /* src_mask */
385 0x000007c4, /* dst_mask */
386 FALSE), /* pcrel_offset */
387
388 /* 64 bit relocation. */
389 HOWTO (R_MIPS_64, /* type */
390 0, /* rightshift */
391 4, /* size (0 = byte, 1 = short, 2 = long) */
392 64, /* bitsize */
393 FALSE, /* pc_relative */
394 0, /* bitpos */
395 complain_overflow_dont, /* complain_on_overflow */
396 bfd_elf_generic_reloc, /* special_function */
397 "R_MIPS_64", /* name */
398 TRUE, /* partial_inplace */
399 MINUS_ONE, /* src_mask */
400 MINUS_ONE, /* dst_mask */
401 FALSE), /* pcrel_offset */
402
403 /* Displacement in the global offset table. */
404 HOWTO (R_MIPS_GOT_DISP, /* 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_signed, /* complain_on_overflow */
411 bfd_elf_generic_reloc, /* special_function */
412 "R_MIPS_GOT_DISP", /* name */
413 TRUE, /* partial_inplace */
414 0x0000ffff, /* src_mask */
415 0x0000ffff, /* dst_mask */
416 FALSE), /* pcrel_offset */
417
418 /* Displacement to page pointer in the global offset table. */
419 HOWTO (R_MIPS_GOT_PAGE, /* type */
420 0, /* rightshift */
421 2, /* size (0 = byte, 1 = short, 2 = long) */
422 16, /* bitsize */
423 FALSE, /* pc_relative */
424 0, /* bitpos */
425 complain_overflow_signed, /* complain_on_overflow */
426 bfd_elf_generic_reloc, /* special_function */
427 "R_MIPS_GOT_PAGE", /* name */
428 TRUE, /* partial_inplace */
429 0x0000ffff, /* src_mask */
430 0x0000ffff, /* dst_mask */
431 FALSE), /* pcrel_offset */
432
433 /* Offset from page pointer in the global offset table. */
434 HOWTO (R_MIPS_GOT_OFST, /* type */
435 0, /* rightshift */
436 2, /* size (0 = byte, 1 = short, 2 = long) */
437 16, /* bitsize */
438 FALSE, /* pc_relative */
439 0, /* bitpos */
440 complain_overflow_signed, /* complain_on_overflow */
441 bfd_elf_generic_reloc, /* special_function */
442 "R_MIPS_GOT_OFST", /* name */
443 TRUE, /* partial_inplace */
444 0x0000ffff, /* src_mask */
445 0x0000ffff, /* dst_mask */
446 FALSE), /* pcrel_offset */
447
448 /* High 16 bits of displacement in global offset table. */
449 HOWTO (R_MIPS_GOT_HI16, /* type */
450 0, /* rightshift */
451 2, /* size (0 = byte, 1 = short, 2 = long) */
452 16, /* bitsize */
453 FALSE, /* pc_relative */
454 0, /* bitpos */
455 complain_overflow_dont, /* complain_on_overflow */
456 bfd_elf_generic_reloc, /* special_function */
457 "R_MIPS_GOT_HI16", /* name */
458 TRUE, /* partial_inplace */
459 0x0000ffff, /* src_mask */
460 0x0000ffff, /* dst_mask */
461 FALSE), /* pcrel_offset */
462
463 /* Low 16 bits of displacement in global offset table. */
464 HOWTO (R_MIPS_GOT_LO16, /* type */
465 0, /* rightshift */
466 2, /* size (0 = byte, 1 = short, 2 = long) */
467 16, /* bitsize */
468 FALSE, /* pc_relative */
469 0, /* bitpos */
470 complain_overflow_dont, /* complain_on_overflow */
471 bfd_elf_generic_reloc, /* special_function */
472 "R_MIPS_GOT_LO16", /* name */
473 TRUE, /* partial_inplace */
474 0x0000ffff, /* src_mask */
475 0x0000ffff, /* dst_mask */
476 FALSE), /* pcrel_offset */
477
478 /* 64 bit substraction. */
479 HOWTO (R_MIPS_SUB, /* type */
480 0, /* rightshift */
481 4, /* size (0 = byte, 1 = short, 2 = long) */
482 64, /* bitsize */
483 FALSE, /* pc_relative */
484 0, /* bitpos */
485 complain_overflow_dont, /* complain_on_overflow */
486 bfd_elf_generic_reloc, /* special_function */
487 "R_MIPS_SUB", /* name */
488 TRUE, /* partial_inplace */
489 MINUS_ONE, /* src_mask */
490 MINUS_ONE, /* dst_mask */
491 FALSE), /* pcrel_offset */
492
493 /* Insert the addend as an instruction. */
494 /* FIXME: Not handled correctly. */
495 HOWTO (R_MIPS_INSERT_A, /* type */
496 0, /* rightshift */
497 2, /* size (0 = byte, 1 = short, 2 = long) */
498 32, /* bitsize */
499 FALSE, /* pc_relative */
500 0, /* bitpos */
501 complain_overflow_dont, /* complain_on_overflow */
502 bfd_elf_generic_reloc, /* special_function */
503 "R_MIPS_INSERT_A", /* name */
504 TRUE, /* partial_inplace */
505 0xffffffff, /* src_mask */
506 0xffffffff, /* dst_mask */
507 FALSE), /* pcrel_offset */
508
509 /* Insert the addend as an instruction, and change all relocations
510 to refer to the old instruction at the address. */
511 /* FIXME: Not handled correctly. */
512 HOWTO (R_MIPS_INSERT_B, /* type */
513 0, /* rightshift */
514 2, /* size (0 = byte, 1 = short, 2 = long) */
515 32, /* bitsize */
516 FALSE, /* pc_relative */
517 0, /* bitpos */
518 complain_overflow_dont, /* complain_on_overflow */
519 bfd_elf_generic_reloc, /* special_function */
520 "R_MIPS_INSERT_B", /* name */
521 TRUE, /* partial_inplace */
522 0xffffffff, /* src_mask */
523 0xffffffff, /* dst_mask */
524 FALSE), /* pcrel_offset */
525
526 /* Delete a 32 bit instruction. */
527 /* FIXME: Not handled correctly. */
528 HOWTO (R_MIPS_DELETE, /* type */
529 0, /* rightshift */
530 2, /* size (0 = byte, 1 = short, 2 = long) */
531 32, /* bitsize */
532 FALSE, /* pc_relative */
533 0, /* bitpos */
534 complain_overflow_dont, /* complain_on_overflow */
535 bfd_elf_generic_reloc, /* special_function */
536 "R_MIPS_DELETE", /* name */
537 TRUE, /* partial_inplace */
538 0xffffffff, /* src_mask */
539 0xffffffff, /* dst_mask */
540 FALSE), /* pcrel_offset */
541
542 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
543 We don't, because
544 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
545 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
546 fallable heuristics.
547 b) No other NewABI toolchain actually emits such relocations. */
548 EMPTY_HOWTO (R_MIPS_HIGHER),
549 EMPTY_HOWTO (R_MIPS_HIGHEST),
550
551 /* High 16 bits of displacement in global offset table. */
552 HOWTO (R_MIPS_CALL_HI16, /* type */
553 0, /* rightshift */
554 2, /* size (0 = byte, 1 = short, 2 = long) */
555 16, /* bitsize */
556 FALSE, /* pc_relative */
557 0, /* bitpos */
558 complain_overflow_dont, /* complain_on_overflow */
559 bfd_elf_generic_reloc, /* special_function */
560 "R_MIPS_CALL_HI16", /* name */
561 TRUE, /* partial_inplace */
562 0x0000ffff, /* src_mask */
563 0x0000ffff, /* dst_mask */
564 FALSE), /* pcrel_offset */
565
566 /* Low 16 bits of displacement in global offset table. */
567 HOWTO (R_MIPS_CALL_LO16, /* type */
568 0, /* rightshift */
569 2, /* size (0 = byte, 1 = short, 2 = long) */
570 16, /* bitsize */
571 FALSE, /* pc_relative */
572 0, /* bitpos */
573 complain_overflow_dont, /* complain_on_overflow */
574 bfd_elf_generic_reloc, /* special_function */
575 "R_MIPS_CALL_LO16", /* name */
576 TRUE, /* partial_inplace */
577 0x0000ffff, /* src_mask */
578 0x0000ffff, /* dst_mask */
579 FALSE), /* pcrel_offset */
580
581 /* Section displacement, used by an associated event location section. */
582 HOWTO (R_MIPS_SCN_DISP, /* type */
583 0, /* rightshift */
584 2, /* size (0 = byte, 1 = short, 2 = long) */
585 32, /* bitsize */
586 FALSE, /* pc_relative */
587 0, /* bitpos */
588 complain_overflow_dont, /* complain_on_overflow */
589 bfd_elf_generic_reloc, /* special_function */
590 "R_MIPS_SCN_DISP", /* name */
591 TRUE, /* partial_inplace */
592 0xffffffff, /* src_mask */
593 0xffffffff, /* dst_mask */
594 FALSE), /* pcrel_offset */
595
596 HOWTO (R_MIPS_REL16, /* type */
597 0, /* rightshift */
598 1, /* size (0 = byte, 1 = short, 2 = long) */
599 16, /* bitsize */
600 FALSE, /* pc_relative */
601 0, /* bitpos */
602 complain_overflow_signed, /* complain_on_overflow */
603 bfd_elf_generic_reloc, /* special_function */
604 "R_MIPS_REL16", /* name */
605 TRUE, /* partial_inplace */
606 0xffff, /* src_mask */
607 0xffff, /* dst_mask */
608 FALSE), /* pcrel_offset */
609
610 /* These two are obsolete. */
611 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
612 EMPTY_HOWTO (R_MIPS_PJUMP),
613
614 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
615 It must be used for multigot GOT's (and only there). */
616 HOWTO (R_MIPS_RELGOT, /* type */
617 0, /* rightshift */
618 2, /* size (0 = byte, 1 = short, 2 = long) */
619 32, /* bitsize */
620 FALSE, /* pc_relative */
621 0, /* bitpos */
622 complain_overflow_dont, /* complain_on_overflow */
623 bfd_elf_generic_reloc, /* special_function */
624 "R_MIPS_RELGOT", /* name */
625 TRUE, /* partial_inplace */
626 0xffffffff, /* src_mask */
627 0xffffffff, /* dst_mask */
628 FALSE), /* pcrel_offset */
629
630 /* Protected jump conversion. This is an optimization hint. No
631 relocation is required for correctness. */
632 HOWTO (R_MIPS_JALR, /* type */
633 0, /* rightshift */
634 2, /* size (0 = byte, 1 = short, 2 = long) */
635 32, /* bitsize */
636 FALSE, /* pc_relative */
637 0, /* bitpos */
638 complain_overflow_dont, /* complain_on_overflow */
639 bfd_elf_generic_reloc, /* special_function */
640 "R_MIPS_JALR", /* name */
641 FALSE, /* partial_inplace */
642 0, /* src_mask */
643 0x00000000, /* dst_mask */
644 FALSE), /* pcrel_offset */
645 };
646
647 /* The relocation table used for SHT_RELA sections. */
648
649 static reloc_howto_type mips_elf64_howto_table_rela[] =
650 {
651 /* No relocation. */
652 HOWTO (R_MIPS_NONE, /* type */
653 0, /* rightshift */
654 0, /* size (0 = byte, 1 = short, 2 = long) */
655 0, /* bitsize */
656 FALSE, /* pc_relative */
657 0, /* bitpos */
658 complain_overflow_dont, /* complain_on_overflow */
659 bfd_elf_generic_reloc, /* special_function */
660 "R_MIPS_NONE", /* name */
661 FALSE, /* partial_inplace */
662 0, /* src_mask */
663 0, /* dst_mask */
664 FALSE), /* pcrel_offset */
665
666 /* 16 bit relocation. */
667 HOWTO (R_MIPS_16, /* type */
668 0, /* rightshift */
669 2, /* size (0 = byte, 1 = short, 2 = long) */
670 16, /* bitsize */
671 FALSE, /* pc_relative */
672 0, /* bitpos */
673 complain_overflow_signed, /* complain_on_overflow */
674 bfd_elf_generic_reloc, /* special_function */
675 "R_MIPS_16", /* name */
676 FALSE, /* partial_inplace */
677 0, /* src_mask */
678 0x0000ffff, /* dst_mask */
679 FALSE), /* pcrel_offset */
680
681 /* 32 bit relocation. */
682 HOWTO (R_MIPS_32, /* type */
683 0, /* rightshift */
684 2, /* size (0 = byte, 1 = short, 2 = long) */
685 32, /* bitsize */
686 FALSE, /* pc_relative */
687 0, /* bitpos */
688 complain_overflow_dont, /* complain_on_overflow */
689 bfd_elf_generic_reloc, /* special_function */
690 "R_MIPS_32", /* name */
691 FALSE, /* partial_inplace */
692 0, /* src_mask */
693 0xffffffff, /* dst_mask */
694 FALSE), /* pcrel_offset */
695
696 /* 32 bit symbol relative relocation. */
697 HOWTO (R_MIPS_REL32, /* type */
698 0, /* rightshift */
699 2, /* size (0 = byte, 1 = short, 2 = long) */
700 32, /* bitsize */
701 FALSE, /* pc_relative */
702 0, /* bitpos */
703 complain_overflow_dont, /* complain_on_overflow */
704 bfd_elf_generic_reloc, /* special_function */
705 "R_MIPS_REL32", /* name */
706 FALSE, /* partial_inplace */
707 0, /* src_mask */
708 0xffffffff, /* dst_mask */
709 FALSE), /* pcrel_offset */
710
711 /* 26 bit jump address. */
712 HOWTO (R_MIPS_26, /* type */
713 2, /* rightshift */
714 2, /* size (0 = byte, 1 = short, 2 = long) */
715 26, /* bitsize */
716 FALSE, /* pc_relative */
717 0, /* bitpos */
718 complain_overflow_dont, /* complain_on_overflow */
719 /* This needs complex overflow
720 detection, because the upper 36
721 bits must match the PC + 4. */
722 bfd_elf_generic_reloc, /* special_function */
723 "R_MIPS_26", /* name */
724 FALSE, /* partial_inplace */
725 0, /* src_mask */
726 0x03ffffff, /* dst_mask */
727 FALSE), /* pcrel_offset */
728
729 /* High 16 bits of symbol value. */
730 HOWTO (R_MIPS_HI16, /* type */
731 0, /* rightshift */
732 2, /* size (0 = byte, 1 = short, 2 = long) */
733 16, /* bitsize */
734 FALSE, /* pc_relative */
735 0, /* bitpos */
736 complain_overflow_dont, /* complain_on_overflow */
737 bfd_elf_generic_reloc, /* special_function */
738 "R_MIPS_HI16", /* name */
739 FALSE, /* partial_inplace */
740 0, /* src_mask */
741 0x0000ffff, /* dst_mask */
742 FALSE), /* pcrel_offset */
743
744 /* Low 16 bits of symbol value. */
745 HOWTO (R_MIPS_LO16, /* type */
746 0, /* rightshift */
747 2, /* size (0 = byte, 1 = short, 2 = long) */
748 16, /* bitsize */
749 FALSE, /* pc_relative */
750 0, /* bitpos */
751 complain_overflow_dont, /* complain_on_overflow */
752 bfd_elf_generic_reloc, /* special_function */
753 "R_MIPS_LO16", /* name */
754 FALSE, /* partial_inplace */
755 0, /* src_mask */
756 0x0000ffff, /* dst_mask */
757 FALSE), /* pcrel_offset */
758
759 /* GP relative reference. */
760 HOWTO (R_MIPS_GPREL16, /* type */
761 0, /* rightshift */
762 2, /* size (0 = byte, 1 = short, 2 = long) */
763 16, /* bitsize */
764 FALSE, /* pc_relative */
765 0, /* bitpos */
766 complain_overflow_signed, /* complain_on_overflow */
767 mips_elf64_gprel16_reloc, /* special_function */
768 "R_MIPS_GPREL16", /* name */
769 FALSE, /* partial_inplace */
770 0, /* src_mask */
771 0x0000ffff, /* dst_mask */
772 FALSE), /* pcrel_offset */
773
774 /* Reference to literal section. */
775 HOWTO (R_MIPS_LITERAL, /* type */
776 0, /* rightshift */
777 2, /* size (0 = byte, 1 = short, 2 = long) */
778 16, /* bitsize */
779 FALSE, /* pc_relative */
780 0, /* bitpos */
781 complain_overflow_signed, /* complain_on_overflow */
782 mips_elf64_literal_reloc, /* special_function */
783 "R_MIPS_LITERAL", /* name */
784 FALSE, /* partial_inplace */
785 0, /* src_mask */
786 0x0000ffff, /* dst_mask */
787 FALSE), /* pcrel_offset */
788
789 /* Reference to global offset table. */
790 HOWTO (R_MIPS_GOT16, /* type */
791 0, /* rightshift */
792 2, /* size (0 = byte, 1 = short, 2 = long) */
793 16, /* bitsize */
794 FALSE, /* pc_relative */
795 0, /* bitpos */
796 complain_overflow_signed, /* complain_on_overflow */
797 mips_elf64_got16_reloc, /* special_function */
798 "R_MIPS_GOT16", /* name */
799 FALSE, /* partial_inplace */
800 0, /* src_mask */
801 0x0000ffff, /* dst_mask */
802 FALSE), /* pcrel_offset */
803
804 /* 16 bit PC relative reference. */
805 HOWTO (R_MIPS_PC16, /* type */
806 0, /* rightshift */
807 2, /* size (0 = byte, 1 = short, 2 = long) */
808 16, /* bitsize */
809 TRUE, /* pc_relative */
810 0, /* bitpos */
811 complain_overflow_signed, /* complain_on_overflow */
812 bfd_elf_generic_reloc, /* special_function */
813 "R_MIPS_PC16", /* name */
814 FALSE, /* partial_inplace */
815 0, /* src_mask */
816 0x0000ffff, /* dst_mask */
817 TRUE), /* pcrel_offset */
818
819 /* 16 bit call through global offset table. */
820 HOWTO (R_MIPS_CALL16, /* type */
821 0, /* rightshift */
822 2, /* size (0 = byte, 1 = short, 2 = long) */
823 16, /* bitsize */
824 FALSE, /* pc_relative */
825 0, /* bitpos */
826 complain_overflow_signed, /* complain_on_overflow */
827 bfd_elf_generic_reloc, /* special_function */
828 "R_MIPS_CALL16", /* name */
829 FALSE, /* partial_inplace */
830 0, /* src_mask */
831 0x0000ffff, /* dst_mask */
832 FALSE), /* pcrel_offset */
833
834 /* 32 bit GP relative reference. */
835 HOWTO (R_MIPS_GPREL32, /* type */
836 0, /* rightshift */
837 2, /* size (0 = byte, 1 = short, 2 = long) */
838 32, /* bitsize */
839 FALSE, /* pc_relative */
840 0, /* bitpos */
841 complain_overflow_dont, /* complain_on_overflow */
842 mips_elf64_gprel32_reloc, /* special_function */
843 "R_MIPS_GPREL32", /* name */
844 FALSE, /* partial_inplace */
845 0, /* src_mask */
846 0xffffffff, /* dst_mask */
847 FALSE), /* pcrel_offset */
848
849 EMPTY_HOWTO (13),
850 EMPTY_HOWTO (14),
851 EMPTY_HOWTO (15),
852
853 /* A 5 bit shift field. */
854 HOWTO (R_MIPS_SHIFT5, /* type */
855 0, /* rightshift */
856 2, /* size (0 = byte, 1 = short, 2 = long) */
857 5, /* bitsize */
858 FALSE, /* pc_relative */
859 6, /* bitpos */
860 complain_overflow_bitfield, /* complain_on_overflow */
861 bfd_elf_generic_reloc, /* special_function */
862 "R_MIPS_SHIFT5", /* name */
863 FALSE, /* partial_inplace */
864 0, /* src_mask */
865 0x000007c0, /* dst_mask */
866 FALSE), /* pcrel_offset */
867
868 /* A 6 bit shift field. */
869 HOWTO (R_MIPS_SHIFT6, /* type */
870 0, /* rightshift */
871 2, /* size (0 = byte, 1 = short, 2 = long) */
872 6, /* bitsize */
873 FALSE, /* pc_relative */
874 6, /* bitpos */
875 complain_overflow_bitfield, /* complain_on_overflow */
876 mips_elf64_shift6_reloc, /* special_function */
877 "R_MIPS_SHIFT6", /* name */
878 FALSE, /* partial_inplace */
879 0, /* src_mask */
880 0x000007c4, /* dst_mask */
881 FALSE), /* pcrel_offset */
882
883 /* 64 bit relocation. */
884 HOWTO (R_MIPS_64, /* type */
885 0, /* rightshift */
886 4, /* size (0 = byte, 1 = short, 2 = long) */
887 64, /* bitsize */
888 FALSE, /* pc_relative */
889 0, /* bitpos */
890 complain_overflow_dont, /* complain_on_overflow */
891 bfd_elf_generic_reloc, /* special_function */
892 "R_MIPS_64", /* name */
893 FALSE, /* partial_inplace */
894 0, /* src_mask */
895 MINUS_ONE, /* dst_mask */
896 FALSE), /* pcrel_offset */
897
898 /* Displacement in the global offset table. */
899 HOWTO (R_MIPS_GOT_DISP, /* type */
900 0, /* rightshift */
901 2, /* size (0 = byte, 1 = short, 2 = long) */
902 16, /* bitsize */
903 FALSE, /* pc_relative */
904 0, /* bitpos */
905 complain_overflow_signed, /* complain_on_overflow */
906 bfd_elf_generic_reloc, /* special_function */
907 "R_MIPS_GOT_DISP", /* name */
908 FALSE, /* partial_inplace */
909 0, /* src_mask */
910 0x0000ffff, /* dst_mask */
911 FALSE), /* pcrel_offset */
912
913 /* Displacement to page pointer in the global offset table. */
914 HOWTO (R_MIPS_GOT_PAGE, /* type */
915 0, /* rightshift */
916 2, /* size (0 = byte, 1 = short, 2 = long) */
917 16, /* bitsize */
918 FALSE, /* pc_relative */
919 0, /* bitpos */
920 complain_overflow_signed, /* complain_on_overflow */
921 bfd_elf_generic_reloc, /* special_function */
922 "R_MIPS_GOT_PAGE", /* name */
923 FALSE, /* partial_inplace */
924 0, /* src_mask */
925 0x0000ffff, /* dst_mask */
926 FALSE), /* pcrel_offset */
927
928 /* Offset from page pointer in the global offset table. */
929 HOWTO (R_MIPS_GOT_OFST, /* type */
930 0, /* rightshift */
931 2, /* size (0 = byte, 1 = short, 2 = long) */
932 16, /* bitsize */
933 FALSE, /* pc_relative */
934 0, /* bitpos */
935 complain_overflow_signed, /* complain_on_overflow */
936 bfd_elf_generic_reloc, /* special_function */
937 "R_MIPS_GOT_OFST", /* name */
938 FALSE, /* partial_inplace */
939 0, /* src_mask */
940 0x0000ffff, /* dst_mask */
941 FALSE), /* pcrel_offset */
942
943 /* High 16 bits of displacement in global offset table. */
944 HOWTO (R_MIPS_GOT_HI16, /* type */
945 0, /* rightshift */
946 2, /* size (0 = byte, 1 = short, 2 = long) */
947 16, /* bitsize */
948 FALSE, /* pc_relative */
949 0, /* bitpos */
950 complain_overflow_dont, /* complain_on_overflow */
951 bfd_elf_generic_reloc, /* special_function */
952 "R_MIPS_GOT_HI16", /* name */
953 FALSE, /* partial_inplace */
954 0, /* src_mask */
955 0x0000ffff, /* dst_mask */
956 FALSE), /* pcrel_offset */
957
958 /* Low 16 bits of displacement in global offset table. */
959 HOWTO (R_MIPS_GOT_LO16, /* type */
960 0, /* rightshift */
961 2, /* size (0 = byte, 1 = short, 2 = long) */
962 16, /* bitsize */
963 FALSE, /* pc_relative */
964 0, /* bitpos */
965 complain_overflow_dont, /* complain_on_overflow */
966 bfd_elf_generic_reloc, /* special_function */
967 "R_MIPS_GOT_LO16", /* name */
968 FALSE, /* partial_inplace */
969 0, /* src_mask */
970 0x0000ffff, /* dst_mask */
971 FALSE), /* pcrel_offset */
972
973 /* 64 bit substraction. */
974 HOWTO (R_MIPS_SUB, /* type */
975 0, /* rightshift */
976 4, /* size (0 = byte, 1 = short, 2 = long) */
977 64, /* 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_SUB", /* name */
983 FALSE, /* partial_inplace */
984 0, /* src_mask */
985 MINUS_ONE, /* dst_mask */
986 FALSE), /* pcrel_offset */
987
988 /* Insert the addend as an instruction. */
989 /* FIXME: Not handled correctly. */
990 HOWTO (R_MIPS_INSERT_A, /* type */
991 0, /* rightshift */
992 2, /* size (0 = byte, 1 = short, 2 = long) */
993 32, /* bitsize */
994 FALSE, /* pc_relative */
995 0, /* bitpos */
996 complain_overflow_dont, /* complain_on_overflow */
997 bfd_elf_generic_reloc, /* special_function */
998 "R_MIPS_INSERT_A", /* name */
999 FALSE, /* partial_inplace */
1000 0, /* src_mask */
1001 0xffffffff, /* dst_mask */
1002 FALSE), /* pcrel_offset */
1003
1004 /* Insert the addend as an instruction, and change all relocations
1005 to refer to the old instruction at the address. */
1006 /* FIXME: Not handled correctly. */
1007 HOWTO (R_MIPS_INSERT_B, /* 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_INSERT_B", /* name */
1016 FALSE, /* partial_inplace */
1017 0, /* src_mask */
1018 0xffffffff, /* dst_mask */
1019 FALSE), /* pcrel_offset */
1020
1021 /* Delete a 32 bit instruction. */
1022 /* FIXME: Not handled correctly. */
1023 HOWTO (R_MIPS_DELETE, /* type */
1024 0, /* rightshift */
1025 2, /* size (0 = byte, 1 = short, 2 = long) */
1026 32, /* 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_DELETE", /* name */
1032 FALSE, /* partial_inplace */
1033 0, /* src_mask */
1034 0xffffffff, /* dst_mask */
1035 FALSE), /* pcrel_offset */
1036
1037 /* Get the higher value of a 64 bit addend. */
1038 HOWTO (R_MIPS_HIGHER, /* type */
1039 0, /* rightshift */
1040 2, /* size (0 = byte, 1 = short, 2 = long) */
1041 16, /* bitsize */
1042 FALSE, /* pc_relative */
1043 0, /* bitpos */
1044 complain_overflow_dont, /* complain_on_overflow */
1045 bfd_elf_generic_reloc, /* special_function */
1046 "R_MIPS_HIGHER", /* name */
1047 FALSE, /* partial_inplace */
1048 0, /* src_mask */
1049 0x0000ffff, /* dst_mask */
1050 FALSE), /* pcrel_offset */
1051
1052 /* Get the highest value of a 64 bit addend. */
1053 HOWTO (R_MIPS_HIGHEST, /* 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_HIGHEST", /* name */
1062 FALSE, /* partial_inplace */
1063 0, /* src_mask */
1064 0x0000ffff, /* dst_mask */
1065 FALSE), /* pcrel_offset */
1066
1067 /* High 16 bits of displacement in global offset table. */
1068 HOWTO (R_MIPS_CALL_HI16, /* type */
1069 0, /* rightshift */
1070 2, /* size (0 = byte, 1 = short, 2 = long) */
1071 16, /* bitsize */
1072 FALSE, /* pc_relative */
1073 0, /* bitpos */
1074 complain_overflow_dont, /* complain_on_overflow */
1075 bfd_elf_generic_reloc, /* special_function */
1076 "R_MIPS_CALL_HI16", /* name */
1077 FALSE, /* partial_inplace */
1078 0, /* src_mask */
1079 0x0000ffff, /* dst_mask */
1080 FALSE), /* pcrel_offset */
1081
1082 /* Low 16 bits of displacement in global offset table. */
1083 HOWTO (R_MIPS_CALL_LO16, /* type */
1084 0, /* rightshift */
1085 2, /* size (0 = byte, 1 = short, 2 = long) */
1086 16, /* bitsize */
1087 FALSE, /* pc_relative */
1088 0, /* bitpos */
1089 complain_overflow_dont, /* complain_on_overflow */
1090 bfd_elf_generic_reloc, /* special_function */
1091 "R_MIPS_CALL_LO16", /* name */
1092 FALSE, /* partial_inplace */
1093 0, /* src_mask */
1094 0x0000ffff, /* dst_mask */
1095 FALSE), /* pcrel_offset */
1096
1097 /* Section displacement, used by an associated event location section. */
1098 HOWTO (R_MIPS_SCN_DISP, /* type */
1099 0, /* rightshift */
1100 2, /* size (0 = byte, 1 = short, 2 = long) */
1101 32, /* bitsize */
1102 FALSE, /* pc_relative */
1103 0, /* bitpos */
1104 complain_overflow_dont, /* complain_on_overflow */
1105 bfd_elf_generic_reloc, /* special_function */
1106 "R_MIPS_SCN_DISP", /* name */
1107 FALSE, /* partial_inplace */
1108 0, /* src_mask */
1109 0xffffffff, /* dst_mask */
1110 FALSE), /* pcrel_offset */
1111
1112 HOWTO (R_MIPS_REL16, /* type */
1113 0, /* rightshift */
1114 1, /* size (0 = byte, 1 = short, 2 = long) */
1115 16, /* bitsize */
1116 FALSE, /* pc_relative */
1117 0, /* bitpos */
1118 complain_overflow_signed, /* complain_on_overflow */
1119 bfd_elf_generic_reloc, /* special_function */
1120 "R_MIPS_REL16", /* name */
1121 FALSE, /* partial_inplace */
1122 0, /* src_mask */
1123 0xffff, /* dst_mask */
1124 FALSE), /* pcrel_offset */
1125
1126 /* These two are obsolete. */
1127 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1128 EMPTY_HOWTO (R_MIPS_PJUMP),
1129
1130 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1131 It must be used for multigot GOT's (and only there). */
1132 HOWTO (R_MIPS_RELGOT, /* type */
1133 0, /* rightshift */
1134 2, /* size (0 = byte, 1 = short, 2 = long) */
1135 32, /* bitsize */
1136 FALSE, /* pc_relative */
1137 0, /* bitpos */
1138 complain_overflow_dont, /* complain_on_overflow */
1139 bfd_elf_generic_reloc, /* special_function */
1140 "R_MIPS_RELGOT", /* name */
1141 FALSE, /* partial_inplace */
1142 0, /* src_mask */
1143 0xffffffff, /* dst_mask */
1144 FALSE), /* pcrel_offset */
1145
1146 /* Protected jump conversion. This is an optimization hint. No
1147 relocation is required for correctness. */
1148 HOWTO (R_MIPS_JALR, /* type */
1149 0, /* rightshift */
1150 2, /* size (0 = byte, 1 = short, 2 = long) */
1151 32, /* bitsize */
1152 FALSE, /* pc_relative */
1153 0, /* bitpos */
1154 complain_overflow_dont, /* complain_on_overflow */
1155 bfd_elf_generic_reloc, /* special_function */
1156 "R_MIPS_JALR", /* name */
1157 FALSE, /* partial_inplace */
1158 0, /* src_mask */
1159 0x00000000, /* dst_mask */
1160 FALSE), /* pcrel_offset */
1161 };
1162
1163 /* The reloc used for the mips16 jump instruction. */
1164 static reloc_howto_type elf_mips16_jump_howto =
1165 HOWTO (R_MIPS16_26, /* type */
1166 2, /* rightshift */
1167 2, /* size (0 = byte, 1 = short, 2 = long) */
1168 26, /* bitsize */
1169 FALSE, /* pc_relative */
1170 0, /* bitpos */
1171 complain_overflow_dont, /* complain_on_overflow */
1172 /* This needs complex overflow
1173 detection, because the upper four
1174 bits must match the PC. */
1175 mips16_jump_reloc, /* special_function */
1176 "R_MIPS16_26", /* name */
1177 TRUE, /* partial_inplace */
1178 0x3ffffff, /* src_mask */
1179 0x3ffffff, /* dst_mask */
1180 FALSE); /* pcrel_offset */
1181
1182 /* The reloc used for the mips16 gprel instruction. */
1183 static reloc_howto_type elf_mips16_gprel_howto =
1184 HOWTO (R_MIPS16_GPREL, /* type */
1185 0, /* rightshift */
1186 2, /* size (0 = byte, 1 = short, 2 = long) */
1187 16, /* bitsize */
1188 FALSE, /* pc_relative */
1189 0, /* bitpos */
1190 complain_overflow_signed, /* complain_on_overflow */
1191 mips16_gprel_reloc, /* special_function */
1192 "R_MIPS16_GPREL", /* name */
1193 TRUE, /* partial_inplace */
1194 0x07ff001f, /* src_mask */
1195 0x07ff001f, /* dst_mask */
1196 FALSE); /* pcrel_offset */
1197
1198 /* GNU extension to record C++ vtable hierarchy */
1199 static reloc_howto_type elf_mips_gnu_vtinherit_howto =
1200 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
1201 0, /* rightshift */
1202 2, /* size (0 = byte, 1 = short, 2 = long) */
1203 0, /* bitsize */
1204 FALSE, /* pc_relative */
1205 0, /* bitpos */
1206 complain_overflow_dont, /* complain_on_overflow */
1207 NULL, /* special_function */
1208 "R_MIPS_GNU_VTINHERIT", /* name */
1209 FALSE, /* partial_inplace */
1210 0, /* src_mask */
1211 0, /* dst_mask */
1212 FALSE); /* pcrel_offset */
1213
1214 /* GNU extension to record C++ vtable member usage */
1215 static reloc_howto_type elf_mips_gnu_vtentry_howto =
1216 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
1217 0, /* rightshift */
1218 2, /* size (0 = byte, 1 = short, 2 = long) */
1219 0, /* bitsize */
1220 FALSE, /* pc_relative */
1221 0, /* bitpos */
1222 complain_overflow_dont, /* complain_on_overflow */
1223 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1224 "R_MIPS_GNU_VTENTRY", /* name */
1225 FALSE, /* partial_inplace */
1226 0, /* src_mask */
1227 0, /* dst_mask */
1228 FALSE); /* pcrel_offset */
1229 \f
1230 /* 16 bit offset for pc-relative branches. */
1231 static reloc_howto_type elf_mips_gnu_rel16_s2 =
1232 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
1233 2, /* rightshift */
1234 2, /* size (0 = byte, 1 = short, 2 = long) */
1235 16, /* bitsize */
1236 TRUE, /* pc_relative */
1237 0, /* bitpos */
1238 complain_overflow_signed, /* complain_on_overflow */
1239 bfd_elf_generic_reloc, /* special_function */
1240 "R_MIPS_GNU_REL16_S2", /* name */
1241 TRUE, /* partial_inplace */
1242 0x0000ffff, /* src_mask */
1243 0x0000ffff, /* dst_mask */
1244 TRUE); /* pcrel_offset */
1245
1246 /* 16 bit offset for pc-relative branches. */
1247 static reloc_howto_type elf_mips_gnu_rela16_s2 =
1248 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
1249 2, /* rightshift */
1250 2, /* size (0 = byte, 1 = short, 2 = long) */
1251 16, /* bitsize */
1252 TRUE, /* pc_relative */
1253 0, /* bitpos */
1254 complain_overflow_signed, /* complain_on_overflow */
1255 bfd_elf_generic_reloc, /* special_function */
1256 "R_MIPS_GNU_REL16_S2", /* name */
1257 FALSE, /* partial_inplace */
1258 0, /* src_mask */
1259 0x0000ffff, /* dst_mask */
1260 TRUE); /* pcrel_offset */
1261 \f
1262 /* Swap in a MIPS 64-bit Rel reloc. */
1263
1264 static void
1265 mips_elf64_swap_reloc_in (abfd, src, dst)
1266 bfd *abfd;
1267 const Elf64_Mips_External_Rel *src;
1268 Elf64_Mips_Internal_Rela *dst;
1269 {
1270 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1271 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1272 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1273 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1274 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1275 dst->r_type = H_GET_8 (abfd, src->r_type);
1276 dst->r_addend = 0;
1277 }
1278
1279 /* Swap in a MIPS 64-bit Rela reloc. */
1280
1281 static void
1282 mips_elf64_swap_reloca_in (abfd, src, dst)
1283 bfd *abfd;
1284 const Elf64_Mips_External_Rela *src;
1285 Elf64_Mips_Internal_Rela *dst;
1286 {
1287 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1288 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1289 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1290 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1291 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1292 dst->r_type = H_GET_8 (abfd, src->r_type);
1293 dst->r_addend = H_GET_S64 (abfd, src->r_addend);
1294 }
1295
1296 /* Swap out a MIPS 64-bit Rel reloc. */
1297
1298 static void
1299 mips_elf64_swap_reloc_out (abfd, src, dst)
1300 bfd *abfd;
1301 const Elf64_Mips_Internal_Rela *src;
1302 Elf64_Mips_External_Rel *dst;
1303 {
1304 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1305 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1306 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1307 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1308 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1309 H_PUT_8 (abfd, src->r_type, dst->r_type);
1310 }
1311
1312 /* Swap out a MIPS 64-bit Rela reloc. */
1313
1314 static void
1315 mips_elf64_swap_reloca_out (abfd, src, dst)
1316 bfd *abfd;
1317 const Elf64_Mips_Internal_Rela *src;
1318 Elf64_Mips_External_Rela *dst;
1319 {
1320 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1321 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1322 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1323 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1324 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1325 H_PUT_8 (abfd, src->r_type, dst->r_type);
1326 H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
1327 }
1328
1329 /* Swap in a MIPS 64-bit Rel reloc. */
1330
1331 static void
1332 mips_elf64_be_swap_reloc_in (abfd, src, dst)
1333 bfd *abfd;
1334 const bfd_byte *src;
1335 Elf_Internal_Rela *dst;
1336 {
1337 Elf64_Mips_Internal_Rela mirel;
1338
1339 mips_elf64_swap_reloc_in (abfd,
1340 (const Elf64_Mips_External_Rel *) src,
1341 &mirel);
1342
1343 dst[0].r_offset = mirel.r_offset;
1344 dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
1345 dst[0].r_addend = 0;
1346 dst[1].r_offset = mirel.r_offset;
1347 dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
1348 dst[1].r_addend = 0;
1349 dst[2].r_offset = mirel.r_offset;
1350 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
1351 dst[2].r_addend = 0;
1352 }
1353
1354 /* Swap in a MIPS 64-bit Rela reloc. */
1355
1356 static void
1357 mips_elf64_be_swap_reloca_in (abfd, src, dst)
1358 bfd *abfd;
1359 const bfd_byte *src;
1360 Elf_Internal_Rela *dst;
1361 {
1362 Elf64_Mips_Internal_Rela mirela;
1363
1364 mips_elf64_swap_reloca_in (abfd,
1365 (const Elf64_Mips_External_Rela *) src,
1366 &mirela);
1367
1368 dst[0].r_offset = mirela.r_offset;
1369 dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
1370 dst[0].r_addend = mirela.r_addend;
1371 dst[1].r_offset = mirela.r_offset;
1372 dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
1373 dst[1].r_addend = 0;
1374 dst[2].r_offset = mirela.r_offset;
1375 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
1376 dst[2].r_addend = 0;
1377 }
1378
1379 /* Swap out a MIPS 64-bit Rel reloc. */
1380
1381 static void
1382 mips_elf64_be_swap_reloc_out (abfd, src, dst)
1383 bfd *abfd;
1384 const Elf_Internal_Rela *src;
1385 bfd_byte *dst;
1386 {
1387 Elf64_Mips_Internal_Rela mirel;
1388
1389 mirel.r_offset = src[0].r_offset;
1390 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1391 #if 0
1392 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
1393 #endif
1394
1395 mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1396 mirel.r_sym = ELF64_R_SYM (src[0].r_info);
1397 mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1398 mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1399 mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1400
1401 mips_elf64_swap_reloc_out (abfd, &mirel,
1402 (Elf64_Mips_External_Rel *) dst);
1403 }
1404
1405 /* Swap out a MIPS 64-bit Rela reloc. */
1406
1407 static void
1408 mips_elf64_be_swap_reloca_out (abfd, src, dst)
1409 bfd *abfd;
1410 const Elf_Internal_Rela *src;
1411 bfd_byte *dst;
1412 {
1413 Elf64_Mips_Internal_Rela mirela;
1414
1415 mirela.r_offset = src[0].r_offset;
1416 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1417 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
1418
1419 mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1420 mirela.r_sym = ELF64_R_SYM (src[0].r_info);
1421 mirela.r_addend = src[0].r_addend;
1422 BFD_ASSERT(src[1].r_addend == 0);
1423 BFD_ASSERT(src[2].r_addend == 0);
1424
1425 mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1426 mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1427 mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1428
1429 mips_elf64_swap_reloca_out (abfd, &mirela,
1430 (Elf64_Mips_External_Rela *) dst);
1431 }
1432 \f
1433 /* Do a R_MIPS_HI16 relocation. */
1434
1435 static bfd_reloc_status_type
1436 mips_elf64_hi16_reloc (abfd, reloc_entry, symbol, data, input_section,
1437 output_bfd, error_message)
1438 bfd *abfd ATTRIBUTE_UNUSED;
1439 arelent *reloc_entry;
1440 asymbol *symbol;
1441 PTR data ATTRIBUTE_UNUSED;
1442 asection *input_section;
1443 bfd *output_bfd;
1444 char **error_message ATTRIBUTE_UNUSED;
1445 {
1446 /* If we're relocating, and this is an external symbol, we don't
1447 want to change anything. */
1448 if (output_bfd != (bfd *) NULL
1449 && (symbol->flags & BSF_SECTION_SYM) == 0
1450 && (symbol->flags & BSF_LOCAL) != 0)
1451 {
1452 reloc_entry->address += input_section->output_offset;
1453 return bfd_reloc_ok;
1454 }
1455
1456 if (reloc_entry->howto->partial_inplace)
1457 {
1458 if (((reloc_entry->addend & 0xffff) + 0x8000) & ~0xffff)
1459 reloc_entry->addend += 0x8000;
1460 }
1461
1462 return bfd_reloc_continue;
1463 }
1464
1465 /* Do a R_MIPS_GOT16 reloc. This is a reloc against the global offset
1466 table used for PIC code. If the symbol is an external symbol, the
1467 instruction is modified to contain the offset of the appropriate
1468 entry in the global offset table. If the symbol is a section
1469 symbol, the next reloc is a R_MIPS_LO16 reloc. The two 16 bit
1470 addends are combined to form the real addend against the section
1471 symbol; the GOT16 is modified to contain the offset of an entry in
1472 the global offset table, and the LO16 is modified to offset it
1473 appropriately. Thus an offset larger than 16 bits requires a
1474 modified value in the global offset table.
1475
1476 This implementation suffices for the assembler, but the linker does
1477 not yet know how to create global offset tables. */
1478
1479 static bfd_reloc_status_type
1480 mips_elf64_got16_reloc (abfd, reloc_entry, symbol, data, input_section,
1481 output_bfd, error_message)
1482 bfd *abfd;
1483 arelent *reloc_entry;
1484 asymbol *symbol;
1485 PTR data;
1486 asection *input_section;
1487 bfd *output_bfd;
1488 char **error_message;
1489 {
1490 /* If we're relocating, and this is a local symbol, we can handle it
1491 just like an R_MIPS_HI16. */
1492 if (output_bfd != (bfd *) NULL
1493 && ((symbol->flags & BSF_SECTION_SYM) != 0
1494 || (symbol->flags & BSF_LOCAL) == 0))
1495 return mips_elf64_hi16_reloc (abfd, reloc_entry, symbol, data,
1496 input_section, output_bfd, error_message);
1497
1498
1499 /* Otherwise we try to handle it as R_MIPS_GOT_DISP. */
1500 return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
1501 input_section, output_bfd, error_message);
1502 }
1503
1504 /* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
1505 dangerous relocation. */
1506
1507 static bfd_boolean
1508 mips_elf64_assign_gp (output_bfd, pgp)
1509 bfd *output_bfd;
1510 bfd_vma *pgp;
1511 {
1512 unsigned int count;
1513 asymbol **sym;
1514 unsigned int i;
1515
1516 /* If we've already figured out what GP will be, just return it. */
1517 *pgp = _bfd_get_gp_value (output_bfd);
1518 if (*pgp)
1519 return TRUE;
1520
1521 count = bfd_get_symcount (output_bfd);
1522 sym = bfd_get_outsymbols (output_bfd);
1523
1524 /* The linker script will have created a symbol named `_gp' with the
1525 appropriate value. */
1526 if (sym == (asymbol **) NULL)
1527 i = count;
1528 else
1529 {
1530 for (i = 0; i < count; i++, sym++)
1531 {
1532 register const char *name;
1533
1534 name = bfd_asymbol_name (*sym);
1535 if (*name == '_' && strcmp (name, "_gp") == 0)
1536 {
1537 *pgp = bfd_asymbol_value (*sym);
1538 _bfd_set_gp_value (output_bfd, *pgp);
1539 break;
1540 }
1541 }
1542 }
1543
1544 if (i >= count)
1545 {
1546 /* Only get the error once. */
1547 *pgp = 4;
1548 _bfd_set_gp_value (output_bfd, *pgp);
1549 return FALSE;
1550 }
1551
1552 return TRUE;
1553 }
1554
1555 /* We have to figure out the gp value, so that we can adjust the
1556 symbol value correctly. We look up the symbol _gp in the output
1557 BFD. If we can't find it, we're stuck. We cache it in the ELF
1558 target data. We don't need to adjust the symbol value for an
1559 external symbol if we are producing relocatable output. */
1560
1561 static bfd_reloc_status_type
1562 mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message, pgp)
1563 bfd *output_bfd;
1564 asymbol *symbol;
1565 bfd_boolean relocatable;
1566 char **error_message;
1567 bfd_vma *pgp;
1568 {
1569 if (bfd_is_und_section (symbol->section)
1570 && ! relocatable)
1571 {
1572 *pgp = 0;
1573 return bfd_reloc_undefined;
1574 }
1575
1576 *pgp = _bfd_get_gp_value (output_bfd);
1577 if (*pgp == 0
1578 && (! relocatable
1579 || (symbol->flags & BSF_SECTION_SYM) != 0))
1580 {
1581 if (relocatable)
1582 {
1583 /* Make up a value. */
1584 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
1585 _bfd_set_gp_value (output_bfd, *pgp);
1586 }
1587 else if (!mips_elf64_assign_gp (output_bfd, pgp))
1588 {
1589 *error_message =
1590 (char *) _("GP relative relocation when _gp not defined");
1591 return bfd_reloc_dangerous;
1592 }
1593 }
1594
1595 return bfd_reloc_ok;
1596 }
1597
1598 /* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1599 become the offset from the gp register. */
1600
1601 static bfd_reloc_status_type
1602 mips_elf64_gprel16_reloc (abfd, reloc_entry, symbol, data, input_section,
1603 output_bfd, error_message)
1604 bfd *abfd;
1605 arelent *reloc_entry;
1606 asymbol *symbol;
1607 PTR data;
1608 asection *input_section;
1609 bfd *output_bfd;
1610 char **error_message;
1611 {
1612 bfd_boolean relocatable;
1613 bfd_reloc_status_type ret;
1614 bfd_vma gp;
1615
1616 /* If we're relocating, and this is an external symbol, we don't want
1617 to change anything. */
1618 if (output_bfd != (bfd *) NULL
1619 && (symbol->flags & BSF_SECTION_SYM) == 0
1620 && (symbol->flags & BSF_LOCAL) != 0)
1621 {
1622 reloc_entry->address += input_section->output_offset;
1623 return bfd_reloc_ok;
1624 }
1625
1626 if (output_bfd != (bfd *) NULL)
1627 relocatable = TRUE;
1628 else
1629 {
1630 relocatable = FALSE;
1631 output_bfd = symbol->section->output_section->owner;
1632 }
1633
1634 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
1635 &gp);
1636 if (ret != bfd_reloc_ok)
1637 return ret;
1638
1639 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1640 input_section, relocatable,
1641 data, gp);
1642 }
1643
1644 /* Do a R_MIPS_LITERAL relocation. */
1645
1646 static bfd_reloc_status_type
1647 mips_elf64_literal_reloc (abfd, reloc_entry, symbol, data, input_section,
1648 output_bfd, error_message)
1649 bfd *abfd;
1650 arelent *reloc_entry;
1651 asymbol *symbol;
1652 PTR data;
1653 asection *input_section;
1654 bfd *output_bfd;
1655 char **error_message;
1656 {
1657 bfd_boolean relocatable;
1658 bfd_reloc_status_type ret;
1659 bfd_vma gp;
1660
1661 /* If we're relocating, and this is an external symbol, we don't
1662 want to change anything. */
1663 if (output_bfd != (bfd *) NULL
1664 && (symbol->flags & BSF_SECTION_SYM) == 0
1665 && (symbol->flags & BSF_LOCAL) != 0)
1666 {
1667 reloc_entry->address += input_section->output_offset;
1668 return bfd_reloc_ok;
1669 }
1670
1671 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
1672 if (output_bfd != (bfd *) NULL)
1673 relocatable = TRUE;
1674 else
1675 {
1676 relocatable = FALSE;
1677 output_bfd = symbol->section->output_section->owner;
1678 }
1679
1680 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
1681 &gp);
1682 if (ret != bfd_reloc_ok)
1683 return ret;
1684
1685 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1686 input_section, relocatable,
1687 data, gp);
1688 }
1689
1690 /* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1691 become the offset from the gp register. */
1692
1693 static bfd_reloc_status_type
1694 mips_elf64_gprel32_reloc (abfd, reloc_entry, symbol, data, input_section,
1695 output_bfd, error_message)
1696 bfd *abfd;
1697 arelent *reloc_entry;
1698 asymbol *symbol;
1699 PTR data;
1700 asection *input_section;
1701 bfd *output_bfd;
1702 char **error_message;
1703 {
1704 bfd_boolean relocatable;
1705 bfd_reloc_status_type ret;
1706 bfd_vma gp;
1707 bfd_vma relocation;
1708 bfd_vma val;
1709
1710 /* If we're relocating, and this is an external symbol, we don't want
1711 to change anything. */
1712 if (output_bfd != (bfd *) NULL
1713 && (symbol->flags & BSF_SECTION_SYM) == 0
1714 && (symbol->flags & BSF_LOCAL) != 0)
1715 {
1716 *error_message = (char *)
1717 _("32bits gp relative relocation occurs for an external symbol");
1718 return bfd_reloc_outofrange;
1719 }
1720
1721 if (output_bfd != (bfd *) NULL)
1722 relocatable = TRUE;
1723 else
1724 {
1725 relocatable = FALSE;
1726 output_bfd = symbol->section->output_section->owner;
1727 }
1728
1729 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
1730 error_message, &gp);
1731 if (ret != bfd_reloc_ok)
1732 return ret;
1733
1734 if (bfd_is_com_section (symbol->section))
1735 relocation = 0;
1736 else
1737 relocation = symbol->value;
1738
1739 relocation += symbol->section->output_section->vma;
1740 relocation += symbol->section->output_offset;
1741
1742 if (reloc_entry->address > input_section->_cooked_size)
1743 return bfd_reloc_outofrange;
1744
1745 /* Set val to the offset into the section or symbol. */
1746 val = reloc_entry->addend;
1747
1748 if (reloc_entry->howto->partial_inplace)
1749 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1750
1751 /* Adjust val for the final section location and GP value. If we
1752 are producing relocatable output, we don't want to do this for
1753 an external symbol. */
1754 if (! relocatable
1755 || (symbol->flags & BSF_SECTION_SYM) != 0)
1756 val += relocation - gp;
1757
1758 if (reloc_entry->howto->partial_inplace)
1759 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
1760 else
1761 reloc_entry->addend = val;
1762
1763 if (relocatable)
1764 reloc_entry->address += input_section->output_offset;
1765
1766 return bfd_reloc_ok;
1767 }
1768
1769 /* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
1770 the rest is at bits 6-10. The bitpos already got right by the howto. */
1771
1772 static bfd_reloc_status_type
1773 mips_elf64_shift6_reloc (abfd, reloc_entry, symbol, data, input_section,
1774 output_bfd, error_message)
1775 bfd *abfd ATTRIBUTE_UNUSED;
1776 arelent *reloc_entry;
1777 asymbol *symbol;
1778 PTR data ATTRIBUTE_UNUSED;
1779 asection *input_section;
1780 bfd *output_bfd;
1781 char **error_message ATTRIBUTE_UNUSED;
1782 {
1783 /* If we're relocating, and this is an external symbol, we don't
1784 want to change anything. */
1785 if (output_bfd != (bfd *) NULL
1786 && (symbol->flags & BSF_SECTION_SYM) == 0
1787 && (symbol->flags & BSF_LOCAL) != 0)
1788 {
1789 reloc_entry->address += input_section->output_offset;
1790 return bfd_reloc_ok;
1791 }
1792
1793 if (reloc_entry->howto->partial_inplace)
1794 {
1795 reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
1796 | (reloc_entry->addend & 0x00000800) >> 9);
1797 }
1798
1799 return bfd_reloc_continue;
1800 }
1801
1802 /* Handle a mips16 jump. */
1803
1804 static bfd_reloc_status_type
1805 mips16_jump_reloc (abfd, reloc_entry, symbol, data, input_section,
1806 output_bfd, error_message)
1807 bfd *abfd ATTRIBUTE_UNUSED;
1808 arelent *reloc_entry;
1809 asymbol *symbol;
1810 PTR data ATTRIBUTE_UNUSED;
1811 asection *input_section;
1812 bfd *output_bfd;
1813 char **error_message ATTRIBUTE_UNUSED;
1814 {
1815 if (output_bfd != (bfd *) NULL
1816 && (symbol->flags & BSF_SECTION_SYM) == 0
1817 && (! reloc_entry->howto->partial_inplace
1818 || reloc_entry->addend == 0))
1819 {
1820 reloc_entry->address += input_section->output_offset;
1821 return bfd_reloc_ok;
1822 }
1823
1824 /* FIXME. */
1825 {
1826 static bfd_boolean warned;
1827
1828 if (! warned)
1829 (*_bfd_error_handler)
1830 (_("Linking mips16 objects into %s format is not supported"),
1831 bfd_get_target (input_section->output_section->owner));
1832 warned = TRUE;
1833 }
1834
1835 return bfd_reloc_undefined;
1836 }
1837
1838 /* Handle a mips16 GP relative reloc. */
1839
1840 static bfd_reloc_status_type
1841 mips16_gprel_reloc (abfd, reloc_entry, symbol, data, input_section,
1842 output_bfd, error_message)
1843 bfd *abfd;
1844 arelent *reloc_entry;
1845 asymbol *symbol;
1846 PTR data;
1847 asection *input_section;
1848 bfd *output_bfd;
1849 char **error_message;
1850 {
1851 bfd_boolean relocatable;
1852 bfd_reloc_status_type ret;
1853 bfd_vma gp;
1854 unsigned short extend = 0;
1855 unsigned short insn = 0;
1856 bfd_signed_vma val;
1857 bfd_vma relocation;
1858
1859 /* If we're relocating, and this is an external symbol with no
1860 addend, we don't want to change anything. */
1861 if (output_bfd != NULL
1862 && (symbol->flags & BSF_SECTION_SYM) == 0
1863 && (symbol->flags & BSF_LOCAL) != 0)
1864 {
1865 reloc_entry->address += input_section->output_offset;
1866 return bfd_reloc_ok;
1867 }
1868
1869 if (output_bfd != NULL)
1870 relocatable = TRUE;
1871 else
1872 {
1873 relocatable = FALSE;
1874 output_bfd = symbol->section->output_section->owner;
1875 }
1876
1877 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
1878 &gp);
1879 if (ret != bfd_reloc_ok)
1880 return ret;
1881
1882 if (reloc_entry->address > input_section->_cooked_size)
1883 return bfd_reloc_outofrange;
1884
1885 if (bfd_is_com_section (symbol->section))
1886 relocation = 0;
1887 else
1888 relocation = symbol->value;
1889
1890 relocation += symbol->section->output_section->vma;
1891 relocation += symbol->section->output_offset;
1892
1893 /* Set val to the offset into the section or symbol. */
1894 val = reloc_entry->addend;
1895
1896 if (reloc_entry->howto->partial_inplace)
1897 {
1898 /* Pick up the mips16 extend instruction and the real instruction. */
1899 extend = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);
1900 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address + 2);
1901 val += ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
1902 }
1903
1904 _bfd_mips_elf_sign_extend(val, 16);
1905
1906 /* Adjust val for the final section location and GP value. If we
1907 are producing relocatable output, we don't want to do this for
1908 an external symbol. */
1909 if (! relocatable
1910 || (symbol->flags & BSF_SECTION_SYM) != 0)
1911 val += relocation - gp;
1912
1913 if (reloc_entry->howto->partial_inplace)
1914 {
1915 bfd_put_16 (abfd,
1916 (bfd_vma) ((extend & 0xf800)
1917 | ((val >> 11) & 0x1f)
1918 | (val & 0x7e0)),
1919 (bfd_byte *) data + reloc_entry->address);
1920 bfd_put_16 (abfd,
1921 (bfd_vma) ((insn & 0xffe0)
1922 | (val & 0x1f)),
1923 (bfd_byte *) data + reloc_entry->address + 2);
1924 }
1925 else
1926 reloc_entry->addend = val;
1927
1928 if (relocatable)
1929 reloc_entry->address += input_section->output_offset;
1930 else if (((val & ~0xffff) != ~0xffff) && ((val & ~0xffff) != 0))
1931 return bfd_reloc_overflow;
1932
1933 return bfd_reloc_ok;
1934 }
1935 \f
1936 /* A mapping from BFD reloc types to MIPS ELF reloc types. */
1937
1938 struct elf_reloc_map {
1939 bfd_reloc_code_real_type bfd_val;
1940 enum elf_mips_reloc_type elf_val;
1941 };
1942
1943 static const struct elf_reloc_map mips_reloc_map[] =
1944 {
1945 { BFD_RELOC_NONE, R_MIPS_NONE },
1946 { BFD_RELOC_16, R_MIPS_16 },
1947 { BFD_RELOC_32, R_MIPS_32 },
1948 /* There is no BFD reloc for R_MIPS_REL32. */
1949 { BFD_RELOC_64, R_MIPS_64 },
1950 { BFD_RELOC_CTOR, R_MIPS_64 },
1951 { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
1952 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1953 { BFD_RELOC_LO16, R_MIPS_LO16 },
1954 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
1955 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
1956 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1957 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1958 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1959 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1960 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
1961 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
1962 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
1963 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1964 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1965 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1966 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1967 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1968 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
1969 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
1970 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
1971 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
1972 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
1973 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
1974 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1975 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
1976 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
1977 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
1978 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
1979 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR }
1980 };
1981
1982 /* Given a BFD reloc type, return a howto structure. */
1983
1984 static reloc_howto_type *
1985 bfd_elf64_bfd_reloc_type_lookup (abfd, code)
1986 bfd *abfd ATTRIBUTE_UNUSED;
1987 bfd_reloc_code_real_type code;
1988 {
1989 unsigned int i;
1990 /* FIXME: We default to RELA here instead of choosing the right
1991 relocation variant. */
1992 reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
1993
1994 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
1995 i++)
1996 {
1997 if (mips_reloc_map[i].bfd_val == code)
1998 return &howto_table[(int) mips_reloc_map[i].elf_val];
1999 }
2000
2001 switch (code)
2002 {
2003 case BFD_RELOC_MIPS16_JMP:
2004 return &elf_mips16_jump_howto;
2005 case BFD_RELOC_MIPS16_GPREL:
2006 return &elf_mips16_gprel_howto;
2007 case BFD_RELOC_VTABLE_INHERIT:
2008 return &elf_mips_gnu_vtinherit_howto;
2009 case BFD_RELOC_VTABLE_ENTRY:
2010 return &elf_mips_gnu_vtentry_howto;
2011 case BFD_RELOC_16_PCREL_S2:
2012 return &elf_mips_gnu_rela16_s2;
2013 default:
2014 bfd_set_error (bfd_error_bad_value);
2015 return NULL;
2016 }
2017 }
2018
2019 /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
2020
2021 static reloc_howto_type *
2022 mips_elf64_rtype_to_howto (r_type, rela_p)
2023 unsigned int r_type;
2024 bfd_boolean rela_p;
2025 {
2026 switch (r_type)
2027 {
2028 case R_MIPS16_26:
2029 return &elf_mips16_jump_howto;
2030 case R_MIPS16_GPREL:
2031 return &elf_mips16_gprel_howto;
2032 case R_MIPS_GNU_VTINHERIT:
2033 return &elf_mips_gnu_vtinherit_howto;
2034 case R_MIPS_GNU_VTENTRY:
2035 return &elf_mips_gnu_vtentry_howto;
2036 case R_MIPS_GNU_REL16_S2:
2037 if (rela_p)
2038 return &elf_mips_gnu_rela16_s2;
2039 else
2040 return &elf_mips_gnu_rel16_s2;
2041 default:
2042 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
2043 if (rela_p)
2044 return &mips_elf64_howto_table_rela[r_type];
2045 else
2046 return &mips_elf64_howto_table_rel[r_type];
2047 break;
2048 }
2049 }
2050
2051 /* Prevent relocation handling by bfd for MIPS ELF64. */
2052
2053 static void
2054 mips_elf64_info_to_howto_rel (abfd, cache_ptr, dst)
2055 bfd *abfd ATTRIBUTE_UNUSED;
2056 arelent *cache_ptr ATTRIBUTE_UNUSED;
2057 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED;
2058 {
2059 BFD_ASSERT (0);
2060 }
2061
2062 static void
2063 mips_elf64_info_to_howto_rela (abfd, cache_ptr, dst)
2064 bfd *abfd ATTRIBUTE_UNUSED;
2065 arelent *cache_ptr ATTRIBUTE_UNUSED;
2066 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED;
2067 {
2068 BFD_ASSERT (0);
2069 }
2070
2071 /* Since each entry in an SHT_REL or SHT_RELA section can represent up
2072 to three relocs, we must tell the user to allocate more space. */
2073
2074 static long
2075 mips_elf64_get_reloc_upper_bound (abfd, sec)
2076 bfd *abfd ATTRIBUTE_UNUSED;
2077 asection *sec;
2078 {
2079 return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
2080 }
2081
2082 static long
2083 mips_elf64_get_dynamic_reloc_upper_bound (abfd)
2084 bfd *abfd;
2085 {
2086 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
2087 }
2088
2089 /* We must also copy more relocations than the corresponding functions
2090 in elf.c would, so the two following functions are slightly
2091 modified from elf.c, that multiply the external relocation count by
2092 3 to obtain the internal relocation count. */
2093
2094 static long
2095 mips_elf64_canonicalize_reloc (abfd, section, relptr, symbols)
2096 bfd *abfd;
2097 sec_ptr section;
2098 arelent **relptr;
2099 asymbol **symbols;
2100 {
2101 arelent *tblptr;
2102 unsigned int i;
2103 struct elf_backend_data *bed = get_elf_backend_data (abfd);
2104
2105 if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
2106 return -1;
2107
2108 tblptr = section->relocation;
2109 for (i = 0; i < section->reloc_count * 3; i++)
2110 *relptr++ = tblptr++;
2111
2112 *relptr = NULL;
2113
2114 return section->reloc_count * 3;
2115 }
2116
2117 static long
2118 mips_elf64_canonicalize_dynamic_reloc (abfd, storage, syms)
2119 bfd *abfd;
2120 arelent **storage;
2121 asymbol **syms;
2122 {
2123 bfd_boolean (*slurp_relocs)
2124 PARAMS ((bfd *, asection *, asymbol **, bfd_boolean));
2125 asection *s;
2126 long ret;
2127
2128 if (elf_dynsymtab (abfd) == 0)
2129 {
2130 bfd_set_error (bfd_error_invalid_operation);
2131 return -1;
2132 }
2133
2134 slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
2135 ret = 0;
2136 for (s = abfd->sections; s != NULL; s = s->next)
2137 {
2138 if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
2139 && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
2140 || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
2141 {
2142 arelent *p;
2143 long count, i;
2144
2145 if (! (*slurp_relocs) (abfd, s, syms, TRUE))
2146 return -1;
2147 count = s->_raw_size / elf_section_data (s)->this_hdr.sh_entsize * 3;
2148 p = s->relocation;
2149 for (i = 0; i < count; i++)
2150 *storage++ = p++;
2151 ret += count;
2152 }
2153 }
2154
2155 *storage = NULL;
2156
2157 return ret;
2158 }
2159
2160 /* Read the relocations from one reloc section. This is mostly copied
2161 from elfcode.h, except for the changes to expand one external
2162 relocation to 3 internal ones. We must unfortunately set
2163 reloc_count to the number of external relocations, because a lot of
2164 generic code seems to depend on this. */
2165
2166 static bfd_boolean
2167 mips_elf64_slurp_one_reloc_table (abfd, asect, rel_hdr, reloc_count,
2168 relents, symbols, dynamic)
2169 bfd *abfd;
2170 asection *asect;
2171 Elf_Internal_Shdr *rel_hdr;
2172 bfd_size_type reloc_count;
2173 arelent *relents;
2174 asymbol **symbols;
2175 bfd_boolean dynamic;
2176 {
2177 PTR allocated = NULL;
2178 bfd_byte *native_relocs;
2179 arelent *relent;
2180 bfd_vma i;
2181 int entsize;
2182 reloc_howto_type *howto_table;
2183
2184 allocated = (PTR) bfd_malloc (rel_hdr->sh_size);
2185 if (allocated == NULL)
2186 return FALSE;
2187
2188 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
2189 || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
2190 != rel_hdr->sh_size))
2191 goto error_return;
2192
2193 native_relocs = (bfd_byte *) allocated;
2194
2195 entsize = rel_hdr->sh_entsize;
2196 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
2197 || entsize == sizeof (Elf64_Mips_External_Rela));
2198
2199 if (entsize == sizeof (Elf64_Mips_External_Rel))
2200 howto_table = mips_elf64_howto_table_rel;
2201 else
2202 howto_table = mips_elf64_howto_table_rela;
2203
2204 for (i = 0, relent = relents;
2205 i < reloc_count;
2206 i++, native_relocs += entsize)
2207 {
2208 Elf64_Mips_Internal_Rela rela;
2209 bfd_boolean used_sym, used_ssym;
2210 int ir;
2211
2212 if (entsize == sizeof (Elf64_Mips_External_Rela))
2213 mips_elf64_swap_reloca_in (abfd,
2214 (Elf64_Mips_External_Rela *) native_relocs,
2215 &rela);
2216 else
2217 mips_elf64_swap_reloc_in (abfd,
2218 (Elf64_Mips_External_Rel *) native_relocs,
2219 &rela);
2220
2221 /* Each entry represents exactly three actual relocations. */
2222
2223 used_sym = FALSE;
2224 used_ssym = FALSE;
2225 for (ir = 0; ir < 3; ir++)
2226 {
2227 enum elf_mips_reloc_type type;
2228
2229 switch (ir)
2230 {
2231 default:
2232 abort ();
2233 case 0:
2234 type = (enum elf_mips_reloc_type) rela.r_type;
2235 break;
2236 case 1:
2237 type = (enum elf_mips_reloc_type) rela.r_type2;
2238 break;
2239 case 2:
2240 type = (enum elf_mips_reloc_type) rela.r_type3;
2241 break;
2242 }
2243
2244 /* Some types require symbols, whereas some do not. */
2245 switch (type)
2246 {
2247 case R_MIPS_NONE:
2248 case R_MIPS_LITERAL:
2249 case R_MIPS_INSERT_A:
2250 case R_MIPS_INSERT_B:
2251 case R_MIPS_DELETE:
2252 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2253 break;
2254
2255 default:
2256 if (! used_sym)
2257 {
2258 if (rela.r_sym == 0)
2259 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2260 else
2261 {
2262 asymbol **ps, *s;
2263
2264 ps = symbols + rela.r_sym - 1;
2265 s = *ps;
2266 if ((s->flags & BSF_SECTION_SYM) == 0)
2267 relent->sym_ptr_ptr = ps;
2268 else
2269 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
2270 }
2271
2272 used_sym = TRUE;
2273 }
2274 else if (! used_ssym)
2275 {
2276 switch (rela.r_ssym)
2277 {
2278 case RSS_UNDEF:
2279 relent->sym_ptr_ptr =
2280 bfd_abs_section_ptr->symbol_ptr_ptr;
2281 break;
2282
2283 case RSS_GP:
2284 case RSS_GP0:
2285 case RSS_LOC:
2286 /* FIXME: I think these need to be handled using
2287 special howto structures. */
2288 BFD_ASSERT (0);
2289 break;
2290
2291 default:
2292 BFD_ASSERT (0);
2293 break;
2294 }
2295
2296 used_ssym = TRUE;
2297 }
2298 else
2299 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2300
2301 break;
2302 }
2303
2304 /* The address of an ELF reloc is section relative for an
2305 object file, and absolute for an executable file or
2306 shared library. The address of a BFD reloc is always
2307 section relative. */
2308 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
2309 relent->address = rela.r_offset;
2310 else
2311 relent->address = rela.r_offset - asect->vma;
2312
2313 relent->addend = rela.r_addend;
2314
2315 relent->howto = &howto_table[(int) type];
2316
2317 ++relent;
2318 }
2319 }
2320
2321 asect->reloc_count += (relent - relents) / 3;
2322
2323 if (allocated != NULL)
2324 free (allocated);
2325
2326 return TRUE;
2327
2328 error_return:
2329 if (allocated != NULL)
2330 free (allocated);
2331 return FALSE;
2332 }
2333
2334 /* Read the relocations. On Irix 6, there can be two reloc sections
2335 associated with a single data section. This is copied from
2336 elfcode.h as well, with changes as small as accounting for 3
2337 internal relocs per external reloc and resetting reloc_count to
2338 zero before processing the relocs of a section. */
2339
2340 static bfd_boolean
2341 mips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic)
2342 bfd *abfd;
2343 asection *asect;
2344 asymbol **symbols;
2345 bfd_boolean dynamic;
2346 {
2347 struct bfd_elf_section_data * const d = elf_section_data (asect);
2348 Elf_Internal_Shdr *rel_hdr;
2349 Elf_Internal_Shdr *rel_hdr2;
2350 bfd_size_type reloc_count;
2351 bfd_size_type reloc_count2;
2352 arelent *relents;
2353 bfd_size_type amt;
2354
2355 if (asect->relocation != NULL)
2356 return TRUE;
2357
2358 if (! dynamic)
2359 {
2360 if ((asect->flags & SEC_RELOC) == 0
2361 || asect->reloc_count == 0)
2362 return TRUE;
2363
2364 rel_hdr = &d->rel_hdr;
2365 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2366 rel_hdr2 = d->rel_hdr2;
2367 reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
2368
2369 BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
2370 BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
2371 || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
2372
2373 }
2374 else
2375 {
2376 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
2377 case because relocations against this section may use the
2378 dynamic symbol table, and in that case bfd_section_from_shdr
2379 in elf.c does not update the RELOC_COUNT. */
2380 if (asect->_raw_size == 0)
2381 return TRUE;
2382
2383 rel_hdr = &d->this_hdr;
2384 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2385 rel_hdr2 = NULL;
2386 reloc_count2 = 0;
2387 }
2388
2389 /* Allocate space for 3 arelent structures for each Rel structure. */
2390 amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
2391 relents = (arelent *) bfd_alloc (abfd, amt);
2392 if (relents == NULL)
2393 return FALSE;
2394
2395 /* The slurp_one_reloc_table routine increments reloc_count. */
2396 asect->reloc_count = 0;
2397
2398 if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2399 rel_hdr, reloc_count,
2400 relents,
2401 symbols, dynamic))
2402 return FALSE;
2403 if (d->rel_hdr2 != NULL)
2404 {
2405 if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2406 rel_hdr2, reloc_count2,
2407 relents + reloc_count * 3,
2408 symbols, dynamic))
2409 return FALSE;
2410 }
2411
2412 asect->relocation = relents;
2413 return TRUE;
2414 }
2415
2416 /* Write out the relocations. */
2417
2418 static void
2419 mips_elf64_write_relocs (abfd, sec, data)
2420 bfd *abfd;
2421 asection *sec;
2422 PTR data;
2423 {
2424 bfd_boolean *failedp = (bfd_boolean *) data;
2425 int count;
2426 Elf_Internal_Shdr *rel_hdr;
2427 unsigned int idx;
2428
2429 /* If we have already failed, don't do anything. */
2430 if (*failedp)
2431 return;
2432
2433 if ((sec->flags & SEC_RELOC) == 0)
2434 return;
2435
2436 /* The linker backend writes the relocs out itself, and sets the
2437 reloc_count field to zero to inhibit writing them here. Also,
2438 sometimes the SEC_RELOC flag gets set even when there aren't any
2439 relocs. */
2440 if (sec->reloc_count == 0)
2441 return;
2442
2443 /* We can combine up to three relocs that refer to the same address
2444 if the latter relocs have no associated symbol. */
2445 count = 0;
2446 for (idx = 0; idx < sec->reloc_count; idx++)
2447 {
2448 bfd_vma addr;
2449 unsigned int i;
2450
2451 ++count;
2452
2453 addr = sec->orelocation[idx]->address;
2454 for (i = 0; i < 2; i++)
2455 {
2456 arelent *r;
2457
2458 if (idx + 1 >= sec->reloc_count)
2459 break;
2460 r = sec->orelocation[idx + 1];
2461 if (r->address != addr
2462 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2463 || (*r->sym_ptr_ptr)->value != 0)
2464 break;
2465
2466 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2467
2468 ++idx;
2469 }
2470 }
2471
2472 rel_hdr = &elf_section_data (sec)->rel_hdr;
2473
2474 /* Do the actual relocation. */
2475
2476 if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
2477 mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
2478 else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
2479 mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
2480 else
2481 BFD_ASSERT (0);
2482 }
2483
2484 static void
2485 mips_elf64_write_rel (abfd, sec, rel_hdr, count, data)
2486 bfd *abfd;
2487 asection *sec;
2488 Elf_Internal_Shdr *rel_hdr;
2489 int *count;
2490 PTR data;
2491 {
2492 bfd_boolean *failedp = (bfd_boolean *) data;
2493 Elf64_Mips_External_Rel *ext_rel;
2494 unsigned int idx;
2495 asymbol *last_sym = 0;
2496 int last_sym_idx = 0;
2497
2498 rel_hdr->sh_size = (bfd_vma)(rel_hdr->sh_entsize * *count);
2499 rel_hdr->contents = (PTR) bfd_alloc (abfd, rel_hdr->sh_size);
2500 if (rel_hdr->contents == NULL)
2501 {
2502 *failedp = TRUE;
2503 return;
2504 }
2505
2506 ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
2507 for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
2508 {
2509 arelent *ptr;
2510 Elf64_Mips_Internal_Rela int_rel;
2511 asymbol *sym;
2512 int n;
2513 unsigned int i;
2514
2515 ptr = sec->orelocation[idx];
2516
2517 /* The address of an ELF reloc is section relative for an object
2518 file, and absolute for an executable file or shared library.
2519 The address of a BFD reloc is always section relative. */
2520 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2521 int_rel.r_offset = ptr->address;
2522 else
2523 int_rel.r_offset = ptr->address + sec->vma;
2524
2525 sym = *ptr->sym_ptr_ptr;
2526 if (sym == last_sym)
2527 n = last_sym_idx;
2528 else
2529 {
2530 last_sym = sym;
2531 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2532 if (n < 0)
2533 {
2534 *failedp = TRUE;
2535 return;
2536 }
2537 last_sym_idx = n;
2538 }
2539
2540 int_rel.r_sym = n;
2541 int_rel.r_ssym = RSS_UNDEF;
2542
2543 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2544 && ! _bfd_elf_validate_reloc (abfd, ptr))
2545 {
2546 *failedp = TRUE;
2547 return;
2548 }
2549
2550 int_rel.r_type = ptr->howto->type;
2551 int_rel.r_type2 = (int) R_MIPS_NONE;
2552 int_rel.r_type3 = (int) R_MIPS_NONE;
2553
2554 for (i = 0; i < 2; i++)
2555 {
2556 arelent *r;
2557
2558 if (idx + 1 >= sec->reloc_count)
2559 break;
2560 r = sec->orelocation[idx + 1];
2561 if (r->address != ptr->address
2562 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2563 || (*r->sym_ptr_ptr)->value != 0)
2564 break;
2565
2566 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2567
2568 if (i == 0)
2569 int_rel.r_type2 = r->howto->type;
2570 else
2571 int_rel.r_type3 = r->howto->type;
2572
2573 ++idx;
2574 }
2575
2576 mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
2577 }
2578
2579 BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
2580 == *count);
2581 }
2582
2583 static void
2584 mips_elf64_write_rela (abfd, sec, rela_hdr, count, data)
2585 bfd *abfd;
2586 asection *sec;
2587 Elf_Internal_Shdr *rela_hdr;
2588 int *count;
2589 PTR data;
2590 {
2591 bfd_boolean *failedp = (bfd_boolean *) data;
2592 Elf64_Mips_External_Rela *ext_rela;
2593 unsigned int idx;
2594 asymbol *last_sym = 0;
2595 int last_sym_idx = 0;
2596
2597 rela_hdr->sh_size = (bfd_vma)(rela_hdr->sh_entsize * *count);
2598 rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
2599 if (rela_hdr->contents == NULL)
2600 {
2601 *failedp = TRUE;
2602 return;
2603 }
2604
2605 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
2606 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
2607 {
2608 arelent *ptr;
2609 Elf64_Mips_Internal_Rela int_rela;
2610 asymbol *sym;
2611 int n;
2612 unsigned int i;
2613
2614 ptr = sec->orelocation[idx];
2615
2616 /* The address of an ELF reloc is section relative for an object
2617 file, and absolute for an executable file or shared library.
2618 The address of a BFD reloc is always section relative. */
2619 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2620 int_rela.r_offset = ptr->address;
2621 else
2622 int_rela.r_offset = ptr->address + sec->vma;
2623
2624 sym = *ptr->sym_ptr_ptr;
2625 if (sym == last_sym)
2626 n = last_sym_idx;
2627 else
2628 {
2629 last_sym = sym;
2630 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2631 if (n < 0)
2632 {
2633 *failedp = TRUE;
2634 return;
2635 }
2636 last_sym_idx = n;
2637 }
2638
2639 int_rela.r_sym = n;
2640 int_rela.r_addend = ptr->addend;
2641 int_rela.r_ssym = RSS_UNDEF;
2642
2643 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2644 && ! _bfd_elf_validate_reloc (abfd, ptr))
2645 {
2646 *failedp = TRUE;
2647 return;
2648 }
2649
2650 int_rela.r_type = ptr->howto->type;
2651 int_rela.r_type2 = (int) R_MIPS_NONE;
2652 int_rela.r_type3 = (int) R_MIPS_NONE;
2653
2654 for (i = 0; i < 2; i++)
2655 {
2656 arelent *r;
2657
2658 if (idx + 1 >= sec->reloc_count)
2659 break;
2660 r = sec->orelocation[idx + 1];
2661 if (r->address != ptr->address
2662 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2663 || (*r->sym_ptr_ptr)->value != 0)
2664 break;
2665
2666 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2667
2668 if (i == 0)
2669 int_rela.r_type2 = r->howto->type;
2670 else
2671 int_rela.r_type3 = r->howto->type;
2672
2673 ++idx;
2674 }
2675
2676 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
2677 }
2678
2679 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
2680 == *count);
2681 }
2682 \f
2683 /* Set the right machine number for a MIPS ELF file. */
2684
2685 static bfd_boolean
2686 mips_elf64_object_p (abfd)
2687 bfd *abfd;
2688 {
2689 unsigned long mach;
2690
2691 /* Irix 6 is broken. Object file symbol tables are not always
2692 sorted correctly such that local symbols precede global symbols,
2693 and the sh_info field in the symbol table is not always right. */
2694 if (elf64_mips_irix_compat (abfd) != ict_none)
2695 elf_bad_symtab (abfd) = TRUE;
2696
2697 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
2698 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
2699 return TRUE;
2700 }
2701
2702 /* Depending on the target vector we generate some version of Irix
2703 executables or "normal" MIPS ELF ABI executables. */
2704 static irix_compat_t
2705 elf64_mips_irix_compat (abfd)
2706 bfd *abfd;
2707 {
2708 if ((abfd->xvec == &bfd_elf64_bigmips_vec)
2709 || (abfd->xvec == &bfd_elf64_littlemips_vec))
2710 return ict_irix6;
2711 else
2712 return ict_none;
2713 }
2714 \f
2715 /* Support for core dump NOTE sections. */
2716 static bfd_boolean
2717 elf64_mips_grok_prstatus (abfd, note)
2718 bfd *abfd;
2719 Elf_Internal_Note *note;
2720 {
2721 int offset;
2722 unsigned int raw_size;
2723
2724 switch (note->descsz)
2725 {
2726 default:
2727 return FALSE;
2728
2729 case 480: /* Linux/MIPS - N64 kernel */
2730 /* pr_cursig */
2731 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
2732
2733 /* pr_pid */
2734 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 32);
2735
2736 /* pr_reg */
2737 offset = 112;
2738 raw_size = 360;
2739
2740 break;
2741 }
2742
2743 /* Make a ".reg/999" section. */
2744 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
2745 raw_size, note->descpos + offset);
2746 }
2747
2748 static bfd_boolean
2749 elf64_mips_grok_psinfo (abfd, note)
2750 bfd *abfd;
2751 Elf_Internal_Note *note;
2752 {
2753 switch (note->descsz)
2754 {
2755 default:
2756 return FALSE;
2757
2758 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
2759 elf_tdata (abfd)->core_program
2760 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
2761 elf_tdata (abfd)->core_command
2762 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
2763 }
2764
2765 /* Note that for some reason, a spurious space is tacked
2766 onto the end of the args in some (at least one anyway)
2767 implementations, so strip it off if it exists. */
2768
2769 {
2770 char *command = elf_tdata (abfd)->core_command;
2771 int n = strlen (command);
2772
2773 if (0 < n && command[n - 1] == ' ')
2774 command[n - 1] = '\0';
2775 }
2776
2777 return TRUE;
2778 }
2779 \f
2780 /* ECOFF swapping routines. These are used when dealing with the
2781 .mdebug section, which is in the ECOFF debugging format. */
2782 static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
2783 {
2784 /* Symbol table magic number. */
2785 magicSym2,
2786 /* Alignment of debugging information. E.g., 4. */
2787 8,
2788 /* Sizes of external symbolic information. */
2789 sizeof (struct hdr_ext),
2790 sizeof (struct dnr_ext),
2791 sizeof (struct pdr_ext),
2792 sizeof (struct sym_ext),
2793 sizeof (struct opt_ext),
2794 sizeof (struct fdr_ext),
2795 sizeof (struct rfd_ext),
2796 sizeof (struct ext_ext),
2797 /* Functions to swap in external symbolic data. */
2798 ecoff_swap_hdr_in,
2799 ecoff_swap_dnr_in,
2800 ecoff_swap_pdr_in,
2801 ecoff_swap_sym_in,
2802 ecoff_swap_opt_in,
2803 ecoff_swap_fdr_in,
2804 ecoff_swap_rfd_in,
2805 ecoff_swap_ext_in,
2806 _bfd_ecoff_swap_tir_in,
2807 _bfd_ecoff_swap_rndx_in,
2808 /* Functions to swap out external symbolic data. */
2809 ecoff_swap_hdr_out,
2810 ecoff_swap_dnr_out,
2811 ecoff_swap_pdr_out,
2812 ecoff_swap_sym_out,
2813 ecoff_swap_opt_out,
2814 ecoff_swap_fdr_out,
2815 ecoff_swap_rfd_out,
2816 ecoff_swap_ext_out,
2817 _bfd_ecoff_swap_tir_out,
2818 _bfd_ecoff_swap_rndx_out,
2819 /* Function to read in symbolic data. */
2820 _bfd_mips_elf_read_ecoff_info
2821 };
2822 \f
2823 /* Relocations in the 64 bit MIPS ELF ABI are more complex than in
2824 standard ELF. This structure is used to redirect the relocation
2825 handling routines. */
2826
2827 const struct elf_size_info mips_elf64_size_info =
2828 {
2829 sizeof (Elf64_External_Ehdr),
2830 sizeof (Elf64_External_Phdr),
2831 sizeof (Elf64_External_Shdr),
2832 sizeof (Elf64_Mips_External_Rel),
2833 sizeof (Elf64_Mips_External_Rela),
2834 sizeof (Elf64_External_Sym),
2835 sizeof (Elf64_External_Dyn),
2836 sizeof (Elf_External_Note),
2837 4, /* hash-table entry size */
2838 3, /* internal relocations per external relocations */
2839 64, /* arch_size */
2840 3, /* log_file_align */
2841 ELFCLASS64,
2842 EV_CURRENT,
2843 bfd_elf64_write_out_phdrs,
2844 bfd_elf64_write_shdrs_and_ehdr,
2845 mips_elf64_write_relocs,
2846 bfd_elf64_swap_symbol_in,
2847 bfd_elf64_swap_symbol_out,
2848 mips_elf64_slurp_reloc_table,
2849 bfd_elf64_slurp_symbol_table,
2850 bfd_elf64_swap_dyn_in,
2851 bfd_elf64_swap_dyn_out,
2852 mips_elf64_be_swap_reloc_in,
2853 mips_elf64_be_swap_reloc_out,
2854 mips_elf64_be_swap_reloca_in,
2855 mips_elf64_be_swap_reloca_out
2856 };
2857
2858 #define ELF_ARCH bfd_arch_mips
2859 #define ELF_MACHINE_CODE EM_MIPS
2860
2861 /* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
2862 a value of 0x1000, and we are compatible.
2863 FIXME: How does this affect NewABI? */
2864 #define ELF_MAXPAGESIZE 0x1000
2865
2866 #define elf_backend_collect TRUE
2867 #define elf_backend_type_change_ok TRUE
2868 #define elf_backend_can_gc_sections TRUE
2869 #define elf_info_to_howto mips_elf64_info_to_howto_rela
2870 #define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
2871 #define elf_backend_object_p mips_elf64_object_p
2872 #define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
2873 #define elf_backend_section_processing _bfd_mips_elf_section_processing
2874 #define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
2875 #define elf_backend_fake_sections _bfd_mips_elf_fake_sections
2876 #define elf_backend_section_from_bfd_section \
2877 _bfd_mips_elf_section_from_bfd_section
2878 #define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
2879 #define elf_backend_link_output_symbol_hook \
2880 _bfd_mips_elf_link_output_symbol_hook
2881 #define elf_backend_create_dynamic_sections \
2882 _bfd_mips_elf_create_dynamic_sections
2883 #define elf_backend_check_relocs _bfd_mips_elf_check_relocs
2884 #define elf_backend_adjust_dynamic_symbol \
2885 _bfd_mips_elf_adjust_dynamic_symbol
2886 #define elf_backend_always_size_sections \
2887 _bfd_mips_elf_always_size_sections
2888 #define elf_backend_size_dynamic_sections \
2889 _bfd_mips_elf_size_dynamic_sections
2890 #define elf_backend_relocate_section _bfd_mips_elf_relocate_section
2891 #define elf_backend_finish_dynamic_symbol \
2892 _bfd_mips_elf_finish_dynamic_symbol
2893 #define elf_backend_finish_dynamic_sections \
2894 _bfd_mips_elf_finish_dynamic_sections
2895 #define elf_backend_final_write_processing \
2896 _bfd_mips_elf_final_write_processing
2897 #define elf_backend_additional_program_headers \
2898 _bfd_mips_elf_additional_program_headers
2899 #define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
2900 #define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
2901 #define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
2902 #define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
2903 #define elf_backend_ignore_discarded_relocs \
2904 _bfd_mips_elf_ignore_discarded_relocs
2905 #define elf_backend_mips_irix_compat elf64_mips_irix_compat
2906 #define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
2907 #define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
2908 #define elf_backend_size_info mips_elf64_size_info
2909
2910 #define elf_backend_grok_prstatus elf64_mips_grok_prstatus
2911 #define elf_backend_grok_psinfo elf64_mips_grok_psinfo
2912
2913 #define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
2914 #define elf_backend_plt_header_size 0
2915
2916 /* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
2917 work better/work only in RELA, so we default to this. */
2918 #define elf_backend_may_use_rel_p 1
2919 #define elf_backend_may_use_rela_p 1
2920 #define elf_backend_default_use_rela_p 1
2921
2922 #define elf_backend_write_section _bfd_mips_elf_write_section
2923
2924 /* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
2925 MIPS-specific function only applies to IRIX5, which had no 64-bit
2926 ABI. */
2927 #define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
2928 #define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
2929 #define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
2930 #define bfd_elf64_bfd_get_relocated_section_contents \
2931 _bfd_elf_mips_get_relocated_section_contents
2932 #define bfd_elf64_bfd_link_hash_table_create \
2933 _bfd_mips_elf_link_hash_table_create
2934 #define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
2935 #define bfd_elf64_bfd_merge_private_bfd_data \
2936 _bfd_mips_elf_merge_private_bfd_data
2937 #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
2938 #define bfd_elf64_bfd_print_private_bfd_data \
2939 _bfd_mips_elf_print_private_bfd_data
2940
2941 #define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
2942 #define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
2943 #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
2944 #define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
2945 #define bfd_elf64_bfd_relax_section _bfd_mips_relax_section
2946
2947 /* MIPS ELF64 archive functions. */
2948 #define bfd_elf64_archive_functions
2949 extern bfd_boolean bfd_elf64_archive_slurp_armap
2950 PARAMS ((bfd *));
2951 extern bfd_boolean bfd_elf64_archive_write_armap
2952 PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
2953 #define bfd_elf64_archive_slurp_extended_name_table \
2954 _bfd_archive_coff_slurp_extended_name_table
2955 #define bfd_elf64_archive_construct_extended_name_table \
2956 _bfd_archive_coff_construct_extended_name_table
2957 #define bfd_elf64_archive_truncate_arname \
2958 _bfd_archive_coff_truncate_arname
2959 #define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
2960 #define bfd_elf64_archive_openr_next_archived_file \
2961 _bfd_archive_coff_openr_next_archived_file
2962 #define bfd_elf64_archive_get_elt_at_index \
2963 _bfd_archive_coff_get_elt_at_index
2964 #define bfd_elf64_archive_generic_stat_arch_elt \
2965 _bfd_archive_coff_generic_stat_arch_elt
2966 #define bfd_elf64_archive_update_armap_timestamp \
2967 _bfd_archive_coff_update_armap_timestamp
2968
2969 /* The SGI style (n)64 NewABI. */
2970 #define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
2971 #define TARGET_LITTLE_NAME "elf64-littlemips"
2972 #define TARGET_BIG_SYM bfd_elf64_bigmips_vec
2973 #define TARGET_BIG_NAME "elf64-bigmips"
2974
2975 #include "elf64-target.h"
2976
2977 #define INCLUDED_TARGET_FILE /* More a type of flag. */
2978
2979 /* The SYSV-style 'traditional' (n)64 NewABI. */
2980 #undef TARGET_LITTLE_SYM
2981 #undef TARGET_LITTLE_NAME
2982 #undef TARGET_BIG_SYM
2983 #undef TARGET_BIG_NAME
2984
2985 #define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
2986 #define TARGET_LITTLE_NAME "elf64-tradlittlemips"
2987 #define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
2988 #define TARGET_BIG_NAME "elf64-tradbigmips"
2989
2990 /* Include the target file again for this target. */
2991 #include "elf64-target.h"