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