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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* MIPS-specific support for 64-bit ELF
2
   Copyright 1996, 1997, 1998, 1999, 2000, 2001
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
   The MIPS 64-bit ELF ABI also uses an unusual archive map format.  */
31
 
32
#include "bfd.h"
33
#include "sysdep.h"
34
#include "libbfd.h"
35
#include "aout/ar.h"
36
#include "bfdlink.h"
37
#include "genlink.h"
38
#include "elf-bfd.h"
39
#include "elf/mips.h"
40
 
41
/* Get the ECOFF swapping routines.  The 64-bit ABI is not supposed to
42
   use ECOFF.  However, we support it anyhow for an easier changeover.  */
43
#include "coff/sym.h"
44
#include "coff/symconst.h"
45
#include "coff/internal.h"
46
#include "coff/ecoff.h"
47
/* The 64 bit versions of the mdebug data structures are in alpha.h.  */
48
#include "coff/alpha.h"
49
#define ECOFF_SIGNED_64
50
#include "ecoffswap.h"
51
 
52
static void mips_elf64_swap_reloc_in
53
  PARAMS ((bfd *, const Elf64_Mips_External_Rel *,
54
           Elf64_Mips_Internal_Rel *));
55
static void mips_elf64_swap_reloca_in
56
  PARAMS ((bfd *, const Elf64_Mips_External_Rela *,
57
           Elf64_Mips_Internal_Rela *));
58
static void mips_elf64_swap_reloc_out
59
  PARAMS ((bfd *, const Elf64_Mips_Internal_Rel *,
60
           Elf64_Mips_External_Rel *));
61
static void mips_elf64_swap_reloca_out
62
  PARAMS ((bfd *, const Elf64_Mips_Internal_Rela *,
63
           Elf64_Mips_External_Rela *));
64
static void mips_elf64_be_swap_reloc_in
65
  PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rel *));
66
static void mips_elf64_be_swap_reloc_out
67
  PARAMS ((bfd *, const Elf_Internal_Rel *, bfd_byte *));
68
static void mips_elf64_be_swap_reloca_in
69
  PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *));
70
static void mips_elf64_be_swap_reloca_out
71
  PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *));
72
static reloc_howto_type *mips_elf64_reloc_type_lookup
73
  PARAMS ((bfd *, bfd_reloc_code_real_type));
74
static long mips_elf64_get_reloc_upper_bound PARAMS ((bfd *, asection *));
75
static boolean mips_elf64_slurp_one_reloc_table
76
  PARAMS ((bfd *, asection *, asymbol **, const Elf_Internal_Shdr *));
77
static boolean mips_elf64_slurp_reloc_table
78
  PARAMS ((bfd *, asection *, asymbol **, boolean));
79
static void mips_elf64_write_relocs PARAMS ((bfd *, asection *, PTR));
80
static boolean mips_elf64_slurp_armap PARAMS ((bfd *));
81
static boolean mips_elf64_write_armap
82
  PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
83
 
84
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
85
   from smaller values.  Start with zero, widen, *then* decrement.  */
86
#define MINUS_ONE       (((bfd_vma)0) - 1)
87
 
88
/* The number of local .got entries we reserve.  */
89
#define MIPS_RESERVED_GOTNO (2)
90
 
91
/* The relocation table used for SHT_REL sections.  */
92
 
93
static reloc_howto_type mips_elf64_howto_table_rel[] =
94
{
95
  /* No relocation.  */
96
  HOWTO (R_MIPS_NONE,           /* type */
97
         0,                      /* rightshift */
98
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
99
         0,                      /* bitsize */
100
         false,                 /* pc_relative */
101
         0,                      /* bitpos */
102
         complain_overflow_dont, /* complain_on_overflow */
103
         bfd_elf_generic_reloc, /* special_function */
104
         "R_MIPS_NONE",         /* name */
105
         false,                 /* partial_inplace */
106
         0,                      /* src_mask */
107
         0,                      /* dst_mask */
108
         false),                /* pcrel_offset */
109
 
110
  /* 16 bit relocation.  */
111
  HOWTO (R_MIPS_16,             /* type */
112
         0,                      /* rightshift */
113
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
114
         16,                    /* bitsize */
115
         false,                 /* pc_relative */
116
         0,                      /* bitpos */
117
         complain_overflow_bitfield, /* complain_on_overflow */
118
         bfd_elf_generic_reloc, /* special_function */
119
         "R_MIPS_16",           /* name */
120
         true,                  /* partial_inplace */
121
         0xffff,                /* src_mask */
122
         0xffff,                /* dst_mask */
123
         false),                /* pcrel_offset */
124
 
125
  /* 32 bit relocation.  */
126
  HOWTO (R_MIPS_32,             /* type */
127
         0,                      /* rightshift */
128
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
129
         32,                    /* bitsize */
130
         false,                 /* pc_relative */
131
         0,                      /* bitpos */
132
         complain_overflow_bitfield, /* complain_on_overflow */
133
         bfd_elf_generic_reloc, /* special_function */
134
         "R_MIPS_32",           /* name */
135
         true,                  /* partial_inplace */
136
         0xffffffff,            /* src_mask */
137
         0xffffffff,            /* dst_mask */
138
         false),                /* pcrel_offset */
139
 
140
  /* 32 bit symbol relative relocation.  */
141
  HOWTO (R_MIPS_REL32,          /* type */
142
         0,                      /* rightshift */
143
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
144
         32,                    /* bitsize */
145
         false,                 /* pc_relative */
146
         0,                      /* bitpos */
147
         complain_overflow_bitfield, /* complain_on_overflow */
148
         bfd_elf_generic_reloc, /* special_function */
149
         "R_MIPS_REL32",        /* name */
150
         true,                  /* partial_inplace */
151
         0xffffffff,            /* src_mask */
152
         0xffffffff,            /* dst_mask */
153
         false),                /* pcrel_offset */
154
 
155
  /* 26 bit branch address.  */
156
  HOWTO (R_MIPS_26,             /* type */
157
         2,                     /* rightshift */
158
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
159
         26,                    /* bitsize */
160
         false,                 /* pc_relative */
161
         0,                      /* bitpos */
162
         complain_overflow_dont, /* complain_on_overflow */
163
                                /* This needs complex overflow
164
                                   detection, because the upper four
165
                                   bits must match the PC + 4.  */
166
         bfd_elf_generic_reloc, /* special_function */
167
         "R_MIPS_26",           /* name */
168
         true,                  /* partial_inplace */
169
         0x3ffffff,             /* src_mask */
170
         0x3ffffff,             /* dst_mask */
171
         false),                /* pcrel_offset */
172
 
173
  /* High 16 bits of symbol value.  */
174
  HOWTO (R_MIPS_HI16,           /* type */
175
         0,                      /* rightshift */
176
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
177
         16,                    /* bitsize */
178
         false,                 /* pc_relative */
179
         0,                      /* bitpos */
180
         complain_overflow_dont, /* complain_on_overflow */
181
         _bfd_mips_elf_hi16_reloc,      /* special_function */
182
         "R_MIPS_HI16",         /* name */
183
         true,                  /* partial_inplace */
184
         0xffff,                /* src_mask */
185
         0xffff,                /* dst_mask */
186
         false),                /* pcrel_offset */
187
 
188
  /* Low 16 bits of symbol value.  */
189
  HOWTO (R_MIPS_LO16,           /* type */
190
         0,                      /* rightshift */
191
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
192
         16,                    /* bitsize */
193
         false,                 /* pc_relative */
194
         0,                      /* bitpos */
195
         complain_overflow_dont, /* complain_on_overflow */
196
         _bfd_mips_elf_lo16_reloc,      /* special_function */
197
         "R_MIPS_LO16",         /* name */
198
         true,                  /* partial_inplace */
199
         0xffff,                /* src_mask */
200
         0xffff,                /* dst_mask */
201
         false),                /* pcrel_offset */
202
 
203
  /* GP relative reference.  */
204
  HOWTO (R_MIPS_GPREL16,        /* type */
205
         0,                      /* rightshift */
206
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
207
         16,                    /* bitsize */
208
         false,                 /* pc_relative */
209
         0,                      /* bitpos */
210
         complain_overflow_signed, /* complain_on_overflow */
211
         _bfd_mips_elf_gprel16_reloc, /* special_function */
212
         "R_MIPS_GPREL16",      /* name */
213
         true,                  /* partial_inplace */
214
         0xffff,                /* src_mask */
215
         0xffff,                /* dst_mask */
216
         false),                /* pcrel_offset */
217
 
218
  /* Reference to literal section.  */
219
  HOWTO (R_MIPS_LITERAL,        /* type */
220
         0,                      /* rightshift */
221
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
222
         16,                    /* bitsize */
223
         false,                 /* pc_relative */
224
         0,                      /* bitpos */
225
         complain_overflow_signed, /* complain_on_overflow */
226
         _bfd_mips_elf_gprel16_reloc, /* special_function */
227
         "R_MIPS_LITERAL",      /* name */
228
         true,                  /* partial_inplace */
229
         0xffff,                /* src_mask */
230
         0xffff,                /* dst_mask */
231
         false),                /* pcrel_offset */
232
 
233
  /* Reference to global offset table.  */
234
  HOWTO (R_MIPS_GOT16,          /* type */
235
         0,                      /* rightshift */
236
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
237
         16,                    /* bitsize */
238
         false,                 /* pc_relative */
239
         0,                      /* bitpos */
240
         complain_overflow_signed, /* complain_on_overflow */
241
         _bfd_mips_elf_got16_reloc,     /* special_function */
242
         "R_MIPS_GOT16",        /* name */
243
         false,                 /* partial_inplace */
244
         0,                      /* src_mask */
245
         0xffff,                /* dst_mask */
246
         false),                /* pcrel_offset */
247
 
248
  /* 16 bit PC relative reference.  */
249
  HOWTO (R_MIPS_PC16,           /* type */
250
         0,                      /* rightshift */
251
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
252
         16,                    /* bitsize */
253
         true,                  /* pc_relative */
254
         0,                      /* bitpos */
255
         complain_overflow_signed, /* complain_on_overflow */
256
         bfd_elf_generic_reloc, /* special_function */
257
         "R_MIPS_PC16",         /* name */
258
         true,                  /* partial_inplace */
259
         0xffff,                /* src_mask */
260
         0xffff,                /* dst_mask */
261
         false),                /* pcrel_offset */
262
 
263
  /* 16 bit call through global offset table.  */
264
  /* FIXME: This is not handled correctly.  */
265
  HOWTO (R_MIPS_CALL16,         /* 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
         bfd_elf_generic_reloc, /* special_function */
273
         "R_MIPS_CALL16",       /* name */
274
         false,                 /* partial_inplace */
275
         0,                      /* src_mask */
276
         0xffff,                /* dst_mask */
277
         false),                /* pcrel_offset */
278
 
279
  /* 32 bit GP relative reference.  */
280
  HOWTO (R_MIPS_GPREL32,        /* type */
281
         0,                      /* rightshift */
282
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
283
         32,                    /* bitsize */
284
         false,                 /* pc_relative */
285
         0,                      /* bitpos */
286
         complain_overflow_bitfield, /* complain_on_overflow */
287
         _bfd_mips_elf_gprel32_reloc, /* special_function */
288
         "R_MIPS_GPREL32",      /* name */
289
         true,                  /* partial_inplace */
290
         0xffffffff,            /* src_mask */
291
         0xffffffff,            /* dst_mask */
292
         false),                /* pcrel_offset */
293
 
294
    { 13 },
295
    { 14 },
296
    { 15 },
297
 
298
  /* A 5 bit shift field.  */
299
  HOWTO (R_MIPS_SHIFT5,         /* type */
300
         0,                      /* rightshift */
301
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
302
         5,                     /* bitsize */
303
         false,                 /* pc_relative */
304
         6,                     /* bitpos */
305
         complain_overflow_bitfield, /* complain_on_overflow */
306
         bfd_elf_generic_reloc, /* special_function */
307
         "R_MIPS_SHIFT5",       /* name */
308
         true,                  /* partial_inplace */
309
         0x000007c0,            /* src_mask */
310
         0x000007c0,            /* dst_mask */
311
         false),                /* pcrel_offset */
312
 
313
  /* A 6 bit shift field.  */
314
  /* FIXME: This is not handled correctly; a special function is
315
     needed to put the most significant bit in the right place.  */
316
  HOWTO (R_MIPS_SHIFT6,         /* type */
317
         0,                      /* rightshift */
318
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
319
         6,                     /* bitsize */
320
         false,                 /* pc_relative */
321
         6,                     /* bitpos */
322
         complain_overflow_bitfield, /* complain_on_overflow */
323
         bfd_elf_generic_reloc, /* special_function */
324
         "R_MIPS_SHIFT6",       /* name */
325
         true,                  /* partial_inplace */
326
         0x000007c4,            /* src_mask */
327
         0x000007c4,            /* dst_mask */
328
         false),                /* pcrel_offset */
329
 
330
  /* 64 bit relocation.  */
331
  HOWTO (R_MIPS_64,             /* type */
332
         0,                      /* rightshift */
333
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
334
         64,                    /* bitsize */
335
         false,                 /* pc_relative */
336
         0,                      /* bitpos */
337
         complain_overflow_bitfield, /* complain_on_overflow */
338
         bfd_elf_generic_reloc, /* special_function */
339
         "R_MIPS_64",           /* name */
340
         true,                  /* partial_inplace */
341
         MINUS_ONE,             /* src_mask */
342
         MINUS_ONE,             /* dst_mask */
343
         false),                /* pcrel_offset */
344
 
345
  /* Displacement in the global offset table.  */
346
  /* FIXME: Not handled correctly.  */
347
  HOWTO (R_MIPS_GOT_DISP,       /* type */
348
         0,                      /* rightshift */
349
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
350
         16,                    /* bitsize */
351
         false,                 /* pc_relative */
352
         0,                      /* bitpos */
353
         complain_overflow_bitfield, /* complain_on_overflow */
354
         bfd_elf_generic_reloc, /* special_function */
355
         "R_MIPS_GOT_DISP",     /* name */
356
         true,                  /* partial_inplace */
357
         0x0000ffff,            /* src_mask */
358
         0x0000ffff,            /* dst_mask */
359
         false),                /* pcrel_offset */
360
 
361
  /* Displacement to page pointer in the global offset table.  */
362
  /* FIXME: Not handled correctly.  */
363
  HOWTO (R_MIPS_GOT_PAGE,       /* type */
364
         0,                      /* rightshift */
365
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
366
         16,                    /* bitsize */
367
         false,                 /* pc_relative */
368
         0,                      /* bitpos */
369
         complain_overflow_bitfield, /* complain_on_overflow */
370
         bfd_elf_generic_reloc, /* special_function */
371
         "R_MIPS_GOT_PAGE",     /* name */
372
         true,                  /* partial_inplace */
373
         0x0000ffff,            /* src_mask */
374
         0x0000ffff,            /* dst_mask */
375
         false),                /* pcrel_offset */
376
 
377
  /* Offset from page pointer in the global offset table.  */
378
  /* FIXME: Not handled correctly.  */
379
  HOWTO (R_MIPS_GOT_OFST,       /* type */
380
         0,                      /* rightshift */
381
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
382
         16,                    /* bitsize */
383
         false,                 /* pc_relative */
384
         0,                      /* bitpos */
385
         complain_overflow_bitfield, /* complain_on_overflow */
386
         bfd_elf_generic_reloc, /* special_function */
387
         "R_MIPS_GOT_OFST",     /* name */
388
         true,                  /* partial_inplace */
389
         0x0000ffff,            /* src_mask */
390
         0x0000ffff,            /* dst_mask */
391
         false),                /* pcrel_offset */
392
 
393
  /* High 16 bits of displacement in global offset table.  */
394
  /* FIXME: Not handled correctly.  */
395
  HOWTO (R_MIPS_GOT_HI16,       /* type */
396
         0,                      /* rightshift */
397
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
398
         16,                    /* bitsize */
399
         false,                 /* pc_relative */
400
         0,                      /* bitpos */
401
         complain_overflow_dont, /* complain_on_overflow */
402
         bfd_elf_generic_reloc, /* special_function */
403
         "R_MIPS_GOT_HI16",     /* name */
404
         true,                  /* partial_inplace */
405
         0x0000ffff,            /* src_mask */
406
         0x0000ffff,            /* dst_mask */
407
         false),                /* pcrel_offset */
408
 
409
  /* Low 16 bits of displacement in global offset table.  */
410
  /* FIXME: Not handled correctly.  */
411
  HOWTO (R_MIPS_GOT_LO16,       /* type */
412
         0,                      /* rightshift */
413
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
414
         16,                    /* bitsize */
415
         false,                 /* pc_relative */
416
         0,                      /* bitpos */
417
         complain_overflow_dont, /* complain_on_overflow */
418
         bfd_elf_generic_reloc, /* special_function */
419
         "R_MIPS_GOT_LO16",     /* name */
420
         true,                  /* partial_inplace */
421
         0x0000ffff,            /* src_mask */
422
         0x0000ffff,            /* dst_mask */
423
         false),                /* pcrel_offset */
424
 
425
  /* 64 bit substraction.  */
426
  /* FIXME: Not handled correctly.  */
427
  HOWTO (R_MIPS_SUB,            /* type */
428
         0,                      /* rightshift */
429
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
430
         64,                    /* bitsize */
431
         false,                 /* pc_relative */
432
         0,                      /* bitpos */
433
         complain_overflow_bitfield, /* complain_on_overflow */
434
         bfd_elf_generic_reloc, /* special_function */
435
         "R_MIPS_SUB",          /* name */
436
         true,                  /* partial_inplace */
437
         MINUS_ONE,             /* src_mask */
438
         MINUS_ONE,             /* dst_mask */
439
         false),                /* pcrel_offset */
440
 
441
  /* Insert the addend as an instruction.  */
442
  /* FIXME: Not handled correctly.  */
443
  HOWTO (R_MIPS_INSERT_A,       /* type */
444
         0,                      /* rightshift */
445
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
446
         0,                      /* bitsize */
447
         false,                 /* pc_relative */
448
         0,                      /* bitpos */
449
         complain_overflow_dont, /* complain_on_overflow */
450
         bfd_elf_generic_reloc, /* special_function */
451
         "R_MIPS_INSERT_A",     /* name */
452
         false,                 /* partial_inplace */
453
         0,                      /* src_mask */
454
         0,                      /* dst_mask */
455
         false),                /* pcrel_offset */
456
 
457
  /* Insert the addend as an instruction, and change all relocations
458
     to refer to the old instruction at the address.  */
459
  /* FIXME: Not handled correctly.  */
460
  HOWTO (R_MIPS_INSERT_B,       /* type */
461
         0,                      /* rightshift */
462
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
463
         0,                      /* bitsize */
464
         false,                 /* pc_relative */
465
         0,                      /* bitpos */
466
         complain_overflow_dont, /* complain_on_overflow */
467
         bfd_elf_generic_reloc, /* special_function */
468
         "R_MIPS_INSERT_B",     /* name */
469
         false,                 /* partial_inplace */
470
         0,                      /* src_mask */
471
         0,                      /* dst_mask */
472
         false),                /* pcrel_offset */
473
 
474
  /* Delete a 32 bit instruction.  */
475
  /* FIXME: Not handled correctly.  */
476
  HOWTO (R_MIPS_DELETE,         /* type */
477
         0,                      /* rightshift */
478
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
479
         0,                      /* bitsize */
480
         false,                 /* pc_relative */
481
         0,                      /* bitpos */
482
         complain_overflow_dont, /* complain_on_overflow */
483
         bfd_elf_generic_reloc, /* special_function */
484
         "R_MIPS_DELETE",       /* name */
485
         false,                 /* partial_inplace */
486
         0,                      /* src_mask */
487
         0,                      /* dst_mask */
488
         false),                /* pcrel_offset */
489
 
490
  /* Get the higher value of a 64 bit addend.  */
491
  /* FIXME: Not handled correctly.  */
492
  HOWTO (R_MIPS_HIGHER,         /* type */
493
         0,                      /* rightshift */
494
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
495
         16,                    /* bitsize */
496
         false,                 /* pc_relative */
497
         0,                      /* bitpos */
498
         complain_overflow_dont, /* complain_on_overflow */
499
         bfd_elf_generic_reloc, /* special_function */
500
         "R_MIPS_HIGHER",       /* name */
501
         true,                  /* partial_inplace */
502
         0xffff,                /* src_mask */
503
         0xffff,                /* dst_mask */
504
         false),                /* pcrel_offset */
505
 
506
  /* Get the highest value of a 64 bit addend.  */
507
  /* FIXME: Not handled correctly.  */
508
  HOWTO (R_MIPS_HIGHEST,        /* type */
509
         0,                      /* rightshift */
510
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
511
         16,                    /* bitsize */
512
         false,                 /* pc_relative */
513
         0,                      /* bitpos */
514
         complain_overflow_dont, /* complain_on_overflow */
515
         bfd_elf_generic_reloc, /* special_function */
516
         "R_MIPS_HIGHEST",      /* name */
517
         true,                  /* partial_inplace */
518
         0xffff,                /* src_mask */
519
         0xffff,                /* dst_mask */
520
         false),                /* pcrel_offset */
521
 
522
  /* High 16 bits of displacement in global offset table.  */
523
  /* FIXME: Not handled correctly.  */
524
  HOWTO (R_MIPS_CALL_HI16,      /* type */
525
         0,                      /* rightshift */
526
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
527
         16,                    /* bitsize */
528
         false,                 /* pc_relative */
529
         0,                      /* bitpos */
530
         complain_overflow_dont, /* complain_on_overflow */
531
         bfd_elf_generic_reloc, /* special_function */
532
         "R_MIPS_CALL_HI16",    /* name */
533
         true,                  /* partial_inplace */
534
         0x0000ffff,            /* src_mask */
535
         0x0000ffff,            /* dst_mask */
536
         false),                /* pcrel_offset */
537
 
538
  /* Low 16 bits of displacement in global offset table.  */
539
  /* FIXME: Not handled correctly.  */
540
  HOWTO (R_MIPS_CALL_LO16,      /* type */
541
         0,                      /* rightshift */
542
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
543
         16,                    /* bitsize */
544
         false,                 /* pc_relative */
545
         0,                      /* bitpos */
546
         complain_overflow_dont, /* complain_on_overflow */
547
         bfd_elf_generic_reloc, /* special_function */
548
         "R_MIPS_CALL_LO16",    /* name */
549
         true,                  /* partial_inplace */
550
         0x0000ffff,            /* src_mask */
551
         0x0000ffff,            /* dst_mask */
552
         false),                /* pcrel_offset */
553
 
554
  /* I'm not sure what the remaining relocs are, but they are defined
555
     on Irix 6.  */
556
 
557
  HOWTO (R_MIPS_SCN_DISP,       /* type */
558
         0,                      /* rightshift */
559
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
560
         0,                      /* bitsize */
561
         false,                 /* pc_relative */
562
         0,                      /* bitpos */
563
         complain_overflow_dont, /* complain_on_overflow */
564
         bfd_elf_generic_reloc, /* special_function */
565
         "R_MIPS_SCN_DISP",     /* name */
566
         false,                 /* partial_inplace */
567
         0,                      /* src_mask */
568
         0,                      /* dst_mask */
569
         false),                /* pcrel_offset */
570
 
571
  HOWTO (R_MIPS_REL16,          /* type */
572
         0,                      /* rightshift */
573
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
574
         0,                      /* bitsize */
575
         false,                 /* pc_relative */
576
         0,                      /* bitpos */
577
         complain_overflow_dont, /* complain_on_overflow */
578
         bfd_elf_generic_reloc, /* special_function */
579
         "R_MIPS_REL16",        /* name */
580
         false,                 /* partial_inplace */
581
         0,                      /* src_mask */
582
         0,                      /* dst_mask */
583
         false),                /* pcrel_offset */
584
 
585
  HOWTO (R_MIPS_ADD_IMMEDIATE,  /* type */
586
         0,                      /* rightshift */
587
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
588
         0,                      /* bitsize */
589
         false,                 /* pc_relative */
590
         0,                      /* bitpos */
591
         complain_overflow_dont, /* complain_on_overflow */
592
         bfd_elf_generic_reloc, /* special_function */
593
         "R_MIPS_ADD_IMMEDIATE", /* name */
594
         false,                 /* partial_inplace */
595
         0,                      /* src_mask */
596
         0,                      /* dst_mask */
597
         false),                /* pcrel_offset */
598
 
599
  HOWTO (R_MIPS_PJUMP,          /* type */
600
         0,                      /* rightshift */
601
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
602
         0,                      /* bitsize */
603
         false,                 /* pc_relative */
604
         0,                      /* bitpos */
605
         complain_overflow_dont, /* complain_on_overflow */
606
         bfd_elf_generic_reloc, /* special_function */
607
         "R_MIPS_PJUMP",        /* name */
608
         false,                 /* partial_inplace */
609
         0,                      /* src_mask */
610
         0,                      /* dst_mask */
611
         false),                /* pcrel_offset */
612
 
613
  HOWTO (R_MIPS_RELGOT,         /* type */
614
         0,                      /* rightshift */
615
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
616
         0,                      /* bitsize */
617
         false,                 /* pc_relative */
618
         0,                      /* bitpos */
619
         complain_overflow_dont, /* complain_on_overflow */
620
         bfd_elf_generic_reloc, /* special_function */
621
         "R_MIPS_RELGOT",       /* name */
622
         false,                 /* partial_inplace */
623
         0,                      /* src_mask */
624
         0,                      /* dst_mask */
625
         false),                /* pcrel_offset */
626
 
627
  /* Protected jump conversion.  This is an optimization hint.  No
628
     relocation is required for correctness.  */
629
  HOWTO (R_MIPS_JALR,           /* type */
630
         0,                      /* rightshift */
631
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
632
         0,                      /* bitsize */
633
         false,                 /* pc_relative */
634
         0,                      /* bitpos */
635
         complain_overflow_dont, /* complain_on_overflow */
636
         bfd_elf_generic_reloc, /* special_function */
637
         "R_MIPS_JALR",         /* name */
638
         false,                 /* partial_inplace */
639
         0x00000000,            /* src_mask */
640
         0x00000000,            /* dst_mask */
641
         false),                /* pcrel_offset */
642
};
643
 
644
/* The relocation table used for SHT_RELA sections.  */
645
 
646
static reloc_howto_type mips_elf64_howto_table_rela[] =
647
{
648
  /* No relocation.  */
649
  HOWTO (R_MIPS_NONE,           /* type */
650
         0,                      /* rightshift */
651
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
652
         0,                      /* bitsize */
653
         false,                 /* pc_relative */
654
         0,                      /* bitpos */
655
         complain_overflow_dont, /* complain_on_overflow */
656
         bfd_elf_generic_reloc, /* special_function */
657
         "R_MIPS_NONE",         /* name */
658
         false,                 /* partial_inplace */
659
         0,                      /* src_mask */
660
         0,                      /* dst_mask */
661
         false),                /* pcrel_offset */
662
 
663
  /* 16 bit relocation.  */
664
  HOWTO (R_MIPS_16,             /* type */
665
         0,                      /* rightshift */
666
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
667
         16,                    /* bitsize */
668
         false,                 /* pc_relative */
669
         0,                      /* bitpos */
670
         complain_overflow_bitfield, /* complain_on_overflow */
671
         bfd_elf_generic_reloc, /* special_function */
672
         "R_MIPS_16",           /* name */
673
         true,                  /* partial_inplace */
674
         0,                      /* src_mask */
675
         0xffff,                /* dst_mask */
676
         false),                /* pcrel_offset */
677
 
678
  /* 32 bit relocation.  */
679
  HOWTO (R_MIPS_32,             /* type */
680
         0,                      /* rightshift */
681
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
682
         32,                    /* bitsize */
683
         false,                 /* pc_relative */
684
         0,                      /* bitpos */
685
         complain_overflow_bitfield, /* complain_on_overflow */
686
         bfd_elf_generic_reloc, /* special_function */
687
         "R_MIPS_32",           /* name */
688
         true,                  /* partial_inplace */
689
         0,                      /* src_mask */
690
         0xffffffff,            /* dst_mask */
691
         false),                /* pcrel_offset */
692
 
693
  /* 32 bit symbol relative relocation.  */
694
  HOWTO (R_MIPS_REL32,          /* type */
695
         0,                      /* rightshift */
696
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
697
         32,                    /* bitsize */
698
         false,                 /* pc_relative */
699
         0,                      /* bitpos */
700
         complain_overflow_bitfield, /* complain_on_overflow */
701
         bfd_elf_generic_reloc, /* special_function */
702
         "R_MIPS_REL32",        /* name */
703
         true,                  /* partial_inplace */
704
         0,                      /* src_mask */
705
         0xffffffff,            /* dst_mask */
706
         false),                /* pcrel_offset */
707
 
708
  /* 26 bit branch address.  */
709
  HOWTO (R_MIPS_26,             /* type */
710
         2,                     /* rightshift */
711
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
712
         26,                    /* bitsize */
713
         false,                 /* pc_relative */
714
         0,                      /* bitpos */
715
         complain_overflow_dont, /* complain_on_overflow */
716
                                /* This needs complex overflow
717
                                   detection, because the upper four
718
                                   bits must match the PC + 4.  */
719
         bfd_elf_generic_reloc, /* special_function */
720
         "R_MIPS_26",           /* name */
721
         true,                  /* partial_inplace */
722
         0,                      /* src_mask */
723
         0x3ffffff,             /* dst_mask */
724
         false),                /* pcrel_offset */
725
 
726
  /* High 16 bits of symbol value.  */
727
  HOWTO (R_MIPS_HI16,           /* type */
728
         0,                      /* rightshift */
729
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
730
         16,                    /* bitsize */
731
         false,                 /* pc_relative */
732
         0,                      /* bitpos */
733
         complain_overflow_dont, /* complain_on_overflow */
734
         bfd_elf_generic_reloc, /* special_function */
735
         "R_MIPS_HI16",         /* name */
736
         true,                  /* partial_inplace */
737
         0,                      /* src_mask */
738
         0xffff,                /* dst_mask */
739
         false),                /* pcrel_offset */
740
 
741
  /* Low 16 bits of symbol value.  */
742
  HOWTO (R_MIPS_LO16,           /* type */
743
         0,                      /* rightshift */
744
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
745
         16,                    /* bitsize */
746
         false,                 /* pc_relative */
747
         0,                      /* bitpos */
748
         complain_overflow_dont, /* complain_on_overflow */
749
         bfd_elf_generic_reloc, /* special_function */
750
         "R_MIPS_LO16",         /* name */
751
         true,                  /* partial_inplace */
752
         0,                      /* src_mask */
753
         0xffff,                /* dst_mask */
754
         false),                /* pcrel_offset */
755
 
756
  /* GP relative reference.  */
757
  HOWTO (R_MIPS_GPREL16,        /* type */
758
         0,                      /* rightshift */
759
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
760
         16,                    /* bitsize */
761
         false,                 /* pc_relative */
762
         0,                      /* bitpos */
763
         complain_overflow_signed, /* complain_on_overflow */
764
         _bfd_mips_elf_gprel16_reloc, /* special_function */
765
         "R_MIPS_GPREL16",      /* name */
766
         true,                  /* partial_inplace */
767
         0,                      /* src_mask */
768
         0xffff,                /* dst_mask */
769
         false),                /* pcrel_offset */
770
 
771
  /* Reference to literal section.  */
772
  HOWTO (R_MIPS_LITERAL,        /* type */
773
         0,                      /* rightshift */
774
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
775
         16,                    /* bitsize */
776
         false,                 /* pc_relative */
777
         0,                      /* bitpos */
778
         complain_overflow_signed, /* complain_on_overflow */
779
         _bfd_mips_elf_gprel16_reloc, /* special_function */
780
         "R_MIPS_LITERAL",      /* name */
781
         true,                  /* partial_inplace */
782
         0,                      /* src_mask */
783
         0xffff,                /* dst_mask */
784
         false),                /* pcrel_offset */
785
 
786
  /* Reference to global offset table.  */
787
  /* FIXME: This is not handled correctly.  */
788
  HOWTO (R_MIPS_GOT16,          /* type */
789
         0,                      /* rightshift */
790
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
791
         16,                    /* bitsize */
792
         false,                 /* pc_relative */
793
         0,                      /* bitpos */
794
         complain_overflow_signed, /* complain_on_overflow */
795
         bfd_elf_generic_reloc, /* special_function */
796
         "R_MIPS_GOT16",        /* name */
797
         false,                 /* partial_inplace */
798
         0,                      /* src_mask */
799
         0xffff,                /* dst_mask */
800
         false),                /* pcrel_offset */
801
 
802
  /* 16 bit PC relative reference.  */
803
  HOWTO (R_MIPS_PC16,           /* type */
804
         0,                      /* rightshift */
805
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
806
         16,                    /* bitsize */
807
         true,                  /* pc_relative */
808
         0,                      /* bitpos */
809
         complain_overflow_signed, /* complain_on_overflow */
810
         bfd_elf_generic_reloc, /* special_function */
811
         "R_MIPS_PC16",         /* name */
812
         true,                  /* partial_inplace */
813
         0,                      /* src_mask */
814
         0xffff,                /* dst_mask */
815
         false),                /* pcrel_offset */
816
 
817
  /* 16 bit call through global offset table.  */
818
  /* FIXME: This is not handled correctly.  */
819
  HOWTO (R_MIPS_CALL16,         /* type */
820
         0,                      /* rightshift */
821
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
822
         16,                    /* bitsize */
823
         false,                 /* pc_relative */
824
         0,                      /* bitpos */
825
         complain_overflow_signed, /* complain_on_overflow */
826
         bfd_elf_generic_reloc, /* special_function */
827
         "R_MIPS_CALL16",       /* name */
828
         false,                 /* partial_inplace */
829
         0,                      /* src_mask */
830
         0xffff,                /* dst_mask */
831
         false),                /* pcrel_offset */
832
 
833
  /* 32 bit GP relative reference.  */
834
  HOWTO (R_MIPS_GPREL32,        /* type */
835
         0,                      /* rightshift */
836
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
837
         32,                    /* bitsize */
838
         false,                 /* pc_relative */
839
         0,                      /* bitpos */
840
         complain_overflow_bitfield, /* complain_on_overflow */
841
         _bfd_mips_elf_gprel32_reloc, /* special_function */
842
         "R_MIPS_GPREL32",      /* name */
843
         true,                  /* partial_inplace */
844
         0,                      /* src_mask */
845
         0xffffffff,            /* dst_mask */
846
         false),                /* pcrel_offset */
847
 
848
    { 13 },
849
    { 14 },
850
    { 15 },
851
 
852
  /* A 5 bit shift field.  */
853
  HOWTO (R_MIPS_SHIFT5,         /* type */
854
         0,                      /* rightshift */
855
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
856
         5,                     /* bitsize */
857
         false,                 /* pc_relative */
858
         6,                     /* bitpos */
859
         complain_overflow_bitfield, /* complain_on_overflow */
860
         bfd_elf_generic_reloc, /* special_function */
861
         "R_MIPS_SHIFT5",       /* name */
862
         true,                  /* partial_inplace */
863
         0,                      /* src_mask */
864
         0x000007c0,            /* dst_mask */
865
         false),                /* pcrel_offset */
866
 
867
  /* A 6 bit shift field.  */
868
  /* FIXME: This is not handled correctly; a special function is
869
     needed to put the most significant bit in the right place.  */
870
  HOWTO (R_MIPS_SHIFT6,         /* type */
871
         0,                      /* rightshift */
872
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
873
         6,                     /* bitsize */
874
         false,                 /* pc_relative */
875
         6,                     /* bitpos */
876
         complain_overflow_bitfield, /* complain_on_overflow */
877
         bfd_elf_generic_reloc, /* special_function */
878
         "R_MIPS_SHIFT6",       /* name */
879
         true,                  /* partial_inplace */
880
         0,                      /* src_mask */
881
         0x000007c4,            /* dst_mask */
882
         false),                /* pcrel_offset */
883
 
884
  /* 64 bit relocation.  */
885
  HOWTO (R_MIPS_64,             /* type */
886
         0,                      /* rightshift */
887
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
888
         64,                    /* bitsize */
889
         false,                 /* pc_relative */
890
         0,                      /* bitpos */
891
         complain_overflow_bitfield, /* complain_on_overflow */
892
         bfd_elf_generic_reloc, /* special_function */
893
         "R_MIPS_64",           /* name */
894
         true,                  /* partial_inplace */
895
         0,                      /* src_mask */
896
         MINUS_ONE,             /* dst_mask */
897
         false),                /* pcrel_offset */
898
 
899
  /* Displacement in the global offset table.  */
900
  /* FIXME: Not handled correctly.  */
901
  HOWTO (R_MIPS_GOT_DISP,       /* type */
902
         0,                      /* rightshift */
903
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
904
         16,                    /* bitsize */
905
         false,                 /* pc_relative */
906
         0,                      /* bitpos */
907
         complain_overflow_bitfield, /* complain_on_overflow */
908
         bfd_elf_generic_reloc, /* special_function */
909
         "R_MIPS_GOT_DISP",     /* name */
910
         true,                  /* partial_inplace */
911
         0,                      /* src_mask */
912
         0x0000ffff,            /* dst_mask */
913
         false),                /* pcrel_offset */
914
 
915
  /* Displacement to page pointer in the global offset table.  */
916
  /* FIXME: Not handled correctly.  */
917
  HOWTO (R_MIPS_GOT_PAGE,       /* type */
918
         0,                      /* rightshift */
919
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
920
         16,                    /* bitsize */
921
         false,                 /* pc_relative */
922
         0,                      /* bitpos */
923
         complain_overflow_bitfield, /* complain_on_overflow */
924
         bfd_elf_generic_reloc, /* special_function */
925
         "R_MIPS_GOT_PAGE",     /* name */
926
         true,                  /* partial_inplace */
927
         0,                      /* src_mask */
928
         0x0000ffff,            /* dst_mask */
929
         false),                /* pcrel_offset */
930
 
931
  /* Offset from page pointer in the global offset table.  */
932
  /* FIXME: Not handled correctly.  */
933
  HOWTO (R_MIPS_GOT_OFST,       /* type */
934
         0,                      /* rightshift */
935
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
936
         16,                    /* bitsize */
937
         false,                 /* pc_relative */
938
         0,                      /* bitpos */
939
         complain_overflow_bitfield, /* complain_on_overflow */
940
         bfd_elf_generic_reloc, /* special_function */
941
         "R_MIPS_GOT_OFST",     /* name */
942
         true,                  /* partial_inplace */
943
         0,                      /* src_mask */
944
         0x0000ffff,            /* dst_mask */
945
         false),                /* pcrel_offset */
946
 
947
  /* High 16 bits of displacement in global offset table.  */
948
  /* FIXME: Not handled correctly.  */
949
  HOWTO (R_MIPS_GOT_HI16,       /* type */
950
         0,                      /* rightshift */
951
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
952
         16,                    /* bitsize */
953
         false,                 /* pc_relative */
954
         0,                      /* bitpos */
955
         complain_overflow_dont, /* complain_on_overflow */
956
         bfd_elf_generic_reloc, /* special_function */
957
         "R_MIPS_GOT_HI16",     /* name */
958
         true,                  /* partial_inplace */
959
         0,                      /* src_mask */
960
         0x0000ffff,            /* dst_mask */
961
         false),                /* pcrel_offset */
962
 
963
  /* Low 16 bits of displacement in global offset table.  */
964
  /* FIXME: Not handled correctly.  */
965
  HOWTO (R_MIPS_GOT_LO16,       /* type */
966
         0,                      /* rightshift */
967
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
968
         16,                    /* bitsize */
969
         false,                 /* pc_relative */
970
         0,                      /* bitpos */
971
         complain_overflow_dont, /* complain_on_overflow */
972
         bfd_elf_generic_reloc, /* special_function */
973
         "R_MIPS_GOT_LO16",     /* name */
974
         true,                  /* partial_inplace */
975
         0,                      /* src_mask */
976
         0x0000ffff,            /* dst_mask */
977
         false),                /* pcrel_offset */
978
 
979
  /* 64 bit substraction.  */
980
  /* FIXME: Not handled correctly.  */
981
  HOWTO (R_MIPS_SUB,            /* type */
982
         0,                      /* rightshift */
983
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
984
         64,                    /* bitsize */
985
         false,                 /* pc_relative */
986
         0,                      /* bitpos */
987
         complain_overflow_bitfield, /* complain_on_overflow */
988
         bfd_elf_generic_reloc, /* special_function */
989
         "R_MIPS_SUB",          /* name */
990
         true,                  /* partial_inplace */
991
         0,                      /* src_mask */
992
         MINUS_ONE,             /* dst_mask */
993
         false),                /* pcrel_offset */
994
 
995
  /* Insert the addend as an instruction.  */
996
  /* FIXME: Not handled correctly.  */
997
  HOWTO (R_MIPS_INSERT_A,       /* type */
998
         0,                      /* rightshift */
999
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
1000
         0,                      /* bitsize */
1001
         false,                 /* pc_relative */
1002
         0,                      /* bitpos */
1003
         complain_overflow_dont, /* complain_on_overflow */
1004
         bfd_elf_generic_reloc, /* special_function */
1005
         "R_MIPS_INSERT_A",     /* name */
1006
         false,                 /* partial_inplace */
1007
         0,                      /* src_mask */
1008
         0,                      /* dst_mask */
1009
         false),                /* pcrel_offset */
1010
 
1011
  /* Insert the addend as an instruction, and change all relocations
1012
     to refer to the old instruction at the address.  */
1013
  /* FIXME: Not handled correctly.  */
1014
  HOWTO (R_MIPS_INSERT_B,       /* type */
1015
         0,                      /* rightshift */
1016
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
1017
         0,                      /* bitsize */
1018
         false,                 /* pc_relative */
1019
         0,                      /* bitpos */
1020
         complain_overflow_dont, /* complain_on_overflow */
1021
         bfd_elf_generic_reloc, /* special_function */
1022
         "R_MIPS_INSERT_B",     /* name */
1023
         false,                 /* partial_inplace */
1024
         0,                      /* src_mask */
1025
         0,                      /* dst_mask */
1026
         false),                /* pcrel_offset */
1027
 
1028
  /* Delete a 32 bit instruction.  */
1029
  /* FIXME: Not handled correctly.  */
1030
  HOWTO (R_MIPS_DELETE,         /* type */
1031
         0,                      /* rightshift */
1032
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
1033
         0,                      /* bitsize */
1034
         false,                 /* pc_relative */
1035
         0,                      /* bitpos */
1036
         complain_overflow_dont, /* complain_on_overflow */
1037
         bfd_elf_generic_reloc, /* special_function */
1038
         "R_MIPS_DELETE",       /* name */
1039
         false,                 /* partial_inplace */
1040
         0,                      /* src_mask */
1041
         0,                      /* dst_mask */
1042
         false),                /* pcrel_offset */
1043
 
1044
  /* Get the higher value of a 64 bit addend.  */
1045
  /* FIXME: Not handled correctly.  */
1046
  HOWTO (R_MIPS_HIGHER,         /* type */
1047
         0,                      /* rightshift */
1048
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1049
         16,                    /* bitsize */
1050
         false,                 /* pc_relative */
1051
         0,                      /* bitpos */
1052
         complain_overflow_dont, /* complain_on_overflow */
1053
         bfd_elf_generic_reloc, /* special_function */
1054
         "R_MIPS_HIGHER",       /* name */
1055
         true,                  /* partial_inplace */
1056
         0,                      /* src_mask */
1057
         0xffff,                /* dst_mask */
1058
         false),                /* pcrel_offset */
1059
 
1060
  /* Get the highest value of a 64 bit addend.  */
1061
  /* FIXME: Not handled correctly.  */
1062
  HOWTO (R_MIPS_HIGHEST,        /* type */
1063
         0,                      /* rightshift */
1064
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1065
         16,                    /* bitsize */
1066
         false,                 /* pc_relative */
1067
         0,                      /* bitpos */
1068
         complain_overflow_dont, /* complain_on_overflow */
1069
         bfd_elf_generic_reloc, /* special_function */
1070
         "R_MIPS_HIGHEST",      /* name */
1071
         true,                  /* partial_inplace */
1072
         0,                      /* src_mask */
1073
         0xffff,                /* dst_mask */
1074
         false),                /* pcrel_offset */
1075
 
1076
  /* High 16 bits of displacement in global offset table.  */
1077
  /* FIXME: Not handled correctly.  */
1078
  HOWTO (R_MIPS_CALL_HI16,      /* type */
1079
         0,                      /* rightshift */
1080
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1081
         16,                    /* bitsize */
1082
         false,                 /* pc_relative */
1083
         0,                      /* bitpos */
1084
         complain_overflow_dont, /* complain_on_overflow */
1085
         bfd_elf_generic_reloc, /* special_function */
1086
         "R_MIPS_CALL_HI16",    /* name */
1087
         true,                  /* partial_inplace */
1088
         0,                      /* src_mask */
1089
         0x0000ffff,            /* dst_mask */
1090
         false),                /* pcrel_offset */
1091
 
1092
  /* Low 16 bits of displacement in global offset table.  */
1093
  /* FIXME: Not handled correctly.  */
1094
  HOWTO (R_MIPS_CALL_LO16,      /* type */
1095
         0,                      /* rightshift */
1096
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1097
         16,                    /* bitsize */
1098
         false,                 /* pc_relative */
1099
         0,                      /* bitpos */
1100
         complain_overflow_dont, /* complain_on_overflow */
1101
         bfd_elf_generic_reloc, /* special_function */
1102
         "R_MIPS_CALL_LO16",    /* name */
1103
         true,                  /* partial_inplace */
1104
         0,                      /* src_mask */
1105
         0x0000ffff,            /* dst_mask */
1106
         false),                /* pcrel_offset */
1107
 
1108
  /* I'm not sure what the remaining relocs are, but they are defined
1109
     on Irix 6.  */
1110
 
1111
  HOWTO (R_MIPS_SCN_DISP,       /* type */
1112
         0,                      /* rightshift */
1113
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
1114
         0,                      /* bitsize */
1115
         false,                 /* pc_relative */
1116
         0,                      /* bitpos */
1117
         complain_overflow_dont, /* complain_on_overflow */
1118
         bfd_elf_generic_reloc, /* special_function */
1119
         "R_MIPS_SCN_DISP",     /* name */
1120
         false,                 /* partial_inplace */
1121
         0,                      /* src_mask */
1122
         0,                      /* dst_mask */
1123
         false),                /* pcrel_offset */
1124
 
1125
  HOWTO (R_MIPS_REL16,          /* type */
1126
         0,                      /* rightshift */
1127
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
1128
         0,                      /* bitsize */
1129
         false,                 /* pc_relative */
1130
         0,                      /* bitpos */
1131
         complain_overflow_dont, /* complain_on_overflow */
1132
         bfd_elf_generic_reloc, /* special_function */
1133
         "R_MIPS_REL16",        /* name */
1134
         false,                 /* partial_inplace */
1135
         0,                      /* src_mask */
1136
         0,                      /* dst_mask */
1137
         false),                /* pcrel_offset */
1138
 
1139
  HOWTO (R_MIPS_ADD_IMMEDIATE,  /* type */
1140
         0,                      /* rightshift */
1141
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
1142
         0,                      /* bitsize */
1143
         false,                 /* pc_relative */
1144
         0,                      /* bitpos */
1145
         complain_overflow_dont, /* complain_on_overflow */
1146
         bfd_elf_generic_reloc, /* special_function */
1147
         "R_MIPS_ADD_IMMEDIATE", /* name */
1148
         false,                 /* partial_inplace */
1149
         0,                      /* src_mask */
1150
         0,                      /* dst_mask */
1151
         false),                /* pcrel_offset */
1152
 
1153
  HOWTO (R_MIPS_PJUMP,          /* type */
1154
         0,                      /* rightshift */
1155
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
1156
         0,                      /* bitsize */
1157
         false,                 /* pc_relative */
1158
         0,                      /* bitpos */
1159
         complain_overflow_dont, /* complain_on_overflow */
1160
         bfd_elf_generic_reloc, /* special_function */
1161
         "R_MIPS_PJUMP",        /* name */
1162
         false,                 /* partial_inplace */
1163
         0,                      /* src_mask */
1164
         0,                      /* dst_mask */
1165
         false),                /* pcrel_offset */
1166
 
1167
  HOWTO (R_MIPS_RELGOT,         /* type */
1168
         0,                      /* rightshift */
1169
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
1170
         0,                      /* bitsize */
1171
         false,                 /* pc_relative */
1172
         0,                      /* bitpos */
1173
         complain_overflow_dont, /* complain_on_overflow */
1174
         bfd_elf_generic_reloc, /* special_function */
1175
         "R_MIPS_RELGOT",       /* name */
1176
         false,                 /* partial_inplace */
1177
         0,                      /* src_mask */
1178
         0,                      /* dst_mask */
1179
         false),                /* pcrel_offset */
1180
 
1181
  /* Protected jump conversion.  This is an optimization hint.  No
1182
     relocation is required for correctness.  */
1183
  HOWTO (R_MIPS_JALR,           /* type */
1184
         0,                      /* rightshift */
1185
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
1186
         0,                      /* bitsize */
1187
         false,                 /* pc_relative */
1188
         0,                      /* bitpos */
1189
         complain_overflow_dont, /* complain_on_overflow */
1190
         bfd_elf_generic_reloc, /* special_function */
1191
         "R_MIPS_JALR",         /* name */
1192
         false,                 /* partial_inplace */
1193
         0x00000000,            /* src_mask */
1194
         0x00000000,            /* dst_mask */
1195
         false),                /* pcrel_offset */
1196
};
1197
 
1198
/* Swap in a MIPS 64-bit Rel reloc.  */
1199
 
1200
static void
1201
mips_elf64_swap_reloc_in (abfd, src, dst)
1202
     bfd *abfd;
1203
     const Elf64_Mips_External_Rel *src;
1204
     Elf64_Mips_Internal_Rel *dst;
1205
{
1206
  dst->r_offset = bfd_h_get_64 (abfd, (bfd_byte *) src->r_offset);
1207
  dst->r_sym = bfd_h_get_32 (abfd, (bfd_byte *) src->r_sym);
1208
  dst->r_ssym = bfd_h_get_8 (abfd, (bfd_byte *) src->r_ssym);
1209
  dst->r_type3 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type3);
1210
  dst->r_type2 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type2);
1211
  dst->r_type = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type);
1212
}
1213
 
1214
/* Swap in a MIPS 64-bit Rela reloc.  */
1215
 
1216
static void
1217
mips_elf64_swap_reloca_in (abfd, src, dst)
1218
     bfd *abfd;
1219
     const Elf64_Mips_External_Rela *src;
1220
     Elf64_Mips_Internal_Rela *dst;
1221
{
1222
  dst->r_offset = bfd_h_get_64 (abfd, (bfd_byte *) src->r_offset);
1223
  dst->r_sym = bfd_h_get_32 (abfd, (bfd_byte *) src->r_sym);
1224
  dst->r_ssym = bfd_h_get_8 (abfd, (bfd_byte *) src->r_ssym);
1225
  dst->r_type3 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type3);
1226
  dst->r_type2 = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type2);
1227
  dst->r_type = bfd_h_get_8 (abfd, (bfd_byte *) src->r_type);
1228
  dst->r_addend = bfd_h_get_signed_64 (abfd, (bfd_byte *) src->r_addend);
1229
}
1230
 
1231
/* Swap out a MIPS 64-bit Rel reloc.  */
1232
 
1233
static void
1234
mips_elf64_swap_reloc_out (abfd, src, dst)
1235
     bfd *abfd;
1236
     const Elf64_Mips_Internal_Rel *src;
1237
     Elf64_Mips_External_Rel *dst;
1238
{
1239
  bfd_h_put_64 (abfd, src->r_offset, (bfd_byte *) dst->r_offset);
1240
  bfd_h_put_32 (abfd, src->r_sym, (bfd_byte *) dst->r_sym);
1241
  bfd_h_put_8 (abfd, src->r_ssym, (bfd_byte *) dst->r_ssym);
1242
  bfd_h_put_8 (abfd, src->r_type3, (bfd_byte *) dst->r_type3);
1243
  bfd_h_put_8 (abfd, src->r_type2, (bfd_byte *) dst->r_type2);
1244
  bfd_h_put_8 (abfd, src->r_type, (bfd_byte *) dst->r_type);
1245
}
1246
 
1247
/* Swap out a MIPS 64-bit Rela reloc.  */
1248
 
1249
static void
1250
mips_elf64_swap_reloca_out (abfd, src, dst)
1251
     bfd *abfd;
1252
     const Elf64_Mips_Internal_Rela *src;
1253
     Elf64_Mips_External_Rela *dst;
1254
{
1255
  bfd_h_put_64 (abfd, src->r_offset, (bfd_byte *) dst->r_offset);
1256
  bfd_h_put_32 (abfd, src->r_sym, (bfd_byte *) dst->r_sym);
1257
  bfd_h_put_8 (abfd, src->r_ssym, (bfd_byte *) dst->r_ssym);
1258
  bfd_h_put_8 (abfd, src->r_type3, (bfd_byte *) dst->r_type3);
1259
  bfd_h_put_8 (abfd, src->r_type2, (bfd_byte *) dst->r_type2);
1260
  bfd_h_put_8 (abfd, src->r_type, (bfd_byte *) dst->r_type);
1261
  bfd_h_put_64 (abfd, src->r_addend, (bfd_byte *) dst->r_addend);
1262
}
1263
 
1264
/* Swap in a MIPS 64-bit Rel reloc.  */
1265
 
1266
static void
1267
mips_elf64_be_swap_reloc_in (abfd, src, dst)
1268
     bfd *abfd;
1269
     const bfd_byte *src;
1270
     Elf_Internal_Rel *dst;
1271
{
1272
  Elf64_Mips_Internal_Rel mirel;
1273
 
1274
  mips_elf64_swap_reloc_in (abfd,
1275
                            (const Elf64_Mips_External_Rel *) src,
1276
                            &mirel);
1277
 
1278
  dst[0].r_offset = mirel.r_offset;
1279
  dst[0].r_info = ELF32_R_INFO (mirel.r_sym, mirel.r_type);
1280
  dst[1].r_offset = mirel.r_offset;
1281
  dst[1].r_info = ELF32_R_INFO (mirel.r_ssym, mirel.r_type2);
1282
  dst[2].r_offset = mirel.r_offset;
1283
  dst[2].r_info = ELF32_R_INFO (STN_UNDEF, mirel.r_type3);
1284
}
1285
 
1286
/* Swap in a MIPS 64-bit Rela reloc.  */
1287
 
1288
static void
1289
mips_elf64_be_swap_reloca_in (abfd, src, dst)
1290
     bfd *abfd;
1291
     const bfd_byte *src;
1292
     Elf_Internal_Rela *dst;
1293
{
1294
  Elf64_Mips_Internal_Rela mirela;
1295
 
1296
  mips_elf64_swap_reloca_in (abfd,
1297
                             (const Elf64_Mips_External_Rela *) src,
1298
                             &mirela);
1299
 
1300
  dst[0].r_offset = mirela.r_offset;
1301
  dst[0].r_info = ELF32_R_INFO (mirela.r_sym, mirela.r_type);
1302
  dst[0].r_addend = mirela.r_addend;
1303
  dst[1].r_offset = mirela.r_offset;
1304
  dst[1].r_info = ELF32_R_INFO (mirela.r_ssym, mirela.r_type2);
1305
  dst[1].r_addend = 0;
1306
  dst[2].r_offset = mirela.r_offset;
1307
  dst[2].r_info = ELF32_R_INFO (STN_UNDEF, mirela.r_type3);
1308
  dst[2].r_addend = 0;
1309
}
1310
 
1311
/* Swap out a MIPS 64-bit Rel reloc.  */
1312
 
1313
static void
1314
mips_elf64_be_swap_reloc_out (abfd, src, dst)
1315
     bfd *abfd;
1316
     const Elf_Internal_Rel *src;
1317
     bfd_byte *dst;
1318
{
1319
  Elf64_Mips_Internal_Rel mirel;
1320
 
1321
  mirel.r_offset = src->r_offset;
1322
  mirel.r_type = ELF32_R_TYPE (src->r_info);
1323
  mirel.r_sym = ELF32_R_SYM (src->r_info);
1324
  mirel.r_type2 = R_MIPS_NONE;
1325
  mirel.r_ssym = STN_UNDEF;
1326
  mirel.r_type3 = R_MIPS_NONE;
1327
 
1328
  mips_elf64_swap_reloc_out (abfd, &mirel,
1329
                             (Elf64_Mips_External_Rel *) dst);
1330
}
1331
 
1332
/* Swap out a MIPS 64-bit Rela reloc.  */
1333
 
1334
static void
1335
mips_elf64_be_swap_reloca_out (abfd, src, dst)
1336
     bfd *abfd;
1337
     const Elf_Internal_Rela *src;
1338
     bfd_byte *dst;
1339
{
1340
  Elf64_Mips_Internal_Rela mirela;
1341
 
1342
  mirela.r_offset = src->r_offset;
1343
  mirela.r_type = ELF32_R_TYPE (src->r_info);
1344
  mirela.r_addend = src->r_addend;
1345
  mirela.r_sym = ELF32_R_SYM (src->r_info);
1346
  mirela.r_type2 = R_MIPS_NONE;
1347
  mirela.r_ssym = STN_UNDEF;
1348
  mirela.r_type3 = R_MIPS_NONE;
1349
 
1350
  mips_elf64_swap_reloca_out (abfd, &mirela,
1351
                              (Elf64_Mips_External_Rela *) dst);
1352
}
1353
 
1354
/* A mapping from BFD reloc types to MIPS ELF reloc types.  */
1355
 
1356
struct elf_reloc_map
1357
{
1358
  bfd_reloc_code_real_type bfd_reloc_val;
1359
  enum elf_mips_reloc_type elf_reloc_val;
1360
};
1361
 
1362
static CONST struct elf_reloc_map mips_reloc_map[] =
1363
{
1364
  { BFD_RELOC_NONE, R_MIPS_NONE, },
1365
  { BFD_RELOC_16, R_MIPS_16 },
1366
  { BFD_RELOC_32, R_MIPS_32 },
1367
  { BFD_RELOC_64, R_MIPS_64 },
1368
  { BFD_RELOC_CTOR, R_MIPS_64 },
1369
  { BFD_RELOC_32_PCREL, R_MIPS_REL32 },
1370
  { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1371
  { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1372
  { BFD_RELOC_LO16, R_MIPS_LO16 },
1373
  { BFD_RELOC_MIPS_GPREL, R_MIPS_GPREL16 },
1374
  { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1375
  { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1376
  { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
1377
  { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1378
  { BFD_RELOC_MIPS_GPREL32, R_MIPS_GPREL32 },
1379
  { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1380
  { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1381
  { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
1382
  { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1383
  { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1384
  { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1385
  { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1386
  { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP }
1387
};
1388
 
1389
/* Given a BFD reloc type, return a howto structure.  */
1390
 
1391
static reloc_howto_type *
1392
mips_elf64_reloc_type_lookup (abfd, code)
1393
     bfd *abfd ATTRIBUTE_UNUSED;
1394
     bfd_reloc_code_real_type code;
1395
{
1396
  unsigned int i;
1397
 
1398
  for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map); i++)
1399
    {
1400
      if (mips_reloc_map[i].bfd_reloc_val == code)
1401
        {
1402
          int v;
1403
 
1404
          v = (int) mips_reloc_map[i].elf_reloc_val;
1405
          return &mips_elf64_howto_table_rel[v];
1406
        }
1407
    }
1408
 
1409
  return NULL;
1410
}
1411
 
1412
/* Since each entry in an SHT_REL or SHT_RELA section can represent up
1413
   to three relocs, we must tell the user to allocate more space.  */
1414
 
1415
static long
1416
mips_elf64_get_reloc_upper_bound (abfd, sec)
1417
     bfd *abfd ATTRIBUTE_UNUSED;
1418
     asection *sec;
1419
{
1420
  return (sec->reloc_count * 3 + 1) * sizeof (arelent *);
1421
}
1422
 
1423
/* Read the relocations from one reloc section.  */
1424
 
1425
static boolean
1426
mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, rel_hdr)
1427
     bfd *abfd;
1428
     asection *asect;
1429
     asymbol **symbols;
1430
     const Elf_Internal_Shdr *rel_hdr;
1431
{
1432
  PTR allocated = NULL;
1433
  bfd_byte *native_relocs;
1434
  arelent *relents;
1435
  arelent *relent;
1436
  unsigned int count;
1437
  unsigned int i;
1438
  int entsize;
1439
  reloc_howto_type *howto_table;
1440
 
1441
  allocated = (PTR) bfd_malloc (rel_hdr->sh_size);
1442
  if (allocated == NULL)
1443
    goto error_return;
1444
 
1445
  if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
1446
      || (bfd_read (allocated, 1, rel_hdr->sh_size, abfd) != rel_hdr->sh_size))
1447
    goto error_return;
1448
 
1449
  native_relocs = (bfd_byte *) allocated;
1450
 
1451
  relents = asect->relocation + asect->reloc_count;
1452
 
1453
  entsize = rel_hdr->sh_entsize;
1454
  BFD_ASSERT (entsize == sizeof (Elf64_Mips_External_Rel)
1455
              || entsize == sizeof (Elf64_Mips_External_Rela));
1456
 
1457
  count = rel_hdr->sh_size / entsize;
1458
 
1459
  if (entsize == sizeof (Elf64_Mips_External_Rel))
1460
    howto_table = mips_elf64_howto_table_rel;
1461
  else
1462
    howto_table = mips_elf64_howto_table_rela;
1463
 
1464
  relent = relents;
1465
  for (i = 0; i < count; i++, native_relocs += entsize)
1466
    {
1467
      Elf64_Mips_Internal_Rela rela;
1468
      boolean used_sym, used_ssym;
1469
      int ir;
1470
 
1471
      if (entsize == sizeof (Elf64_Mips_External_Rela))
1472
        mips_elf64_swap_reloca_in (abfd,
1473
                                   (Elf64_Mips_External_Rela *) native_relocs,
1474
                                   &rela);
1475
      else
1476
        {
1477
          Elf64_Mips_Internal_Rel rel;
1478
 
1479
          mips_elf64_swap_reloc_in (abfd,
1480
                                    (Elf64_Mips_External_Rel *) native_relocs,
1481
                                    &rel);
1482
          rela.r_offset = rel.r_offset;
1483
          rela.r_sym = rel.r_sym;
1484
          rela.r_ssym = rel.r_ssym;
1485
          rela.r_type3 = rel.r_type3;
1486
          rela.r_type2 = rel.r_type2;
1487
          rela.r_type = rel.r_type;
1488
          rela.r_addend = 0;
1489
        }
1490
 
1491
      /* Each entry represents up to three actual relocations.  */
1492
 
1493
      used_sym = false;
1494
      used_ssym = false;
1495
      for (ir = 0; ir < 3; ir++)
1496
        {
1497
          enum elf_mips_reloc_type type;
1498
 
1499
          switch (ir)
1500
            {
1501
            default:
1502
              abort ();
1503
            case 0:
1504
              type = (enum elf_mips_reloc_type) rela.r_type;
1505
              break;
1506
            case 1:
1507
              type = (enum elf_mips_reloc_type) rela.r_type2;
1508
              break;
1509
            case 2:
1510
              type = (enum elf_mips_reloc_type) rela.r_type3;
1511
              break;
1512
            }
1513
 
1514
          if (type == R_MIPS_NONE)
1515
            {
1516
              /* There are no more relocations in this entry.  If this
1517
                 is the first entry, we need to generate a dummy
1518
                 relocation so that the generic linker knows that
1519
                 there has been a break in the sequence of relocations
1520
                 applying to a particular address.  */
1521
              if (ir == 0)
1522
                {
1523
                  relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1524
                  if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
1525
                    relent->address = rela.r_offset;
1526
                  else
1527
                    relent->address = rela.r_offset - asect->vma;
1528
                  relent->addend = 0;
1529
                  relent->howto = &howto_table[(int) R_MIPS_NONE];
1530
                  ++relent;
1531
                }
1532
              break;
1533
            }
1534
 
1535
          /* Some types require symbols, whereas some do not.  */
1536
          switch (type)
1537
            {
1538
            case R_MIPS_NONE:
1539
            case R_MIPS_LITERAL:
1540
            case R_MIPS_INSERT_A:
1541
            case R_MIPS_INSERT_B:
1542
            case R_MIPS_DELETE:
1543
              relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1544
              break;
1545
 
1546
            default:
1547
              if (! used_sym)
1548
                {
1549
                  if (rela.r_sym == 0)
1550
                    relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1551
                  else
1552
                    {
1553
                      asymbol **ps, *s;
1554
 
1555
                      ps = symbols + rela.r_sym - 1;
1556
                      s = *ps;
1557
                      if ((s->flags & BSF_SECTION_SYM) == 0)
1558
                        relent->sym_ptr_ptr = ps;
1559
                      else
1560
                        relent->sym_ptr_ptr = s->section->symbol_ptr_ptr;
1561
                    }
1562
 
1563
                  used_sym = true;
1564
                }
1565
              else if (! used_ssym)
1566
                {
1567
                  switch (rela.r_ssym)
1568
                    {
1569
                    case RSS_UNDEF:
1570
                      relent->sym_ptr_ptr =
1571
                        bfd_abs_section_ptr->symbol_ptr_ptr;
1572
                      break;
1573
 
1574
                    case RSS_GP:
1575
                    case RSS_GP0:
1576
                    case RSS_LOC:
1577
                      /* FIXME: I think these need to be handled using
1578
                         special howto structures.  */
1579
                      BFD_ASSERT (0);
1580
                      break;
1581
 
1582
                    default:
1583
                      BFD_ASSERT (0);
1584
                      break;
1585
                    }
1586
 
1587
                  used_ssym = true;
1588
                }
1589
              else
1590
                relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
1591
 
1592
              break;
1593
            }
1594
 
1595
          /* The address of an ELF reloc is section relative for an
1596
             object file, and absolute for an executable file or
1597
             shared library.  The address of a BFD reloc is always
1598
             section relative.  */
1599
          if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
1600
            relent->address = rela.r_offset;
1601
          else
1602
            relent->address = rela.r_offset - asect->vma;
1603
 
1604
          relent->addend = rela.r_addend;
1605
 
1606
          relent->howto = &howto_table[(int) type];
1607
 
1608
          ++relent;
1609
        }
1610
    }
1611
 
1612
  asect->reloc_count += relent - relents;
1613
 
1614
  if (allocated != NULL)
1615
    free (allocated);
1616
 
1617
  return true;
1618
 
1619
 error_return:
1620
  if (allocated != NULL)
1621
    free (allocated);
1622
  return false;
1623
}
1624
 
1625
/* Read the relocations.  On Irix 6, there can be two reloc sections
1626
   associated with a single data section.  */
1627
 
1628
static boolean
1629
mips_elf64_slurp_reloc_table (abfd, asect, symbols, dynamic)
1630
     bfd *abfd;
1631
     asection *asect;
1632
     asymbol **symbols;
1633
     boolean dynamic;
1634
{
1635
  struct bfd_elf_section_data * const d = elf_section_data (asect);
1636
 
1637
  if (dynamic)
1638
    {
1639
      bfd_set_error (bfd_error_invalid_operation);
1640
      return false;
1641
    }
1642
 
1643
  if (asect->relocation != NULL
1644
      || (asect->flags & SEC_RELOC) == 0
1645
      || asect->reloc_count == 0)
1646
    return true;
1647
 
1648
  /* Allocate space for 3 arelent structures for each Rel structure.  */
1649
  asect->relocation = ((arelent *)
1650
                       bfd_alloc (abfd,
1651
                                  asect->reloc_count * 3 * sizeof (arelent)));
1652
  if (asect->relocation == NULL)
1653
    return false;
1654
 
1655
  /* The slurp_one_reloc_table routine increments reloc_count.  */
1656
  asect->reloc_count = 0;
1657
 
1658
  if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols, &d->rel_hdr))
1659
    return false;
1660
  if (d->rel_hdr2 != NULL)
1661
    {
1662
      if (! mips_elf64_slurp_one_reloc_table (abfd, asect, symbols,
1663
                                              d->rel_hdr2))
1664
        return false;
1665
    }
1666
 
1667
  return true;
1668
}
1669
 
1670
/* Write out the relocations.  */
1671
 
1672
static void
1673
mips_elf64_write_relocs (abfd, sec, data)
1674
     bfd *abfd;
1675
     asection *sec;
1676
     PTR data;
1677
{
1678
  boolean *failedp = (boolean *) data;
1679
  unsigned int count;
1680
  Elf_Internal_Shdr *rela_hdr;
1681
  Elf64_Mips_External_Rela *ext_rela;
1682
  unsigned int idx;
1683
  asymbol *last_sym = 0;
1684
  int last_sym_idx = 0;
1685
 
1686
  /* If we have already failed, don't do anything.  */
1687
  if (*failedp)
1688
    return;
1689
 
1690
  if ((sec->flags & SEC_RELOC) == 0)
1691
    return;
1692
 
1693
  /* The linker backend writes the relocs out itself, and sets the
1694
     reloc_count field to zero to inhibit writing them here.  Also,
1695
     sometimes the SEC_RELOC flag gets set even when there aren't any
1696
     relocs.  */
1697
  if (sec->reloc_count == 0)
1698
    return;
1699
 
1700
  /* We can combine up to three relocs that refer to the same address
1701
     if the latter relocs have no associated symbol.  */
1702
  count = 0;
1703
  for (idx = 0; idx < sec->reloc_count; idx++)
1704
    {
1705
      bfd_vma addr;
1706
      unsigned int i;
1707
 
1708
      ++count;
1709
 
1710
      addr = sec->orelocation[idx]->address;
1711
      for (i = 0; i < 2; i++)
1712
        {
1713
          arelent *r;
1714
 
1715
          if (idx + 1 >= sec->reloc_count)
1716
            break;
1717
          r = sec->orelocation[idx + 1];
1718
          if (r->address != addr
1719
              || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
1720
              || (*r->sym_ptr_ptr)->value != 0)
1721
            break;
1722
 
1723
          /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
1724
 
1725
          ++idx;
1726
        }
1727
    }
1728
 
1729
  rela_hdr = &elf_section_data (sec)->rel_hdr;
1730
 
1731
  rela_hdr->sh_size = rela_hdr->sh_entsize * count;
1732
  rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size);
1733
  if (rela_hdr->contents == NULL)
1734
    {
1735
      *failedp = true;
1736
      return;
1737
    }
1738
 
1739
  ext_rela = (Elf64_Mips_External_Rela *) rela_hdr->contents;
1740
  for (idx = 0; idx < sec->reloc_count; idx++, ext_rela++)
1741
    {
1742
      arelent *ptr;
1743
      Elf64_Mips_Internal_Rela int_rela;
1744
      asymbol *sym;
1745
      int n;
1746
      unsigned int i;
1747
 
1748
      ptr = sec->orelocation[idx];
1749
 
1750
      /* The address of an ELF reloc is section relative for an object
1751
         file, and absolute for an executable file or shared library.
1752
         The address of a BFD reloc is always section relative.  */
1753
      if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
1754
        int_rela.r_offset = ptr->address;
1755
      else
1756
        int_rela.r_offset = ptr->address + sec->vma;
1757
 
1758
      sym = *ptr->sym_ptr_ptr;
1759
      if (sym == last_sym)
1760
        n = last_sym_idx;
1761
      else
1762
        {
1763
          last_sym = sym;
1764
          n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
1765
          if (n < 0)
1766
            {
1767
              *failedp = true;
1768
              return;
1769
            }
1770
          last_sym_idx = n;
1771
        }
1772
 
1773
      int_rela.r_sym = n;
1774
 
1775
      int_rela.r_addend = ptr->addend;
1776
 
1777
      int_rela.r_ssym = RSS_UNDEF;
1778
 
1779
      if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
1780
          && ! _bfd_elf_validate_reloc (abfd, ptr))
1781
        {
1782
          *failedp = true;
1783
          return;
1784
        }
1785
 
1786
      int_rela.r_type = ptr->howto->type;
1787
      int_rela.r_type2 = (int) R_MIPS_NONE;
1788
      int_rela.r_type3 = (int) R_MIPS_NONE;
1789
 
1790
      for (i = 0; i < 2; i++)
1791
        {
1792
          arelent *r;
1793
 
1794
          if (idx + 1 >= sec->reloc_count)
1795
            break;
1796
          r = sec->orelocation[idx + 1];
1797
          if (r->address != ptr->address
1798
              || ! bfd_is_abs_section ((*r->sym_ptr_ptr)->section)
1799
              || (*r->sym_ptr_ptr)->value != 0)
1800
            break;
1801
 
1802
          /* We can merge the reloc at IDX + 1 with the reloc at IDX.  */
1803
 
1804
          if (i == 0)
1805
            int_rela.r_type2 = r->howto->type;
1806
          else
1807
            int_rela.r_type3 = r->howto->type;
1808
 
1809
          ++idx;
1810
        }
1811
 
1812
      mips_elf64_swap_reloca_out (abfd, &int_rela, ext_rela);
1813
    }
1814
 
1815
  BFD_ASSERT (ext_rela - (Elf64_Mips_External_Rela *) rela_hdr->contents
1816
              == count);
1817
}
1818
 
1819
/* Irix 6 defines a brand new archive map format, so that they can
1820
   have archives more than 4 GB in size.  */
1821
 
1822
/* Read an Irix 6 armap.  */
1823
 
1824
static boolean
1825
mips_elf64_slurp_armap (abfd)
1826
     bfd *abfd;
1827
{
1828
  struct artdata *ardata = bfd_ardata (abfd);
1829
  char nextname[17];
1830
  file_ptr arhdrpos;
1831
  bfd_size_type i, parsed_size, nsymz, stringsize, carsym_size, ptrsize;
1832
  struct areltdata *mapdata;
1833
  bfd_byte int_buf[8];
1834
  char *stringbase;
1835
  bfd_byte *raw_armap = NULL;
1836
  carsym *carsyms;
1837
 
1838
  ardata->symdefs = NULL;
1839
 
1840
  /* Get the name of the first element.  */
1841
  arhdrpos = bfd_tell (abfd);
1842
  i = bfd_read ((PTR) nextname, 1, 16, abfd);
1843
  if (i == 0)
1844
    return true;
1845
  if (i != 16)
1846
    return false;
1847
 
1848
  if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0)
1849
    return false;
1850
 
1851
  /* Archives with traditional armaps are still permitted.  */
1852
  if (strncmp (nextname, "/               ", 16) == 0)
1853
    return bfd_slurp_armap (abfd);
1854
 
1855
  if (strncmp (nextname, "/SYM64/         ", 16) != 0)
1856
    {
1857
      bfd_has_map (abfd) = false;
1858
      return true;
1859
    }
1860
 
1861
  mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
1862
  if (mapdata == NULL)
1863
    return false;
1864
  parsed_size = mapdata->parsed_size;
1865
  bfd_release (abfd, (PTR) mapdata);
1866
 
1867
  if (bfd_read (int_buf, 1, 8, abfd) != 8)
1868
    {
1869
      if (bfd_get_error () != bfd_error_system_call)
1870
        bfd_set_error (bfd_error_malformed_archive);
1871
      return false;
1872
    }
1873
 
1874
  nsymz = bfd_getb64 (int_buf);
1875
  stringsize = parsed_size - 8 * nsymz - 8;
1876
 
1877
  carsym_size = nsymz * sizeof (carsym);
1878
  ptrsize = 8 * nsymz;
1879
 
1880
  ardata->symdefs = (carsym *) bfd_zalloc (abfd, carsym_size + stringsize + 1);
1881
  if (ardata->symdefs == NULL)
1882
    return false;
1883
  carsyms = ardata->symdefs;
1884
  stringbase = ((char *) ardata->symdefs) + carsym_size;
1885
 
1886
  raw_armap = (bfd_byte *) bfd_alloc (abfd, ptrsize);
1887
  if (raw_armap == NULL)
1888
    goto error_return;
1889
 
1890
  if (bfd_read (raw_armap, 1, ptrsize, abfd) != ptrsize
1891
      || bfd_read (stringbase, 1, stringsize, abfd) != stringsize)
1892
    {
1893
      if (bfd_get_error () != bfd_error_system_call)
1894
        bfd_set_error (bfd_error_malformed_archive);
1895
      goto error_return;
1896
    }
1897
 
1898
  for (i = 0; i < nsymz; i++)
1899
    {
1900
      carsyms->file_offset = bfd_getb64 (raw_armap + i * 8);
1901
      carsyms->name = stringbase;
1902
      stringbase += strlen (stringbase) + 1;
1903
      ++carsyms;
1904
    }
1905
  *stringbase = '\0';
1906
 
1907
  ardata->symdef_count = nsymz;
1908
  ardata->first_file_filepos = arhdrpos + sizeof (struct ar_hdr) + parsed_size;
1909
 
1910
  bfd_has_map (abfd) = true;
1911
  bfd_release (abfd, raw_armap);
1912
 
1913
  return true;
1914
 
1915
 error_return:
1916
  if (raw_armap != NULL)
1917
    bfd_release (abfd, raw_armap);
1918
  if (ardata->symdefs != NULL)
1919
    bfd_release (abfd, ardata->symdefs);
1920
  return false;
1921
}
1922
 
1923
/* Write out an Irix 6 armap.  The Irix 6 tools are supposed to be
1924
   able to handle ordinary ELF armaps, but at least on Irix 6.2 the
1925
   linker crashes.  */
1926
 
1927
static boolean
1928
mips_elf64_write_armap (arch, elength, map, symbol_count, stridx)
1929
     bfd *arch;
1930
     unsigned int elength;
1931
     struct orl *map;
1932
     unsigned int symbol_count;
1933
     int stridx;
1934
{
1935
  unsigned int ranlibsize = (symbol_count * 8) + 8;
1936
  unsigned int stringsize = stridx;
1937
  unsigned int mapsize = stringsize + ranlibsize;
1938
  file_ptr archive_member_file_ptr;
1939
  bfd *current = arch->archive_head;
1940
  unsigned int count;
1941
  struct ar_hdr hdr;
1942
  unsigned int i;
1943
  int padding;
1944
  bfd_byte buf[8];
1945
 
1946
  padding = BFD_ALIGN (mapsize, 8) - mapsize;
1947
  mapsize += padding;
1948
 
1949
  /* work out where the first object file will go in the archive */
1950
  archive_member_file_ptr = (mapsize
1951
                             + elength
1952
                             + sizeof (struct ar_hdr)
1953
                             + SARMAG);
1954
 
1955
  memset ((char *) (&hdr), 0, sizeof (struct ar_hdr));
1956
  strcpy (hdr.ar_name, "/SYM64/");
1957
  sprintf (hdr.ar_size, "%-10d", (int) mapsize);
1958
  sprintf (hdr.ar_date, "%ld", (long) time (NULL));
1959
  /* This, at least, is what Intel coff sets the values to.: */
1960
  sprintf ((hdr.ar_uid), "%d", 0);
1961
  sprintf ((hdr.ar_gid), "%d", 0);
1962
  sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0);
1963
  strncpy (hdr.ar_fmag, ARFMAG, 2);
1964
 
1965
  for (i = 0; i < sizeof (struct ar_hdr); i++)
1966
    if (((char *) (&hdr))[i] == '\0')
1967
      (((char *) (&hdr))[i]) = ' ';
1968
 
1969
  /* Write the ar header for this item and the number of symbols */
1970
 
1971
  if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), arch)
1972
      != sizeof (struct ar_hdr))
1973
    return false;
1974
 
1975
  bfd_putb64 (symbol_count, buf);
1976
  if (bfd_write (buf, 1, 8, arch) != 8)
1977
    return false;
1978
 
1979
  /* Two passes, first write the file offsets for each symbol -
1980
     remembering that each offset is on a two byte boundary.  */
1981
 
1982
  /* Write out the file offset for the file associated with each
1983
     symbol, and remember to keep the offsets padded out.  */
1984
 
1985
  current = arch->archive_head;
1986
  count = 0;
1987
  while (current != (bfd *) NULL && count < symbol_count)
1988
    {
1989
      /* For each symbol which is used defined in this object, write out
1990
         the object file's address in the archive */
1991
 
1992
      while (((bfd *) (map[count]).pos) == current)
1993
        {
1994
          bfd_putb64 (archive_member_file_ptr, buf);
1995
          if (bfd_write (buf, 1, 8, arch) != 8)
1996
            return false;
1997
          count++;
1998
        }
1999
      /* Add size of this archive entry */
2000
      archive_member_file_ptr += (arelt_size (current)
2001
                                  + sizeof (struct ar_hdr));
2002
      /* remember about the even alignment */
2003
      archive_member_file_ptr += archive_member_file_ptr % 2;
2004
      current = current->next;
2005
    }
2006
 
2007
  /* now write the strings themselves */
2008
  for (count = 0; count < symbol_count; count++)
2009
    {
2010
      size_t len = strlen (*map[count].name) + 1;
2011
 
2012
      if (bfd_write (*map[count].name, 1, len, arch) != len)
2013
        return false;
2014
    }
2015
 
2016
  /* The spec says that this should be padded to an 8 byte boundary.
2017
     However, the Irix 6.2 tools do not appear to do this.  */
2018
  while (padding != 0)
2019
    {
2020
      if (bfd_write ("", 1, 1, arch) != 1)
2021
        return false;
2022
      --padding;
2023
    }
2024
 
2025
  return true;
2026
}
2027
 
2028
/* ECOFF swapping routines.  These are used when dealing with the
2029
   .mdebug section, which is in the ECOFF debugging format.  */
2030
static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap =
2031
{
2032
  /* Symbol table magic number.  */
2033
  magicSym2,
2034
  /* Alignment of debugging information.  E.g., 4.  */
2035
  8,
2036
  /* Sizes of external symbolic information.  */
2037
  sizeof (struct hdr_ext),
2038
  sizeof (struct dnr_ext),
2039
  sizeof (struct pdr_ext),
2040
  sizeof (struct sym_ext),
2041
  sizeof (struct opt_ext),
2042
  sizeof (struct fdr_ext),
2043
  sizeof (struct rfd_ext),
2044
  sizeof (struct ext_ext),
2045
  /* Functions to swap in external symbolic data.  */
2046
  ecoff_swap_hdr_in,
2047
  ecoff_swap_dnr_in,
2048
  ecoff_swap_pdr_in,
2049
  ecoff_swap_sym_in,
2050
  ecoff_swap_opt_in,
2051
  ecoff_swap_fdr_in,
2052
  ecoff_swap_rfd_in,
2053
  ecoff_swap_ext_in,
2054
  _bfd_ecoff_swap_tir_in,
2055
  _bfd_ecoff_swap_rndx_in,
2056
  /* Functions to swap out external symbolic data.  */
2057
  ecoff_swap_hdr_out,
2058
  ecoff_swap_dnr_out,
2059
  ecoff_swap_pdr_out,
2060
  ecoff_swap_sym_out,
2061
  ecoff_swap_opt_out,
2062
  ecoff_swap_fdr_out,
2063
  ecoff_swap_rfd_out,
2064
  ecoff_swap_ext_out,
2065
  _bfd_ecoff_swap_tir_out,
2066
  _bfd_ecoff_swap_rndx_out,
2067
  /* Function to read in symbolic data.  */
2068
  _bfd_mips_elf_read_ecoff_info
2069
};
2070
 
2071
/* Relocations in the 64 bit MIPS ELF ABI are more complex than in
2072
   standard ELF.  This structure is used to redirect the relocation
2073
   handling routines.  */
2074
 
2075
const struct elf_size_info mips_elf64_size_info =
2076
{
2077
  sizeof (Elf64_External_Ehdr),
2078
  sizeof (Elf64_External_Phdr),
2079
  sizeof (Elf64_External_Shdr),
2080
  sizeof (Elf64_Mips_External_Rel),
2081
  sizeof (Elf64_Mips_External_Rela),
2082
  sizeof (Elf64_External_Sym),
2083
  sizeof (Elf64_External_Dyn),
2084
  sizeof (Elf_External_Note),
2085
  4,            /* hash-table entry size */
2086
  3,            /* internal relocations per external relocations */
2087
  64,           /* arch_size */
2088
  8,            /* file_align */
2089
  ELFCLASS64,
2090
  EV_CURRENT,
2091
  bfd_elf64_write_out_phdrs,
2092
  bfd_elf64_write_shdrs_and_ehdr,
2093
  mips_elf64_write_relocs,
2094
  bfd_elf64_swap_symbol_out,
2095
  mips_elf64_slurp_reloc_table,
2096
  bfd_elf64_slurp_symbol_table,
2097
  bfd_elf64_swap_dyn_in,
2098
  bfd_elf64_swap_dyn_out,
2099
  mips_elf64_be_swap_reloc_in,
2100
  mips_elf64_be_swap_reloc_out,
2101
  mips_elf64_be_swap_reloca_in,
2102
  mips_elf64_be_swap_reloca_out
2103
};
2104
 
2105
#define TARGET_LITTLE_SYM               bfd_elf64_littlemips_vec
2106
#define TARGET_LITTLE_NAME              "elf64-littlemips"
2107
#define TARGET_BIG_SYM                  bfd_elf64_bigmips_vec
2108
#define TARGET_BIG_NAME                 "elf64-bigmips"
2109
#define ELF_ARCH                        bfd_arch_mips
2110
#define ELF_MACHINE_CODE                EM_MIPS
2111
 
2112
#define ELF_MAXPAGESIZE                 0x1000
2113
 
2114
#define elf_backend_collect             true
2115
#define elf_backend_type_change_ok      true
2116
#define elf_backend_can_gc_sections     true
2117
#define elf_backend_size_info           mips_elf64_size_info
2118
#define elf_backend_object_p            _bfd_mips_elf_object_p
2119
#define elf_backend_section_from_shdr   _bfd_mips_elf_section_from_shdr
2120
#define elf_backend_fake_sections       _bfd_mips_elf_fake_sections
2121
#define elf_backend_section_from_bfd_section \
2122
                                        _bfd_mips_elf_section_from_bfd_section
2123
#define elf_backend_section_processing  _bfd_mips_elf_section_processing
2124
#define elf_backend_symbol_processing   _bfd_mips_elf_symbol_processing
2125
#define elf_backend_additional_program_headers \
2126
                                        _bfd_mips_elf_additional_program_headers
2127
#define elf_backend_modify_segment_map  _bfd_mips_elf_modify_segment_map
2128
#define elf_backend_final_write_processing \
2129
                                        _bfd_mips_elf_final_write_processing
2130
#define elf_backend_ecoff_debug_swap    &mips_elf64_ecoff_debug_swap
2131
#define elf_backend_add_symbol_hook     _bfd_mips_elf_add_symbol_hook
2132
#define elf_backend_create_dynamic_sections \
2133
                                        _bfd_mips_elf_create_dynamic_sections
2134
#define elf_backend_check_relocs        _bfd_mips_elf_check_relocs
2135
#define elf_backend_adjust_dynamic_symbol \
2136
                                        _bfd_mips_elf_adjust_dynamic_symbol
2137
#define elf_backend_always_size_sections \
2138
                                        _bfd_mips_elf_always_size_sections
2139
#define elf_backend_size_dynamic_sections \
2140
                                        _bfd_mips_elf_size_dynamic_sections
2141
#define elf_backend_relocate_section    _bfd_mips_elf_relocate_section
2142
#define elf_backend_link_output_symbol_hook \
2143
                                        _bfd_mips_elf_link_output_symbol_hook
2144
#define elf_backend_finish_dynamic_symbol \
2145
                                        _bfd_mips_elf_finish_dynamic_symbol
2146
#define elf_backend_finish_dynamic_sections \
2147
                                        _bfd_mips_elf_finish_dynamic_sections
2148
#define elf_backend_gc_mark_hook        _bfd_mips_elf_gc_mark_hook
2149
#define elf_backend_gc_sweep_hook       _bfd_mips_elf_gc_sweep_hook
2150
#define elf_backend_got_header_size     (4*MIPS_RESERVED_GOTNO)
2151
#define elf_backend_plt_header_size     0
2152
#define elf_backend_may_use_rel_p       1
2153
 
2154
/* We don't set bfd_elf64_bfd_is_local_label_name because the 32-bit
2155
   MIPS-specific function only applies to IRIX5, which had no 64-bit
2156
   ABI.  */
2157
#define bfd_elf64_find_nearest_line     _bfd_mips_elf_find_nearest_line
2158
#define bfd_elf64_set_section_contents  _bfd_mips_elf_set_section_contents
2159
#define bfd_elf64_bfd_link_hash_table_create \
2160
                                        _bfd_mips_elf_link_hash_table_create
2161
#define bfd_elf64_bfd_final_link        _bfd_mips_elf_final_link
2162
#define bfd_elf64_bfd_copy_private_bfd_data \
2163
                                        _bfd_mips_elf_copy_private_bfd_data
2164
#define bfd_elf64_bfd_merge_private_bfd_data \
2165
                                        _bfd_mips_elf_merge_private_bfd_data
2166
#define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags
2167
#define bfd_elf64_bfd_print_private_bfd_data \
2168
                                        _bfd_mips_elf_print_private_bfd_data
2169
 
2170
#define bfd_elf64_get_reloc_upper_bound mips_elf64_get_reloc_upper_bound
2171
#define bfd_elf64_bfd_reloc_type_lookup mips_elf64_reloc_type_lookup
2172
#define bfd_elf64_archive_functions
2173
#define bfd_elf64_archive_slurp_armap   mips_elf64_slurp_armap
2174
#define bfd_elf64_archive_slurp_extended_name_table \
2175
                                _bfd_archive_coff_slurp_extended_name_table
2176
#define bfd_elf64_archive_construct_extended_name_table \
2177
                                _bfd_archive_coff_construct_extended_name_table
2178
#define bfd_elf64_archive_truncate_arname \
2179
                                        _bfd_archive_coff_truncate_arname
2180
#define bfd_elf64_archive_write_armap   mips_elf64_write_armap
2181
#define bfd_elf64_archive_read_ar_hdr   _bfd_archive_coff_read_ar_hdr
2182
#define bfd_elf64_archive_openr_next_archived_file \
2183
                                _bfd_archive_coff_openr_next_archived_file
2184
#define bfd_elf64_archive_get_elt_at_index \
2185
                                        _bfd_archive_coff_get_elt_at_index
2186
#define bfd_elf64_archive_generic_stat_arch_elt \
2187
                                        _bfd_archive_coff_generic_stat_arch_elt
2188
#define bfd_elf64_archive_update_armap_timestamp \
2189
                                _bfd_archive_coff_update_armap_timestamp
2190
 
2191
#include "elf64-target.h"
2192
 
2193
/* Support for traditional mips targets */
2194
 
2195
#define INCLUDED_TARGET_FILE            /* More a type of flag */
2196
 
2197
#undef TARGET_LITTLE_SYM
2198
#undef TARGET_LITTLE_NAME
2199
#undef TARGET_BIG_SYM
2200
#undef TARGET_BIG_NAME
2201
 
2202
#define TARGET_LITTLE_SYM               bfd_elf64_tradlittlemips_vec
2203
#define TARGET_LITTLE_NAME              "elf64-tradlittlemips"
2204
#define TARGET_BIG_SYM                  bfd_elf64_tradbigmips_vec
2205
#define TARGET_BIG_NAME                 "elf64-tradbigmips"
2206
 
2207
/* Include the target file again for this target */
2208
#include "elf64-target.h"

powered by: WebSVN 2.1.0

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