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