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