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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [bfd/] [elf64-mips.c] - Blame information for rev 865

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

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

powered by: WebSVN 2.1.0

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