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