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