bfd/
[deliverable/binutils-gdb.git] / bfd / elf64-mips.c
CommitLineData
252b5132 1/* MIPS-specific support for 64-bit ELF
157090f7 2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4f608e79
L
3 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
252b5132 5 Ian Lance Taylor, Cygnus Support
103186c6
MM
6 Linker support added by Mark Mitchell, CodeSourcery, LLC.
7 <mark@codesourcery.com>
252b5132 8
cd123cb7 9 This file is part of BFD, the Binary File Descriptor library.
252b5132 10
cd123cb7
NC
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
252b5132 15
cd123cb7
NC
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
24 MA 02110-1301, USA. */
252b5132 25
252b5132
RH
26
27/* This file supports the 64-bit MIPS ELF ABI.
28
29 The MIPS 64-bit ELF ABI uses an unusual reloc format. This file
30 overrides the usual ELF reloc handling, and handles reading and
36b45482 31 writing the relocations here. */
252b5132 32
5b6a02bc
TS
33/* TODO: Many things are unsupported, even if there is some code for it
34 . (which was mostly stolen from elf32-mips.c and slightly adapted).
35 .
36 . - Relocation handling for REL relocs is wrong in many cases and
37 . generally untested.
38 . - Relocation handling for RELA relocs related to GOT support are
39 . also likely to be wrong.
a4382ec6 40 . - Support for MIPS16 is untested.
5b6a02bc
TS
41 . - Combined relocs with RSS_* entries are unsupported.
42 . - The whole GOT handling for NewABI is missing, some parts of
c6e90b02 43 . the OldABI version is still lying around and should be removed.
5b6a02bc
TS
44 */
45
252b5132 46#include "sysdep.h"
3db64b00 47#include "bfd.h"
252b5132
RH
48#include "libbfd.h"
49#include "aout/ar.h"
50#include "bfdlink.h"
51#include "genlink.h"
52#include "elf-bfd.h"
c6e90b02 53#include "elfxx-mips.h"
252b5132
RH
54#include "elf/mips.h"
55
56/* Get the ECOFF swapping routines. The 64-bit ABI is not supposed to
57 use ECOFF. However, we support it anyhow for an easier changeover. */
58#include "coff/sym.h"
59#include "coff/symconst.h"
60#include "coff/internal.h"
61#include "coff/ecoff.h"
62/* The 64 bit versions of the mdebug data structures are in alpha.h. */
63#include "coff/alpha.h"
23e2c83b 64#define ECOFF_SIGNED_64
252b5132
RH
65#include "ecoffswap.h"
66
67static void mips_elf64_swap_reloc_in
11a2be4d 68 (bfd *, const Elf64_Mips_External_Rel *, Elf64_Mips_Internal_Rela *);
252b5132 69static void mips_elf64_swap_reloca_in
11a2be4d 70 (bfd *, const Elf64_Mips_External_Rela *, Elf64_Mips_Internal_Rela *);
252b5132 71static void mips_elf64_swap_reloc_out
11a2be4d 72 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rel *);
252b5132 73static void mips_elf64_swap_reloca_out
11a2be4d 74 (bfd *, const Elf64_Mips_Internal_Rela *, Elf64_Mips_External_Rela *);
c7ac6ff8 75static void mips_elf64_be_swap_reloc_in
11a2be4d 76 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
c7ac6ff8 77static void mips_elf64_be_swap_reloc_out
11a2be4d 78 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
c7ac6ff8 79static void mips_elf64_be_swap_reloca_in
11a2be4d 80 (bfd *, const bfd_byte *, Elf_Internal_Rela *);
c7ac6ff8 81static void mips_elf64_be_swap_reloca_out
11a2be4d 82 (bfd *, const Elf_Internal_Rela *, bfd_byte *);
c6e90b02 83static reloc_howto_type *bfd_elf64_bfd_reloc_type_lookup
11a2be4d 84 (bfd *, bfd_reloc_code_real_type);
c6e90b02 85static reloc_howto_type *mips_elf64_rtype_to_howto
11a2be4d 86 (unsigned int, bfd_boolean);
5b6a02bc 87static void mips_elf64_info_to_howto_rel
11a2be4d 88 (bfd *, arelent *, Elf_Internal_Rela *);
5b6a02bc 89static void mips_elf64_info_to_howto_rela
11a2be4d 90 (bfd *, arelent *, Elf_Internal_Rela *);
b34976b6 91static long mips_elf64_get_reloc_upper_bound
11a2be4d 92 (bfd *, asection *);
fee24f1c 93static long mips_elf64_canonicalize_reloc
11a2be4d
RS
94 (bfd *, asection *, arelent **, asymbol **);
95static long mips_elf64_get_dynamic_reloc_upper_bound
96 (bfd *);
fee24f1c 97static long mips_elf64_canonicalize_dynamic_reloc
11a2be4d 98 (bfd *, arelent **, asymbol **);
b34976b6 99static bfd_boolean mips_elf64_slurp_one_reloc_table
11a2be4d
RS
100 (bfd *, asection *, Elf_Internal_Shdr *, bfd_size_type, arelent *,
101 asymbol **, bfd_boolean);
b34976b6 102static bfd_boolean mips_elf64_slurp_reloc_table
11a2be4d 103 (bfd *, asection *, asymbol **, bfd_boolean);
b34976b6 104static void mips_elf64_write_relocs
11a2be4d 105 (bfd *, asection *, void *);
5b6a02bc 106static void mips_elf64_write_rel
11a2be4d 107 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
5b6a02bc 108static void mips_elf64_write_rela
11a2be4d 109 (bfd *, asection *, Elf_Internal_Shdr *, int *, void *);
5b6a02bc 110static bfd_reloc_status_type mips_elf64_gprel16_reloc
11a2be4d 111 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
5b6a02bc 112static bfd_reloc_status_type mips_elf64_literal_reloc
11a2be4d 113 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
5b6a02bc 114static bfd_reloc_status_type mips_elf64_gprel32_reloc
11a2be4d 115 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
5b6a02bc 116static bfd_reloc_status_type mips_elf64_shift6_reloc
11a2be4d 117 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
a4382ec6 118static bfd_reloc_status_type mips16_gprel_reloc
11a2be4d 119 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
b34976b6 120static bfd_boolean mips_elf64_assign_gp
11a2be4d 121 (bfd *, bfd_vma *);
5b6a02bc 122static bfd_reloc_status_type mips_elf64_final_gp
11a2be4d 123 (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
b34976b6 124static bfd_boolean mips_elf64_object_p
11a2be4d 125 (bfd *);
b34976b6 126static irix_compat_t elf64_mips_irix_compat
11a2be4d 127 (bfd *);
d0112f73 128static bfd_boolean elf64_mips_grok_prstatus
11a2be4d 129 (bfd *, Elf_Internal_Note *);
d0112f73 130static bfd_boolean elf64_mips_grok_psinfo
11a2be4d 131 (bfd *, Elf_Internal_Note *);
c6e90b02 132
a4382ec6
TS
133extern const bfd_target bfd_elf64_bigmips_vec;
134extern const bfd_target bfd_elf64_littlemips_vec;
252b5132
RH
135
136/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
137 from smaller values. Start with zero, widen, *then* decrement. */
138#define MINUS_ONE (((bfd_vma)0) - 1)
139
103186c6
MM
140/* The number of local .got entries we reserve. */
141#define MIPS_RESERVED_GOTNO (2)
c6e90b02 142\f
252b5132
RH
143/* The relocation table used for SHT_REL sections. */
144
145static reloc_howto_type mips_elf64_howto_table_rel[] =
146{
147 /* No relocation. */
148 HOWTO (R_MIPS_NONE, /* type */
149 0, /* rightshift */
150 0, /* size (0 = byte, 1 = short, 2 = long) */
151 0, /* bitsize */
b34976b6 152 FALSE, /* pc_relative */
252b5132
RH
153 0, /* bitpos */
154 complain_overflow_dont, /* complain_on_overflow */
30ac9238 155 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 156 "R_MIPS_NONE", /* name */
b34976b6 157 FALSE, /* partial_inplace */
252b5132
RH
158 0, /* src_mask */
159 0, /* dst_mask */
b34976b6 160 FALSE), /* pcrel_offset */
252b5132
RH
161
162 /* 16 bit relocation. */
163 HOWTO (R_MIPS_16, /* type */
164 0, /* rightshift */
5b6a02bc 165 2, /* size (0 = byte, 1 = short, 2 = long) */
252b5132 166 16, /* bitsize */
b34976b6 167 FALSE, /* pc_relative */
252b5132 168 0, /* bitpos */
5b6a02bc 169 complain_overflow_signed, /* complain_on_overflow */
30ac9238 170 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 171 "R_MIPS_16", /* name */
b34976b6 172 TRUE, /* partial_inplace */
5b6a02bc
TS
173 0x0000ffff, /* src_mask */
174 0x0000ffff, /* dst_mask */
b34976b6 175 FALSE), /* pcrel_offset */
252b5132
RH
176
177 /* 32 bit relocation. */
178 HOWTO (R_MIPS_32, /* type */
179 0, /* rightshift */
180 2, /* size (0 = byte, 1 = short, 2 = long) */
181 32, /* bitsize */
b34976b6 182 FALSE, /* pc_relative */
252b5132 183 0, /* bitpos */
77bfe34f 184 complain_overflow_dont, /* complain_on_overflow */
30ac9238 185 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 186 "R_MIPS_32", /* name */
b34976b6 187 TRUE, /* partial_inplace */
252b5132
RH
188 0xffffffff, /* src_mask */
189 0xffffffff, /* dst_mask */
b34976b6 190 FALSE), /* pcrel_offset */
252b5132
RH
191
192 /* 32 bit symbol relative relocation. */
193 HOWTO (R_MIPS_REL32, /* type */
194 0, /* rightshift */
195 2, /* size (0 = byte, 1 = short, 2 = long) */
196 32, /* bitsize */
b34976b6 197 FALSE, /* pc_relative */
252b5132 198 0, /* bitpos */
77bfe34f 199 complain_overflow_dont, /* complain_on_overflow */
30ac9238 200 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 201 "R_MIPS_REL32", /* name */
b34976b6 202 TRUE, /* partial_inplace */
252b5132
RH
203 0xffffffff, /* src_mask */
204 0xffffffff, /* dst_mask */
b34976b6 205 FALSE), /* pcrel_offset */
252b5132 206
77bfe34f 207 /* 26 bit jump address. */
252b5132
RH
208 HOWTO (R_MIPS_26, /* type */
209 2, /* rightshift */
210 2, /* size (0 = byte, 1 = short, 2 = long) */
211 26, /* bitsize */
b34976b6 212 FALSE, /* pc_relative */
252b5132
RH
213 0, /* bitpos */
214 complain_overflow_dont, /* complain_on_overflow */
56fc028e 215 /* This needs complex overflow
77bfe34f 216 detection, because the upper 36
b401d8e5 217 bits must match the PC + 4. */
30ac9238 218 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 219 "R_MIPS_26", /* name */
b34976b6 220 TRUE, /* partial_inplace */
5b6a02bc
TS
221 0x03ffffff, /* src_mask */
222 0x03ffffff, /* dst_mask */
b34976b6 223 FALSE), /* pcrel_offset */
252b5132 224
a4382ec6
TS
225 /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
226 However, the native IRIX6 tools use them, so we try our best. */
227
252b5132
RH
228 /* High 16 bits of symbol value. */
229 HOWTO (R_MIPS_HI16, /* type */
30ac9238 230 16, /* rightshift */
252b5132
RH
231 2, /* size (0 = byte, 1 = short, 2 = long) */
232 16, /* bitsize */
b34976b6 233 FALSE, /* pc_relative */
252b5132
RH
234 0, /* bitpos */
235 complain_overflow_dont, /* complain_on_overflow */
30ac9238 236 _bfd_mips_elf_hi16_reloc, /* special_function */
252b5132 237 "R_MIPS_HI16", /* name */
b34976b6 238 TRUE, /* partial_inplace */
5b6a02bc
TS
239 0x0000ffff, /* src_mask */
240 0x0000ffff, /* dst_mask */
b34976b6 241 FALSE), /* pcrel_offset */
252b5132
RH
242
243 /* Low 16 bits of symbol value. */
244 HOWTO (R_MIPS_LO16, /* type */
245 0, /* rightshift */
246 2, /* size (0 = byte, 1 = short, 2 = long) */
247 16, /* bitsize */
b34976b6 248 FALSE, /* pc_relative */
252b5132
RH
249 0, /* bitpos */
250 complain_overflow_dont, /* complain_on_overflow */
30ac9238 251 _bfd_mips_elf_lo16_reloc, /* special_function */
252b5132 252 "R_MIPS_LO16", /* name */
b34976b6 253 TRUE, /* partial_inplace */
5b6a02bc
TS
254 0x0000ffff, /* src_mask */
255 0x0000ffff, /* dst_mask */
b34976b6 256 FALSE), /* pcrel_offset */
252b5132
RH
257
258 /* GP relative reference. */
259 HOWTO (R_MIPS_GPREL16, /* type */
260 0, /* rightshift */
261 2, /* size (0 = byte, 1 = short, 2 = long) */
262 16, /* bitsize */
b34976b6 263 FALSE, /* pc_relative */
252b5132
RH
264 0, /* bitpos */
265 complain_overflow_signed, /* complain_on_overflow */
5b6a02bc 266 mips_elf64_gprel16_reloc, /* special_function */
252b5132 267 "R_MIPS_GPREL16", /* name */
b34976b6 268 TRUE, /* partial_inplace */
5b6a02bc
TS
269 0x0000ffff, /* src_mask */
270 0x0000ffff, /* dst_mask */
b34976b6 271 FALSE), /* pcrel_offset */
252b5132
RH
272
273 /* Reference to literal section. */
274 HOWTO (R_MIPS_LITERAL, /* type */
275 0, /* rightshift */
276 2, /* size (0 = byte, 1 = short, 2 = long) */
277 16, /* bitsize */
b34976b6 278 FALSE, /* pc_relative */
252b5132
RH
279 0, /* bitpos */
280 complain_overflow_signed, /* complain_on_overflow */
5b6a02bc 281 mips_elf64_literal_reloc, /* special_function */
252b5132 282 "R_MIPS_LITERAL", /* name */
b34976b6 283 TRUE, /* partial_inplace */
5b6a02bc
TS
284 0x0000ffff, /* src_mask */
285 0x0000ffff, /* dst_mask */
b34976b6 286 FALSE), /* pcrel_offset */
252b5132
RH
287
288 /* Reference to global offset table. */
289 HOWTO (R_MIPS_GOT16, /* type */
290 0, /* rightshift */
291 2, /* size (0 = byte, 1 = short, 2 = long) */
292 16, /* bitsize */
b34976b6 293 FALSE, /* pc_relative */
252b5132
RH
294 0, /* bitpos */
295 complain_overflow_signed, /* complain_on_overflow */
30ac9238 296 _bfd_mips_elf_got16_reloc, /* special_function */
252b5132 297 "R_MIPS_GOT16", /* name */
b34976b6 298 TRUE, /* partial_inplace */
5b6a02bc
TS
299 0x0000ffff, /* src_mask */
300 0x0000ffff, /* dst_mask */
b34976b6 301 FALSE), /* pcrel_offset */
252b5132 302
bad36eac
DJ
303 /* 16 bit PC relative reference. Note that the ABI document has a typo
304 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
305 We do the right thing here. */
252b5132 306 HOWTO (R_MIPS_PC16, /* type */
bad36eac 307 2, /* rightshift */
252b5132
RH
308 2, /* size (0 = byte, 1 = short, 2 = long) */
309 16, /* bitsize */
b34976b6 310 TRUE, /* pc_relative */
252b5132
RH
311 0, /* bitpos */
312 complain_overflow_signed, /* complain_on_overflow */
30ac9238 313 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 314 "R_MIPS_PC16", /* name */
b34976b6 315 TRUE, /* partial_inplace */
5b6a02bc
TS
316 0x0000ffff, /* src_mask */
317 0x0000ffff, /* dst_mask */
b34976b6 318 TRUE), /* pcrel_offset */
252b5132
RH
319
320 /* 16 bit call through global offset table. */
252b5132
RH
321 HOWTO (R_MIPS_CALL16, /* type */
322 0, /* rightshift */
323 2, /* size (0 = byte, 1 = short, 2 = long) */
324 16, /* bitsize */
b34976b6 325 FALSE, /* pc_relative */
252b5132
RH
326 0, /* bitpos */
327 complain_overflow_signed, /* complain_on_overflow */
30ac9238 328 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 329 "R_MIPS_CALL16", /* name */
b34976b6 330 TRUE, /* partial_inplace */
5b6a02bc
TS
331 0x0000ffff, /* src_mask */
332 0x0000ffff, /* dst_mask */
b34976b6 333 FALSE), /* pcrel_offset */
252b5132
RH
334
335 /* 32 bit GP relative reference. */
336 HOWTO (R_MIPS_GPREL32, /* type */
337 0, /* rightshift */
338 2, /* size (0 = byte, 1 = short, 2 = long) */
339 32, /* bitsize */
b34976b6 340 FALSE, /* pc_relative */
252b5132 341 0, /* bitpos */
5b6a02bc
TS
342 complain_overflow_dont, /* complain_on_overflow */
343 mips_elf64_gprel32_reloc, /* special_function */
252b5132 344 "R_MIPS_GPREL32", /* name */
b34976b6 345 TRUE, /* partial_inplace */
252b5132
RH
346 0xffffffff, /* src_mask */
347 0xffffffff, /* dst_mask */
b34976b6 348 FALSE), /* pcrel_offset */
252b5132 349
a4382ec6
TS
350 EMPTY_HOWTO (13),
351 EMPTY_HOWTO (14),
352 EMPTY_HOWTO (15),
252b5132
RH
353
354 /* A 5 bit shift field. */
355 HOWTO (R_MIPS_SHIFT5, /* type */
356 0, /* rightshift */
357 2, /* size (0 = byte, 1 = short, 2 = long) */
358 5, /* bitsize */
b34976b6 359 FALSE, /* pc_relative */
252b5132
RH
360 6, /* bitpos */
361 complain_overflow_bitfield, /* complain_on_overflow */
30ac9238 362 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 363 "R_MIPS_SHIFT5", /* name */
b34976b6 364 TRUE, /* partial_inplace */
252b5132
RH
365 0x000007c0, /* src_mask */
366 0x000007c0, /* dst_mask */
b34976b6 367 FALSE), /* pcrel_offset */
252b5132
RH
368
369 /* A 6 bit shift field. */
252b5132
RH
370 HOWTO (R_MIPS_SHIFT6, /* type */
371 0, /* rightshift */
372 2, /* size (0 = byte, 1 = short, 2 = long) */
373 6, /* bitsize */
b34976b6 374 FALSE, /* pc_relative */
252b5132
RH
375 6, /* bitpos */
376 complain_overflow_bitfield, /* complain_on_overflow */
5b6a02bc 377 mips_elf64_shift6_reloc, /* special_function */
252b5132 378 "R_MIPS_SHIFT6", /* name */
b34976b6 379 TRUE, /* partial_inplace */
252b5132
RH
380 0x000007c4, /* src_mask */
381 0x000007c4, /* dst_mask */
b34976b6 382 FALSE), /* pcrel_offset */
252b5132
RH
383
384 /* 64 bit relocation. */
385 HOWTO (R_MIPS_64, /* type */
386 0, /* rightshift */
387 4, /* size (0 = byte, 1 = short, 2 = long) */
388 64, /* bitsize */
b34976b6 389 FALSE, /* pc_relative */
252b5132 390 0, /* bitpos */
77bfe34f 391 complain_overflow_dont, /* complain_on_overflow */
30ac9238 392 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 393 "R_MIPS_64", /* name */
b34976b6 394 TRUE, /* partial_inplace */
252b5132
RH
395 MINUS_ONE, /* src_mask */
396 MINUS_ONE, /* dst_mask */
b34976b6 397 FALSE), /* pcrel_offset */
252b5132
RH
398
399 /* Displacement in the global offset table. */
252b5132
RH
400 HOWTO (R_MIPS_GOT_DISP, /* type */
401 0, /* rightshift */
402 2, /* size (0 = byte, 1 = short, 2 = long) */
403 16, /* bitsize */
b34976b6 404 FALSE, /* pc_relative */
252b5132 405 0, /* bitpos */
77bfe34f 406 complain_overflow_signed, /* complain_on_overflow */
30ac9238 407 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 408 "R_MIPS_GOT_DISP", /* name */
b34976b6 409 TRUE, /* partial_inplace */
252b5132
RH
410 0x0000ffff, /* src_mask */
411 0x0000ffff, /* dst_mask */
b34976b6 412 FALSE), /* pcrel_offset */
252b5132
RH
413
414 /* Displacement to page pointer in the global offset table. */
252b5132
RH
415 HOWTO (R_MIPS_GOT_PAGE, /* type */
416 0, /* rightshift */
417 2, /* size (0 = byte, 1 = short, 2 = long) */
418 16, /* bitsize */
b34976b6 419 FALSE, /* pc_relative */
252b5132 420 0, /* bitpos */
77bfe34f 421 complain_overflow_signed, /* complain_on_overflow */
30ac9238 422 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 423 "R_MIPS_GOT_PAGE", /* name */
b34976b6 424 TRUE, /* partial_inplace */
252b5132
RH
425 0x0000ffff, /* src_mask */
426 0x0000ffff, /* dst_mask */
b34976b6 427 FALSE), /* pcrel_offset */
252b5132
RH
428
429 /* Offset from page pointer in the global offset table. */
252b5132
RH
430 HOWTO (R_MIPS_GOT_OFST, /* type */
431 0, /* rightshift */
432 2, /* size (0 = byte, 1 = short, 2 = long) */
433 16, /* bitsize */
b34976b6 434 FALSE, /* pc_relative */
252b5132 435 0, /* bitpos */
77bfe34f 436 complain_overflow_signed, /* complain_on_overflow */
30ac9238 437 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 438 "R_MIPS_GOT_OFST", /* name */
b34976b6 439 TRUE, /* partial_inplace */
252b5132
RH
440 0x0000ffff, /* src_mask */
441 0x0000ffff, /* dst_mask */
b34976b6 442 FALSE), /* pcrel_offset */
252b5132
RH
443
444 /* High 16 bits of displacement in global offset table. */
252b5132
RH
445 HOWTO (R_MIPS_GOT_HI16, /* type */
446 0, /* rightshift */
447 2, /* size (0 = byte, 1 = short, 2 = long) */
448 16, /* bitsize */
b34976b6 449 FALSE, /* pc_relative */
252b5132
RH
450 0, /* bitpos */
451 complain_overflow_dont, /* complain_on_overflow */
30ac9238 452 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 453 "R_MIPS_GOT_HI16", /* name */
b34976b6 454 TRUE, /* partial_inplace */
252b5132
RH
455 0x0000ffff, /* src_mask */
456 0x0000ffff, /* dst_mask */
b34976b6 457 FALSE), /* pcrel_offset */
252b5132
RH
458
459 /* Low 16 bits of displacement in global offset table. */
252b5132
RH
460 HOWTO (R_MIPS_GOT_LO16, /* type */
461 0, /* rightshift */
462 2, /* size (0 = byte, 1 = short, 2 = long) */
463 16, /* bitsize */
b34976b6 464 FALSE, /* pc_relative */
252b5132
RH
465 0, /* bitpos */
466 complain_overflow_dont, /* complain_on_overflow */
30ac9238 467 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 468 "R_MIPS_GOT_LO16", /* name */
b34976b6 469 TRUE, /* partial_inplace */
252b5132
RH
470 0x0000ffff, /* src_mask */
471 0x0000ffff, /* dst_mask */
b34976b6 472 FALSE), /* pcrel_offset */
252b5132 473
4cc11e76 474 /* 64 bit subtraction. */
252b5132
RH
475 HOWTO (R_MIPS_SUB, /* type */
476 0, /* rightshift */
477 4, /* size (0 = byte, 1 = short, 2 = long) */
478 64, /* bitsize */
b34976b6 479 FALSE, /* pc_relative */
252b5132 480 0, /* bitpos */
77bfe34f 481 complain_overflow_dont, /* complain_on_overflow */
30ac9238 482 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 483 "R_MIPS_SUB", /* name */
b34976b6 484 TRUE, /* partial_inplace */
252b5132
RH
485 MINUS_ONE, /* src_mask */
486 MINUS_ONE, /* dst_mask */
b34976b6 487 FALSE), /* pcrel_offset */
252b5132
RH
488
489 /* Insert the addend as an instruction. */
490 /* FIXME: Not handled correctly. */
491 HOWTO (R_MIPS_INSERT_A, /* type */
492 0, /* rightshift */
77bfe34f
TS
493 2, /* size (0 = byte, 1 = short, 2 = long) */
494 32, /* bitsize */
b34976b6 495 FALSE, /* pc_relative */
252b5132
RH
496 0, /* bitpos */
497 complain_overflow_dont, /* complain_on_overflow */
30ac9238 498 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 499 "R_MIPS_INSERT_A", /* name */
b34976b6 500 TRUE, /* partial_inplace */
77bfe34f
TS
501 0xffffffff, /* src_mask */
502 0xffffffff, /* dst_mask */
b34976b6 503 FALSE), /* pcrel_offset */
252b5132
RH
504
505 /* Insert the addend as an instruction, and change all relocations
506 to refer to the old instruction at the address. */
507 /* FIXME: Not handled correctly. */
508 HOWTO (R_MIPS_INSERT_B, /* type */
509 0, /* rightshift */
77bfe34f
TS
510 2, /* size (0 = byte, 1 = short, 2 = long) */
511 32, /* bitsize */
b34976b6 512 FALSE, /* pc_relative */
252b5132
RH
513 0, /* bitpos */
514 complain_overflow_dont, /* complain_on_overflow */
30ac9238 515 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 516 "R_MIPS_INSERT_B", /* name */
b34976b6 517 TRUE, /* partial_inplace */
77bfe34f
TS
518 0xffffffff, /* src_mask */
519 0xffffffff, /* dst_mask */
b34976b6 520 FALSE), /* pcrel_offset */
252b5132
RH
521
522 /* Delete a 32 bit instruction. */
523 /* FIXME: Not handled correctly. */
524 HOWTO (R_MIPS_DELETE, /* type */
525 0, /* rightshift */
77bfe34f
TS
526 2, /* size (0 = byte, 1 = short, 2 = long) */
527 32, /* bitsize */
b34976b6 528 FALSE, /* pc_relative */
252b5132
RH
529 0, /* bitpos */
530 complain_overflow_dont, /* complain_on_overflow */
30ac9238 531 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 532 "R_MIPS_DELETE", /* name */
b34976b6 533 TRUE, /* partial_inplace */
77bfe34f
TS
534 0xffffffff, /* src_mask */
535 0xffffffff, /* dst_mask */
b34976b6 536 FALSE), /* pcrel_offset */
252b5132 537
a4382ec6
TS
538 /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
539 We don't, because
540 a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
541 R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
542 fallable heuristics.
543 b) No other NewABI toolchain actually emits such relocations. */
544 EMPTY_HOWTO (R_MIPS_HIGHER),
545 EMPTY_HOWTO (R_MIPS_HIGHEST),
252b5132
RH
546
547 /* High 16 bits of displacement in global offset table. */
252b5132
RH
548 HOWTO (R_MIPS_CALL_HI16, /* type */
549 0, /* rightshift */
550 2, /* size (0 = byte, 1 = short, 2 = long) */
551 16, /* bitsize */
b34976b6 552 FALSE, /* pc_relative */
252b5132
RH
553 0, /* bitpos */
554 complain_overflow_dont, /* complain_on_overflow */
30ac9238 555 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 556 "R_MIPS_CALL_HI16", /* name */
b34976b6 557 TRUE, /* partial_inplace */
5b6a02bc
TS
558 0x0000ffff, /* src_mask */
559 0x0000ffff, /* dst_mask */
b34976b6 560 FALSE), /* pcrel_offset */
252b5132
RH
561
562 /* Low 16 bits of displacement in global offset table. */
252b5132
RH
563 HOWTO (R_MIPS_CALL_LO16, /* type */
564 0, /* rightshift */
565 2, /* size (0 = byte, 1 = short, 2 = long) */
566 16, /* bitsize */
b34976b6 567 FALSE, /* pc_relative */
252b5132
RH
568 0, /* bitpos */
569 complain_overflow_dont, /* complain_on_overflow */
30ac9238 570 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 571 "R_MIPS_CALL_LO16", /* name */
b34976b6 572 TRUE, /* partial_inplace */
5b6a02bc
TS
573 0x0000ffff, /* src_mask */
574 0x0000ffff, /* dst_mask */
b34976b6 575 FALSE), /* pcrel_offset */
252b5132 576
5b6a02bc 577 /* Section displacement, used by an associated event location section. */
252b5132
RH
578 HOWTO (R_MIPS_SCN_DISP, /* type */
579 0, /* rightshift */
77bfe34f
TS
580 2, /* size (0 = byte, 1 = short, 2 = long) */
581 32, /* bitsize */
b34976b6 582 FALSE, /* pc_relative */
252b5132
RH
583 0, /* bitpos */
584 complain_overflow_dont, /* complain_on_overflow */
30ac9238 585 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 586 "R_MIPS_SCN_DISP", /* name */
b34976b6 587 TRUE, /* partial_inplace */
77bfe34f
TS
588 0xffffffff, /* src_mask */
589 0xffffffff, /* dst_mask */
b34976b6 590 FALSE), /* pcrel_offset */
252b5132
RH
591
592 HOWTO (R_MIPS_REL16, /* type */
593 0, /* rightshift */
77bfe34f
TS
594 1, /* size (0 = byte, 1 = short, 2 = long) */
595 16, /* bitsize */
b34976b6 596 FALSE, /* pc_relative */
252b5132 597 0, /* bitpos */
77bfe34f 598 complain_overflow_signed, /* complain_on_overflow */
30ac9238 599 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 600 "R_MIPS_REL16", /* name */
b34976b6 601 TRUE, /* partial_inplace */
77bfe34f
TS
602 0xffff, /* src_mask */
603 0xffff, /* dst_mask */
b34976b6 604 FALSE), /* pcrel_offset */
252b5132 605
77bfe34f
TS
606 /* These two are obsolete. */
607 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
608 EMPTY_HOWTO (R_MIPS_PJUMP),
252b5132 609
5b6a02bc
TS
610 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
611 It must be used for multigot GOT's (and only there). */
252b5132
RH
612 HOWTO (R_MIPS_RELGOT, /* type */
613 0, /* rightshift */
77bfe34f
TS
614 2, /* size (0 = byte, 1 = short, 2 = long) */
615 32, /* bitsize */
b34976b6 616 FALSE, /* pc_relative */
252b5132
RH
617 0, /* bitpos */
618 complain_overflow_dont, /* complain_on_overflow */
30ac9238 619 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 620 "R_MIPS_RELGOT", /* name */
b34976b6 621 TRUE, /* partial_inplace */
77bfe34f
TS
622 0xffffffff, /* src_mask */
623 0xffffffff, /* dst_mask */
b34976b6 624 FALSE), /* pcrel_offset */
d2905643 625
fe8bc63d 626 /* Protected jump conversion. This is an optimization hint. No
d2905643 627 relocation is required for correctness. */
99277196 628 HOWTO (R_MIPS_JALR, /* type */
d2905643 629 0, /* rightshift */
77bfe34f 630 2, /* size (0 = byte, 1 = short, 2 = long) */
5b6a02bc 631 32, /* bitsize */
b34976b6 632 FALSE, /* pc_relative */
d2905643
MM
633 0, /* bitpos */
634 complain_overflow_dont, /* complain_on_overflow */
30ac9238 635 _bfd_mips_elf_generic_reloc, /* special_function */
99277196 636 "R_MIPS_JALR", /* name */
b34976b6 637 FALSE, /* partial_inplace */
77bfe34f 638 0, /* src_mask */
5b6a02bc 639 0x00000000, /* dst_mask */
b34976b6 640 FALSE), /* pcrel_offset */
0f20cc35
DJ
641
642 /* TLS relocations. */
643 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
644 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
645
646 HOWTO (R_MIPS_TLS_DTPMOD64, /* type */
647 0, /* rightshift */
648 4, /* size (0 = byte, 1 = short, 2 = long) */
649 64, /* bitsize */
650 FALSE, /* pc_relative */
651 0, /* bitpos */
652 complain_overflow_dont, /* complain_on_overflow */
653 _bfd_mips_elf_generic_reloc, /* special_function */
654 "R_MIPS_TLS_DTPMOD64", /* name */
655 TRUE, /* partial_inplace */
656 MINUS_ONE, /* src_mask */
657 MINUS_ONE, /* dst_mask */
658 FALSE), /* pcrel_offset */
659
660 HOWTO (R_MIPS_TLS_DTPREL64, /* type */
661 0, /* rightshift */
662 4, /* size (0 = byte, 1 = short, 2 = long) */
663 64, /* bitsize */
664 FALSE, /* pc_relative */
665 0, /* bitpos */
666 complain_overflow_dont, /* complain_on_overflow */
667 _bfd_mips_elf_generic_reloc, /* special_function */
668 "R_MIPS_TLS_DTPREL64", /* name */
669 TRUE, /* partial_inplace */
670 MINUS_ONE, /* src_mask */
671 MINUS_ONE, /* dst_mask */
672 FALSE), /* pcrel_offset */
673
674 /* TLS general dynamic variable reference. */
675 HOWTO (R_MIPS_TLS_GD, /* type */
676 0, /* rightshift */
677 2, /* size (0 = byte, 1 = short, 2 = long) */
678 16, /* bitsize */
679 FALSE, /* pc_relative */
680 0, /* bitpos */
681 complain_overflow_signed, /* complain_on_overflow */
682 _bfd_mips_elf_generic_reloc, /* special_function */
683 "R_MIPS_TLS_GD", /* name */
684 TRUE, /* partial_inplace */
685 0x0000ffff, /* src_mask */
686 0x0000ffff, /* dst_mask */
687 FALSE), /* pcrel_offset */
688
689 /* TLS local dynamic variable reference. */
690 HOWTO (R_MIPS_TLS_LDM, /* type */
691 0, /* rightshift */
692 2, /* size (0 = byte, 1 = short, 2 = long) */
693 16, /* bitsize */
694 FALSE, /* pc_relative */
695 0, /* bitpos */
696 complain_overflow_signed, /* complain_on_overflow */
697 _bfd_mips_elf_generic_reloc, /* special_function */
698 "R_MIPS_TLS_LDM", /* name */
699 TRUE, /* partial_inplace */
700 0x0000ffff, /* src_mask */
701 0x0000ffff, /* dst_mask */
702 FALSE), /* pcrel_offset */
703
704 /* TLS local dynamic offset. */
705 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
706 0, /* rightshift */
707 2, /* size (0 = byte, 1 = short, 2 = long) */
708 16, /* bitsize */
709 FALSE, /* pc_relative */
710 0, /* bitpos */
711 complain_overflow_signed, /* complain_on_overflow */
712 _bfd_mips_elf_generic_reloc, /* special_function */
713 "R_MIPS_TLS_DTPREL_HI16", /* name */
714 TRUE, /* partial_inplace */
715 0x0000ffff, /* src_mask */
716 0x0000ffff, /* dst_mask */
717 FALSE), /* pcrel_offset */
718
719 /* TLS local dynamic offset. */
720 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
721 0, /* rightshift */
722 2, /* size (0 = byte, 1 = short, 2 = long) */
723 16, /* bitsize */
724 FALSE, /* pc_relative */
725 0, /* bitpos */
726 complain_overflow_signed, /* complain_on_overflow */
727 _bfd_mips_elf_generic_reloc, /* special_function */
728 "R_MIPS_TLS_DTPREL_LO16", /* name */
729 TRUE, /* partial_inplace */
730 0x0000ffff, /* src_mask */
731 0x0000ffff, /* dst_mask */
732 FALSE), /* pcrel_offset */
733
734 /* TLS thread pointer offset. */
735 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
736 0, /* rightshift */
737 2, /* size (0 = byte, 1 = short, 2 = long) */
738 16, /* bitsize */
739 FALSE, /* pc_relative */
740 0, /* bitpos */
741 complain_overflow_signed, /* complain_on_overflow */
742 _bfd_mips_elf_generic_reloc, /* special_function */
743 "R_MIPS_TLS_GOTTPREL", /* name */
744 TRUE, /* partial_inplace */
745 0x0000ffff, /* src_mask */
746 0x0000ffff, /* dst_mask */
747 FALSE), /* pcrel_offset */
748
749 /* TLS IE dynamic relocations. */
750 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
751
752 HOWTO (R_MIPS_TLS_TPREL64, /* type */
753 0, /* rightshift */
754 4, /* size (0 = byte, 1 = short, 2 = long) */
755 64, /* bitsize */
756 FALSE, /* pc_relative */
757 0, /* bitpos */
758 complain_overflow_dont, /* complain_on_overflow */
759 _bfd_mips_elf_generic_reloc, /* special_function */
760 "R_MIPS_TLS_TPREL64", /* name */
761 TRUE, /* partial_inplace */
762 MINUS_ONE, /* src_mask */
763 MINUS_ONE, /* dst_mask */
764 FALSE), /* pcrel_offset */
765
766 /* TLS thread pointer offset. */
767 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
768 0, /* rightshift */
769 2, /* size (0 = byte, 1 = short, 2 = long) */
770 16, /* bitsize */
771 FALSE, /* pc_relative */
772 0, /* bitpos */
773 complain_overflow_signed, /* complain_on_overflow */
774 _bfd_mips_elf_generic_reloc, /* special_function */
775 "R_MIPS_TLS_TPREL_HI16", /* name */
776 TRUE, /* partial_inplace */
777 0x0000ffff, /* src_mask */
778 0x0000ffff, /* dst_mask */
779 FALSE), /* pcrel_offset */
780
781 /* TLS thread pointer offset. */
782 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
783 0, /* rightshift */
784 2, /* size (0 = byte, 1 = short, 2 = long) */
785 16, /* bitsize */
786 FALSE, /* pc_relative */
787 0, /* bitpos */
788 complain_overflow_signed, /* complain_on_overflow */
789 _bfd_mips_elf_generic_reloc, /* special_function */
790 "R_MIPS_TLS_TPREL_LO16", /* name */
791 TRUE, /* partial_inplace */
792 0x0000ffff, /* src_mask */
793 0x0000ffff, /* dst_mask */
794 FALSE), /* pcrel_offset */
165b93e7
RS
795
796 /* 32 bit relocation with no addend. */
797 HOWTO (R_MIPS_GLOB_DAT, /* type */
798 0, /* rightshift */
799 2, /* size (0 = byte, 1 = short, 2 = long) */
800 32, /* bitsize */
801 FALSE, /* pc_relative */
802 0, /* bitpos */
803 complain_overflow_dont, /* complain_on_overflow */
804 _bfd_mips_elf_generic_reloc, /* special_function */
805 "R_MIPS_GLOB_DAT", /* name */
806 FALSE, /* partial_inplace */
807 0x0, /* src_mask */
808 0xffffffff, /* dst_mask */
809 FALSE), /* pcrel_offset */
252b5132
RH
810};
811
812/* The relocation table used for SHT_RELA sections. */
813
814static reloc_howto_type mips_elf64_howto_table_rela[] =
815{
816 /* No relocation. */
817 HOWTO (R_MIPS_NONE, /* type */
818 0, /* rightshift */
819 0, /* size (0 = byte, 1 = short, 2 = long) */
820 0, /* bitsize */
b34976b6 821 FALSE, /* pc_relative */
252b5132
RH
822 0, /* bitpos */
823 complain_overflow_dont, /* complain_on_overflow */
30ac9238 824 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 825 "R_MIPS_NONE", /* name */
b34976b6 826 FALSE, /* partial_inplace */
252b5132
RH
827 0, /* src_mask */
828 0, /* dst_mask */
b34976b6 829 FALSE), /* pcrel_offset */
252b5132
RH
830
831 /* 16 bit relocation. */
832 HOWTO (R_MIPS_16, /* type */
833 0, /* rightshift */
5b6a02bc 834 2, /* size (0 = byte, 1 = short, 2 = long) */
252b5132 835 16, /* bitsize */
b34976b6 836 FALSE, /* pc_relative */
252b5132 837 0, /* bitpos */
5b6a02bc 838 complain_overflow_signed, /* complain_on_overflow */
30ac9238 839 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 840 "R_MIPS_16", /* name */
b34976b6 841 FALSE, /* partial_inplace */
252b5132 842 0, /* src_mask */
5b6a02bc 843 0x0000ffff, /* dst_mask */
b34976b6 844 FALSE), /* pcrel_offset */
252b5132
RH
845
846 /* 32 bit relocation. */
847 HOWTO (R_MIPS_32, /* type */
848 0, /* rightshift */
849 2, /* size (0 = byte, 1 = short, 2 = long) */
850 32, /* bitsize */
b34976b6 851 FALSE, /* pc_relative */
252b5132 852 0, /* bitpos */
77bfe34f 853 complain_overflow_dont, /* complain_on_overflow */
30ac9238 854 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 855 "R_MIPS_32", /* name */
b34976b6 856 FALSE, /* partial_inplace */
252b5132
RH
857 0, /* src_mask */
858 0xffffffff, /* dst_mask */
b34976b6 859 FALSE), /* pcrel_offset */
252b5132
RH
860
861 /* 32 bit symbol relative relocation. */
862 HOWTO (R_MIPS_REL32, /* type */
863 0, /* rightshift */
864 2, /* size (0 = byte, 1 = short, 2 = long) */
865 32, /* bitsize */
b34976b6 866 FALSE, /* pc_relative */
252b5132 867 0, /* bitpos */
77bfe34f 868 complain_overflow_dont, /* complain_on_overflow */
30ac9238 869 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 870 "R_MIPS_REL32", /* name */
b34976b6 871 FALSE, /* partial_inplace */
252b5132
RH
872 0, /* src_mask */
873 0xffffffff, /* dst_mask */
b34976b6 874 FALSE), /* pcrel_offset */
252b5132 875
77bfe34f 876 /* 26 bit jump address. */
252b5132
RH
877 HOWTO (R_MIPS_26, /* type */
878 2, /* rightshift */
879 2, /* size (0 = byte, 1 = short, 2 = long) */
880 26, /* bitsize */
b34976b6 881 FALSE, /* pc_relative */
252b5132
RH
882 0, /* bitpos */
883 complain_overflow_dont, /* complain_on_overflow */
56fc028e 884 /* This needs complex overflow
77bfe34f 885 detection, because the upper 36
b401d8e5 886 bits must match the PC + 4. */
30ac9238 887 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 888 "R_MIPS_26", /* name */
b34976b6 889 FALSE, /* partial_inplace */
252b5132 890 0, /* src_mask */
5b6a02bc 891 0x03ffffff, /* dst_mask */
b34976b6 892 FALSE), /* pcrel_offset */
252b5132
RH
893
894 /* High 16 bits of symbol value. */
895 HOWTO (R_MIPS_HI16, /* type */
896 0, /* rightshift */
897 2, /* size (0 = byte, 1 = short, 2 = long) */
898 16, /* bitsize */
b34976b6 899 FALSE, /* pc_relative */
252b5132
RH
900 0, /* bitpos */
901 complain_overflow_dont, /* complain_on_overflow */
30ac9238 902 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 903 "R_MIPS_HI16", /* name */
b34976b6 904 FALSE, /* partial_inplace */
252b5132 905 0, /* src_mask */
5b6a02bc 906 0x0000ffff, /* dst_mask */
b34976b6 907 FALSE), /* pcrel_offset */
252b5132
RH
908
909 /* Low 16 bits of symbol value. */
910 HOWTO (R_MIPS_LO16, /* type */
911 0, /* rightshift */
912 2, /* size (0 = byte, 1 = short, 2 = long) */
913 16, /* bitsize */
b34976b6 914 FALSE, /* pc_relative */
252b5132
RH
915 0, /* bitpos */
916 complain_overflow_dont, /* complain_on_overflow */
30ac9238 917 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 918 "R_MIPS_LO16", /* name */
b34976b6 919 FALSE, /* partial_inplace */
252b5132 920 0, /* src_mask */
5b6a02bc 921 0x0000ffff, /* dst_mask */
b34976b6 922 FALSE), /* pcrel_offset */
252b5132
RH
923
924 /* GP relative reference. */
925 HOWTO (R_MIPS_GPREL16, /* type */
926 0, /* rightshift */
927 2, /* size (0 = byte, 1 = short, 2 = long) */
928 16, /* bitsize */
b34976b6 929 FALSE, /* pc_relative */
252b5132
RH
930 0, /* bitpos */
931 complain_overflow_signed, /* complain_on_overflow */
a4382ec6 932 mips_elf64_gprel16_reloc, /* special_function */
252b5132 933 "R_MIPS_GPREL16", /* name */
b34976b6 934 FALSE, /* partial_inplace */
252b5132 935 0, /* src_mask */
5b6a02bc 936 0x0000ffff, /* dst_mask */
b34976b6 937 FALSE), /* pcrel_offset */
252b5132
RH
938
939 /* Reference to literal section. */
940 HOWTO (R_MIPS_LITERAL, /* type */
941 0, /* rightshift */
942 2, /* size (0 = byte, 1 = short, 2 = long) */
943 16, /* bitsize */
b34976b6 944 FALSE, /* pc_relative */
252b5132
RH
945 0, /* bitpos */
946 complain_overflow_signed, /* complain_on_overflow */
5b6a02bc 947 mips_elf64_literal_reloc, /* special_function */
252b5132 948 "R_MIPS_LITERAL", /* name */
b34976b6 949 FALSE, /* partial_inplace */
252b5132 950 0, /* src_mask */
5b6a02bc 951 0x0000ffff, /* dst_mask */
b34976b6 952 FALSE), /* pcrel_offset */
252b5132
RH
953
954 /* Reference to global offset table. */
252b5132
RH
955 HOWTO (R_MIPS_GOT16, /* type */
956 0, /* rightshift */
957 2, /* size (0 = byte, 1 = short, 2 = long) */
958 16, /* bitsize */
b34976b6 959 FALSE, /* pc_relative */
252b5132
RH
960 0, /* bitpos */
961 complain_overflow_signed, /* complain_on_overflow */
30ac9238 962 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 963 "R_MIPS_GOT16", /* name */
b34976b6 964 FALSE, /* partial_inplace */
252b5132 965 0, /* src_mask */
5b6a02bc 966 0x0000ffff, /* dst_mask */
b34976b6 967 FALSE), /* pcrel_offset */
252b5132 968
bad36eac
DJ
969 /* 16 bit PC relative reference. Note that the ABI document has a typo
970 and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
971 We do the right thing here. */
252b5132 972 HOWTO (R_MIPS_PC16, /* type */
bad36eac 973 2, /* rightshift */
252b5132
RH
974 2, /* size (0 = byte, 1 = short, 2 = long) */
975 16, /* bitsize */
b34976b6 976 TRUE, /* pc_relative */
252b5132
RH
977 0, /* bitpos */
978 complain_overflow_signed, /* complain_on_overflow */
30ac9238 979 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 980 "R_MIPS_PC16", /* name */
b34976b6 981 FALSE, /* partial_inplace */
252b5132 982 0, /* src_mask */
5b6a02bc 983 0x0000ffff, /* dst_mask */
b34976b6 984 TRUE), /* pcrel_offset */
252b5132
RH
985
986 /* 16 bit call through global offset table. */
252b5132
RH
987 HOWTO (R_MIPS_CALL16, /* type */
988 0, /* rightshift */
989 2, /* size (0 = byte, 1 = short, 2 = long) */
990 16, /* bitsize */
b34976b6 991 FALSE, /* pc_relative */
252b5132
RH
992 0, /* bitpos */
993 complain_overflow_signed, /* complain_on_overflow */
30ac9238 994 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 995 "R_MIPS_CALL16", /* name */
b34976b6 996 FALSE, /* partial_inplace */
252b5132 997 0, /* src_mask */
5b6a02bc 998 0x0000ffff, /* dst_mask */
b34976b6 999 FALSE), /* pcrel_offset */
252b5132
RH
1000
1001 /* 32 bit GP relative reference. */
1002 HOWTO (R_MIPS_GPREL32, /* type */
1003 0, /* rightshift */
1004 2, /* size (0 = byte, 1 = short, 2 = long) */
1005 32, /* bitsize */
b34976b6 1006 FALSE, /* pc_relative */
252b5132 1007 0, /* bitpos */
5b6a02bc
TS
1008 complain_overflow_dont, /* complain_on_overflow */
1009 mips_elf64_gprel32_reloc, /* special_function */
252b5132 1010 "R_MIPS_GPREL32", /* name */
b34976b6 1011 FALSE, /* partial_inplace */
252b5132
RH
1012 0, /* src_mask */
1013 0xffffffff, /* dst_mask */
b34976b6 1014 FALSE), /* pcrel_offset */
252b5132 1015
a4382ec6
TS
1016 EMPTY_HOWTO (13),
1017 EMPTY_HOWTO (14),
1018 EMPTY_HOWTO (15),
252b5132
RH
1019
1020 /* A 5 bit shift field. */
1021 HOWTO (R_MIPS_SHIFT5, /* type */
1022 0, /* rightshift */
1023 2, /* size (0 = byte, 1 = short, 2 = long) */
1024 5, /* bitsize */
b34976b6 1025 FALSE, /* pc_relative */
252b5132
RH
1026 6, /* bitpos */
1027 complain_overflow_bitfield, /* complain_on_overflow */
30ac9238 1028 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1029 "R_MIPS_SHIFT5", /* name */
b34976b6 1030 FALSE, /* partial_inplace */
252b5132
RH
1031 0, /* src_mask */
1032 0x000007c0, /* dst_mask */
b34976b6 1033 FALSE), /* pcrel_offset */
252b5132
RH
1034
1035 /* A 6 bit shift field. */
252b5132
RH
1036 HOWTO (R_MIPS_SHIFT6, /* type */
1037 0, /* rightshift */
1038 2, /* size (0 = byte, 1 = short, 2 = long) */
1039 6, /* bitsize */
b34976b6 1040 FALSE, /* pc_relative */
252b5132
RH
1041 6, /* bitpos */
1042 complain_overflow_bitfield, /* complain_on_overflow */
5b6a02bc 1043 mips_elf64_shift6_reloc, /* special_function */
252b5132 1044 "R_MIPS_SHIFT6", /* name */
b34976b6 1045 FALSE, /* partial_inplace */
252b5132
RH
1046 0, /* src_mask */
1047 0x000007c4, /* dst_mask */
b34976b6 1048 FALSE), /* pcrel_offset */
252b5132
RH
1049
1050 /* 64 bit relocation. */
1051 HOWTO (R_MIPS_64, /* type */
1052 0, /* rightshift */
1053 4, /* size (0 = byte, 1 = short, 2 = long) */
1054 64, /* bitsize */
b34976b6 1055 FALSE, /* pc_relative */
252b5132 1056 0, /* bitpos */
77bfe34f 1057 complain_overflow_dont, /* complain_on_overflow */
30ac9238 1058 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1059 "R_MIPS_64", /* name */
b34976b6 1060 FALSE, /* partial_inplace */
252b5132
RH
1061 0, /* src_mask */
1062 MINUS_ONE, /* dst_mask */
b34976b6 1063 FALSE), /* pcrel_offset */
252b5132
RH
1064
1065 /* Displacement in the global offset table. */
252b5132
RH
1066 HOWTO (R_MIPS_GOT_DISP, /* type */
1067 0, /* rightshift */
1068 2, /* size (0 = byte, 1 = short, 2 = long) */
1069 16, /* bitsize */
b34976b6 1070 FALSE, /* pc_relative */
252b5132 1071 0, /* bitpos */
77bfe34f 1072 complain_overflow_signed, /* complain_on_overflow */
30ac9238 1073 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1074 "R_MIPS_GOT_DISP", /* name */
b34976b6 1075 FALSE, /* partial_inplace */
252b5132
RH
1076 0, /* src_mask */
1077 0x0000ffff, /* dst_mask */
b34976b6 1078 FALSE), /* pcrel_offset */
252b5132
RH
1079
1080 /* Displacement to page pointer in the global offset table. */
252b5132
RH
1081 HOWTO (R_MIPS_GOT_PAGE, /* type */
1082 0, /* rightshift */
1083 2, /* size (0 = byte, 1 = short, 2 = long) */
1084 16, /* bitsize */
b34976b6 1085 FALSE, /* pc_relative */
252b5132 1086 0, /* bitpos */
77bfe34f 1087 complain_overflow_signed, /* complain_on_overflow */
30ac9238 1088 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1089 "R_MIPS_GOT_PAGE", /* name */
b34976b6 1090 FALSE, /* partial_inplace */
252b5132
RH
1091 0, /* src_mask */
1092 0x0000ffff, /* dst_mask */
b34976b6 1093 FALSE), /* pcrel_offset */
252b5132
RH
1094
1095 /* Offset from page pointer in the global offset table. */
252b5132
RH
1096 HOWTO (R_MIPS_GOT_OFST, /* type */
1097 0, /* rightshift */
1098 2, /* size (0 = byte, 1 = short, 2 = long) */
1099 16, /* bitsize */
b34976b6 1100 FALSE, /* pc_relative */
252b5132 1101 0, /* bitpos */
77bfe34f 1102 complain_overflow_signed, /* complain_on_overflow */
30ac9238 1103 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1104 "R_MIPS_GOT_OFST", /* name */
b34976b6 1105 FALSE, /* partial_inplace */
252b5132
RH
1106 0, /* src_mask */
1107 0x0000ffff, /* dst_mask */
b34976b6 1108 FALSE), /* pcrel_offset */
252b5132
RH
1109
1110 /* High 16 bits of displacement in global offset table. */
252b5132
RH
1111 HOWTO (R_MIPS_GOT_HI16, /* type */
1112 0, /* rightshift */
1113 2, /* size (0 = byte, 1 = short, 2 = long) */
1114 16, /* bitsize */
b34976b6 1115 FALSE, /* pc_relative */
252b5132
RH
1116 0, /* bitpos */
1117 complain_overflow_dont, /* complain_on_overflow */
30ac9238 1118 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1119 "R_MIPS_GOT_HI16", /* name */
b34976b6 1120 FALSE, /* partial_inplace */
252b5132
RH
1121 0, /* src_mask */
1122 0x0000ffff, /* dst_mask */
b34976b6 1123 FALSE), /* pcrel_offset */
252b5132
RH
1124
1125 /* Low 16 bits of displacement in global offset table. */
252b5132
RH
1126 HOWTO (R_MIPS_GOT_LO16, /* type */
1127 0, /* rightshift */
1128 2, /* size (0 = byte, 1 = short, 2 = long) */
1129 16, /* bitsize */
b34976b6 1130 FALSE, /* pc_relative */
252b5132
RH
1131 0, /* bitpos */
1132 complain_overflow_dont, /* complain_on_overflow */
30ac9238 1133 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1134 "R_MIPS_GOT_LO16", /* name */
b34976b6 1135 FALSE, /* partial_inplace */
252b5132
RH
1136 0, /* src_mask */
1137 0x0000ffff, /* dst_mask */
b34976b6 1138 FALSE), /* pcrel_offset */
252b5132 1139
4cc11e76 1140 /* 64 bit subtraction. */
252b5132
RH
1141 HOWTO (R_MIPS_SUB, /* type */
1142 0, /* rightshift */
1143 4, /* size (0 = byte, 1 = short, 2 = long) */
1144 64, /* bitsize */
b34976b6 1145 FALSE, /* pc_relative */
252b5132 1146 0, /* bitpos */
77bfe34f 1147 complain_overflow_dont, /* complain_on_overflow */
30ac9238 1148 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1149 "R_MIPS_SUB", /* name */
b34976b6 1150 FALSE, /* partial_inplace */
252b5132
RH
1151 0, /* src_mask */
1152 MINUS_ONE, /* dst_mask */
b34976b6 1153 FALSE), /* pcrel_offset */
252b5132
RH
1154
1155 /* Insert the addend as an instruction. */
1156 /* FIXME: Not handled correctly. */
1157 HOWTO (R_MIPS_INSERT_A, /* type */
1158 0, /* rightshift */
77bfe34f
TS
1159 2, /* size (0 = byte, 1 = short, 2 = long) */
1160 32, /* bitsize */
b34976b6 1161 FALSE, /* pc_relative */
252b5132
RH
1162 0, /* bitpos */
1163 complain_overflow_dont, /* complain_on_overflow */
30ac9238 1164 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1165 "R_MIPS_INSERT_A", /* name */
b34976b6 1166 FALSE, /* partial_inplace */
252b5132 1167 0, /* src_mask */
77bfe34f 1168 0xffffffff, /* dst_mask */
b34976b6 1169 FALSE), /* pcrel_offset */
252b5132
RH
1170
1171 /* Insert the addend as an instruction, and change all relocations
1172 to refer to the old instruction at the address. */
1173 /* FIXME: Not handled correctly. */
1174 HOWTO (R_MIPS_INSERT_B, /* type */
1175 0, /* rightshift */
77bfe34f
TS
1176 2, /* size (0 = byte, 1 = short, 2 = long) */
1177 32, /* bitsize */
b34976b6 1178 FALSE, /* pc_relative */
252b5132
RH
1179 0, /* bitpos */
1180 complain_overflow_dont, /* complain_on_overflow */
30ac9238 1181 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1182 "R_MIPS_INSERT_B", /* name */
b34976b6 1183 FALSE, /* partial_inplace */
252b5132 1184 0, /* src_mask */
77bfe34f 1185 0xffffffff, /* dst_mask */
b34976b6 1186 FALSE), /* pcrel_offset */
252b5132
RH
1187
1188 /* Delete a 32 bit instruction. */
1189 /* FIXME: Not handled correctly. */
1190 HOWTO (R_MIPS_DELETE, /* type */
1191 0, /* rightshift */
77bfe34f
TS
1192 2, /* size (0 = byte, 1 = short, 2 = long) */
1193 32, /* bitsize */
b34976b6 1194 FALSE, /* pc_relative */
252b5132
RH
1195 0, /* bitpos */
1196 complain_overflow_dont, /* complain_on_overflow */
30ac9238 1197 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1198 "R_MIPS_DELETE", /* name */
b34976b6 1199 FALSE, /* partial_inplace */
252b5132 1200 0, /* src_mask */
77bfe34f 1201 0xffffffff, /* dst_mask */
b34976b6 1202 FALSE), /* pcrel_offset */
252b5132
RH
1203
1204 /* Get the higher value of a 64 bit addend. */
252b5132
RH
1205 HOWTO (R_MIPS_HIGHER, /* type */
1206 0, /* rightshift */
1207 2, /* size (0 = byte, 1 = short, 2 = long) */
1208 16, /* bitsize */
b34976b6 1209 FALSE, /* pc_relative */
252b5132
RH
1210 0, /* bitpos */
1211 complain_overflow_dont, /* complain_on_overflow */
30ac9238 1212 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1213 "R_MIPS_HIGHER", /* name */
b34976b6 1214 FALSE, /* partial_inplace */
252b5132 1215 0, /* src_mask */
5b6a02bc 1216 0x0000ffff, /* dst_mask */
b34976b6 1217 FALSE), /* pcrel_offset */
252b5132
RH
1218
1219 /* Get the highest value of a 64 bit addend. */
252b5132
RH
1220 HOWTO (R_MIPS_HIGHEST, /* type */
1221 0, /* rightshift */
1222 2, /* size (0 = byte, 1 = short, 2 = long) */
1223 16, /* bitsize */
b34976b6 1224 FALSE, /* pc_relative */
252b5132
RH
1225 0, /* bitpos */
1226 complain_overflow_dont, /* complain_on_overflow */
30ac9238 1227 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1228 "R_MIPS_HIGHEST", /* name */
b34976b6 1229 FALSE, /* partial_inplace */
252b5132 1230 0, /* src_mask */
5b6a02bc 1231 0x0000ffff, /* dst_mask */
b34976b6 1232 FALSE), /* pcrel_offset */
252b5132
RH
1233
1234 /* High 16 bits of displacement in global offset table. */
252b5132
RH
1235 HOWTO (R_MIPS_CALL_HI16, /* type */
1236 0, /* rightshift */
1237 2, /* size (0 = byte, 1 = short, 2 = long) */
1238 16, /* bitsize */
b34976b6 1239 FALSE, /* pc_relative */
252b5132
RH
1240 0, /* bitpos */
1241 complain_overflow_dont, /* complain_on_overflow */
30ac9238 1242 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1243 "R_MIPS_CALL_HI16", /* name */
b34976b6 1244 FALSE, /* partial_inplace */
252b5132 1245 0, /* src_mask */
5b6a02bc 1246 0x0000ffff, /* dst_mask */
b34976b6 1247 FALSE), /* pcrel_offset */
252b5132
RH
1248
1249 /* Low 16 bits of displacement in global offset table. */
252b5132
RH
1250 HOWTO (R_MIPS_CALL_LO16, /* type */
1251 0, /* rightshift */
1252 2, /* size (0 = byte, 1 = short, 2 = long) */
1253 16, /* bitsize */
b34976b6 1254 FALSE, /* pc_relative */
252b5132
RH
1255 0, /* bitpos */
1256 complain_overflow_dont, /* complain_on_overflow */
30ac9238 1257 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1258 "R_MIPS_CALL_LO16", /* name */
b34976b6 1259 FALSE, /* partial_inplace */
252b5132 1260 0, /* src_mask */
5b6a02bc 1261 0x0000ffff, /* dst_mask */
b34976b6 1262 FALSE), /* pcrel_offset */
252b5132 1263
5b6a02bc 1264 /* Section displacement, used by an associated event location section. */
252b5132
RH
1265 HOWTO (R_MIPS_SCN_DISP, /* type */
1266 0, /* rightshift */
77bfe34f
TS
1267 2, /* size (0 = byte, 1 = short, 2 = long) */
1268 32, /* bitsize */
b34976b6 1269 FALSE, /* pc_relative */
252b5132
RH
1270 0, /* bitpos */
1271 complain_overflow_dont, /* complain_on_overflow */
30ac9238 1272 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1273 "R_MIPS_SCN_DISP", /* name */
b34976b6 1274 FALSE, /* partial_inplace */
252b5132 1275 0, /* src_mask */
77bfe34f 1276 0xffffffff, /* dst_mask */
b34976b6 1277 FALSE), /* pcrel_offset */
252b5132
RH
1278
1279 HOWTO (R_MIPS_REL16, /* type */
1280 0, /* rightshift */
77bfe34f
TS
1281 1, /* size (0 = byte, 1 = short, 2 = long) */
1282 16, /* bitsize */
b34976b6 1283 FALSE, /* pc_relative */
252b5132 1284 0, /* bitpos */
77bfe34f 1285 complain_overflow_signed, /* complain_on_overflow */
30ac9238 1286 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1287 "R_MIPS_REL16", /* name */
b34976b6 1288 FALSE, /* partial_inplace */
252b5132 1289 0, /* src_mask */
77bfe34f 1290 0xffff, /* dst_mask */
b34976b6 1291 FALSE), /* pcrel_offset */
252b5132 1292
77bfe34f
TS
1293 /* These two are obsolete. */
1294 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1295 EMPTY_HOWTO (R_MIPS_PJUMP),
252b5132 1296
5b6a02bc
TS
1297 /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1298 It must be used for multigot GOT's (and only there). */
252b5132
RH
1299 HOWTO (R_MIPS_RELGOT, /* type */
1300 0, /* rightshift */
77bfe34f
TS
1301 2, /* size (0 = byte, 1 = short, 2 = long) */
1302 32, /* bitsize */
b34976b6 1303 FALSE, /* pc_relative */
252b5132
RH
1304 0, /* bitpos */
1305 complain_overflow_dont, /* complain_on_overflow */
30ac9238 1306 _bfd_mips_elf_generic_reloc, /* special_function */
252b5132 1307 "R_MIPS_RELGOT", /* name */
b34976b6 1308 FALSE, /* partial_inplace */
252b5132 1309 0, /* src_mask */
77bfe34f 1310 0xffffffff, /* dst_mask */
b34976b6 1311 FALSE), /* pcrel_offset */
d2905643 1312
fe8bc63d 1313 /* Protected jump conversion. This is an optimization hint. No
d2905643 1314 relocation is required for correctness. */
99277196 1315 HOWTO (R_MIPS_JALR, /* type */
d2905643 1316 0, /* rightshift */
77bfe34f 1317 2, /* size (0 = byte, 1 = short, 2 = long) */
5b6a02bc 1318 32, /* bitsize */
b34976b6 1319 FALSE, /* pc_relative */
d2905643
MM
1320 0, /* bitpos */
1321 complain_overflow_dont, /* complain_on_overflow */
30ac9238 1322 _bfd_mips_elf_generic_reloc, /* special_function */
99277196 1323 "R_MIPS_JALR", /* name */
b34976b6 1324 FALSE, /* partial_inplace */
77bfe34f 1325 0, /* src_mask */
5b6a02bc 1326 0x00000000, /* dst_mask */
b34976b6 1327 FALSE), /* pcrel_offset */
0f20cc35
DJ
1328
1329 /* TLS relocations. */
1330 EMPTY_HOWTO (R_MIPS_TLS_DTPMOD32),
1331 EMPTY_HOWTO (R_MIPS_TLS_DTPREL32),
fcbc2f09
MR
1332
1333 HOWTO (R_MIPS_TLS_DTPMOD64, /* 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_DTPMOD64", /* name */
667bf02a 1342 FALSE, /* partial_inplace */
72c4ab07 1343 0, /* src_mask */
fcbc2f09
MR
1344 MINUS_ONE, /* dst_mask */
1345 FALSE), /* pcrel_offset */
741d6ea8
JM
1346
1347 HOWTO (R_MIPS_TLS_DTPREL64, /* type */
1348 0, /* rightshift */
1349 4, /* size (0 = byte, 1 = short, 2 = long) */
1350 64, /* bitsize */
1351 FALSE, /* pc_relative */
1352 0, /* bitpos */
1353 complain_overflow_dont, /* complain_on_overflow */
1354 _bfd_mips_elf_generic_reloc, /* special_function */
1355 "R_MIPS_TLS_DTPREL64", /* name */
667bf02a 1356 FALSE, /* partial_inplace */
72c4ab07 1357 0, /* src_mask */
741d6ea8
JM
1358 MINUS_ONE, /* dst_mask */
1359 FALSE), /* pcrel_offset */
0f20cc35
DJ
1360
1361 /* TLS general dynamic variable reference. */
1362 HOWTO (R_MIPS_TLS_GD, /* type */
1363 0, /* rightshift */
1364 2, /* size (0 = byte, 1 = short, 2 = long) */
1365 16, /* bitsize */
1366 FALSE, /* pc_relative */
1367 0, /* bitpos */
1368 complain_overflow_signed, /* complain_on_overflow */
1369 _bfd_mips_elf_generic_reloc, /* special_function */
1370 "R_MIPS_TLS_GD", /* name */
667bf02a 1371 FALSE, /* partial_inplace */
72c4ab07 1372 0, /* src_mask */
0f20cc35
DJ
1373 0x0000ffff, /* dst_mask */
1374 FALSE), /* pcrel_offset */
1375
1376 /* TLS local dynamic variable reference. */
1377 HOWTO (R_MIPS_TLS_LDM, /* type */
1378 0, /* rightshift */
1379 2, /* size (0 = byte, 1 = short, 2 = long) */
1380 16, /* bitsize */
1381 FALSE, /* pc_relative */
1382 0, /* bitpos */
1383 complain_overflow_signed, /* complain_on_overflow */
1384 _bfd_mips_elf_generic_reloc, /* special_function */
1385 "R_MIPS_TLS_LDM", /* name */
667bf02a 1386 FALSE, /* partial_inplace */
72c4ab07 1387 0, /* src_mask */
0f20cc35
DJ
1388 0x0000ffff, /* dst_mask */
1389 FALSE), /* pcrel_offset */
1390
1391 /* TLS local dynamic offset. */
1392 HOWTO (R_MIPS_TLS_DTPREL_HI16, /* type */
1393 0, /* rightshift */
1394 2, /* size (0 = byte, 1 = short, 2 = long) */
1395 16, /* bitsize */
1396 FALSE, /* pc_relative */
1397 0, /* bitpos */
1398 complain_overflow_signed, /* complain_on_overflow */
1399 _bfd_mips_elf_generic_reloc, /* special_function */
1400 "R_MIPS_TLS_DTPREL_HI16", /* name */
667bf02a 1401 FALSE, /* partial_inplace */
72c4ab07 1402 0, /* src_mask */
0f20cc35
DJ
1403 0x0000ffff, /* dst_mask */
1404 FALSE), /* pcrel_offset */
1405
1406 /* TLS local dynamic offset. */
1407 HOWTO (R_MIPS_TLS_DTPREL_LO16, /* type */
1408 0, /* rightshift */
1409 2, /* size (0 = byte, 1 = short, 2 = long) */
1410 16, /* bitsize */
1411 FALSE, /* pc_relative */
1412 0, /* bitpos */
1413 complain_overflow_signed, /* complain_on_overflow */
1414 _bfd_mips_elf_generic_reloc, /* special_function */
1415 "R_MIPS_TLS_DTPREL_LO16", /* name */
667bf02a 1416 FALSE, /* partial_inplace */
72c4ab07 1417 0, /* src_mask */
0f20cc35
DJ
1418 0x0000ffff, /* dst_mask */
1419 FALSE), /* pcrel_offset */
1420
1421 /* TLS thread pointer offset. */
1422 HOWTO (R_MIPS_TLS_GOTTPREL, /* type */
1423 0, /* rightshift */
1424 2, /* size (0 = byte, 1 = short, 2 = long) */
1425 16, /* bitsize */
1426 FALSE, /* pc_relative */
1427 0, /* bitpos */
1428 complain_overflow_signed, /* complain_on_overflow */
1429 _bfd_mips_elf_generic_reloc, /* special_function */
1430 "R_MIPS_TLS_GOTTPREL", /* name */
667bf02a 1431 FALSE, /* partial_inplace */
72c4ab07 1432 0, /* src_mask */
0f20cc35
DJ
1433 0x0000ffff, /* dst_mask */
1434 FALSE), /* pcrel_offset */
1435
fcbc2f09 1436 /* TLS IE dynamic relocations. */
0f20cc35 1437 EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
fcbc2f09
MR
1438
1439 HOWTO (R_MIPS_TLS_TPREL64, /* type */
1440 0, /* rightshift */
1441 4, /* size (0 = byte, 1 = short, 2 = long) */
1442 64, /* bitsize */
1443 FALSE, /* pc_relative */
1444 0, /* bitpos */
1445 complain_overflow_dont, /* complain_on_overflow */
1446 _bfd_mips_elf_generic_reloc, /* special_function */
1447 "R_MIPS_TLS_TPREL64", /* name */
667bf02a 1448 FALSE, /* partial_inplace */
72c4ab07 1449 0, /* src_mask */
fcbc2f09
MR
1450 MINUS_ONE, /* dst_mask */
1451 FALSE), /* pcrel_offset */
0f20cc35
DJ
1452
1453 /* TLS thread pointer offset. */
1454 HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
1455 0, /* rightshift */
1456 2, /* size (0 = byte, 1 = short, 2 = long) */
1457 16, /* bitsize */
1458 FALSE, /* pc_relative */
1459 0, /* bitpos */
1460 complain_overflow_signed, /* complain_on_overflow */
1461 _bfd_mips_elf_generic_reloc, /* special_function */
1462 "R_MIPS_TLS_TPREL_HI16", /* name */
667bf02a 1463 FALSE, /* partial_inplace */
72c4ab07 1464 0, /* src_mask */
0f20cc35
DJ
1465 0x0000ffff, /* dst_mask */
1466 FALSE), /* pcrel_offset */
1467
1468 /* TLS thread pointer offset. */
1469 HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
1470 0, /* rightshift */
1471 2, /* size (0 = byte, 1 = short, 2 = long) */
1472 16, /* bitsize */
1473 FALSE, /* pc_relative */
1474 0, /* bitpos */
1475 complain_overflow_signed, /* complain_on_overflow */
1476 _bfd_mips_elf_generic_reloc, /* special_function */
1477 "R_MIPS_TLS_TPREL_LO16", /* name */
667bf02a 1478 FALSE, /* partial_inplace */
72c4ab07 1479 0, /* src_mask */
0f20cc35
DJ
1480 0x0000ffff, /* dst_mask */
1481 FALSE), /* pcrel_offset */
165b93e7
RS
1482
1483 /* 32 bit relocation with no addend. */
1484 HOWTO (R_MIPS_GLOB_DAT, /* type */
1485 0, /* rightshift */
1486 2, /* size (0 = byte, 1 = short, 2 = long) */
1487 32, /* bitsize */
1488 FALSE, /* pc_relative */
1489 0, /* bitpos */
1490 complain_overflow_dont, /* complain_on_overflow */
1491 _bfd_mips_elf_generic_reloc, /* special_function */
1492 "R_MIPS_GLOB_DAT", /* name */
1493 FALSE, /* partial_inplace */
1494 0x0, /* src_mask */
1495 0xffffffff, /* dst_mask */
1496 FALSE), /* pcrel_offset */
252b5132 1497};
a4382ec6 1498
d6f16593
MR
1499static reloc_howto_type mips16_elf64_howto_table_rel[] =
1500{
1501 /* The reloc used for the mips16 jump instruction. */
a4382ec6
TS
1502 HOWTO (R_MIPS16_26, /* type */
1503 2, /* rightshift */
1504 2, /* size (0 = byte, 1 = short, 2 = long) */
1505 26, /* bitsize */
b34976b6 1506 FALSE, /* pc_relative */
a4382ec6
TS
1507 0, /* bitpos */
1508 complain_overflow_dont, /* complain_on_overflow */
1509 /* This needs complex overflow
1510 detection, because the upper four
1511 bits must match the PC. */
35d3d567 1512 _bfd_mips_elf_generic_reloc, /* special_function */
a4382ec6 1513 "R_MIPS16_26", /* name */
b34976b6 1514 TRUE, /* partial_inplace */
a4382ec6
TS
1515 0x3ffffff, /* src_mask */
1516 0x3ffffff, /* dst_mask */
d6f16593 1517 FALSE), /* pcrel_offset */
a4382ec6 1518
d6f16593 1519 /* The reloc used for the mips16 gprel instruction. */
a4382ec6
TS
1520 HOWTO (R_MIPS16_GPREL, /* type */
1521 0, /* rightshift */
1522 2, /* size (0 = byte, 1 = short, 2 = long) */
1523 16, /* bitsize */
b34976b6 1524 FALSE, /* pc_relative */
a4382ec6
TS
1525 0, /* bitpos */
1526 complain_overflow_signed, /* complain_on_overflow */
1527 mips16_gprel_reloc, /* special_function */
1528 "R_MIPS16_GPREL", /* name */
b34976b6 1529 TRUE, /* partial_inplace */
d6f16593
MR
1530 0x0000ffff, /* src_mask */
1531 0x0000ffff, /* dst_mask */
1532 FALSE), /* pcrel_offset */
1533
738e5348
RS
1534 /* A MIPS16 reference to the global offset table. */
1535 HOWTO (R_MIPS16_GOT16, /* type */
1536 0, /* rightshift */
1537 2, /* size (0 = byte, 1 = short, 2 = long) */
1538 16, /* bitsize */
1539 FALSE, /* pc_relative */
1540 0, /* bitpos */
1541 complain_overflow_dont, /* complain_on_overflow */
1542 _bfd_mips_elf_got16_reloc, /* special_function */
1543 "R_MIPS16_GOT16", /* name */
1544 TRUE, /* partial_inplace */
1545 0x0000ffff, /* src_mask */
1546 0x0000ffff, /* dst_mask */
1547 FALSE), /* pcrel_offset */
d6f16593 1548
738e5348
RS
1549 /* A MIPS16 call through the global offset table. */
1550 HOWTO (R_MIPS16_CALL16, /* type */
1551 0, /* rightshift */
1552 2, /* size (0 = byte, 1 = short, 2 = long) */
1553 16, /* bitsize */
1554 FALSE, /* pc_relative */
1555 0, /* bitpos */
1556 complain_overflow_dont, /* complain_on_overflow */
1557 _bfd_mips_elf_generic_reloc, /* special_function */
1558 "R_MIPS16_CALL16", /* name */
1559 TRUE, /* partial_inplace */
1560 0x0000ffff, /* src_mask */
1561 0x0000ffff, /* dst_mask */
1562 FALSE), /* pcrel_offset */
d6f16593
MR
1563
1564 /* MIPS16 high 16 bits of symbol value. */
1565 HOWTO (R_MIPS16_HI16, /* type */
1566 16, /* rightshift */
1567 2, /* size (0 = byte, 1 = short, 2 = long) */
1568 16, /* bitsize */
1569 FALSE, /* pc_relative */
1570 0, /* bitpos */
1571 complain_overflow_dont, /* complain_on_overflow */
1572 _bfd_mips_elf_hi16_reloc, /* special_function */
1573 "R_MIPS16_HI16", /* name */
1574 TRUE, /* partial_inplace */
1575 0x0000ffff, /* src_mask */
1576 0x0000ffff, /* dst_mask */
1577 FALSE), /* pcrel_offset */
1578
1579 /* MIPS16 low 16 bits of symbol value. */
1580 HOWTO (R_MIPS16_LO16, /* type */
1581 0, /* rightshift */
1582 2, /* size (0 = byte, 1 = short, 2 = long) */
1583 16, /* bitsize */
1584 FALSE, /* pc_relative */
1585 0, /* bitpos */
1586 complain_overflow_dont, /* complain_on_overflow */
1587 _bfd_mips_elf_lo16_reloc, /* special_function */
1588 "R_MIPS16_LO16", /* name */
1589 TRUE, /* partial_inplace */
1590 0x0000ffff, /* src_mask */
1591 0x0000ffff, /* dst_mask */
1592 FALSE), /* pcrel_offset */
d0f13682
CLT
1593
1594 /* MIPS16 TLS general dynamic variable reference. */
1595 HOWTO (R_MIPS16_TLS_GD, /* type */
1596 0, /* rightshift */
1597 2, /* size (0 = byte, 1 = short, 2 = long) */
1598 16, /* bitsize */
1599 FALSE, /* pc_relative */
1600 0, /* bitpos */
1601 complain_overflow_signed, /* complain_on_overflow */
1602 _bfd_mips_elf_generic_reloc, /* special_function */
1603 "R_MIPS16_TLS_GD", /* name */
1604 TRUE, /* partial_inplace */
1605 0x0000ffff, /* src_mask */
1606 0x0000ffff, /* dst_mask */
1607 FALSE), /* pcrel_offset */
1608
1609 /* MIPS16 TLS local dynamic variable reference. */
1610 HOWTO (R_MIPS16_TLS_LDM, /* type */
1611 0, /* rightshift */
1612 2, /* size (0 = byte, 1 = short, 2 = long) */
1613 16, /* bitsize */
1614 FALSE, /* pc_relative */
1615 0, /* bitpos */
1616 complain_overflow_signed, /* complain_on_overflow */
1617 _bfd_mips_elf_generic_reloc, /* special_function */
1618 "R_MIPS16_TLS_LDM", /* name */
1619 TRUE, /* partial_inplace */
1620 0x0000ffff, /* src_mask */
1621 0x0000ffff, /* dst_mask */
1622 FALSE), /* pcrel_offset */
1623
1624 /* MIPS16 TLS local dynamic offset. */
1625 HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */
1626 0, /* rightshift */
1627 2, /* size (0 = byte, 1 = short, 2 = long) */
1628 16, /* bitsize */
1629 FALSE, /* pc_relative */
1630 0, /* bitpos */
1631 complain_overflow_signed, /* complain_on_overflow */
1632 _bfd_mips_elf_generic_reloc, /* special_function */
1633 "R_MIPS16_TLS_DTPREL_HI16", /* name */
1634 TRUE, /* partial_inplace */
1635 0x0000ffff, /* src_mask */
1636 0x0000ffff, /* dst_mask */
1637 FALSE), /* pcrel_offset */
1638
1639 /* MIPS16 TLS local dynamic offset. */
1640 HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */
1641 0, /* rightshift */
1642 2, /* size (0 = byte, 1 = short, 2 = long) */
1643 16, /* bitsize */
1644 FALSE, /* pc_relative */
1645 0, /* bitpos */
1646 complain_overflow_signed, /* complain_on_overflow */
1647 _bfd_mips_elf_generic_reloc, /* special_function */
1648 "R_MIPS16_TLS_DTPREL_LO16", /* name */
1649 TRUE, /* partial_inplace */
1650 0x0000ffff, /* src_mask */
1651 0x0000ffff, /* dst_mask */
1652 FALSE), /* pcrel_offset */
1653
1654 /* MIPS16 TLS thread pointer offset. */
1655 HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
1656 0, /* rightshift */
1657 2, /* size (0 = byte, 1 = short, 2 = long) */
1658 16, /* bitsize */
1659 FALSE, /* pc_relative */
1660 0, /* bitpos */
1661 complain_overflow_signed, /* complain_on_overflow */
1662 _bfd_mips_elf_generic_reloc, /* special_function */
1663 "R_MIPS16_TLS_GOTTPREL", /* name */
1664 TRUE, /* partial_inplace */
1665 0x0000ffff, /* src_mask */
1666 0x0000ffff, /* dst_mask */
1667 FALSE), /* pcrel_offset */
1668
1669 /* MIPS16 TLS thread pointer offset. */
1670 HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */
1671 0, /* rightshift */
1672 2, /* size (0 = byte, 1 = short, 2 = long) */
1673 16, /* bitsize */
1674 FALSE, /* pc_relative */
1675 0, /* bitpos */
1676 complain_overflow_signed, /* complain_on_overflow */
1677 _bfd_mips_elf_generic_reloc, /* special_function */
1678 "R_MIPS16_TLS_TPREL_HI16", /* name */
1679 TRUE, /* partial_inplace */
1680 0x0000ffff, /* src_mask */
1681 0x0000ffff, /* dst_mask */
1682 FALSE), /* pcrel_offset */
1683
1684 /* MIPS16 TLS thread pointer offset. */
1685 HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */
1686 0, /* rightshift */
1687 2, /* size (0 = byte, 1 = short, 2 = long) */
1688 16, /* bitsize */
1689 FALSE, /* pc_relative */
1690 0, /* bitpos */
1691 complain_overflow_signed, /* complain_on_overflow */
1692 _bfd_mips_elf_generic_reloc, /* special_function */
1693 "R_MIPS16_TLS_TPREL_LO16", /* name */
1694 TRUE, /* partial_inplace */
1695 0x0000ffff, /* src_mask */
1696 0x0000ffff, /* dst_mask */
1697 FALSE), /* pcrel_offset */
d6f16593
MR
1698};
1699
1700static reloc_howto_type mips16_elf64_howto_table_rela[] =
1701{
1702 /* The reloc used for the mips16 jump instruction. */
1703 HOWTO (R_MIPS16_26, /* type */
1704 2, /* rightshift */
1705 2, /* size (0 = byte, 1 = short, 2 = long) */
1706 26, /* bitsize */
1707 FALSE, /* pc_relative */
1708 0, /* bitpos */
1709 complain_overflow_dont, /* complain_on_overflow */
1710 /* This needs complex overflow
1711 detection, because the upper four
1712 bits must match the PC. */
35d3d567 1713 _bfd_mips_elf_generic_reloc, /* special_function */
d6f16593
MR
1714 "R_MIPS16_26", /* name */
1715 FALSE, /* partial_inplace */
72c4ab07 1716 0, /* src_mask */
d6f16593
MR
1717 0x3ffffff, /* dst_mask */
1718 FALSE), /* pcrel_offset */
1719
1720 /* The reloc used for the mips16 gprel instruction. */
1721 HOWTO (R_MIPS16_GPREL, /* type */
1722 0, /* rightshift */
1723 2, /* size (0 = byte, 1 = short, 2 = long) */
1724 16, /* bitsize */
1725 FALSE, /* pc_relative */
1726 0, /* bitpos */
1727 complain_overflow_signed, /* complain_on_overflow */
1728 mips16_gprel_reloc, /* special_function */
1729 "R_MIPS16_GPREL", /* name */
1730 FALSE, /* partial_inplace */
72c4ab07 1731 0, /* src_mask */
d6f16593
MR
1732 0x0000ffff, /* dst_mask */
1733 FALSE), /* pcrel_offset */
1734
738e5348
RS
1735 /* A MIPS16 reference to the global offset table. */
1736 HOWTO (R_MIPS16_GOT16, /* type */
1737 0, /* rightshift */
1738 2, /* size (0 = byte, 1 = short, 2 = long) */
1739 16, /* bitsize */
1740 FALSE, /* pc_relative */
1741 0, /* bitpos */
1742 complain_overflow_dont, /* complain_on_overflow */
1743 _bfd_mips_elf_got16_reloc, /* special_function */
1744 "R_MIPS16_GOT16", /* name */
1745 FALSE, /* partial_inplace */
72c4ab07 1746 0, /* src_mask */
738e5348
RS
1747 0x0000ffff, /* dst_mask */
1748 FALSE), /* pcrel_offset */
d6f16593 1749
738e5348
RS
1750 /* A MIPS16 call through the global offset table. */
1751 HOWTO (R_MIPS16_CALL16, /* type */
1752 0, /* rightshift */
1753 2, /* size (0 = byte, 1 = short, 2 = long) */
1754 16, /* bitsize */
1755 FALSE, /* pc_relative */
1756 0, /* bitpos */
1757 complain_overflow_dont, /* complain_on_overflow */
1758 _bfd_mips_elf_generic_reloc, /* special_function */
1759 "R_MIPS16_CALL16", /* name */
1760 FALSE, /* partial_inplace */
72c4ab07 1761 0, /* src_mask */
738e5348
RS
1762 0x0000ffff, /* dst_mask */
1763 FALSE), /* pcrel_offset */
d6f16593
MR
1764
1765 /* MIPS16 high 16 bits of symbol value. */
1766 HOWTO (R_MIPS16_HI16, /* type */
1767 16, /* rightshift */
1768 2, /* size (0 = byte, 1 = short, 2 = long) */
1769 16, /* bitsize */
1770 FALSE, /* pc_relative */
1771 0, /* bitpos */
1772 complain_overflow_dont, /* complain_on_overflow */
1773 _bfd_mips_elf_hi16_reloc, /* special_function */
1774 "R_MIPS16_HI16", /* name */
1775 FALSE, /* partial_inplace */
72c4ab07 1776 0, /* src_mask */
d6f16593
MR
1777 0x0000ffff, /* dst_mask */
1778 FALSE), /* pcrel_offset */
1779
1780 /* MIPS16 low 16 bits of symbol value. */
1781 HOWTO (R_MIPS16_LO16, /* type */
1782 0, /* rightshift */
1783 2, /* size (0 = byte, 1 = short, 2 = long) */
1784 16, /* bitsize */
1785 FALSE, /* pc_relative */
1786 0, /* bitpos */
1787 complain_overflow_dont, /* complain_on_overflow */
1788 _bfd_mips_elf_lo16_reloc, /* special_function */
1789 "R_MIPS16_LO16", /* name */
1790 FALSE, /* partial_inplace */
72c4ab07 1791 0, /* src_mask */
d6f16593
MR
1792 0x0000ffff, /* dst_mask */
1793 FALSE), /* pcrel_offset */
d0f13682
CLT
1794
1795 /* MIPS16 TLS general dynamic variable reference. */
1796 HOWTO (R_MIPS16_TLS_GD, /* type */
1797 0, /* rightshift */
1798 2, /* size (0 = byte, 1 = short, 2 = long) */
1799 16, /* bitsize */
1800 FALSE, /* pc_relative */
1801 0, /* bitpos */
1802 complain_overflow_signed, /* complain_on_overflow */
1803 _bfd_mips_elf_generic_reloc, /* special_function */
1804 "R_MIPS16_TLS_GD", /* name */
1805 FALSE, /* partial_inplace */
1806 0x0000ffff, /* src_mask */
1807 0x0000ffff, /* dst_mask */
1808 FALSE), /* pcrel_offset */
1809
1810 /* MIPS16 TLS local dynamic variable reference. */
1811 HOWTO (R_MIPS16_TLS_LDM, /* type */
1812 0, /* rightshift */
1813 2, /* size (0 = byte, 1 = short, 2 = long) */
1814 16, /* bitsize */
1815 FALSE, /* pc_relative */
1816 0, /* bitpos */
1817 complain_overflow_signed, /* complain_on_overflow */
1818 _bfd_mips_elf_generic_reloc, /* special_function */
1819 "R_MIPS16_TLS_LDM", /* name */
1820 FALSE, /* partial_inplace */
1821 0x0000ffff, /* src_mask */
1822 0x0000ffff, /* dst_mask */
1823 FALSE), /* pcrel_offset */
1824
1825 /* MIPS16 TLS local dynamic offset. */
1826 HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */
1827 0, /* rightshift */
1828 2, /* size (0 = byte, 1 = short, 2 = long) */
1829 16, /* bitsize */
1830 FALSE, /* pc_relative */
1831 0, /* bitpos */
1832 complain_overflow_signed, /* complain_on_overflow */
1833 _bfd_mips_elf_generic_reloc, /* special_function */
1834 "R_MIPS16_TLS_DTPREL_HI16", /* name */
1835 FALSE, /* partial_inplace */
1836 0x0000ffff, /* src_mask */
1837 0x0000ffff, /* dst_mask */
1838 FALSE), /* pcrel_offset */
1839
1840 /* MIPS16 TLS local dynamic offset. */
1841 HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */
1842 0, /* rightshift */
1843 2, /* size (0 = byte, 1 = short, 2 = long) */
1844 16, /* bitsize */
1845 FALSE, /* pc_relative */
1846 0, /* bitpos */
1847 complain_overflow_signed, /* complain_on_overflow */
1848 _bfd_mips_elf_generic_reloc, /* special_function */
1849 "R_MIPS16_TLS_DTPREL_LO16", /* name */
1850 FALSE, /* partial_inplace */
1851 0x0000ffff, /* src_mask */
1852 0x0000ffff, /* dst_mask */
1853 FALSE), /* pcrel_offset */
1854
1855 /* MIPS16 TLS thread pointer offset. */
1856 HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
1857 0, /* rightshift */
1858 2, /* size (0 = byte, 1 = short, 2 = long) */
1859 16, /* bitsize */
1860 FALSE, /* pc_relative */
1861 0, /* bitpos */
1862 complain_overflow_signed, /* complain_on_overflow */
1863 _bfd_mips_elf_generic_reloc, /* special_function */
1864 "R_MIPS16_TLS_GOTTPREL", /* name */
1865 FALSE, /* partial_inplace */
1866 0x0000ffff, /* src_mask */
1867 0x0000ffff, /* dst_mask */
1868 FALSE), /* pcrel_offset */
1869
1870 /* MIPS16 TLS thread pointer offset. */
1871 HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */
1872 0, /* rightshift */
1873 2, /* size (0 = byte, 1 = short, 2 = long) */
1874 16, /* bitsize */
1875 FALSE, /* pc_relative */
1876 0, /* bitpos */
1877 complain_overflow_signed, /* complain_on_overflow */
1878 _bfd_mips_elf_generic_reloc, /* special_function */
1879 "R_MIPS16_TLS_TPREL_HI16", /* name */
1880 FALSE, /* partial_inplace */
1881 0x0000ffff, /* src_mask */
1882 0x0000ffff, /* dst_mask */
1883 FALSE), /* pcrel_offset */
1884
1885 /* MIPS16 TLS thread pointer offset. */
1886 HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */
1887 0, /* rightshift */
1888 2, /* size (0 = byte, 1 = short, 2 = long) */
1889 16, /* bitsize */
1890 FALSE, /* pc_relative */
1891 0, /* bitpos */
1892 complain_overflow_signed, /* complain_on_overflow */
1893 _bfd_mips_elf_generic_reloc, /* special_function */
1894 "R_MIPS16_TLS_TPREL_LO16", /* name */
1895 FALSE, /* partial_inplace */
1896 0x0000ffff, /* src_mask */
1897 0x0000ffff, /* dst_mask */
1898 FALSE), /* pcrel_offset */
d6f16593 1899};
a4382ec6 1900
df58fc94
RS
1901static reloc_howto_type micromips_elf64_howto_table_rel[] =
1902{
1903 EMPTY_HOWTO (130),
1904 EMPTY_HOWTO (131),
1905 EMPTY_HOWTO (132),
1906
1907 /* 26 bit jump address. */
1908 HOWTO (R_MICROMIPS_26_S1, /* type */
1909 1, /* rightshift */
1910 2, /* size (0 = byte, 1 = short, 2 = long) */
1911 26, /* bitsize */
1912 FALSE, /* pc_relative */
1913 0, /* bitpos */
1914 complain_overflow_dont, /* complain_on_overflow */
1915 /* This needs complex overflow
1916 detection, because the upper four
1917 bits must match the PC. */
1918 _bfd_mips_elf_generic_reloc, /* special_function */
1919 "R_MICROMIPS_26_S1", /* name */
1920 TRUE, /* partial_inplace */
1921 0x3ffffff, /* src_mask */
1922 0x3ffffff, /* dst_mask */
1923 FALSE), /* pcrel_offset */
1924
1925 /* High 16 bits of symbol value. */
1926 HOWTO (R_MICROMIPS_HI16, /* type */
1927 16, /* rightshift */
1928 2, /* size (0 = byte, 1 = short, 2 = long) */
1929 16, /* bitsize */
1930 FALSE, /* pc_relative */
1931 0, /* bitpos */
1932 complain_overflow_dont, /* complain_on_overflow */
1933 _bfd_mips_elf_hi16_reloc, /* special_function */
1934 "R_MICROMIPS_HI16", /* name */
1935 TRUE, /* partial_inplace */
1936 0x0000ffff, /* src_mask */
1937 0x0000ffff, /* dst_mask */
1938 FALSE), /* pcrel_offset */
1939
1940 /* Low 16 bits of symbol value. */
1941 HOWTO (R_MICROMIPS_LO16, /* type */
1942 0, /* rightshift */
1943 2, /* size (0 = byte, 1 = short, 2 = long) */
1944 16, /* bitsize */
1945 FALSE, /* pc_relative */
1946 0, /* bitpos */
1947 complain_overflow_dont, /* complain_on_overflow */
1948 _bfd_mips_elf_lo16_reloc, /* special_function */
1949 "R_MICROMIPS_LO16", /* name */
1950 TRUE, /* partial_inplace */
1951 0x0000ffff, /* src_mask */
1952 0x0000ffff, /* dst_mask */
1953 FALSE), /* pcrel_offset */
1954
1955 /* GP relative reference. */
1956 HOWTO (R_MICROMIPS_GPREL16, /* type */
1957 0, /* rightshift */
1958 2, /* size (0 = byte, 1 = short, 2 = long) */
1959 16, /* bitsize */
1960 FALSE, /* pc_relative */
1961 0, /* bitpos */
1962 complain_overflow_signed, /* complain_on_overflow */
1963 _bfd_mips_elf32_gprel16_reloc, /* special_function */
1964 "R_MICROMIPS_GPREL16", /* name */
1965 TRUE, /* partial_inplace */
1966 0x0000ffff, /* src_mask */
1967 0x0000ffff, /* dst_mask */
1968 FALSE), /* pcrel_offset */
1969
1970 /* Reference to literal section. */
1971 HOWTO (R_MICROMIPS_LITERAL, /* type */
1972 0, /* rightshift */
1973 2, /* size (0 = byte, 1 = short, 2 = long) */
1974 16, /* bitsize */
1975 FALSE, /* pc_relative */
1976 0, /* bitpos */
1977 complain_overflow_signed, /* complain_on_overflow */
1978 _bfd_mips_elf32_gprel16_reloc, /* special_function */
1979 "R_MICROMIPS_LITERAL", /* name */
1980 TRUE, /* partial_inplace */
1981 0x0000ffff, /* src_mask */
1982 0x0000ffff, /* dst_mask */
1983 FALSE), /* pcrel_offset */
1984
1985 /* Reference to global offset table. */
1986 HOWTO (R_MICROMIPS_GOT16, /* type */
1987 0, /* rightshift */
1988 2, /* size (0 = byte, 1 = short, 2 = long) */
1989 16, /* bitsize */
1990 FALSE, /* pc_relative */
1991 0, /* bitpos */
1992 complain_overflow_signed, /* complain_on_overflow */
1993 _bfd_mips_elf_got16_reloc, /* special_function */
1994 "R_MICROMIPS_GOT16", /* name */
1995 TRUE, /* partial_inplace */
1996 0x0000ffff, /* src_mask */
1997 0x0000ffff, /* dst_mask */
1998 FALSE), /* pcrel_offset */
1999
2000 /* This is for microMIPS branches. */
2001 HOWTO (R_MICROMIPS_PC7_S1, /* type */
2002 1, /* rightshift */
2003 1, /* size (0 = byte, 1 = short, 2 = long) */
2004 7, /* bitsize */
2005 TRUE, /* pc_relative */
2006 0, /* bitpos */
2007 complain_overflow_signed, /* complain_on_overflow */
2008 _bfd_mips_elf_generic_reloc, /* special_function */
2009 "R_MICROMIPS_PC7_S1", /* name */
2010 TRUE, /* partial_inplace */
2011 0x0000007f, /* src_mask */
2012 0x0000007f, /* dst_mask */
2013 TRUE), /* pcrel_offset */
2014
2015 HOWTO (R_MICROMIPS_PC10_S1, /* type */
2016 1, /* rightshift */
2017 1, /* size (0 = byte, 1 = short, 2 = long) */
2018 10, /* bitsize */
2019 TRUE, /* pc_relative */
2020 0, /* bitpos */
2021 complain_overflow_signed, /* complain_on_overflow */
2022 _bfd_mips_elf_generic_reloc, /* special_function */
2023 "R_MICROMIPS_PC10_S1", /* name */
2024 TRUE, /* partial_inplace */
2025 0x000003ff, /* src_mask */
2026 0x000003ff, /* dst_mask */
2027 TRUE), /* pcrel_offset */
2028
2029 HOWTO (R_MICROMIPS_PC16_S1, /* type */
2030 1, /* rightshift */
2031 2, /* size (0 = byte, 1 = short, 2 = long) */
2032 16, /* bitsize */
2033 TRUE, /* pc_relative */
2034 0, /* bitpos */
2035 complain_overflow_signed, /* complain_on_overflow */
2036 _bfd_mips_elf_generic_reloc, /* special_function */
2037 "R_MICROMIPS_PC16_S1", /* name */
2038 TRUE, /* partial_inplace */
2039 0x0000ffff, /* src_mask */
2040 0x0000ffff, /* dst_mask */
2041 TRUE), /* pcrel_offset */
2042
2043 /* 16 bit call through global offset table. */
2044 HOWTO (R_MICROMIPS_CALL16, /* type */
2045 0, /* rightshift */
2046 2, /* size (0 = byte, 1 = short, 2 = long) */
2047 16, /* bitsize */
2048 FALSE, /* pc_relative */
2049 0, /* bitpos */
2050 complain_overflow_signed, /* complain_on_overflow */
2051 _bfd_mips_elf_generic_reloc, /* special_function */
2052 "R_MICROMIPS_CALL16", /* name */
2053 TRUE, /* partial_inplace */
2054 0x0000ffff, /* src_mask */
2055 0x0000ffff, /* dst_mask */
2056 FALSE), /* pcrel_offset */
2057
2058 EMPTY_HOWTO (143),
2059 EMPTY_HOWTO (144),
2060
2061 /* Displacement in the global offset table. */
2062 HOWTO (R_MICROMIPS_GOT_DISP, /* type */
2063 0, /* rightshift */
2064 2, /* size (0 = byte, 1 = short, 2 = long) */
2065 16, /* bitsize */
2066 FALSE, /* pc_relative */
2067 0, /* bitpos */
2068 complain_overflow_signed, /* complain_on_overflow */
2069 _bfd_mips_elf_generic_reloc, /* special_function */
2070 "R_MICROMIPS_GOT_DISP",/* name */
2071 TRUE, /* partial_inplace */
2072 0x0000ffff, /* src_mask */
2073 0x0000ffff, /* dst_mask */
2074 FALSE), /* pcrel_offset */
2075
2076 /* Displacement to page pointer in the global offset table. */
2077 HOWTO (R_MICROMIPS_GOT_PAGE, /* type */
2078 0, /* rightshift */
2079 2, /* size (0 = byte, 1 = short, 2 = long) */
2080 16, /* bitsize */
2081 FALSE, /* pc_relative */
2082 0, /* bitpos */
2083 complain_overflow_signed, /* complain_on_overflow */
2084 _bfd_mips_elf_generic_reloc, /* special_function */
2085 "R_MICROMIPS_GOT_PAGE",/* name */
2086 TRUE, /* partial_inplace */
2087 0x0000ffff, /* src_mask */
2088 0x0000ffff, /* dst_mask */
2089 FALSE), /* pcrel_offset */
2090
2091 /* Offset from page pointer in the global offset table. */
2092 HOWTO (R_MICROMIPS_GOT_OFST, /* type */
2093 0, /* rightshift */
2094 2, /* size (0 = byte, 1 = short, 2 = long) */
2095 16, /* bitsize */
2096 FALSE, /* pc_relative */
2097 0, /* bitpos */
2098 complain_overflow_signed, /* complain_on_overflow */
2099 _bfd_mips_elf_generic_reloc, /* special_function */
2100 "R_MICROMIPS_GOT_OFST",/* name */
2101 TRUE, /* partial_inplace */
2102 0x0000ffff, /* src_mask */
2103 0x0000ffff, /* dst_mask */
2104 FALSE), /* pcrel_offset */
2105
2106 /* High 16 bits of displacement in global offset table. */
2107 HOWTO (R_MICROMIPS_GOT_HI16, /* type */
2108 0, /* rightshift */
2109 2, /* size (0 = byte, 1 = short, 2 = long) */
2110 16, /* bitsize */
2111 FALSE, /* pc_relative */
2112 0, /* bitpos */
2113 complain_overflow_dont, /* complain_on_overflow */
2114 _bfd_mips_elf_generic_reloc, /* special_function */
2115 "R_MICROMIPS_GOT_HI16",/* name */
2116 TRUE, /* partial_inplace */
2117 0x0000ffff, /* src_mask */
2118 0x0000ffff, /* dst_mask */
2119 FALSE), /* pcrel_offset */
2120
2121 /* Low 16 bits of displacement in global offset table. */
2122 HOWTO (R_MICROMIPS_GOT_LO16, /* type */
2123 0, /* rightshift */
2124 2, /* size (0 = byte, 1 = short, 2 = long) */
2125 16, /* bitsize */
2126 FALSE, /* pc_relative */
2127 0, /* bitpos */
2128 complain_overflow_dont, /* complain_on_overflow */
2129 _bfd_mips_elf_generic_reloc, /* special_function */
2130 "R_MICROMIPS_GOT_LO16",/* name */
2131 TRUE, /* partial_inplace */
2132 0x0000ffff, /* src_mask */
2133 0x0000ffff, /* dst_mask */
2134 FALSE), /* pcrel_offset */
2135
2136 /* 64 bit subtraction. Used in the N32 ABI. */
2137 HOWTO (R_MICROMIPS_SUB, /* type */
2138 0, /* rightshift */
2139 4, /* size (0 = byte, 1 = short, 2 = long) */
2140 64, /* bitsize */
2141 FALSE, /* pc_relative */
2142 0, /* bitpos */
2143 complain_overflow_dont, /* complain_on_overflow */
2144 _bfd_mips_elf_generic_reloc, /* special_function */
2145 "R_MICROMIPS_SUB", /* name */
2146 TRUE, /* partial_inplace */
2147 MINUS_ONE, /* src_mask */
2148 MINUS_ONE, /* dst_mask */
2149 FALSE), /* pcrel_offset */
2150
2151 /* We don't support these for REL relocations, because it means building
2152 the addend from a R_MICROMIPS_HIGHEST/R_MICROMIPS_HIGHER/
2153 R_MICROMIPS_HI16/R_MICROMIPS_LO16 sequence with varying ordering,
2154 using fallable heuristics. */
2155 EMPTY_HOWTO (R_MICROMIPS_HIGHER),
2156 EMPTY_HOWTO (R_MICROMIPS_HIGHEST),
2157
2158 /* High 16 bits of displacement in global offset table. */
2159 HOWTO (R_MICROMIPS_CALL_HI16, /* type */
2160 0, /* rightshift */
2161 2, /* size (0 = byte, 1 = short, 2 = long) */
2162 16, /* bitsize */
2163 FALSE, /* pc_relative */
2164 0, /* bitpos */
2165 complain_overflow_dont, /* complain_on_overflow */
2166 _bfd_mips_elf_generic_reloc, /* special_function */
2167 "R_MICROMIPS_CALL_HI16",/* name */
2168 TRUE, /* partial_inplace */
2169 0x0000ffff, /* src_mask */
2170 0x0000ffff, /* dst_mask */
2171 FALSE), /* pcrel_offset */
2172
2173 /* Low 16 bits of displacement in global offset table. */
2174 HOWTO (R_MICROMIPS_CALL_LO16, /* type */
2175 0, /* rightshift */
2176 2, /* size (0 = byte, 1 = short, 2 = long) */
2177 16, /* bitsize */
2178 FALSE, /* pc_relative */
2179 0, /* bitpos */
2180 complain_overflow_dont, /* complain_on_overflow */
2181 _bfd_mips_elf_generic_reloc, /* special_function */
2182 "R_MICROMIPS_CALL_LO16",/* name */
2183 TRUE, /* partial_inplace */
2184 0x0000ffff, /* src_mask */
2185 0x0000ffff, /* dst_mask */
2186 FALSE), /* pcrel_offset */
2187};
2188
2189static reloc_howto_type micromips_elf64_howto_table_rela[] =
2190{
2191 EMPTY_HOWTO (130),
2192 EMPTY_HOWTO (131),
2193 EMPTY_HOWTO (132),
2194
2195 /* 26 bit jump address. */
2196 HOWTO (R_MICROMIPS_26_S1, /* type */
2197 1, /* rightshift */
2198 2, /* size (0 = byte, 1 = short, 2 = long) */
2199 26, /* bitsize */
2200 FALSE, /* pc_relative */
2201 0, /* bitpos */
2202 complain_overflow_dont, /* complain_on_overflow */
2203 /* This needs complex overflow
2204 detection, because the upper four
2205 bits must match the PC. */
2206 _bfd_mips_elf_generic_reloc, /* special_function */
2207 "R_MICROMIPS_26_S1", /* name */
2208 FALSE, /* partial_inplace */
72c4ab07 2209 0, /* src_mask */
df58fc94
RS
2210 0x3ffffff, /* dst_mask */
2211 FALSE), /* pcrel_offset */
2212
2213 /* High 16 bits of symbol value. */
2214 HOWTO (R_MICROMIPS_HI16, /* type */
2215 16, /* rightshift */
2216 2, /* size (0 = byte, 1 = short, 2 = long) */
2217 16, /* bitsize */
2218 FALSE, /* pc_relative */
2219 0, /* bitpos */
2220 complain_overflow_dont, /* complain_on_overflow */
2221 _bfd_mips_elf_hi16_reloc, /* special_function */
2222 "R_MICROMIPS_HI16", /* name */
2223 FALSE, /* partial_inplace */
72c4ab07 2224 0, /* src_mask */
df58fc94
RS
2225 0x0000ffff, /* dst_mask */
2226 FALSE), /* pcrel_offset */
2227
2228 /* Low 16 bits of symbol value. */
2229 HOWTO (R_MICROMIPS_LO16, /* type */
2230 0, /* rightshift */
2231 2, /* size (0 = byte, 1 = short, 2 = long) */
2232 16, /* bitsize */
2233 FALSE, /* pc_relative */
2234 0, /* bitpos */
2235 complain_overflow_dont, /* complain_on_overflow */
2236 _bfd_mips_elf_lo16_reloc, /* special_function */
2237 "R_MICROMIPS_LO16", /* name */
2238 FALSE, /* partial_inplace */
72c4ab07 2239 0, /* src_mask */
df58fc94
RS
2240 0x0000ffff, /* dst_mask */
2241 FALSE), /* pcrel_offset */
2242
2243 /* GP relative reference. */
2244 HOWTO (R_MICROMIPS_GPREL16, /* type */
2245 0, /* rightshift */
2246 2, /* size (0 = byte, 1 = short, 2 = long) */
2247 16, /* bitsize */
2248 FALSE, /* pc_relative */
2249 0, /* bitpos */
2250 complain_overflow_signed, /* complain_on_overflow */
2251 _bfd_mips_elf32_gprel16_reloc, /* special_function */
2252 "R_MICROMIPS_GPREL16", /* name */
2253 FALSE, /* partial_inplace */
72c4ab07 2254 0, /* src_mask */
df58fc94
RS
2255 0x0000ffff, /* dst_mask */
2256 FALSE), /* pcrel_offset */
2257
2258 /* Reference to literal section. */
2259 HOWTO (R_MICROMIPS_LITERAL, /* type */
2260 0, /* rightshift */
2261 2, /* size (0 = byte, 1 = short, 2 = long) */
2262 16, /* bitsize */
2263 FALSE, /* pc_relative */
2264 0, /* bitpos */
2265 complain_overflow_signed, /* complain_on_overflow */
2266 _bfd_mips_elf32_gprel16_reloc, /* special_function */
2267 "R_MICROMIPS_LITERAL", /* name */
2268 FALSE, /* partial_inplace */
72c4ab07 2269 0, /* src_mask */
df58fc94
RS
2270 0x0000ffff, /* dst_mask */
2271 FALSE), /* pcrel_offset */
2272
2273 /* Reference to global offset table. */
2274 HOWTO (R_MICROMIPS_GOT16, /* type */
2275 0, /* rightshift */
2276 2, /* size (0 = byte, 1 = short, 2 = long) */
2277 16, /* bitsize */
2278 FALSE, /* pc_relative */
2279 0, /* bitpos */
2280 complain_overflow_signed, /* complain_on_overflow */
2281 _bfd_mips_elf_got16_reloc, /* special_function */
2282 "R_MICROMIPS_GOT16", /* name */
2283 FALSE, /* partial_inplace */
72c4ab07 2284 0, /* src_mask */
df58fc94
RS
2285 0x0000ffff, /* dst_mask */
2286 FALSE), /* pcrel_offset */
2287
2288 /* This is for microMIPS branches. */
2289 HOWTO (R_MICROMIPS_PC7_S1, /* type */
2290 1, /* rightshift */
2291 1, /* size (0 = byte, 1 = short, 2 = long) */
2292 7, /* bitsize */
2293 TRUE, /* pc_relative */
2294 0, /* bitpos */
2295 complain_overflow_signed, /* complain_on_overflow */
2296 _bfd_mips_elf_generic_reloc, /* special_function */
2297 "R_MICROMIPS_PC7_S1", /* name */
2298 FALSE, /* partial_inplace */
72c4ab07 2299 0, /* src_mask */
df58fc94
RS
2300 0x0000007f, /* dst_mask */
2301 TRUE), /* pcrel_offset */
2302
2303 HOWTO (R_MICROMIPS_PC10_S1, /* type */
2304 1, /* rightshift */
2305 1, /* size (0 = byte, 1 = short, 2 = long) */
2306 10, /* bitsize */
2307 TRUE, /* pc_relative */
2308 0, /* bitpos */
2309 complain_overflow_signed, /* complain_on_overflow */
2310 _bfd_mips_elf_generic_reloc, /* special_function */
2311 "R_MICROMIPS_PC10_S1", /* name */
2312 FALSE, /* partial_inplace */
72c4ab07 2313 0, /* src_mask */
df58fc94
RS
2314 0x000003ff, /* dst_mask */
2315 TRUE), /* pcrel_offset */
2316
2317 HOWTO (R_MICROMIPS_PC16_S1, /* type */
2318 1, /* rightshift */
2319 2, /* size (0 = byte, 1 = short, 2 = long) */
2320 16, /* bitsize */
2321 TRUE, /* pc_relative */
2322 0, /* bitpos */
2323 complain_overflow_signed, /* complain_on_overflow */
2324 _bfd_mips_elf_generic_reloc, /* special_function */
2325 "R_MICROMIPS_PC16_S1", /* name */
2326 FALSE, /* partial_inplace */
72c4ab07 2327 0, /* src_mask */
df58fc94
RS
2328 0x0000ffff, /* dst_mask */
2329 TRUE), /* pcrel_offset */
2330
2331 /* 16 bit call through global offset table. */
2332 HOWTO (R_MICROMIPS_CALL16, /* type */
2333 0, /* rightshift */
2334 2, /* size (0 = byte, 1 = short, 2 = long) */
2335 16, /* bitsize */
2336 FALSE, /* pc_relative */
2337 0, /* bitpos */
2338 complain_overflow_signed, /* complain_on_overflow */
2339 _bfd_mips_elf_generic_reloc, /* special_function */
2340 "R_MICROMIPS_CALL16", /* name */
2341 FALSE, /* partial_inplace */
72c4ab07 2342 0, /* src_mask */
df58fc94
RS
2343 0x0000ffff, /* dst_mask */
2344 FALSE), /* pcrel_offset */
2345
2346 EMPTY_HOWTO (143),
2347 EMPTY_HOWTO (144),
2348
2349 /* Displacement in the global offset table. */
2350 HOWTO (R_MICROMIPS_GOT_DISP, /* type */
2351 0, /* rightshift */
2352 2, /* size (0 = byte, 1 = short, 2 = long) */
2353 16, /* bitsize */
2354 FALSE, /* pc_relative */
2355 0, /* bitpos */
2356 complain_overflow_signed, /* complain_on_overflow */
2357 _bfd_mips_elf_generic_reloc, /* special_function */
2358 "R_MICROMIPS_GOT_DISP",/* name */
2359 FALSE, /* partial_inplace */
72c4ab07 2360 0, /* src_mask */
df58fc94
RS
2361 0x0000ffff, /* dst_mask */
2362 FALSE), /* pcrel_offset */
2363
2364 /* Displacement to page pointer in the global offset table. */
2365 HOWTO (R_MICROMIPS_GOT_PAGE, /* type */
2366 0, /* rightshift */
2367 2, /* size (0 = byte, 1 = short, 2 = long) */
2368 16, /* bitsize */
2369 FALSE, /* pc_relative */
2370 0, /* bitpos */
2371 complain_overflow_signed, /* complain_on_overflow */
2372 _bfd_mips_elf_generic_reloc, /* special_function */
2373 "R_MICROMIPS_GOT_PAGE",/* name */
2374 FALSE, /* partial_inplace */
72c4ab07 2375 0, /* src_mask */
df58fc94
RS
2376 0x0000ffff, /* dst_mask */
2377 FALSE), /* pcrel_offset */
2378
2379 /* Offset from page pointer in the global offset table. */
2380 HOWTO (R_MICROMIPS_GOT_OFST, /* type */
2381 0, /* rightshift */
2382 2, /* size (0 = byte, 1 = short, 2 = long) */
2383 16, /* bitsize */
2384 FALSE, /* pc_relative */
2385 0, /* bitpos */
2386 complain_overflow_signed, /* complain_on_overflow */
2387 _bfd_mips_elf_generic_reloc, /* special_function */
2388 "R_MICROMIPS_GOT_OFST",/* name */
2389 FALSE, /* partial_inplace */
72c4ab07 2390 0, /* src_mask */
df58fc94
RS
2391 0x0000ffff, /* dst_mask */
2392 FALSE), /* pcrel_offset */
2393
2394 /* High 16 bits of displacement in global offset table. */
2395 HOWTO (R_MICROMIPS_GOT_HI16, /* type */
2396 0, /* rightshift */
2397 2, /* size (0 = byte, 1 = short, 2 = long) */
2398 16, /* bitsize */
2399 FALSE, /* pc_relative */
2400 0, /* bitpos */
2401 complain_overflow_dont, /* complain_on_overflow */
2402 _bfd_mips_elf_generic_reloc, /* special_function */
2403 "R_MICROMIPS_GOT_HI16",/* name */
2404 FALSE, /* partial_inplace */
72c4ab07 2405 0, /* src_mask */
df58fc94
RS
2406 0x0000ffff, /* dst_mask */
2407 FALSE), /* pcrel_offset */
2408
2409 /* Low 16 bits of displacement in global offset table. */
2410 HOWTO (R_MICROMIPS_GOT_LO16, /* type */
2411 0, /* rightshift */
2412 2, /* size (0 = byte, 1 = short, 2 = long) */
2413 16, /* bitsize */
2414 FALSE, /* pc_relative */
2415 0, /* bitpos */
2416 complain_overflow_dont, /* complain_on_overflow */
2417 _bfd_mips_elf_generic_reloc, /* special_function */
2418 "R_MICROMIPS_GOT_LO16",/* name */
2419 FALSE, /* partial_inplace */
72c4ab07 2420 0, /* src_mask */
df58fc94
RS
2421 0x0000ffff, /* dst_mask */
2422 FALSE), /* pcrel_offset */
2423
2424 /* 64 bit subtraction. Used in the N32 ABI. */
2425 HOWTO (R_MICROMIPS_SUB, /* type */
2426 0, /* rightshift */
2427 4, /* size (0 = byte, 1 = short, 2 = long) */
2428 64, /* bitsize */
2429 FALSE, /* pc_relative */
2430 0, /* bitpos */
2431 complain_overflow_dont, /* complain_on_overflow */
2432 _bfd_mips_elf_generic_reloc, /* special_function */
2433 "R_MICROMIPS_SUB", /* name */
2434 FALSE, /* partial_inplace */
72c4ab07 2435 0, /* src_mask */
df58fc94
RS
2436 MINUS_ONE, /* dst_mask */
2437 FALSE), /* pcrel_offset */
2438
2439 /* Get the higher value of a 64 bit addend. */
2440 HOWTO (R_MICROMIPS_HIGHER, /* type */
2441 0, /* rightshift */
2442 2, /* size (0 = byte, 1 = short, 2 = long) */
2443 16, /* bitsize */
2444 FALSE, /* pc_relative */
2445 0, /* bitpos */
2446 complain_overflow_dont, /* complain_on_overflow */
2447 _bfd_mips_elf_generic_reloc, /* special_function */
2448 "R_MICROMIPS_HIGHER", /* name */
2449 FALSE, /* partial_inplace */
72c4ab07 2450 0, /* src_mask */
df58fc94
RS
2451 0x0000ffff, /* dst_mask */
2452 FALSE), /* pcrel_offset */
2453
2454 /* Get the highest value of a 64 bit addend. */
2455 HOWTO (R_MICROMIPS_HIGHEST, /* type */
2456 0, /* rightshift */
2457 2, /* size (0 = byte, 1 = short, 2 = long) */
2458 16, /* bitsize */
2459 FALSE, /* pc_relative */
2460 0, /* bitpos */
2461 complain_overflow_dont, /* complain_on_overflow */
2462 _bfd_mips_elf_generic_reloc, /* special_function */
2463 "R_MICROMIPS_HIGHEST", /* name */
2464 FALSE, /* partial_inplace */
72c4ab07 2465 0, /* src_mask */
df58fc94
RS
2466 0x0000ffff, /* dst_mask */
2467 FALSE), /* pcrel_offset */
2468
2469 /* High 16 bits of displacement in global offset table. */
2470 HOWTO (R_MICROMIPS_CALL_HI16, /* type */
2471 0, /* rightshift */
2472 2, /* size (0 = byte, 1 = short, 2 = long) */
2473 16, /* bitsize */
2474 FALSE, /* pc_relative */
2475 0, /* bitpos */
2476 complain_overflow_dont, /* complain_on_overflow */
2477 _bfd_mips_elf_generic_reloc, /* special_function */
2478 "R_MICROMIPS_CALL_HI16",/* name */
2479 FALSE, /* partial_inplace */
72c4ab07 2480 0, /* src_mask */
df58fc94
RS
2481 0x0000ffff, /* dst_mask */
2482 FALSE), /* pcrel_offset */
2483
2484 /* Low 16 bits of displacement in global offset table. */
2485 HOWTO (R_MICROMIPS_CALL_LO16, /* type */
2486 0, /* rightshift */
2487 2, /* size (0 = byte, 1 = short, 2 = long) */
2488 16, /* bitsize */
2489 FALSE, /* pc_relative */
2490 0, /* bitpos */
2491 complain_overflow_dont, /* complain_on_overflow */
2492 _bfd_mips_elf_generic_reloc, /* special_function */
2493 "R_MICROMIPS_CALL_LO16",/* name */
2494 FALSE, /* partial_inplace */
72c4ab07 2495 0, /* src_mask */
df58fc94
RS
2496 0x0000ffff, /* dst_mask */
2497 FALSE), /* pcrel_offset */
2498};
2499
a4382ec6
TS
2500/* GNU extension to record C++ vtable hierarchy */
2501static reloc_howto_type elf_mips_gnu_vtinherit_howto =
2502 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
2503 0, /* rightshift */
2504 2, /* size (0 = byte, 1 = short, 2 = long) */
2505 0, /* bitsize */
b34976b6 2506 FALSE, /* pc_relative */
a4382ec6
TS
2507 0, /* bitpos */
2508 complain_overflow_dont, /* complain_on_overflow */
2509 NULL, /* special_function */
2510 "R_MIPS_GNU_VTINHERIT", /* name */
b34976b6 2511 FALSE, /* partial_inplace */
a4382ec6
TS
2512 0, /* src_mask */
2513 0, /* dst_mask */
b34976b6 2514 FALSE); /* pcrel_offset */
a4382ec6
TS
2515
2516/* GNU extension to record C++ vtable member usage */
2517static reloc_howto_type elf_mips_gnu_vtentry_howto =
2518 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
2519 0, /* rightshift */
2520 2, /* size (0 = byte, 1 = short, 2 = long) */
2521 0, /* bitsize */
b34976b6 2522 FALSE, /* pc_relative */
a4382ec6
TS
2523 0, /* bitpos */
2524 complain_overflow_dont, /* complain_on_overflow */
2525 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
2526 "R_MIPS_GNU_VTENTRY", /* name */
b34976b6 2527 FALSE, /* partial_inplace */
a4382ec6
TS
2528 0, /* src_mask */
2529 0, /* dst_mask */
b34976b6 2530 FALSE); /* pcrel_offset */
c6e90b02 2531\f
d0c728db
TS
2532/* 16 bit offset for pc-relative branches. */
2533static reloc_howto_type elf_mips_gnu_rel16_s2 =
2534 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
2535 2, /* rightshift */
2536 2, /* size (0 = byte, 1 = short, 2 = long) */
2537 16, /* bitsize */
2538 TRUE, /* pc_relative */
2539 0, /* bitpos */
2540 complain_overflow_signed, /* complain_on_overflow */
30ac9238 2541 _bfd_mips_elf_generic_reloc, /* special_function */
d0c728db
TS
2542 "R_MIPS_GNU_REL16_S2", /* name */
2543 TRUE, /* partial_inplace */
2544 0x0000ffff, /* src_mask */
2545 0x0000ffff, /* dst_mask */
2546 TRUE); /* pcrel_offset */
2547
2548/* 16 bit offset for pc-relative branches. */
2549static reloc_howto_type elf_mips_gnu_rela16_s2 =
2550 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
2551 2, /* rightshift */
2552 2, /* size (0 = byte, 1 = short, 2 = long) */
2553 16, /* bitsize */
2554 TRUE, /* pc_relative */
2555 0, /* bitpos */
2556 complain_overflow_signed, /* complain_on_overflow */
30ac9238 2557 _bfd_mips_elf_generic_reloc, /* special_function */
d0c728db
TS
2558 "R_MIPS_GNU_REL16_S2", /* name */
2559 FALSE, /* partial_inplace */
2560 0, /* src_mask */
2561 0x0000ffff, /* dst_mask */
2562 TRUE); /* pcrel_offset */
2563\f
861fb55a
DJ
2564/* Originally a VxWorks extension, but now used for other systems too. */
2565static reloc_howto_type elf_mips_copy_howto =
2566 HOWTO (R_MIPS_COPY, /* type */
2567 0, /* rightshift */
2568 0, /* this one is variable size */
2569 0, /* bitsize */
2570 FALSE, /* pc_relative */
2571 0, /* bitpos */
2572 complain_overflow_bitfield, /* complain_on_overflow */
2573 bfd_elf_generic_reloc, /* special_function */
2574 "R_MIPS_COPY", /* name */
2575 FALSE, /* partial_inplace */
2576 0x0, /* src_mask */
2577 0x0, /* dst_mask */
2578 FALSE); /* pcrel_offset */
2579
2580/* Originally a VxWorks extension, but now used for other systems too. */
2581static reloc_howto_type elf_mips_jump_slot_howto =
2582 HOWTO (R_MIPS_JUMP_SLOT, /* type */
2583 0, /* rightshift */
2584 4, /* size (0 = byte, 1 = short, 2 = long) */
2585 64, /* bitsize */
2586 FALSE, /* pc_relative */
2587 0, /* bitpos */
2588 complain_overflow_bitfield, /* complain_on_overflow */
2589 bfd_elf_generic_reloc, /* special_function */
2590 "R_MIPS_JUMP_SLOT", /* name */
2591 FALSE, /* partial_inplace */
2592 0x0, /* src_mask */
2593 0x0, /* dst_mask */
2594 FALSE); /* pcrel_offset */
2595\f
252b5132
RH
2596/* Swap in a MIPS 64-bit Rel reloc. */
2597
2598static void
11a2be4d
RS
2599mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src,
2600 Elf64_Mips_Internal_Rela *dst)
252b5132 2601{
dc810e39
AM
2602 dst->r_offset = H_GET_64 (abfd, src->r_offset);
2603 dst->r_sym = H_GET_32 (abfd, src->r_sym);
2604 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
2605 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
2606 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
2607 dst->r_type = H_GET_8 (abfd, src->r_type);
947216bf 2608 dst->r_addend = 0;
252b5132
RH
2609}
2610
2611/* Swap in a MIPS 64-bit Rela reloc. */
2612
2613static void
11a2be4d
RS
2614mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src,
2615 Elf64_Mips_Internal_Rela *dst)
252b5132 2616{
dc810e39
AM
2617 dst->r_offset = H_GET_64 (abfd, src->r_offset);
2618 dst->r_sym = H_GET_32 (abfd, src->r_sym);
2619 dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
2620 dst->r_type3 = H_GET_8 (abfd, src->r_type3);
2621 dst->r_type2 = H_GET_8 (abfd, src->r_type2);
2622 dst->r_type = H_GET_8 (abfd, src->r_type);
2623 dst->r_addend = H_GET_S64 (abfd, src->r_addend);
252b5132
RH
2624}
2625
252b5132
RH
2626/* Swap out a MIPS 64-bit Rel reloc. */
2627
2628static void
11a2be4d
RS
2629mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
2630 Elf64_Mips_External_Rel *dst)
252b5132 2631{
dc810e39
AM
2632 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
2633 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
2634 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
2635 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
2636 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
2637 H_PUT_8 (abfd, src->r_type, dst->r_type);
252b5132
RH
2638}
2639
252b5132
RH
2640/* Swap out a MIPS 64-bit Rela reloc. */
2641
2642static void
11a2be4d
RS
2643mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
2644 Elf64_Mips_External_Rela *dst)
252b5132 2645{
dc810e39
AM
2646 H_PUT_64 (abfd, src->r_offset, dst->r_offset);
2647 H_PUT_32 (abfd, src->r_sym, dst->r_sym);
2648 H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
2649 H_PUT_8 (abfd, src->r_type3, dst->r_type3);
2650 H_PUT_8 (abfd, src->r_type2, dst->r_type2);
2651 H_PUT_8 (abfd, src->r_type, dst->r_type);
5b6a02bc 2652 H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
252b5132
RH
2653}
2654
c7ac6ff8
MM
2655/* Swap in a MIPS 64-bit Rel reloc. */
2656
2657static void
11a2be4d
RS
2658mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src,
2659 Elf_Internal_Rela *dst)
c7ac6ff8 2660{
947216bf 2661 Elf64_Mips_Internal_Rela mirel;
c7ac6ff8 2662
fe8bc63d 2663 mips_elf64_swap_reloc_in (abfd,
c7ac6ff8
MM
2664 (const Elf64_Mips_External_Rel *) src,
2665 &mirel);
2666
2667 dst[0].r_offset = mirel.r_offset;
5b6a02bc 2668 dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
947216bf 2669 dst[0].r_addend = 0;
c7ac6ff8 2670 dst[1].r_offset = mirel.r_offset;
5b6a02bc 2671 dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
947216bf 2672 dst[1].r_addend = 0;
c7ac6ff8 2673 dst[2].r_offset = mirel.r_offset;
5b6a02bc 2674 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
947216bf 2675 dst[2].r_addend = 0;
c7ac6ff8
MM
2676}
2677
2678/* Swap in a MIPS 64-bit Rela reloc. */
2679
2680static void
11a2be4d
RS
2681mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src,
2682 Elf_Internal_Rela *dst)
c7ac6ff8
MM
2683{
2684 Elf64_Mips_Internal_Rela mirela;
2685
fe8bc63d 2686 mips_elf64_swap_reloca_in (abfd,
c7ac6ff8
MM
2687 (const Elf64_Mips_External_Rela *) src,
2688 &mirela);
2689
2690 dst[0].r_offset = mirela.r_offset;
5b6a02bc 2691 dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
c7ac6ff8
MM
2692 dst[0].r_addend = mirela.r_addend;
2693 dst[1].r_offset = mirela.r_offset;
5b6a02bc 2694 dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
c7ac6ff8
MM
2695 dst[1].r_addend = 0;
2696 dst[2].r_offset = mirela.r_offset;
5b6a02bc 2697 dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
c7ac6ff8
MM
2698 dst[2].r_addend = 0;
2699}
2700
2701/* Swap out a MIPS 64-bit Rel reloc. */
2702
2703static void
11a2be4d
RS
2704mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src,
2705 bfd_byte *dst)
c7ac6ff8 2706{
947216bf 2707 Elf64_Mips_Internal_Rela mirel;
c7ac6ff8 2708
5b6a02bc
TS
2709 mirel.r_offset = src[0].r_offset;
2710 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
b0189df0 2711 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
5b6a02bc
TS
2712
2713 mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
2714 mirel.r_sym = ELF64_R_SYM (src[0].r_info);
a902ee94 2715 mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
5b6a02bc 2716 mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
a902ee94 2717 mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
c7ac6ff8 2718
fe8bc63d 2719 mips_elf64_swap_reloc_out (abfd, &mirel,
c7ac6ff8
MM
2720 (Elf64_Mips_External_Rel *) dst);
2721}
2722
2723/* Swap out a MIPS 64-bit Rela reloc. */
2724
2725static void
11a2be4d
RS
2726mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
2727 bfd_byte *dst)
c7ac6ff8
MM
2728{
2729 Elf64_Mips_Internal_Rela mirela;
2730
5b6a02bc
TS
2731 mirela.r_offset = src[0].r_offset;
2732 BFD_ASSERT(src[0].r_offset == src[1].r_offset);
2733 BFD_ASSERT(src[0].r_offset == src[2].r_offset);
2734
2735 mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
2736 mirela.r_sym = ELF64_R_SYM (src[0].r_info);
2737 mirela.r_addend = src[0].r_addend;
2738 BFD_ASSERT(src[1].r_addend == 0);
2739 BFD_ASSERT(src[2].r_addend == 0);
2740
47293a4c 2741 mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
5b6a02bc 2742 mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
47293a4c 2743 mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
c7ac6ff8 2744
fe8bc63d 2745 mips_elf64_swap_reloca_out (abfd, &mirela,
c7ac6ff8
MM
2746 (Elf64_Mips_External_Rela *) dst);
2747}
c6e90b02 2748\f
b34976b6 2749/* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
5b6a02bc 2750 dangerous relocation. */
252b5132 2751
b34976b6 2752static bfd_boolean
11a2be4d 2753mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp)
252b5132 2754{
252b5132 2755 unsigned int count;
5b6a02bc 2756 asymbol **sym;
252b5132 2757 unsigned int i;
252b5132 2758
5b6a02bc
TS
2759 /* If we've already figured out what GP will be, just return it. */
2760 *pgp = _bfd_get_gp_value (output_bfd);
2761 if (*pgp)
b34976b6 2762 return TRUE;
252b5132 2763
5b6a02bc
TS
2764 count = bfd_get_symcount (output_bfd);
2765 sym = bfd_get_outsymbols (output_bfd);
252b5132 2766
5b6a02bc
TS
2767 /* The linker script will have created a symbol named `_gp' with the
2768 appropriate value. */
11a2be4d 2769 if (sym == NULL)
5b6a02bc
TS
2770 i = count;
2771 else
2772 {
2773 for (i = 0; i < count; i++, sym++)
2774 {
3f9c735e 2775 register const char *name;
252b5132 2776
5b6a02bc
TS
2777 name = bfd_asymbol_name (*sym);
2778 if (*name == '_' && strcmp (name, "_gp") == 0)
2779 {
2780 *pgp = bfd_asymbol_value (*sym);
2781 _bfd_set_gp_value (output_bfd, *pgp);
2782 break;
2783 }
2784 }
2785 }
252b5132 2786
5b6a02bc
TS
2787 if (i >= count)
2788 {
2789 /* Only get the error once. */
2790 *pgp = 4;
2791 _bfd_set_gp_value (output_bfd, *pgp);
b34976b6 2792 return FALSE;
5b6a02bc 2793 }
252b5132 2794
b34976b6 2795 return TRUE;
5b6a02bc 2796}
252b5132 2797
5b6a02bc
TS
2798/* We have to figure out the gp value, so that we can adjust the
2799 symbol value correctly. We look up the symbol _gp in the output
2800 BFD. If we can't find it, we're stuck. We cache it in the ELF
2801 target data. We don't need to adjust the symbol value for an
1049f94e 2802 external symbol if we are producing relocatable output. */
5b6a02bc
TS
2803
2804static bfd_reloc_status_type
11a2be4d
RS
2805mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
2806 char **error_message, bfd_vma *pgp)
5b6a02bc
TS
2807{
2808 if (bfd_is_und_section (symbol->section)
1049f94e 2809 && ! relocatable)
252b5132 2810 {
5b6a02bc
TS
2811 *pgp = 0;
2812 return bfd_reloc_undefined;
2813 }
252b5132 2814
5b6a02bc
TS
2815 *pgp = _bfd_get_gp_value (output_bfd);
2816 if (*pgp == 0
1049f94e 2817 && (! relocatable
5b6a02bc
TS
2818 || (symbol->flags & BSF_SECTION_SYM) != 0))
2819 {
1049f94e 2820 if (relocatable)
252b5132 2821 {
5b6a02bc 2822 /* Make up a value. */
a902ee94 2823 *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
5b6a02bc
TS
2824 _bfd_set_gp_value (output_bfd, *pgp);
2825 }
2826 else if (!mips_elf64_assign_gp (output_bfd, pgp))
2827 {
2828 *error_message =
2829 (char *) _("GP relative relocation when _gp not defined");
2830 return bfd_reloc_dangerous;
252b5132 2831 }
5b6a02bc 2832 }
252b5132 2833
5b6a02bc
TS
2834 return bfd_reloc_ok;
2835}
252b5132 2836
5b6a02bc
TS
2837/* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
2838 become the offset from the gp register. */
252b5132 2839
a4382ec6 2840static bfd_reloc_status_type
11a2be4d
RS
2841mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2842 void *data, asection *input_section, bfd *output_bfd,
2843 char **error_message)
5b6a02bc 2844{
1049f94e 2845 bfd_boolean relocatable;
5b6a02bc
TS
2846 bfd_reloc_status_type ret;
2847 bfd_vma gp;
2848
a7ebbfdf
TS
2849 /* If we're relocating, and this is an external symbol, we don't want
2850 to change anything. */
11a2be4d 2851 if (output_bfd != NULL
5b6a02bc 2852 && (symbol->flags & BSF_SECTION_SYM) == 0
a7ebbfdf 2853 && (symbol->flags & BSF_LOCAL) != 0)
5b6a02bc
TS
2854 {
2855 reloc_entry->address += input_section->output_offset;
2856 return bfd_reloc_ok;
2857 }
2858
11a2be4d 2859 if (output_bfd != NULL)
1049f94e 2860 relocatable = TRUE;
5b6a02bc
TS
2861 else
2862 {
1049f94e 2863 relocatable = FALSE;
5b6a02bc
TS
2864 output_bfd = symbol->section->output_section->owner;
2865 }
2866
1049f94e 2867 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
5b6a02bc
TS
2868 &gp);
2869 if (ret != bfd_reloc_ok)
2870 return ret;
2871
c6e90b02 2872 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1049f94e 2873 input_section, relocatable,
c6e90b02 2874 data, gp);
5b6a02bc
TS
2875}
2876
a4382ec6 2877/* Do a R_MIPS_LITERAL relocation. */
5b6a02bc 2878
a4382ec6 2879static bfd_reloc_status_type
11a2be4d
RS
2880mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2881 void *data, asection *input_section, bfd *output_bfd,
2882 char **error_message)
5b6a02bc 2883{
1049f94e 2884 bfd_boolean relocatable;
a4382ec6 2885 bfd_reloc_status_type ret;
5b6a02bc
TS
2886 bfd_vma gp;
2887
254f0426 2888 /* R_MIPS_LITERAL relocations are defined for local symbols only. */
11a2be4d 2889 if (output_bfd != NULL
5b6a02bc 2890 && (symbol->flags & BSF_SECTION_SYM) == 0
a7ebbfdf 2891 && (symbol->flags & BSF_LOCAL) != 0)
5b6a02bc 2892 {
254f0426
MR
2893 *error_message = (char *)
2894 _("literal relocation occurs for an external symbol");
2895 return bfd_reloc_outofrange;
5b6a02bc
TS
2896 }
2897
a4382ec6 2898 /* FIXME: The entries in the .lit8 and .lit4 sections should be merged. */
11a2be4d 2899 if (output_bfd != NULL)
1049f94e 2900 relocatable = TRUE;
5b6a02bc
TS
2901 else
2902 {
1049f94e 2903 relocatable = FALSE;
5b6a02bc
TS
2904 output_bfd = symbol->section->output_section->owner;
2905 }
2906
1049f94e 2907 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
a4382ec6
TS
2908 &gp);
2909 if (ret != bfd_reloc_ok)
2910 return ret;
5b6a02bc 2911
a4382ec6 2912 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1049f94e 2913 input_section, relocatable,
a4382ec6 2914 data, gp);
5b6a02bc
TS
2915}
2916
a4382ec6
TS
2917/* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
2918 become the offset from the gp register. */
5b6a02bc 2919
a4382ec6 2920static bfd_reloc_status_type
11a2be4d
RS
2921mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2922 void *data, asection *input_section, bfd *output_bfd,
2923 char **error_message)
5b6a02bc 2924{
1049f94e 2925 bfd_boolean relocatable;
5b6a02bc
TS
2926 bfd_reloc_status_type ret;
2927 bfd_vma gp;
2928 bfd_vma relocation;
a7ebbfdf 2929 bfd_vma val;
5b6a02bc 2930
765f2ef6 2931 /* R_MIPS_GPREL32 relocations are defined for local symbols only. */
11a2be4d 2932 if (output_bfd != NULL
5b6a02bc 2933 && (symbol->flags & BSF_SECTION_SYM) == 0
a7ebbfdf 2934 && (symbol->flags & BSF_LOCAL) != 0)
5b6a02bc
TS
2935 {
2936 *error_message = (char *)
2937 _("32bits gp relative relocation occurs for an external symbol");
2938 return bfd_reloc_outofrange;
2939 }
2940
11a2be4d 2941 if (output_bfd != NULL)
1049f94e 2942 relocatable = TRUE;
5b6a02bc
TS
2943 else
2944 {
1049f94e 2945 relocatable = FALSE;
5b6a02bc 2946 output_bfd = symbol->section->output_section->owner;
5b6a02bc
TS
2947 }
2948
99277196
MR
2949 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
2950 error_message, &gp);
2951 if (ret != bfd_reloc_ok)
2952 return ret;
a7ebbfdf 2953
5b6a02bc
TS
2954 if (bfd_is_com_section (symbol->section))
2955 relocation = 0;
2956 else
2957 relocation = symbol->value;
2958
2959 relocation += symbol->section->output_section->vma;
2960 relocation += symbol->section->output_offset;
2961
07515404 2962 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
5b6a02bc
TS
2963 return bfd_reloc_outofrange;
2964
5b6a02bc 2965 /* Set val to the offset into the section or symbol. */
a7ebbfdf
TS
2966 val = reloc_entry->addend;
2967
2968 if (reloc_entry->howto->partial_inplace)
2969 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
5b6a02bc
TS
2970
2971 /* Adjust val for the final section location and GP value. If we
1049f94e 2972 are producing relocatable output, we don't want to do this for
5b6a02bc 2973 an external symbol. */
1049f94e 2974 if (! relocatable
5b6a02bc
TS
2975 || (symbol->flags & BSF_SECTION_SYM) != 0)
2976 val += relocation - gp;
2977
a7ebbfdf
TS
2978 if (reloc_entry->howto->partial_inplace)
2979 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
2980 else
2981 reloc_entry->addend = val;
5b6a02bc 2982
1049f94e 2983 if (relocatable)
5b6a02bc
TS
2984 reloc_entry->address += input_section->output_offset;
2985
2986 return bfd_reloc_ok;
2987}
2988
2989/* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
a4382ec6 2990 the rest is at bits 6-10. The bitpos already got right by the howto. */
5b6a02bc 2991
a4382ec6 2992static bfd_reloc_status_type
30ac9238
RS
2993mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2994 void *data, asection *input_section, bfd *output_bfd,
2995 char **error_message)
5b6a02bc 2996{
a7ebbfdf
TS
2997 if (reloc_entry->howto->partial_inplace)
2998 {
2999 reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
3000 | (reloc_entry->addend & 0x00000800) >> 9);
3001 }
5b6a02bc 3002
30ac9238
RS
3003 return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
3004 input_section, output_bfd,
3005 error_message);
5b6a02bc
TS
3006}
3007
a4382ec6
TS
3008/* Handle a mips16 GP relative reloc. */
3009
3010static bfd_reloc_status_type
11a2be4d
RS
3011mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3012 void *data, asection *input_section, bfd *output_bfd,
3013 char **error_message)
a4382ec6 3014{
1049f94e 3015 bfd_boolean relocatable;
a4382ec6 3016 bfd_reloc_status_type ret;
d6f16593 3017 bfd_byte *location;
a4382ec6 3018 bfd_vma gp;
a4382ec6 3019
7f05722e
MR
3020 /* If we're relocating, and this is an external symbol, we don't want
3021 to change anything. */
a4382ec6
TS
3022 if (output_bfd != NULL
3023 && (symbol->flags & BSF_SECTION_SYM) == 0
a7ebbfdf 3024 && (symbol->flags & BSF_LOCAL) != 0)
a4382ec6
TS
3025 {
3026 reloc_entry->address += input_section->output_offset;
3027 return bfd_reloc_ok;
3028 }
3029
3030 if (output_bfd != NULL)
1049f94e 3031 relocatable = TRUE;
a4382ec6
TS
3032 else
3033 {
1049f94e 3034 relocatable = FALSE;
a4382ec6
TS
3035 output_bfd = symbol->section->output_section->owner;
3036 }
3037
1049f94e 3038 ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
a4382ec6
TS
3039 &gp);
3040 if (ret != bfd_reloc_ok)
3041 return ret;
3042
d6f16593 3043 location = (bfd_byte *) data + reloc_entry->address;
df58fc94
RS
3044 _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
3045 location);
d6f16593
MR
3046 ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
3047 input_section, relocatable,
3048 data, gp);
df58fc94
RS
3049 _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
3050 location);
a7ebbfdf 3051
d6f16593 3052 return ret;
a4382ec6
TS
3053}
3054\f
3055/* A mapping from BFD reloc types to MIPS ELF reloc types. */
3056
3057struct elf_reloc_map {
3058 bfd_reloc_code_real_type bfd_val;
3059 enum elf_mips_reloc_type elf_val;
3060};
3061
3062static const struct elf_reloc_map mips_reloc_map[] =
3063{
3064 { BFD_RELOC_NONE, R_MIPS_NONE },
3065 { BFD_RELOC_16, R_MIPS_16 },
3066 { BFD_RELOC_32, R_MIPS_32 },
3067 /* There is no BFD reloc for R_MIPS_REL32. */
3068 { BFD_RELOC_64, R_MIPS_64 },
3069 { BFD_RELOC_CTOR, R_MIPS_64 },
bad36eac 3070 { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
a4382ec6
TS
3071 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
3072 { BFD_RELOC_LO16, R_MIPS_LO16 },
3073 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
3074 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
3075 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
3076 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
3077 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
3078 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
3079 { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
3080 { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
3081 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
3082 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
3083 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
3084 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
3085 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
3086 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
3087 { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
3088 { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
3089 { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
3090 { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
3091 { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
3092 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
3093 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
3094 { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
3095 { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
3096 /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated. */
3097 { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
0f20cc35
DJ
3098 { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
3099 { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
3100 { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
3101 { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
3102 { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
3103 { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
3104 { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
3105 { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
3106 { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
3107 { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
3108 { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
3109 { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
3110 { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
3111 { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
a4382ec6
TS
3112};
3113
d6f16593
MR
3114static const struct elf_reloc_map mips16_reloc_map[] =
3115{
3116 { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
3117 { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
738e5348
RS
3118 { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
3119 { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
d6f16593
MR
3120 { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
3121 { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
d0f13682
CLT
3122 { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
3123 { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
3124 { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
3125 R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
3126 { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
3127 R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
3128 { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
3129 { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
3130 { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
d6f16593
MR
3131};
3132
df58fc94
RS
3133static const struct elf_reloc_map micromips_reloc_map[] =
3134{
3135 { BFD_RELOC_MICROMIPS_JMP, R_MICROMIPS_26_S1 - R_MICROMIPS_min },
3136 { BFD_RELOC_MICROMIPS_HI16_S, R_MICROMIPS_HI16 - R_MICROMIPS_min },
3137 { BFD_RELOC_MICROMIPS_LO16, R_MICROMIPS_LO16 - R_MICROMIPS_min },
3138 { BFD_RELOC_MICROMIPS_GPREL16, R_MICROMIPS_GPREL16 - R_MICROMIPS_min },
3139 { BFD_RELOC_MICROMIPS_LITERAL, R_MICROMIPS_LITERAL - R_MICROMIPS_min },
3140 { BFD_RELOC_MICROMIPS_GOT16, R_MICROMIPS_GOT16 - R_MICROMIPS_min },
3141 { BFD_RELOC_MICROMIPS_7_PCREL_S1, R_MICROMIPS_PC7_S1 - R_MICROMIPS_min },
3142 { BFD_RELOC_MICROMIPS_10_PCREL_S1, R_MICROMIPS_PC10_S1 - R_MICROMIPS_min },
3143 { BFD_RELOC_MICROMIPS_16_PCREL_S1, R_MICROMIPS_PC16_S1 - R_MICROMIPS_min },
3144 { BFD_RELOC_MICROMIPS_CALL16, R_MICROMIPS_CALL16 - R_MICROMIPS_min },
3145 { BFD_RELOC_MICROMIPS_GOT_DISP, R_MICROMIPS_GOT_DISP - R_MICROMIPS_min },
3146 { BFD_RELOC_MICROMIPS_GOT_PAGE, R_MICROMIPS_GOT_PAGE - R_MICROMIPS_min },
3147 { BFD_RELOC_MICROMIPS_GOT_OFST, R_MICROMIPS_GOT_OFST - R_MICROMIPS_min },
3148 { BFD_RELOC_MICROMIPS_GOT_HI16, R_MICROMIPS_GOT_HI16 - R_MICROMIPS_min },
3149 { BFD_RELOC_MICROMIPS_GOT_LO16, R_MICROMIPS_GOT_LO16 - R_MICROMIPS_min },
3150 { BFD_RELOC_MICROMIPS_SUB, R_MICROMIPS_SUB - R_MICROMIPS_min },
3151 { BFD_RELOC_MICROMIPS_HIGHER, R_MICROMIPS_HIGHER - R_MICROMIPS_min },
3152 { BFD_RELOC_MICROMIPS_HIGHEST, R_MICROMIPS_HIGHEST - R_MICROMIPS_min },
3153 { BFD_RELOC_MICROMIPS_CALL_HI16, R_MICROMIPS_CALL_HI16 - R_MICROMIPS_min },
3154 { BFD_RELOC_MICROMIPS_CALL_LO16, R_MICROMIPS_CALL_LO16 - R_MICROMIPS_min },
3155};
5b6a02bc
TS
3156/* Given a BFD reloc type, return a howto structure. */
3157
3158static reloc_howto_type *
11a2be4d
RS
3159bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3160 bfd_reloc_code_real_type code)
5b6a02bc 3161{
a4382ec6 3162 unsigned int i;
5b6a02bc
TS
3163 /* FIXME: We default to RELA here instead of choosing the right
3164 relocation variant. */
3165 reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
d6f16593 3166 reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela;
df58fc94 3167 reloc_howto_type *howto_micromips_table = micromips_elf64_howto_table_rela;
5b6a02bc 3168
a4382ec6
TS
3169 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
3170 i++)
3171 {
3172 if (mips_reloc_map[i].bfd_val == code)
3173 return &howto_table[(int) mips_reloc_map[i].elf_val];
3174 }
3175
d6f16593
MR
3176 for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
3177 i++)
3178 {
3179 if (mips16_reloc_map[i].bfd_val == code)
3180 return &howto16_table[(int) mips16_reloc_map[i].elf_val];
3181 }
3182
df58fc94
RS
3183 for (i = 0; i < sizeof (micromips_reloc_map) / sizeof (struct elf_reloc_map);
3184 i++)
3185 {
3186 if (micromips_reloc_map[i].bfd_val == code)
3187 return &howto_micromips_table[(int) micromips_reloc_map[i].elf_val];
3188 }
3189
5b6a02bc
TS
3190 switch (code)
3191 {
5b6a02bc
TS
3192 case BFD_RELOC_VTABLE_INHERIT:
3193 return &elf_mips_gnu_vtinherit_howto;
3194 case BFD_RELOC_VTABLE_ENTRY:
3195 return &elf_mips_gnu_vtentry_howto;
861fb55a
DJ
3196 case BFD_RELOC_MIPS_COPY:
3197 return &elf_mips_copy_howto;
3198 case BFD_RELOC_MIPS_JUMP_SLOT:
3199 return &elf_mips_jump_slot_howto;
5b6a02bc
TS
3200 default:
3201 bfd_set_error (bfd_error_bad_value);
3202 return NULL;
3203 }
3204}
3205
157090f7
AM
3206static reloc_howto_type *
3207bfd_elf64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3208 const char *r_name)
3209{
3210 unsigned int i;
3211
3212 for (i = 0;
3213 i < (sizeof (mips_elf64_howto_table_rela)
3214 / sizeof (mips_elf64_howto_table_rela[0])); i++)
3215 if (mips_elf64_howto_table_rela[i].name != NULL
3216 && strcasecmp (mips_elf64_howto_table_rela[i].name, r_name) == 0)
3217 return &mips_elf64_howto_table_rela[i];
3218
3219 for (i = 0;
3220 i < (sizeof (mips16_elf64_howto_table_rela)
3221 / sizeof (mips16_elf64_howto_table_rela[0]));
3222 i++)
3223 if (mips16_elf64_howto_table_rela[i].name != NULL
3224 && strcasecmp (mips16_elf64_howto_table_rela[i].name, r_name) == 0)
3225 return &mips16_elf64_howto_table_rela[i];
3226
df58fc94
RS
3227 for (i = 0;
3228 i < (sizeof (micromips_elf64_howto_table_rela)
3229 / sizeof (micromips_elf64_howto_table_rela[0]));
3230 i++)
3231 if (micromips_elf64_howto_table_rela[i].name != NULL
3232 && strcasecmp (micromips_elf64_howto_table_rela[i].name, r_name) == 0)
3233 return &micromips_elf64_howto_table_rela[i];
3234
157090f7
AM
3235 if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
3236 return &elf_mips_gnu_vtinherit_howto;
3237 if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
3238 return &elf_mips_gnu_vtentry_howto;
3239 if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
3240 return &elf_mips_gnu_rel16_s2;
3241 if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
3242 return &elf_mips_gnu_rela16_s2;
861fb55a
DJ
3243 if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
3244 return &elf_mips_copy_howto;
3245 if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
3246 return &elf_mips_jump_slot_howto;
157090f7
AM
3247
3248 return NULL;
3249}
3250
947216bf 3251/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
c6e90b02
TS
3252
3253static reloc_howto_type *
11a2be4d 3254mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
c6e90b02
TS
3255{
3256 switch (r_type)
3257 {
c6e90b02
TS
3258 case R_MIPS_GNU_VTINHERIT:
3259 return &elf_mips_gnu_vtinherit_howto;
c6e90b02
TS
3260 case R_MIPS_GNU_VTENTRY:
3261 return &elf_mips_gnu_vtentry_howto;
d0c728db
TS
3262 case R_MIPS_GNU_REL16_S2:
3263 if (rela_p)
3264 return &elf_mips_gnu_rela16_s2;
3265 else
3266 return &elf_mips_gnu_rel16_s2;
861fb55a
DJ
3267 case R_MIPS_COPY:
3268 return &elf_mips_copy_howto;
3269 case R_MIPS_JUMP_SLOT:
3270 return &elf_mips_jump_slot_howto;
c6e90b02 3271 default:
df58fc94
RS
3272 if (r_type >= R_MICROMIPS_min && r_type < R_MICROMIPS_max)
3273 {
3274 if (rela_p)
3275 return &micromips_elf64_howto_table_rela[r_type - R_MICROMIPS_min];
3276 else
3277 return &micromips_elf64_howto_table_rel[r_type - R_MICROMIPS_min];
3278 }
d6f16593
MR
3279 if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
3280 {
3281 if (rela_p)
3282 return &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min];
3283 else
3284 return &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min];
3285 }
c6e90b02
TS
3286 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
3287 if (rela_p)
3288 return &mips_elf64_howto_table_rela[r_type];
3289 else
3290 return &mips_elf64_howto_table_rel[r_type];
3291 break;
3292 }
3293}
3294
5b6a02bc
TS
3295/* Prevent relocation handling by bfd for MIPS ELF64. */
3296
3297static void
11a2be4d
RS
3298mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
3299 arelent *cache_ptr ATTRIBUTE_UNUSED,
3300 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
5b6a02bc
TS
3301{
3302 BFD_ASSERT (0);
3303}
3304
3305static void
11a2be4d
RS
3306mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
3307 arelent *cache_ptr ATTRIBUTE_UNUSED,
3308 Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
5b6a02bc
TS
3309{
3310 BFD_ASSERT (0);
3311}
3312
3313/* Since each entry in an SHT_REL or SHT_RELA section can represent up
3314 to three relocs, we must tell the user to allocate more space. */
3315
3316static long
11a2be4d 3317mips_elf64_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
5b6a02bc
TS
3318{
3319 return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
3320}
3321
fee24f1c 3322static long
11a2be4d 3323mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
fee24f1c
AO
3324{
3325 return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
3326}
3327
3328/* We must also copy more relocations than the corresponding functions
3329 in elf.c would, so the two following functions are slightly
3330 modified from elf.c, that multiply the external relocation count by
3331 3 to obtain the internal relocation count. */
3332
3333static long
11a2be4d
RS
3334mips_elf64_canonicalize_reloc (bfd *abfd, sec_ptr section,
3335 arelent **relptr, asymbol **symbols)
fee24f1c
AO
3336{
3337 arelent *tblptr;
3338 unsigned int i;
9c5bfbb7 3339 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
fee24f1c
AO
3340
3341 if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
3342 return -1;
3343
3344 tblptr = section->relocation;
3345 for (i = 0; i < section->reloc_count * 3; i++)
3346 *relptr++ = tblptr++;
3347
3348 *relptr = NULL;
3349
3350 return section->reloc_count * 3;
3351}
3352
3353static long
11a2be4d
RS
3354mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
3355 asymbol **syms)
fee24f1c 3356{
11a2be4d 3357 bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
fee24f1c
AO
3358 asection *s;
3359 long ret;
3360
3361 if (elf_dynsymtab (abfd) == 0)
3362 {
3363 bfd_set_error (bfd_error_invalid_operation);
3364 return -1;
3365 }
3366
3367 slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
3368 ret = 0;
3369 for (s = abfd->sections; s != NULL; s = s->next)
3370 {
3371 if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
3372 && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
3373 || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
3374 {
3375 arelent *p;
3376 long count, i;
3377
3378 if (! (*slurp_relocs) (abfd, s, syms, TRUE))
3379 return -1;
eea6121a 3380 count = s->size / elf_section_data (s)->this_hdr.sh_entsize * 3;
fee24f1c
AO
3381 p = s->relocation;
3382 for (i = 0; i < count; i++)
3383 *storage++ = p++;
3384 ret += count;
3385 }
3386 }
3387
3388 *storage = NULL;
3389
3390 return ret;
3391}
3392
3393/* Read the relocations from one reloc section. This is mostly copied
3394 from elfcode.h, except for the changes to expand one external
3395 relocation to 3 internal ones. We must unfortunately set
3396 reloc_count to the number of external relocations, because a lot of
3397 generic code seems to depend on this. */
5b6a02bc 3398
b34976b6 3399static bfd_boolean
11a2be4d
RS
3400mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
3401 Elf_Internal_Shdr *rel_hdr,
3402 bfd_size_type reloc_count,
3403 arelent *relents, asymbol **symbols,
3404 bfd_boolean dynamic)
5b6a02bc 3405{
11a2be4d 3406 void *allocated;
5b6a02bc 3407 bfd_byte *native_relocs;
5b6a02bc 3408 arelent *relent;
5b6a02bc
TS
3409 bfd_vma i;
3410 int entsize;
32159579 3411 bfd_boolean rela_p;
5b6a02bc 3412
11a2be4d 3413 allocated = bfd_malloc (rel_hdr->sh_size);
5b6a02bc 3414 if (allocated == NULL)
b34976b6 3415 return FALSE;
5b6a02bc
TS
3416
3417 if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
fee24f1c
AO
3418 || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
3419 != rel_hdr->sh_size))
5b6a02bc
TS
3420 goto error_return;
3421
11a2be4d 3422 native_relocs = allocated;
5b6a02bc 3423
5b6a02bc
TS
3424 entsize = rel_hdr->sh_entsize;
3425 BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
3426 || entsize == sizeof (Elf64_Mips_External_Rela));
3427
5b6a02bc 3428 if (entsize == sizeof (Elf64_Mips_External_Rel))
32159579 3429 rela_p = FALSE;
5b6a02bc 3430 else
32159579 3431 rela_p = TRUE;
5b6a02bc 3432
fee24f1c
AO
3433 for (i = 0, relent = relents;
3434 i < reloc_count;
3435 i++, native_relocs += entsize)
5b6a02bc
TS
3436 {
3437 Elf64_Mips_Internal_Rela rela;
b34976b6 3438 bfd_boolean used_sym, used_ssym;
5b6a02bc
TS
3439 int ir;
3440
3441 if (entsize == sizeof (Elf64_Mips_External_Rela))
3442 mips_elf64_swap_reloca_in (abfd,
3443 (Elf64_Mips_External_Rela *) native_relocs,
3444 &rela);
3445 else
947216bf
AM
3446 mips_elf64_swap_reloc_in (abfd,
3447 (Elf64_Mips_External_Rel *) native_relocs,
3448 &rela);
5b6a02bc 3449
49179469 3450 /* Each entry represents exactly three actual relocations. */
5b6a02bc 3451
b34976b6
AM
3452 used_sym = FALSE;
3453 used_ssym = FALSE;
5b6a02bc
TS
3454 for (ir = 0; ir < 3; ir++)
3455 {
3456 enum elf_mips_reloc_type type;
3457
3458 switch (ir)
252b5132
RH
3459 {
3460 default:
3461 abort ();
3462 case 0:
3463 type = (enum elf_mips_reloc_type) rela.r_type;
3464 break;
3465 case 1:
3466 type = (enum elf_mips_reloc_type) rela.r_type2;
3467 break;
3468 case 2:
3469 type = (enum elf_mips_reloc_type) rela.r_type3;
3470 break;
3471 }
3472
252b5132
RH
3473 /* Some types require symbols, whereas some do not. */
3474 switch (type)
3475 {
3476 case R_MIPS_NONE:
3477 case R_MIPS_LITERAL:
3478 case R_MIPS_INSERT_A:
3479 case R_MIPS_INSERT_B:
3480 case R_MIPS_DELETE:
3481 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3482 break;
3483
3484 default:
3485 if (! used_sym)
3486 {
cf35638d 3487 if (rela.r_sym == STN_UNDEF)
252b5132
RH
3488 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3489 else
3490 {
3491 asymbol **ps, *s;
3492
3493 ps = symbols + rela.r_sym - 1;
3494 s = *ps;
3495 if ((s->flags & BSF_SECTION_SYM) == 0)
3496 relent->sym_ptr_ptr = ps;
3497 else
3498 relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
3499 }
3500
b34976b6 3501 used_sym = TRUE;
252b5132
RH
3502 }
3503 else if (! used_ssym)
3504 {
3505 switch (rela.r_ssym)
3506 {
3507 case RSS_UNDEF:
3508 relent->sym_ptr_ptr =
3509 bfd_abs_section_ptr->symbol_ptr_ptr;
3510 break;
3511
3512 case RSS_GP:
3513 case RSS_GP0:
3514 case RSS_LOC:
3515 /* FIXME: I think these need to be handled using
99277196 3516 special howto structures. */
252b5132
RH
3517 BFD_ASSERT (0);
3518 break;
3519
3520 default:
3521 BFD_ASSERT (0);
3522 break;
3523 }
3524
b34976b6 3525 used_ssym = TRUE;
252b5132
RH
3526 }
3527 else
3528 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3529
3530 break;
3531 }
3532
3533 /* The address of an ELF reloc is section relative for an
3534 object file, and absolute for an executable file or
3535 shared library. The address of a BFD reloc is always
3536 section relative. */
fee24f1c 3537 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
252b5132
RH
3538 relent->address = rela.r_offset;
3539 else
3540 relent->address = rela.r_offset - asect->vma;
3541
3542 relent->addend = rela.r_addend;
3543
32159579 3544 relent->howto = mips_elf64_rtype_to_howto (type, rela_p);
252b5132
RH
3545
3546 ++relent;
3547 }
3548 }
3549
49179469 3550 asect->reloc_count += (relent - relents) / 3;
252b5132
RH
3551
3552 if (allocated != NULL)
3553 free (allocated);
3554
b34976b6 3555 return TRUE;
252b5132
RH
3556
3557 error_return:
3558 if (allocated != NULL)
3559 free (allocated);
b34976b6 3560 return FALSE;
252b5132
RH
3561}
3562
3563/* Read the relocations. On Irix 6, there can be two reloc sections
fee24f1c
AO
3564 associated with a single data section. This is copied from
3565 elfcode.h as well, with changes as small as accounting for 3
3566 internal relocs per external reloc and resetting reloc_count to
3567 zero before processing the relocs of a section. */
252b5132 3568
b34976b6 3569static bfd_boolean
11a2be4d
RS
3570mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
3571 asymbol **symbols, bfd_boolean dynamic)
252b5132
RH
3572{
3573 struct bfd_elf_section_data * const d = elf_section_data (asect);
fee24f1c
AO
3574 Elf_Internal_Shdr *rel_hdr;
3575 Elf_Internal_Shdr *rel_hdr2;
3576 bfd_size_type reloc_count;
3577 bfd_size_type reloc_count2;
3578 arelent *relents;
3579 bfd_size_type amt;
3580
3581 if (asect->relocation != NULL)
3582 return TRUE;
252b5132 3583
fee24f1c 3584 if (! dynamic)
252b5132 3585 {
fee24f1c
AO
3586 if ((asect->flags & SEC_RELOC) == 0
3587 || asect->reloc_count == 0)
3588 return TRUE;
252b5132 3589
d4730f92
BS
3590 rel_hdr = d->rel.hdr;
3591 reloc_count = rel_hdr ? NUM_SHDR_ENTRIES (rel_hdr) : 0;
3592 rel_hdr2 = d->rela.hdr;
fee24f1c
AO
3593 reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
3594
3595 BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
d4730f92 3596 BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
fee24f1c
AO
3597 || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
3598
3599 }
3600 else
3601 {
3602 /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
3603 case because relocations against this section may use the
3604 dynamic symbol table, and in that case bfd_section_from_shdr
3605 in elf.c does not update the RELOC_COUNT. */
eea6121a 3606 if (asect->size == 0)
fee24f1c
AO
3607 return TRUE;
3608
3609 rel_hdr = &d->this_hdr;
3610 reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
3611 rel_hdr2 = NULL;
3612 reloc_count2 = 0;
3613 }
252b5132
RH
3614
3615 /* Allocate space for 3 arelent structures for each Rel structure. */
fee24f1c 3616 amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
11a2be4d 3617 relents = bfd_alloc (abfd, amt);
fee24f1c 3618 if (relents == NULL)
b34976b6 3619 return FALSE;
252b5132
RH
3620
3621 /* The slurp_one_reloc_table routine increments reloc_count. */
3622 asect->reloc_count = 0;
3623
d4730f92
BS
3624 if (rel_hdr != NULL
3625 && ! mips_elf64_slurp_one_reloc_table (abfd, asect,
3626 rel_hdr, reloc_count,
3627 relents,
3628 symbols, dynamic))
3629 return FALSE;
3630 if (rel_hdr2 != NULL
3631 && ! mips_elf64_slurp_one_reloc_table (abfd, asect,
3632 rel_hdr2, reloc_count2,
3633 relents + reloc_count * 3,
3634 symbols, dynamic))
b34976b6 3635 return FALSE;
252b5132 3636
fee24f1c 3637 asect->relocation = relents;
b34976b6 3638 return TRUE;
252b5132
RH
3639}
3640
3641/* Write out the relocations. */
3642
3643static void
11a2be4d 3644mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
252b5132 3645{
11a2be4d 3646 bfd_boolean *failedp = data;
5b6a02bc
TS
3647 int count;
3648 Elf_Internal_Shdr *rel_hdr;
252b5132 3649 unsigned int idx;
252b5132
RH
3650
3651 /* If we have already failed, don't do anything. */
3652 if (*failedp)
3653 return;
3654
3655 if ((sec->flags & SEC_RELOC) == 0)
3656 return;
3657
3658 /* The linker backend writes the relocs out itself, and sets the
3659 reloc_count field to zero to inhibit writing them here. Also,
3660 sometimes the SEC_RELOC flag gets set even when there aren't any
3661 relocs. */
3662 if (sec->reloc_count == 0)
3663 return;
3664
3665 /* We can combine up to three relocs that refer to the same address
3666 if the latter relocs have no associated symbol. */
3667 count = 0;
3668 for (idx = 0; idx < sec->reloc_count; idx++)
3669 {
3670 bfd_vma addr;
3671 unsigned int i;
3672
3673 ++count;
3674
3675 addr = sec->orelocation[idx]->address;
3676 for (i = 0; i < 2; i++)
3677 {
3678 arelent *r;
3679
3680 if (idx + 1 >= sec->reloc_count)
3681 break;
3682 r = sec->orelocation[idx + 1];
3683 if (r->address != addr
3684 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
3685 || (*r->sym_ptr_ptr)->value != 0)
3686 break;
3687
3688 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
3689
3690 ++idx;
3691 }
3692 }
3693
d4730f92 3694 rel_hdr = _bfd_elf_single_rel_hdr (sec);
252b5132 3695
5b6a02bc
TS
3696 /* Do the actual relocation. */
3697
3698 if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
3699 mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
3700 else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
3701 mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
3702 else
3703 BFD_ASSERT (0);
3704}
3705
3706static void
11a2be4d
RS
3707mips_elf64_write_rel (bfd *abfd, asection *sec,
3708 Elf_Internal_Shdr *rel_hdr,
3709 int *count, void *data)
5b6a02bc 3710{
11a2be4d 3711 bfd_boolean *failedp = data;
5b6a02bc
TS
3712 Elf64_Mips_External_Rel *ext_rel;
3713 unsigned int idx;
3714 asymbol *last_sym = 0;
3715 int last_sym_idx = 0;
3716
11a2be4d
RS
3717 rel_hdr->sh_size = rel_hdr->sh_entsize * *count;
3718 rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size);
5b6a02bc 3719 if (rel_hdr->contents == NULL)
252b5132 3720 {
b34976b6 3721 *failedp = TRUE;
252b5132
RH
3722 return;
3723 }
3724
5b6a02bc
TS
3725 ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
3726 for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
252b5132
RH
3727 {
3728 arelent *ptr;
947216bf 3729 Elf64_Mips_Internal_Rela int_rel;
252b5132
RH
3730 asymbol *sym;
3731 int n;
3732 unsigned int i;
3733
3734 ptr = sec->orelocation[idx];
3735
3736 /* The address of an ELF reloc is section relative for an object
3737 file, and absolute for an executable file or shared library.
3738 The address of a BFD reloc is always section relative. */
3739 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
5b6a02bc 3740 int_rel.r_offset = ptr->address;
252b5132 3741 else
5b6a02bc 3742 int_rel.r_offset = ptr->address + sec->vma;
252b5132
RH
3743
3744 sym = *ptr->sym_ptr_ptr;
3745 if (sym == last_sym)
3746 n = last_sym_idx;
99022dfb
RS
3747 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
3748 n = STN_UNDEF;
252b5132
RH
3749 else
3750 {
3751 last_sym = sym;
3752 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
3753 if (n < 0)
3754 {
b34976b6 3755 *failedp = TRUE;
252b5132
RH
3756 return;
3757 }
3758 last_sym_idx = n;
3759 }
3760
5b6a02bc
TS
3761 int_rel.r_sym = n;
3762 int_rel.r_ssym = RSS_UNDEF;
252b5132
RH
3763
3764 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
3765 && ! _bfd_elf_validate_reloc (abfd, ptr))
3766 {
b34976b6 3767 *failedp = TRUE;
252b5132
RH
3768 return;
3769 }
3770
5b6a02bc
TS
3771 int_rel.r_type = ptr->howto->type;
3772 int_rel.r_type2 = (int) R_MIPS_NONE;
3773 int_rel.r_type3 = (int) R_MIPS_NONE;
252b5132
RH
3774
3775 for (i = 0; i < 2; i++)
3776 {
3777 arelent *r;
3778
3779 if (idx + 1 >= sec->reloc_count)
3780 break;
3781 r = sec->orelocation[idx + 1];
3782 if (r->address != ptr->address
3783 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
3784 || (*r->sym_ptr_ptr)->value != 0)
3785 break;
3786
3787 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
3788
3789 if (i == 0)
5b6a02bc 3790 int_rel.r_type2 = r->howto->type;
252b5132 3791 else
5b6a02bc 3792 int_rel.r_type3 = r->howto->type;
252b5132
RH
3793
3794 ++idx;
3795 }
3796
5b6a02bc 3797 mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
252b5132
RH
3798 }
3799
5b6a02bc
TS
3800 BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
3801 == *count);
252b5132 3802}
5b6a02bc
TS
3803
3804static void
11a2be4d
RS
3805mips_elf64_write_rela (bfd *abfd, asection *sec,
3806 Elf_Internal_Shdr *rela_hdr,
3807 int *count, void *data)
5b6a02bc 3808{
11a2be4d 3809 bfd_boolean *failedp = data;
5b6a02bc
TS
3810 Elf64_Mips_External_Rela *ext_rela;
3811 unsigned int idx;
3812 asymbol *last_sym = 0;
3813 int last_sym_idx = 0;
3814
11a2be4d
RS
3815 rela_hdr->sh_size = rela_hdr->sh_entsize * *count;
3816 rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
5b6a02bc
TS
3817 if (rela_hdr->contents == NULL)
3818 {
b34976b6 3819 *failedp = TRUE;
5b6a02bc
TS
3820 return;
3821 }
3822
3823 ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
3824 for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
3825 {
3826 arelent *ptr;
3827 Elf64_Mips_Internal_Rela int_rela;
3828 asymbol *sym;
3829 int n;
3830 unsigned int i;
3831
3832 ptr = sec->orelocation[idx];
3833
3834 /* The address of an ELF reloc is section relative for an object
3835 file, and absolute for an executable file or shared library.
3836 The address of a BFD reloc is always section relative. */
3837 if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
3838 int_rela.r_offset = ptr->address;
3839 else
3840 int_rela.r_offset = ptr->address + sec->vma;
3841
3842 sym = *ptr->sym_ptr_ptr;
3843 if (sym == last_sym)
3844 n = last_sym_idx;
99022dfb
RS
3845 else if (bfd_is_abs_section (sym->section) && sym->value == 0)
3846 n = STN_UNDEF;
5b6a02bc
TS
3847 else
3848 {
3849 last_sym = sym;
3850 n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
3851 if (n < 0)
3852 {
b34976b6 3853 *failedp = TRUE;
5b6a02bc
TS
3854 return;
3855 }
3856 last_sym_idx = n;
3857 }
3858
3859 int_rela.r_sym = n;
3860 int_rela.r_addend = ptr->addend;
3861 int_rela.r_ssym = RSS_UNDEF;
3862
3863 if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
3864 && ! _bfd_elf_validate_reloc (abfd, ptr))
3865 {
b34976b6 3866 *failedp = TRUE;
5b6a02bc
TS
3867 return;
3868 }
3869
3870 int_rela.r_type = ptr->howto->type;
3871 int_rela.r_type2 = (int) R_MIPS_NONE;
3872 int_rela.r_type3 = (int) R_MIPS_NONE;
3873
3874 for (i = 0; i < 2; i++)
3875 {
3876 arelent *r;
3877
3878 if (idx + 1 >= sec->reloc_count)
3879 break;
3880 r = sec->orelocation[idx + 1];
3881 if (r->address != ptr->address
3882 || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
3883 || (*r->sym_ptr_ptr)->value != 0)
3884 break;
3885
3886 /* We can merge the reloc at IDX + 1 with the reloc at IDX. */
3887
3888 if (i == 0)
3889 int_rela.r_type2 = r->howto->type;
3890 else
3891 int_rela.r_type3 = r->howto->type;
3892
3893 ++idx;
3894 }
3895
3896 mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
3897 }
3898
3899 BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
3900 == *count);
3901}
3902\f
c6e90b02 3903/* Set the right machine number for a MIPS ELF file. */
5b6a02bc 3904
b34976b6 3905static bfd_boolean
11a2be4d 3906mips_elf64_object_p (bfd *abfd)
5b6a02bc 3907{
c6e90b02 3908 unsigned long mach;
5b6a02bc 3909
c6e90b02
TS
3910 /* Irix 6 is broken. Object file symbol tables are not always
3911 sorted correctly such that local symbols precede global symbols,
3912 and the sh_info field in the symbol table is not always right. */
a4382ec6 3913 if (elf64_mips_irix_compat (abfd) != ict_none)
b34976b6 3914 elf_bad_symtab (abfd) = TRUE;
5b6a02bc 3915
c6e90b02
TS
3916 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
3917 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
b34976b6 3918 return TRUE;
5b6a02bc
TS
3919}
3920
c6e90b02
TS
3921/* Depending on the target vector we generate some version of Irix
3922 executables or "normal" MIPS ELF ABI executables. */
3923static irix_compat_t
11a2be4d 3924elf64_mips_irix_compat (bfd *abfd)
5b6a02bc 3925{
a4382ec6
TS
3926 if ((abfd->xvec == &bfd_elf64_bigmips_vec)
3927 || (abfd->xvec == &bfd_elf64_littlemips_vec))
c6e90b02 3928 return ict_irix6;
a4382ec6
TS
3929 else
3930 return ict_none;
5b6a02bc
TS
3931}
3932\f
d0112f73
KB
3933/* Support for core dump NOTE sections. */
3934static bfd_boolean
11a2be4d 3935elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
d0112f73
KB
3936{
3937 int offset;
eea6121a 3938 unsigned int size;
d0112f73
KB
3939
3940 switch (note->descsz)
3941 {
3942 default:
3943 return FALSE;
3944
3945 case 480: /* Linux/MIPS - N64 kernel */
3946 /* pr_cursig */
3947 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
3948
3949 /* pr_pid */
261b8d08 3950 elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 32);
d0112f73
KB
3951
3952 /* pr_reg */
3953 offset = 112;
eea6121a 3954 size = 360;
d0112f73
KB
3955
3956 break;
3957 }
3958
3959 /* Make a ".reg/999" section. */
3960 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
eea6121a 3961 size, note->descpos + offset);
d0112f73
KB
3962}
3963
3964static bfd_boolean
11a2be4d 3965elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
d0112f73
KB
3966{
3967 switch (note->descsz)
3968 {
3969 default:
3970 return FALSE;
3971
3972 case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
3973 elf_tdata (abfd)->core_program
3974 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
3975 elf_tdata (abfd)->core_command
3976 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
3977 }
3978
3979 /* Note that for some reason, a spurious space is tacked
3980 onto the end of the args in some (at least one anyway)
3981 implementations, so strip it off if it exists. */
3982
3983 {
3984 char *command = elf_tdata (abfd)->core_command;
3985 int n = strlen (command);
3986
3987 if (0 < n && command[n - 1] == ' ')
3988 command[n - 1] = '\0';
3989 }
3990
3991 return TRUE;
3992}
3993\f
c6e90b02
TS
3994/* ECOFF swapping routines. These are used when dealing with the
3995 .mdebug section, which is in the ECOFF debugging format. */
3996static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
5b6a02bc 3997{
c6e90b02
TS
3998 /* Symbol table magic number. */
3999 magicSym2,
4000 /* Alignment of debugging information. E.g., 4. */
4001 8,
4002 /* Sizes of external symbolic information. */
4003 sizeof (struct hdr_ext),
4004 sizeof (struct dnr_ext),
4005 sizeof (struct pdr_ext),
4006 sizeof (struct sym_ext),
4007 sizeof (struct opt_ext),
4008 sizeof (struct fdr_ext),
4009 sizeof (struct rfd_ext),
4010 sizeof (struct ext_ext),
4011 /* Functions to swap in external symbolic data. */
4012 ecoff_swap_hdr_in,
4013 ecoff_swap_dnr_in,
4014 ecoff_swap_pdr_in,
4015 ecoff_swap_sym_in,
4016 ecoff_swap_opt_in,
4017 ecoff_swap_fdr_in,
4018 ecoff_swap_rfd_in,
4019 ecoff_swap_ext_in,
4020 _bfd_ecoff_swap_tir_in,
4021 _bfd_ecoff_swap_rndx_in,
4022 /* Functions to swap out external symbolic data. */
4023 ecoff_swap_hdr_out,
4024 ecoff_swap_dnr_out,
4025 ecoff_swap_pdr_out,
4026 ecoff_swap_sym_out,
4027 ecoff_swap_opt_out,
4028 ecoff_swap_fdr_out,
4029 ecoff_swap_rfd_out,
4030 ecoff_swap_ext_out,
4031 _bfd_ecoff_swap_tir_out,
4032 _bfd_ecoff_swap_rndx_out,
4033 /* Function to read in symbolic data. */
4034 _bfd_mips_elf_read_ecoff_info
4035};
4036\f
4037/* Relocations in the 64 bit MIPS ELF ABI are more complex than in
4038 standard ELF. This structure is used to redirect the relocation
4039 handling routines. */
5b6a02bc 4040
c6e90b02 4041const struct elf_size_info mips_elf64_size_info =
5b6a02bc 4042{
c6e90b02
TS
4043 sizeof (Elf64_External_Ehdr),
4044 sizeof (Elf64_External_Phdr),
4045 sizeof (Elf64_External_Shdr),
4046 sizeof (Elf64_Mips_External_Rel),
4047 sizeof (Elf64_Mips_External_Rela),
4048 sizeof (Elf64_External_Sym),
4049 sizeof (Elf64_External_Dyn),
4050 sizeof (Elf_External_Note),
99277196
MR
4051 4, /* hash-table entry size */
4052 3, /* internal relocations per external relocations */
c6e90b02 4053 64, /* arch_size */
45d6a902 4054 3, /* log_file_align */
c6e90b02
TS
4055 ELFCLASS64,
4056 EV_CURRENT,
4057 bfd_elf64_write_out_phdrs,
4058 bfd_elf64_write_shdrs_and_ehdr,
1489a3a0 4059 bfd_elf64_checksum_contents,
c6e90b02 4060 mips_elf64_write_relocs,
73ff0d56 4061 bfd_elf64_swap_symbol_in,
c6e90b02
TS
4062 bfd_elf64_swap_symbol_out,
4063 mips_elf64_slurp_reloc_table,
4064 bfd_elf64_slurp_symbol_table,
4065 bfd_elf64_swap_dyn_in,
4066 bfd_elf64_swap_dyn_out,
4067 mips_elf64_be_swap_reloc_in,
4068 mips_elf64_be_swap_reloc_out,
4069 mips_elf64_be_swap_reloca_in,
4070 mips_elf64_be_swap_reloca_out
5b6a02bc
TS
4071};
4072
c6e90b02 4073#define ELF_ARCH bfd_arch_mips
ae95ffa6 4074#define ELF_TARGET_ID MIPS_ELF_DATA
c6e90b02 4075#define ELF_MACHINE_CODE EM_MIPS
103186c6 4076
b34976b6
AM
4077#define elf_backend_collect TRUE
4078#define elf_backend_type_change_ok TRUE
4079#define elf_backend_can_gc_sections TRUE
5b6a02bc
TS
4080#define elf_info_to_howto mips_elf64_info_to_howto_rela
4081#define elf_info_to_howto_rel mips_elf64_info_to_howto_rel
c6e90b02 4082#define elf_backend_object_p mips_elf64_object_p
5b6a02bc
TS
4083#define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
4084#define elf_backend_section_processing _bfd_mips_elf_section_processing
103186c6 4085#define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
252b5132
RH
4086#define elf_backend_fake_sections _bfd_mips_elf_fake_sections
4087#define elf_backend_section_from_bfd_section \
c6e90b02 4088 _bfd_mips_elf_section_from_bfd_section
103186c6 4089#define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
5b6a02bc 4090#define elf_backend_link_output_symbol_hook \
c6e90b02 4091 _bfd_mips_elf_link_output_symbol_hook
103186c6 4092#define elf_backend_create_dynamic_sections \
c6e90b02
TS
4093 _bfd_mips_elf_create_dynamic_sections
4094#define elf_backend_check_relocs _bfd_mips_elf_check_relocs
8992f0d7
TS
4095#define elf_backend_merge_symbol_attribute \
4096 _bfd_mips_elf_merge_symbol_attribute
ad9563d6 4097#define elf_backend_get_target_dtag _bfd_mips_elf_get_target_dtag
103186c6 4098#define elf_backend_adjust_dynamic_symbol \
c6e90b02 4099 _bfd_mips_elf_adjust_dynamic_symbol
103186c6 4100#define elf_backend_always_size_sections \
c6e90b02 4101 _bfd_mips_elf_always_size_sections
103186c6 4102#define elf_backend_size_dynamic_sections \
c6e90b02 4103 _bfd_mips_elf_size_dynamic_sections
74541ad4 4104#define elf_backend_init_index_section _bfd_elf_init_1_index_section
c6e90b02 4105#define elf_backend_relocate_section _bfd_mips_elf_relocate_section
103186c6 4106#define elf_backend_finish_dynamic_symbol \
c6e90b02 4107 _bfd_mips_elf_finish_dynamic_symbol
103186c6 4108#define elf_backend_finish_dynamic_sections \
c6e90b02 4109 _bfd_mips_elf_finish_dynamic_sections
5b6a02bc 4110#define elf_backend_final_write_processing \
c6e90b02 4111 _bfd_mips_elf_final_write_processing
5b6a02bc 4112#define elf_backend_additional_program_headers \
c6e90b02 4113 _bfd_mips_elf_additional_program_headers
5b6a02bc 4114#define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
c6e90b02
TS
4115#define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
4116#define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
427b80f4
RS
4117#define elf_backend_copy_indirect_symbol \
4118 _bfd_mips_elf_copy_indirect_symbol
53bfd6b4
MR
4119#define elf_backend_ignore_discarded_relocs \
4120 _bfd_mips_elf_ignore_discarded_relocs
c6e90b02
TS
4121#define elf_backend_mips_irix_compat elf64_mips_irix_compat
4122#define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
5b6a02bc
TS
4123#define elf_backend_ecoff_debug_swap &mips_elf64_ecoff_debug_swap
4124#define elf_backend_size_info mips_elf64_size_info
d0112f73
KB
4125
4126#define elf_backend_grok_prstatus elf64_mips_grok_prstatus
4127#define elf_backend_grok_psinfo elf64_mips_grok_psinfo
5b6a02bc 4128
a44acb1e 4129#define elf_backend_got_header_size (8 * MIPS_RESERVED_GOTNO)
1e2be829
TS
4130
4131/* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
c6e90b02 4132 work better/work only in RELA, so we default to this. */
1e2be829
TS
4133#define elf_backend_may_use_rel_p 1
4134#define elf_backend_may_use_rela_p 1
4135#define elf_backend_default_use_rela_p 1
861fb55a
DJ
4136#define elf_backend_rela_plts_and_copies_p 0
4137#define elf_backend_plt_readonly 1
4138#define elf_backend_plt_sym_val _bfd_mips_elf_plt_sym_val
103186c6 4139
f1187097
DJ
4140#define elf_backend_sign_extend_vma TRUE
4141
d01414a5
TS
4142#define elf_backend_write_section _bfd_mips_elf_write_section
4143
fe8bc63d 4144/* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
103186c6
MM
4145 MIPS-specific function only applies to IRIX5, which had no 64-bit
4146 ABI. */
df58fc94
RS
4147#define bfd_elf64_bfd_is_target_special_symbol \
4148 _bfd_mips_elf_is_target_special_symbol
252b5132 4149#define bfd_elf64_find_nearest_line _bfd_mips_elf_find_nearest_line
4ab527b0 4150#define bfd_elf64_find_inliner_info _bfd_mips_elf_find_inliner_info
f0abc2a1 4151#define bfd_elf64_new_section_hook _bfd_mips_elf_new_section_hook
252b5132 4152#define bfd_elf64_set_section_contents _bfd_mips_elf_set_section_contents
c6e90b02
TS
4153#define bfd_elf64_bfd_get_relocated_section_contents \
4154 _bfd_elf_mips_get_relocated_section_contents
103186c6 4155#define bfd_elf64_bfd_link_hash_table_create \
c6e90b02
TS
4156 _bfd_mips_elf_link_hash_table_create
4157#define bfd_elf64_bfd_final_link _bfd_mips_elf_final_link
252b5132 4158#define bfd_elf64_bfd_merge_private_bfd_data \
c6e90b02 4159 _bfd_mips_elf_merge_private_bfd_data
252b5132 4160#define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
103186c6 4161#define bfd_elf64_bfd_print_private_bfd_data \
c6e90b02 4162 _bfd_mips_elf_print_private_bfd_data
252b5132 4163
103186c6 4164#define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
fee24f1c
AO
4165#define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
4166#define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
4167#define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
d0647110 4168#define bfd_elf64_bfd_relax_section _bfd_mips_relax_section
c6e90b02
TS
4169
4170/* MIPS ELF64 archive functions. */
252b5132 4171#define bfd_elf64_archive_functions
b34976b6 4172extern bfd_boolean bfd_elf64_archive_slurp_armap
11a2be4d 4173 (bfd *);
b34976b6 4174extern bfd_boolean bfd_elf64_archive_write_armap
11a2be4d 4175 (bfd *, unsigned int, struct orl *, unsigned int, int);
252b5132 4176#define bfd_elf64_archive_slurp_extended_name_table \
c6e90b02 4177 _bfd_archive_coff_slurp_extended_name_table
252b5132 4178#define bfd_elf64_archive_construct_extended_name_table \
c6e90b02 4179 _bfd_archive_coff_construct_extended_name_table
252b5132 4180#define bfd_elf64_archive_truncate_arname \
c6e90b02 4181 _bfd_archive_coff_truncate_arname
252b5132 4182#define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
8f95b6e4 4183#define bfd_elf64_archive_write_ar_hdr _bfd_archive_coff_write_ar_hdr
252b5132 4184#define bfd_elf64_archive_openr_next_archived_file \
c6e90b02 4185 _bfd_archive_coff_openr_next_archived_file
252b5132 4186#define bfd_elf64_archive_get_elt_at_index \
c6e90b02 4187 _bfd_archive_coff_get_elt_at_index
252b5132 4188#define bfd_elf64_archive_generic_stat_arch_elt \
c6e90b02 4189 _bfd_archive_coff_generic_stat_arch_elt
252b5132 4190#define bfd_elf64_archive_update_armap_timestamp \
c6e90b02 4191 _bfd_archive_coff_update_armap_timestamp
252b5132 4192
5b6a02bc
TS
4193/* The SGI style (n)64 NewABI. */
4194#define TARGET_LITTLE_SYM bfd_elf64_littlemips_vec
4195#define TARGET_LITTLE_NAME "elf64-littlemips"
4196#define TARGET_BIG_SYM bfd_elf64_bigmips_vec
4197#define TARGET_BIG_NAME "elf64-bigmips"
fdbafa10 4198
7fd91fe0
TS
4199#define ELF_MAXPAGESIZE 0x10000
4200#define ELF_COMMONPAGESIZE 0x1000
fdbafa10 4201
4301eeb1 4202#include "elf64-target.h"
fdbafa10 4203
5b6a02bc 4204/* The SYSV-style 'traditional' (n)64 NewABI. */
fdbafa10
L
4205#undef TARGET_LITTLE_SYM
4206#undef TARGET_LITTLE_NAME
4207#undef TARGET_BIG_SYM
4208#undef TARGET_BIG_NAME
4209
4301eeb1 4210#undef ELF_MAXPAGESIZE
7fd91fe0 4211#undef ELF_COMMONPAGESIZE
4301eeb1 4212
99277196
MR
4213#define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_vec
4214#define TARGET_LITTLE_NAME "elf64-tradlittlemips"
4215#define TARGET_BIG_SYM bfd_elf64_tradbigmips_vec
4216#define TARGET_BIG_NAME "elf64-tradbigmips"
fdbafa10 4217
4301eeb1 4218#define ELF_MAXPAGESIZE 0x10000
7fd91fe0 4219#define ELF_COMMONPAGESIZE 0x1000
4301eeb1
MR
4220#define elf64_bed elf64_tradbed
4221
5b6a02bc 4222/* Include the target file again for this target. */
fdbafa10 4223#include "elf64-target.h"
aeffff67
RS
4224
4225
4226/* FreeBSD support. */
4227
4228#undef TARGET_LITTLE_SYM
4229#undef TARGET_LITTLE_NAME
4230#undef TARGET_BIG_SYM
4231#undef TARGET_BIG_NAME
4232
4233#define TARGET_LITTLE_SYM bfd_elf64_tradlittlemips_freebsd_vec
4234#define TARGET_LITTLE_NAME "elf64-tradlittlemips-freebsd"
4235#define TARGET_BIG_SYM bfd_elf64_tradbigmips_freebsd_vec
4236#define TARGET_BIG_NAME "elf64-tradbigmips-freebsd"
4237
4238#undef ELF_OSABI
4239#define ELF_OSABI ELFOSABI_FREEBSD
4240
4241/* The kernel recognizes executables as valid only if they carry a
4242 "FreeBSD" label in the ELF header. So we put this label on all
4243 executables and (for simplicity) also all other object files. */
4244
4245static void
4246elf_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info)
4247{
4248 _bfd_elf_set_osabi (abfd, info);
4249}
4250
4251#undef elf_backend_post_process_headers
4252#define elf_backend_post_process_headers elf_fbsd_post_process_headers
4253#undef elf64_bed
4254#define elf64_bed elf64_fbsd_tradbed
4255
4256#include "elf64-target.h"
This page took 0.877618 seconds and 4 git commands to generate.