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