~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to binutils/bfd/elf64-mips.c

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

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