OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [bfd/] [elf64-mips.c] - Blame information for rev 307

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

Line No. Rev Author Line
1 227 jeremybenn
/* MIPS-specific support for 64-bit ELF
2
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3
   2006, 2007, 2008 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
 
1332
  HOWTO (R_MIPS_TLS_DTPMOD64,   /* type */
1333
         0,                      /* rightshift */
1334
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
1335
         64,                    /* bitsize */
1336
         FALSE,                 /* pc_relative */
1337
         0,                      /* bitpos */
1338
         complain_overflow_dont, /* complain_on_overflow */
1339
         _bfd_mips_elf_generic_reloc, /* special_function */
1340
         "R_MIPS_TLS_DTPMOD64", /* name */
1341
         TRUE,                  /* partial_inplace */
1342
         MINUS_ONE,             /* src_mask */
1343
         MINUS_ONE,             /* dst_mask */
1344
         FALSE),                /* pcrel_offset */
1345
 
1346
  HOWTO (R_MIPS_TLS_DTPREL64,   /* type */
1347
         0,                      /* rightshift */
1348
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
1349
         64,                    /* bitsize */
1350
         FALSE,                 /* pc_relative */
1351
         0,                      /* bitpos */
1352
         complain_overflow_dont, /* complain_on_overflow */
1353
         _bfd_mips_elf_generic_reloc, /* special_function */
1354
         "R_MIPS_TLS_DTPREL64", /* name */
1355
         TRUE,                  /* partial_inplace */
1356
         MINUS_ONE,             /* src_mask */
1357
         MINUS_ONE,             /* dst_mask */
1358
         FALSE),                /* pcrel_offset */
1359
 
1360
  /* TLS general dynamic variable reference.  */
1361
  HOWTO (R_MIPS_TLS_GD,         /* type */
1362
         0,                      /* rightshift */
1363
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1364
         16,                    /* bitsize */
1365
         FALSE,                 /* pc_relative */
1366
         0,                      /* bitpos */
1367
         complain_overflow_signed, /* complain_on_overflow */
1368
         _bfd_mips_elf_generic_reloc, /* special_function */
1369
         "R_MIPS_TLS_GD",       /* name */
1370
         TRUE,                  /* partial_inplace */
1371
         0x0000ffff,            /* src_mask */
1372
         0x0000ffff,            /* dst_mask */
1373
         FALSE),                /* pcrel_offset */
1374
 
1375
  /* TLS local dynamic variable reference.  */
1376
  HOWTO (R_MIPS_TLS_LDM,        /* type */
1377
         0,                      /* rightshift */
1378
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1379
         16,                    /* bitsize */
1380
         FALSE,                 /* pc_relative */
1381
         0,                      /* bitpos */
1382
         complain_overflow_signed, /* complain_on_overflow */
1383
         _bfd_mips_elf_generic_reloc, /* special_function */
1384
         "R_MIPS_TLS_LDM",      /* name */
1385
         TRUE,                  /* partial_inplace */
1386
         0x0000ffff,            /* src_mask */
1387
         0x0000ffff,            /* dst_mask */
1388
         FALSE),                /* pcrel_offset */
1389
 
1390
  /* TLS local dynamic offset.  */
1391
  HOWTO (R_MIPS_TLS_DTPREL_HI16,        /* type */
1392
         0,                      /* rightshift */
1393
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1394
         16,                    /* bitsize */
1395
         FALSE,                 /* pc_relative */
1396
         0,                      /* bitpos */
1397
         complain_overflow_signed, /* complain_on_overflow */
1398
         _bfd_mips_elf_generic_reloc, /* special_function */
1399
         "R_MIPS_TLS_DTPREL_HI16",      /* name */
1400
         TRUE,                  /* partial_inplace */
1401
         0x0000ffff,            /* src_mask */
1402
         0x0000ffff,            /* dst_mask */
1403
         FALSE),                /* pcrel_offset */
1404
 
1405
  /* TLS local dynamic offset.  */
1406
  HOWTO (R_MIPS_TLS_DTPREL_LO16,        /* type */
1407
         0,                      /* rightshift */
1408
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1409
         16,                    /* bitsize */
1410
         FALSE,                 /* pc_relative */
1411
         0,                      /* bitpos */
1412
         complain_overflow_signed, /* complain_on_overflow */
1413
         _bfd_mips_elf_generic_reloc, /* special_function */
1414
         "R_MIPS_TLS_DTPREL_LO16",      /* name */
1415
         TRUE,                  /* partial_inplace */
1416
         0x0000ffff,            /* src_mask */
1417
         0x0000ffff,            /* dst_mask */
1418
         FALSE),                /* pcrel_offset */
1419
 
1420
  /* TLS thread pointer offset.  */
1421
  HOWTO (R_MIPS_TLS_GOTTPREL,   /* type */
1422
         0,                      /* rightshift */
1423
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1424
         16,                    /* bitsize */
1425
         FALSE,                 /* pc_relative */
1426
         0,                      /* bitpos */
1427
         complain_overflow_signed, /* complain_on_overflow */
1428
         _bfd_mips_elf_generic_reloc, /* special_function */
1429
         "R_MIPS_TLS_GOTTPREL", /* name */
1430
         TRUE,                  /* partial_inplace */
1431
         0x0000ffff,            /* src_mask */
1432
         0x0000ffff,            /* dst_mask */
1433
         FALSE),                /* pcrel_offset */
1434
 
1435
  /* TLS IE dynamic relocations.  */
1436
  EMPTY_HOWTO (R_MIPS_TLS_TPREL32),
1437
 
1438
  HOWTO (R_MIPS_TLS_TPREL64,    /* type */
1439
         0,                      /* rightshift */
1440
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
1441
         64,                    /* bitsize */
1442
         FALSE,                 /* pc_relative */
1443
         0,                      /* bitpos */
1444
         complain_overflow_dont, /* complain_on_overflow */
1445
         _bfd_mips_elf_generic_reloc, /* special_function */
1446
         "R_MIPS_TLS_TPREL64",  /* name */
1447
         TRUE,                  /* partial_inplace */
1448
         MINUS_ONE,             /* src_mask */
1449
         MINUS_ONE,             /* dst_mask */
1450
         FALSE),                /* pcrel_offset */
1451
 
1452
  /* TLS thread pointer offset.  */
1453
  HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
1454
         0,                      /* rightshift */
1455
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1456
         16,                    /* bitsize */
1457
         FALSE,                 /* pc_relative */
1458
         0,                      /* bitpos */
1459
         complain_overflow_signed, /* complain_on_overflow */
1460
         _bfd_mips_elf_generic_reloc, /* special_function */
1461
         "R_MIPS_TLS_TPREL_HI16", /* name */
1462
         TRUE,                  /* partial_inplace */
1463
         0x0000ffff,            /* src_mask */
1464
         0x0000ffff,            /* dst_mask */
1465
         FALSE),                /* pcrel_offset */
1466
 
1467
  /* TLS thread pointer offset.  */
1468
  HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
1469
         0,                      /* rightshift */
1470
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1471
         16,                    /* bitsize */
1472
         FALSE,                 /* pc_relative */
1473
         0,                      /* bitpos */
1474
         complain_overflow_signed, /* complain_on_overflow */
1475
         _bfd_mips_elf_generic_reloc, /* special_function */
1476
         "R_MIPS_TLS_TPREL_LO16", /* name */
1477
         TRUE,                  /* partial_inplace */
1478
         0x0000ffff,            /* src_mask */
1479
         0x0000ffff,            /* dst_mask */
1480
         FALSE),                /* pcrel_offset */
1481
 
1482
  /* 32 bit relocation with no addend.  */
1483
  HOWTO (R_MIPS_GLOB_DAT,       /* type */
1484
         0,                      /* rightshift */
1485
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1486
         32,                    /* bitsize */
1487
         FALSE,                 /* pc_relative */
1488
         0,                      /* bitpos */
1489
         complain_overflow_dont, /* complain_on_overflow */
1490
         _bfd_mips_elf_generic_reloc, /* special_function */
1491
         "R_MIPS_GLOB_DAT",     /* name */
1492
         FALSE,                 /* partial_inplace */
1493
         0x0,                   /* src_mask */
1494
         0xffffffff,            /* dst_mask */
1495
         FALSE),                /* pcrel_offset */
1496
};
1497
 
1498
static reloc_howto_type mips16_elf64_howto_table_rel[] =
1499
{
1500
  /* The reloc used for the mips16 jump instruction.  */
1501
  HOWTO (R_MIPS16_26,           /* type */
1502
         2,                     /* rightshift */
1503
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1504
         26,                    /* bitsize */
1505
         FALSE,                 /* pc_relative */
1506
         0,                      /* bitpos */
1507
         complain_overflow_dont, /* complain_on_overflow */
1508
                                /* This needs complex overflow
1509
                                   detection, because the upper four
1510
                                   bits must match the PC.  */
1511
         _bfd_mips_elf_generic_reloc, /* special_function */
1512
         "R_MIPS16_26",         /* name */
1513
         TRUE,                  /* partial_inplace */
1514
         0x3ffffff,             /* src_mask */
1515
         0x3ffffff,             /* dst_mask */
1516
         FALSE),                /* pcrel_offset */
1517
 
1518
  /* The reloc used for the mips16 gprel instruction.  */
1519
  HOWTO (R_MIPS16_GPREL,        /* type */
1520
         0,                      /* rightshift */
1521
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1522
         16,                    /* bitsize */
1523
         FALSE,                 /* pc_relative */
1524
         0,                      /* bitpos */
1525
         complain_overflow_signed, /* complain_on_overflow */
1526
         mips16_gprel_reloc,    /* special_function */
1527
         "R_MIPS16_GPREL",      /* name */
1528
         TRUE,                  /* partial_inplace */
1529
         0x0000ffff,            /* src_mask */
1530
         0x0000ffff,            /* dst_mask */
1531
         FALSE),                /* pcrel_offset */
1532
 
1533
  /* A MIPS16 reference to the global offset table.  */
1534
  HOWTO (R_MIPS16_GOT16,        /* type */
1535
         0,                      /* rightshift */
1536
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1537
         16,                    /* bitsize */
1538
         FALSE,                 /* pc_relative */
1539
         0,                      /* bitpos */
1540
         complain_overflow_dont, /* complain_on_overflow */
1541
         _bfd_mips_elf_got16_reloc, /* special_function */
1542
         "R_MIPS16_GOT16",      /* name */
1543
         TRUE,                  /* partial_inplace */
1544
         0x0000ffff,            /* src_mask */
1545
         0x0000ffff,            /* dst_mask */
1546
         FALSE),                /* pcrel_offset */
1547
 
1548
  /* A MIPS16 call through the global offset table.  */
1549
  HOWTO (R_MIPS16_CALL16,       /* type */
1550
         0,                      /* rightshift */
1551
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1552
         16,                    /* bitsize */
1553
         FALSE,                 /* pc_relative */
1554
         0,                      /* bitpos */
1555
         complain_overflow_dont, /* complain_on_overflow */
1556
         _bfd_mips_elf_generic_reloc, /* special_function */
1557
         "R_MIPS16_CALL16",     /* name */
1558
         TRUE,                  /* partial_inplace */
1559
         0x0000ffff,            /* src_mask */
1560
         0x0000ffff,            /* dst_mask */
1561
         FALSE),                /* pcrel_offset */
1562
 
1563
  /* MIPS16 high 16 bits of symbol value.  */
1564
  HOWTO (R_MIPS16_HI16,         /* type */
1565
         16,                    /* rightshift */
1566
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1567
         16,                    /* bitsize */
1568
         FALSE,                 /* pc_relative */
1569
         0,                      /* bitpos */
1570
         complain_overflow_dont, /* complain_on_overflow */
1571
         _bfd_mips_elf_hi16_reloc, /* special_function */
1572
         "R_MIPS16_HI16",       /* name */
1573
         TRUE,                  /* partial_inplace */
1574
         0x0000ffff,            /* src_mask */
1575
         0x0000ffff,            /* dst_mask */
1576
         FALSE),                /* pcrel_offset */
1577
 
1578
  /* MIPS16 low 16 bits of symbol value.  */
1579
  HOWTO (R_MIPS16_LO16,         /* type */
1580
         0,                      /* rightshift */
1581
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1582
         16,                    /* bitsize */
1583
         FALSE,                 /* pc_relative */
1584
         0,                      /* bitpos */
1585
         complain_overflow_dont, /* complain_on_overflow */
1586
         _bfd_mips_elf_lo16_reloc, /* special_function */
1587
         "R_MIPS16_LO16",       /* name */
1588
         TRUE,                  /* partial_inplace */
1589
         0x0000ffff,            /* src_mask */
1590
         0x0000ffff,            /* dst_mask */
1591
         FALSE),                /* pcrel_offset */
1592
};
1593
 
1594
static reloc_howto_type mips16_elf64_howto_table_rela[] =
1595
{
1596
  /* The reloc used for the mips16 jump instruction.  */
1597
  HOWTO (R_MIPS16_26,           /* type */
1598
         2,                     /* rightshift */
1599
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1600
         26,                    /* bitsize */
1601
         FALSE,                 /* pc_relative */
1602
         0,                      /* bitpos */
1603
         complain_overflow_dont, /* complain_on_overflow */
1604
                                /* This needs complex overflow
1605
                                   detection, because the upper four
1606
                                   bits must match the PC.  */
1607
         _bfd_mips_elf_generic_reloc, /* special_function */
1608
         "R_MIPS16_26",         /* name */
1609
         FALSE,                 /* partial_inplace */
1610
         0x3ffffff,             /* src_mask */
1611
         0x3ffffff,             /* dst_mask */
1612
         FALSE),                /* pcrel_offset */
1613
 
1614
  /* The reloc used for the mips16 gprel instruction.  */
1615
  HOWTO (R_MIPS16_GPREL,        /* type */
1616
         0,                      /* rightshift */
1617
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1618
         16,                    /* bitsize */
1619
         FALSE,                 /* pc_relative */
1620
         0,                      /* bitpos */
1621
         complain_overflow_signed, /* complain_on_overflow */
1622
         mips16_gprel_reloc,    /* special_function */
1623
         "R_MIPS16_GPREL",      /* name */
1624
         FALSE,                 /* partial_inplace */
1625
         0x0000ffff,            /* src_mask */
1626
         0x0000ffff,            /* dst_mask */
1627
         FALSE),                /* pcrel_offset */
1628
 
1629
  /* A MIPS16 reference to the global offset table.  */
1630
  HOWTO (R_MIPS16_GOT16,        /* type */
1631
         0,                      /* rightshift */
1632
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1633
         16,                    /* bitsize */
1634
         FALSE,                 /* pc_relative */
1635
         0,                      /* bitpos */
1636
         complain_overflow_dont, /* complain_on_overflow */
1637
         _bfd_mips_elf_got16_reloc, /* special_function */
1638
         "R_MIPS16_GOT16",      /* name */
1639
         FALSE,                 /* partial_inplace */
1640
         0x0000ffff,            /* src_mask */
1641
         0x0000ffff,            /* dst_mask */
1642
         FALSE),                /* pcrel_offset */
1643
 
1644
  /* A MIPS16 call through the global offset table.  */
1645
  HOWTO (R_MIPS16_CALL16,       /* type */
1646
         0,                      /* rightshift */
1647
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1648
         16,                    /* bitsize */
1649
         FALSE,                 /* pc_relative */
1650
         0,                      /* bitpos */
1651
         complain_overflow_dont, /* complain_on_overflow */
1652
         _bfd_mips_elf_generic_reloc, /* special_function */
1653
         "R_MIPS16_CALL16",     /* name */
1654
         FALSE,                 /* partial_inplace */
1655
         0x0000ffff,            /* src_mask */
1656
         0x0000ffff,            /* dst_mask */
1657
         FALSE),                /* pcrel_offset */
1658
 
1659
  /* MIPS16 high 16 bits of symbol value.  */
1660
  HOWTO (R_MIPS16_HI16,         /* type */
1661
         16,                    /* rightshift */
1662
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1663
         16,                    /* bitsize */
1664
         FALSE,                 /* pc_relative */
1665
         0,                      /* bitpos */
1666
         complain_overflow_dont, /* complain_on_overflow */
1667
         _bfd_mips_elf_hi16_reloc, /* special_function */
1668
         "R_MIPS16_HI16",       /* name */
1669
         FALSE,                 /* partial_inplace */
1670
         0x0000ffff,            /* src_mask */
1671
         0x0000ffff,            /* dst_mask */
1672
         FALSE),                /* pcrel_offset */
1673
 
1674
  /* MIPS16 low 16 bits of symbol value.  */
1675
  HOWTO (R_MIPS16_LO16,         /* type */
1676
         0,                      /* rightshift */
1677
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1678
         16,                    /* bitsize */
1679
         FALSE,                 /* pc_relative */
1680
         0,                      /* bitpos */
1681
         complain_overflow_dont, /* complain_on_overflow */
1682
         _bfd_mips_elf_lo16_reloc, /* special_function */
1683
         "R_MIPS16_LO16",       /* name */
1684
         FALSE,                 /* partial_inplace */
1685
         0x0000ffff,            /* src_mask */
1686
         0x0000ffff,            /* dst_mask */
1687
         FALSE),                /* pcrel_offset */
1688
};
1689
 
1690
/* GNU extension to record C++ vtable hierarchy */
1691
static reloc_howto_type elf_mips_gnu_vtinherit_howto =
1692
  HOWTO (R_MIPS_GNU_VTINHERIT,  /* type */
1693
         0,                      /* rightshift */
1694
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1695
         0,                      /* bitsize */
1696
         FALSE,                 /* pc_relative */
1697
         0,                      /* bitpos */
1698
         complain_overflow_dont, /* complain_on_overflow */
1699
         NULL,                  /* special_function */
1700
         "R_MIPS_GNU_VTINHERIT", /* name */
1701
         FALSE,                 /* partial_inplace */
1702
         0,                      /* src_mask */
1703
         0,                      /* dst_mask */
1704
         FALSE);                /* pcrel_offset */
1705
 
1706
/* GNU extension to record C++ vtable member usage */
1707
static reloc_howto_type elf_mips_gnu_vtentry_howto =
1708
  HOWTO (R_MIPS_GNU_VTENTRY,    /* type */
1709
         0,                      /* rightshift */
1710
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1711
         0,                      /* bitsize */
1712
         FALSE,                 /* pc_relative */
1713
         0,                      /* bitpos */
1714
         complain_overflow_dont, /* complain_on_overflow */
1715
         _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1716
         "R_MIPS_GNU_VTENTRY",  /* name */
1717
         FALSE,                 /* partial_inplace */
1718
         0,                      /* src_mask */
1719
         0,                      /* dst_mask */
1720
         FALSE);                /* pcrel_offset */
1721
 
1722
/* 16 bit offset for pc-relative branches.  */
1723
static reloc_howto_type elf_mips_gnu_rel16_s2 =
1724
  HOWTO (R_MIPS_GNU_REL16_S2,   /* type */
1725
         2,                     /* rightshift */
1726
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1727
         16,                    /* bitsize */
1728
         TRUE,                  /* pc_relative */
1729
         0,                      /* bitpos */
1730
         complain_overflow_signed, /* complain_on_overflow */
1731
         _bfd_mips_elf_generic_reloc,   /* special_function */
1732
         "R_MIPS_GNU_REL16_S2", /* name */
1733
         TRUE,                  /* partial_inplace */
1734
         0x0000ffff,            /* src_mask */
1735
         0x0000ffff,            /* dst_mask */
1736
         TRUE);                 /* pcrel_offset */
1737
 
1738
/* 16 bit offset for pc-relative branches.  */
1739
static reloc_howto_type elf_mips_gnu_rela16_s2 =
1740
  HOWTO (R_MIPS_GNU_REL16_S2,   /* type */
1741
         2,                     /* rightshift */
1742
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1743
         16,                    /* bitsize */
1744
         TRUE,                  /* pc_relative */
1745
         0,                      /* bitpos */
1746
         complain_overflow_signed, /* complain_on_overflow */
1747
         _bfd_mips_elf_generic_reloc,   /* special_function */
1748
         "R_MIPS_GNU_REL16_S2", /* name */
1749
         FALSE,                 /* partial_inplace */
1750
         0,                      /* src_mask */
1751
         0x0000ffff,            /* dst_mask */
1752
         TRUE);                 /* pcrel_offset */
1753
 
1754
/* Originally a VxWorks extension, but now used for other systems too.  */
1755
static reloc_howto_type elf_mips_copy_howto =
1756
  HOWTO (R_MIPS_COPY,           /* type */
1757
         0,                      /* rightshift */
1758
         0,                      /* this one is variable size */
1759
         0,                      /* bitsize */
1760
         FALSE,                 /* pc_relative */
1761
         0,                      /* bitpos */
1762
         complain_overflow_bitfield, /* complain_on_overflow */
1763
         bfd_elf_generic_reloc, /* special_function */
1764
         "R_MIPS_COPY",         /* name */
1765
         FALSE,                 /* partial_inplace */
1766
         0x0,                   /* src_mask */
1767
         0x0,                   /* dst_mask */
1768
         FALSE);                /* pcrel_offset */
1769
 
1770
/* Originally a VxWorks extension, but now used for other systems too.  */
1771
static reloc_howto_type elf_mips_jump_slot_howto =
1772
  HOWTO (R_MIPS_JUMP_SLOT,      /* type */
1773
         0,                      /* rightshift */
1774
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
1775
         64,                    /* bitsize */
1776
         FALSE,                 /* pc_relative */
1777
         0,                      /* bitpos */
1778
         complain_overflow_bitfield, /* complain_on_overflow */
1779
         bfd_elf_generic_reloc, /* special_function */
1780
         "R_MIPS_JUMP_SLOT",    /* name */
1781
         FALSE,                 /* partial_inplace */
1782
         0x0,                   /* src_mask */
1783
         0x0,                   /* dst_mask */
1784
         FALSE);                /* pcrel_offset */
1785
 
1786
/* Swap in a MIPS 64-bit Rel reloc.  */
1787
 
1788
static void
1789
mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src,
1790
                          Elf64_Mips_Internal_Rela *dst)
1791
{
1792
  dst->r_offset = H_GET_64 (abfd, src->r_offset);
1793
  dst->r_sym = H_GET_32 (abfd, src->r_sym);
1794
  dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1795
  dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1796
  dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1797
  dst->r_type = H_GET_8 (abfd, src->r_type);
1798
  dst->r_addend = 0;
1799
}
1800
 
1801
/* Swap in a MIPS 64-bit Rela reloc.  */
1802
 
1803
static void
1804
mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src,
1805
                           Elf64_Mips_Internal_Rela *dst)
1806
{
1807
  dst->r_offset = H_GET_64 (abfd, src->r_offset);
1808
  dst->r_sym = H_GET_32 (abfd, src->r_sym);
1809
  dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
1810
  dst->r_type3 = H_GET_8 (abfd, src->r_type3);
1811
  dst->r_type2 = H_GET_8 (abfd, src->r_type2);
1812
  dst->r_type = H_GET_8 (abfd, src->r_type);
1813
  dst->r_addend = H_GET_S64 (abfd, src->r_addend);
1814
}
1815
 
1816
/* Swap out a MIPS 64-bit Rel reloc.  */
1817
 
1818
static void
1819
mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1820
                           Elf64_Mips_External_Rel *dst)
1821
{
1822
  H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1823
  H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1824
  H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1825
  H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1826
  H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1827
  H_PUT_8 (abfd, src->r_type, dst->r_type);
1828
}
1829
 
1830
/* Swap out a MIPS 64-bit Rela reloc.  */
1831
 
1832
static void
1833
mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
1834
                            Elf64_Mips_External_Rela *dst)
1835
{
1836
  H_PUT_64 (abfd, src->r_offset, dst->r_offset);
1837
  H_PUT_32 (abfd, src->r_sym, dst->r_sym);
1838
  H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
1839
  H_PUT_8 (abfd, src->r_type3, dst->r_type3);
1840
  H_PUT_8 (abfd, src->r_type2, dst->r_type2);
1841
  H_PUT_8 (abfd, src->r_type, dst->r_type);
1842
  H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
1843
}
1844
 
1845
/* Swap in a MIPS 64-bit Rel reloc.  */
1846
 
1847
static void
1848
mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src,
1849
                             Elf_Internal_Rela *dst)
1850
{
1851
  Elf64_Mips_Internal_Rela mirel;
1852
 
1853
  mips_elf64_swap_reloc_in (abfd,
1854
                            (const Elf64_Mips_External_Rel *) src,
1855
                            &mirel);
1856
 
1857
  dst[0].r_offset = mirel.r_offset;
1858
  dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
1859
  dst[0].r_addend = 0;
1860
  dst[1].r_offset = mirel.r_offset;
1861
  dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
1862
  dst[1].r_addend = 0;
1863
  dst[2].r_offset = mirel.r_offset;
1864
  dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
1865
  dst[2].r_addend = 0;
1866
}
1867
 
1868
/* Swap in a MIPS 64-bit Rela reloc.  */
1869
 
1870
static void
1871
mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src,
1872
                              Elf_Internal_Rela *dst)
1873
{
1874
  Elf64_Mips_Internal_Rela mirela;
1875
 
1876
  mips_elf64_swap_reloca_in (abfd,
1877
                             (const Elf64_Mips_External_Rela *) src,
1878
                             &mirela);
1879
 
1880
  dst[0].r_offset = mirela.r_offset;
1881
  dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
1882
  dst[0].r_addend = mirela.r_addend;
1883
  dst[1].r_offset = mirela.r_offset;
1884
  dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
1885
  dst[1].r_addend = 0;
1886
  dst[2].r_offset = mirela.r_offset;
1887
  dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
1888
  dst[2].r_addend = 0;
1889
}
1890
 
1891
/* Swap out a MIPS 64-bit Rel reloc.  */
1892
 
1893
static void
1894
mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src,
1895
                              bfd_byte *dst)
1896
{
1897
  Elf64_Mips_Internal_Rela mirel;
1898
 
1899
  mirel.r_offset = src[0].r_offset;
1900
  BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1901
 
1902
  mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1903
  mirel.r_sym = ELF64_R_SYM (src[0].r_info);
1904
  mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1905
  mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1906
  mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1907
 
1908
  mips_elf64_swap_reloc_out (abfd, &mirel,
1909
                             (Elf64_Mips_External_Rel *) dst);
1910
}
1911
 
1912
/* Swap out a MIPS 64-bit Rela reloc.  */
1913
 
1914
static void
1915
mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
1916
                               bfd_byte *dst)
1917
{
1918
  Elf64_Mips_Internal_Rela mirela;
1919
 
1920
  mirela.r_offset = src[0].r_offset;
1921
  BFD_ASSERT(src[0].r_offset == src[1].r_offset);
1922
  BFD_ASSERT(src[0].r_offset == src[2].r_offset);
1923
 
1924
  mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
1925
  mirela.r_sym = ELF64_R_SYM (src[0].r_info);
1926
  mirela.r_addend = src[0].r_addend;
1927
  BFD_ASSERT(src[1].r_addend == 0);
1928
  BFD_ASSERT(src[2].r_addend == 0);
1929
 
1930
  mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
1931
  mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
1932
  mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
1933
 
1934
  mips_elf64_swap_reloca_out (abfd, &mirela,
1935
                              (Elf64_Mips_External_Rela *) dst);
1936
}
1937
 
1938
/* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
1939
   dangerous relocation.  */
1940
 
1941
static bfd_boolean
1942
mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp)
1943
{
1944
  unsigned int count;
1945
  asymbol **sym;
1946
  unsigned int i;
1947
 
1948
  /* If we've already figured out what GP will be, just return it.  */
1949
  *pgp = _bfd_get_gp_value (output_bfd);
1950
  if (*pgp)
1951
    return TRUE;
1952
 
1953
  count = bfd_get_symcount (output_bfd);
1954
  sym = bfd_get_outsymbols (output_bfd);
1955
 
1956
  /* The linker script will have created a symbol named `_gp' with the
1957
     appropriate value.  */
1958
  if (sym == NULL)
1959
    i = count;
1960
  else
1961
    {
1962
      for (i = 0; i < count; i++, sym++)
1963
        {
1964
          register const char *name;
1965
 
1966
          name = bfd_asymbol_name (*sym);
1967
          if (*name == '_' && strcmp (name, "_gp") == 0)
1968
            {
1969
              *pgp = bfd_asymbol_value (*sym);
1970
              _bfd_set_gp_value (output_bfd, *pgp);
1971
              break;
1972
            }
1973
        }
1974
    }
1975
 
1976
  if (i >= count)
1977
    {
1978
      /* Only get the error once.  */
1979
      *pgp = 4;
1980
      _bfd_set_gp_value (output_bfd, *pgp);
1981
      return FALSE;
1982
    }
1983
 
1984
  return TRUE;
1985
}
1986
 
1987
/* We have to figure out the gp value, so that we can adjust the
1988
   symbol value correctly.  We look up the symbol _gp in the output
1989
   BFD.  If we can't find it, we're stuck.  We cache it in the ELF
1990
   target data.  We don't need to adjust the symbol value for an
1991
   external symbol if we are producing relocatable output.  */
1992
 
1993
static bfd_reloc_status_type
1994
mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
1995
                     char **error_message, bfd_vma *pgp)
1996
{
1997
  if (bfd_is_und_section (symbol->section)
1998
      && ! relocatable)
1999
    {
2000
      *pgp = 0;
2001
      return bfd_reloc_undefined;
2002
    }
2003
 
2004
  *pgp = _bfd_get_gp_value (output_bfd);
2005
  if (*pgp == 0
2006
      && (! relocatable
2007
          || (symbol->flags & BSF_SECTION_SYM) != 0))
2008
    {
2009
      if (relocatable)
2010
        {
2011
          /* Make up a value.  */
2012
          *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
2013
          _bfd_set_gp_value (output_bfd, *pgp);
2014
        }
2015
      else if (!mips_elf64_assign_gp (output_bfd, pgp))
2016
        {
2017
          *error_message =
2018
            (char *) _("GP relative relocation when _gp not defined");
2019
          return bfd_reloc_dangerous;
2020
        }
2021
    }
2022
 
2023
  return bfd_reloc_ok;
2024
}
2025
 
2026
/* Do a R_MIPS_GPREL16 relocation.  This is a 16 bit value which must
2027
   become the offset from the gp register.  */
2028
 
2029
static bfd_reloc_status_type
2030
mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2031
                          void *data, asection *input_section, bfd *output_bfd,
2032
                          char **error_message)
2033
{
2034
  bfd_boolean relocatable;
2035
  bfd_reloc_status_type ret;
2036
  bfd_vma gp;
2037
 
2038
  /* If we're relocating, and this is an external symbol, we don't want
2039
     to change anything.  */
2040
  if (output_bfd != NULL
2041
      && (symbol->flags & BSF_SECTION_SYM) == 0
2042
      && (symbol->flags & BSF_LOCAL) != 0)
2043
    {
2044
      reloc_entry->address += input_section->output_offset;
2045
      return bfd_reloc_ok;
2046
    }
2047
 
2048
  if (output_bfd != NULL)
2049
    relocatable = TRUE;
2050
  else
2051
    {
2052
      relocatable = FALSE;
2053
      output_bfd = symbol->section->output_section->owner;
2054
    }
2055
 
2056
  ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
2057
                             &gp);
2058
  if (ret != bfd_reloc_ok)
2059
    return ret;
2060
 
2061
  return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2062
                                        input_section, relocatable,
2063
                                        data, gp);
2064
}
2065
 
2066
/* Do a R_MIPS_LITERAL relocation.  */
2067
 
2068
static bfd_reloc_status_type
2069
mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2070
                          void *data, asection *input_section, bfd *output_bfd,
2071
                          char **error_message)
2072
{
2073
  bfd_boolean relocatable;
2074
  bfd_reloc_status_type ret;
2075
  bfd_vma gp;
2076
 
2077
  /* R_MIPS_LITERAL relocations are defined for local symbols only.  */
2078
  if (output_bfd != NULL
2079
      && (symbol->flags & BSF_SECTION_SYM) == 0
2080
      && (symbol->flags & BSF_LOCAL) != 0)
2081
    {
2082
      *error_message = (char *)
2083
        _("literal relocation occurs for an external symbol");
2084
      return bfd_reloc_outofrange;
2085
    }
2086
 
2087
  /* FIXME: The entries in the .lit8 and .lit4 sections should be merged.  */
2088
  if (output_bfd != NULL)
2089
    relocatable = TRUE;
2090
  else
2091
    {
2092
      relocatable = FALSE;
2093
      output_bfd = symbol->section->output_section->owner;
2094
    }
2095
 
2096
  ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
2097
                             &gp);
2098
  if (ret != bfd_reloc_ok)
2099
    return ret;
2100
 
2101
  return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2102
                                        input_section, relocatable,
2103
                                        data, gp);
2104
}
2105
 
2106
/* Do a R_MIPS_GPREL32 relocation.  This is a 32 bit value which must
2107
   become the offset from the gp register.  */
2108
 
2109
static bfd_reloc_status_type
2110
mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2111
                          void *data, asection *input_section, bfd *output_bfd,
2112
                          char **error_message)
2113
{
2114
  bfd_boolean relocatable;
2115
  bfd_reloc_status_type ret;
2116
  bfd_vma gp;
2117
  bfd_vma relocation;
2118
  bfd_vma val;
2119
 
2120
  /* R_MIPS_GPREL32 relocations are defined for local symbols only.  */
2121
  if (output_bfd != NULL
2122
      && (symbol->flags & BSF_SECTION_SYM) == 0
2123
      && (symbol->flags & BSF_LOCAL) != 0)
2124
    {
2125
      *error_message = (char *)
2126
        _("32bits gp relative relocation occurs for an external symbol");
2127
      return bfd_reloc_outofrange;
2128
    }
2129
 
2130
  if (output_bfd != NULL)
2131
    relocatable = TRUE;
2132
  else
2133
    {
2134
      relocatable = FALSE;
2135
      output_bfd = symbol->section->output_section->owner;
2136
    }
2137
 
2138
  ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
2139
                             error_message, &gp);
2140
  if (ret != bfd_reloc_ok)
2141
    return ret;
2142
 
2143
  if (bfd_is_com_section (symbol->section))
2144
    relocation = 0;
2145
  else
2146
    relocation = symbol->value;
2147
 
2148
  relocation += symbol->section->output_section->vma;
2149
  relocation += symbol->section->output_offset;
2150
 
2151
  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
2152
    return bfd_reloc_outofrange;
2153
 
2154
  /* Set val to the offset into the section or symbol.  */
2155
  val = reloc_entry->addend;
2156
 
2157
  if (reloc_entry->howto->partial_inplace)
2158
    val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
2159
 
2160
  /* Adjust val for the final section location and GP value.  If we
2161
     are producing relocatable output, we don't want to do this for
2162
     an external symbol.  */
2163
  if (! relocatable
2164
      || (symbol->flags & BSF_SECTION_SYM) != 0)
2165
    val += relocation - gp;
2166
 
2167
  if (reloc_entry->howto->partial_inplace)
2168
    bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
2169
  else
2170
    reloc_entry->addend = val;
2171
 
2172
  if (relocatable)
2173
    reloc_entry->address += input_section->output_offset;
2174
 
2175
  return bfd_reloc_ok;
2176
}
2177
 
2178
/* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
2179
   the rest is at bits 6-10. The bitpos already got right by the howto.  */
2180
 
2181
static bfd_reloc_status_type
2182
mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2183
                         void *data, asection *input_section, bfd *output_bfd,
2184
                         char **error_message)
2185
{
2186
  if (reloc_entry->howto->partial_inplace)
2187
    {
2188
      reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
2189
                             | (reloc_entry->addend & 0x00000800) >> 9);
2190
    }
2191
 
2192
  return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
2193
                                      input_section, output_bfd,
2194
                                      error_message);
2195
}
2196
 
2197
/* Handle a mips16 GP relative reloc.  */
2198
 
2199
static bfd_reloc_status_type
2200
mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2201
                    void *data, asection *input_section, bfd *output_bfd,
2202
                    char **error_message)
2203
{
2204
  bfd_boolean relocatable;
2205
  bfd_reloc_status_type ret;
2206
  bfd_byte *location;
2207
  bfd_vma gp;
2208
 
2209
  /* If we're relocating, and this is an external symbol, we don't want
2210
     to change anything.  */
2211
  if (output_bfd != NULL
2212
      && (symbol->flags & BSF_SECTION_SYM) == 0
2213
      && (symbol->flags & BSF_LOCAL) != 0)
2214
    {
2215
      reloc_entry->address += input_section->output_offset;
2216
      return bfd_reloc_ok;
2217
    }
2218
 
2219
  if (output_bfd != NULL)
2220
    relocatable = TRUE;
2221
  else
2222
    {
2223
      relocatable = FALSE;
2224
      output_bfd = symbol->section->output_section->owner;
2225
    }
2226
 
2227
  ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
2228
                             &gp);
2229
  if (ret != bfd_reloc_ok)
2230
    return ret;
2231
 
2232
  location = (bfd_byte *) data + reloc_entry->address;
2233
  _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
2234
                                   location);
2235
  ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2236
                                       input_section, relocatable,
2237
                                       data, gp);
2238
  _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
2239
                                 location);
2240
 
2241
  return ret;
2242
}
2243
 
2244
/* A mapping from BFD reloc types to MIPS ELF reloc types.  */
2245
 
2246
struct elf_reloc_map {
2247
  bfd_reloc_code_real_type bfd_val;
2248
  enum elf_mips_reloc_type elf_val;
2249
};
2250
 
2251
static const struct elf_reloc_map mips_reloc_map[] =
2252
{
2253
  { BFD_RELOC_NONE, R_MIPS_NONE },
2254
  { BFD_RELOC_16, R_MIPS_16 },
2255
  { BFD_RELOC_32, R_MIPS_32 },
2256
  /* There is no BFD reloc for R_MIPS_REL32.  */
2257
  { BFD_RELOC_64, R_MIPS_64 },
2258
  { BFD_RELOC_CTOR, R_MIPS_64 },
2259
  { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
2260
  { BFD_RELOC_HI16_S, R_MIPS_HI16 },
2261
  { BFD_RELOC_LO16, R_MIPS_LO16 },
2262
  { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
2263
  { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
2264
  { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
2265
  { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
2266
  { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
2267
  { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
2268
  { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
2269
  { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
2270
  { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
2271
  { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
2272
  { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
2273
  { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
2274
  { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
2275
  { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
2276
  { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
2277
  { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
2278
  { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
2279
  { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
2280
  { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
2281
  { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
2282
  { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
2283
  { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
2284
  { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
2285
  /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated.  */
2286
  { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
2287
  { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
2288
  { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
2289
  { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
2290
  { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
2291
  { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
2292
  { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
2293
  { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
2294
  { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
2295
  { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
2296
  { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
2297
  { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
2298
  { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
2299
  { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
2300
  { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
2301
};
2302
 
2303
static const struct elf_reloc_map mips16_reloc_map[] =
2304
{
2305
  { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
2306
  { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
2307
  { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
2308
  { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
2309
  { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
2310
  { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
2311
};
2312
 
2313
/* Given a BFD reloc type, return a howto structure.  */
2314
 
2315
static reloc_howto_type *
2316
bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
2317
                                 bfd_reloc_code_real_type code)
2318
{
2319
  unsigned int i;
2320
  /* FIXME: We default to RELA here instead of choosing the right
2321
     relocation variant.  */
2322
  reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
2323
  reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela;
2324
 
2325
  for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
2326
       i++)
2327
    {
2328
      if (mips_reloc_map[i].bfd_val == code)
2329
        return &howto_table[(int) mips_reloc_map[i].elf_val];
2330
    }
2331
 
2332
  for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
2333
       i++)
2334
    {
2335
      if (mips16_reloc_map[i].bfd_val == code)
2336
        return &howto16_table[(int) mips16_reloc_map[i].elf_val];
2337
    }
2338
 
2339
  switch (code)
2340
    {
2341
    case BFD_RELOC_VTABLE_INHERIT:
2342
      return &elf_mips_gnu_vtinherit_howto;
2343
    case BFD_RELOC_VTABLE_ENTRY:
2344
      return &elf_mips_gnu_vtentry_howto;
2345
    case BFD_RELOC_MIPS_COPY:
2346
      return &elf_mips_copy_howto;
2347
    case BFD_RELOC_MIPS_JUMP_SLOT:
2348
      return &elf_mips_jump_slot_howto;
2349
    default:
2350
      bfd_set_error (bfd_error_bad_value);
2351
      return NULL;
2352
    }
2353
}
2354
 
2355
static reloc_howto_type *
2356
bfd_elf64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
2357
                                 const char *r_name)
2358
{
2359
  unsigned int i;
2360
 
2361
  for (i = 0;
2362
       i < (sizeof (mips_elf64_howto_table_rela)
2363
            / sizeof (mips_elf64_howto_table_rela[0])); i++)
2364
    if (mips_elf64_howto_table_rela[i].name != NULL
2365
        && strcasecmp (mips_elf64_howto_table_rela[i].name, r_name) == 0)
2366
      return &mips_elf64_howto_table_rela[i];
2367
 
2368
  for (i = 0;
2369
       i < (sizeof (mips16_elf64_howto_table_rela)
2370
            / sizeof (mips16_elf64_howto_table_rela[0]));
2371
       i++)
2372
    if (mips16_elf64_howto_table_rela[i].name != NULL
2373
        && strcasecmp (mips16_elf64_howto_table_rela[i].name, r_name) == 0)
2374
      return &mips16_elf64_howto_table_rela[i];
2375
 
2376
  if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
2377
    return &elf_mips_gnu_vtinherit_howto;
2378
  if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
2379
    return &elf_mips_gnu_vtentry_howto;
2380
  if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
2381
    return &elf_mips_gnu_rel16_s2;
2382
  if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
2383
    return &elf_mips_gnu_rela16_s2;
2384
  if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
2385
    return &elf_mips_copy_howto;
2386
  if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
2387
    return &elf_mips_jump_slot_howto;
2388
 
2389
  return NULL;
2390
}
2391
 
2392
/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
2393
 
2394
static reloc_howto_type *
2395
mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
2396
{
2397
  switch (r_type)
2398
    {
2399
    case R_MIPS_GNU_VTINHERIT:
2400
      return &elf_mips_gnu_vtinherit_howto;
2401
    case R_MIPS_GNU_VTENTRY:
2402
      return &elf_mips_gnu_vtentry_howto;
2403
    case R_MIPS_GNU_REL16_S2:
2404
      if (rela_p)
2405
        return &elf_mips_gnu_rela16_s2;
2406
      else
2407
        return &elf_mips_gnu_rel16_s2;
2408
    case R_MIPS_COPY:
2409
      return &elf_mips_copy_howto;
2410
    case R_MIPS_JUMP_SLOT:
2411
      return &elf_mips_jump_slot_howto;
2412
    default:
2413
      if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
2414
        {
2415
          if (rela_p)
2416
            return &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min];
2417
          else
2418
            return &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min];
2419
        }
2420
      BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
2421
      if (rela_p)
2422
        return &mips_elf64_howto_table_rela[r_type];
2423
      else
2424
        return &mips_elf64_howto_table_rel[r_type];
2425
      break;
2426
    }
2427
}
2428
 
2429
/* Prevent relocation handling by bfd for MIPS ELF64.  */
2430
 
2431
static void
2432
mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
2433
                              arelent *cache_ptr ATTRIBUTE_UNUSED,
2434
                              Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
2435
{
2436
  BFD_ASSERT (0);
2437
}
2438
 
2439
static void
2440
mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
2441
                               arelent *cache_ptr ATTRIBUTE_UNUSED,
2442
                               Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
2443
{
2444
  BFD_ASSERT (0);
2445
}
2446
 
2447
/* Since each entry in an SHT_REL or SHT_RELA section can represent up
2448
   to three relocs, we must tell the user to allocate more space.  */
2449
 
2450
static long
2451
mips_elf64_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
2452
{
2453
  return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
2454
}
2455
 
2456
static long
2457
mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
2458
{
2459
  return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
2460
}
2461
 
2462
/* We must also copy more relocations than the corresponding functions
2463
   in elf.c would, so the two following functions are slightly
2464
   modified from elf.c, that multiply the external relocation count by
2465
   3 to obtain the internal relocation count.  */
2466
 
2467
static long
2468
mips_elf64_canonicalize_reloc (bfd *abfd, sec_ptr section,
2469
                               arelent **relptr, asymbol **symbols)
2470
{
2471
  arelent *tblptr;
2472
  unsigned int i;
2473
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
2474
 
2475
  if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
2476
    return -1;
2477
 
2478
  tblptr = section->relocation;
2479
  for (i = 0; i < section->reloc_count * 3; i++)
2480
    *relptr++ = tblptr++;
2481
 
2482
  *relptr = NULL;
2483
 
2484
  return section->reloc_count * 3;
2485
}
2486
 
2487
static long
2488
mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
2489
                                       asymbol **syms)
2490
{
2491
  bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
2492
  asection *s;
2493
  long ret;
2494
 
2495
  if (elf_dynsymtab (abfd) == 0)
2496
    {
2497
      bfd_set_error (bfd_error_invalid_operation);
2498
      return -1;
2499
    }
2500
 
2501
  slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
2502
  ret = 0;
2503
  for (s = abfd->sections; s != NULL; s = s->next)
2504
    {
2505
      if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
2506
          && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
2507
              || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
2508
        {
2509
          arelent *p;
2510
          long count, i;
2511
 
2512
          if (! (*slurp_relocs) (abfd, s, syms, TRUE))
2513
            return -1;
2514
          count = s->size / elf_section_data (s)->this_hdr.sh_entsize * 3;
2515
          p = s->relocation;
2516
          for (i = 0; i < count; i++)
2517
            *storage++ = p++;
2518
          ret += count;
2519
        }
2520
    }
2521
 
2522
  *storage = NULL;
2523
 
2524
  return ret;
2525
}
2526
 
2527
/* Read the relocations from one reloc section.  This is mostly copied
2528
   from elfcode.h, except for the changes to expand one external
2529
   relocation to 3 internal ones.  We must unfortunately set
2530
   reloc_count to the number of external relocations, because a lot of
2531
   generic code seems to depend on this.  */
2532
 
2533
static bfd_boolean
2534
mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
2535
                                  Elf_Internal_Shdr *rel_hdr,
2536
                                  bfd_size_type reloc_count,
2537
                                  arelent *relents, asymbol **symbols,
2538
                                  bfd_boolean dynamic)
2539
{
2540
  void *allocated;
2541
  bfd_byte *native_relocs;
2542
  arelent *relent;
2543
  bfd_vma i;
2544
  int entsize;
2545
  bfd_boolean rela_p;
2546
 
2547
  allocated = bfd_malloc (rel_hdr->sh_size);
2548
  if (allocated == NULL)
2549
    return FALSE;
2550
 
2551
  if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
2552
      || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
2553
          != rel_hdr->sh_size))
2554
    goto error_return;
2555
 
2556
  native_relocs = allocated;
2557
 
2558
  entsize = rel_hdr->sh_entsize;
2559
  BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
2560
              || entsize == sizeof (Elf64_Mips_External_Rela));
2561
 
2562
  if (entsize == sizeof (Elf64_Mips_External_Rel))
2563
    rela_p = FALSE;
2564
  else
2565
    rela_p = TRUE;
2566
 
2567
  for (i = 0, relent = relents;
2568
       i < reloc_count;
2569
       i++, native_relocs += entsize)
2570
    {
2571
      Elf64_Mips_Internal_Rela rela;
2572
      bfd_boolean used_sym, used_ssym;
2573
      int ir;
2574
 
2575
      if (entsize == sizeof (Elf64_Mips_External_Rela))
2576
        mips_elf64_swap_reloca_in (abfd,
2577
                                   (Elf64_Mips_External_Rela *) native_relocs,
2578
                                   &rela);
2579
      else
2580
        mips_elf64_swap_reloc_in (abfd,
2581
                                  (Elf64_Mips_External_Rel *) native_relocs,
2582
                                  &rela);
2583
 
2584
      /* Each entry represents exactly three actual relocations.  */
2585
 
2586
      used_sym = FALSE;
2587
      used_ssym = FALSE;
2588
      for (ir = 0; ir < 3; ir++)
2589
        {
2590
          enum elf_mips_reloc_type type;
2591
 
2592
          switch (ir)
2593
            {
2594
            default:
2595
              abort ();
2596
            case 0:
2597
              type = (enum elf_mips_reloc_type) rela.r_type;
2598
              break;
2599
            case 1:
2600
              type = (enum elf_mips_reloc_type) rela.r_type2;
2601
              break;
2602
            case 2:
2603
              type = (enum elf_mips_reloc_type) rela.r_type3;
2604
              break;
2605
            }
2606
 
2607
          /* Some types require symbols, whereas some do not.  */
2608
          switch (type)
2609
            {
2610
            case R_MIPS_NONE:
2611
            case R_MIPS_LITERAL:
2612
            case R_MIPS_INSERT_A:
2613
            case R_MIPS_INSERT_B:
2614
            case R_MIPS_DELETE:
2615
              relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2616
              break;
2617
 
2618
            default:
2619
              if (! used_sym)
2620
                {
2621
                  if (rela.r_sym == 0)
2622
                    relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2623
                  else
2624
                    {
2625
                      asymbol **ps, *s;
2626
 
2627
                      ps = symbols + rela.r_sym - 1;
2628
                      s = *ps;
2629
                      if ((s->flags & BSF_SECTION_SYM) == 0)
2630
                        relent->sym_ptr_ptr = ps;
2631
                      else
2632
                        relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
2633
                    }
2634
 
2635
                  used_sym = TRUE;
2636
                }
2637
              else if (! used_ssym)
2638
                {
2639
                  switch (rela.r_ssym)
2640
                    {
2641
                    case RSS_UNDEF:
2642
                      relent->sym_ptr_ptr =
2643
                        bfd_abs_section_ptr->symbol_ptr_ptr;
2644
                      break;
2645
 
2646
                    case RSS_GP:
2647
                    case RSS_GP0:
2648
                    case RSS_LOC:
2649
                      /* FIXME: I think these need to be handled using
2650
                         special howto structures.  */
2651
                      BFD_ASSERT (0);
2652
                      break;
2653
 
2654
                    default:
2655
                      BFD_ASSERT (0);
2656
                      break;
2657
                    }
2658
 
2659
                  used_ssym = TRUE;
2660
                }
2661
              else
2662
                relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
2663
 
2664
              break;
2665
            }
2666
 
2667
          /* The address of an ELF reloc is section relative for an
2668
             object file, and absolute for an executable file or
2669
             shared library.  The address of a BFD reloc is always
2670
             section relative.  */
2671
          if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
2672
            relent->address = rela.r_offset;
2673
          else
2674
            relent->address = rela.r_offset - asect->vma;
2675
 
2676
          relent->addend = rela.r_addend;
2677
 
2678
          relent->howto = mips_elf64_rtype_to_howto (type, rela_p);
2679
 
2680
          ++relent;
2681
        }
2682
    }
2683
 
2684
  asect->reloc_count += (relent - relents) / 3;
2685
 
2686
  if (allocated != NULL)
2687
    free (allocated);
2688
 
2689
  return TRUE;
2690
 
2691
 error_return:
2692
  if (allocated != NULL)
2693
    free (allocated);
2694
  return FALSE;
2695
}
2696
 
2697
/* Read the relocations.  On Irix 6, there can be two reloc sections
2698
   associated with a single data section.  This is copied from
2699
   elfcode.h as well, with changes as small as accounting for 3
2700
   internal relocs per external reloc and resetting reloc_count to
2701
   zero before processing the relocs of a section.  */
2702
 
2703
static bfd_boolean
2704
mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
2705
                              asymbol **symbols, bfd_boolean dynamic)
2706
{
2707
  struct bfd_elf_section_data * const d = elf_section_data (asect);
2708
  Elf_Internal_Shdr *rel_hdr;
2709
  Elf_Internal_Shdr *rel_hdr2;
2710
  bfd_size_type reloc_count;
2711
  bfd_size_type reloc_count2;
2712
  arelent *relents;
2713
  bfd_size_type amt;
2714
 
2715
  if (asect->relocation != NULL)
2716
    return TRUE;
2717
 
2718
  if (! dynamic)
2719
    {
2720
      if ((asect->flags & SEC_RELOC) == 0
2721
          || asect->reloc_count == 0)
2722
        return TRUE;
2723
 
2724
      rel_hdr = &d->rel_hdr;
2725
      reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2726
      rel_hdr2 = d->rel_hdr2;
2727
      reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
2728
 
2729
      BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
2730
      BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset
2731
                  || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
2732
 
2733
    }
2734
  else
2735
    {
2736
      /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
2737
         case because relocations against this section may use the
2738
         dynamic symbol table, and in that case bfd_section_from_shdr
2739
         in elf.c does not update the RELOC_COUNT.  */
2740
      if (asect->size == 0)
2741
        return TRUE;
2742
 
2743
      rel_hdr = &d->this_hdr;
2744
      reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
2745
      rel_hdr2 = NULL;
2746
      reloc_count2 = 0;
2747
    }
2748
 
2749
  /* Allocate space for 3 arelent structures for each Rel structure.  */
2750
  amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
2751
  relents = bfd_alloc (abfd, amt);
2752
  if (relents == NULL)
2753
    return FALSE;
2754
 
2755
  /* The slurp_one_reloc_table routine increments reloc_count.  */
2756
  asect->reloc_count = 0;
2757
 
2758
  if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2759
                                          rel_hdr, reloc_count,
2760
                                          relents,
2761
                                          symbols, dynamic))
2762
    return FALSE;
2763
  if (d->rel_hdr2 != NULL)
2764
    {
2765
      if (! mips_elf64_slurp_one_reloc_table (abfd, asect,
2766
                                              rel_hdr2, reloc_count2,
2767
                                              relents + reloc_count * 3,
2768
                                              symbols, dynamic))
2769
        return FALSE;
2770
    }
2771
 
2772
  asect->relocation = relents;
2773
  return TRUE;
2774
}
2775
 
2776
/* Write out the relocations.  */
2777
 
2778
static void
2779
mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
2780
{
2781
  bfd_boolean *failedp = data;
2782
  int count;
2783
  Elf_Internal_Shdr *rel_hdr;
2784
  unsigned int idx;
2785
 
2786
  /* If we have already failed, don't do anything.  */
2787
  if (*failedp)
2788
    return;
2789
 
2790
  if ((sec->flags & SEC_RELOC) == 0)
2791
    return;
2792
 
2793
  /* The linker backend writes the relocs out itself, and sets the
2794
     reloc_count field to zero to inhibit writing them here.  Also,
2795
     sometimes the SEC_RELOC flag gets set even when there aren't any
2796
     relocs.  */
2797
  if (sec->reloc_count == 0)
2798
    return;
2799
 
2800
  /* We can combine up to three relocs that refer to the same address
2801
     if the latter relocs have no associated symbol.  */
2802
  count = 0;
2803
  for (idx = 0; idx < sec->reloc_count; idx++)
2804
    {
2805
      bfd_vma addr;
2806
      unsigned int i;
2807
 
2808
      ++count;
2809
 
2810
      addr = sec->orelocation[idx]->address;
2811
      for (i = 0; i < 2; i++)
2812
        {
2813
          arelent *r;
2814
 
2815
          if (idx + 1 >= sec->reloc_count)
2816
            break;
2817
          r = sec->orelocation[idx + 1];
2818
          if (r->address != addr
2819
              || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2820
              || (*r->sym_ptr_ptr)->value != 0)
2821
            break;
2822
 
2823
          /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
2824
 
2825
          ++idx;
2826
        }
2827
    }
2828
 
2829
  rel_hdr = &elf_section_data (sec)->rel_hdr;
2830
 
2831
  /* Do the actual relocation.  */
2832
 
2833
  if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
2834
    mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
2835
  else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
2836
    mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
2837
  else
2838
    BFD_ASSERT (0);
2839
}
2840
 
2841
static void
2842
mips_elf64_write_rel (bfd *abfd, asection *sec,
2843
                      Elf_Internal_Shdr *rel_hdr,
2844
                      int *count, void *data)
2845
{
2846
  bfd_boolean *failedp = data;
2847
  Elf64_Mips_External_Rel *ext_rel;
2848
  unsigned int idx;
2849
  asymbol *last_sym = 0;
2850
  int last_sym_idx = 0;
2851
 
2852
  rel_hdr->sh_size = rel_hdr->sh_entsize * *count;
2853
  rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size);
2854
  if (rel_hdr->contents == NULL)
2855
    {
2856
      *failedp = TRUE;
2857
      return;
2858
    }
2859
 
2860
  ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
2861
  for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
2862
    {
2863
      arelent *ptr;
2864
      Elf64_Mips_Internal_Rela int_rel;
2865
      asymbol *sym;
2866
      int n;
2867
      unsigned int i;
2868
 
2869
      ptr = sec->orelocation[idx];
2870
 
2871
      /* The address of an ELF reloc is section relative for an object
2872
         file, and absolute for an executable file or shared library.
2873
         The address of a BFD reloc is always section relative.  */
2874
      if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2875
        int_rel.r_offset = ptr->address;
2876
      else
2877
        int_rel.r_offset = ptr->address + sec->vma;
2878
 
2879
      sym = *ptr->sym_ptr_ptr;
2880
      if (sym == last_sym)
2881
        n = last_sym_idx;
2882
      else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2883
        n = STN_UNDEF;
2884
      else
2885
        {
2886
          last_sym = sym;
2887
          n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2888
          if (n < 0)
2889
            {
2890
              *failedp = TRUE;
2891
              return;
2892
            }
2893
          last_sym_idx = n;
2894
        }
2895
 
2896
      int_rel.r_sym = n;
2897
      int_rel.r_ssym = RSS_UNDEF;
2898
 
2899
      if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2900
          && ! _bfd_elf_validate_reloc (abfd, ptr))
2901
        {
2902
          *failedp = TRUE;
2903
          return;
2904
        }
2905
 
2906
      int_rel.r_type = ptr->howto->type;
2907
      int_rel.r_type2 = (int) R_MIPS_NONE;
2908
      int_rel.r_type3 = (int) R_MIPS_NONE;
2909
 
2910
      for (i = 0; i < 2; i++)
2911
        {
2912
          arelent *r;
2913
 
2914
          if (idx + 1 >= sec->reloc_count)
2915
            break;
2916
          r = sec->orelocation[idx + 1];
2917
          if (r->address != ptr->address
2918
              || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
2919
              || (*r->sym_ptr_ptr)->value != 0)
2920
            break;
2921
 
2922
          /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
2923
 
2924
          if (i == 0)
2925
            int_rel.r_type2 = r->howto->type;
2926
          else
2927
            int_rel.r_type3 = r->howto->type;
2928
 
2929
          ++idx;
2930
        }
2931
 
2932
      mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
2933
    }
2934
 
2935
  BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
2936
              == *count);
2937
}
2938
 
2939
static void
2940
mips_elf64_write_rela (bfd *abfd, asection *sec,
2941
                       Elf_Internal_Shdr *rela_hdr,
2942
                       int *count, void *data)
2943
{
2944
  bfd_boolean *failedp = data;
2945
  Elf64_Mips_External_Rela *ext_rela;
2946
  unsigned int idx;
2947
  asymbol *last_sym = 0;
2948
  int last_sym_idx = 0;
2949
 
2950
  rela_hdr->sh_size = rela_hdr->sh_entsize * *count;
2951
  rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
2952
  if (rela_hdr->contents == NULL)
2953
    {
2954
      *failedp = TRUE;
2955
      return;
2956
    }
2957
 
2958
  ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
2959
  for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
2960
    {
2961
      arelent *ptr;
2962
      Elf64_Mips_Internal_Rela int_rela;
2963
      asymbol *sym;
2964
      int n;
2965
      unsigned int i;
2966
 
2967
      ptr = sec->orelocation[idx];
2968
 
2969
      /* The address of an ELF reloc is section relative for an object
2970
         file, and absolute for an executable file or shared library.
2971
         The address of a BFD reloc is always section relative.  */
2972
      if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
2973
        int_rela.r_offset = ptr->address;
2974
      else
2975
        int_rela.r_offset = ptr->address + sec->vma;
2976
 
2977
      sym = *ptr->sym_ptr_ptr;
2978
      if (sym == last_sym)
2979
        n = last_sym_idx;
2980
      else if (bfd_is_abs_section (sym->section) && sym->value == 0)
2981
        n = STN_UNDEF;
2982
      else
2983
        {
2984
          last_sym = sym;
2985
          n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
2986
          if (n < 0)
2987
            {
2988
              *failedp = TRUE;
2989
              return;
2990
            }
2991
          last_sym_idx = n;
2992
        }
2993
 
2994
      int_rela.r_sym = n;
2995
      int_rela.r_addend = ptr->addend;
2996
      int_rela.r_ssym = RSS_UNDEF;
2997
 
2998
      if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
2999
          && ! _bfd_elf_validate_reloc (abfd, ptr))
3000
        {
3001
          *failedp = TRUE;
3002
          return;
3003
        }
3004
 
3005
      int_rela.r_type = ptr->howto->type;
3006
      int_rela.r_type2 = (int) R_MIPS_NONE;
3007
      int_rela.r_type3 = (int) R_MIPS_NONE;
3008
 
3009
      for (i = 0; i < 2; i++)
3010
        {
3011
          arelent *r;
3012
 
3013
          if (idx + 1 >= sec->reloc_count)
3014
            break;
3015
          r = sec->orelocation[idx + 1];
3016
          if (r->address != ptr->address
3017
              || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
3018
              || (*r->sym_ptr_ptr)->value != 0)
3019
            break;
3020
 
3021
          /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
3022
 
3023
          if (i == 0)
3024
            int_rela.r_type2 = r->howto->type;
3025
          else
3026
            int_rela.r_type3 = r->howto->type;
3027
 
3028
          ++idx;
3029
        }
3030
 
3031
      mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
3032
    }
3033
 
3034
  BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
3035
              == *count);
3036
}
3037
 
3038
/* Set the right machine number for a MIPS ELF file.  */
3039
 
3040
static bfd_boolean
3041
mips_elf64_object_p (bfd *abfd)
3042
{
3043
  unsigned long mach;
3044
 
3045
  /* Irix 6 is broken.  Object file symbol tables are not always
3046
     sorted correctly such that local symbols precede global symbols,
3047
     and the sh_info field in the symbol table is not always right.  */
3048
  if (elf64_mips_irix_compat (abfd) != ict_none)
3049
    elf_bad_symtab (abfd) = TRUE;
3050
 
3051
  mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
3052
  bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
3053
  return TRUE;
3054
}
3055
 
3056
/* Depending on the target vector we generate some version of Irix
3057
   executables or "normal" MIPS ELF ABI executables.  */
3058
static irix_compat_t
3059
elf64_mips_irix_compat (bfd *abfd)
3060
{
3061
  if ((abfd->xvec == &bfd_elf64_bigmips_vec)
3062
      || (abfd->xvec == &bfd_elf64_littlemips_vec))
3063
    return ict_irix6;
3064
  else
3065
    return ict_none;
3066
}
3067
 
3068
/* Support for core dump NOTE sections.  */
3069
static bfd_boolean
3070
elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3071
{
3072
  int offset;
3073
  unsigned int size;
3074
 
3075
  switch (note->descsz)
3076
    {
3077
      default:
3078
        return FALSE;
3079
 
3080
      case 480:         /* Linux/MIPS - N64 kernel */
3081
        /* pr_cursig */
3082
        elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
3083
 
3084
        /* pr_pid */
3085
        elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 32);
3086
 
3087
        /* pr_reg */
3088
        offset = 112;
3089
        size = 360;
3090
 
3091
        break;
3092
    }
3093
 
3094
  /* Make a ".reg/999" section.  */
3095
  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
3096
                                          size, note->descpos + offset);
3097
}
3098
 
3099
static bfd_boolean
3100
elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3101
{
3102
  switch (note->descsz)
3103
    {
3104
      default:
3105
        return FALSE;
3106
 
3107
      case 136:         /* Linux/MIPS - N64 kernel elf_prpsinfo */
3108
        elf_tdata (abfd)->core_program
3109
         = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
3110
        elf_tdata (abfd)->core_command
3111
         = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
3112
    }
3113
 
3114
  /* Note that for some reason, a spurious space is tacked
3115
     onto the end of the args in some (at least one anyway)
3116
     implementations, so strip it off if it exists.  */
3117
 
3118
  {
3119
    char *command = elf_tdata (abfd)->core_command;
3120
    int n = strlen (command);
3121
 
3122
    if (0 < n && command[n - 1] == ' ')
3123
      command[n - 1] = '\0';
3124
  }
3125
 
3126
  return TRUE;
3127
}
3128
 
3129
/* ECOFF swapping routines.  These are used when dealing with the
3130
   .mdebug section, which is in the ECOFF debugging format.  */
3131
static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
3132
{
3133
  /* Symbol table magic number.  */
3134
  magicSym2,
3135
  /* Alignment of debugging information.  E.g., 4.  */
3136
  8,
3137
  /* Sizes of external symbolic information.  */
3138
  sizeof (struct hdr_ext),
3139
  sizeof (struct dnr_ext),
3140
  sizeof (struct pdr_ext),
3141
  sizeof (struct sym_ext),
3142
  sizeof (struct opt_ext),
3143
  sizeof (struct fdr_ext),
3144
  sizeof (struct rfd_ext),
3145
  sizeof (struct ext_ext),
3146
  /* Functions to swap in external symbolic data.  */
3147
  ecoff_swap_hdr_in,
3148
  ecoff_swap_dnr_in,
3149
  ecoff_swap_pdr_in,
3150
  ecoff_swap_sym_in,
3151
  ecoff_swap_opt_in,
3152
  ecoff_swap_fdr_in,
3153
  ecoff_swap_rfd_in,
3154
  ecoff_swap_ext_in,
3155
  _bfd_ecoff_swap_tir_in,
3156
  _bfd_ecoff_swap_rndx_in,
3157
  /* Functions to swap out external symbolic data.  */
3158
  ecoff_swap_hdr_out,
3159
  ecoff_swap_dnr_out,
3160
  ecoff_swap_pdr_out,
3161
  ecoff_swap_sym_out,
3162
  ecoff_swap_opt_out,
3163
  ecoff_swap_fdr_out,
3164
  ecoff_swap_rfd_out,
3165
  ecoff_swap_ext_out,
3166
  _bfd_ecoff_swap_tir_out,
3167
  _bfd_ecoff_swap_rndx_out,
3168
  /* Function to read in symbolic data.  */
3169
  _bfd_mips_elf_read_ecoff_info
3170
};
3171
 
3172
/* Relocations in the 64 bit MIPS ELF ABI are more complex than in
3173
   standard ELF.  This structure is used to redirect the relocation
3174
   handling routines.  */
3175
 
3176
const struct elf_size_info mips_elf64_size_info =
3177
{
3178
  sizeof (Elf64_External_Ehdr),
3179
  sizeof (Elf64_External_Phdr),
3180
  sizeof (Elf64_External_Shdr),
3181
  sizeof (Elf64_Mips_External_Rel),
3182
  sizeof (Elf64_Mips_External_Rela),
3183
  sizeof (Elf64_External_Sym),
3184
  sizeof (Elf64_External_Dyn),
3185
  sizeof (Elf_External_Note),
3186
  4,            /* hash-table entry size */
3187
  3,            /* internal relocations per external relocations */
3188
  64,           /* arch_size */
3189
  3,            /* log_file_align */
3190
  ELFCLASS64,
3191
  EV_CURRENT,
3192
  bfd_elf64_write_out_phdrs,
3193
  bfd_elf64_write_shdrs_and_ehdr,
3194
  bfd_elf64_checksum_contents,
3195
  mips_elf64_write_relocs,
3196
  bfd_elf64_swap_symbol_in,
3197
  bfd_elf64_swap_symbol_out,
3198
  mips_elf64_slurp_reloc_table,
3199
  bfd_elf64_slurp_symbol_table,
3200
  bfd_elf64_swap_dyn_in,
3201
  bfd_elf64_swap_dyn_out,
3202
  mips_elf64_be_swap_reloc_in,
3203
  mips_elf64_be_swap_reloc_out,
3204
  mips_elf64_be_swap_reloca_in,
3205
  mips_elf64_be_swap_reloca_out
3206
};
3207
 
3208
#define ELF_ARCH                        bfd_arch_mips
3209
#define ELF_MACHINE_CODE                EM_MIPS
3210
 
3211
#define elf_backend_collect             TRUE
3212
#define elf_backend_type_change_ok      TRUE
3213
#define elf_backend_can_gc_sections     TRUE
3214
#define elf_info_to_howto               mips_elf64_info_to_howto_rela
3215
#define elf_info_to_howto_rel           mips_elf64_info_to_howto_rel
3216
#define elf_backend_object_p            mips_elf64_object_p
3217
#define elf_backend_symbol_processing   _bfd_mips_elf_symbol_processing
3218
#define elf_backend_section_processing  _bfd_mips_elf_section_processing
3219
#define elf_backend_section_from_shdr   _bfd_mips_elf_section_from_shdr
3220
#define elf_backend_fake_sections       _bfd_mips_elf_fake_sections
3221
#define elf_backend_section_from_bfd_section \
3222
                                _bfd_mips_elf_section_from_bfd_section
3223
#define elf_backend_add_symbol_hook     _bfd_mips_elf_add_symbol_hook
3224
#define elf_backend_link_output_symbol_hook \
3225
                                _bfd_mips_elf_link_output_symbol_hook
3226
#define elf_backend_create_dynamic_sections \
3227
                                _bfd_mips_elf_create_dynamic_sections
3228
#define elf_backend_check_relocs        _bfd_mips_elf_check_relocs
3229
#define elf_backend_merge_symbol_attribute \
3230
                                _bfd_mips_elf_merge_symbol_attribute
3231
#define elf_backend_get_target_dtag     _bfd_mips_elf_get_target_dtag
3232
#define elf_backend_adjust_dynamic_symbol \
3233
                                _bfd_mips_elf_adjust_dynamic_symbol
3234
#define elf_backend_always_size_sections \
3235
                                _bfd_mips_elf_always_size_sections
3236
#define elf_backend_size_dynamic_sections \
3237
                                _bfd_mips_elf_size_dynamic_sections
3238
#define elf_backend_init_index_section  _bfd_elf_init_1_index_section
3239
#define elf_backend_relocate_section    _bfd_mips_elf_relocate_section
3240
#define elf_backend_finish_dynamic_symbol \
3241
                                _bfd_mips_elf_finish_dynamic_symbol
3242
#define elf_backend_finish_dynamic_sections \
3243
                                _bfd_mips_elf_finish_dynamic_sections
3244
#define elf_backend_final_write_processing \
3245
                                _bfd_mips_elf_final_write_processing
3246
#define elf_backend_additional_program_headers \
3247
                                _bfd_mips_elf_additional_program_headers
3248
#define elf_backend_modify_segment_map  _bfd_mips_elf_modify_segment_map
3249
#define elf_backend_gc_mark_hook        _bfd_mips_elf_gc_mark_hook
3250
#define elf_backend_gc_sweep_hook       _bfd_mips_elf_gc_sweep_hook
3251
#define elf_backend_copy_indirect_symbol \
3252
                                        _bfd_mips_elf_copy_indirect_symbol
3253
#define elf_backend_ignore_discarded_relocs \
3254
                                        _bfd_mips_elf_ignore_discarded_relocs
3255
#define elf_backend_mips_irix_compat    elf64_mips_irix_compat
3256
#define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
3257
#define elf_backend_ecoff_debug_swap    &mips_elf64_ecoff_debug_swap
3258
#define elf_backend_size_info           mips_elf64_size_info
3259
 
3260
#define elf_backend_grok_prstatus       elf64_mips_grok_prstatus
3261
#define elf_backend_grok_psinfo         elf64_mips_grok_psinfo
3262
 
3263
#define elf_backend_got_header_size     (4 * MIPS_RESERVED_GOTNO)
3264
 
3265
/* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
3266
   work better/work only in RELA, so we default to this.  */
3267
#define elf_backend_may_use_rel_p       1
3268
#define elf_backend_may_use_rela_p      1
3269
#define elf_backend_default_use_rela_p  1
3270
#define elf_backend_rela_plts_and_copies_p 0
3271
#define elf_backend_plt_readonly        1
3272
#define elf_backend_plt_sym_val         _bfd_mips_elf_plt_sym_val
3273
 
3274
#define elf_backend_sign_extend_vma     TRUE
3275
 
3276
#define elf_backend_write_section       _bfd_mips_elf_write_section
3277
 
3278
/* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
3279
   MIPS-specific function only applies to IRIX5, which had no 64-bit
3280
   ABI.  */
3281
#define bfd_elf64_find_nearest_line     _bfd_mips_elf_find_nearest_line
3282
#define bfd_elf64_find_inliner_info     _bfd_mips_elf_find_inliner_info
3283
#define bfd_elf64_new_section_hook      _bfd_mips_elf_new_section_hook
3284
#define bfd_elf64_set_section_contents  _bfd_mips_elf_set_section_contents
3285
#define bfd_elf64_bfd_get_relocated_section_contents \
3286
                                _bfd_elf_mips_get_relocated_section_contents
3287
#define bfd_elf64_mkobject              _bfd_mips_elf_mkobject
3288
#define bfd_elf64_bfd_link_hash_table_create \
3289
                                _bfd_mips_elf_link_hash_table_create
3290
#define bfd_elf64_bfd_final_link        _bfd_mips_elf_final_link
3291
#define bfd_elf64_bfd_merge_private_bfd_data \
3292
                                _bfd_mips_elf_merge_private_bfd_data
3293
#define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
3294
#define bfd_elf64_bfd_print_private_bfd_data \
3295
                                _bfd_mips_elf_print_private_bfd_data
3296
 
3297
#define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
3298
#define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
3299
#define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
3300
#define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
3301
#define bfd_elf64_bfd_relax_section     _bfd_mips_relax_section
3302
 
3303
/* MIPS ELF64 archive functions.  */
3304
#define bfd_elf64_archive_functions
3305
extern bfd_boolean bfd_elf64_archive_slurp_armap
3306
  (bfd *);
3307
extern bfd_boolean bfd_elf64_archive_write_armap
3308
  (bfd *, unsigned int, struct orl *, unsigned int, int);
3309
#define bfd_elf64_archive_slurp_extended_name_table \
3310
                        _bfd_archive_coff_slurp_extended_name_table
3311
#define bfd_elf64_archive_construct_extended_name_table \
3312
                        _bfd_archive_coff_construct_extended_name_table
3313
#define bfd_elf64_archive_truncate_arname \
3314
                        _bfd_archive_coff_truncate_arname
3315
#define bfd_elf64_archive_read_ar_hdr   _bfd_archive_coff_read_ar_hdr
3316
#define bfd_elf64_archive_write_ar_hdr  _bfd_archive_coff_write_ar_hdr
3317
#define bfd_elf64_archive_openr_next_archived_file \
3318
                        _bfd_archive_coff_openr_next_archived_file
3319
#define bfd_elf64_archive_get_elt_at_index \
3320
                        _bfd_archive_coff_get_elt_at_index
3321
#define bfd_elf64_archive_generic_stat_arch_elt \
3322
                        _bfd_archive_coff_generic_stat_arch_elt
3323
#define bfd_elf64_archive_update_armap_timestamp \
3324
                        _bfd_archive_coff_update_armap_timestamp
3325
 
3326
/* The SGI style (n)64 NewABI.  */
3327
#define TARGET_LITTLE_SYM               bfd_elf64_littlemips_vec
3328
#define TARGET_LITTLE_NAME              "elf64-littlemips"
3329
#define TARGET_BIG_SYM                  bfd_elf64_bigmips_vec
3330
#define TARGET_BIG_NAME                 "elf64-bigmips"
3331
 
3332
#define ELF_MAXPAGESIZE                 0x10000
3333
#define ELF_COMMONPAGESIZE              0x1000
3334
 
3335
#include "elf64-target.h"
3336
 
3337
/* The SYSV-style 'traditional' (n)64 NewABI.  */
3338
#undef TARGET_LITTLE_SYM
3339
#undef TARGET_LITTLE_NAME
3340
#undef TARGET_BIG_SYM
3341
#undef TARGET_BIG_NAME
3342
 
3343
#undef ELF_MAXPAGESIZE
3344
#undef ELF_COMMONPAGESIZE
3345
 
3346
#define TARGET_LITTLE_SYM               bfd_elf64_tradlittlemips_vec
3347
#define TARGET_LITTLE_NAME              "elf64-tradlittlemips"
3348
#define TARGET_BIG_SYM                  bfd_elf64_tradbigmips_vec
3349
#define TARGET_BIG_NAME                 "elf64-tradbigmips"
3350
 
3351
#define ELF_MAXPAGESIZE                 0x10000
3352
#define ELF_COMMONPAGESIZE              0x1000
3353
#define elf64_bed                       elf64_tradbed
3354
 
3355
/* Include the target file again for this target.  */
3356
#include "elf64-target.h"

powered by: WebSVN 2.1.0

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