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