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