OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [bfd/] [elf64-mips.c] - Blame information for rev 300

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.