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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elf64-mips.c] - Blame information for rev 231

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

Line No. Rev Author Line
1 14 khays
/* 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
         FALSE,                 /* partial_inplace */
1343 166 khays
         0,                      /* src_mask */
1344 14 khays
         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
         FALSE,                 /* partial_inplace */
1357 166 khays
         0,                      /* src_mask */
1358 14 khays
         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
         FALSE,                 /* partial_inplace */
1372 166 khays
         0,                      /* src_mask */
1373 14 khays
         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
         FALSE,                 /* partial_inplace */
1387 166 khays
         0,                      /* src_mask */
1388 14 khays
         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
         FALSE,                 /* partial_inplace */
1402 166 khays
         0,                      /* src_mask */
1403 14 khays
         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
         FALSE,                 /* partial_inplace */
1417 166 khays
         0,                      /* src_mask */
1418 14 khays
         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
         FALSE,                 /* partial_inplace */
1432 166 khays
         0,                      /* src_mask */
1433 14 khays
         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
         FALSE,                 /* partial_inplace */
1449 166 khays
         0,                      /* src_mask */
1450 14 khays
         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
         FALSE,                 /* partial_inplace */
1464 166 khays
         0,                      /* src_mask */
1465 14 khays
         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
         FALSE,                 /* partial_inplace */
1479 166 khays
         0,                      /* src_mask */
1480 14 khays
         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 166 khays
 
1594
  /* MIPS16 TLS general dynamic variable reference.  */
1595
  HOWTO (R_MIPS16_TLS_GD,       /* type */
1596
         0,                      /* rightshift */
1597
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1598
         16,                    /* bitsize */
1599
         FALSE,                 /* pc_relative */
1600
         0,                      /* bitpos */
1601
         complain_overflow_signed, /* complain_on_overflow */
1602
         _bfd_mips_elf_generic_reloc, /* special_function */
1603
         "R_MIPS16_TLS_GD",     /* name */
1604
         TRUE,                  /* partial_inplace */
1605
         0x0000ffff,            /* src_mask */
1606
         0x0000ffff,            /* dst_mask */
1607
         FALSE),                /* pcrel_offset */
1608
 
1609
  /* MIPS16 TLS local dynamic variable reference.  */
1610
  HOWTO (R_MIPS16_TLS_LDM,      /* type */
1611
         0,                      /* rightshift */
1612
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1613
         16,                    /* bitsize */
1614
         FALSE,                 /* pc_relative */
1615
         0,                      /* bitpos */
1616
         complain_overflow_signed, /* complain_on_overflow */
1617
         _bfd_mips_elf_generic_reloc, /* special_function */
1618
         "R_MIPS16_TLS_LDM",    /* name */
1619
         TRUE,                  /* partial_inplace */
1620
         0x0000ffff,            /* src_mask */
1621
         0x0000ffff,            /* dst_mask */
1622
         FALSE),                /* pcrel_offset */
1623
 
1624
  /* MIPS16 TLS local dynamic offset.  */
1625
  HOWTO (R_MIPS16_TLS_DTPREL_HI16,      /* type */
1626
         0,                      /* rightshift */
1627
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1628
         16,                    /* bitsize */
1629
         FALSE,                 /* pc_relative */
1630
         0,                      /* bitpos */
1631
         complain_overflow_signed, /* complain_on_overflow */
1632
         _bfd_mips_elf_generic_reloc, /* special_function */
1633
         "R_MIPS16_TLS_DTPREL_HI16",    /* name */
1634
         TRUE,                  /* partial_inplace */
1635
         0x0000ffff,            /* src_mask */
1636
         0x0000ffff,            /* dst_mask */
1637
         FALSE),                /* pcrel_offset */
1638
 
1639
  /* MIPS16 TLS local dynamic offset.  */
1640
  HOWTO (R_MIPS16_TLS_DTPREL_LO16,      /* type */
1641
         0,                      /* rightshift */
1642
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1643
         16,                    /* bitsize */
1644
         FALSE,                 /* pc_relative */
1645
         0,                      /* bitpos */
1646
         complain_overflow_signed, /* complain_on_overflow */
1647
         _bfd_mips_elf_generic_reloc, /* special_function */
1648
         "R_MIPS16_TLS_DTPREL_LO16",    /* name */
1649
         TRUE,                  /* partial_inplace */
1650
         0x0000ffff,            /* src_mask */
1651
         0x0000ffff,            /* dst_mask */
1652
         FALSE),                /* pcrel_offset */
1653
 
1654
  /* MIPS16 TLS thread pointer offset.  */
1655
  HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
1656
         0,                      /* rightshift */
1657
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1658
         16,                    /* bitsize */
1659
         FALSE,                 /* pc_relative */
1660
         0,                      /* bitpos */
1661
         complain_overflow_signed, /* complain_on_overflow */
1662
         _bfd_mips_elf_generic_reloc, /* special_function */
1663
         "R_MIPS16_TLS_GOTTPREL",       /* name */
1664
         TRUE,                  /* partial_inplace */
1665
         0x0000ffff,            /* src_mask */
1666
         0x0000ffff,            /* dst_mask */
1667
         FALSE),                /* pcrel_offset */
1668
 
1669
  /* MIPS16 TLS thread pointer offset.  */
1670
  HOWTO (R_MIPS16_TLS_TPREL_HI16,       /* type */
1671
         0,                      /* rightshift */
1672
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1673
         16,                    /* bitsize */
1674
         FALSE,                 /* pc_relative */
1675
         0,                      /* bitpos */
1676
         complain_overflow_signed, /* complain_on_overflow */
1677
         _bfd_mips_elf_generic_reloc, /* special_function */
1678
         "R_MIPS16_TLS_TPREL_HI16", /* name */
1679
         TRUE,                  /* partial_inplace */
1680
         0x0000ffff,            /* src_mask */
1681
         0x0000ffff,            /* dst_mask */
1682
         FALSE),                /* pcrel_offset */
1683
 
1684
  /* MIPS16 TLS thread pointer offset.  */
1685
  HOWTO (R_MIPS16_TLS_TPREL_LO16,       /* type */
1686
         0,                      /* rightshift */
1687
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1688
         16,                    /* bitsize */
1689
         FALSE,                 /* pc_relative */
1690
         0,                      /* bitpos */
1691
         complain_overflow_signed, /* complain_on_overflow */
1692
         _bfd_mips_elf_generic_reloc, /* special_function */
1693
         "R_MIPS16_TLS_TPREL_LO16", /* name */
1694
         TRUE,                  /* partial_inplace */
1695
         0x0000ffff,            /* src_mask */
1696
         0x0000ffff,            /* dst_mask */
1697
         FALSE),                /* pcrel_offset */
1698 14 khays
};
1699
 
1700
static reloc_howto_type mips16_elf64_howto_table_rela[] =
1701
{
1702
  /* The reloc used for the mips16 jump instruction.  */
1703
  HOWTO (R_MIPS16_26,           /* type */
1704
         2,                     /* rightshift */
1705
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1706
         26,                    /* bitsize */
1707
         FALSE,                 /* pc_relative */
1708
         0,                      /* bitpos */
1709
         complain_overflow_dont, /* complain_on_overflow */
1710
                                /* This needs complex overflow
1711
                                   detection, because the upper four
1712
                                   bits must match the PC.  */
1713
         _bfd_mips_elf_generic_reloc, /* special_function */
1714
         "R_MIPS16_26",         /* name */
1715
         FALSE,                 /* partial_inplace */
1716 166 khays
         0,                      /* src_mask */
1717 14 khays
         0x3ffffff,             /* dst_mask */
1718
         FALSE),                /* pcrel_offset */
1719
 
1720
  /* The reloc used for the mips16 gprel instruction.  */
1721
  HOWTO (R_MIPS16_GPREL,        /* type */
1722
         0,                      /* rightshift */
1723
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1724
         16,                    /* bitsize */
1725
         FALSE,                 /* pc_relative */
1726
         0,                      /* bitpos */
1727
         complain_overflow_signed, /* complain_on_overflow */
1728
         mips16_gprel_reloc,    /* special_function */
1729
         "R_MIPS16_GPREL",      /* name */
1730
         FALSE,                 /* partial_inplace */
1731 166 khays
         0,                      /* src_mask */
1732 14 khays
         0x0000ffff,            /* dst_mask */
1733
         FALSE),                /* pcrel_offset */
1734
 
1735
  /* A MIPS16 reference to the global offset table.  */
1736
  HOWTO (R_MIPS16_GOT16,        /* type */
1737
         0,                      /* rightshift */
1738
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1739
         16,                    /* bitsize */
1740
         FALSE,                 /* pc_relative */
1741
         0,                      /* bitpos */
1742
         complain_overflow_dont, /* complain_on_overflow */
1743
         _bfd_mips_elf_got16_reloc, /* special_function */
1744
         "R_MIPS16_GOT16",      /* name */
1745
         FALSE,                 /* partial_inplace */
1746 166 khays
         0,                      /* src_mask */
1747 14 khays
         0x0000ffff,            /* dst_mask */
1748
         FALSE),                /* pcrel_offset */
1749
 
1750
  /* A MIPS16 call through the global offset table.  */
1751
  HOWTO (R_MIPS16_CALL16,       /* type */
1752
         0,                      /* rightshift */
1753
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1754
         16,                    /* bitsize */
1755
         FALSE,                 /* pc_relative */
1756
         0,                      /* bitpos */
1757
         complain_overflow_dont, /* complain_on_overflow */
1758
         _bfd_mips_elf_generic_reloc, /* special_function */
1759
         "R_MIPS16_CALL16",     /* name */
1760
         FALSE,                 /* partial_inplace */
1761 166 khays
         0,                      /* src_mask */
1762 14 khays
         0x0000ffff,            /* dst_mask */
1763
         FALSE),                /* pcrel_offset */
1764
 
1765
  /* MIPS16 high 16 bits of symbol value.  */
1766
  HOWTO (R_MIPS16_HI16,         /* type */
1767
         16,                    /* rightshift */
1768
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1769
         16,                    /* bitsize */
1770
         FALSE,                 /* pc_relative */
1771
         0,                      /* bitpos */
1772
         complain_overflow_dont, /* complain_on_overflow */
1773
         _bfd_mips_elf_hi16_reloc, /* special_function */
1774
         "R_MIPS16_HI16",       /* name */
1775
         FALSE,                 /* partial_inplace */
1776 166 khays
         0,                      /* src_mask */
1777 14 khays
         0x0000ffff,            /* dst_mask */
1778
         FALSE),                /* pcrel_offset */
1779
 
1780
  /* MIPS16 low 16 bits of symbol value.  */
1781
  HOWTO (R_MIPS16_LO16,         /* type */
1782
         0,                      /* rightshift */
1783
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1784
         16,                    /* bitsize */
1785
         FALSE,                 /* pc_relative */
1786
         0,                      /* bitpos */
1787
         complain_overflow_dont, /* complain_on_overflow */
1788
         _bfd_mips_elf_lo16_reloc, /* special_function */
1789
         "R_MIPS16_LO16",       /* name */
1790
         FALSE,                 /* partial_inplace */
1791 166 khays
         0,                      /* src_mask */
1792
         0x0000ffff,            /* dst_mask */
1793
         FALSE),                /* pcrel_offset */
1794
 
1795
  /* MIPS16 TLS general dynamic variable reference.  */
1796
  HOWTO (R_MIPS16_TLS_GD,       /* type */
1797
         0,                      /* rightshift */
1798
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1799
         16,                    /* bitsize */
1800
         FALSE,                 /* pc_relative */
1801
         0,                      /* bitpos */
1802
         complain_overflow_signed, /* complain_on_overflow */
1803
         _bfd_mips_elf_generic_reloc, /* special_function */
1804
         "R_MIPS16_TLS_GD",     /* name */
1805
         FALSE,                 /* partial_inplace */
1806 14 khays
         0x0000ffff,            /* src_mask */
1807
         0x0000ffff,            /* dst_mask */
1808
         FALSE),                /* pcrel_offset */
1809 166 khays
 
1810
  /* MIPS16 TLS local dynamic variable reference.  */
1811
  HOWTO (R_MIPS16_TLS_LDM,      /* type */
1812
         0,                      /* rightshift */
1813
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1814
         16,                    /* bitsize */
1815
         FALSE,                 /* pc_relative */
1816
         0,                      /* bitpos */
1817
         complain_overflow_signed, /* complain_on_overflow */
1818
         _bfd_mips_elf_generic_reloc, /* special_function */
1819
         "R_MIPS16_TLS_LDM",    /* name */
1820
         FALSE,                 /* partial_inplace */
1821
         0x0000ffff,            /* src_mask */
1822
         0x0000ffff,            /* dst_mask */
1823
         FALSE),                /* pcrel_offset */
1824
 
1825
  /* MIPS16 TLS local dynamic offset.  */
1826
  HOWTO (R_MIPS16_TLS_DTPREL_HI16,      /* type */
1827
         0,                      /* rightshift */
1828
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1829
         16,                    /* bitsize */
1830
         FALSE,                 /* pc_relative */
1831
         0,                      /* bitpos */
1832
         complain_overflow_signed, /* complain_on_overflow */
1833
         _bfd_mips_elf_generic_reloc, /* special_function */
1834
         "R_MIPS16_TLS_DTPREL_HI16",    /* name */
1835
         FALSE,                 /* partial_inplace */
1836
         0x0000ffff,            /* src_mask */
1837
         0x0000ffff,            /* dst_mask */
1838
         FALSE),                /* pcrel_offset */
1839
 
1840
  /* MIPS16 TLS local dynamic offset.  */
1841
  HOWTO (R_MIPS16_TLS_DTPREL_LO16,      /* type */
1842
         0,                      /* rightshift */
1843
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1844
         16,                    /* bitsize */
1845
         FALSE,                 /* pc_relative */
1846
         0,                      /* bitpos */
1847
         complain_overflow_signed, /* complain_on_overflow */
1848
         _bfd_mips_elf_generic_reloc, /* special_function */
1849
         "R_MIPS16_TLS_DTPREL_LO16",    /* name */
1850
         FALSE,                 /* partial_inplace */
1851
         0x0000ffff,            /* src_mask */
1852
         0x0000ffff,            /* dst_mask */
1853
         FALSE),                /* pcrel_offset */
1854
 
1855
  /* MIPS16 TLS thread pointer offset.  */
1856
  HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */
1857
         0,                      /* rightshift */
1858
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1859
         16,                    /* bitsize */
1860
         FALSE,                 /* pc_relative */
1861
         0,                      /* bitpos */
1862
         complain_overflow_signed, /* complain_on_overflow */
1863
         _bfd_mips_elf_generic_reloc, /* special_function */
1864
         "R_MIPS16_TLS_GOTTPREL",       /* name */
1865
         FALSE,                 /* partial_inplace */
1866
         0x0000ffff,            /* src_mask */
1867
         0x0000ffff,            /* dst_mask */
1868
         FALSE),                /* pcrel_offset */
1869
 
1870
  /* MIPS16 TLS thread pointer offset.  */
1871
  HOWTO (R_MIPS16_TLS_TPREL_HI16,       /* type */
1872
         0,                      /* rightshift */
1873
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1874
         16,                    /* bitsize */
1875
         FALSE,                 /* pc_relative */
1876
         0,                      /* bitpos */
1877
         complain_overflow_signed, /* complain_on_overflow */
1878
         _bfd_mips_elf_generic_reloc, /* special_function */
1879
         "R_MIPS16_TLS_TPREL_HI16", /* name */
1880
         FALSE,                 /* partial_inplace */
1881
         0x0000ffff,            /* src_mask */
1882
         0x0000ffff,            /* dst_mask */
1883
         FALSE),                /* pcrel_offset */
1884
 
1885
  /* MIPS16 TLS thread pointer offset.  */
1886
  HOWTO (R_MIPS16_TLS_TPREL_LO16,       /* type */
1887
         0,                      /* rightshift */
1888
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1889
         16,                    /* bitsize */
1890
         FALSE,                 /* pc_relative */
1891
         0,                      /* bitpos */
1892
         complain_overflow_signed, /* complain_on_overflow */
1893
         _bfd_mips_elf_generic_reloc, /* special_function */
1894
         "R_MIPS16_TLS_TPREL_LO16", /* name */
1895
         FALSE,                 /* partial_inplace */
1896
         0x0000ffff,            /* src_mask */
1897
         0x0000ffff,            /* dst_mask */
1898
         FALSE),                /* pcrel_offset */
1899 14 khays
};
1900
 
1901 161 khays
static reloc_howto_type micromips_elf64_howto_table_rel[] =
1902
{
1903
  EMPTY_HOWTO (130),
1904
  EMPTY_HOWTO (131),
1905
  EMPTY_HOWTO (132),
1906
 
1907
  /* 26 bit jump address.  */
1908
  HOWTO (R_MICROMIPS_26_S1,     /* type */
1909
         1,                     /* rightshift */
1910
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1911
         26,                    /* bitsize */
1912
         FALSE,                 /* pc_relative */
1913
         0,                      /* bitpos */
1914
         complain_overflow_dont, /* complain_on_overflow */
1915
                                /* This needs complex overflow
1916
                                   detection, because the upper four
1917
                                   bits must match the PC.  */
1918
         _bfd_mips_elf_generic_reloc, /* special_function */
1919
         "R_MICROMIPS_26_S1",   /* name */
1920
         TRUE,                  /* partial_inplace */
1921
         0x3ffffff,             /* src_mask */
1922
         0x3ffffff,             /* dst_mask */
1923
         FALSE),                /* pcrel_offset */
1924
 
1925
  /* High 16 bits of symbol value.  */
1926
  HOWTO (R_MICROMIPS_HI16,      /* type */
1927
         16,                    /* rightshift */
1928
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1929
         16,                    /* bitsize */
1930
         FALSE,                 /* pc_relative */
1931
         0,                      /* bitpos */
1932
         complain_overflow_dont, /* complain_on_overflow */
1933
         _bfd_mips_elf_hi16_reloc, /* special_function */
1934
         "R_MICROMIPS_HI16",    /* name */
1935
         TRUE,                  /* partial_inplace */
1936
         0x0000ffff,            /* src_mask */
1937
         0x0000ffff,            /* dst_mask */
1938
         FALSE),                /* pcrel_offset */
1939
 
1940
  /* Low 16 bits of symbol value.  */
1941
  HOWTO (R_MICROMIPS_LO16,      /* type */
1942
         0,                      /* rightshift */
1943
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1944
         16,                    /* bitsize */
1945
         FALSE,                 /* pc_relative */
1946
         0,                      /* bitpos */
1947
         complain_overflow_dont, /* complain_on_overflow */
1948
         _bfd_mips_elf_lo16_reloc, /* special_function */
1949
         "R_MICROMIPS_LO16",    /* name */
1950
         TRUE,                  /* partial_inplace */
1951
         0x0000ffff,            /* src_mask */
1952
         0x0000ffff,            /* dst_mask */
1953
         FALSE),                /* pcrel_offset */
1954
 
1955
  /* GP relative reference.  */
1956
  HOWTO (R_MICROMIPS_GPREL16,   /* type */
1957
         0,                      /* rightshift */
1958
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1959
         16,                    /* bitsize */
1960
         FALSE,                 /* pc_relative */
1961
         0,                      /* bitpos */
1962
         complain_overflow_signed, /* complain_on_overflow */
1963
         _bfd_mips_elf32_gprel16_reloc, /* special_function */
1964
         "R_MICROMIPS_GPREL16", /* name */
1965
         TRUE,                  /* partial_inplace */
1966
         0x0000ffff,            /* src_mask */
1967
         0x0000ffff,            /* dst_mask */
1968
         FALSE),                /* pcrel_offset */
1969
 
1970
  /* Reference to literal section.  */
1971
  HOWTO (R_MICROMIPS_LITERAL,   /* type */
1972
         0,                      /* rightshift */
1973
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1974
         16,                    /* bitsize */
1975
         FALSE,                 /* pc_relative */
1976
         0,                      /* bitpos */
1977
         complain_overflow_signed, /* complain_on_overflow */
1978
         _bfd_mips_elf32_gprel16_reloc, /* special_function */
1979
         "R_MICROMIPS_LITERAL", /* name */
1980
         TRUE,                  /* partial_inplace */
1981
         0x0000ffff,            /* src_mask */
1982
         0x0000ffff,            /* dst_mask */
1983
         FALSE),                /* pcrel_offset */
1984
 
1985
  /* Reference to global offset table.  */
1986
  HOWTO (R_MICROMIPS_GOT16,     /* type */
1987
         0,                      /* rightshift */
1988
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1989
         16,                    /* bitsize */
1990
         FALSE,                 /* pc_relative */
1991
         0,                      /* bitpos */
1992
         complain_overflow_signed, /* complain_on_overflow */
1993
         _bfd_mips_elf_got16_reloc, /* special_function */
1994
         "R_MICROMIPS_GOT16",   /* name */
1995
         TRUE,                  /* partial_inplace */
1996
         0x0000ffff,            /* src_mask */
1997
         0x0000ffff,            /* dst_mask */
1998
         FALSE),                /* pcrel_offset */
1999
 
2000
  /* This is for microMIPS branches.  */
2001
  HOWTO (R_MICROMIPS_PC7_S1,    /* type */
2002
         1,                     /* rightshift */
2003
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
2004
         7,                     /* bitsize */
2005
         TRUE,                  /* pc_relative */
2006
         0,                      /* bitpos */
2007
         complain_overflow_signed, /* complain_on_overflow */
2008
         _bfd_mips_elf_generic_reloc, /* special_function */
2009
         "R_MICROMIPS_PC7_S1",  /* name */
2010
         TRUE,                  /* partial_inplace */
2011
         0x0000007f,            /* src_mask */
2012
         0x0000007f,            /* dst_mask */
2013
         TRUE),                 /* pcrel_offset */
2014
 
2015
  HOWTO (R_MICROMIPS_PC10_S1,   /* type */
2016
         1,                     /* rightshift */
2017
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
2018
         10,                    /* bitsize */
2019
         TRUE,                  /* pc_relative */
2020
         0,                      /* bitpos */
2021
         complain_overflow_signed, /* complain_on_overflow */
2022
         _bfd_mips_elf_generic_reloc, /* special_function */
2023
         "R_MICROMIPS_PC10_S1", /* name */
2024
         TRUE,                  /* partial_inplace */
2025
         0x000003ff,            /* src_mask */
2026
         0x000003ff,            /* dst_mask */
2027
         TRUE),                 /* pcrel_offset */
2028
 
2029
  HOWTO (R_MICROMIPS_PC16_S1,   /* type */
2030
         1,                     /* rightshift */
2031
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2032
         16,                    /* bitsize */
2033
         TRUE,                  /* pc_relative */
2034
         0,                      /* bitpos */
2035
         complain_overflow_signed, /* complain_on_overflow */
2036
         _bfd_mips_elf_generic_reloc, /* special_function */
2037
         "R_MICROMIPS_PC16_S1", /* name */
2038
         TRUE,                  /* partial_inplace */
2039
         0x0000ffff,            /* src_mask */
2040
         0x0000ffff,            /* dst_mask */
2041
         TRUE),                 /* pcrel_offset */
2042
 
2043
  /* 16 bit call through global offset table.  */
2044
  HOWTO (R_MICROMIPS_CALL16,    /* type */
2045
         0,                      /* rightshift */
2046
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2047
         16,                    /* bitsize */
2048
         FALSE,                 /* pc_relative */
2049
         0,                      /* bitpos */
2050
         complain_overflow_signed, /* complain_on_overflow */
2051
         _bfd_mips_elf_generic_reloc, /* special_function */
2052
         "R_MICROMIPS_CALL16",  /* name */
2053
         TRUE,                  /* partial_inplace */
2054
         0x0000ffff,            /* src_mask */
2055
         0x0000ffff,            /* dst_mask */
2056
         FALSE),                /* pcrel_offset */
2057
 
2058
  EMPTY_HOWTO (143),
2059
  EMPTY_HOWTO (144),
2060
 
2061
  /* Displacement in the global offset table.  */
2062
  HOWTO (R_MICROMIPS_GOT_DISP,  /* type */
2063
         0,                      /* rightshift */
2064
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2065
         16,                    /* bitsize */
2066
         FALSE,                 /* pc_relative */
2067
         0,                      /* bitpos */
2068
         complain_overflow_signed, /* complain_on_overflow */
2069
         _bfd_mips_elf_generic_reloc, /* special_function */
2070
         "R_MICROMIPS_GOT_DISP",/* name */
2071
         TRUE,                  /* partial_inplace */
2072
         0x0000ffff,            /* src_mask */
2073
         0x0000ffff,            /* dst_mask */
2074
         FALSE),                /* pcrel_offset */
2075
 
2076
  /* Displacement to page pointer in the global offset table.  */
2077
  HOWTO (R_MICROMIPS_GOT_PAGE,  /* type */
2078
         0,                      /* rightshift */
2079
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2080
         16,                    /* bitsize */
2081
         FALSE,                 /* pc_relative */
2082
         0,                      /* bitpos */
2083
         complain_overflow_signed, /* complain_on_overflow */
2084
         _bfd_mips_elf_generic_reloc, /* special_function */
2085
         "R_MICROMIPS_GOT_PAGE",/* name */
2086
         TRUE,                  /* partial_inplace */
2087
         0x0000ffff,            /* src_mask */
2088
         0x0000ffff,            /* dst_mask */
2089
         FALSE),                /* pcrel_offset */
2090
 
2091
  /* Offset from page pointer in the global offset table.  */
2092
  HOWTO (R_MICROMIPS_GOT_OFST,  /* type */
2093
         0,                      /* rightshift */
2094
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2095
         16,                    /* bitsize */
2096
         FALSE,                 /* pc_relative */
2097
         0,                      /* bitpos */
2098
         complain_overflow_signed, /* complain_on_overflow */
2099
         _bfd_mips_elf_generic_reloc, /* special_function */
2100
         "R_MICROMIPS_GOT_OFST",/* name */
2101
         TRUE,                  /* partial_inplace */
2102
         0x0000ffff,            /* src_mask */
2103
         0x0000ffff,            /* dst_mask */
2104
         FALSE),                /* pcrel_offset */
2105
 
2106
  /* High 16 bits of displacement in global offset table.  */
2107
  HOWTO (R_MICROMIPS_GOT_HI16,  /* type */
2108
         0,                      /* rightshift */
2109
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2110
         16,                    /* bitsize */
2111
         FALSE,                 /* pc_relative */
2112
         0,                      /* bitpos */
2113
         complain_overflow_dont, /* complain_on_overflow */
2114
         _bfd_mips_elf_generic_reloc, /* special_function */
2115
         "R_MICROMIPS_GOT_HI16",/* name */
2116
         TRUE,                  /* partial_inplace */
2117
         0x0000ffff,            /* src_mask */
2118
         0x0000ffff,            /* dst_mask */
2119
         FALSE),                /* pcrel_offset */
2120
 
2121
  /* Low 16 bits of displacement in global offset table.  */
2122
  HOWTO (R_MICROMIPS_GOT_LO16,  /* type */
2123
         0,                      /* rightshift */
2124
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2125
         16,                    /* bitsize */
2126
         FALSE,                 /* pc_relative */
2127
         0,                      /* bitpos */
2128
         complain_overflow_dont, /* complain_on_overflow */
2129
         _bfd_mips_elf_generic_reloc, /* special_function */
2130
         "R_MICROMIPS_GOT_LO16",/* name */
2131
         TRUE,                  /* partial_inplace */
2132
         0x0000ffff,            /* src_mask */
2133
         0x0000ffff,            /* dst_mask */
2134
         FALSE),                /* pcrel_offset */
2135
 
2136
  /* 64 bit subtraction.  Used in the N32 ABI.  */
2137
  HOWTO (R_MICROMIPS_SUB,       /* type */
2138
         0,                      /* rightshift */
2139
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
2140
         64,                    /* bitsize */
2141
         FALSE,                 /* pc_relative */
2142
         0,                      /* bitpos */
2143
         complain_overflow_dont, /* complain_on_overflow */
2144
         _bfd_mips_elf_generic_reloc, /* special_function */
2145
         "R_MICROMIPS_SUB",     /* name */
2146
         TRUE,                  /* partial_inplace */
2147
         MINUS_ONE,             /* src_mask */
2148
         MINUS_ONE,             /* dst_mask */
2149
         FALSE),                /* pcrel_offset */
2150
 
2151
  /* We don't support these for REL relocations, because it means building
2152
     the addend from a R_MICROMIPS_HIGHEST/R_MICROMIPS_HIGHER/
2153
     R_MICROMIPS_HI16/R_MICROMIPS_LO16 sequence with varying ordering,
2154
     using fallable heuristics.  */
2155
  EMPTY_HOWTO (R_MICROMIPS_HIGHER),
2156
  EMPTY_HOWTO (R_MICROMIPS_HIGHEST),
2157
 
2158
  /* High 16 bits of displacement in global offset table.  */
2159
  HOWTO (R_MICROMIPS_CALL_HI16, /* type */
2160
         0,                      /* rightshift */
2161
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2162
         16,                    /* bitsize */
2163
         FALSE,                 /* pc_relative */
2164
         0,                      /* bitpos */
2165
         complain_overflow_dont, /* complain_on_overflow */
2166
         _bfd_mips_elf_generic_reloc, /* special_function */
2167
         "R_MICROMIPS_CALL_HI16",/* name */
2168
         TRUE,                  /* partial_inplace */
2169
         0x0000ffff,            /* src_mask */
2170
         0x0000ffff,            /* dst_mask */
2171
         FALSE),                /* pcrel_offset */
2172
 
2173
  /* Low 16 bits of displacement in global offset table.  */
2174
  HOWTO (R_MICROMIPS_CALL_LO16, /* type */
2175
         0,                      /* rightshift */
2176
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2177
         16,                    /* bitsize */
2178
         FALSE,                 /* pc_relative */
2179
         0,                      /* bitpos */
2180
         complain_overflow_dont, /* complain_on_overflow */
2181
         _bfd_mips_elf_generic_reloc, /* special_function */
2182
         "R_MICROMIPS_CALL_LO16",/* name */
2183
         TRUE,                  /* partial_inplace */
2184
         0x0000ffff,            /* src_mask */
2185
         0x0000ffff,            /* dst_mask */
2186
         FALSE),                /* pcrel_offset */
2187
};
2188
 
2189
static reloc_howto_type micromips_elf64_howto_table_rela[] =
2190
{
2191
  EMPTY_HOWTO (130),
2192
  EMPTY_HOWTO (131),
2193
  EMPTY_HOWTO (132),
2194
 
2195
  /* 26 bit jump address.  */
2196
  HOWTO (R_MICROMIPS_26_S1,     /* type */
2197
         1,                     /* rightshift */
2198
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2199
         26,                    /* bitsize */
2200
         FALSE,                 /* pc_relative */
2201
         0,                      /* bitpos */
2202
         complain_overflow_dont, /* complain_on_overflow */
2203
                                /* This needs complex overflow
2204
                                   detection, because the upper four
2205
                                   bits must match the PC.  */
2206
         _bfd_mips_elf_generic_reloc, /* special_function */
2207
         "R_MICROMIPS_26_S1",   /* name */
2208
         FALSE,                 /* partial_inplace */
2209 166 khays
         0,                      /* src_mask */
2210 161 khays
         0x3ffffff,             /* dst_mask */
2211
         FALSE),                /* pcrel_offset */
2212
 
2213
  /* High 16 bits of symbol value.  */
2214
  HOWTO (R_MICROMIPS_HI16,      /* type */
2215
         16,                    /* rightshift */
2216
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2217
         16,                    /* bitsize */
2218
         FALSE,                 /* pc_relative */
2219
         0,                      /* bitpos */
2220
         complain_overflow_dont, /* complain_on_overflow */
2221
         _bfd_mips_elf_hi16_reloc, /* special_function */
2222
         "R_MICROMIPS_HI16",    /* name */
2223
         FALSE,                 /* partial_inplace */
2224 166 khays
         0,                      /* src_mask */
2225 161 khays
         0x0000ffff,            /* dst_mask */
2226
         FALSE),                /* pcrel_offset */
2227
 
2228
  /* Low 16 bits of symbol value.  */
2229
  HOWTO (R_MICROMIPS_LO16,      /* type */
2230
         0,                      /* rightshift */
2231
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2232
         16,                    /* bitsize */
2233
         FALSE,                 /* pc_relative */
2234
         0,                      /* bitpos */
2235
         complain_overflow_dont, /* complain_on_overflow */
2236
         _bfd_mips_elf_lo16_reloc, /* special_function */
2237
         "R_MICROMIPS_LO16",    /* name */
2238
         FALSE,                 /* partial_inplace */
2239 166 khays
         0,                      /* src_mask */
2240 161 khays
         0x0000ffff,            /* dst_mask */
2241
         FALSE),                /* pcrel_offset */
2242
 
2243
  /* GP relative reference.  */
2244
  HOWTO (R_MICROMIPS_GPREL16,   /* type */
2245
         0,                      /* rightshift */
2246
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2247
         16,                    /* bitsize */
2248
         FALSE,                 /* pc_relative */
2249
         0,                      /* bitpos */
2250
         complain_overflow_signed, /* complain_on_overflow */
2251
         _bfd_mips_elf32_gprel16_reloc, /* special_function */
2252
         "R_MICROMIPS_GPREL16", /* name */
2253
         FALSE,                 /* partial_inplace */
2254 166 khays
         0,                      /* src_mask */
2255 161 khays
         0x0000ffff,            /* dst_mask */
2256
         FALSE),                /* pcrel_offset */
2257
 
2258
  /* Reference to literal section.  */
2259
  HOWTO (R_MICROMIPS_LITERAL,   /* type */
2260
         0,                      /* rightshift */
2261
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2262
         16,                    /* bitsize */
2263
         FALSE,                 /* pc_relative */
2264
         0,                      /* bitpos */
2265
         complain_overflow_signed, /* complain_on_overflow */
2266
         _bfd_mips_elf32_gprel16_reloc, /* special_function */
2267
         "R_MICROMIPS_LITERAL", /* name */
2268
         FALSE,                 /* partial_inplace */
2269 166 khays
         0,                      /* src_mask */
2270 161 khays
         0x0000ffff,            /* dst_mask */
2271
         FALSE),                /* pcrel_offset */
2272
 
2273
  /* Reference to global offset table.  */
2274
  HOWTO (R_MICROMIPS_GOT16,     /* type */
2275
         0,                      /* rightshift */
2276
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2277
         16,                    /* bitsize */
2278
         FALSE,                 /* pc_relative */
2279
         0,                      /* bitpos */
2280
         complain_overflow_signed, /* complain_on_overflow */
2281
         _bfd_mips_elf_got16_reloc, /* special_function */
2282
         "R_MICROMIPS_GOT16",   /* name */
2283
         FALSE,                 /* partial_inplace */
2284 166 khays
         0,                      /* src_mask */
2285 161 khays
         0x0000ffff,            /* dst_mask */
2286
         FALSE),                /* pcrel_offset */
2287
 
2288
  /* This is for microMIPS branches.  */
2289
  HOWTO (R_MICROMIPS_PC7_S1,    /* type */
2290
         1,                     /* rightshift */
2291
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
2292
         7,                     /* bitsize */
2293
         TRUE,                  /* pc_relative */
2294
         0,                      /* bitpos */
2295
         complain_overflow_signed, /* complain_on_overflow */
2296
         _bfd_mips_elf_generic_reloc, /* special_function */
2297
         "R_MICROMIPS_PC7_S1",  /* name */
2298
         FALSE,                 /* partial_inplace */
2299 166 khays
         0,                      /* src_mask */
2300 161 khays
         0x0000007f,            /* dst_mask */
2301
         TRUE),                 /* pcrel_offset */
2302
 
2303
  HOWTO (R_MICROMIPS_PC10_S1,   /* type */
2304
         1,                     /* rightshift */
2305
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
2306
         10,                    /* bitsize */
2307
         TRUE,                  /* pc_relative */
2308
         0,                      /* bitpos */
2309
         complain_overflow_signed, /* complain_on_overflow */
2310
         _bfd_mips_elf_generic_reloc, /* special_function */
2311
         "R_MICROMIPS_PC10_S1", /* name */
2312
         FALSE,                 /* partial_inplace */
2313 166 khays
         0,                      /* src_mask */
2314 161 khays
         0x000003ff,            /* dst_mask */
2315
         TRUE),                 /* pcrel_offset */
2316
 
2317
  HOWTO (R_MICROMIPS_PC16_S1,   /* type */
2318
         1,                     /* rightshift */
2319
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2320
         16,                    /* bitsize */
2321
         TRUE,                  /* pc_relative */
2322
         0,                      /* bitpos */
2323
         complain_overflow_signed, /* complain_on_overflow */
2324
         _bfd_mips_elf_generic_reloc, /* special_function */
2325
         "R_MICROMIPS_PC16_S1", /* name */
2326
         FALSE,                 /* partial_inplace */
2327 166 khays
         0,                      /* src_mask */
2328 161 khays
         0x0000ffff,            /* dst_mask */
2329
         TRUE),                 /* pcrel_offset */
2330
 
2331
  /* 16 bit call through global offset table.  */
2332
  HOWTO (R_MICROMIPS_CALL16,    /* type */
2333
         0,                      /* rightshift */
2334
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2335
         16,                    /* bitsize */
2336
         FALSE,                 /* pc_relative */
2337
         0,                      /* bitpos */
2338
         complain_overflow_signed, /* complain_on_overflow */
2339
         _bfd_mips_elf_generic_reloc, /* special_function */
2340
         "R_MICROMIPS_CALL16",  /* name */
2341
         FALSE,                 /* partial_inplace */
2342 166 khays
         0,                      /* src_mask */
2343 161 khays
         0x0000ffff,            /* dst_mask */
2344
         FALSE),                /* pcrel_offset */
2345
 
2346
  EMPTY_HOWTO (143),
2347
  EMPTY_HOWTO (144),
2348
 
2349
  /* Displacement in the global offset table.  */
2350
  HOWTO (R_MICROMIPS_GOT_DISP,  /* type */
2351
         0,                      /* rightshift */
2352
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2353
         16,                    /* bitsize */
2354
         FALSE,                 /* pc_relative */
2355
         0,                      /* bitpos */
2356
         complain_overflow_signed, /* complain_on_overflow */
2357
         _bfd_mips_elf_generic_reloc, /* special_function */
2358
         "R_MICROMIPS_GOT_DISP",/* name */
2359
         FALSE,                 /* partial_inplace */
2360 166 khays
         0,                      /* src_mask */
2361 161 khays
         0x0000ffff,            /* dst_mask */
2362
         FALSE),                /* pcrel_offset */
2363
 
2364
  /* Displacement to page pointer in the global offset table.  */
2365
  HOWTO (R_MICROMIPS_GOT_PAGE,  /* type */
2366
         0,                      /* rightshift */
2367
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2368
         16,                    /* bitsize */
2369
         FALSE,                 /* pc_relative */
2370
         0,                      /* bitpos */
2371
         complain_overflow_signed, /* complain_on_overflow */
2372
         _bfd_mips_elf_generic_reloc, /* special_function */
2373
         "R_MICROMIPS_GOT_PAGE",/* name */
2374
         FALSE,                 /* partial_inplace */
2375 166 khays
         0,                      /* src_mask */
2376 161 khays
         0x0000ffff,            /* dst_mask */
2377
         FALSE),                /* pcrel_offset */
2378
 
2379
  /* Offset from page pointer in the global offset table.  */
2380
  HOWTO (R_MICROMIPS_GOT_OFST,  /* type */
2381
         0,                      /* rightshift */
2382
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2383
         16,                    /* bitsize */
2384
         FALSE,                 /* pc_relative */
2385
         0,                      /* bitpos */
2386
         complain_overflow_signed, /* complain_on_overflow */
2387
         _bfd_mips_elf_generic_reloc, /* special_function */
2388
         "R_MICROMIPS_GOT_OFST",/* name */
2389
         FALSE,                 /* partial_inplace */
2390 166 khays
         0,                      /* src_mask */
2391 161 khays
         0x0000ffff,            /* dst_mask */
2392
         FALSE),                /* pcrel_offset */
2393
 
2394
  /* High 16 bits of displacement in global offset table.  */
2395
  HOWTO (R_MICROMIPS_GOT_HI16,  /* type */
2396
         0,                      /* rightshift */
2397
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2398
         16,                    /* bitsize */
2399
         FALSE,                 /* pc_relative */
2400
         0,                      /* bitpos */
2401
         complain_overflow_dont, /* complain_on_overflow */
2402
         _bfd_mips_elf_generic_reloc, /* special_function */
2403
         "R_MICROMIPS_GOT_HI16",/* name */
2404
         FALSE,                 /* partial_inplace */
2405 166 khays
         0,                      /* src_mask */
2406 161 khays
         0x0000ffff,            /* dst_mask */
2407
         FALSE),                /* pcrel_offset */
2408
 
2409
  /* Low 16 bits of displacement in global offset table.  */
2410
  HOWTO (R_MICROMIPS_GOT_LO16,  /* type */
2411
         0,                      /* rightshift */
2412
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2413
         16,                    /* bitsize */
2414
         FALSE,                 /* pc_relative */
2415
         0,                      /* bitpos */
2416
         complain_overflow_dont, /* complain_on_overflow */
2417
         _bfd_mips_elf_generic_reloc, /* special_function */
2418
         "R_MICROMIPS_GOT_LO16",/* name */
2419
         FALSE,                 /* partial_inplace */
2420 166 khays
         0,                      /* src_mask */
2421 161 khays
         0x0000ffff,            /* dst_mask */
2422
         FALSE),                /* pcrel_offset */
2423
 
2424
  /* 64 bit subtraction.  Used in the N32 ABI.  */
2425
  HOWTO (R_MICROMIPS_SUB,       /* type */
2426
         0,                      /* rightshift */
2427
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
2428
         64,                    /* bitsize */
2429
         FALSE,                 /* pc_relative */
2430
         0,                      /* bitpos */
2431
         complain_overflow_dont, /* complain_on_overflow */
2432
         _bfd_mips_elf_generic_reloc, /* special_function */
2433
         "R_MICROMIPS_SUB",     /* name */
2434
         FALSE,                 /* partial_inplace */
2435 166 khays
         0,                      /* src_mask */
2436 161 khays
         MINUS_ONE,             /* dst_mask */
2437
         FALSE),                /* pcrel_offset */
2438
 
2439
  /* Get the higher value of a 64 bit addend.  */
2440
  HOWTO (R_MICROMIPS_HIGHER,    /* type */
2441
         0,                      /* rightshift */
2442
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2443
         16,                    /* bitsize */
2444
         FALSE,                 /* pc_relative */
2445
         0,                      /* bitpos */
2446
         complain_overflow_dont, /* complain_on_overflow */
2447
         _bfd_mips_elf_generic_reloc, /* special_function */
2448
         "R_MICROMIPS_HIGHER",  /* name */
2449
         FALSE,                 /* partial_inplace */
2450 166 khays
         0,                      /* src_mask */
2451 161 khays
         0x0000ffff,            /* dst_mask */
2452
         FALSE),                /* pcrel_offset */
2453
 
2454
  /* Get the highest value of a 64 bit addend.  */
2455
  HOWTO (R_MICROMIPS_HIGHEST,   /* type */
2456
         0,                      /* rightshift */
2457
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2458
         16,                    /* bitsize */
2459
         FALSE,                 /* pc_relative */
2460
         0,                      /* bitpos */
2461
         complain_overflow_dont, /* complain_on_overflow */
2462
         _bfd_mips_elf_generic_reloc, /* special_function */
2463
         "R_MICROMIPS_HIGHEST", /* name */
2464
         FALSE,                 /* partial_inplace */
2465 166 khays
         0,                      /* src_mask */
2466 161 khays
         0x0000ffff,            /* dst_mask */
2467
         FALSE),                /* pcrel_offset */
2468
 
2469
  /* High 16 bits of displacement in global offset table.  */
2470
  HOWTO (R_MICROMIPS_CALL_HI16, /* type */
2471
         0,                      /* rightshift */
2472
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2473
         16,                    /* bitsize */
2474
         FALSE,                 /* pc_relative */
2475
         0,                      /* bitpos */
2476
         complain_overflow_dont, /* complain_on_overflow */
2477
         _bfd_mips_elf_generic_reloc, /* special_function */
2478
         "R_MICROMIPS_CALL_HI16",/* name */
2479
         FALSE,                 /* partial_inplace */
2480 166 khays
         0,                      /* src_mask */
2481 161 khays
         0x0000ffff,            /* dst_mask */
2482
         FALSE),                /* pcrel_offset */
2483
 
2484
  /* Low 16 bits of displacement in global offset table.  */
2485
  HOWTO (R_MICROMIPS_CALL_LO16, /* type */
2486
         0,                      /* rightshift */
2487
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2488
         16,                    /* bitsize */
2489
         FALSE,                 /* pc_relative */
2490
         0,                      /* bitpos */
2491
         complain_overflow_dont, /* complain_on_overflow */
2492
         _bfd_mips_elf_generic_reloc, /* special_function */
2493
         "R_MICROMIPS_CALL_LO16",/* name */
2494
         FALSE,                 /* partial_inplace */
2495 166 khays
         0,                      /* src_mask */
2496 161 khays
         0x0000ffff,            /* dst_mask */
2497
         FALSE),                /* pcrel_offset */
2498
};
2499
 
2500 14 khays
/* GNU extension to record C++ vtable hierarchy */
2501
static reloc_howto_type elf_mips_gnu_vtinherit_howto =
2502
  HOWTO (R_MIPS_GNU_VTINHERIT,  /* type */
2503
         0,                      /* rightshift */
2504
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2505
         0,                      /* bitsize */
2506
         FALSE,                 /* pc_relative */
2507
         0,                      /* bitpos */
2508
         complain_overflow_dont, /* complain_on_overflow */
2509
         NULL,                  /* special_function */
2510
         "R_MIPS_GNU_VTINHERIT", /* name */
2511
         FALSE,                 /* partial_inplace */
2512
         0,                      /* src_mask */
2513
         0,                      /* dst_mask */
2514
         FALSE);                /* pcrel_offset */
2515
 
2516
/* GNU extension to record C++ vtable member usage */
2517
static reloc_howto_type elf_mips_gnu_vtentry_howto =
2518
  HOWTO (R_MIPS_GNU_VTENTRY,    /* type */
2519
         0,                      /* rightshift */
2520
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2521
         0,                      /* bitsize */
2522
         FALSE,                 /* pc_relative */
2523
         0,                      /* bitpos */
2524
         complain_overflow_dont, /* complain_on_overflow */
2525
         _bfd_elf_rel_vtable_reloc_fn, /* special_function */
2526
         "R_MIPS_GNU_VTENTRY",  /* name */
2527
         FALSE,                 /* partial_inplace */
2528
         0,                      /* src_mask */
2529
         0,                      /* dst_mask */
2530
         FALSE);                /* pcrel_offset */
2531
 
2532
/* 16 bit offset for pc-relative branches.  */
2533
static reloc_howto_type elf_mips_gnu_rel16_s2 =
2534
  HOWTO (R_MIPS_GNU_REL16_S2,   /* type */
2535
         2,                     /* rightshift */
2536
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2537
         16,                    /* bitsize */
2538
         TRUE,                  /* pc_relative */
2539
         0,                      /* bitpos */
2540
         complain_overflow_signed, /* complain_on_overflow */
2541
         _bfd_mips_elf_generic_reloc,   /* special_function */
2542
         "R_MIPS_GNU_REL16_S2", /* name */
2543
         TRUE,                  /* partial_inplace */
2544
         0x0000ffff,            /* src_mask */
2545
         0x0000ffff,            /* dst_mask */
2546
         TRUE);                 /* pcrel_offset */
2547
 
2548
/* 16 bit offset for pc-relative branches.  */
2549
static reloc_howto_type elf_mips_gnu_rela16_s2 =
2550
  HOWTO (R_MIPS_GNU_REL16_S2,   /* type */
2551
         2,                     /* rightshift */
2552
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
2553
         16,                    /* bitsize */
2554
         TRUE,                  /* pc_relative */
2555
         0,                      /* bitpos */
2556
         complain_overflow_signed, /* complain_on_overflow */
2557
         _bfd_mips_elf_generic_reloc,   /* special_function */
2558
         "R_MIPS_GNU_REL16_S2", /* name */
2559
         FALSE,                 /* partial_inplace */
2560
         0,                      /* src_mask */
2561
         0x0000ffff,            /* dst_mask */
2562
         TRUE);                 /* pcrel_offset */
2563
 
2564
/* Originally a VxWorks extension, but now used for other systems too.  */
2565
static reloc_howto_type elf_mips_copy_howto =
2566
  HOWTO (R_MIPS_COPY,           /* type */
2567
         0,                      /* rightshift */
2568
         0,                      /* this one is variable size */
2569
         0,                      /* bitsize */
2570
         FALSE,                 /* pc_relative */
2571
         0,                      /* bitpos */
2572
         complain_overflow_bitfield, /* complain_on_overflow */
2573
         bfd_elf_generic_reloc, /* special_function */
2574
         "R_MIPS_COPY",         /* name */
2575
         FALSE,                 /* partial_inplace */
2576
         0x0,                   /* src_mask */
2577
         0x0,                   /* dst_mask */
2578
         FALSE);                /* pcrel_offset */
2579
 
2580
/* Originally a VxWorks extension, but now used for other systems too.  */
2581
static reloc_howto_type elf_mips_jump_slot_howto =
2582
  HOWTO (R_MIPS_JUMP_SLOT,      /* type */
2583
         0,                      /* rightshift */
2584
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
2585
         64,                    /* bitsize */
2586
         FALSE,                 /* pc_relative */
2587
         0,                      /* bitpos */
2588
         complain_overflow_bitfield, /* complain_on_overflow */
2589
         bfd_elf_generic_reloc, /* special_function */
2590
         "R_MIPS_JUMP_SLOT",    /* name */
2591
         FALSE,                 /* partial_inplace */
2592
         0x0,                   /* src_mask */
2593
         0x0,                   /* dst_mask */
2594
         FALSE);                /* pcrel_offset */
2595
 
2596
/* Swap in a MIPS 64-bit Rel reloc.  */
2597
 
2598
static void
2599
mips_elf64_swap_reloc_in (bfd *abfd, const Elf64_Mips_External_Rel *src,
2600
                          Elf64_Mips_Internal_Rela *dst)
2601
{
2602
  dst->r_offset = H_GET_64 (abfd, src->r_offset);
2603
  dst->r_sym = H_GET_32 (abfd, src->r_sym);
2604
  dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
2605
  dst->r_type3 = H_GET_8 (abfd, src->r_type3);
2606
  dst->r_type2 = H_GET_8 (abfd, src->r_type2);
2607
  dst->r_type = H_GET_8 (abfd, src->r_type);
2608
  dst->r_addend = 0;
2609
}
2610
 
2611
/* Swap in a MIPS 64-bit Rela reloc.  */
2612
 
2613
static void
2614
mips_elf64_swap_reloca_in (bfd *abfd, const Elf64_Mips_External_Rela *src,
2615
                           Elf64_Mips_Internal_Rela *dst)
2616
{
2617
  dst->r_offset = H_GET_64 (abfd, src->r_offset);
2618
  dst->r_sym = H_GET_32 (abfd, src->r_sym);
2619
  dst->r_ssym = H_GET_8 (abfd, src->r_ssym);
2620
  dst->r_type3 = H_GET_8 (abfd, src->r_type3);
2621
  dst->r_type2 = H_GET_8 (abfd, src->r_type2);
2622
  dst->r_type = H_GET_8 (abfd, src->r_type);
2623
  dst->r_addend = H_GET_S64 (abfd, src->r_addend);
2624
}
2625
 
2626
/* Swap out a MIPS 64-bit Rel reloc.  */
2627
 
2628
static void
2629
mips_elf64_swap_reloc_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
2630
                           Elf64_Mips_External_Rel *dst)
2631
{
2632
  H_PUT_64 (abfd, src->r_offset, dst->r_offset);
2633
  H_PUT_32 (abfd, src->r_sym, dst->r_sym);
2634
  H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
2635
  H_PUT_8 (abfd, src->r_type3, dst->r_type3);
2636
  H_PUT_8 (abfd, src->r_type2, dst->r_type2);
2637
  H_PUT_8 (abfd, src->r_type, dst->r_type);
2638
}
2639
 
2640
/* Swap out a MIPS 64-bit Rela reloc.  */
2641
 
2642
static void
2643
mips_elf64_swap_reloca_out (bfd *abfd, const Elf64_Mips_Internal_Rela *src,
2644
                            Elf64_Mips_External_Rela *dst)
2645
{
2646
  H_PUT_64 (abfd, src->r_offset, dst->r_offset);
2647
  H_PUT_32 (abfd, src->r_sym, dst->r_sym);
2648
  H_PUT_8 (abfd, src->r_ssym, dst->r_ssym);
2649
  H_PUT_8 (abfd, src->r_type3, dst->r_type3);
2650
  H_PUT_8 (abfd, src->r_type2, dst->r_type2);
2651
  H_PUT_8 (abfd, src->r_type, dst->r_type);
2652
  H_PUT_S64 (abfd, src->r_addend, dst->r_addend);
2653
}
2654
 
2655
/* Swap in a MIPS 64-bit Rel reloc.  */
2656
 
2657
static void
2658
mips_elf64_be_swap_reloc_in (bfd *abfd, const bfd_byte *src,
2659
                             Elf_Internal_Rela *dst)
2660
{
2661
  Elf64_Mips_Internal_Rela mirel;
2662
 
2663
  mips_elf64_swap_reloc_in (abfd,
2664
                            (const Elf64_Mips_External_Rel *) src,
2665
                            &mirel);
2666
 
2667
  dst[0].r_offset = mirel.r_offset;
2668
  dst[0].r_info = ELF64_R_INFO (mirel.r_sym, mirel.r_type);
2669
  dst[0].r_addend = 0;
2670
  dst[1].r_offset = mirel.r_offset;
2671
  dst[1].r_info = ELF64_R_INFO (mirel.r_ssym, mirel.r_type2);
2672
  dst[1].r_addend = 0;
2673
  dst[2].r_offset = mirel.r_offset;
2674
  dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirel.r_type3);
2675
  dst[2].r_addend = 0;
2676
}
2677
 
2678
/* Swap in a MIPS 64-bit Rela reloc.  */
2679
 
2680
static void
2681
mips_elf64_be_swap_reloca_in (bfd *abfd, const bfd_byte *src,
2682
                              Elf_Internal_Rela *dst)
2683
{
2684
  Elf64_Mips_Internal_Rela mirela;
2685
 
2686
  mips_elf64_swap_reloca_in (abfd,
2687
                             (const Elf64_Mips_External_Rela *) src,
2688
                             &mirela);
2689
 
2690
  dst[0].r_offset = mirela.r_offset;
2691
  dst[0].r_info = ELF64_R_INFO (mirela.r_sym, mirela.r_type);
2692
  dst[0].r_addend = mirela.r_addend;
2693
  dst[1].r_offset = mirela.r_offset;
2694
  dst[1].r_info = ELF64_R_INFO (mirela.r_ssym, mirela.r_type2);
2695
  dst[1].r_addend = 0;
2696
  dst[2].r_offset = mirela.r_offset;
2697
  dst[2].r_info = ELF64_R_INFO (STN_UNDEF, mirela.r_type3);
2698
  dst[2].r_addend = 0;
2699
}
2700
 
2701
/* Swap out a MIPS 64-bit Rel reloc.  */
2702
 
2703
static void
2704
mips_elf64_be_swap_reloc_out (bfd *abfd, const Elf_Internal_Rela *src,
2705
                              bfd_byte *dst)
2706
{
2707
  Elf64_Mips_Internal_Rela mirel;
2708
 
2709
  mirel.r_offset = src[0].r_offset;
2710
  BFD_ASSERT(src[0].r_offset == src[1].r_offset);
2711
 
2712
  mirel.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
2713
  mirel.r_sym = ELF64_R_SYM (src[0].r_info);
2714
  mirel.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
2715
  mirel.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
2716
  mirel.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
2717
 
2718
  mips_elf64_swap_reloc_out (abfd, &mirel,
2719
                             (Elf64_Mips_External_Rel *) dst);
2720
}
2721
 
2722
/* Swap out a MIPS 64-bit Rela reloc.  */
2723
 
2724
static void
2725
mips_elf64_be_swap_reloca_out (bfd *abfd, const Elf_Internal_Rela *src,
2726
                               bfd_byte *dst)
2727
{
2728
  Elf64_Mips_Internal_Rela mirela;
2729
 
2730
  mirela.r_offset = src[0].r_offset;
2731
  BFD_ASSERT(src[0].r_offset == src[1].r_offset);
2732
  BFD_ASSERT(src[0].r_offset == src[2].r_offset);
2733
 
2734
  mirela.r_type = ELF64_MIPS_R_TYPE (src[0].r_info);
2735
  mirela.r_sym = ELF64_R_SYM (src[0].r_info);
2736
  mirela.r_addend = src[0].r_addend;
2737
  BFD_ASSERT(src[1].r_addend == 0);
2738
  BFD_ASSERT(src[2].r_addend == 0);
2739
 
2740
  mirela.r_type2 = ELF64_MIPS_R_TYPE (src[1].r_info);
2741
  mirela.r_ssym = ELF64_MIPS_R_SSYM (src[1].r_info);
2742
  mirela.r_type3 = ELF64_MIPS_R_TYPE (src[2].r_info);
2743
 
2744
  mips_elf64_swap_reloca_out (abfd, &mirela,
2745
                              (Elf64_Mips_External_Rela *) dst);
2746
}
2747
 
2748
/* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
2749
   dangerous relocation.  */
2750
 
2751
static bfd_boolean
2752
mips_elf64_assign_gp (bfd *output_bfd, bfd_vma *pgp)
2753
{
2754
  unsigned int count;
2755
  asymbol **sym;
2756
  unsigned int i;
2757
 
2758
  /* If we've already figured out what GP will be, just return it.  */
2759
  *pgp = _bfd_get_gp_value (output_bfd);
2760
  if (*pgp)
2761
    return TRUE;
2762
 
2763
  count = bfd_get_symcount (output_bfd);
2764
  sym = bfd_get_outsymbols (output_bfd);
2765
 
2766
  /* The linker script will have created a symbol named `_gp' with the
2767
     appropriate value.  */
2768
  if (sym == NULL)
2769
    i = count;
2770
  else
2771
    {
2772
      for (i = 0; i < count; i++, sym++)
2773
        {
2774
          register const char *name;
2775
 
2776
          name = bfd_asymbol_name (*sym);
2777
          if (*name == '_' && strcmp (name, "_gp") == 0)
2778
            {
2779
              *pgp = bfd_asymbol_value (*sym);
2780
              _bfd_set_gp_value (output_bfd, *pgp);
2781
              break;
2782
            }
2783
        }
2784
    }
2785
 
2786
  if (i >= count)
2787
    {
2788
      /* Only get the error once.  */
2789
      *pgp = 4;
2790
      _bfd_set_gp_value (output_bfd, *pgp);
2791
      return FALSE;
2792
    }
2793
 
2794
  return TRUE;
2795
}
2796
 
2797
/* We have to figure out the gp value, so that we can adjust the
2798
   symbol value correctly.  We look up the symbol _gp in the output
2799
   BFD.  If we can't find it, we're stuck.  We cache it in the ELF
2800
   target data.  We don't need to adjust the symbol value for an
2801
   external symbol if we are producing relocatable output.  */
2802
 
2803
static bfd_reloc_status_type
2804
mips_elf64_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
2805
                     char **error_message, bfd_vma *pgp)
2806
{
2807
  if (bfd_is_und_section (symbol->section)
2808
      && ! relocatable)
2809
    {
2810
      *pgp = 0;
2811
      return bfd_reloc_undefined;
2812
    }
2813
 
2814
  *pgp = _bfd_get_gp_value (output_bfd);
2815
  if (*pgp == 0
2816
      && (! relocatable
2817
          || (symbol->flags & BSF_SECTION_SYM) != 0))
2818
    {
2819
      if (relocatable)
2820
        {
2821
          /* Make up a value.  */
2822
          *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
2823
          _bfd_set_gp_value (output_bfd, *pgp);
2824
        }
2825
      else if (!mips_elf64_assign_gp (output_bfd, pgp))
2826
        {
2827
          *error_message =
2828
            (char *) _("GP relative relocation when _gp not defined");
2829
          return bfd_reloc_dangerous;
2830
        }
2831
    }
2832
 
2833
  return bfd_reloc_ok;
2834
}
2835
 
2836
/* Do a R_MIPS_GPREL16 relocation.  This is a 16 bit value which must
2837
   become the offset from the gp register.  */
2838
 
2839
static bfd_reloc_status_type
2840
mips_elf64_gprel16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2841
                          void *data, asection *input_section, bfd *output_bfd,
2842
                          char **error_message)
2843
{
2844
  bfd_boolean relocatable;
2845
  bfd_reloc_status_type ret;
2846
  bfd_vma gp;
2847
 
2848
  /* If we're relocating, and this is an external symbol, we don't want
2849
     to change anything.  */
2850
  if (output_bfd != NULL
2851
      && (symbol->flags & BSF_SECTION_SYM) == 0
2852
      && (symbol->flags & BSF_LOCAL) != 0)
2853
    {
2854
      reloc_entry->address += input_section->output_offset;
2855
      return bfd_reloc_ok;
2856
    }
2857
 
2858
  if (output_bfd != NULL)
2859
    relocatable = TRUE;
2860
  else
2861
    {
2862
      relocatable = FALSE;
2863
      output_bfd = symbol->section->output_section->owner;
2864
    }
2865
 
2866
  ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
2867
                             &gp);
2868
  if (ret != bfd_reloc_ok)
2869
    return ret;
2870
 
2871
  return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2872
                                        input_section, relocatable,
2873
                                        data, gp);
2874
}
2875
 
2876
/* Do a R_MIPS_LITERAL relocation.  */
2877
 
2878
static bfd_reloc_status_type
2879
mips_elf64_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2880
                          void *data, asection *input_section, bfd *output_bfd,
2881
                          char **error_message)
2882
{
2883
  bfd_boolean relocatable;
2884
  bfd_reloc_status_type ret;
2885
  bfd_vma gp;
2886
 
2887
  /* R_MIPS_LITERAL relocations are defined for local symbols only.  */
2888
  if (output_bfd != NULL
2889
      && (symbol->flags & BSF_SECTION_SYM) == 0
2890
      && (symbol->flags & BSF_LOCAL) != 0)
2891
    {
2892
      *error_message = (char *)
2893
        _("literal relocation occurs for an external symbol");
2894
      return bfd_reloc_outofrange;
2895
    }
2896
 
2897
  /* FIXME: The entries in the .lit8 and .lit4 sections should be merged.  */
2898
  if (output_bfd != NULL)
2899
    relocatable = TRUE;
2900
  else
2901
    {
2902
      relocatable = FALSE;
2903
      output_bfd = symbol->section->output_section->owner;
2904
    }
2905
 
2906
  ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
2907
                             &gp);
2908
  if (ret != bfd_reloc_ok)
2909
    return ret;
2910
 
2911
  return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
2912
                                        input_section, relocatable,
2913
                                        data, gp);
2914
}
2915
 
2916
/* Do a R_MIPS_GPREL32 relocation.  This is a 32 bit value which must
2917
   become the offset from the gp register.  */
2918
 
2919
static bfd_reloc_status_type
2920
mips_elf64_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2921
                          void *data, asection *input_section, bfd *output_bfd,
2922
                          char **error_message)
2923
{
2924
  bfd_boolean relocatable;
2925
  bfd_reloc_status_type ret;
2926
  bfd_vma gp;
2927
  bfd_vma relocation;
2928
  bfd_vma val;
2929
 
2930
  /* R_MIPS_GPREL32 relocations are defined for local symbols only.  */
2931
  if (output_bfd != NULL
2932
      && (symbol->flags & BSF_SECTION_SYM) == 0
2933
      && (symbol->flags & BSF_LOCAL) != 0)
2934
    {
2935
      *error_message = (char *)
2936
        _("32bits gp relative relocation occurs for an external symbol");
2937
      return bfd_reloc_outofrange;
2938
    }
2939
 
2940
  if (output_bfd != NULL)
2941
    relocatable = TRUE;
2942
  else
2943
    {
2944
      relocatable = FALSE;
2945
      output_bfd = symbol->section->output_section->owner;
2946
    }
2947
 
2948
  ret = mips_elf64_final_gp (output_bfd, symbol, relocatable,
2949
                             error_message, &gp);
2950
  if (ret != bfd_reloc_ok)
2951
    return ret;
2952
 
2953
  if (bfd_is_com_section (symbol->section))
2954
    relocation = 0;
2955
  else
2956
    relocation = symbol->value;
2957
 
2958
  relocation += symbol->section->output_section->vma;
2959
  relocation += symbol->section->output_offset;
2960
 
2961
  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
2962
    return bfd_reloc_outofrange;
2963
 
2964
  /* Set val to the offset into the section or symbol.  */
2965
  val = reloc_entry->addend;
2966
 
2967
  if (reloc_entry->howto->partial_inplace)
2968
    val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
2969
 
2970
  /* Adjust val for the final section location and GP value.  If we
2971
     are producing relocatable output, we don't want to do this for
2972
     an external symbol.  */
2973
  if (! relocatable
2974
      || (symbol->flags & BSF_SECTION_SYM) != 0)
2975
    val += relocation - gp;
2976
 
2977
  if (reloc_entry->howto->partial_inplace)
2978
    bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
2979
  else
2980
    reloc_entry->addend = val;
2981
 
2982
  if (relocatable)
2983
    reloc_entry->address += input_section->output_offset;
2984
 
2985
  return bfd_reloc_ok;
2986
}
2987
 
2988
/* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
2989
   the rest is at bits 6-10. The bitpos already got right by the howto.  */
2990
 
2991
static bfd_reloc_status_type
2992
mips_elf64_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
2993
                         void *data, asection *input_section, bfd *output_bfd,
2994
                         char **error_message)
2995
{
2996
  if (reloc_entry->howto->partial_inplace)
2997
    {
2998
      reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
2999
                             | (reloc_entry->addend & 0x00000800) >> 9);
3000
    }
3001
 
3002
  return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
3003
                                      input_section, output_bfd,
3004
                                      error_message);
3005
}
3006
 
3007
/* Handle a mips16 GP relative reloc.  */
3008
 
3009
static bfd_reloc_status_type
3010
mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
3011
                    void *data, asection *input_section, bfd *output_bfd,
3012
                    char **error_message)
3013
{
3014
  bfd_boolean relocatable;
3015
  bfd_reloc_status_type ret;
3016
  bfd_byte *location;
3017
  bfd_vma gp;
3018
 
3019
  /* If we're relocating, and this is an external symbol, we don't want
3020
     to change anything.  */
3021
  if (output_bfd != NULL
3022
      && (symbol->flags & BSF_SECTION_SYM) == 0
3023
      && (symbol->flags & BSF_LOCAL) != 0)
3024
    {
3025
      reloc_entry->address += input_section->output_offset;
3026
      return bfd_reloc_ok;
3027
    }
3028
 
3029
  if (output_bfd != NULL)
3030
    relocatable = TRUE;
3031
  else
3032
    {
3033
      relocatable = FALSE;
3034
      output_bfd = symbol->section->output_section->owner;
3035
    }
3036
 
3037
  ret = mips_elf64_final_gp (output_bfd, symbol, relocatable, error_message,
3038
                             &gp);
3039
  if (ret != bfd_reloc_ok)
3040
    return ret;
3041
 
3042
  location = (bfd_byte *) data + reloc_entry->address;
3043 161 khays
  _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
3044
                                 location);
3045 14 khays
  ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
3046
                                       input_section, relocatable,
3047
                                       data, gp);
3048 161 khays
  _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
3049
                               location);
3050 14 khays
 
3051
  return ret;
3052
}
3053
 
3054
/* A mapping from BFD reloc types to MIPS ELF reloc types.  */
3055
 
3056
struct elf_reloc_map {
3057
  bfd_reloc_code_real_type bfd_val;
3058
  enum elf_mips_reloc_type elf_val;
3059
};
3060
 
3061
static const struct elf_reloc_map mips_reloc_map[] =
3062
{
3063
  { BFD_RELOC_NONE, R_MIPS_NONE },
3064
  { BFD_RELOC_16, R_MIPS_16 },
3065
  { BFD_RELOC_32, R_MIPS_32 },
3066
  /* There is no BFD reloc for R_MIPS_REL32.  */
3067
  { BFD_RELOC_64, R_MIPS_64 },
3068
  { BFD_RELOC_CTOR, R_MIPS_64 },
3069
  { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
3070
  { BFD_RELOC_HI16_S, R_MIPS_HI16 },
3071
  { BFD_RELOC_LO16, R_MIPS_LO16 },
3072
  { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
3073
  { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
3074
  { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
3075
  { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
3076
  { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
3077
  { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
3078
  { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
3079
  { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
3080
  { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
3081
  { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
3082
  { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
3083
  { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
3084
  { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
3085
  { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
3086
  { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
3087
  { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
3088
  { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
3089
  { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
3090
  { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
3091
  { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
3092
  { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
3093
  { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
3094
  { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
3095
  /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated.  */
3096
  { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
3097
  { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
3098
  { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
3099
  { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
3100
  { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
3101
  { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
3102
  { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
3103
  { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
3104
  { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
3105
  { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
3106
  { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
3107
  { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
3108
  { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
3109
  { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
3110
  { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
3111
};
3112
 
3113
static const struct elf_reloc_map mips16_reloc_map[] =
3114
{
3115
  { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
3116
  { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
3117
  { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
3118
  { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
3119
  { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
3120
  { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
3121 166 khays
  { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min },
3122
  { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min },
3123
  { BFD_RELOC_MIPS16_TLS_DTPREL_HI16,
3124
    R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min },
3125
  { BFD_RELOC_MIPS16_TLS_DTPREL_LO16,
3126
    R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min },
3127
  { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min },
3128
  { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min },
3129
  { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min }
3130 14 khays
};
3131
 
3132 161 khays
static const struct elf_reloc_map micromips_reloc_map[] =
3133
{
3134
  { BFD_RELOC_MICROMIPS_JMP, R_MICROMIPS_26_S1 - R_MICROMIPS_min },
3135
  { BFD_RELOC_MICROMIPS_HI16_S, R_MICROMIPS_HI16 - R_MICROMIPS_min },
3136
  { BFD_RELOC_MICROMIPS_LO16, R_MICROMIPS_LO16 - R_MICROMIPS_min },
3137
  { BFD_RELOC_MICROMIPS_GPREL16, R_MICROMIPS_GPREL16 - R_MICROMIPS_min },
3138
  { BFD_RELOC_MICROMIPS_LITERAL, R_MICROMIPS_LITERAL - R_MICROMIPS_min },
3139
  { BFD_RELOC_MICROMIPS_GOT16, R_MICROMIPS_GOT16 - R_MICROMIPS_min },
3140
  { BFD_RELOC_MICROMIPS_7_PCREL_S1, R_MICROMIPS_PC7_S1 - R_MICROMIPS_min },
3141
  { BFD_RELOC_MICROMIPS_10_PCREL_S1, R_MICROMIPS_PC10_S1 - R_MICROMIPS_min },
3142
  { BFD_RELOC_MICROMIPS_16_PCREL_S1, R_MICROMIPS_PC16_S1 - R_MICROMIPS_min },
3143
  { BFD_RELOC_MICROMIPS_CALL16, R_MICROMIPS_CALL16 - R_MICROMIPS_min },
3144
  { BFD_RELOC_MICROMIPS_GOT_DISP, R_MICROMIPS_GOT_DISP - R_MICROMIPS_min },
3145
  { BFD_RELOC_MICROMIPS_GOT_PAGE, R_MICROMIPS_GOT_PAGE - R_MICROMIPS_min },
3146
  { BFD_RELOC_MICROMIPS_GOT_OFST, R_MICROMIPS_GOT_OFST - R_MICROMIPS_min },
3147
  { BFD_RELOC_MICROMIPS_GOT_HI16, R_MICROMIPS_GOT_HI16 - R_MICROMIPS_min },
3148
  { BFD_RELOC_MICROMIPS_GOT_LO16, R_MICROMIPS_GOT_LO16 - R_MICROMIPS_min },
3149
  { BFD_RELOC_MICROMIPS_SUB, R_MICROMIPS_SUB - R_MICROMIPS_min },
3150
  { BFD_RELOC_MICROMIPS_HIGHER, R_MICROMIPS_HIGHER - R_MICROMIPS_min },
3151
  { BFD_RELOC_MICROMIPS_HIGHEST, R_MICROMIPS_HIGHEST - R_MICROMIPS_min },
3152
  { BFD_RELOC_MICROMIPS_CALL_HI16, R_MICROMIPS_CALL_HI16 - R_MICROMIPS_min },
3153
  { BFD_RELOC_MICROMIPS_CALL_LO16, R_MICROMIPS_CALL_LO16 - R_MICROMIPS_min },
3154
};
3155 14 khays
/* Given a BFD reloc type, return a howto structure.  */
3156
 
3157
static reloc_howto_type *
3158
bfd_elf64_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3159
                                 bfd_reloc_code_real_type code)
3160
{
3161
  unsigned int i;
3162
  /* FIXME: We default to RELA here instead of choosing the right
3163
     relocation variant.  */
3164
  reloc_howto_type *howto_table = mips_elf64_howto_table_rela;
3165
  reloc_howto_type *howto16_table = mips16_elf64_howto_table_rela;
3166 161 khays
  reloc_howto_type *howto_micromips_table = micromips_elf64_howto_table_rela;
3167 14 khays
 
3168
  for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
3169
       i++)
3170
    {
3171
      if (mips_reloc_map[i].bfd_val == code)
3172
        return &howto_table[(int) mips_reloc_map[i].elf_val];
3173
    }
3174
 
3175
  for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
3176
       i++)
3177
    {
3178
      if (mips16_reloc_map[i].bfd_val == code)
3179
        return &howto16_table[(int) mips16_reloc_map[i].elf_val];
3180
    }
3181
 
3182 161 khays
  for (i = 0; i < sizeof (micromips_reloc_map) / sizeof (struct elf_reloc_map);
3183
       i++)
3184
    {
3185
      if (micromips_reloc_map[i].bfd_val == code)
3186
        return &howto_micromips_table[(int) micromips_reloc_map[i].elf_val];
3187
    }
3188
 
3189 14 khays
  switch (code)
3190
    {
3191
    case BFD_RELOC_VTABLE_INHERIT:
3192
      return &elf_mips_gnu_vtinherit_howto;
3193
    case BFD_RELOC_VTABLE_ENTRY:
3194
      return &elf_mips_gnu_vtentry_howto;
3195
    case BFD_RELOC_MIPS_COPY:
3196
      return &elf_mips_copy_howto;
3197
    case BFD_RELOC_MIPS_JUMP_SLOT:
3198
      return &elf_mips_jump_slot_howto;
3199
    default:
3200
      bfd_set_error (bfd_error_bad_value);
3201
      return NULL;
3202
    }
3203
}
3204
 
3205
static reloc_howto_type *
3206
bfd_elf64_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3207
                                 const char *r_name)
3208
{
3209
  unsigned int i;
3210
 
3211
  for (i = 0;
3212
       i < (sizeof (mips_elf64_howto_table_rela)
3213
            / sizeof (mips_elf64_howto_table_rela[0])); i++)
3214
    if (mips_elf64_howto_table_rela[i].name != NULL
3215
        && strcasecmp (mips_elf64_howto_table_rela[i].name, r_name) == 0)
3216
      return &mips_elf64_howto_table_rela[i];
3217
 
3218
  for (i = 0;
3219
       i < (sizeof (mips16_elf64_howto_table_rela)
3220
            / sizeof (mips16_elf64_howto_table_rela[0]));
3221
       i++)
3222
    if (mips16_elf64_howto_table_rela[i].name != NULL
3223
        && strcasecmp (mips16_elf64_howto_table_rela[i].name, r_name) == 0)
3224
      return &mips16_elf64_howto_table_rela[i];
3225
 
3226 161 khays
  for (i = 0;
3227
       i < (sizeof (micromips_elf64_howto_table_rela)
3228
            / sizeof (micromips_elf64_howto_table_rela[0]));
3229
       i++)
3230
    if (micromips_elf64_howto_table_rela[i].name != NULL
3231
        && strcasecmp (micromips_elf64_howto_table_rela[i].name, r_name) == 0)
3232
      return &micromips_elf64_howto_table_rela[i];
3233
 
3234 14 khays
  if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
3235
    return &elf_mips_gnu_vtinherit_howto;
3236
  if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
3237
    return &elf_mips_gnu_vtentry_howto;
3238
  if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
3239
    return &elf_mips_gnu_rel16_s2;
3240
  if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
3241
    return &elf_mips_gnu_rela16_s2;
3242
  if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
3243
    return &elf_mips_copy_howto;
3244
  if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
3245
    return &elf_mips_jump_slot_howto;
3246
 
3247
  return NULL;
3248
}
3249
 
3250
/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
3251
 
3252
static reloc_howto_type *
3253
mips_elf64_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
3254
{
3255
  switch (r_type)
3256
    {
3257
    case R_MIPS_GNU_VTINHERIT:
3258
      return &elf_mips_gnu_vtinherit_howto;
3259
    case R_MIPS_GNU_VTENTRY:
3260
      return &elf_mips_gnu_vtentry_howto;
3261
    case R_MIPS_GNU_REL16_S2:
3262
      if (rela_p)
3263
        return &elf_mips_gnu_rela16_s2;
3264
      else
3265
        return &elf_mips_gnu_rel16_s2;
3266
    case R_MIPS_COPY:
3267
      return &elf_mips_copy_howto;
3268
    case R_MIPS_JUMP_SLOT:
3269
      return &elf_mips_jump_slot_howto;
3270
    default:
3271 161 khays
      if (r_type >= R_MICROMIPS_min && r_type < R_MICROMIPS_max)
3272
        {
3273
          if (rela_p)
3274
            return &micromips_elf64_howto_table_rela[r_type - R_MICROMIPS_min];
3275
          else
3276
            return &micromips_elf64_howto_table_rel[r_type - R_MICROMIPS_min];
3277
        }
3278 14 khays
      if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
3279
        {
3280
          if (rela_p)
3281
            return &mips16_elf64_howto_table_rela[r_type - R_MIPS16_min];
3282
          else
3283
            return &mips16_elf64_howto_table_rel[r_type - R_MIPS16_min];
3284
        }
3285
      BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
3286
      if (rela_p)
3287
        return &mips_elf64_howto_table_rela[r_type];
3288
      else
3289
        return &mips_elf64_howto_table_rel[r_type];
3290
      break;
3291
    }
3292
}
3293
 
3294
/* Prevent relocation handling by bfd for MIPS ELF64.  */
3295
 
3296
static void
3297
mips_elf64_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
3298
                              arelent *cache_ptr ATTRIBUTE_UNUSED,
3299
                              Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
3300
{
3301
  BFD_ASSERT (0);
3302
}
3303
 
3304
static void
3305
mips_elf64_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
3306
                               arelent *cache_ptr ATTRIBUTE_UNUSED,
3307
                               Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
3308
{
3309
  BFD_ASSERT (0);
3310
}
3311
 
3312
/* Since each entry in an SHT_REL or SHT_RELA section can represent up
3313
   to three relocs, we must tell the user to allocate more space.  */
3314
 
3315
static long
3316
mips_elf64_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
3317
{
3318
  return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
3319
}
3320
 
3321
static long
3322
mips_elf64_get_dynamic_reloc_upper_bound (bfd *abfd)
3323
{
3324
  return _bfd_elf_get_dynamic_reloc_upper_bound (abfd) * 3;
3325
}
3326
 
3327
/* We must also copy more relocations than the corresponding functions
3328
   in elf.c would, so the two following functions are slightly
3329
   modified from elf.c, that multiply the external relocation count by
3330
   3 to obtain the internal relocation count.  */
3331
 
3332
static long
3333
mips_elf64_canonicalize_reloc (bfd *abfd, sec_ptr section,
3334
                               arelent **relptr, asymbol **symbols)
3335
{
3336
  arelent *tblptr;
3337
  unsigned int i;
3338
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
3339
 
3340
  if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
3341
    return -1;
3342
 
3343
  tblptr = section->relocation;
3344
  for (i = 0; i < section->reloc_count * 3; i++)
3345
    *relptr++ = tblptr++;
3346
 
3347
  *relptr = NULL;
3348
 
3349
  return section->reloc_count * 3;
3350
}
3351
 
3352
static long
3353
mips_elf64_canonicalize_dynamic_reloc (bfd *abfd, arelent **storage,
3354
                                       asymbol **syms)
3355
{
3356
  bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
3357
  asection *s;
3358
  long ret;
3359
 
3360
  if (elf_dynsymtab (abfd) == 0)
3361
    {
3362
      bfd_set_error (bfd_error_invalid_operation);
3363
      return -1;
3364
    }
3365
 
3366
  slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
3367
  ret = 0;
3368
  for (s = abfd->sections; s != NULL; s = s->next)
3369
    {
3370
      if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
3371
          && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
3372
              || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
3373
        {
3374
          arelent *p;
3375
          long count, i;
3376
 
3377
          if (! (*slurp_relocs) (abfd, s, syms, TRUE))
3378
            return -1;
3379
          count = s->size / elf_section_data (s)->this_hdr.sh_entsize * 3;
3380
          p = s->relocation;
3381
          for (i = 0; i < count; i++)
3382
            *storage++ = p++;
3383
          ret += count;
3384
        }
3385
    }
3386
 
3387
  *storage = NULL;
3388
 
3389
  return ret;
3390
}
3391
 
3392
/* Read the relocations from one reloc section.  This is mostly copied
3393
   from elfcode.h, except for the changes to expand one external
3394
   relocation to 3 internal ones.  We must unfortunately set
3395
   reloc_count to the number of external relocations, because a lot of
3396
   generic code seems to depend on this.  */
3397
 
3398
static bfd_boolean
3399
mips_elf64_slurp_one_reloc_table (bfd *abfd, asection *asect,
3400
                                  Elf_Internal_Shdr *rel_hdr,
3401
                                  bfd_size_type reloc_count,
3402
                                  arelent *relents, asymbol **symbols,
3403
                                  bfd_boolean dynamic)
3404
{
3405
  void *allocated;
3406
  bfd_byte *native_relocs;
3407
  arelent *relent;
3408
  bfd_vma i;
3409
  int entsize;
3410
  bfd_boolean rela_p;
3411
 
3412
  allocated = bfd_malloc (rel_hdr->sh_size);
3413
  if (allocated == NULL)
3414
    return FALSE;
3415
 
3416
  if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
3417
      || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
3418
          != rel_hdr->sh_size))
3419
    goto error_return;
3420
 
3421
  native_relocs = allocated;
3422
 
3423
  entsize = rel_hdr->sh_entsize;
3424
  BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
3425
              || entsize == sizeof (Elf64_Mips_External_Rela));
3426
 
3427
  if (entsize == sizeof (Elf64_Mips_External_Rel))
3428
    rela_p = FALSE;
3429
  else
3430
    rela_p = TRUE;
3431
 
3432
  for (i = 0, relent = relents;
3433
       i < reloc_count;
3434
       i++, native_relocs += entsize)
3435
    {
3436
      Elf64_Mips_Internal_Rela rela;
3437
      bfd_boolean used_sym, used_ssym;
3438
      int ir;
3439
 
3440
      if (entsize == sizeof (Elf64_Mips_External_Rela))
3441
        mips_elf64_swap_reloca_in (abfd,
3442
                                   (Elf64_Mips_External_Rela *) native_relocs,
3443
                                   &rela);
3444
      else
3445
        mips_elf64_swap_reloc_in (abfd,
3446
                                  (Elf64_Mips_External_Rel *) native_relocs,
3447
                                  &rela);
3448
 
3449
      /* Each entry represents exactly three actual relocations.  */
3450
 
3451
      used_sym = FALSE;
3452
      used_ssym = FALSE;
3453
      for (ir = 0; ir < 3; ir++)
3454
        {
3455
          enum elf_mips_reloc_type type;
3456
 
3457
          switch (ir)
3458
            {
3459
            default:
3460
              abort ();
3461
            case 0:
3462
              type = (enum elf_mips_reloc_type) rela.r_type;
3463
              break;
3464
            case 1:
3465
              type = (enum elf_mips_reloc_type) rela.r_type2;
3466
              break;
3467
            case 2:
3468
              type = (enum elf_mips_reloc_type) rela.r_type3;
3469
              break;
3470
            }
3471
 
3472
          /* Some types require symbols, whereas some do not.  */
3473
          switch (type)
3474
            {
3475
            case R_MIPS_NONE:
3476
            case R_MIPS_LITERAL:
3477
            case R_MIPS_INSERT_A:
3478
            case R_MIPS_INSERT_B:
3479
            case R_MIPS_DELETE:
3480
              relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3481
              break;
3482
 
3483
            default:
3484
              if (! used_sym)
3485
                {
3486
                  if (rela.r_sym == STN_UNDEF)
3487
                    relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3488
                  else
3489
                    {
3490
                      asymbol **ps, *s;
3491
 
3492
                      ps = symbols + rela.r_sym - 1;
3493
                      s = *ps;
3494
                      if ((s->flags & BSF_SECTION_SYM) == 0)
3495
                        relent->sym_ptr_ptr = ps;
3496
                      else
3497
                        relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
3498
                    }
3499
 
3500
                  used_sym = TRUE;
3501
                }
3502
              else if (! used_ssym)
3503
                {
3504
                  switch (rela.r_ssym)
3505
                    {
3506
                    case RSS_UNDEF:
3507
                      relent->sym_ptr_ptr =
3508
                        bfd_abs_section_ptr->symbol_ptr_ptr;
3509
                      break;
3510
 
3511
                    case RSS_GP:
3512
                    case RSS_GP0:
3513
                    case RSS_LOC:
3514
                      /* FIXME: I think these need to be handled using
3515
                         special howto structures.  */
3516
                      BFD_ASSERT (0);
3517
                      break;
3518
 
3519
                    default:
3520
                      BFD_ASSERT (0);
3521
                      break;
3522
                    }
3523
 
3524
                  used_ssym = TRUE;
3525
                }
3526
              else
3527
                relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3528
 
3529
              break;
3530
            }
3531
 
3532
          /* The address of an ELF reloc is section relative for an
3533
             object file, and absolute for an executable file or
3534
             shared library.  The address of a BFD reloc is always
3535
             section relative.  */
3536
          if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
3537
            relent->address = rela.r_offset;
3538
          else
3539
            relent->address = rela.r_offset - asect->vma;
3540
 
3541
          relent->addend = rela.r_addend;
3542
 
3543
          relent->howto = mips_elf64_rtype_to_howto (type, rela_p);
3544
 
3545
          ++relent;
3546
        }
3547
    }
3548
 
3549
  asect->reloc_count += (relent - relents) / 3;
3550
 
3551
  if (allocated != NULL)
3552
    free (allocated);
3553
 
3554
  return TRUE;
3555
 
3556
 error_return:
3557
  if (allocated != NULL)
3558
    free (allocated);
3559
  return FALSE;
3560
}
3561
 
3562
/* Read the relocations.  On Irix 6, there can be two reloc sections
3563
   associated with a single data section.  This is copied from
3564
   elfcode.h as well, with changes as small as accounting for 3
3565
   internal relocs per external reloc and resetting reloc_count to
3566
   zero before processing the relocs of a section.  */
3567
 
3568
static bfd_boolean
3569
mips_elf64_slurp_reloc_table (bfd *abfd, asection *asect,
3570
                              asymbol **symbols, bfd_boolean dynamic)
3571
{
3572
  struct bfd_elf_section_data * const d = elf_section_data (asect);
3573
  Elf_Internal_Shdr *rel_hdr;
3574
  Elf_Internal_Shdr *rel_hdr2;
3575
  bfd_size_type reloc_count;
3576
  bfd_size_type reloc_count2;
3577
  arelent *relents;
3578
  bfd_size_type amt;
3579
 
3580
  if (asect->relocation != NULL)
3581
    return TRUE;
3582
 
3583
  if (! dynamic)
3584
    {
3585
      if ((asect->flags & SEC_RELOC) == 0
3586
          || asect->reloc_count == 0)
3587
        return TRUE;
3588
 
3589
      rel_hdr = d->rel.hdr;
3590
      reloc_count = rel_hdr ? NUM_SHDR_ENTRIES (rel_hdr) : 0;
3591
      rel_hdr2 = d->rela.hdr;
3592
      reloc_count2 = (rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0);
3593
 
3594
      BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
3595
      BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
3596
                  || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
3597
 
3598
    }
3599
  else
3600
    {
3601
      /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
3602
         case because relocations against this section may use the
3603
         dynamic symbol table, and in that case bfd_section_from_shdr
3604
         in elf.c does not update the RELOC_COUNT.  */
3605
      if (asect->size == 0)
3606
        return TRUE;
3607
 
3608
      rel_hdr = &d->this_hdr;
3609
      reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
3610
      rel_hdr2 = NULL;
3611
      reloc_count2 = 0;
3612
    }
3613
 
3614
  /* Allocate space for 3 arelent structures for each Rel structure.  */
3615
  amt = (reloc_count + reloc_count2) * 3 * sizeof (arelent);
3616
  relents = bfd_alloc (abfd, amt);
3617
  if (relents == NULL)
3618
    return FALSE;
3619
 
3620
  /* The slurp_one_reloc_table routine increments reloc_count.  */
3621
  asect->reloc_count = 0;
3622
 
3623
  if (rel_hdr != NULL
3624
      && ! mips_elf64_slurp_one_reloc_table (abfd, asect,
3625
                                             rel_hdr, reloc_count,
3626
                                             relents,
3627
                                             symbols, dynamic))
3628
    return FALSE;
3629
  if (rel_hdr2 != NULL
3630
      && ! mips_elf64_slurp_one_reloc_table (abfd, asect,
3631
                                             rel_hdr2, reloc_count2,
3632
                                             relents + reloc_count * 3,
3633
                                             symbols, dynamic))
3634
    return FALSE;
3635
 
3636
  asect->relocation = relents;
3637
  return TRUE;
3638
}
3639
 
3640
/* Write out the relocations.  */
3641
 
3642
static void
3643
mips_elf64_write_relocs (bfd *abfd, asection *sec, void *data)
3644
{
3645
  bfd_boolean *failedp = data;
3646
  int count;
3647
  Elf_Internal_Shdr *rel_hdr;
3648
  unsigned int idx;
3649
 
3650
  /* If we have already failed, don't do anything.  */
3651
  if (*failedp)
3652
    return;
3653
 
3654
  if ((sec->flags & SEC_RELOC) == 0)
3655
    return;
3656
 
3657
  /* The linker backend writes the relocs out itself, and sets the
3658
     reloc_count field to zero to inhibit writing them here.  Also,
3659
     sometimes the SEC_RELOC flag gets set even when there aren't any
3660
     relocs.  */
3661
  if (sec->reloc_count == 0)
3662
    return;
3663
 
3664
  /* We can combine up to three relocs that refer to the same address
3665
     if the latter relocs have no associated symbol.  */
3666
  count = 0;
3667
  for (idx = 0; idx < sec->reloc_count; idx++)
3668
    {
3669
      bfd_vma addr;
3670
      unsigned int i;
3671
 
3672
      ++count;
3673
 
3674
      addr = sec->orelocation[idx]->address;
3675
      for (i = 0; i < 2; i++)
3676
        {
3677
          arelent *r;
3678
 
3679
          if (idx + 1 >= sec->reloc_count)
3680
            break;
3681
          r = sec->orelocation[idx + 1];
3682
          if (r->address != addr
3683
              || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
3684
              || (*r->sym_ptr_ptr)->value != 0)
3685
            break;
3686
 
3687
          /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
3688
 
3689
          ++idx;
3690
        }
3691
    }
3692
 
3693
  rel_hdr = _bfd_elf_single_rel_hdr (sec);
3694
 
3695
  /* Do the actual relocation.  */
3696
 
3697
  if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rel))
3698
    mips_elf64_write_rel (abfd, sec, rel_hdr, &count, data);
3699
  else if (rel_hdr->sh_entsize == sizeof(Elf64_Mips_External_Rela))
3700
    mips_elf64_write_rela (abfd, sec, rel_hdr, &count, data);
3701
  else
3702
    BFD_ASSERT (0);
3703
}
3704
 
3705
static void
3706
mips_elf64_write_rel (bfd *abfd, asection *sec,
3707
                      Elf_Internal_Shdr *rel_hdr,
3708
                      int *count, void *data)
3709
{
3710
  bfd_boolean *failedp = data;
3711
  Elf64_Mips_External_Rel *ext_rel;
3712
  unsigned int idx;
3713
  asymbol *last_sym = 0;
3714
  int last_sym_idx = 0;
3715
 
3716
  rel_hdr->sh_size = rel_hdr->sh_entsize * *count;
3717
  rel_hdr->contents = bfd_alloc (abfd, rel_hdr->sh_size);
3718
  if (rel_hdr->contents == NULL)
3719
    {
3720
      *failedp = TRUE;
3721
      return;
3722
    }
3723
 
3724
  ext_rel = (Elf64_Mips_External_Rel *) rel_hdr->contents;
3725
  for (idx = 0; idx < sec->reloc_count; idx++, ext_rel++)
3726
    {
3727
      arelent *ptr;
3728
      Elf64_Mips_Internal_Rela int_rel;
3729
      asymbol *sym;
3730
      int n;
3731
      unsigned int i;
3732
 
3733
      ptr = sec->orelocation[idx];
3734
 
3735
      /* The address of an ELF reloc is section relative for an object
3736
         file, and absolute for an executable file or shared library.
3737
         The address of a BFD reloc is always section relative.  */
3738
      if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
3739
        int_rel.r_offset = ptr->address;
3740
      else
3741
        int_rel.r_offset = ptr->address + sec->vma;
3742
 
3743
      sym = *ptr->sym_ptr_ptr;
3744
      if (sym == last_sym)
3745
        n = last_sym_idx;
3746
      else if (bfd_is_abs_section (sym->section) && sym->value == 0)
3747
        n = STN_UNDEF;
3748
      else
3749
        {
3750
          last_sym = sym;
3751
          n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
3752
          if (n < 0)
3753
            {
3754
              *failedp = TRUE;
3755
              return;
3756
            }
3757
          last_sym_idx = n;
3758
        }
3759
 
3760
      int_rel.r_sym = n;
3761
      int_rel.r_ssym = RSS_UNDEF;
3762
 
3763
      if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
3764
          && ! _bfd_elf_validate_reloc (abfd, ptr))
3765
        {
3766
          *failedp = TRUE;
3767
          return;
3768
        }
3769
 
3770
      int_rel.r_type = ptr->howto->type;
3771
      int_rel.r_type2 = (int) R_MIPS_NONE;
3772
      int_rel.r_type3 = (int) R_MIPS_NONE;
3773
 
3774
      for (i = 0; i < 2; i++)
3775
        {
3776
          arelent *r;
3777
 
3778
          if (idx + 1 >= sec->reloc_count)
3779
            break;
3780
          r = sec->orelocation[idx + 1];
3781
          if (r->address != ptr->address
3782
              || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
3783
              || (*r->sym_ptr_ptr)->value != 0)
3784
            break;
3785
 
3786
          /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
3787
 
3788
          if (i == 0)
3789
            int_rel.r_type2 = r->howto->type;
3790
          else
3791
            int_rel.r_type3 = r->howto->type;
3792
 
3793
          ++idx;
3794
        }
3795
 
3796
      mips_elf64_swap_reloc_out (abfd, &int_rel, ext_rel);
3797
    }
3798
 
3799
  BFD_ASSERT (ext_rel - (Elf64_Mips_External_Rel *) rel_hdr->contents
3800
              == *count);
3801
}
3802
 
3803
static void
3804
mips_elf64_write_rela (bfd *abfd, asection *sec,
3805
                       Elf_Internal_Shdr *rela_hdr,
3806
                       int *count, void *data)
3807
{
3808
  bfd_boolean *failedp = data;
3809
  Elf64_Mips_External_Rela *ext_rela;
3810
  unsigned int idx;
3811
  asymbol *last_sym = 0;
3812
  int last_sym_idx = 0;
3813
 
3814
  rela_hdr->sh_size = rela_hdr->sh_entsize * *count;
3815
  rela_hdr->contents = bfd_alloc (abfd, rela_hdr->sh_size);
3816
  if (rela_hdr->contents == NULL)
3817
    {
3818
      *failedp = TRUE;
3819
      return;
3820
    }
3821
 
3822
  ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
3823
  for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
3824
    {
3825
      arelent *ptr;
3826
      Elf64_Mips_Internal_Rela int_rela;
3827
      asymbol *sym;
3828
      int n;
3829
      unsigned int i;
3830
 
3831
      ptr = sec->orelocation[idx];
3832
 
3833
      /* The address of an ELF reloc is section relative for an object
3834
         file, and absolute for an executable file or shared library.
3835
         The address of a BFD reloc is always section relative.  */
3836
      if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
3837
        int_rela.r_offset = ptr->address;
3838
      else
3839
        int_rela.r_offset = ptr->address + sec->vma;
3840
 
3841
      sym = *ptr->sym_ptr_ptr;
3842
      if (sym == last_sym)
3843
        n = last_sym_idx;
3844
      else if (bfd_is_abs_section (sym->section) && sym->value == 0)
3845
        n = STN_UNDEF;
3846
      else
3847
        {
3848
          last_sym = sym;
3849
          n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
3850
          if (n < 0)
3851
            {
3852
              *failedp = TRUE;
3853
              return;
3854
            }
3855
          last_sym_idx = n;
3856
        }
3857
 
3858
      int_rela.r_sym = n;
3859
      int_rela.r_addend = ptr->addend;
3860
      int_rela.r_ssym = RSS_UNDEF;
3861
 
3862
      if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
3863
          && ! _bfd_elf_validate_reloc (abfd, ptr))
3864
        {
3865
          *failedp = TRUE;
3866
          return;
3867
        }
3868
 
3869
      int_rela.r_type = ptr->howto->type;
3870
      int_rela.r_type2 = (int) R_MIPS_NONE;
3871
      int_rela.r_type3 = (int) R_MIPS_NONE;
3872
 
3873
      for (i = 0; i < 2; i++)
3874
        {
3875
          arelent *r;
3876
 
3877
          if (idx + 1 >= sec->reloc_count)
3878
            break;
3879
          r = sec->orelocation[idx + 1];
3880
          if (r->address != ptr->address
3881
              || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
3882
              || (*r->sym_ptr_ptr)->value != 0)
3883
            break;
3884
 
3885
          /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
3886
 
3887
          if (i == 0)
3888
            int_rela.r_type2 = r->howto->type;
3889
          else
3890
            int_rela.r_type3 = r->howto->type;
3891
 
3892
          ++idx;
3893
        }
3894
 
3895
      mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
3896
    }
3897
 
3898
  BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
3899
              == *count);
3900
}
3901
 
3902
/* Set the right machine number for a MIPS ELF file.  */
3903
 
3904
static bfd_boolean
3905
mips_elf64_object_p (bfd *abfd)
3906
{
3907
  unsigned long mach;
3908
 
3909
  /* Irix 6 is broken.  Object file symbol tables are not always
3910
     sorted correctly such that local symbols precede global symbols,
3911
     and the sh_info field in the symbol table is not always right.  */
3912
  if (elf64_mips_irix_compat (abfd) != ict_none)
3913
    elf_bad_symtab (abfd) = TRUE;
3914
 
3915
  mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
3916
  bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
3917
  return TRUE;
3918
}
3919
 
3920
/* Depending on the target vector we generate some version of Irix
3921
   executables or "normal" MIPS ELF ABI executables.  */
3922
static irix_compat_t
3923
elf64_mips_irix_compat (bfd *abfd)
3924
{
3925
  if ((abfd->xvec == &bfd_elf64_bigmips_vec)
3926
      || (abfd->xvec == &bfd_elf64_littlemips_vec))
3927
    return ict_irix6;
3928
  else
3929
    return ict_none;
3930
}
3931
 
3932
/* Support for core dump NOTE sections.  */
3933
static bfd_boolean
3934
elf64_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
3935
{
3936
  int offset;
3937
  unsigned int size;
3938
 
3939
  switch (note->descsz)
3940
    {
3941
      default:
3942
        return FALSE;
3943
 
3944
      case 480:         /* Linux/MIPS - N64 kernel */
3945
        /* pr_cursig */
3946
        elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
3947
 
3948
        /* pr_pid */
3949
        elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 32);
3950
 
3951
        /* pr_reg */
3952
        offset = 112;
3953
        size = 360;
3954
 
3955
        break;
3956
    }
3957
 
3958
  /* Make a ".reg/999" section.  */
3959
  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
3960
                                          size, note->descpos + offset);
3961
}
3962
 
3963
static bfd_boolean
3964
elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
3965
{
3966
  switch (note->descsz)
3967
    {
3968
      default:
3969
        return FALSE;
3970
 
3971
      case 136:         /* Linux/MIPS - N64 kernel elf_prpsinfo */
3972
        elf_tdata (abfd)->core_program
3973
         = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
3974
        elf_tdata (abfd)->core_command
3975
         = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
3976
    }
3977
 
3978
  /* Note that for some reason, a spurious space is tacked
3979
     onto the end of the args in some (at least one anyway)
3980
     implementations, so strip it off if it exists.  */
3981
 
3982
  {
3983
    char *command = elf_tdata (abfd)->core_command;
3984
    int n = strlen (command);
3985
 
3986
    if (0 < n && command[n - 1] == ' ')
3987
      command[n - 1] = '\0';
3988
  }
3989
 
3990
  return TRUE;
3991
}
3992
 
3993
/* ECOFF swapping routines.  These are used when dealing with the
3994
   .mdebug section, which is in the ECOFF debugging format.  */
3995
static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
3996
{
3997
  /* Symbol table magic number.  */
3998
  magicSym2,
3999
  /* Alignment of debugging information.  E.g., 4.  */
4000
  8,
4001
  /* Sizes of external symbolic information.  */
4002
  sizeof (struct hdr_ext),
4003
  sizeof (struct dnr_ext),
4004
  sizeof (struct pdr_ext),
4005
  sizeof (struct sym_ext),
4006
  sizeof (struct opt_ext),
4007
  sizeof (struct fdr_ext),
4008
  sizeof (struct rfd_ext),
4009
  sizeof (struct ext_ext),
4010
  /* Functions to swap in external symbolic data.  */
4011
  ecoff_swap_hdr_in,
4012
  ecoff_swap_dnr_in,
4013
  ecoff_swap_pdr_in,
4014
  ecoff_swap_sym_in,
4015
  ecoff_swap_opt_in,
4016
  ecoff_swap_fdr_in,
4017
  ecoff_swap_rfd_in,
4018
  ecoff_swap_ext_in,
4019
  _bfd_ecoff_swap_tir_in,
4020
  _bfd_ecoff_swap_rndx_in,
4021
  /* Functions to swap out external symbolic data.  */
4022
  ecoff_swap_hdr_out,
4023
  ecoff_swap_dnr_out,
4024
  ecoff_swap_pdr_out,
4025
  ecoff_swap_sym_out,
4026
  ecoff_swap_opt_out,
4027
  ecoff_swap_fdr_out,
4028
  ecoff_swap_rfd_out,
4029
  ecoff_swap_ext_out,
4030
  _bfd_ecoff_swap_tir_out,
4031
  _bfd_ecoff_swap_rndx_out,
4032
  /* Function to read in symbolic data.  */
4033
  _bfd_mips_elf_read_ecoff_info
4034
};
4035
 
4036
/* Relocations in the 64 bit MIPS ELF ABI are more complex than in
4037
   standard ELF.  This structure is used to redirect the relocation
4038
   handling routines.  */
4039
 
4040
const struct elf_size_info mips_elf64_size_info =
4041
{
4042
  sizeof (Elf64_External_Ehdr),
4043
  sizeof (Elf64_External_Phdr),
4044
  sizeof (Elf64_External_Shdr),
4045
  sizeof (Elf64_Mips_External_Rel),
4046
  sizeof (Elf64_Mips_External_Rela),
4047
  sizeof (Elf64_External_Sym),
4048
  sizeof (Elf64_External_Dyn),
4049
  sizeof (Elf_External_Note),
4050
  4,            /* hash-table entry size */
4051
  3,            /* internal relocations per external relocations */
4052
  64,           /* arch_size */
4053
  3,            /* log_file_align */
4054
  ELFCLASS64,
4055
  EV_CURRENT,
4056
  bfd_elf64_write_out_phdrs,
4057
  bfd_elf64_write_shdrs_and_ehdr,
4058
  bfd_elf64_checksum_contents,
4059
  mips_elf64_write_relocs,
4060
  bfd_elf64_swap_symbol_in,
4061
  bfd_elf64_swap_symbol_out,
4062
  mips_elf64_slurp_reloc_table,
4063
  bfd_elf64_slurp_symbol_table,
4064
  bfd_elf64_swap_dyn_in,
4065
  bfd_elf64_swap_dyn_out,
4066
  mips_elf64_be_swap_reloc_in,
4067
  mips_elf64_be_swap_reloc_out,
4068
  mips_elf64_be_swap_reloca_in,
4069
  mips_elf64_be_swap_reloca_out
4070
};
4071
 
4072
#define ELF_ARCH                        bfd_arch_mips
4073
#define ELF_TARGET_ID                   MIPS_ELF_DATA
4074
#define ELF_MACHINE_CODE                EM_MIPS
4075
 
4076
#define elf_backend_collect             TRUE
4077
#define elf_backend_type_change_ok      TRUE
4078
#define elf_backend_can_gc_sections     TRUE
4079
#define elf_info_to_howto               mips_elf64_info_to_howto_rela
4080
#define elf_info_to_howto_rel           mips_elf64_info_to_howto_rel
4081
#define elf_backend_object_p            mips_elf64_object_p
4082
#define elf_backend_symbol_processing   _bfd_mips_elf_symbol_processing
4083
#define elf_backend_section_processing  _bfd_mips_elf_section_processing
4084
#define elf_backend_section_from_shdr   _bfd_mips_elf_section_from_shdr
4085
#define elf_backend_fake_sections       _bfd_mips_elf_fake_sections
4086
#define elf_backend_section_from_bfd_section \
4087
                                _bfd_mips_elf_section_from_bfd_section
4088
#define elf_backend_add_symbol_hook     _bfd_mips_elf_add_symbol_hook
4089
#define elf_backend_link_output_symbol_hook \
4090
                                _bfd_mips_elf_link_output_symbol_hook
4091
#define elf_backend_create_dynamic_sections \
4092
                                _bfd_mips_elf_create_dynamic_sections
4093
#define elf_backend_check_relocs        _bfd_mips_elf_check_relocs
4094
#define elf_backend_merge_symbol_attribute \
4095
                                _bfd_mips_elf_merge_symbol_attribute
4096
#define elf_backend_get_target_dtag     _bfd_mips_elf_get_target_dtag
4097
#define elf_backend_adjust_dynamic_symbol \
4098
                                _bfd_mips_elf_adjust_dynamic_symbol
4099
#define elf_backend_always_size_sections \
4100
                                _bfd_mips_elf_always_size_sections
4101
#define elf_backend_size_dynamic_sections \
4102
                                _bfd_mips_elf_size_dynamic_sections
4103
#define elf_backend_init_index_section  _bfd_elf_init_1_index_section
4104
#define elf_backend_relocate_section    _bfd_mips_elf_relocate_section
4105
#define elf_backend_finish_dynamic_symbol \
4106
                                _bfd_mips_elf_finish_dynamic_symbol
4107
#define elf_backend_finish_dynamic_sections \
4108
                                _bfd_mips_elf_finish_dynamic_sections
4109
#define elf_backend_final_write_processing \
4110
                                _bfd_mips_elf_final_write_processing
4111
#define elf_backend_additional_program_headers \
4112
                                _bfd_mips_elf_additional_program_headers
4113
#define elf_backend_modify_segment_map  _bfd_mips_elf_modify_segment_map
4114
#define elf_backend_gc_mark_hook        _bfd_mips_elf_gc_mark_hook
4115
#define elf_backend_gc_sweep_hook       _bfd_mips_elf_gc_sweep_hook
4116
#define elf_backend_copy_indirect_symbol \
4117
                                        _bfd_mips_elf_copy_indirect_symbol
4118
#define elf_backend_ignore_discarded_relocs \
4119
                                        _bfd_mips_elf_ignore_discarded_relocs
4120
#define elf_backend_mips_irix_compat    elf64_mips_irix_compat
4121
#define elf_backend_mips_rtype_to_howto mips_elf64_rtype_to_howto
4122
#define elf_backend_ecoff_debug_swap    &mips_elf64_ecoff_debug_swap
4123
#define elf_backend_size_info           mips_elf64_size_info
4124
 
4125
#define elf_backend_grok_prstatus       elf64_mips_grok_prstatus
4126
#define elf_backend_grok_psinfo         elf64_mips_grok_psinfo
4127
 
4128
#define elf_backend_got_header_size     (4 * MIPS_RESERVED_GOTNO)
4129
 
4130
/* MIPS ELF64 can use a mixture of REL and RELA, but some Relocations
4131
   work better/work only in RELA, so we default to this.  */
4132
#define elf_backend_may_use_rel_p       1
4133
#define elf_backend_may_use_rela_p      1
4134
#define elf_backend_default_use_rela_p  1
4135
#define elf_backend_rela_plts_and_copies_p 0
4136
#define elf_backend_plt_readonly        1
4137
#define elf_backend_plt_sym_val         _bfd_mips_elf_plt_sym_val
4138
 
4139
#define elf_backend_sign_extend_vma     TRUE
4140
 
4141
#define elf_backend_write_section       _bfd_mips_elf_write_section
4142
 
4143
/* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
4144
   MIPS-specific function only applies to IRIX5, which had no 64-bit
4145
   ABI.  */
4146 161 khays
#define bfd_elf64_bfd_is_target_special_symbol \
4147
                                        _bfd_mips_elf_is_target_special_symbol
4148 14 khays
#define bfd_elf64_find_nearest_line     _bfd_mips_elf_find_nearest_line
4149
#define bfd_elf64_find_inliner_info     _bfd_mips_elf_find_inliner_info
4150
#define bfd_elf64_new_section_hook      _bfd_mips_elf_new_section_hook
4151
#define bfd_elf64_set_section_contents  _bfd_mips_elf_set_section_contents
4152
#define bfd_elf64_bfd_get_relocated_section_contents \
4153
                                _bfd_elf_mips_get_relocated_section_contents
4154
#define bfd_elf64_bfd_link_hash_table_create \
4155
                                _bfd_mips_elf_link_hash_table_create
4156
#define bfd_elf64_bfd_final_link        _bfd_mips_elf_final_link
4157
#define bfd_elf64_bfd_merge_private_bfd_data \
4158
                                _bfd_mips_elf_merge_private_bfd_data
4159
#define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
4160
#define bfd_elf64_bfd_print_private_bfd_data \
4161
                                _bfd_mips_elf_print_private_bfd_data
4162
 
4163
#define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
4164
#define bfd_elf64_canonicalize_reloc mips_elf64_canonicalize_reloc
4165
#define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound
4166
#define bfd_elf64_canonicalize_dynamic_reloc mips_elf64_canonicalize_dynamic_reloc
4167
#define bfd_elf64_bfd_relax_section     _bfd_mips_relax_section
4168
 
4169
/* MIPS ELF64 archive functions.  */
4170
#define bfd_elf64_archive_functions
4171
extern bfd_boolean bfd_elf64_archive_slurp_armap
4172
  (bfd *);
4173
extern bfd_boolean bfd_elf64_archive_write_armap
4174
  (bfd *, unsigned int, struct orl *, unsigned int, int);
4175
#define bfd_elf64_archive_slurp_extended_name_table \
4176
                        _bfd_archive_coff_slurp_extended_name_table
4177
#define bfd_elf64_archive_construct_extended_name_table \
4178
                        _bfd_archive_coff_construct_extended_name_table
4179
#define bfd_elf64_archive_truncate_arname \
4180
                        _bfd_archive_coff_truncate_arname
4181
#define bfd_elf64_archive_read_ar_hdr   _bfd_archive_coff_read_ar_hdr
4182
#define bfd_elf64_archive_write_ar_hdr  _bfd_archive_coff_write_ar_hdr
4183
#define bfd_elf64_archive_openr_next_archived_file \
4184
                        _bfd_archive_coff_openr_next_archived_file
4185
#define bfd_elf64_archive_get_elt_at_index \
4186
                        _bfd_archive_coff_get_elt_at_index
4187
#define bfd_elf64_archive_generic_stat_arch_elt \
4188
                        _bfd_archive_coff_generic_stat_arch_elt
4189
#define bfd_elf64_archive_update_armap_timestamp \
4190
                        _bfd_archive_coff_update_armap_timestamp
4191
 
4192
/* The SGI style (n)64 NewABI.  */
4193
#define TARGET_LITTLE_SYM               bfd_elf64_littlemips_vec
4194
#define TARGET_LITTLE_NAME              "elf64-littlemips"
4195
#define TARGET_BIG_SYM                  bfd_elf64_bigmips_vec
4196
#define TARGET_BIG_NAME                 "elf64-bigmips"
4197
 
4198
#define ELF_MAXPAGESIZE                 0x10000
4199
#define ELF_COMMONPAGESIZE              0x1000
4200
 
4201
#include "elf64-target.h"
4202
 
4203
/* The SYSV-style 'traditional' (n)64 NewABI.  */
4204
#undef TARGET_LITTLE_SYM
4205
#undef TARGET_LITTLE_NAME
4206
#undef TARGET_BIG_SYM
4207
#undef TARGET_BIG_NAME
4208
 
4209
#undef ELF_MAXPAGESIZE
4210
#undef ELF_COMMONPAGESIZE
4211
 
4212
#define TARGET_LITTLE_SYM               bfd_elf64_tradlittlemips_vec
4213
#define TARGET_LITTLE_NAME              "elf64-tradlittlemips"
4214
#define TARGET_BIG_SYM                  bfd_elf64_tradbigmips_vec
4215
#define TARGET_BIG_NAME                 "elf64-tradbigmips"
4216
 
4217
#define ELF_MAXPAGESIZE                 0x10000
4218
#define ELF_COMMONPAGESIZE              0x1000
4219
#define elf64_bed                       elf64_tradbed
4220
 
4221
/* Include the target file again for this target.  */
4222
#include "elf64-target.h"
4223
 
4224
 
4225
/* FreeBSD support.  */
4226
 
4227
#undef TARGET_LITTLE_SYM
4228
#undef TARGET_LITTLE_NAME
4229
#undef TARGET_BIG_SYM
4230
#undef TARGET_BIG_NAME
4231
 
4232
#define TARGET_LITTLE_SYM               bfd_elf64_tradlittlemips_freebsd_vec
4233
#define TARGET_LITTLE_NAME              "elf64-tradlittlemips-freebsd"
4234
#define TARGET_BIG_SYM                  bfd_elf64_tradbigmips_freebsd_vec
4235
#define TARGET_BIG_NAME                 "elf64-tradbigmips-freebsd"
4236
 
4237
#undef  ELF_OSABI
4238
#define ELF_OSABI                       ELFOSABI_FREEBSD
4239
 
4240
/* The kernel recognizes executables as valid only if they carry a
4241
   "FreeBSD" label in the ELF header.  So we put this label on all
4242
   executables and (for simplicity) also all other object files.  */
4243
 
4244
static void
4245
elf_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info)
4246
{
4247
  _bfd_elf_set_osabi (abfd, info);
4248
}
4249
 
4250
#undef  elf_backend_post_process_headers
4251
#define elf_backend_post_process_headers        elf_fbsd_post_process_headers
4252
#undef  elf64_bed
4253
#define elf64_bed                               elf64_fbsd_tradbed
4254
 
4255
#include "elf64-target.h"

powered by: WebSVN 2.1.0

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