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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [bfd/] [elf64-mips.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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