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