* elfxx-ia64.c (elfNN_ia64_add_symbol_hook): Warning fix.
[deliverable/binutils-gdb.git] / bfd / elf64-mips.c
CommitLineData
252b5132 1/* MIPS-specific support for 64-bit ELF
157090f7
AM
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 2007 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),
1331 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
741d6ea8
JM
1332
1333 HOWTO (R_MIPS_TLS_DTPREL64, /* type */
1334 0, /* rightshift */
1335 4, /* size (0 = byte, 1 = short, 2 = long) */
1336 64, /* bitsize */
1337 FALSE, /* pc_relative */
1338 0, /* bitpos */
1339 complain_overflow_dont, /* complain_on_overflow */
1340 _bfd_mips_elf_generic_reloc, /* special_function */
1341 "R_MIPS_TLS_DTPREL64", /* name */
1342 TRUE, /* partial_inplace */
1343 MINUS_ONE, /* src_mask */
1344 MINUS_ONE, /* dst_mask */
1345 FALSE), /* pcrel_offset */
0f20cc35
DJ
1346
1347 /* TLS general dynamic variable reference. */
1348 HOWTO (R_MIPS_TLS_GD, /* type */
1349 0, /* rightshift */
1350 2, /* size (0 = byte, 1 = short, 2 = long) */
1351 16, /* bitsize */
1352 FALSE, /* pc_relative */
1353 0, /* bitpos */
1354 complain_overflow_signed, /* complain_on_overflow */
1355 _bfd_mips_elf_generic_reloc, /* special_function */
1356 "R_MIPS_TLS_GD", /* name */
1357 TRUE, /* partial_inplace */
1358 0x0000ffff, /* src_mask */
1359 0x0000ffff, /* dst_mask */
1360 FALSE), /* pcrel_offset */
1361
1362 /* TLS local dynamic variable reference. */
1363 HOWTO (R_MIPS_TLS_LDM, /* type */
1364 0, /* rightshift */
1365 2, /* size (0 = byte, 1 = short, 2 = long) */
1366 16, /* bitsize */
1367 FALSE, /* pc_relative */
1368 0, /* bitpos */
1369 complain_overflow_signed, /* complain_on_overflow */
1370 _bfd_mips_elf_generic_reloc, /* special_function */
1371 "R_MIPS_TLS_LDM", /* name */
1372 TRUE, /* partial_inplace */
1373 0x0000ffff, /* src_mask */
1374 0x0000ffff, /* dst_mask */
1375 FALSE), /* pcrel_offset */
1376
1377 /* TLS local dynamic offset. */
1378 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
1379 0, /* rightshift */
1380 2, /* size (0 = byte, 1 = short, 2 = long) */
1381 16, /* bitsize */
1382 FALSE, /* pc_relative */
1383 0, /* bitpos */
1384 complain_overflow_signed, /* complain_on_overflow */
1385 _bfd_mips_elf_generic_reloc, /* special_function */
1386 "R_MIPS_TLS_DTPREL_HI16", /* name */
1387 TRUE, /* partial_inplace */
1388 0x0000ffff, /* src_mask */
1389 0x0000ffff, /* dst_mask */
1390 FALSE), /* pcrel_offset */
1391
1392 /* TLS local dynamic offset. */
1393 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
1394 0, /* rightshift */
1395 2, /* size (0 = byte, 1 = short, 2 = long) */
1396 16, /* bitsize */
1397 FALSE, /* pc_relative */
1398 0, /* bitpos */
1399 complain_overflow_signed, /* complain_on_overflow */
1400 _bfd_mips_elf_generic_reloc, /* special_function */
1401 "R_MIPS_TLS_DTPREL_LO16", /* name */
1402 TRUE, /* partial_inplace */
1403 0x0000ffff, /* src_mask */
1404 0x0000ffff, /* dst_mask */
1405 FALSE), /* pcrel_offset */
1406
1407 /* TLS thread pointer offset. */
1408 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
1409 0, /* rightshift */
1410 2, /* size (0 = byte, 1 = short, 2 = long) */
1411 16, /* bitsize */
1412 FALSE, /* pc_relative */
1413 0, /* bitpos */
1414 complain_overflow_signed, /* complain_on_overflow */
1415 _bfd_mips_elf_generic_reloc, /* special_function */
1416 "R_MIPS_TLS_GOTTPREL", /* name */
1417 TRUE, /* partial_inplace */
1418 0x0000ffff, /* src_mask */
1419 0x0000ffff, /* dst_mask */
1420 FALSE), /* pcrel_offset */
1421
1422 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
1423 EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
1424
1425 /* TLS thread pointer offset. */
1426 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
1427 0, /* rightshift */
1428 2, /* size (0 = byte, 1 = short, 2 = long) */
1429 16, /* bitsize */
1430 FALSE, /* pc_relative */
1431 0, /* bitpos */
1432 complain_overflow_signed, /* complain_on_overflow */
1433 _bfd_mips_elf_generic_reloc, /* special_function */
1434 "R_MIPS_TLS_TPREL_HI16", /* name */
1435 TRUE, /* partial_inplace */
1436 0x0000ffff, /* src_mask */
1437 0x0000ffff, /* dst_mask */
1438 FALSE), /* pcrel_offset */
1439
1440 /* TLS thread pointer offset. */
1441 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
1442 0, /* rightshift */
1443 2, /* size (0 = byte, 1 = short, 2 = long) */
1444 16, /* bitsize */
1445 FALSE, /* pc_relative */
1446 0, /* bitpos */
1447 complain_overflow_signed, /* complain_on_overflow */
1448 _bfd_mips_elf_generic_reloc, /* special_function */
1449 "R_MIPS_TLS_TPREL_LO16", /* name */
1450 TRUE, /* partial_inplace */
1451 0x0000ffff, /* src_mask */
1452 0x0000ffff, /* dst_mask */
1453 FALSE), /* pcrel_offset */
165b93e7
RS
1454
1455 /* 32 bit relocation with no addend. */
1456 HOWTO (R_MIPS_GLOB_DAT, /* type */
1457 0, /* rightshift */
1458 2, /* size (0 = byte, 1 = short, 2 = long) */
1459 32, /* bitsize */
1460 FALSE, /* pc_relative */
1461 0, /* bitpos */
1462 complain_overflow_dont, /* complain_on_overflow */
1463 _bfd_mips_elf_generic_reloc, /* special_function */
1464 "R_MIPS_GLOB_DAT", /* name */
1465 FALSE, /* partial_inplace */
1466 0x0, /* src_mask */
1467 0xffffffff, /* dst_mask */
1468 FALSE), /* pcrel_offset */
252b5132 1469};
a4382ec6 1470
d6f16593
MR
1471static reloc_howto_type mips16_elf64_howto_table_rel[] =
1472{
1473 /* The reloc used for the mips16 jump instruction. */
a4382ec6
TS
1474 HOWTO (R_MIPS16_26, /* type */
1475 2, /* rightshift */
1476 2, /* size (0 = byte, 1 = short, 2 = long) */
1477 26, /* bitsize */
b34976b6 1478 FALSE, /* pc_relative */
a4382ec6
TS
1479 0, /* bitpos */
1480 complain_overflow_dont, /* complain_on_overflow */
1481 /* This needs complex overflow
1482 detection, because the upper four
1483 bits must match the PC. */
35d3d567 1484 _bfd_mips_elf_generic_reloc, /* special_function */
a4382ec6 1485 "R_MIPS16_26", /* name */
b34976b6 1486 TRUE, /* partial_inplace */
a4382ec6
TS
1487 0x3ffffff, /* src_mask */
1488 0x3ffffff, /* dst_mask */
d6f16593 1489 FALSE), /* pcrel_offset */
a4382ec6 1490
d6f16593 1491 /* The reloc used for the mips16 gprel instruction. */
a4382ec6
TS
1492 HOWTO (R_MIPS16_GPREL, /* type */
1493 0, /* rightshift */
1494 2, /* size (0 = byte, 1 = short, 2 = long) */
1495 16, /* bitsize */
b34976b6 1496 FALSE, /* pc_relative */
a4382ec6
TS
1497 0, /* bitpos */
1498 complain_overflow_signed, /* complain_on_overflow */
1499 mips16_gprel_reloc, /* special_function */
1500 "R_MIPS16_GPREL", /* name */
b34976b6 1501 TRUE, /* partial_inplace */
d6f16593
MR
1502 0x0000ffff, /* src_mask */
1503 0x0000ffff, /* dst_mask */
1504 FALSE), /* pcrel_offset */
1505
1506 /* A placeholder for MIPS16 reference to global offset table. */
1507 EMPTY_HOWTO (R_MIPS16_GOT16),
1508
1509 /* A placeholder for MIPS16 16 bit call through global offset table. */
1510 EMPTY_HOWTO (R_MIPS16_CALL16),
1511
1512 /* MIPS16 high 16 bits of symbol value. */
1513 HOWTO (R_MIPS16_HI16, /* type */
1514 16, /* rightshift */
1515 2, /* size (0 = byte, 1 = short, 2 = long) */
1516 16, /* bitsize */
1517 FALSE, /* pc_relative */
1518 0, /* bitpos */
1519 complain_overflow_dont, /* complain_on_overflow */
1520 _bfd_mips_elf_hi16_reloc, /* special_function */
1521 "R_MIPS16_HI16", /* name */
1522 TRUE, /* partial_inplace */
1523 0x0000ffff, /* src_mask */
1524 0x0000ffff, /* dst_mask */
1525 FALSE), /* pcrel_offset */
1526
1527 /* MIPS16 low 16 bits of symbol value. */
1528 HOWTO (R_MIPS16_LO16, /* type */
1529 0, /* rightshift */
1530 2, /* size (0 = byte, 1 = short, 2 = long) */
1531 16, /* bitsize */
1532 FALSE, /* pc_relative */
1533 0, /* bitpos */
1534 complain_overflow_dont, /* complain_on_overflow */
1535 _bfd_mips_elf_lo16_reloc, /* special_function */
1536 "R_MIPS16_LO16", /* name */
1537 TRUE, /* partial_inplace */
1538 0x0000ffff, /* src_mask */
1539 0x0000ffff, /* dst_mask */
1540 FALSE), /* pcrel_offset */
1541};
1542
1543static reloc_howto_type mips16_elf64_howto_table_rela[] =
1544{
1545 /* The reloc used for the mips16 jump instruction. */
1546 HOWTO (R_MIPS16_26, /* type */
1547 2, /* rightshift */
1548 2, /* size (0 = byte, 1 = short, 2 = long) */
1549 26, /* bitsize */
1550 FALSE, /* pc_relative */
1551 0, /* bitpos */
1552 complain_overflow_dont, /* complain_on_overflow */
1553 /* This needs complex overflow
1554 detection, because the upper four
1555 bits must match the PC. */
35d3d567 1556 _bfd_mips_elf_generic_reloc, /* special_function */
d6f16593
MR
1557 "R_MIPS16_26", /* name */
1558 FALSE, /* partial_inplace */
1559 0x3ffffff, /* src_mask */
1560 0x3ffffff, /* dst_mask */
1561 FALSE), /* pcrel_offset */
1562
1563 /* The reloc used for the mips16 gprel instruction. */
1564 HOWTO (R_MIPS16_GPREL, /* type */
1565 0, /* rightshift */
1566 2, /* size (0 = byte, 1 = short, 2 = long) */
1567 16, /* bitsize */
1568 FALSE, /* pc_relative */
1569 0, /* bitpos */
1570 complain_overflow_signed, /* complain_on_overflow */
1571 mips16_gprel_reloc, /* special_function */
1572 "R_MIPS16_GPREL", /* name */
1573 FALSE, /* partial_inplace */
1574 0x0000ffff, /* src_mask */
1575 0x0000ffff, /* dst_mask */
1576 FALSE), /* pcrel_offset */
1577
1578 /* A placeholder for MIPS16 reference to global offset table. */
1579 EMPTY_HOWTO (R_MIPS16_GOT16),
1580
1581 /* A placeholder for MIPS16 16 bit call through global offset table. */
1582 EMPTY_HOWTO (R_MIPS16_CALL16),
1583
1584 /* MIPS16 high 16 bits of symbol value. */
1585 HOWTO (R_MIPS16_HI16, /* type */
1586 16, /* rightshift */
1587 2, /* size (0 = byte, 1 = short, 2 = long) */
1588 16, /* bitsize */
1589 FALSE, /* pc_relative */
1590 0, /* bitpos */
1591 complain_overflow_dont, /* complain_on_overflow */
1592 _bfd_mips_elf_hi16_reloc, /* special_function */
1593 "R_MIPS16_HI16", /* name */
1594 FALSE, /* partial_inplace */
1595 0x0000ffff, /* src_mask */
1596 0x0000ffff, /* dst_mask */
1597 FALSE), /* pcrel_offset */
1598
1599 /* MIPS16 low 16 bits of symbol value. */
1600 HOWTO (R_MIPS16_LO16, /* type */
1601 0, /* rightshift */
1602 2, /* size (0 = byte, 1 = short, 2 = long) */
1603 16, /* bitsize */
1604 FALSE, /* pc_relative */
1605 0, /* bitpos */
1606 complain_overflow_dont, /* complain_on_overflow */
1607 _bfd_mips_elf_lo16_reloc, /* special_function */
1608 "R_MIPS16_LO16", /* name */
1609 FALSE, /* partial_inplace */
1610 0x0000ffff, /* src_mask */
1611 0x0000ffff, /* dst_mask */
1612 FALSE), /* pcrel_offset */
1613};
a4382ec6
TS
1614
1615/* GNU extension to record C++ vtable hierarchy */
1616static reloc_howto_type elf_mips_gnu_vtinherit_howto =
1617 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
1618 0, /* rightshift */
1619 2, /* size (0 = byte, 1 = short, 2 = long) */
1620 0, /* bitsize */
b34976b6 1621 FALSE, /* pc_relative */
a4382ec6
TS
1622 0, /* bitpos */
1623 complain_overflow_dont, /* complain_on_overflow */
1624 NULL, /* special_function */
1625 "R_MIPS_GNU_VTINHERIT", /* name */
b34976b6 1626 FALSE, /* partial_inplace */
a4382ec6
TS
1627 0, /* src_mask */
1628 0, /* dst_mask */
b34976b6 1629 FALSE); /* pcrel_offset */
a4382ec6
TS
1630
1631/* GNU extension to record C++ vtable member usage */
1632static reloc_howto_type elf_mips_gnu_vtentry_howto =
1633 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
1634 0, /* rightshift */
1635 2, /* size (0 = byte, 1 = short, 2 = long) */
1636 0, /* bitsize */
b34976b6 1637 FALSE, /* pc_relative */
a4382ec6
TS
1638 0, /* bitpos */
1639 complain_overflow_dont, /* complain_on_overflow */
1640 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1641 "R_MIPS_GNU_VTENTRY", /* name */
b34976b6 1642 FALSE, /* partial_inplace */
a4382ec6
TS
1643 0, /* src_mask */
1644 0, /* dst_mask */
b34976b6 1645 FALSE); /* pcrel_offset */
c6e90b02 1646\f
d0c728db
TS
1647/* 16 bit offset for pc-relative branches. */
1648static reloc_howto_type elf_mips_gnu_rel16_s2 =
1649 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
1650 2, /* rightshift */
1651 2, /* size (0 = byte, 1 = short, 2 = long) */
1652 16, /* bitsize */
1653 TRUE, /* pc_relative */
1654 0, /* bitpos */
1655 complain_overflow_signed, /* complain_on_overflow */
30ac9238 1656 _bfd_mips_elf_generic_reloc, /* special_function */
d0c728db
TS
1657 "R_MIPS_GNU_REL16_S2", /* name */
1658 TRUE, /* partial_inplace */
1659 0x0000ffff, /* src_mask */
1660 0x0000ffff, /* dst_mask */
1661 TRUE); /* pcrel_offset */
1662
1663/* 16 bit offset for pc-relative branches. */
1664static reloc_howto_type elf_mips_gnu_rela16_s2 =
1665 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
1666 2, /* rightshift */
1667 2, /* size (0 = byte, 1 = short, 2 = long) */
1668 16, /* bitsize */
1669 TRUE, /* pc_relative */
1670 0, /* bitpos */
1671 complain_overflow_signed, /* complain_on_overflow */
30ac9238 1672 _bfd_mips_elf_generic_reloc, /* special_function */
d0c728db
TS
1673 "R_MIPS_GNU_REL16_S2", /* name */
1674 FALSE, /* partial_inplace */
1675 0, /* src_mask */
1676 0x0000ffff, /* dst_mask */
1677 TRUE); /* pcrel_offset */
1678\f
252b5132
RH
1679/* Swap in a MIPS 64-bit Rel reloc. */
1680
1681static void
11a2be4d
RS
1682mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src,
1683 Elf64_Mips_Internal_Rela *dst)
252b5132 1684{
dc810e39
AM
1685 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1686 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1687 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1688 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1689 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1690 dst->r_type = H_GET_8 (abfd, src->r_type);
947216bf 1691 dst->r_addend = 0;
252b5132
RH
1692}
1693
1694/* Swap in a MIPS 64-bit Rela reloc. */
1695
1696static void
11a2be4d
RS
1697mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src,
1698 Elf64_Mips_Internal_Rela *dst)
252b5132 1699{
dc810e39
AM
1700 dst->r_offset = H_GET_64 (abfd, src->r_offset);
1701 dst->r_sym = H_GET_32 (abfd, src->r_sym);
1702 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1703 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1704 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1705 dst->r_type = H_GET_8 (abfd, src->r_type);
1706 dst->r_addend = H_GET_S64 (abfd, src->r_addend);
252b5132
RH
1707}
1708
252b5132
RH
1709/* Swap out a MIPS 64-bit Rel reloc. */
1710
1711static void
11a2be4d
RS
1712mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1713 Elf64_Mips_External_Rel *dst)
252b5132 1714{
dc810e39
AM
1715 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1716 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1717 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1718 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1719 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1720 H_PUT_8 (abfd, src->r_type, dst->r_type);
252b5132
RH
1721}
1722
252b5132
RH
1723/* Swap out a MIPS 64-bit Rela reloc. */
1724
1725static void
11a2be4d
RS
1726mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1727 Elf64_Mips_External_Rela *dst)
252b5132 1728{
dc810e39
AM
1729 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1730 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1731 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1732 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1733 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1734 H_PUT_8 (abfd, src->r_type, dst->r_type);
5b6a02bc 1735 H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
252b5132
RH
1736}
1737
c7ac6ff8
MM
1738/* Swap in a MIPS 64-bit Rel reloc. */
1739
1740static void
11a2be4d
RS
1741mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src,
1742 Elf_Internal_Rela *dst)
c7ac6ff8 1743{
947216bf 1744 Elf64_Mips_Internal_Rela mirel;
c7ac6ff8 1745
fe8bc63d 1746 mips_elf64_swap_reloc_in (abfd,
c7ac6ff8
MM
1747 (const Elf64_Mips_External_Rel *) src,
1748 &mirel);
1749
1750 dst[0].r_offset = mirel.r_offset;
5b6a02bc 1751 dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
947216bf 1752 dst[0].r_addend = 0;
c7ac6ff8 1753 dst[1].r_offset = mirel.r_offset;
5b6a02bc 1754 dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
947216bf 1755 dst[1].r_addend = 0;
c7ac6ff8 1756 dst[2].r_offset = mirel.r_offset;
5b6a02bc 1757 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
947216bf 1758 dst[2].r_addend = 0;
c7ac6ff8
MM
1759}
1760
1761/* Swap in a MIPS 64-bit Rela reloc. */
1762
1763static void
11a2be4d
RS
1764mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src,
1765 Elf_Internal_Rela *dst)
c7ac6ff8
MM
1766{
1767 Elf64_Mips_Internal_Rela mirela;
1768
fe8bc63d 1769 mips_elf64_swap_reloca_in (abfd,
c7ac6ff8
MM
1770 (const Elf64_Mips_External_Rela *) src,
1771 &mirela);
1772
1773 dst[0].r_offset = mirela.r_offset;
5b6a02bc 1774 dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
c7ac6ff8
MM
1775 dst[0].r_addend = mirela.r_addend;
1776 dst[1].r_offset = mirela.r_offset;
5b6a02bc 1777 dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
c7ac6ff8
MM
1778 dst[1].r_addend = 0;
1779 dst[2].r_offset = mirela.r_offset;
5b6a02bc 1780 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
c7ac6ff8
MM
1781 dst[2].r_addend = 0;
1782}
1783
1784/* Swap out a MIPS 64-bit Rel reloc. */
1785
1786static void
11a2be4d
RS
1787mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src,
1788 bfd_byte *dst)
c7ac6ff8 1789{
947216bf 1790 Elf64_Mips_Internal_Rela mirel;
c7ac6ff8 1791
5b6a02bc
TS
1792 mirel.r_offset = src[0].r_offset;
1793 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
5b6a02bc
TS
1794
1795 mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1796 mirel.r_sym = ELF64_R_SYM (src[0].r_info);
a902ee94 1797 mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
5b6a02bc 1798 mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
a902ee94 1799 mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
c7ac6ff8 1800
fe8bc63d 1801 mips_elf64_swap_reloc_out (abfd, &mirel,
c7ac6ff8
MM
1802 (Elf64_Mips_External_Rel *) dst);
1803}
1804
1805/* Swap out a MIPS 64-bit Rela reloc. */
1806
1807static void
11a2be4d
RS
1808mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
1809 bfd_byte *dst)
c7ac6ff8
MM
1810{
1811 Elf64_Mips_Internal_Rela mirela;
1812
5b6a02bc
TS
1813 mirela.r_offset = src[0].r_offset;
1814 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1815 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
1816
1817 mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1818 mirela.r_sym = ELF64_R_SYM (src[0].r_info);
1819 mirela.r_addend = src[0].r_addend;
1820 BFD_ASSERT(src[1].r_addend == 0);
1821 BFD_ASSERT(src[2].r_addend == 0);
1822
47293a4c 1823 mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
5b6a02bc 1824 mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
47293a4c 1825 mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
c7ac6ff8 1826
fe8bc63d 1827 mips_elf64_swap_reloca_out (abfd, &mirela,
c7ac6ff8
MM
1828 (Elf64_Mips_External_Rela *) dst);
1829}
c6e90b02 1830\f
b34976b6 1831/* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
5b6a02bc 1832 dangerous relocation. */
252b5132 1833
b34976b6 1834static bfd_boolean
11a2be4d 1835mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp)
252b5132 1836{
252b5132 1837 unsigned int count;
5b6a02bc 1838 asymbol **sym;
252b5132 1839 unsigned int i;
252b5132 1840
5b6a02bc
TS
1841 /* If we've already figured out what GP will be, just return it. */
1842 *pgp = _bfd_get_gp_value (output_bfd);
1843 if (*pgp)
b34976b6 1844 return TRUE;
252b5132 1845
5b6a02bc
TS
1846 count = bfd_get_symcount (output_bfd);
1847 sym = bfd_get_outsymbols (output_bfd);
252b5132 1848
5b6a02bc
TS
1849 /* The linker script will have created a symbol named `_gp' with the
1850 appropriate value. */
11a2be4d 1851 if (sym == NULL)
5b6a02bc
TS
1852 i = count;
1853 else
1854 {
1855 for (i = 0; i < count; i++, sym++)
1856 {
3f9c735e 1857 register const char *name;
252b5132 1858
5b6a02bc
TS
1859 name = bfd_asymbol_name (*sym);
1860 if (*name == '_' && strcmp (name, "_gp") == 0)
1861 {
1862 *pgp = bfd_asymbol_value (*sym);
1863 _bfd_set_gp_value (output_bfd, *pgp);
1864 break;
1865 }
1866 }
1867 }
252b5132 1868
5b6a02bc
TS
1869 if (i >= count)
1870 {
1871 /* Only get the error once. */
1872 *pgp = 4;
1873 _bfd_set_gp_value (output_bfd, *pgp);
b34976b6 1874 return FALSE;
5b6a02bc 1875 }
252b5132 1876
b34976b6 1877 return TRUE;
5b6a02bc 1878}
252b5132 1879
5b6a02bc
TS
1880/* We have to figure out the gp value, so that we can adjust the
1881 symbol value correctly. We look up the symbol _gp in the output
1882 BFD. If we can't find it, we're stuck. We cache it in the ELF
1883 target data. We don't need to adjust the symbol value for an
1049f94e 1884 external symbol if we are producing relocatable output. */
5b6a02bc
TS
1885
1886static bfd_reloc_status_type
11a2be4d
RS
1887mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
1888 char **error_message, bfd_vma *pgp)
5b6a02bc
TS
1889{
1890 if (bfd_is_und_section (symbol->section)
1049f94e 1891 && ! relocatable)
252b5132 1892 {
5b6a02bc
TS
1893 *pgp = 0;
1894 return bfd_reloc_undefined;
1895 }
252b5132 1896
5b6a02bc
TS
1897 *pgp = _bfd_get_gp_value (output_bfd);
1898 if (*pgp == 0
1049f94e 1899 && (! relocatable
5b6a02bc
TS
1900 || (symbol->flags & BSF_SECTION_SYM) != 0))
1901 {
1049f94e 1902 if (relocatable)
252b5132 1903 {
5b6a02bc 1904 /* Make up a value. */
a902ee94 1905 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
5b6a02bc
TS
1906 _bfd_set_gp_value (output_bfd, *pgp);
1907 }
1908 else if (!mips_elf64_assign_gp (output_bfd, pgp))
1909 {
1910 *error_message =
1911 (char *) _("GP relative relocation when _gp not defined");
1912 return bfd_reloc_dangerous;
252b5132 1913 }
5b6a02bc 1914 }
252b5132 1915
5b6a02bc
TS
1916 return bfd_reloc_ok;
1917}
252b5132 1918
5b6a02bc
TS
1919/* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1920 become the offset from the gp register. */
252b5132 1921
a4382ec6 1922static bfd_reloc_status_type
11a2be4d
RS
1923mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1924 void *data, asection *input_section, bfd *output_bfd,
1925 char **error_message)
5b6a02bc 1926{
1049f94e 1927 bfd_boolean relocatable;
5b6a02bc
TS
1928 bfd_reloc_status_type ret;
1929 bfd_vma gp;
1930
a7ebbfdf
TS
1931 /* If we're relocating, and this is an external symbol, we don't want
1932 to change anything. */
11a2be4d 1933 if (output_bfd != NULL
5b6a02bc 1934 && (symbol->flags & BSF_SECTION_SYM) == 0
a7ebbfdf 1935 && (symbol->flags & BSF_LOCAL) != 0)
5b6a02bc
TS
1936 {
1937 reloc_entry->address += input_section->output_offset;
1938 return bfd_reloc_ok;
1939 }
1940
11a2be4d 1941 if (output_bfd != NULL)
1049f94e 1942 relocatable = TRUE;
5b6a02bc
TS
1943 else
1944 {
1049f94e 1945 relocatable = FALSE;
5b6a02bc
TS
1946 output_bfd = symbol->section->output_section->owner;
1947 }
1948
1049f94e 1949 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
5b6a02bc
TS
1950 &gp);
1951 if (ret != bfd_reloc_ok)
1952 return ret;
1953
c6e90b02 1954 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1049f94e 1955 input_section, relocatable,
c6e90b02 1956 data, gp);
5b6a02bc
TS
1957}
1958
a4382ec6 1959/* Do a R_MIPS_LITERAL relocation. */
5b6a02bc 1960
a4382ec6 1961static bfd_reloc_status_type
11a2be4d
RS
1962mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1963 void *data, asection *input_section, bfd *output_bfd,
1964 char **error_message)
5b6a02bc 1965{
1049f94e 1966 bfd_boolean relocatable;
a4382ec6 1967 bfd_reloc_status_type ret;
5b6a02bc
TS
1968 bfd_vma gp;
1969
254f0426 1970 /* R_MIPS_LITERAL relocations are defined for local symbols only. */
11a2be4d 1971 if (output_bfd != NULL
5b6a02bc 1972 && (symbol->flags & BSF_SECTION_SYM) == 0
a7ebbfdf 1973 && (symbol->flags & BSF_LOCAL) != 0)
5b6a02bc 1974 {
254f0426
MR
1975 *error_message = (char *)
1976 _("literal relocation occurs for an external symbol");
1977 return bfd_reloc_outofrange;
5b6a02bc
TS
1978 }
1979
a4382ec6 1980 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
11a2be4d 1981 if (output_bfd != NULL)
1049f94e 1982 relocatable = TRUE;
5b6a02bc
TS
1983 else
1984 {
1049f94e 1985 relocatable = FALSE;
5b6a02bc
TS
1986 output_bfd = symbol->section->output_section->owner;
1987 }
1988
1049f94e 1989 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
a4382ec6
TS
1990 &gp);
1991 if (ret != bfd_reloc_ok)
1992 return ret;
5b6a02bc 1993
a4382ec6 1994 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1049f94e 1995 input_section, relocatable,
a4382ec6 1996 data, gp);
5b6a02bc
TS
1997}
1998
a4382ec6
TS
1999/* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
2000 become the offset from the gp register. */
5b6a02bc 2001
a4382ec6 2002static bfd_reloc_status_type
11a2be4d
RS
2003mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2004 void *data, asection *input_section, bfd *output_bfd,
2005 char **error_message)
5b6a02bc 2006{
1049f94e 2007 bfd_boolean relocatable;
5b6a02bc
TS
2008 bfd_reloc_status_type ret;
2009 bfd_vma gp;
2010 bfd_vma relocation;
a7ebbfdf 2011 bfd_vma val;
5b6a02bc 2012
765f2ef6 2013 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
11a2be4d 2014 if (output_bfd != NULL
5b6a02bc 2015 && (symbol->flags & BSF_SECTION_SYM) == 0
a7ebbfdf 2016 && (symbol->flags & BSF_LOCAL) != 0)
5b6a02bc
TS
2017 {
2018 *error_message = (char *)
2019 _("32bits gp relative relocation occurs for an external symbol");
2020 return bfd_reloc_outofrange;
2021 }
2022
11a2be4d 2023 if (output_bfd != NULL)
1049f94e 2024 relocatable = TRUE;
5b6a02bc
TS
2025 else
2026 {
1049f94e 2027 relocatable = FALSE;
5b6a02bc 2028 output_bfd = symbol->section->output_section->owner;
5b6a02bc
TS
2029 }
2030
99277196
MR
2031 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
2032 error_message, &gp);
2033 if (ret != bfd_reloc_ok)
2034 return ret;
a7ebbfdf 2035
5b6a02bc
TS
2036 if (bfd_is_com_section (symbol->section))
2037 relocation = 0;
2038 else
2039 relocation = symbol->value;
2040
2041 relocation += symbol->section->output_section->vma;
2042 relocation += symbol->section->output_offset;
2043
07515404 2044 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
5b6a02bc
TS
2045 return bfd_reloc_outofrange;
2046
5b6a02bc 2047 /* Set val to the offset into the section or symbol. */
a7ebbfdf
TS
2048 val = reloc_entry->addend;
2049
2050 if (reloc_entry->howto->partial_inplace)
2051 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
5b6a02bc
TS
2052
2053 /* Adjust val for the final section location and GP value. If we
1049f94e 2054 are producing relocatable output, we don't want to do this for
5b6a02bc 2055 an external symbol. */
1049f94e 2056 if (! relocatable
5b6a02bc
TS
2057 || (symbol->flags & BSF_SECTION_SYM) != 0)
2058 val += relocation - gp;
2059
a7ebbfdf
TS
2060 if (reloc_entry->howto->partial_inplace)
2061 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
2062 else
2063 reloc_entry->addend = val;
5b6a02bc 2064
1049f94e 2065 if (relocatable)
5b6a02bc
TS
2066 reloc_entry->address += input_section->output_offset;
2067
2068 return bfd_reloc_ok;
2069}
2070
2071/* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
a4382ec6 2072 the rest is at bits 6-10. The bitpos already got right by the howto. */
5b6a02bc 2073
a4382ec6 2074static bfd_reloc_status_type
30ac9238
RS
2075mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2076 void *data, asection *input_section, bfd *output_bfd,
2077 char **error_message)
5b6a02bc 2078{
a7ebbfdf
TS
2079 if (reloc_entry->howto->partial_inplace)
2080 {
2081 reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
2082 | (reloc_entry->addend & 0x00000800) >> 9);
2083 }
5b6a02bc 2084
30ac9238
RS
2085 return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
2086 input_section, output_bfd,
2087 error_message);
5b6a02bc
TS
2088}
2089
a4382ec6
TS
2090/* Handle a mips16 GP relative reloc. */
2091
2092static bfd_reloc_status_type
11a2be4d
RS
2093mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2094 void *data, asection *input_section, bfd *output_bfd,
2095 char **error_message)
a4382ec6 2096{
1049f94e 2097 bfd_boolean relocatable;
a4382ec6 2098 bfd_reloc_status_type ret;
d6f16593 2099 bfd_byte *location;
a4382ec6 2100 bfd_vma gp;
a4382ec6 2101
7f05722e
MR
2102 /* If we're relocating, and this is an external symbol, we don't want
2103 to change anything. */
a4382ec6
TS
2104 if (output_bfd != NULL
2105 && (symbol->flags & BSF_SECTION_SYM) == 0
a7ebbfdf 2106 && (symbol->flags & BSF_LOCAL) != 0)
a4382ec6
TS
2107 {
2108 reloc_entry->address += input_section->output_offset;
2109 return bfd_reloc_ok;
2110 }
2111
2112 if (output_bfd != NULL)
1049f94e 2113 relocatable = TRUE;
a4382ec6
TS
2114 else
2115 {
1049f94e 2116 relocatable = FALSE;
a4382ec6
TS
2117 output_bfd = symbol->section->output_section->owner;
2118 }
2119
1049f94e 2120 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
a4382ec6
TS
2121 &gp);
2122 if (ret != bfd_reloc_ok)
2123 return ret;
2124
d6f16593
MR
2125 location = (bfd_byte *) data + reloc_entry->address;
2126 _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
2127 location);
2128 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2129 input_section, relocatable,
2130 data, gp);
2131 _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
2132 location);
a7ebbfdf 2133
d6f16593 2134 return ret;
a4382ec6
TS
2135}
2136\f
2137/* A mapping from BFD reloc types to MIPS ELF reloc types. */
2138
2139struct elf_reloc_map {
2140 bfd_reloc_code_real_type bfd_val;
2141 enum elf_mips_reloc_type elf_val;
2142};
2143
2144static const struct elf_reloc_map mips_reloc_map[] =
2145{
2146 { BFD_RELOC_NONE, R_MIPS_NONE },
2147 { BFD_RELOC_16, R_MIPS_16 },
2148 { BFD_RELOC_32, R_MIPS_32 },
2149 /* There is no BFD reloc for R_MIPS_REL32. */
2150 { BFD_RELOC_64, R_MIPS_64 },
2151 { BFD_RELOC_CTOR, R_MIPS_64 },
bad36eac 2152 { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
a4382ec6
TS
2153 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
2154 { BFD_RELOC_LO16, R_MIPS_LO16 },
2155 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
2156 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
2157 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
2158 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
2159 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
2160 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
2161 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
2162 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
2163 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
2164 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
2165 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
2166 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
2167 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
2168 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
2169 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
2170 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
2171 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
2172 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
2173 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
2174 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
2175 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
2176 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
2177 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
2178 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
2179 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
0f20cc35
DJ
2180 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
2181 { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
2182 { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
2183 { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
2184 { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
2185 { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
2186 { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
2187 { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
2188 { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
2189 { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
2190 { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
2191 { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
2192 { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
2193 { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
a4382ec6
TS
2194};
2195
d6f16593
MR
2196static const struct elf_reloc_map mips16_reloc_map[] =
2197{
2198 { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
2199 { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
2200 { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
2201 { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
2202};
2203
5b6a02bc
TS
2204/* Given a BFD reloc type, return a howto structure. */
2205
2206static reloc_howto_type *
11a2be4d
RS
2207bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
2208 bfd_reloc_code_real_type code)
5b6a02bc 2209{
a4382ec6 2210 unsigned int i;
5b6a02bc
TS
2211 /* FIXME: We default to RELA here instead of choosing the right
2212 relocation variant. */
2213 reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
d6f16593 2214 reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela;
5b6a02bc 2215
a4382ec6
TS
2216 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
2217 i++)
2218 {
2219 if (mips_reloc_map[i].bfd_val == code)
2220 return &howto_table[(int) mips_reloc_map[i].elf_val];
2221 }
2222
d6f16593
MR
2223 for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
2224 i++)
2225 {
2226 if (mips16_reloc_map[i].bfd_val == code)
2227 return &howto16_table[(int) mips16_reloc_map[i].elf_val];
2228 }
2229
5b6a02bc
TS
2230 switch (code)
2231 {
5b6a02bc
TS
2232 case BFD_RELOC_VTABLE_INHERIT:
2233 return &elf_mips_gnu_vtinherit_howto;
2234 case BFD_RELOC_VTABLE_ENTRY:
2235 return &elf_mips_gnu_vtentry_howto;
5b6a02bc
TS
2236 default:
2237 bfd_set_error (bfd_error_bad_value);
2238 return NULL;
2239 }
2240}
2241
157090f7
AM
2242static reloc_howto_type *
2243bfd_elf64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
2244 const char *r_name)
2245{
2246 unsigned int i;
2247
2248 for (i = 0;
2249 i < (sizeof (mips_elf64_howto_table_rela)
2250 / sizeof (mips_elf64_howto_table_rela[0])); i++)
2251 if (mips_elf64_howto_table_rela[i].name != NULL
2252 && strcasecmp (mips_elf64_howto_table_rela[i].name, r_name) == 0)
2253 return &mips_elf64_howto_table_rela[i];
2254
2255 for (i = 0;
2256 i < (sizeof (mips16_elf64_howto_table_rela)
2257 / sizeof (mips16_elf64_howto_table_rela[0]));
2258 i++)
2259 if (mips16_elf64_howto_table_rela[i].name != NULL
2260 && strcasecmp (mips16_elf64_howto_table_rela[i].name, r_name) == 0)
2261 return &mips16_elf64_howto_table_rela[i];
2262
2263 if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
2264 return &elf_mips_gnu_vtinherit_howto;
2265 if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
2266 return &elf_mips_gnu_vtentry_howto;
2267 if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
2268 return &elf_mips_gnu_rel16_s2;
2269 if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
2270 return &elf_mips_gnu_rela16_s2;
2271
2272 return NULL;
2273}
2274
947216bf 2275/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
c6e90b02
TS
2276
2277static reloc_howto_type *
11a2be4d 2278mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
c6e90b02
TS
2279{
2280 switch (r_type)
2281 {
c6e90b02
TS
2282 case R_MIPS_GNU_VTINHERIT:
2283 return &elf_mips_gnu_vtinherit_howto;
c6e90b02
TS
2284 case R_MIPS_GNU_VTENTRY:
2285 return &elf_mips_gnu_vtentry_howto;
d0c728db
TS
2286 case R_MIPS_GNU_REL16_S2:
2287 if (rela_p)
2288 return &elf_mips_gnu_rela16_s2;
2289 else
2290 return &elf_mips_gnu_rel16_s2;
c6e90b02 2291 default:
d6f16593
MR
2292 if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
2293 {
2294 if (rela_p)
2295 return &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min];
2296 else
2297 return &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min];
2298 }
c6e90b02
TS
2299 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
2300 if (rela_p)
2301 return &mips_elf64_howto_table_rela[r_type];
2302 else
2303 return &mips_elf64_howto_table_rel[r_type];
2304 break;
2305 }
2306}
2307
5b6a02bc
TS
2308/* Prevent relocation handling by bfd for MIPS ELF64. */
2309
2310static void
11a2be4d
RS
2311mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
2312 arelent *cache_ptr ATTRIBUTE_UNUSED,
2313 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
5b6a02bc
TS
2314{
2315 BFD_ASSERT (0);
2316}
2317
2318static void
11a2be4d
RS
2319mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
2320 arelent *cache_ptr ATTRIBUTE_UNUSED,
2321 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
5b6a02bc
TS
2322{
2323 BFD_ASSERT (0);
2324}
2325
2326/* Since each entry in an SHT_REL or SHT_RELA section can represent up
2327 to three relocs, we must tell the user to allocate more space. */
2328
2329static long
11a2be4d 2330mips_elf64_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
5b6a02bc
TS
2331{
2332 return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
2333}
2334
fee24f1c 2335static long
11a2be4d 2336mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
fee24f1c
AO
2337{
2338 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
2339}
2340
2341/* We must also copy more relocations than the corresponding functions
2342 in elf.c would, so the two following functions are slightly
2343 modified from elf.c, that multiply the external relocation count by
2344 3 to obtain the internal relocation count. */
2345
2346static long
11a2be4d
RS
2347mips_elf64_canonicalize_reloc (bfd *abfd, sec_ptr section,
2348 arelent **relptr, asymbol **symbols)
fee24f1c
AO
2349{
2350 arelent *tblptr;
2351 unsigned int i;
9c5bfbb7 2352 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
fee24f1c
AO
2353
2354 if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
2355 return -1;
2356
2357 tblptr = section->relocation;
2358 for (i = 0; i < section->reloc_count * 3; i++)
2359 *relptr++ = tblptr++;
2360
2361 *relptr = NULL;
2362
2363 return section->reloc_count * 3;
2364}
2365
2366static long
11a2be4d
RS
2367mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
2368 asymbol **syms)
fee24f1c 2369{
11a2be4d 2370 bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
fee24f1c
AO
2371 asection *s;
2372 long ret;
2373
2374 if (elf_dynsymtab (abfd) == 0)
2375 {
2376 bfd_set_error (bfd_error_invalid_operation);
2377 return -1;
2378 }
2379
2380 slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
2381 ret = 0;
2382 for (s = abfd->sections; s != NULL; s = s->next)
2383 {
2384 if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
2385 && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
2386 || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
2387 {
2388 arelent *p;
2389 long count, i;
2390
2391 if (! (*slurp_relocs) (abfd, s, syms, TRUE))
2392 return -1;
eea6121a 2393 count = s->size / elf_section_data (s)->this_hdr.sh_entsize * 3;
fee24f1c
AO
2394 p = s->relocation;
2395 for (i = 0; i < count; i++)
2396 *storage++ = p++;
2397 ret += count;
2398 }
2399 }
2400
2401 *storage = NULL;
2402
2403 return ret;
2404}
2405
2406/* Read the relocations from one reloc section. This is mostly copied
2407 from elfcode.h, except for the changes to expand one external
2408 relocation to 3 internal ones. We must unfortunately set
2409 reloc_count to the number of external relocations, because a lot of
2410 generic code seems to depend on this. */
5b6a02bc 2411
b34976b6 2412static bfd_boolean
11a2be4d
RS
2413mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
2414 Elf_Internal_Shdr *rel_hdr,
2415 bfd_size_type reloc_count,
2416 arelent *relents, asymbol **symbols,
2417 bfd_boolean dynamic)
5b6a02bc 2418{
11a2be4d 2419 void *allocated;
5b6a02bc 2420 bfd_byte *native_relocs;
5b6a02bc 2421 arelent *relent;
5b6a02bc
TS
2422 bfd_vma i;
2423 int entsize;
32159579 2424 bfd_boolean rela_p;
5b6a02bc 2425
11a2be4d 2426 allocated = bfd_malloc (rel_hdr->sh_size);
5b6a02bc 2427 if (allocated == NULL)
b34976b6 2428 return FALSE;
5b6a02bc
TS
2429
2430 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
fee24f1c
AO
2431 || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
2432 != rel_hdr->sh_size))
5b6a02bc
TS
2433 goto error_return;
2434
11a2be4d 2435 native_relocs = allocated;
5b6a02bc 2436
5b6a02bc
TS
2437 entsize = rel_hdr->sh_entsize;
2438 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
2439 || entsize == sizeof (Elf64_Mips_External_Rela));
2440
5b6a02bc 2441 if (entsize == sizeof (Elf64_Mips_External_Rel))
32159579 2442 rela_p = FALSE;
5b6a02bc 2443 else
32159579 2444 rela_p = TRUE;
5b6a02bc 2445
fee24f1c
AO
2446 for (i = 0, relent = relents;
2447 i < reloc_count;
2448 i++, native_relocs += entsize)
5b6a02bc
TS
2449 {
2450 Elf64_Mips_Internal_Rela rela;
b34976b6 2451 bfd_boolean used_sym, used_ssym;
5b6a02bc
TS
2452 int ir;
2453
2454 if (entsize == sizeof (Elf64_Mips_External_Rela))
2455 mips_elf64_swap_reloca_in (abfd,
2456 (Elf64_Mips_External_Rela *) native_relocs,
2457 &rela);
2458 else
947216bf
AM
2459 mips_elf64_swap_reloc_in (abfd,
2460 (Elf64_Mips_External_Rel *) native_relocs,
2461 &rela);
5b6a02bc 2462
49179469 2463 /* Each entry represents exactly three actual relocations. */
5b6a02bc 2464
b34976b6
AM
2465 used_sym = FALSE;
2466 used_ssym = FALSE;
5b6a02bc
TS
2467 for (ir = 0; ir < 3; ir++)
2468 {
2469 enum elf_mips_reloc_type type;
2470
2471 switch (ir)
252b5132
RH
2472 {
2473 default:
2474 abort ();
2475 case 0:
2476 type = (enum elf_mips_reloc_type) rela.r_type;
2477 break;
2478 case 1:
2479 type = (enum elf_mips_reloc_type) rela.r_type2;
2480 break;
2481 case 2:
2482 type = (enum elf_mips_reloc_type) rela.r_type3;
2483 break;
2484 }
2485
252b5132
RH
2486 /* Some types require symbols, whereas some do not. */
2487 switch (type)
2488 {
2489 case R_MIPS_NONE:
2490 case R_MIPS_LITERAL:
2491 case R_MIPS_INSERT_A:
2492 case R_MIPS_INSERT_B:
2493 case R_MIPS_DELETE:
2494 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2495 break;
2496
2497 default:
2498 if (! used_sym)
2499 {
2500 if (rela.r_sym == 0)
2501 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2502 else
2503 {
2504 asymbol **ps, *s;
2505
2506 ps = symbols + rela.r_sym - 1;
2507 s = *ps;
2508 if ((s->flags & BSF_SECTION_SYM) == 0)
2509 relent->sym_ptr_ptr = ps;
2510 else
2511 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
2512 }
2513
b34976b6 2514 used_sym = TRUE;
252b5132
RH
2515 }
2516 else if (! used_ssym)
2517 {
2518 switch (rela.r_ssym)
2519 {
2520 case RSS_UNDEF:
2521 relent->sym_ptr_ptr =
2522 bfd_abs_section_ptr->symbol_ptr_ptr;
2523 break;
2524
2525 case RSS_GP:
2526 case RSS_GP0:
2527 case RSS_LOC:
2528 /* FIXME: I think these need to be handled using
99277196 2529 special howto structures. */
252b5132
RH
2530 BFD_ASSERT (0);
2531 break;
2532
2533 default:
2534 BFD_ASSERT (0);
2535 break;
2536 }
2537
b34976b6 2538 used_ssym = TRUE;
252b5132
RH
2539 }
2540 else
2541 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2542
2543 break;
2544 }
2545
2546 /* The address of an ELF reloc is section relative for an
2547 object file, and absolute for an executable file or
2548 shared library. The address of a BFD reloc is always
2549 section relative. */
fee24f1c 2550 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
252b5132
RH
2551 relent->address = rela.r_offset;
2552 else
2553 relent->address = rela.r_offset - asect->vma;
2554
2555 relent->addend = rela.r_addend;
2556
32159579 2557 relent->howto = mips_elf64_rtype_to_howto (type, rela_p);
252b5132
RH
2558
2559 ++relent;
2560 }
2561 }
2562
49179469 2563 asect->reloc_count += (relent - relents) / 3;
252b5132
RH
2564
2565 if (allocated != NULL)
2566 free (allocated);
2567
b34976b6 2568 return TRUE;
252b5132
RH
2569
2570 error_return:
2571 if (allocated != NULL)
2572 free (allocated);
b34976b6 2573 return FALSE;
252b5132
RH
2574}
2575
2576/* Read the relocations. On Irix 6, there can be two reloc sections
fee24f1c
AO
2577 associated with a single data section. This is copied from
2578 elfcode.h as well, with changes as small as accounting for 3
2579 internal relocs per external reloc and resetting reloc_count to
2580 zero before processing the relocs of a section. */
252b5132 2581
b34976b6 2582static bfd_boolean
11a2be4d
RS
2583mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
2584 asymbol **symbols, bfd_boolean dynamic)
252b5132
RH
2585{
2586 struct bfd_elf_section_data * const d = elf_section_data (asect);
fee24f1c
AO
2587 Elf_Internal_Shdr *rel_hdr;
2588 Elf_Internal_Shdr *rel_hdr2;
2589 bfd_size_type reloc_count;
2590 bfd_size_type reloc_count2;
2591 arelent *relents;
2592 bfd_size_type amt;
2593
2594 if (asect->relocation != NULL)
2595 return TRUE;
252b5132 2596
fee24f1c 2597 if (! dynamic)
252b5132 2598 {
fee24f1c
AO
2599 if ((asect->flags & SEC_RELOC) == 0
2600 || asect->reloc_count == 0)
2601 return TRUE;
252b5132 2602
fee24f1c
AO
2603 rel_hdr = &d->rel_hdr;
2604 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2605 rel_hdr2 = d->rel_hdr2;
2606 reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
2607
2608 BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
2609 BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
2610 || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
2611
2612 }
2613 else
2614 {
2615 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
2616 case because relocations against this section may use the
2617 dynamic symbol table, and in that case bfd_section_from_shdr
2618 in elf.c does not update the RELOC_COUNT. */
eea6121a 2619 if (asect->size == 0)
fee24f1c
AO
2620 return TRUE;
2621
2622 rel_hdr = &d->this_hdr;
2623 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2624 rel_hdr2 = NULL;
2625 reloc_count2 = 0;
2626 }
252b5132
RH
2627
2628 /* Allocate space for 3 arelent structures for each Rel structure. */
fee24f1c 2629 amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
11a2be4d 2630 relents = bfd_alloc (abfd, amt);
fee24f1c 2631 if (relents == NULL)
b34976b6 2632 return FALSE;
252b5132
RH
2633
2634 /* The slurp_one_reloc_table routine increments reloc_count. */
2635 asect->reloc_count = 0;
2636
fee24f1c
AO
2637 if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2638 rel_hdr, reloc_count,
2639 relents,
2640 symbols, dynamic))
b34976b6 2641 return FALSE;
252b5132
RH
2642 if (d->rel_hdr2 != NULL)
2643 {
fee24f1c
AO
2644 if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2645 rel_hdr2, reloc_count2,
2646 relents + reloc_count * 3,
2647 symbols, dynamic))
b34976b6 2648 return FALSE;
252b5132
RH
2649 }
2650
fee24f1c 2651 asect->relocation = relents;
b34976b6 2652 return TRUE;
252b5132
RH
2653}
2654
2655/* Write out the relocations. */
2656
2657static void
11a2be4d 2658mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
252b5132 2659{
11a2be4d 2660 bfd_boolean *failedp = data;
5b6a02bc
TS
2661 int count;
2662 Elf_Internal_Shdr *rel_hdr;
252b5132 2663 unsigned int idx;
252b5132
RH
2664
2665 /* If we have already failed, don't do anything. */
2666 if (*failedp)
2667 return;
2668
2669 if ((sec->flags & SEC_RELOC) == 0)
2670 return;
2671
2672 /* The linker backend writes the relocs out itself, and sets the
2673 reloc_count field to zero to inhibit writing them here. Also,
2674 sometimes the SEC_RELOC flag gets set even when there aren't any
2675 relocs. */
2676 if (sec->reloc_count == 0)
2677 return;
2678
2679 /* We can combine up to three relocs that refer to the same address
2680 if the latter relocs have no associated symbol. */
2681 count = 0;
2682 for (idx = 0; idx < sec->reloc_count; idx++)
2683 {
2684 bfd_vma addr;
2685 unsigned int i;
2686
2687 ++count;
2688
2689 addr = sec->orelocation[idx]->address;
2690 for (i = 0; i < 2; i++)
2691 {
2692 arelent *r;
2693
2694 if (idx + 1 >= sec->reloc_count)
2695 break;
2696 r = sec->orelocation[idx + 1];
2697 if (r->address != addr
2698 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2699 || (*r->sym_ptr_ptr)->value != 0)
2700 break;
2701
2702 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2703
2704 ++idx;
2705 }
2706 }
2707
5b6a02bc 2708 rel_hdr = &elf_section_data (sec)->rel_hdr;
252b5132 2709
5b6a02bc
TS
2710 /* Do the actual relocation. */
2711
2712 if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
2713 mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
2714 else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
2715 mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
2716 else
2717 BFD_ASSERT (0);
2718}
2719
2720static void
11a2be4d
RS
2721mips_elf64_write_rel (bfd *abfd, asection *sec,
2722 Elf_Internal_Shdr *rel_hdr,
2723 int *count, void *data)
5b6a02bc 2724{
11a2be4d 2725 bfd_boolean *failedp = data;
5b6a02bc
TS
2726 Elf64_Mips_External_Rel *ext_rel;
2727 unsigned int idx;
2728 asymbol *last_sym = 0;
2729 int last_sym_idx = 0;
2730
11a2be4d
RS
2731 rel_hdr->sh_size = rel_hdr->sh_entsize * *count;
2732 rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size);
5b6a02bc 2733 if (rel_hdr->contents == NULL)
252b5132 2734 {
b34976b6 2735 *failedp = TRUE;
252b5132
RH
2736 return;
2737 }
2738
5b6a02bc
TS
2739 ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
2740 for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
252b5132
RH
2741 {
2742 arelent *ptr;
947216bf 2743 Elf64_Mips_Internal_Rela int_rel;
252b5132
RH
2744 asymbol *sym;
2745 int n;
2746 unsigned int i;
2747
2748 ptr = sec->orelocation[idx];
2749
2750 /* The address of an ELF reloc is section relative for an object
2751 file, and absolute for an executable file or shared library.
2752 The address of a BFD reloc is always section relative. */
2753 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
5b6a02bc 2754 int_rel.r_offset = ptr->address;
252b5132 2755 else
5b6a02bc 2756 int_rel.r_offset = ptr->address + sec->vma;
252b5132
RH
2757
2758 sym = *ptr->sym_ptr_ptr;
2759 if (sym == last_sym)
2760 n = last_sym_idx;
99022dfb
RS
2761 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2762 n = STN_UNDEF;
252b5132
RH
2763 else
2764 {
2765 last_sym = sym;
2766 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2767 if (n < 0)
2768 {
b34976b6 2769 *failedp = TRUE;
252b5132
RH
2770 return;
2771 }
2772 last_sym_idx = n;
2773 }
2774
5b6a02bc
TS
2775 int_rel.r_sym = n;
2776 int_rel.r_ssym = RSS_UNDEF;
252b5132
RH
2777
2778 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2779 && ! _bfd_elf_validate_reloc (abfd, ptr))
2780 {
b34976b6 2781 *failedp = TRUE;
252b5132
RH
2782 return;
2783 }
2784
5b6a02bc
TS
2785 int_rel.r_type = ptr->howto->type;
2786 int_rel.r_type2 = (int) R_MIPS_NONE;
2787 int_rel.r_type3 = (int) R_MIPS_NONE;
252b5132
RH
2788
2789 for (i = 0; i < 2; i++)
2790 {
2791 arelent *r;
2792
2793 if (idx + 1 >= sec->reloc_count)
2794 break;
2795 r = sec->orelocation[idx + 1];
2796 if (r->address != ptr->address
2797 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2798 || (*r->sym_ptr_ptr)->value != 0)
2799 break;
2800
2801 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2802
2803 if (i == 0)
5b6a02bc 2804 int_rel.r_type2 = r->howto->type;
252b5132 2805 else
5b6a02bc 2806 int_rel.r_type3 = r->howto->type;
252b5132
RH
2807
2808 ++idx;
2809 }
2810
5b6a02bc 2811 mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
252b5132
RH
2812 }
2813
5b6a02bc
TS
2814 BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
2815 == *count);
252b5132 2816}
5b6a02bc
TS
2817
2818static void
11a2be4d
RS
2819mips_elf64_write_rela (bfd *abfd, asection *sec,
2820 Elf_Internal_Shdr *rela_hdr,
2821 int *count, void *data)
5b6a02bc 2822{
11a2be4d 2823 bfd_boolean *failedp = data;
5b6a02bc
TS
2824 Elf64_Mips_External_Rela *ext_rela;
2825 unsigned int idx;
2826 asymbol *last_sym = 0;
2827 int last_sym_idx = 0;
2828
11a2be4d
RS
2829 rela_hdr->sh_size = rela_hdr->sh_entsize * *count;
2830 rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
5b6a02bc
TS
2831 if (rela_hdr->contents == NULL)
2832 {
b34976b6 2833 *failedp = TRUE;
5b6a02bc
TS
2834 return;
2835 }
2836
2837 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
2838 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
2839 {
2840 arelent *ptr;
2841 Elf64_Mips_Internal_Rela int_rela;
2842 asymbol *sym;
2843 int n;
2844 unsigned int i;
2845
2846 ptr = sec->orelocation[idx];
2847
2848 /* The address of an ELF reloc is section relative for an object
2849 file, and absolute for an executable file or shared library.
2850 The address of a BFD reloc is always section relative. */
2851 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2852 int_rela.r_offset = ptr->address;
2853 else
2854 int_rela.r_offset = ptr->address + sec->vma;
2855
2856 sym = *ptr->sym_ptr_ptr;
2857 if (sym == last_sym)
2858 n = last_sym_idx;
99022dfb
RS
2859 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2860 n = STN_UNDEF;
5b6a02bc
TS
2861 else
2862 {
2863 last_sym = sym;
2864 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2865 if (n < 0)
2866 {
b34976b6 2867 *failedp = TRUE;
5b6a02bc
TS
2868 return;
2869 }
2870 last_sym_idx = n;
2871 }
2872
2873 int_rela.r_sym = n;
2874 int_rela.r_addend = ptr->addend;
2875 int_rela.r_ssym = RSS_UNDEF;
2876
2877 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2878 && ! _bfd_elf_validate_reloc (abfd, ptr))
2879 {
b34976b6 2880 *failedp = TRUE;
5b6a02bc
TS
2881 return;
2882 }
2883
2884 int_rela.r_type = ptr->howto->type;
2885 int_rela.r_type2 = (int) R_MIPS_NONE;
2886 int_rela.r_type3 = (int) R_MIPS_NONE;
2887
2888 for (i = 0; i < 2; i++)
2889 {
2890 arelent *r;
2891
2892 if (idx + 1 >= sec->reloc_count)
2893 break;
2894 r = sec->orelocation[idx + 1];
2895 if (r->address != ptr->address
2896 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2897 || (*r->sym_ptr_ptr)->value != 0)
2898 break;
2899
2900 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
2901
2902 if (i == 0)
2903 int_rela.r_type2 = r->howto->type;
2904 else
2905 int_rela.r_type3 = r->howto->type;
2906
2907 ++idx;
2908 }
2909
2910 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
2911 }
2912
2913 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
2914 == *count);
2915}
2916\f
c6e90b02 2917/* Set the right machine number for a MIPS ELF file. */
5b6a02bc 2918
b34976b6 2919static bfd_boolean
11a2be4d 2920mips_elf64_object_p (bfd *abfd)
5b6a02bc 2921{
c6e90b02 2922 unsigned long mach;
5b6a02bc 2923
c6e90b02
TS
2924 /* Irix 6 is broken. Object file symbol tables are not always
2925 sorted correctly such that local symbols precede global symbols,
2926 and the sh_info field in the symbol table is not always right. */
a4382ec6 2927 if (elf64_mips_irix_compat (abfd) != ict_none)
b34976b6 2928 elf_bad_symtab (abfd) = TRUE;
5b6a02bc 2929
c6e90b02
TS
2930 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
2931 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
b34976b6 2932 return TRUE;
5b6a02bc
TS
2933}
2934
c6e90b02
TS
2935/* Depending on the target vector we generate some version of Irix
2936 executables or "normal" MIPS ELF ABI executables. */
2937static irix_compat_t
11a2be4d 2938elf64_mips_irix_compat (bfd *abfd)
5b6a02bc 2939{
a4382ec6
TS
2940 if ((abfd->xvec == &bfd_elf64_bigmips_vec)
2941 || (abfd->xvec == &bfd_elf64_littlemips_vec))
c6e90b02 2942 return ict_irix6;
a4382ec6
TS
2943 else
2944 return ict_none;
5b6a02bc
TS
2945}
2946\f
d0112f73
KB
2947/* Support for core dump NOTE sections. */
2948static bfd_boolean
11a2be4d 2949elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
d0112f73
KB
2950{
2951 int offset;
eea6121a 2952 unsigned int size;
d0112f73
KB
2953
2954 switch (note->descsz)
2955 {
2956 default:
2957 return FALSE;
2958
2959 case 480: /* Linux/MIPS - N64 kernel */
2960 /* pr_cursig */
2961 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
2962
2963 /* pr_pid */
2964 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 32);
2965
2966 /* pr_reg */
2967 offset = 112;
eea6121a 2968 size = 360;
d0112f73
KB
2969
2970 break;
2971 }
2972
2973 /* Make a ".reg/999" section. */
2974 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
eea6121a 2975 size, note->descpos + offset);
d0112f73
KB
2976}
2977
2978static bfd_boolean
11a2be4d 2979elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
d0112f73
KB
2980{
2981 switch (note->descsz)
2982 {
2983 default:
2984 return FALSE;
2985
2986 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
2987 elf_tdata (abfd)->core_program
2988 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
2989 elf_tdata (abfd)->core_command
2990 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
2991 }
2992
2993 /* Note that for some reason, a spurious space is tacked
2994 onto the end of the args in some (at least one anyway)
2995 implementations, so strip it off if it exists. */
2996
2997 {
2998 char *command = elf_tdata (abfd)->core_command;
2999 int n = strlen (command);
3000
3001 if (0 < n && command[n - 1] == ' ')
3002 command[n - 1] = '\0';
3003 }
3004
3005 return TRUE;
3006}
3007\f
c6e90b02
TS
3008/* ECOFF swapping routines. These are used when dealing with the
3009 .mdebug section, which is in the ECOFF debugging format. */
3010static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
5b6a02bc 3011{
c6e90b02
TS
3012 /* Symbol table magic number. */
3013 magicSym2,
3014 /* Alignment of debugging information. E.g., 4. */
3015 8,
3016 /* Sizes of external symbolic information. */
3017 sizeof (struct hdr_ext),
3018 sizeof (struct dnr_ext),
3019 sizeof (struct pdr_ext),
3020 sizeof (struct sym_ext),
3021 sizeof (struct opt_ext),
3022 sizeof (struct fdr_ext),
3023 sizeof (struct rfd_ext),
3024 sizeof (struct ext_ext),
3025 /* Functions to swap in external symbolic data. */
3026 ecoff_swap_hdr_in,
3027 ecoff_swap_dnr_in,
3028 ecoff_swap_pdr_in,
3029 ecoff_swap_sym_in,
3030 ecoff_swap_opt_in,
3031 ecoff_swap_fdr_in,
3032 ecoff_swap_rfd_in,
3033 ecoff_swap_ext_in,
3034 _bfd_ecoff_swap_tir_in,
3035 _bfd_ecoff_swap_rndx_in,
3036 /* Functions to swap out external symbolic data. */
3037 ecoff_swap_hdr_out,
3038 ecoff_swap_dnr_out,
3039 ecoff_swap_pdr_out,
3040 ecoff_swap_sym_out,
3041 ecoff_swap_opt_out,
3042 ecoff_swap_fdr_out,
3043 ecoff_swap_rfd_out,
3044 ecoff_swap_ext_out,
3045 _bfd_ecoff_swap_tir_out,
3046 _bfd_ecoff_swap_rndx_out,
3047 /* Function to read in symbolic data. */
3048 _bfd_mips_elf_read_ecoff_info
3049};
3050\f
3051/* Relocations in the 64 bit MIPS ELF ABI are more complex than in
3052 standard ELF. This structure is used to redirect the relocation
3053 handling routines. */
5b6a02bc 3054
c6e90b02 3055const struct elf_size_info mips_elf64_size_info =
5b6a02bc 3056{
c6e90b02
TS
3057 sizeof (Elf64_External_Ehdr),
3058 sizeof (Elf64_External_Phdr),
3059 sizeof (Elf64_External_Shdr),
3060 sizeof (Elf64_Mips_External_Rel),
3061 sizeof (Elf64_Mips_External_Rela),
3062 sizeof (Elf64_External_Sym),
3063 sizeof (Elf64_External_Dyn),
3064 sizeof (Elf_External_Note),
99277196
MR
3065 4, /* hash-table entry size */
3066 3, /* internal relocations per external relocations */
c6e90b02 3067 64, /* arch_size */
45d6a902 3068 3, /* log_file_align */
c6e90b02
TS
3069 ELFCLASS64,
3070 EV_CURRENT,
3071 bfd_elf64_write_out_phdrs,
3072 bfd_elf64_write_shdrs_and_ehdr,
1489a3a0 3073 bfd_elf64_checksum_contents,
c6e90b02 3074 mips_elf64_write_relocs,
73ff0d56 3075 bfd_elf64_swap_symbol_in,
c6e90b02
TS
3076 bfd_elf64_swap_symbol_out,
3077 mips_elf64_slurp_reloc_table,
3078 bfd_elf64_slurp_symbol_table,
3079 bfd_elf64_swap_dyn_in,
3080 bfd_elf64_swap_dyn_out,
3081 mips_elf64_be_swap_reloc_in,
3082 mips_elf64_be_swap_reloc_out,
3083 mips_elf64_be_swap_reloca_in,
3084 mips_elf64_be_swap_reloca_out
5b6a02bc
TS
3085};
3086
c6e90b02
TS
3087#define ELF_ARCH bfd_arch_mips
3088#define ELF_MACHINE_CODE EM_MIPS
103186c6 3089
b34976b6
AM
3090#define elf_backend_collect TRUE
3091#define elf_backend_type_change_ok TRUE
3092#define elf_backend_can_gc_sections TRUE
5b6a02bc
TS
3093#define elf_info_to_howto mips_elf64_info_to_howto_rela
3094#define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
c6e90b02 3095#define elf_backend_object_p mips_elf64_object_p
5b6a02bc
TS
3096#define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
3097#define elf_backend_section_processing _bfd_mips_elf_section_processing
103186c6 3098#define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
252b5132
RH
3099#define elf_backend_fake_sections _bfd_mips_elf_fake_sections
3100#define elf_backend_section_from_bfd_section \
c6e90b02 3101 _bfd_mips_elf_section_from_bfd_section
103186c6 3102#define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
5b6a02bc 3103#define elf_backend_link_output_symbol_hook \
c6e90b02 3104 _bfd_mips_elf_link_output_symbol_hook
103186c6 3105#define elf_backend_create_dynamic_sections \
c6e90b02
TS
3106 _bfd_mips_elf_create_dynamic_sections
3107#define elf_backend_check_relocs _bfd_mips_elf_check_relocs
8992f0d7
TS
3108#define elf_backend_merge_symbol_attribute \
3109 _bfd_mips_elf_merge_symbol_attribute
103186c6 3110#define elf_backend_adjust_dynamic_symbol \
c6e90b02 3111 _bfd_mips_elf_adjust_dynamic_symbol
103186c6 3112#define elf_backend_always_size_sections \
c6e90b02 3113 _bfd_mips_elf_always_size_sections
103186c6 3114#define elf_backend_size_dynamic_sections \
c6e90b02 3115 _bfd_mips_elf_size_dynamic_sections
74541ad4 3116#define elf_backend_init_index_section _bfd_elf_init_1_index_section
c6e90b02 3117#define elf_backend_relocate_section _bfd_mips_elf_relocate_section
103186c6 3118#define elf_backend_finish_dynamic_symbol \
c6e90b02 3119 _bfd_mips_elf_finish_dynamic_symbol
103186c6 3120#define elf_backend_finish_dynamic_sections \
c6e90b02 3121 _bfd_mips_elf_finish_dynamic_sections
5b6a02bc 3122#define elf_backend_final_write_processing \
c6e90b02 3123 _bfd_mips_elf_final_write_processing
5b6a02bc 3124#define elf_backend_additional_program_headers \
c6e90b02 3125 _bfd_mips_elf_additional_program_headers
5b6a02bc 3126#define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
c6e90b02
TS
3127#define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
3128#define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
427b80f4
RS
3129#define elf_backend_copy_indirect_symbol \
3130 _bfd_mips_elf_copy_indirect_symbol
c6e90b02 3131#define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
53bfd6b4
MR
3132#define elf_backend_ignore_discarded_relocs \
3133 _bfd_mips_elf_ignore_discarded_relocs
c6e90b02
TS
3134#define elf_backend_mips_irix_compat elf64_mips_irix_compat
3135#define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
5b6a02bc
TS
3136#define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
3137#define elf_backend_size_info mips_elf64_size_info
d0112f73
KB
3138
3139#define elf_backend_grok_prstatus elf64_mips_grok_prstatus
3140#define elf_backend_grok_psinfo elf64_mips_grok_psinfo
5b6a02bc
TS
3141
3142#define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
1e2be829
TS
3143
3144/* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
c6e90b02 3145 work better/work only in RELA, so we default to this. */
1e2be829
TS
3146#define elf_backend_may_use_rel_p 1
3147#define elf_backend_may_use_rela_p 1
3148#define elf_backend_default_use_rela_p 1
103186c6 3149
d01414a5
TS
3150#define elf_backend_write_section _bfd_mips_elf_write_section
3151
fe8bc63d 3152/* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
103186c6
MM
3153 MIPS-specific function only applies to IRIX5, which had no 64-bit
3154 ABI. */
252b5132 3155#define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
4ab527b0 3156#define bfd_elf64_find_inliner_info _bfd_mips_elf_find_inliner_info
f0abc2a1 3157#define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
252b5132 3158#define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
c6e90b02
TS
3159#define bfd_elf64_bfd_get_relocated_section_contents \
3160 _bfd_elf_mips_get_relocated_section_contents
103186c6 3161#define bfd_elf64_bfd_link_hash_table_create \
c6e90b02
TS
3162 _bfd_mips_elf_link_hash_table_create
3163#define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
252b5132 3164#define bfd_elf64_bfd_merge_private_bfd_data \
c6e90b02 3165 _bfd_mips_elf_merge_private_bfd_data
252b5132 3166#define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
103186c6 3167#define bfd_elf64_bfd_print_private_bfd_data \
c6e90b02 3168 _bfd_mips_elf_print_private_bfd_data
252b5132 3169
103186c6 3170#define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
fee24f1c
AO
3171#define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
3172#define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
3173#define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
d0647110 3174#define bfd_elf64_bfd_relax_section _bfd_mips_relax_section
c6e90b02
TS
3175
3176/* MIPS ELF64 archive functions. */
252b5132 3177#define bfd_elf64_archive_functions
b34976b6 3178extern bfd_boolean bfd_elf64_archive_slurp_armap
11a2be4d 3179 (bfd *);
b34976b6 3180extern bfd_boolean bfd_elf64_archive_write_armap
11a2be4d 3181 (bfd *, unsigned int, struct orl *, unsigned int, int);
252b5132 3182#define bfd_elf64_archive_slurp_extended_name_table \
c6e90b02 3183 _bfd_archive_coff_slurp_extended_name_table
252b5132 3184#define bfd_elf64_archive_construct_extended_name_table \
c6e90b02 3185 _bfd_archive_coff_construct_extended_name_table
252b5132 3186#define bfd_elf64_archive_truncate_arname \
c6e90b02 3187 _bfd_archive_coff_truncate_arname
252b5132
RH
3188#define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
3189#define bfd_elf64_archive_openr_next_archived_file \
c6e90b02 3190 _bfd_archive_coff_openr_next_archived_file
252b5132 3191#define bfd_elf64_archive_get_elt_at_index \
c6e90b02 3192 _bfd_archive_coff_get_elt_at_index
252b5132 3193#define bfd_elf64_archive_generic_stat_arch_elt \
c6e90b02 3194 _bfd_archive_coff_generic_stat_arch_elt
252b5132 3195#define bfd_elf64_archive_update_armap_timestamp \
c6e90b02 3196 _bfd_archive_coff_update_armap_timestamp
252b5132 3197
5b6a02bc
TS
3198/* The SGI style (n)64 NewABI. */
3199#define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
3200#define TARGET_LITTLE_NAME "elf64-littlemips"
3201#define TARGET_BIG_SYM bfd_elf64_bigmips_vec
3202#define TARGET_BIG_NAME "elf64-bigmips"
fdbafa10 3203
7fd91fe0
TS
3204#define ELF_MAXPAGESIZE 0x10000
3205#define ELF_COMMONPAGESIZE 0x1000
fdbafa10 3206
4301eeb1 3207#include "elf64-target.h"
fdbafa10 3208
5b6a02bc 3209/* The SYSV-style 'traditional' (n)64 NewABI. */
fdbafa10
L
3210#undef TARGET_LITTLE_SYM
3211#undef TARGET_LITTLE_NAME
3212#undef TARGET_BIG_SYM
3213#undef TARGET_BIG_NAME
3214
4301eeb1 3215#undef ELF_MAXPAGESIZE
7fd91fe0 3216#undef ELF_COMMONPAGESIZE
4301eeb1 3217
99277196
MR
3218#define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
3219#define TARGET_LITTLE_NAME "elf64-tradlittlemips"
3220#define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
3221#define TARGET_BIG_NAME "elf64-tradbigmips"
fdbafa10 3222
4301eeb1 3223#define ELF_MAXPAGESIZE 0x10000
7fd91fe0 3224#define ELF_COMMONPAGESIZE 0x1000
4301eeb1
MR
3225#define elf64_bed elf64_tradbed
3226
5b6a02bc 3227/* Include the target file again for this target. */
fdbafa10 3228#include "elf64-target.h"
This page took 0.608994 seconds and 4 git commands to generate.