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