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