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