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