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