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