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