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