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