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

Subversion Repositories open8_urisc

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

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

Line No. Rev Author Line
1 14 khays
/* MIPS-specific support for 32-bit ELF
2
   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3
   2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4
 
5
   Most of the information added by Ian Lance Taylor, Cygnus Support,
6
   <ian@cygnus.com>.
7
   N32/64 ABI support added by Mark Mitchell, CodeSourcery, LLC.
8
   <mark@codesourcery.com>
9
   Traditional MIPS targets support added by Koundinya.K, Dansk Data
10
   Elektronik & Operations Research Group. <kk@ddeorg.soft.net>
11
 
12
   This file is part of BFD, the Binary File Descriptor library.
13
 
14
   This program is free software; you can redistribute it and/or modify
15
   it under the terms of the GNU General Public License as published by
16
   the Free Software Foundation; either version 3 of the License, or
17
   (at your option) any later version.
18
 
19
   This program is distributed in the hope that it will be useful,
20
   but WITHOUT ANY WARRANTY; without even the implied warranty of
21
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
   GNU General Public License for more details.
23
 
24
   You should have received a copy of the GNU General Public License
25
   along with this program; if not, write to the Free Software
26
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
27
   MA 02110-1301, USA.  */
28
 
29
 
30
/* This file handles MIPS ELF targets.  SGI Irix 5 uses a slightly
31
   different MIPS ELF from other targets.  This matters when linking.
32
   This file supports both, switching at runtime.  */
33
 
34
#include "sysdep.h"
35
#include "bfd.h"
36
#include "libbfd.h"
37
#include "bfdlink.h"
38
#include "genlink.h"
39
#include "elf-bfd.h"
40
#include "elfxx-mips.h"
41
#include "elf/mips.h"
42
#include "elf-vxworks.h"
43
 
44
/* Get the ECOFF swapping routines.  */
45
#include "coff/sym.h"
46
#include "coff/symconst.h"
47
#include "coff/internal.h"
48
#include "coff/ecoff.h"
49
#include "coff/mips.h"
50
#define ECOFF_SIGNED_32
51
#include "ecoffswap.h"
52
 
53
static bfd_reloc_status_type gprel32_with_gp
54
  (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma);
55
static bfd_reloc_status_type mips_elf_gprel32_reloc
56
  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
57
static bfd_reloc_status_type mips32_64bit_reloc
58
  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
59
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
60
  (bfd *, bfd_reloc_code_real_type);
61
static reloc_howto_type *mips_elf32_rtype_to_howto
62
  (unsigned int, bfd_boolean);
63
static void mips_info_to_howto_rel
64
  (bfd *, arelent *, Elf_Internal_Rela *);
65
static void mips_info_to_howto_rela
66
  (bfd *, arelent *, Elf_Internal_Rela *);
67
static bfd_boolean mips_elf_sym_is_global
68
  (bfd *, asymbol *);
69
static bfd_boolean mips_elf32_object_p
70
  (bfd *);
71
static bfd_boolean mips_elf_is_local_label_name
72
  (bfd *, const char *);
73
static bfd_reloc_status_type mips16_gprel_reloc
74
  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
75
static bfd_reloc_status_type mips_elf_final_gp
76
  (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
77
static bfd_boolean mips_elf_assign_gp
78
  (bfd *, bfd_vma *);
79
static bfd_boolean elf32_mips_grok_prstatus
80
  (bfd *, Elf_Internal_Note *);
81
static bfd_boolean elf32_mips_grok_psinfo
82
  (bfd *, Elf_Internal_Note *);
83
static irix_compat_t elf32_mips_irix_compat
84
  (bfd *);
85
 
86
extern const bfd_target bfd_elf32_bigmips_vec;
87
extern const bfd_target bfd_elf32_littlemips_vec;
88
 
89
/* Nonzero if ABFD is using the N32 ABI.  */
90
#define ABI_N32_P(abfd) \
91
  ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
92
 
93
/* Whether we are trying to be compatible with IRIX at all.  */
94
#define SGI_COMPAT(abfd) \
95
  (elf32_mips_irix_compat (abfd) != ict_none)
96
 
97
/* The number of local .got entries we reserve.  */
98
#define MIPS_RESERVED_GOTNO (2)
99
 
100
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
101
   from smaller values.  Start with zero, widen, *then* decrement.  */
102
#define MINUS_ONE       (((bfd_vma)0) - 1)
103
 
104
/* The relocation table used for SHT_REL sections.  */
105
 
106
static reloc_howto_type elf_mips_howto_table_rel[] =
107
{
108
  /* No relocation.  */
109
  HOWTO (R_MIPS_NONE,           /* type */
110
         0,                      /* rightshift */
111
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
112
         0,                      /* bitsize */
113
         FALSE,                 /* pc_relative */
114
         0,                      /* bitpos */
115
         complain_overflow_dont, /* complain_on_overflow */
116
         _bfd_mips_elf_generic_reloc, /* special_function */
117
         "R_MIPS_NONE",         /* name */
118
         FALSE,                 /* partial_inplace */
119
         0,                      /* src_mask */
120
         0,                      /* dst_mask */
121
         FALSE),                /* pcrel_offset */
122
 
123
  /* 16 bit relocation.  */
124
  HOWTO (R_MIPS_16,             /* type */
125
         0,                      /* rightshift */
126
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
127
         16,                    /* bitsize */
128
         FALSE,                 /* pc_relative */
129
         0,                      /* bitpos */
130
         complain_overflow_signed, /* complain_on_overflow */
131
         _bfd_mips_elf_generic_reloc, /* special_function */
132
         "R_MIPS_16",           /* name */
133
         TRUE,                  /* partial_inplace */
134
         0x0000ffff,            /* src_mask */
135
         0x0000ffff,            /* dst_mask */
136
         FALSE),                /* pcrel_offset */
137
 
138
  /* 32 bit relocation.  */
139
  HOWTO (R_MIPS_32,             /* type */
140
         0,                      /* rightshift */
141
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
142
         32,                    /* bitsize */
143
         FALSE,                 /* pc_relative */
144
         0,                      /* bitpos */
145
         complain_overflow_dont, /* complain_on_overflow */
146
         _bfd_mips_elf_generic_reloc, /* special_function */
147
         "R_MIPS_32",           /* name */
148
         TRUE,                  /* partial_inplace */
149
         0xffffffff,            /* src_mask */
150
         0xffffffff,            /* dst_mask */
151
         FALSE),                /* pcrel_offset */
152
 
153
  /* 32 bit symbol relative relocation.  */
154
  HOWTO (R_MIPS_REL32,          /* type */
155
         0,                      /* rightshift */
156
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
157
         32,                    /* bitsize */
158
         FALSE,                 /* pc_relative */
159
         0,                      /* bitpos */
160
         complain_overflow_dont, /* complain_on_overflow */
161
         _bfd_mips_elf_generic_reloc, /* special_function */
162
         "R_MIPS_REL32",        /* name */
163
         TRUE,                  /* partial_inplace */
164
         0xffffffff,            /* src_mask */
165
         0xffffffff,            /* dst_mask */
166
         FALSE),                /* pcrel_offset */
167
 
168
  /* 26 bit jump address.  */
169
  HOWTO (R_MIPS_26,             /* type */
170
         2,                     /* rightshift */
171
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
172
         26,                    /* bitsize */
173
         FALSE,                 /* pc_relative */
174
         0,                      /* bitpos */
175
         complain_overflow_dont, /* complain_on_overflow */
176
                                /* This needs complex overflow
177
                                   detection, because the upper four
178
                                   bits must match the PC + 4.  */
179
         _bfd_mips_elf_generic_reloc, /* special_function */
180
         "R_MIPS_26",           /* name */
181
         TRUE,                  /* partial_inplace */
182
         0x03ffffff,            /* src_mask */
183
         0x03ffffff,            /* dst_mask */
184
         FALSE),                /* pcrel_offset */
185
 
186
  /* High 16 bits of symbol value.  */
187
  HOWTO (R_MIPS_HI16,           /* type */
188
         16,                    /* rightshift */
189
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
190
         16,                    /* bitsize */
191
         FALSE,                 /* pc_relative */
192
         0,                      /* bitpos */
193
         complain_overflow_dont, /* complain_on_overflow */
194
         _bfd_mips_elf_hi16_reloc, /* special_function */
195
         "R_MIPS_HI16",         /* name */
196
         TRUE,                  /* partial_inplace */
197
         0x0000ffff,            /* src_mask */
198
         0x0000ffff,            /* dst_mask */
199
         FALSE),                /* pcrel_offset */
200
 
201
  /* Low 16 bits of symbol value.  */
202
  HOWTO (R_MIPS_LO16,           /* type */
203
         0,                      /* rightshift */
204
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
205
         16,                    /* bitsize */
206
         FALSE,                 /* pc_relative */
207
         0,                      /* bitpos */
208
         complain_overflow_dont, /* complain_on_overflow */
209
         _bfd_mips_elf_lo16_reloc, /* special_function */
210
         "R_MIPS_LO16",         /* name */
211
         TRUE,                  /* partial_inplace */
212
         0x0000ffff,            /* src_mask */
213
         0x0000ffff,            /* dst_mask */
214
         FALSE),                /* pcrel_offset */
215
 
216
  /* GP relative reference.  */
217
  HOWTO (R_MIPS_GPREL16,        /* type */
218
         0,                      /* rightshift */
219
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
220
         16,                    /* bitsize */
221
         FALSE,                 /* pc_relative */
222
         0,                      /* bitpos */
223
         complain_overflow_signed, /* complain_on_overflow */
224
         _bfd_mips_elf32_gprel16_reloc, /* special_function */
225
         "R_MIPS_GPREL16",      /* name */
226
         TRUE,                  /* partial_inplace */
227
         0x0000ffff,            /* src_mask */
228
         0x0000ffff,            /* dst_mask */
229
         FALSE),                /* pcrel_offset */
230
 
231
  /* Reference to literal section.  */
232
  HOWTO (R_MIPS_LITERAL,        /* type */
233
         0,                      /* rightshift */
234
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
235
         16,                    /* bitsize */
236
         FALSE,                 /* pc_relative */
237
         0,                      /* bitpos */
238
         complain_overflow_signed, /* complain_on_overflow */
239
         _bfd_mips_elf32_gprel16_reloc, /* special_function */
240
         "R_MIPS_LITERAL",      /* name */
241
         TRUE,                  /* partial_inplace */
242
         0x0000ffff,            /* src_mask */
243
         0x0000ffff,            /* dst_mask */
244
         FALSE),                /* pcrel_offset */
245
 
246
  /* Reference to global offset table.  */
247
  HOWTO (R_MIPS_GOT16,          /* type */
248
         0,                      /* rightshift */
249
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
250
         16,                    /* bitsize */
251
         FALSE,                 /* pc_relative */
252
         0,                      /* bitpos */
253
         complain_overflow_signed, /* complain_on_overflow */
254
         _bfd_mips_elf_got16_reloc, /* special_function */
255
         "R_MIPS_GOT16",        /* name */
256
         TRUE,                  /* partial_inplace */
257
         0x0000ffff,            /* src_mask */
258
         0x0000ffff,            /* dst_mask */
259
         FALSE),                /* pcrel_offset */
260
 
261
  /* 16 bit PC relative reference.  Note that the ABI document has a typo
262
     and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
263
     We do the right thing here.  */
264
  HOWTO (R_MIPS_PC16,           /* type */
265
         2,                     /* rightshift */
266
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
267
         16,                    /* bitsize */
268
         TRUE,                  /* pc_relative */
269
         0,                      /* bitpos */
270
         complain_overflow_signed, /* complain_on_overflow */
271
         _bfd_mips_elf_generic_reloc, /* special_function */
272
         "R_MIPS_PC16",         /* name */
273
         TRUE,                  /* partial_inplace */
274
         0x0000ffff,            /* src_mask */
275
         0x0000ffff,            /* dst_mask */
276
         TRUE),                 /* pcrel_offset */
277
 
278
  /* 16 bit call through global offset table.  */
279
  HOWTO (R_MIPS_CALL16,         /* type */
280
         0,                      /* rightshift */
281
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
282
         16,                    /* bitsize */
283
         FALSE,                 /* pc_relative */
284
         0,                      /* bitpos */
285
         complain_overflow_signed, /* complain_on_overflow */
286
         _bfd_mips_elf_generic_reloc, /* special_function */
287
         "R_MIPS_CALL16",       /* name */
288
         TRUE,                  /* partial_inplace */
289
         0x0000ffff,            /* src_mask */
290
         0x0000ffff,            /* dst_mask */
291
         FALSE),                /* pcrel_offset */
292
 
293
  /* 32 bit GP relative reference.  */
294
  HOWTO (R_MIPS_GPREL32,        /* type */
295
         0,                      /* rightshift */
296
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
297
         32,                    /* bitsize */
298
         FALSE,                 /* pc_relative */
299
         0,                      /* bitpos */
300
         complain_overflow_dont, /* complain_on_overflow */
301
         mips_elf_gprel32_reloc, /* special_function */
302
         "R_MIPS_GPREL32",      /* name */
303
         TRUE,                  /* partial_inplace */
304
         0xffffffff,            /* src_mask */
305
         0xffffffff,            /* dst_mask */
306
         FALSE),                /* pcrel_offset */
307
 
308
  /* The remaining relocs are defined on Irix 5, although they are
309
     not defined by the ABI.  */
310
  EMPTY_HOWTO (13),
311
  EMPTY_HOWTO (14),
312
  EMPTY_HOWTO (15),
313
 
314
  /* A 5 bit shift field.  */
315
  HOWTO (R_MIPS_SHIFT5,         /* type */
316
         0,                      /* rightshift */
317
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
318
         5,                     /* bitsize */
319
         FALSE,                 /* pc_relative */
320
         6,                     /* bitpos */
321
         complain_overflow_bitfield, /* complain_on_overflow */
322
         _bfd_mips_elf_generic_reloc, /* special_function */
323
         "R_MIPS_SHIFT5",       /* name */
324
         TRUE,                  /* partial_inplace */
325
         0x000007c0,            /* src_mask */
326
         0x000007c0,            /* dst_mask */
327
         FALSE),                /* pcrel_offset */
328
 
329
  /* A 6 bit shift field.  */
330
  /* FIXME: This is not handled correctly; a special function is
331
     needed to put the most significant bit in the right place.  */
332
  HOWTO (R_MIPS_SHIFT6,         /* type */
333
         0,                      /* rightshift */
334
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
335
         6,                     /* bitsize */
336
         FALSE,                 /* pc_relative */
337
         6,                     /* bitpos */
338
         complain_overflow_bitfield, /* complain_on_overflow */
339
         _bfd_mips_elf_generic_reloc, /* special_function */
340
         "R_MIPS_SHIFT6",       /* name */
341
         TRUE,                  /* partial_inplace */
342
         0x000007c4,            /* src_mask */
343
         0x000007c4,            /* dst_mask */
344
         FALSE),                /* pcrel_offset */
345
 
346
  /* A 64 bit relocation.  */
347
  HOWTO (R_MIPS_64,             /* type */
348
         0,                      /* rightshift */
349
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
350
         64,                    /* bitsize */
351
         FALSE,                 /* pc_relative */
352
         0,                      /* bitpos */
353
         complain_overflow_dont, /* complain_on_overflow */
354
         mips32_64bit_reloc,    /* special_function */
355
         "R_MIPS_64",           /* name */
356
         TRUE,                  /* partial_inplace */
357
         MINUS_ONE,             /* src_mask */
358
         MINUS_ONE,             /* dst_mask */
359
         FALSE),                /* pcrel_offset */
360
 
361
  /* Displacement in the global offset table.  */
362
  HOWTO (R_MIPS_GOT_DISP,       /* type */
363
         0,                      /* rightshift */
364
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
365
         16,                    /* bitsize */
366
         FALSE,                 /* pc_relative */
367
         0,                      /* bitpos */
368
         complain_overflow_signed, /* complain_on_overflow */
369
         _bfd_mips_elf_generic_reloc, /* special_function */
370
         "R_MIPS_GOT_DISP",     /* name */
371
         TRUE,                  /* partial_inplace */
372
         0x0000ffff,            /* src_mask */
373
         0x0000ffff,            /* dst_mask */
374
         FALSE),                /* pcrel_offset */
375
 
376
  /* Displacement to page pointer in the global offset table.  */
377
  HOWTO (R_MIPS_GOT_PAGE,       /* type */
378
         0,                      /* rightshift */
379
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
380
         16,                    /* bitsize */
381
         FALSE,                 /* pc_relative */
382
         0,                      /* bitpos */
383
         complain_overflow_signed, /* complain_on_overflow */
384
         _bfd_mips_elf_generic_reloc, /* special_function */
385
         "R_MIPS_GOT_PAGE",     /* name */
386
         TRUE,                  /* partial_inplace */
387
         0x0000ffff,            /* src_mask */
388
         0x0000ffff,            /* dst_mask */
389
         FALSE),                /* pcrel_offset */
390
 
391
  /* Offset from page pointer in the global offset table.  */
392
  HOWTO (R_MIPS_GOT_OFST,       /* type */
393
         0,                      /* rightshift */
394
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
395
         16,                    /* bitsize */
396
         FALSE,                 /* pc_relative */
397
         0,                      /* bitpos */
398
         complain_overflow_signed, /* complain_on_overflow */
399
         _bfd_mips_elf_generic_reloc, /* special_function */
400
         "R_MIPS_GOT_OFST",     /* name */
401
         TRUE,                  /* partial_inplace */
402
         0x0000ffff,            /* src_mask */
403
         0x0000ffff,            /* dst_mask */
404
         FALSE),                /* pcrel_offset */
405
 
406
  /* High 16 bits of displacement in global offset table.  */
407
  HOWTO (R_MIPS_GOT_HI16,       /* type */
408
         0,                      /* rightshift */
409
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
410
         16,                    /* bitsize */
411
         FALSE,                 /* pc_relative */
412
         0,                      /* bitpos */
413
         complain_overflow_dont, /* complain_on_overflow */
414
         _bfd_mips_elf_generic_reloc, /* special_function */
415
         "R_MIPS_GOT_HI16",     /* name */
416
         TRUE,                  /* partial_inplace */
417
         0x0000ffff,            /* src_mask */
418
         0x0000ffff,            /* dst_mask */
419
         FALSE),                /* pcrel_offset */
420
 
421
  /* Low 16 bits of displacement in global offset table.  */
422
  HOWTO (R_MIPS_GOT_LO16,       /* type */
423
         0,                      /* rightshift */
424
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
425
         16,                    /* bitsize */
426
         FALSE,                 /* pc_relative */
427
         0,                      /* bitpos */
428
         complain_overflow_dont, /* complain_on_overflow */
429
         _bfd_mips_elf_generic_reloc, /* special_function */
430
         "R_MIPS_GOT_LO16",     /* name */
431
         TRUE,                  /* partial_inplace */
432
         0x0000ffff,            /* src_mask */
433
         0x0000ffff,            /* dst_mask */
434
         FALSE),                /* pcrel_offset */
435
 
436
  /* 64 bit subtraction.  Used in the N32 ABI.  */
437
  HOWTO (R_MIPS_SUB,            /* type */
438
         0,                      /* rightshift */
439
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
440
         64,                    /* bitsize */
441
         FALSE,                 /* pc_relative */
442
         0,                      /* bitpos */
443
         complain_overflow_dont, /* complain_on_overflow */
444
         _bfd_mips_elf_generic_reloc, /* special_function */
445
         "R_MIPS_SUB",          /* name */
446
         TRUE,                  /* partial_inplace */
447
         MINUS_ONE,             /* src_mask */
448
         MINUS_ONE,             /* dst_mask */
449
         FALSE),                /* pcrel_offset */
450
 
451
  /* Used to cause the linker to insert and delete instructions?  */
452
  EMPTY_HOWTO (R_MIPS_INSERT_A),
453
  EMPTY_HOWTO (R_MIPS_INSERT_B),
454
  EMPTY_HOWTO (R_MIPS_DELETE),
455
 
456
  /* Get the higher value of a 64 bit addend.  */
457
  HOWTO (R_MIPS_HIGHER,         /* type */
458
         0,                      /* rightshift */
459
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
460
         16,                    /* bitsize */
461
         FALSE,                 /* pc_relative */
462
         0,                      /* bitpos */
463
         complain_overflow_dont, /* complain_on_overflow */
464
         _bfd_mips_elf_generic_reloc, /* special_function */
465
         "R_MIPS_HIGHER",       /* name */
466
         TRUE,                  /* partial_inplace */
467
         0x0000ffff,            /* src_mask */
468
         0x0000ffff,            /* dst_mask */
469
         FALSE),                /* pcrel_offset */
470
 
471
  /* Get the highest value of a 64 bit addend.  */
472
  HOWTO (R_MIPS_HIGHEST,        /* type */
473
         0,                      /* rightshift */
474
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
475
         16,                    /* bitsize */
476
         FALSE,                 /* pc_relative */
477
         0,                      /* bitpos */
478
         complain_overflow_dont, /* complain_on_overflow */
479
         _bfd_mips_elf_generic_reloc, /* special_function */
480
         "R_MIPS_HIGHEST",      /* name */
481
         TRUE,                  /* partial_inplace */
482
         0x0000ffff,            /* src_mask */
483
         0x0000ffff,            /* dst_mask */
484
         FALSE),                /* pcrel_offset */
485
 
486
  /* High 16 bits of displacement in global offset table.  */
487
  HOWTO (R_MIPS_CALL_HI16,      /* type */
488
         0,                      /* rightshift */
489
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
490
         16,                    /* bitsize */
491
         FALSE,                 /* pc_relative */
492
         0,                      /* bitpos */
493
         complain_overflow_dont, /* complain_on_overflow */
494
         _bfd_mips_elf_generic_reloc, /* special_function */
495
         "R_MIPS_CALL_HI16",    /* name */
496
         TRUE,                  /* partial_inplace */
497
         0x0000ffff,            /* src_mask */
498
         0x0000ffff,            /* dst_mask */
499
         FALSE),                /* pcrel_offset */
500
 
501
  /* Low 16 bits of displacement in global offset table.  */
502
  HOWTO (R_MIPS_CALL_LO16,      /* type */
503
         0,                      /* rightshift */
504
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
505
         16,                    /* bitsize */
506
         FALSE,                 /* pc_relative */
507
         0,                      /* bitpos */
508
         complain_overflow_dont, /* complain_on_overflow */
509
         _bfd_mips_elf_generic_reloc, /* special_function */
510
         "R_MIPS_CALL_LO16",    /* name */
511
         TRUE,                  /* partial_inplace */
512
         0x0000ffff,            /* src_mask */
513
         0x0000ffff,            /* dst_mask */
514
         FALSE),                /* pcrel_offset */
515
 
516
  /* Section displacement.  */
517
  HOWTO (R_MIPS_SCN_DISP,       /* type */
518
         0,                      /* rightshift */
519
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
520
         32,                    /* bitsize */
521
         FALSE,                 /* pc_relative */
522
         0,                      /* bitpos */
523
         complain_overflow_dont, /* complain_on_overflow */
524
         _bfd_mips_elf_generic_reloc, /* special_function */
525
         "R_MIPS_SCN_DISP",     /* name */
526
         TRUE,                  /* partial_inplace */
527
         0xffffffff,            /* src_mask */
528
         0xffffffff,            /* dst_mask */
529
         FALSE),                /* pcrel_offset */
530
 
531
  EMPTY_HOWTO (R_MIPS_REL16),
532
  EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
533
  EMPTY_HOWTO (R_MIPS_PJUMP),
534
  EMPTY_HOWTO (R_MIPS_RELGOT),
535
 
536
  /* Protected jump conversion.  This is an optimization hint.  No
537
     relocation is required for correctness.  */
538
  HOWTO (R_MIPS_JALR,           /* type */
539
         0,                      /* rightshift */
540
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
541
         32,                    /* bitsize */
542
         FALSE,                 /* pc_relative */
543
         0,                      /* bitpos */
544
         complain_overflow_dont, /* complain_on_overflow */
545
         _bfd_mips_elf_generic_reloc, /* special_function */
546
         "R_MIPS_JALR",         /* name */
547
         FALSE,                 /* partial_inplace */
548
         0x00000000,            /* src_mask */
549
         0x00000000,            /* dst_mask */
550
         FALSE),                /* pcrel_offset */
551
 
552
  /* TLS GD/LD dynamic relocations.  */
553
  HOWTO (R_MIPS_TLS_DTPMOD32,   /* type */
554
         0,                      /* rightshift */
555
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
556
         32,                    /* bitsize */
557
         FALSE,                 /* pc_relative */
558
         0,                      /* bitpos */
559
         complain_overflow_dont, /* complain_on_overflow */
560
         _bfd_mips_elf_generic_reloc, /* special_function */
561
         "R_MIPS_TLS_DTPMOD32", /* name */
562
         TRUE,                  /* partial_inplace */
563
         0xffffffff,            /* src_mask */
564
         0xffffffff,            /* dst_mask */
565
         FALSE),                /* pcrel_offset */
566
 
567
  HOWTO (R_MIPS_TLS_DTPREL32,   /* type */
568
         0,                      /* rightshift */
569
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
570
         32,                    /* bitsize */
571
         FALSE,                 /* pc_relative */
572
         0,                      /* bitpos */
573
         complain_overflow_dont, /* complain_on_overflow */
574
         _bfd_mips_elf_generic_reloc, /* special_function */
575
         "R_MIPS_TLS_DTPREL32", /* name */
576
         TRUE,                  /* partial_inplace */
577
         0xffffffff,            /* src_mask */
578
         0xffffffff,            /* dst_mask */
579
         FALSE),                /* pcrel_offset */
580
 
581
  EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
582
  EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
583
 
584
  /* TLS general dynamic variable reference.  */
585
  HOWTO (R_MIPS_TLS_GD,         /* type */
586
         0,                      /* rightshift */
587
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
588
         16,                    /* bitsize */
589
         FALSE,                 /* pc_relative */
590
         0,                      /* bitpos */
591
         complain_overflow_signed, /* complain_on_overflow */
592
         _bfd_mips_elf_generic_reloc, /* special_function */
593
         "R_MIPS_TLS_GD",       /* name */
594
         TRUE,                  /* partial_inplace */
595
         0x0000ffff,            /* src_mask */
596
         0x0000ffff,            /* dst_mask */
597
         FALSE),                /* pcrel_offset */
598
 
599
  /* TLS local dynamic variable reference.  */
600
  HOWTO (R_MIPS_TLS_LDM,        /* type */
601
         0,                      /* rightshift */
602
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
603
         16,                    /* bitsize */
604
         FALSE,                 /* pc_relative */
605
         0,                      /* bitpos */
606
         complain_overflow_signed, /* complain_on_overflow */
607
         _bfd_mips_elf_generic_reloc, /* special_function */
608
         "R_MIPS_TLS_LDM",      /* name */
609
         TRUE,                  /* partial_inplace */
610
         0x0000ffff,            /* src_mask */
611
         0x0000ffff,            /* dst_mask */
612
         FALSE),                /* pcrel_offset */
613
 
614
  /* TLS local dynamic offset.  */
615
  HOWTO (R_MIPS_TLS_DTPREL_HI16,        /* type */
616
         0,                      /* rightshift */
617
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
618
         16,                    /* bitsize */
619
         FALSE,                 /* pc_relative */
620
         0,                      /* bitpos */
621
         complain_overflow_signed, /* complain_on_overflow */
622
         _bfd_mips_elf_generic_reloc, /* special_function */
623
         "R_MIPS_TLS_DTPREL_HI16",      /* name */
624
         TRUE,                  /* partial_inplace */
625
         0x0000ffff,            /* src_mask */
626
         0x0000ffff,            /* dst_mask */
627
         FALSE),                /* pcrel_offset */
628
 
629
  /* TLS local dynamic offset.  */
630
  HOWTO (R_MIPS_TLS_DTPREL_LO16,        /* type */
631
         0,                      /* rightshift */
632
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
633
         16,                    /* bitsize */
634
         FALSE,                 /* pc_relative */
635
         0,                      /* bitpos */
636
         complain_overflow_signed, /* complain_on_overflow */
637
         _bfd_mips_elf_generic_reloc, /* special_function */
638
         "R_MIPS_TLS_DTPREL_LO16",      /* name */
639
         TRUE,                  /* partial_inplace */
640
         0x0000ffff,            /* src_mask */
641
         0x0000ffff,            /* dst_mask */
642
         FALSE),                /* pcrel_offset */
643
 
644
  /* TLS thread pointer offset.  */
645
  HOWTO (R_MIPS_TLS_GOTTPREL,   /* type */
646
         0,                      /* rightshift */
647
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
648
         16,                    /* bitsize */
649
         FALSE,                 /* pc_relative */
650
         0,                      /* bitpos */
651
         complain_overflow_signed, /* complain_on_overflow */
652
         _bfd_mips_elf_generic_reloc, /* special_function */
653
         "R_MIPS_TLS_GOTTPREL", /* name */
654
         TRUE,                  /* partial_inplace */
655
         0x0000ffff,            /* src_mask */
656
         0x0000ffff,            /* dst_mask */
657
         FALSE),                /* pcrel_offset */
658
 
659
  /* TLS IE dynamic relocations.  */
660
  HOWTO (R_MIPS_TLS_TPREL32,    /* type */
661
         0,                      /* rightshift */
662
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
663
         32,                    /* bitsize */
664
         FALSE,                 /* pc_relative */
665
         0,                      /* bitpos */
666
         complain_overflow_dont, /* complain_on_overflow */
667
         _bfd_mips_elf_generic_reloc, /* special_function */
668
         "R_MIPS_TLS_TPREL32",  /* name */
669
         TRUE,                  /* partial_inplace */
670
         0xffffffff,            /* src_mask */
671
         0xffffffff,            /* dst_mask */
672
         FALSE),                /* pcrel_offset */
673
 
674
  EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
675
 
676
  /* TLS thread pointer offset.  */
677
  HOWTO (R_MIPS_TLS_TPREL_HI16, /* type */
678
         0,                      /* rightshift */
679
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
680
         16,                    /* bitsize */
681
         FALSE,                 /* pc_relative */
682
         0,                      /* bitpos */
683
         complain_overflow_signed, /* complain_on_overflow */
684
         _bfd_mips_elf_generic_reloc, /* special_function */
685
         "R_MIPS_TLS_TPREL_HI16", /* name */
686
         TRUE,                  /* partial_inplace */
687
         0x0000ffff,            /* src_mask */
688
         0x0000ffff,            /* dst_mask */
689
         FALSE),                /* pcrel_offset */
690
 
691
  /* TLS thread pointer offset.  */
692
  HOWTO (R_MIPS_TLS_TPREL_LO16, /* type */
693
         0,                      /* rightshift */
694
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
695
         16,                    /* bitsize */
696
         FALSE,                 /* pc_relative */
697
         0,                      /* bitpos */
698
         complain_overflow_signed, /* complain_on_overflow */
699
         _bfd_mips_elf_generic_reloc, /* special_function */
700
         "R_MIPS_TLS_TPREL_LO16", /* name */
701
         TRUE,                  /* partial_inplace */
702
         0x0000ffff,            /* src_mask */
703
         0x0000ffff,            /* dst_mask */
704
         FALSE),                /* pcrel_offset */
705
 
706
  /* 32 bit relocation with no addend.  */
707
  HOWTO (R_MIPS_GLOB_DAT,       /* type */
708
         0,                      /* rightshift */
709
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
710
         32,                    /* bitsize */
711
         FALSE,                 /* pc_relative */
712
         0,                      /* bitpos */
713
         complain_overflow_dont, /* complain_on_overflow */
714
         _bfd_mips_elf_generic_reloc, /* special_function */
715
         "R_MIPS_GLOB_DAT",     /* name */
716
         FALSE,                 /* partial_inplace */
717
         0x0,                   /* src_mask */
718
         0xffffffff,            /* dst_mask */
719
         FALSE),                /* pcrel_offset */
720
};
721
 
722
/* The reloc used for BFD_RELOC_CTOR when doing a 64 bit link.  This
723
   is a hack to make the linker think that we need 64 bit values.  */
724
static reloc_howto_type elf_mips_ctor64_howto =
725
  HOWTO (R_MIPS_64,             /* type */
726
         0,                      /* rightshift */
727
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
728
         32,                    /* bitsize */
729
         FALSE,                 /* pc_relative */
730
         0,                      /* bitpos */
731
         complain_overflow_signed, /* complain_on_overflow */
732
         mips32_64bit_reloc,    /* special_function */
733
         "R_MIPS_64",           /* name */
734
         TRUE,                  /* partial_inplace */
735
         0xffffffff,            /* src_mask */
736
         0xffffffff,            /* dst_mask */
737
         FALSE);                /* pcrel_offset */
738
 
739
static reloc_howto_type elf_mips16_howto_table_rel[] =
740
{
741
  /* The reloc used for the mips16 jump instruction.  */
742
  HOWTO (R_MIPS16_26,           /* type */
743
         2,                     /* rightshift */
744
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
745
         26,                    /* bitsize */
746
         FALSE,                 /* pc_relative */
747
         0,                      /* bitpos */
748
         complain_overflow_dont, /* complain_on_overflow */
749
                                /* This needs complex overflow
750
                                   detection, because the upper four
751
                                   bits must match the PC.  */
752
         _bfd_mips_elf_generic_reloc, /* special_function */
753
         "R_MIPS16_26",         /* name */
754
         TRUE,                  /* partial_inplace */
755
         0x3ffffff,             /* src_mask */
756
         0x3ffffff,             /* dst_mask */
757
         FALSE),                /* pcrel_offset */
758
 
759
  /* The reloc used for the mips16 gprel instruction.  */
760
  HOWTO (R_MIPS16_GPREL,        /* type */
761
         0,                      /* rightshift */
762
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
763
         16,                    /* bitsize */
764
         FALSE,                 /* pc_relative */
765
         0,                      /* bitpos */
766
         complain_overflow_signed, /* complain_on_overflow */
767
         mips16_gprel_reloc,    /* special_function */
768
         "R_MIPS16_GPREL",      /* name */
769
         TRUE,                  /* partial_inplace */
770
         0x0000ffff,            /* src_mask */
771
         0x0000ffff,            /* dst_mask */
772
         FALSE),                /* pcrel_offset */
773
 
774
  /* A MIPS16 reference to the global offset table.  */
775
  HOWTO (R_MIPS16_GOT16,        /* type */
776
         0,                      /* rightshift */
777
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
778
         16,                    /* bitsize */
779
         FALSE,                 /* pc_relative */
780
         0,                      /* bitpos */
781
         complain_overflow_dont, /* complain_on_overflow */
782
         _bfd_mips_elf_got16_reloc, /* special_function */
783
         "R_MIPS16_GOT16",      /* name */
784
         TRUE,                  /* partial_inplace */
785
         0x0000ffff,            /* src_mask */
786
         0x0000ffff,            /* dst_mask */
787
         FALSE),                /* pcrel_offset */
788
 
789
  /* A MIPS16 call through the global offset table.  */
790
  HOWTO (R_MIPS16_CALL16,       /* type */
791
         0,                      /* rightshift */
792
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
793
         16,                    /* bitsize */
794
         FALSE,                 /* pc_relative */
795
         0,                      /* bitpos */
796
         complain_overflow_dont, /* complain_on_overflow */
797
         _bfd_mips_elf_generic_reloc, /* special_function */
798
         "R_MIPS16_CALL16",     /* name */
799
         TRUE,                  /* partial_inplace */
800
         0x0000ffff,            /* src_mask */
801
         0x0000ffff,            /* dst_mask */
802
         FALSE),                /* pcrel_offset */
803
 
804
  /* MIPS16 high 16 bits of symbol value.  */
805
  HOWTO (R_MIPS16_HI16,         /* type */
806
         16,                    /* rightshift */
807
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
808
         16,                    /* bitsize */
809
         FALSE,                 /* pc_relative */
810
         0,                      /* bitpos */
811
         complain_overflow_dont, /* complain_on_overflow */
812
         _bfd_mips_elf_hi16_reloc, /* special_function */
813
         "R_MIPS16_HI16",       /* name */
814
         TRUE,                  /* partial_inplace */
815
         0x0000ffff,            /* src_mask */
816
         0x0000ffff,            /* dst_mask */
817
         FALSE),                /* pcrel_offset */
818
 
819
  /* MIPS16 low 16 bits of symbol value.  */
820
  HOWTO (R_MIPS16_LO16,         /* type */
821
         0,                      /* rightshift */
822
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
823
         16,                    /* bitsize */
824
         FALSE,                 /* pc_relative */
825
         0,                      /* bitpos */
826
         complain_overflow_dont, /* complain_on_overflow */
827
         _bfd_mips_elf_lo16_reloc, /* special_function */
828
         "R_MIPS16_LO16",       /* name */
829
         TRUE,                  /* partial_inplace */
830
         0x0000ffff,            /* src_mask */
831
         0x0000ffff,            /* dst_mask */
832
         FALSE),                /* pcrel_offset */
833
};
834
 
835 161 khays
static reloc_howto_type elf_micromips_howto_table_rel[] =
836
{
837
  EMPTY_HOWTO (130),
838
  EMPTY_HOWTO (131),
839
  EMPTY_HOWTO (132),
840
 
841
  /* 26 bit jump address.  */
842
  HOWTO (R_MICROMIPS_26_S1,     /* type */
843
         1,                     /* rightshift */
844
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
845
         26,                    /* bitsize */
846
         FALSE,                 /* pc_relative */
847
         0,                      /* bitpos */
848
         complain_overflow_dont, /* complain_on_overflow */
849
                                /* This needs complex overflow
850
                                   detection, because the upper four
851
                                   bits must match the PC.  */
852
         _bfd_mips_elf_generic_reloc, /* special_function */
853
         "R_MICROMIPS_26_S1",   /* name */
854
         TRUE,                  /* partial_inplace */
855
         0x3ffffff,             /* src_mask */
856
         0x3ffffff,             /* dst_mask */
857
         FALSE),                /* pcrel_offset */
858
 
859
  /* High 16 bits of symbol value.  */
860
  HOWTO (R_MICROMIPS_HI16,      /* type */
861
         16,                    /* rightshift */
862
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
863
         16,                    /* bitsize */
864
         FALSE,                 /* pc_relative */
865
         0,                      /* bitpos */
866
         complain_overflow_dont, /* complain_on_overflow */
867
         _bfd_mips_elf_hi16_reloc, /* special_function */
868
         "R_MICROMIPS_HI16",    /* name */
869
         TRUE,                  /* partial_inplace */
870
         0x0000ffff,            /* src_mask */
871
         0x0000ffff,            /* dst_mask */
872
         FALSE),                /* pcrel_offset */
873
 
874
  /* Low 16 bits of symbol value.  */
875
  HOWTO (R_MICROMIPS_LO16,      /* type */
876
         0,                      /* rightshift */
877
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
878
         16,                    /* bitsize */
879
         FALSE,                 /* pc_relative */
880
         0,                      /* bitpos */
881
         complain_overflow_dont, /* complain_on_overflow */
882
         _bfd_mips_elf_lo16_reloc, /* special_function */
883
         "R_MICROMIPS_LO16",    /* name */
884
         TRUE,                  /* partial_inplace */
885
         0x0000ffff,            /* src_mask */
886
         0x0000ffff,            /* dst_mask */
887
         FALSE),                /* pcrel_offset */
888
 
889
  /* GP relative reference.  */
890
  HOWTO (R_MICROMIPS_GPREL16,   /* type */
891
         0,                      /* rightshift */
892
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
893
         16,                    /* bitsize */
894
         FALSE,                 /* pc_relative */
895
         0,                      /* bitpos */
896
         complain_overflow_signed, /* complain_on_overflow */
897
         _bfd_mips_elf32_gprel16_reloc, /* special_function */
898
         "R_MICROMIPS_GPREL16", /* name */
899
         TRUE,                  /* partial_inplace */
900
         0x0000ffff,            /* src_mask */
901
         0x0000ffff,            /* dst_mask */
902
         FALSE),                /* pcrel_offset */
903
 
904
  /* Reference to literal section.  */
905
  HOWTO (R_MICROMIPS_LITERAL,   /* type */
906
         0,                      /* rightshift */
907
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
908
         16,                    /* bitsize */
909
         FALSE,                 /* pc_relative */
910
         0,                      /* bitpos */
911
         complain_overflow_signed, /* complain_on_overflow */
912
         _bfd_mips_elf32_gprel16_reloc, /* special_function */
913
         "R_MICROMIPS_LITERAL", /* name */
914
         TRUE,                  /* partial_inplace */
915
         0x0000ffff,            /* src_mask */
916
         0x0000ffff,            /* dst_mask */
917
         FALSE),                /* pcrel_offset */
918
 
919
  /* Reference to global offset table.  */
920
  HOWTO (R_MICROMIPS_GOT16,     /* type */
921
         0,                      /* rightshift */
922
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
923
         16,                    /* bitsize */
924
         FALSE,                 /* pc_relative */
925
         0,                      /* bitpos */
926
         complain_overflow_signed, /* complain_on_overflow */
927
         _bfd_mips_elf_got16_reloc, /* special_function */
928
         "R_MICROMIPS_GOT16",   /* name */
929
         TRUE,                  /* partial_inplace */
930
         0x0000ffff,            /* src_mask */
931
         0x0000ffff,            /* dst_mask */
932
         FALSE),                /* pcrel_offset */
933
 
934
  /* This is for microMIPS branches.  */
935
  HOWTO (R_MICROMIPS_PC7_S1,    /* type */
936
         1,                     /* rightshift */
937
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
938
         7,                     /* bitsize */
939
         TRUE,                  /* pc_relative */
940
         0,                      /* bitpos */
941
         complain_overflow_signed, /* complain_on_overflow */
942
         _bfd_mips_elf_generic_reloc, /* special_function */
943
         "R_MICROMIPS_PC7_S1",  /* name */
944
         TRUE,                  /* partial_inplace */
945
         0x0000007f,            /* src_mask */
946
         0x0000007f,            /* dst_mask */
947
         TRUE),                 /* pcrel_offset */
948
 
949
  HOWTO (R_MICROMIPS_PC10_S1,   /* type */
950
         1,                     /* rightshift */
951
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
952
         10,                    /* bitsize */
953
         TRUE,                  /* pc_relative */
954
         0,                      /* bitpos */
955
         complain_overflow_signed, /* complain_on_overflow */
956
         _bfd_mips_elf_generic_reloc, /* special_function */
957
         "R_MICROMIPS_PC10_S1", /* name */
958
         TRUE,                  /* partial_inplace */
959
         0x000003ff,            /* src_mask */
960
         0x000003ff,            /* dst_mask */
961
         TRUE),                 /* pcrel_offset */
962
 
963
  HOWTO (R_MICROMIPS_PC16_S1,   /* type */
964
         1,                     /* rightshift */
965
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
966
         16,                    /* bitsize */
967
         TRUE,                  /* pc_relative */
968
         0,                      /* bitpos */
969
         complain_overflow_signed, /* complain_on_overflow */
970
         _bfd_mips_elf_generic_reloc, /* special_function */
971
         "R_MICROMIPS_PC16_S1", /* name */
972
         TRUE,                  /* partial_inplace */
973
         0x0000ffff,            /* src_mask */
974
         0x0000ffff,            /* dst_mask */
975
         TRUE),                 /* pcrel_offset */
976
 
977
  /* 16 bit call through global offset table.  */
978
  HOWTO (R_MICROMIPS_CALL16,    /* type */
979
         0,                      /* rightshift */
980
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
981
         16,                    /* bitsize */
982
         FALSE,                 /* pc_relative */
983
         0,                      /* bitpos */
984
         complain_overflow_signed, /* complain_on_overflow */
985
         _bfd_mips_elf_generic_reloc, /* special_function */
986
         "R_MICROMIPS_CALL16",  /* name */
987
         TRUE,                  /* partial_inplace */
988
         0x0000ffff,            /* src_mask */
989
         0x0000ffff,            /* dst_mask */
990
         FALSE),                /* pcrel_offset */
991
 
992
  EMPTY_HOWTO (143),
993
  EMPTY_HOWTO (144),
994
 
995
  /* Displacement in the global offset table.  */
996
  HOWTO (R_MICROMIPS_GOT_DISP,  /* type */
997
         0,                      /* rightshift */
998
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
999
         16,                    /* bitsize */
1000
         FALSE,                 /* pc_relative */
1001
         0,                      /* bitpos */
1002
         complain_overflow_signed, /* complain_on_overflow */
1003
         _bfd_mips_elf_generic_reloc, /* special_function */
1004
         "R_MICROMIPS_GOT_DISP",/* name */
1005
         TRUE,                  /* partial_inplace */
1006
         0x0000ffff,            /* src_mask */
1007
         0x0000ffff,            /* dst_mask */
1008
         FALSE),                /* pcrel_offset */
1009
 
1010
  /* Displacement to page pointer in the global offset table.  */
1011
  HOWTO (R_MICROMIPS_GOT_PAGE,  /* type */
1012
         0,                      /* rightshift */
1013
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1014
         16,                    /* bitsize */
1015
         FALSE,                 /* pc_relative */
1016
         0,                      /* bitpos */
1017
         complain_overflow_signed, /* complain_on_overflow */
1018
         _bfd_mips_elf_generic_reloc, /* special_function */
1019
         "R_MICROMIPS_GOT_PAGE",/* name */
1020
         TRUE,                  /* partial_inplace */
1021
         0x0000ffff,            /* src_mask */
1022
         0x0000ffff,            /* dst_mask */
1023
         FALSE),                /* pcrel_offset */
1024
 
1025
  /* Offset from page pointer in the global offset table.  */
1026
  HOWTO (R_MICROMIPS_GOT_OFST,  /* type */
1027
         0,                      /* rightshift */
1028
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1029
         16,                    /* bitsize */
1030
         FALSE,                 /* pc_relative */
1031
         0,                      /* bitpos */
1032
         complain_overflow_signed, /* complain_on_overflow */
1033
         _bfd_mips_elf_generic_reloc, /* special_function */
1034
         "R_MICROMIPS_GOT_OFST",/* name */
1035
         TRUE,                  /* partial_inplace */
1036
         0x0000ffff,            /* src_mask */
1037
         0x0000ffff,            /* dst_mask */
1038
         FALSE),                /* pcrel_offset */
1039
 
1040
  /* High 16 bits of displacement in global offset table.  */
1041
  HOWTO (R_MICROMIPS_GOT_HI16,  /* type */
1042
         0,                      /* rightshift */
1043
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1044
         16,                    /* bitsize */
1045
         FALSE,                 /* pc_relative */
1046
         0,                      /* bitpos */
1047
         complain_overflow_dont, /* complain_on_overflow */
1048
         _bfd_mips_elf_generic_reloc, /* special_function */
1049
         "R_MICROMIPS_GOT_HI16",/* name */
1050
         TRUE,                  /* partial_inplace */
1051
         0x0000ffff,            /* src_mask */
1052
         0x0000ffff,            /* dst_mask */
1053
         FALSE),                /* pcrel_offset */
1054
 
1055
  /* Low 16 bits of displacement in global offset table.  */
1056
  HOWTO (R_MICROMIPS_GOT_LO16,  /* type */
1057
         0,                      /* rightshift */
1058
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1059
         16,                    /* bitsize */
1060
         FALSE,                 /* pc_relative */
1061
         0,                      /* bitpos */
1062
         complain_overflow_dont, /* complain_on_overflow */
1063
         _bfd_mips_elf_generic_reloc, /* special_function */
1064
         "R_MICROMIPS_GOT_LO16",/* name */
1065
         TRUE,                  /* partial_inplace */
1066
         0x0000ffff,            /* src_mask */
1067
         0x0000ffff,            /* dst_mask */
1068
         FALSE),                /* pcrel_offset */
1069
 
1070
  /* 64 bit subtraction.  Used in the N32 ABI.  */
1071
  HOWTO (R_MICROMIPS_SUB,       /* type */
1072
         0,                      /* rightshift */
1073
         4,                     /* size (0 = byte, 1 = short, 2 = long) */
1074
         64,                    /* bitsize */
1075
         FALSE,                 /* pc_relative */
1076
         0,                      /* bitpos */
1077
         complain_overflow_dont, /* complain_on_overflow */
1078
         _bfd_mips_elf_generic_reloc, /* special_function */
1079
         "R_MICROMIPS_SUB",     /* name */
1080
         TRUE,                  /* partial_inplace */
1081
         MINUS_ONE,             /* src_mask */
1082
         MINUS_ONE,             /* dst_mask */
1083
         FALSE),                /* pcrel_offset */
1084
 
1085
  /* Get the higher value of a 64 bit addend.  */
1086
  HOWTO (R_MICROMIPS_HIGHER,    /* type */
1087
         0,                      /* rightshift */
1088
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1089
         16,                    /* bitsize */
1090
         FALSE,                 /* pc_relative */
1091
         0,                      /* bitpos */
1092
         complain_overflow_dont, /* complain_on_overflow */
1093
         _bfd_mips_elf_generic_reloc, /* special_function */
1094
         "R_MICROMIPS_HIGHER",  /* name */
1095
         TRUE,                  /* partial_inplace */
1096
         0x0000ffff,            /* src_mask */
1097
         0x0000ffff,            /* dst_mask */
1098
         FALSE),                /* pcrel_offset */
1099
 
1100
  /* Get the highest value of a 64 bit addend.  */
1101
  HOWTO (R_MICROMIPS_HIGHEST,   /* type */
1102
         0,                      /* rightshift */
1103
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1104
         16,                    /* bitsize */
1105
         FALSE,                 /* pc_relative */
1106
         0,                      /* bitpos */
1107
         complain_overflow_dont, /* complain_on_overflow */
1108
         _bfd_mips_elf_generic_reloc, /* special_function */
1109
         "R_MICROMIPS_HIGHEST", /* name */
1110
         TRUE,                  /* partial_inplace */
1111
         0x0000ffff,            /* src_mask */
1112
         0x0000ffff,            /* dst_mask */
1113
         FALSE),                /* pcrel_offset */
1114
 
1115
  /* High 16 bits of displacement in global offset table.  */
1116
  HOWTO (R_MICROMIPS_CALL_HI16, /* type */
1117
         0,                      /* rightshift */
1118
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1119
         16,                    /* bitsize */
1120
         FALSE,                 /* pc_relative */
1121
         0,                      /* bitpos */
1122
         complain_overflow_dont, /* complain_on_overflow */
1123
         _bfd_mips_elf_generic_reloc, /* special_function */
1124
         "R_MICROMIPS_CALL_HI16",/* name */
1125
         TRUE,                  /* partial_inplace */
1126
         0x0000ffff,            /* src_mask */
1127
         0x0000ffff,            /* dst_mask */
1128
         FALSE),                /* pcrel_offset */
1129
 
1130
  /* Low 16 bits of displacement in global offset table.  */
1131
  HOWTO (R_MICROMIPS_CALL_LO16, /* type */
1132
         0,                      /* rightshift */
1133
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1134
         16,                    /* bitsize */
1135
         FALSE,                 /* pc_relative */
1136
         0,                      /* bitpos */
1137
         complain_overflow_dont, /* complain_on_overflow */
1138
         _bfd_mips_elf_generic_reloc, /* special_function */
1139
         "R_MICROMIPS_CALL_LO16",/* name */
1140
         TRUE,                  /* partial_inplace */
1141
         0x0000ffff,            /* src_mask */
1142
         0x0000ffff,            /* dst_mask */
1143
         FALSE),                /* pcrel_offset */
1144
 
1145
  /* Section displacement.  */
1146
  HOWTO (R_MICROMIPS_SCN_DISP,  /* type */
1147
         0,                      /* rightshift */
1148
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1149
         32,                    /* bitsize */
1150
         FALSE,                 /* pc_relative */
1151
         0,                      /* bitpos */
1152
         complain_overflow_dont, /* complain_on_overflow */
1153
         _bfd_mips_elf_generic_reloc, /* special_function */
1154
         "R_MICROMIPS_SCN_DISP",/* name */
1155
         TRUE,                  /* partial_inplace */
1156
         0xffffffff,            /* src_mask */
1157
         0xffffffff,            /* dst_mask */
1158
         FALSE),                /* pcrel_offset */
1159
 
1160
  /* Protected jump conversion.  This is an optimization hint.  No
1161
     relocation is required for correctness.  */
1162
  HOWTO (R_MICROMIPS_JALR,      /* type */
1163
         0,                      /* rightshift */
1164
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1165
         32,                    /* bitsize */
1166
         FALSE,                 /* pc_relative */
1167
         0,                      /* bitpos */
1168
         complain_overflow_dont, /* complain_on_overflow */
1169
         _bfd_mips_elf_generic_reloc, /* special_function */
1170
         "R_MICROMIPS_JALR",    /* name */
1171
         FALSE,                 /* partial_inplace */
1172
         0x00000000,            /* src_mask */
1173
         0x00000000,            /* dst_mask */
1174
         FALSE),                /* pcrel_offset */
1175
 
1176
  /* Low 16 bits of symbol value.  Note that the high 16 bits of symbol values
1177
     must be zero.  This is used for relaxation.  */
1178
  HOWTO (R_MICROMIPS_HI0_LO16,  /* type */
1179
         0,                      /* rightshift */
1180
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1181
         16,                    /* bitsize */
1182
         FALSE,                 /* pc_relative */
1183
         0,                      /* bitpos */
1184
         complain_overflow_dont, /* complain_on_overflow */
1185
         _bfd_mips_elf_generic_reloc, /* special_function */
1186
         "R_MICROMIPS_HI0_LO16",/* name */
1187
         TRUE,                  /* partial_inplace */
1188
         0x0000ffff,            /* src_mask */
1189
         0x0000ffff,            /* dst_mask */
1190
         FALSE),                /* pcrel_offset */
1191
 
1192
  EMPTY_HOWTO (158),
1193
  EMPTY_HOWTO (159),
1194
  EMPTY_HOWTO (160),
1195
  EMPTY_HOWTO (161),
1196
 
1197
  /* TLS general dynamic variable reference.  */
1198
  HOWTO (R_MICROMIPS_TLS_GD,            /* type */
1199
         0,                      /* rightshift */
1200
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1201
         16,                    /* bitsize */
1202
         FALSE,                 /* pc_relative */
1203
         0,                      /* bitpos */
1204
         complain_overflow_signed, /* complain_on_overflow */
1205
         _bfd_mips_elf_generic_reloc, /* special_function */
1206
         "R_MICROMIPS_TLS_GD",  /* name */
1207
         TRUE,                  /* partial_inplace */
1208
         0x0000ffff,            /* src_mask */
1209
         0x0000ffff,            /* dst_mask */
1210
         FALSE),                /* pcrel_offset */
1211
 
1212
  /* TLS local dynamic variable reference.  */
1213
  HOWTO (R_MICROMIPS_TLS_LDM,   /* type */
1214
         0,                      /* rightshift */
1215
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1216
         16,                    /* bitsize */
1217
         FALSE,                 /* pc_relative */
1218
         0,                      /* bitpos */
1219
         complain_overflow_signed, /* complain_on_overflow */
1220
         _bfd_mips_elf_generic_reloc, /* special_function */
1221
         "R_MICROMIPS_TLS_LDM", /* name */
1222
         TRUE,                  /* partial_inplace */
1223
         0x0000ffff,            /* src_mask */
1224
         0x0000ffff,            /* dst_mask */
1225
         FALSE),                /* pcrel_offset */
1226
 
1227
  /* TLS local dynamic offset.  */
1228
  HOWTO (R_MICROMIPS_TLS_DTPREL_HI16,   /* type */
1229
         0,                      /* rightshift */
1230
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1231
         16,                    /* bitsize */
1232
         FALSE,                 /* pc_relative */
1233
         0,                      /* bitpos */
1234
         complain_overflow_signed, /* complain_on_overflow */
1235
         _bfd_mips_elf_generic_reloc, /* special_function */
1236
         "R_MICROMIPS_TLS_DTPREL_HI16", /* name */
1237
         TRUE,                  /* partial_inplace */
1238
         0x0000ffff,            /* src_mask */
1239
         0x0000ffff,            /* dst_mask */
1240
         FALSE),                /* pcrel_offset */
1241
 
1242
  /* TLS local dynamic offset.  */
1243
  HOWTO (R_MICROMIPS_TLS_DTPREL_LO16,   /* type */
1244
         0,                      /* rightshift */
1245
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1246
         16,                    /* bitsize */
1247
         FALSE,                 /* pc_relative */
1248
         0,                      /* bitpos */
1249
         complain_overflow_signed, /* complain_on_overflow */
1250
         _bfd_mips_elf_generic_reloc, /* special_function */
1251
         "R_MICROMIPS_TLS_DTPREL_LO16", /* name */
1252
         TRUE,                  /* partial_inplace */
1253
         0x0000ffff,            /* src_mask */
1254
         0x0000ffff,            /* dst_mask */
1255
         FALSE),                /* pcrel_offset */
1256
 
1257
  /* TLS thread pointer offset.  */
1258
  HOWTO (R_MICROMIPS_TLS_GOTTPREL,      /* type */
1259
         0,                      /* rightshift */
1260
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1261
         16,                    /* bitsize */
1262
         FALSE,                 /* pc_relative */
1263
         0,                      /* bitpos */
1264
         complain_overflow_signed, /* complain_on_overflow */
1265
         _bfd_mips_elf_generic_reloc, /* special_function */
1266
         "R_MICROMIPS_TLS_GOTTPREL",    /* name */
1267
         TRUE,                  /* partial_inplace */
1268
         0x0000ffff,            /* src_mask */
1269
         0x0000ffff,            /* dst_mask */
1270
         FALSE),                /* pcrel_offset */
1271
 
1272
  EMPTY_HOWTO (167),
1273
  EMPTY_HOWTO (168),
1274
 
1275
  /* TLS thread pointer offset.  */
1276
  HOWTO (R_MICROMIPS_TLS_TPREL_HI16,    /* type */
1277
         0,                      /* rightshift */
1278
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1279
         16,                    /* bitsize */
1280
         FALSE,                 /* pc_relative */
1281
         0,                      /* bitpos */
1282
         complain_overflow_signed, /* complain_on_overflow */
1283
         _bfd_mips_elf_generic_reloc, /* special_function */
1284
         "R_MICROMIPS_TLS_TPREL_HI16", /* name */
1285
         TRUE,                  /* partial_inplace */
1286
         0x0000ffff,            /* src_mask */
1287
         0x0000ffff,            /* dst_mask */
1288
         FALSE),                /* pcrel_offset */
1289
 
1290
  /* TLS thread pointer offset.  */
1291
  HOWTO (R_MICROMIPS_TLS_TPREL_LO16,    /* type */
1292
         0,                      /* rightshift */
1293
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1294
         16,                    /* bitsize */
1295
         FALSE,                 /* pc_relative */
1296
         0,                      /* bitpos */
1297
         complain_overflow_signed, /* complain_on_overflow */
1298
         _bfd_mips_elf_generic_reloc, /* special_function */
1299
         "R_MICROMIPS_TLS_TPREL_LO16", /* name */
1300
         TRUE,                  /* partial_inplace */
1301
         0x0000ffff,            /* src_mask */
1302
         0x0000ffff,            /* dst_mask */
1303
         FALSE),                /* pcrel_offset */
1304
 
1305
  EMPTY_HOWTO (171),
1306
 
1307
  /* GP- and PC-relative relocations.  */
1308
  HOWTO (R_MICROMIPS_GPREL7_S2, /* type */
1309
         2,                     /* rightshift */
1310
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
1311
         7,                     /* bitsize */
1312
         FALSE,                 /* pc_relative */
1313
         0,                      /* bitpos */
1314
         complain_overflow_signed, /* complain_on_overflow */
1315
         _bfd_mips_elf32_gprel16_reloc, /* special_function */
1316
         "R_MICROMIPS_GPREL7_S2",       /* name */
1317
         TRUE,                  /* partial_inplace */
1318
         0x0000007f,            /* src_mask */
1319
         0x0000007f,            /* dst_mask */
1320
         FALSE),                /* pcrel_offset */
1321
 
1322
  HOWTO (R_MICROMIPS_PC23_S2,   /* type */
1323
         2,                     /* rightshift */
1324
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1325
         23,                    /* bitsize */
1326
         TRUE,                  /* pc_relative */
1327
         0,                      /* bitpos */
1328
         complain_overflow_signed, /* complain_on_overflow */
1329
         _bfd_mips_elf_generic_reloc, /* special_function */
1330
         "R_MICROMIPS_PC23_S2", /* name */
1331
         TRUE,                  /* partial_inplace */
1332
         0x007fffff,            /* src_mask */
1333
         0x007fffff,            /* dst_mask */
1334
         TRUE),                 /* pcrel_offset */
1335
};
1336
 
1337 14 khays
/* 16 bit offset for pc-relative branches.  */
1338
static reloc_howto_type elf_mips_gnu_rel16_s2 =
1339
  HOWTO (R_MIPS_GNU_REL16_S2,   /* type */
1340
         2,                     /* rightshift */
1341
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1342
         16,                    /* bitsize */
1343
         TRUE,                  /* pc_relative */
1344
         0,                      /* bitpos */
1345
         complain_overflow_signed, /* complain_on_overflow */
1346
         _bfd_mips_elf_generic_reloc, /* special_function */
1347
         "R_MIPS_GNU_REL16_S2", /* name */
1348
         TRUE,                  /* partial_inplace */
1349
         0xffff,                /* src_mask */
1350
         0xffff,                /* dst_mask */
1351
         TRUE);                 /* pcrel_offset */
1352
 
1353
/* 32 bit pc-relative.  This was a GNU extension used by embedded-PIC.
1354
   It was co-opted by mips-linux for exception-handling data.  It is no
1355
   longer used, but should continue to be supported by the linker for
1356
   backward compatibility.  (GCC stopped using it in May, 2004.)  */
1357
static reloc_howto_type elf_mips_gnu_pcrel32 =
1358
  HOWTO (R_MIPS_PC32,           /* type */
1359
         0,                      /* rightshift */
1360
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1361
         32,                    /* bitsize */
1362
         TRUE,                  /* pc_relative */
1363
         0,                      /* bitpos */
1364
         complain_overflow_signed, /* complain_on_overflow */
1365
         _bfd_mips_elf_generic_reloc, /* special_function */
1366
         "R_MIPS_PC32",         /* name */
1367
         TRUE,                  /* partial_inplace */
1368
         0xffffffff,            /* src_mask */
1369
         0xffffffff,            /* dst_mask */
1370
         TRUE);                 /* pcrel_offset */
1371
 
1372
/* GNU extension to record C++ vtable hierarchy */
1373
static reloc_howto_type elf_mips_gnu_vtinherit_howto =
1374
  HOWTO (R_MIPS_GNU_VTINHERIT,  /* type */
1375
         0,                      /* rightshift */
1376
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1377
         0,                      /* bitsize */
1378
         FALSE,                 /* pc_relative */
1379
         0,                      /* bitpos */
1380
         complain_overflow_dont, /* complain_on_overflow */
1381
         NULL,                  /* special_function */
1382
         "R_MIPS_GNU_VTINHERIT", /* name */
1383
         FALSE,                 /* partial_inplace */
1384
         0,                      /* src_mask */
1385
         0,                      /* dst_mask */
1386
         FALSE);                /* pcrel_offset */
1387
 
1388
/* GNU extension to record C++ vtable member usage */
1389
static reloc_howto_type elf_mips_gnu_vtentry_howto =
1390
  HOWTO (R_MIPS_GNU_VTENTRY,    /* type */
1391
         0,                      /* rightshift */
1392
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1393
         0,                      /* bitsize */
1394
         FALSE,                 /* pc_relative */
1395
         0,                      /* bitpos */
1396
         complain_overflow_dont, /* complain_on_overflow */
1397
         _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1398
         "R_MIPS_GNU_VTENTRY",  /* name */
1399
         FALSE,                 /* partial_inplace */
1400
         0,                      /* src_mask */
1401
         0,                      /* dst_mask */
1402
         FALSE);                /* pcrel_offset */
1403
 
1404
/* Originally a VxWorks extension, but now used for other systems too.  */
1405
static reloc_howto_type elf_mips_copy_howto =
1406
  HOWTO (R_MIPS_COPY,           /* type */
1407
         0,                      /* rightshift */
1408
         0,                      /* this one is variable size */
1409
         0,                      /* bitsize */
1410
         FALSE,                 /* pc_relative */
1411
         0,                      /* bitpos */
1412
         complain_overflow_bitfield, /* complain_on_overflow */
1413
         bfd_elf_generic_reloc, /* special_function */
1414
         "R_MIPS_COPY",         /* name */
1415
         FALSE,                 /* partial_inplace */
1416
         0x0,                   /* src_mask */
1417
         0x0,                   /* dst_mask */
1418
         FALSE);                /* pcrel_offset */
1419
 
1420
/* Originally a VxWorks extension, but now used for other systems too.  */
1421
static reloc_howto_type elf_mips_jump_slot_howto =
1422
  HOWTO (R_MIPS_JUMP_SLOT,      /* type */
1423
         0,                      /* rightshift */
1424
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
1425
         32,                    /* bitsize */
1426
         FALSE,                 /* pc_relative */
1427
         0,                      /* bitpos */
1428
         complain_overflow_bitfield, /* complain_on_overflow */
1429
         bfd_elf_generic_reloc, /* special_function */
1430
         "R_MIPS_JUMP_SLOT",    /* name */
1431
         FALSE,                 /* partial_inplace */
1432
         0x0,                   /* src_mask */
1433
         0x0,                   /* dst_mask */
1434
         FALSE);                /* pcrel_offset */
1435
 
1436
/* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
1437
   dangerous relocation.  */
1438
 
1439
static bfd_boolean
1440
mips_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
1441
{
1442
  unsigned int count;
1443
  asymbol **sym;
1444
  unsigned int i;
1445
 
1446
  /* If we've already figured out what GP will be, just return it.  */
1447
  *pgp = _bfd_get_gp_value (output_bfd);
1448
  if (*pgp)
1449
    return TRUE;
1450
 
1451
  count = bfd_get_symcount (output_bfd);
1452
  sym = bfd_get_outsymbols (output_bfd);
1453
 
1454
  /* The linker script will have created a symbol named `_gp' with the
1455
     appropriate value.  */
1456
  if (sym == NULL)
1457
    i = count;
1458
  else
1459
    {
1460
      for (i = 0; i < count; i++, sym++)
1461
        {
1462
          register const char *name;
1463
 
1464
          name = bfd_asymbol_name (*sym);
1465
          if (*name == '_' && strcmp (name, "_gp") == 0)
1466
            {
1467
              *pgp = bfd_asymbol_value (*sym);
1468
              _bfd_set_gp_value (output_bfd, *pgp);
1469
              break;
1470
            }
1471
        }
1472
    }
1473
 
1474
  if (i >= count)
1475
    {
1476
      /* Only get the error once.  */
1477
      *pgp = 4;
1478
      _bfd_set_gp_value (output_bfd, *pgp);
1479
      return FALSE;
1480
    }
1481
 
1482
  return TRUE;
1483
}
1484
 
1485
/* We have to figure out the gp value, so that we can adjust the
1486
   symbol value correctly.  We look up the symbol _gp in the output
1487
   BFD.  If we can't find it, we're stuck.  We cache it in the ELF
1488
   target data.  We don't need to adjust the symbol value for an
1489
   external symbol if we are producing relocatable output.  */
1490
 
1491
static bfd_reloc_status_type
1492
mips_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
1493
                   char **error_message, bfd_vma *pgp)
1494
{
1495
  if (bfd_is_und_section (symbol->section)
1496
      && ! relocatable)
1497
    {
1498
      *pgp = 0;
1499
      return bfd_reloc_undefined;
1500
    }
1501
 
1502
  *pgp = _bfd_get_gp_value (output_bfd);
1503
  if (*pgp == 0
1504
      && (! relocatable
1505
          || (symbol->flags & BSF_SECTION_SYM) != 0))
1506
    {
1507
      if (relocatable)
1508
        {
1509
          /* Make up a value.  */
1510
          *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
1511
          _bfd_set_gp_value (output_bfd, *pgp);
1512
        }
1513
      else if (!mips_elf_assign_gp (output_bfd, pgp))
1514
        {
1515
          *error_message =
1516
            (char *) _("GP relative relocation when _gp not defined");
1517
          return bfd_reloc_dangerous;
1518
        }
1519
    }
1520
 
1521
  return bfd_reloc_ok;
1522
}
1523
 
1524
/* Do a R_MIPS_GPREL16 relocation.  This is a 16 bit value which must
1525
   become the offset from the gp register.  This function also handles
1526
   R_MIPS_LITERAL relocations, although those can be handled more
1527
   cleverly because the entries in the .lit8 and .lit4 sections can be
1528
   merged.  */
1529
 
1530
bfd_reloc_status_type
1531
_bfd_mips_elf32_gprel16_reloc (bfd *abfd, arelent *reloc_entry,
1532
                               asymbol *symbol, void *data,
1533
                               asection *input_section, bfd *output_bfd,
1534
                               char **error_message)
1535
{
1536
  bfd_boolean relocatable;
1537
  bfd_reloc_status_type ret;
1538 161 khays
  bfd_byte *location;
1539 14 khays
  bfd_vma gp;
1540
 
1541 161 khays
  /* R_MIPS_LITERAL/R_MICROMIPS_LITERAL relocations are defined for local
1542
     symbols only.  */
1543
  if (literal_reloc_p (reloc_entry->howto->type)
1544 14 khays
      && output_bfd != NULL
1545
      && (symbol->flags & BSF_SECTION_SYM) == 0
1546
      && (symbol->flags & BSF_LOCAL) != 0)
1547
    {
1548
      *error_message = (char *)
1549
        _("literal relocation occurs for an external symbol");
1550
      return bfd_reloc_outofrange;
1551
    }
1552
 
1553
  if (output_bfd != NULL)
1554
    relocatable = TRUE;
1555
  else
1556
    {
1557
      relocatable = FALSE;
1558
      output_bfd = symbol->section->output_section->owner;
1559
    }
1560
 
1561
  ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
1562
                           &gp);
1563
  if (ret != bfd_reloc_ok)
1564
    return ret;
1565
 
1566 161 khays
  location = (bfd_byte *) data + reloc_entry->address;
1567
  _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
1568
                                 location);
1569
  ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1570
                                       input_section, relocatable,
1571
                                       data, gp);
1572
  _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
1573
                               location);
1574
 
1575
  return ret;
1576 14 khays
}
1577
 
1578
/* Do a R_MIPS_GPREL32 relocation.  This is a 32 bit value which must
1579
   become the offset from the gp register.  */
1580
 
1581
static bfd_reloc_status_type
1582
mips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1583
                        void *data, asection *input_section, bfd *output_bfd,
1584
                        char **error_message)
1585
{
1586
  bfd_boolean relocatable;
1587
  bfd_reloc_status_type ret;
1588
  bfd_vma gp;
1589
 
1590
  /* R_MIPS_GPREL32 relocations are defined for local symbols only.  */
1591
  if (output_bfd != NULL
1592
      && (symbol->flags & BSF_SECTION_SYM) == 0
1593
      && (symbol->flags & BSF_LOCAL) != 0)
1594
    {
1595
      *error_message = (char *)
1596
        _("32bits gp relative relocation occurs for an external symbol");
1597
      return bfd_reloc_outofrange;
1598
    }
1599
 
1600
  if (output_bfd != NULL)
1601
    relocatable = TRUE;
1602
  else
1603
    {
1604
      relocatable = FALSE;
1605
      output_bfd = symbol->section->output_section->owner;
1606
    }
1607
 
1608
  ret = mips_elf_final_gp (output_bfd, symbol, relocatable,
1609
                           error_message, &gp);
1610
  if (ret != bfd_reloc_ok)
1611
    return ret;
1612
 
1613
  return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
1614
                          relocatable, data, gp);
1615
}
1616
 
1617
static bfd_reloc_status_type
1618
gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
1619
                 asection *input_section, bfd_boolean relocatable,
1620
                 void *data, bfd_vma gp)
1621
{
1622
  bfd_vma relocation;
1623
  bfd_vma val;
1624
 
1625
  if (bfd_is_com_section (symbol->section))
1626
    relocation = 0;
1627
  else
1628
    relocation = symbol->value;
1629
 
1630
  relocation += symbol->section->output_section->vma;
1631
  relocation += symbol->section->output_offset;
1632
 
1633
  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
1634
    return bfd_reloc_outofrange;
1635
 
1636
  /* Set val to the offset into the section or symbol.  */
1637
  val = reloc_entry->addend;
1638
 
1639
  if (reloc_entry->howto->partial_inplace)
1640
    val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1641
 
1642
  /* Adjust val for the final section location and GP value.  If we
1643
     are producing relocatable output, we don't want to do this for
1644
     an external symbol.  */
1645
  if (! relocatable
1646
      || (symbol->flags & BSF_SECTION_SYM) != 0)
1647
    val += relocation - gp;
1648
 
1649
  if (reloc_entry->howto->partial_inplace)
1650
    bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
1651
  else
1652
    reloc_entry->addend = val;
1653
 
1654
  if (relocatable)
1655
    reloc_entry->address += input_section->output_offset;
1656
 
1657
  return bfd_reloc_ok;
1658
}
1659
 
1660
/* Handle a 64 bit reloc in a 32 bit MIPS ELF file.  These are
1661
   generated when addresses are 64 bits.  The upper 32 bits are a simple
1662
   sign extension.  */
1663
 
1664
static bfd_reloc_status_type
1665
mips32_64bit_reloc (bfd *abfd, arelent *reloc_entry,
1666
                    asymbol *symbol ATTRIBUTE_UNUSED,
1667
                    void *data, asection *input_section,
1668
                    bfd *output_bfd, char **error_message)
1669
{
1670
  bfd_reloc_status_type r;
1671
  arelent reloc32;
1672
  unsigned long val;
1673
  bfd_size_type addr;
1674
 
1675
  /* Do a normal 32 bit relocation on the lower 32 bits.  */
1676
  reloc32 = *reloc_entry;
1677
  if (bfd_big_endian (abfd))
1678
    reloc32.address += 4;
1679
  reloc32.howto = &elf_mips_howto_table_rel[R_MIPS_32];
1680
  r = bfd_perform_relocation (abfd, &reloc32, data, input_section,
1681
                              output_bfd, error_message);
1682
 
1683
  /* Sign extend into the upper 32 bits.  */
1684
  val = bfd_get_32 (abfd, (bfd_byte *) data + reloc32.address);
1685
  if ((val & 0x80000000) != 0)
1686
    val = 0xffffffff;
1687
  else
1688
    val = 0;
1689
  addr = reloc_entry->address;
1690
  if (bfd_little_endian (abfd))
1691
    addr += 4;
1692
  bfd_put_32 (abfd, val, (bfd_byte *) data + addr);
1693
 
1694
  return r;
1695
}
1696
 
1697
/* Handle a mips16 GP relative reloc.  */
1698
 
1699
static bfd_reloc_status_type
1700
mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1701
                    void *data, asection *input_section, bfd *output_bfd,
1702
                    char **error_message)
1703
{
1704
  bfd_boolean relocatable;
1705
  bfd_reloc_status_type ret;
1706
  bfd_byte *location;
1707
  bfd_vma gp;
1708
 
1709
  /* If we're relocating, and this is an external symbol, we don't want
1710
     to change anything.  */
1711
  if (output_bfd != NULL
1712
      && (symbol->flags & BSF_SECTION_SYM) == 0
1713
      && (symbol->flags & BSF_LOCAL) != 0)
1714
    {
1715
      reloc_entry->address += input_section->output_offset;
1716
      return bfd_reloc_ok;
1717
    }
1718
 
1719
  if (output_bfd != NULL)
1720
    relocatable = TRUE;
1721
  else
1722
    {
1723
      relocatable = FALSE;
1724
      output_bfd = symbol->section->output_section->owner;
1725
    }
1726
 
1727
  ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
1728
                           &gp);
1729
  if (ret != bfd_reloc_ok)
1730
    return ret;
1731
 
1732
  location = (bfd_byte *) data + reloc_entry->address;
1733 161 khays
  _bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
1734
                                 location);
1735 14 khays
  ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1736
                                       input_section, relocatable,
1737
                                       data, gp);
1738 161 khays
  _bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
1739
                               location);
1740 14 khays
 
1741
  return ret;
1742
}
1743
 
1744
/* A mapping from BFD reloc types to MIPS ELF reloc types.  */
1745
 
1746
struct elf_reloc_map {
1747
  bfd_reloc_code_real_type bfd_val;
1748
  enum elf_mips_reloc_type elf_val;
1749
};
1750
 
1751
static const struct elf_reloc_map mips_reloc_map[] =
1752
{
1753
  { BFD_RELOC_NONE, R_MIPS_NONE },
1754
  { BFD_RELOC_16, R_MIPS_16 },
1755
  { BFD_RELOC_32, R_MIPS_32 },
1756
  /* There is no BFD reloc for R_MIPS_REL32.  */
1757
  { BFD_RELOC_64, R_MIPS_64 },
1758
  { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1759
  { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1760
  { BFD_RELOC_LO16, R_MIPS_LO16 },
1761
  { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
1762
  { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1763
  { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1764
  { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
1765
  { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1766
  { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
1767
  { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1768
  { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1769
  { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
1770
  { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1771
  { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1772
  { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1773
  { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1774
  { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
1775
  { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
1776
  { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
1777
  { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
1778
  { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
1779
  { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
1780
  { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
1781
  { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
1782
  { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
1783
  { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
1784
  { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
1785
  { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
1786
  { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
1787
  { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
1788
  { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
1789
};
1790
 
1791
static const struct elf_reloc_map mips16_reloc_map[] =
1792
{
1793
  { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
1794
  { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
1795
  { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
1796
  { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
1797
  { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
1798
  { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
1799
};
1800
 
1801 161 khays
static const struct elf_reloc_map micromips_reloc_map[] =
1802
{
1803
  { BFD_RELOC_MICROMIPS_JMP, R_MICROMIPS_26_S1 - R_MICROMIPS_min },
1804
  { BFD_RELOC_MICROMIPS_HI16_S, R_MICROMIPS_HI16 - R_MICROMIPS_min },
1805
  { BFD_RELOC_MICROMIPS_LO16, R_MICROMIPS_LO16 - R_MICROMIPS_min },
1806
  { BFD_RELOC_MICROMIPS_GPREL16, R_MICROMIPS_GPREL16 - R_MICROMIPS_min },
1807
  { BFD_RELOC_MICROMIPS_LITERAL, R_MICROMIPS_LITERAL - R_MICROMIPS_min },
1808
  { BFD_RELOC_MICROMIPS_GOT16, R_MICROMIPS_GOT16 - R_MICROMIPS_min },
1809
  { BFD_RELOC_MICROMIPS_7_PCREL_S1, R_MICROMIPS_PC7_S1 - R_MICROMIPS_min },
1810
  { BFD_RELOC_MICROMIPS_10_PCREL_S1, R_MICROMIPS_PC10_S1 - R_MICROMIPS_min },
1811
  { BFD_RELOC_MICROMIPS_16_PCREL_S1, R_MICROMIPS_PC16_S1 - R_MICROMIPS_min },
1812
  { BFD_RELOC_MICROMIPS_CALL16, R_MICROMIPS_CALL16 - R_MICROMIPS_min },
1813
  { BFD_RELOC_MICROMIPS_GOT_DISP, R_MICROMIPS_GOT_DISP - R_MICROMIPS_min },
1814
  { BFD_RELOC_MICROMIPS_GOT_PAGE, R_MICROMIPS_GOT_PAGE - R_MICROMIPS_min },
1815
  { BFD_RELOC_MICROMIPS_GOT_OFST, R_MICROMIPS_GOT_OFST - R_MICROMIPS_min },
1816
  { BFD_RELOC_MICROMIPS_GOT_HI16, R_MICROMIPS_GOT_HI16 - R_MICROMIPS_min },
1817
  { BFD_RELOC_MICROMIPS_GOT_LO16, R_MICROMIPS_GOT_LO16 - R_MICROMIPS_min },
1818
  { BFD_RELOC_MICROMIPS_SUB, R_MICROMIPS_SUB - R_MICROMIPS_min },
1819
  { BFD_RELOC_MICROMIPS_HIGHER, R_MICROMIPS_HIGHER - R_MICROMIPS_min },
1820
  { BFD_RELOC_MICROMIPS_HIGHEST, R_MICROMIPS_HIGHEST - R_MICROMIPS_min },
1821
  { BFD_RELOC_MICROMIPS_CALL_HI16, R_MICROMIPS_CALL_HI16 - R_MICROMIPS_min },
1822
  { BFD_RELOC_MICROMIPS_CALL_LO16, R_MICROMIPS_CALL_LO16 - R_MICROMIPS_min },
1823
  { BFD_RELOC_MICROMIPS_SCN_DISP, R_MICROMIPS_SCN_DISP - R_MICROMIPS_min },
1824
  { BFD_RELOC_MICROMIPS_JALR, R_MICROMIPS_JALR - R_MICROMIPS_min },
1825
  /* There is no BFD reloc for R_MICROMIPS_HI0_LO16.  */
1826
  { BFD_RELOC_MICROMIPS_TLS_GD, R_MICROMIPS_TLS_GD - R_MICROMIPS_min },
1827
  { BFD_RELOC_MICROMIPS_TLS_LDM, R_MICROMIPS_TLS_LDM - R_MICROMIPS_min },
1828
  { BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16,
1829
    R_MICROMIPS_TLS_DTPREL_HI16 - R_MICROMIPS_min },
1830
  { BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16,
1831
    R_MICROMIPS_TLS_DTPREL_LO16 - R_MICROMIPS_min },
1832
  { BFD_RELOC_MICROMIPS_TLS_GOTTPREL,
1833
    R_MICROMIPS_TLS_GOTTPREL - R_MICROMIPS_min },
1834
  { BFD_RELOC_MICROMIPS_TLS_TPREL_HI16,
1835
    R_MICROMIPS_TLS_TPREL_HI16 - R_MICROMIPS_min },
1836
  { BFD_RELOC_MICROMIPS_TLS_TPREL_LO16,
1837
    R_MICROMIPS_TLS_TPREL_LO16 - R_MICROMIPS_min },
1838
  /* There is no BFD reloc for R_MICROMIPS_GPREL7_S2.  */
1839
  /* There is no BFD reloc for R_MICROMIPS_PC23_S2.  */
1840
};
1841
 
1842 14 khays
/* Given a BFD reloc type, return a howto structure.  */
1843
 
1844
static reloc_howto_type *
1845
bfd_elf32_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
1846
{
1847
  unsigned int i;
1848
  reloc_howto_type *howto_table = elf_mips_howto_table_rel;
1849
  reloc_howto_type *howto16_table = elf_mips16_howto_table_rel;
1850 161 khays
  reloc_howto_type *howto_micromips_table = elf_micromips_howto_table_rel;
1851 14 khays
 
1852
  for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
1853
       i++)
1854
    {
1855
      if (mips_reloc_map[i].bfd_val == code)
1856
        return &howto_table[(int) mips_reloc_map[i].elf_val];
1857
    }
1858
 
1859
  for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
1860
       i++)
1861
    {
1862
      if (mips16_reloc_map[i].bfd_val == code)
1863
        return &howto16_table[(int) mips16_reloc_map[i].elf_val];
1864
    }
1865
 
1866 161 khays
  for (i = 0; i < sizeof (micromips_reloc_map) / sizeof (struct elf_reloc_map);
1867
       i++)
1868
    {
1869
      if (micromips_reloc_map[i].bfd_val == code)
1870
        return &howto_micromips_table[(int) micromips_reloc_map[i].elf_val];
1871
    }
1872
 
1873 14 khays
  switch (code)
1874
    {
1875
    default:
1876
      bfd_set_error (bfd_error_bad_value);
1877
      return NULL;
1878
 
1879
    case BFD_RELOC_CTOR:
1880
      /* We need to handle BFD_RELOC_CTOR specially.
1881
         Select the right relocation (R_MIPS_32 or R_MIPS_64) based on the
1882
         size of addresses of the ABI.  */
1883
      if ((elf_elfheader (abfd)->e_flags & (E_MIPS_ABI_O64
1884
                                            | E_MIPS_ABI_EABI64)) != 0)
1885
        return &elf_mips_ctor64_howto;
1886
      else
1887
        return &howto_table[(int) R_MIPS_32];
1888
 
1889
    case BFD_RELOC_VTABLE_INHERIT:
1890
      return &elf_mips_gnu_vtinherit_howto;
1891
    case BFD_RELOC_VTABLE_ENTRY:
1892
      return &elf_mips_gnu_vtentry_howto;
1893
    case BFD_RELOC_32_PCREL:
1894
      return &elf_mips_gnu_pcrel32;
1895
    case BFD_RELOC_MIPS_COPY:
1896
      return &elf_mips_copy_howto;
1897
    case BFD_RELOC_MIPS_JUMP_SLOT:
1898
      return &elf_mips_jump_slot_howto;
1899
    }
1900
}
1901
 
1902
static reloc_howto_type *
1903
bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1904
                                 const char *r_name)
1905
{
1906
  unsigned int i;
1907
 
1908
  for (i = 0;
1909
       i < (sizeof (elf_mips_howto_table_rel)
1910
            / sizeof (elf_mips_howto_table_rel[0]));
1911
       i++)
1912
    if (elf_mips_howto_table_rel[i].name != NULL
1913
        && strcasecmp (elf_mips_howto_table_rel[i].name, r_name) == 0)
1914
      return &elf_mips_howto_table_rel[i];
1915
 
1916
  for (i = 0;
1917
       i < (sizeof (elf_mips16_howto_table_rel)
1918
            / sizeof (elf_mips16_howto_table_rel[0]));
1919
       i++)
1920
    if (elf_mips16_howto_table_rel[i].name != NULL
1921
        && strcasecmp (elf_mips16_howto_table_rel[i].name, r_name) == 0)
1922
      return &elf_mips16_howto_table_rel[i];
1923
 
1924 161 khays
  for (i = 0;
1925
       i < (sizeof (elf_micromips_howto_table_rel)
1926
            / sizeof (elf_micromips_howto_table_rel[0]));
1927
       i++)
1928
    if (elf_micromips_howto_table_rel[i].name != NULL
1929
        && strcasecmp (elf_micromips_howto_table_rel[i].name, r_name) == 0)
1930
      return &elf_micromips_howto_table_rel[i];
1931
 
1932 14 khays
  if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
1933
    return &elf_mips_gnu_pcrel32;
1934
  if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
1935
    return &elf_mips_gnu_rel16_s2;
1936
  if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
1937
    return &elf_mips_gnu_vtinherit_howto;
1938
  if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
1939
    return &elf_mips_gnu_vtentry_howto;
1940
  if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
1941
    return &elf_mips_copy_howto;
1942
  if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
1943
    return &elf_mips_jump_slot_howto;
1944
 
1945
  return NULL;
1946
}
1947
 
1948
/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
1949
 
1950
static reloc_howto_type *
1951
mips_elf32_rtype_to_howto (unsigned int r_type,
1952
                           bfd_boolean rela_p ATTRIBUTE_UNUSED)
1953
{
1954
  switch (r_type)
1955
    {
1956
    case R_MIPS_GNU_VTINHERIT:
1957
      return &elf_mips_gnu_vtinherit_howto;
1958
    case R_MIPS_GNU_VTENTRY:
1959
      return &elf_mips_gnu_vtentry_howto;
1960
    case R_MIPS_GNU_REL16_S2:
1961
      return &elf_mips_gnu_rel16_s2;
1962
    case R_MIPS_PC32:
1963
      return &elf_mips_gnu_pcrel32;
1964
    case R_MIPS_COPY:
1965
      return &elf_mips_copy_howto;
1966
    case R_MIPS_JUMP_SLOT:
1967
      return &elf_mips_jump_slot_howto;
1968
    default:
1969 161 khays
      if (r_type >= R_MICROMIPS_min && r_type < R_MICROMIPS_max)
1970
        return &elf_micromips_howto_table_rel[r_type - R_MICROMIPS_min];
1971 14 khays
      if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
1972
        return &elf_mips16_howto_table_rel[r_type - R_MIPS16_min];
1973
      BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
1974
      return &elf_mips_howto_table_rel[r_type];
1975
    }
1976
}
1977
 
1978
/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
1979
 
1980
static void
1981
mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
1982
{
1983
  const struct elf_backend_data *bed;
1984
  unsigned int r_type;
1985
 
1986
  r_type = ELF32_R_TYPE (dst->r_info);
1987
  bed = get_elf_backend_data (abfd);
1988
  cache_ptr->howto = bed->elf_backend_mips_rtype_to_howto (r_type, FALSE);
1989
 
1990
  /* The addend for a GPREL16 or LITERAL relocation comes from the GP
1991
     value for the object file.  We get the addend now, rather than
1992
     when we do the relocation, because the symbol manipulations done
1993
     by the linker may cause us to lose track of the input BFD.  */
1994
  if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
1995 161 khays
      && (gprel16_reloc_p (r_type) || literal_reloc_p (r_type)))
1996 14 khays
    cache_ptr->addend = elf_gp (abfd);
1997
}
1998
 
1999
/* Given a MIPS Elf_Internal_Rela, fill in an arelent structure.  */
2000
 
2001
static void
2002
mips_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
2003
{
2004
  mips_info_to_howto_rel (abfd, cache_ptr, dst);
2005
 
2006
  /* If we ever need to do any extra processing with dst->r_addend
2007
     (the field omitted in an Elf_Internal_Rel) we can do it here.  */
2008
}
2009
 
2010
/* Determine whether a symbol is global for the purposes of splitting
2011
   the symbol table into global symbols and local symbols.  At least
2012
   on Irix 5, this split must be between section symbols and all other
2013
   symbols.  On most ELF targets the split is between static symbols
2014
   and externally visible symbols.  */
2015
 
2016
static bfd_boolean
2017
mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
2018
{
2019
  if (SGI_COMPAT (abfd))
2020
    return (sym->flags & BSF_SECTION_SYM) == 0;
2021
  else
2022
    return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0
2023
            || bfd_is_und_section (bfd_get_section (sym))
2024
            || bfd_is_com_section (bfd_get_section (sym)));
2025
}
2026
 
2027
/* Set the right machine number for a MIPS ELF file.  */
2028
 
2029
static bfd_boolean
2030
mips_elf32_object_p (bfd *abfd)
2031
{
2032
  unsigned long mach;
2033
 
2034
  /* Irix 5 and 6 are broken.  Object file symbol tables are not always
2035
     sorted correctly such that local symbols precede global symbols,
2036
     and the sh_info field in the symbol table is not always right.  */
2037
  if (SGI_COMPAT (abfd))
2038
    elf_bad_symtab (abfd) = TRUE;
2039
 
2040
  if (ABI_N32_P (abfd))
2041
    return FALSE;
2042
 
2043
  mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
2044
  bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
2045
 
2046
  return TRUE;
2047
}
2048
 
2049
/* MIPS ELF local labels start with '$', not 'L'.  */
2050
 
2051
static bfd_boolean
2052
mips_elf_is_local_label_name (bfd *abfd, const char *name)
2053
{
2054
  if (name[0] == '$')
2055
    return TRUE;
2056
 
2057
  /* On Irix 6, the labels go back to starting with '.', so we accept
2058
     the generic ELF local label syntax as well.  */
2059
  return _bfd_elf_is_local_label_name (abfd, name);
2060
}
2061
 
2062
/* Support for core dump NOTE sections.  */
2063
static bfd_boolean
2064
elf32_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
2065
{
2066
  int offset;
2067
  unsigned int size;
2068
 
2069
  switch (note->descsz)
2070
    {
2071
      default:
2072
        return FALSE;
2073
 
2074
      case 256:         /* Linux/MIPS */
2075
        /* pr_cursig */
2076
        elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
2077
 
2078
        /* pr_pid */
2079
        elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 24);
2080
 
2081
        /* pr_reg */
2082
        offset = 72;
2083
        size = 180;
2084
 
2085
        break;
2086
    }
2087
 
2088
  /* Make a ".reg/999" section.  */
2089
  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
2090
                                          size, note->descpos + offset);
2091
}
2092
 
2093
static bfd_boolean
2094
elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
2095
{
2096
  switch (note->descsz)
2097
    {
2098
      default:
2099
        return FALSE;
2100
 
2101
      case 128:         /* Linux/MIPS elf_prpsinfo */
2102
        elf_tdata (abfd)->core_program
2103
         = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
2104
        elf_tdata (abfd)->core_command
2105
         = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
2106
    }
2107
 
2108
  /* Note that for some reason, a spurious space is tacked
2109
     onto the end of the args in some (at least one anyway)
2110
     implementations, so strip it off if it exists.  */
2111
 
2112
  {
2113
    char *command = elf_tdata (abfd)->core_command;
2114
    int n = strlen (command);
2115
 
2116
    if (0 < n && command[n - 1] == ' ')
2117
      command[n - 1] = '\0';
2118
  }
2119
 
2120
  return TRUE;
2121
}
2122
 
2123
/* Depending on the target vector we generate some version of Irix
2124
   executables or "normal" MIPS ELF ABI executables.  */
2125
static irix_compat_t
2126
elf32_mips_irix_compat (bfd *abfd)
2127
{
2128
  if ((abfd->xvec == &bfd_elf32_bigmips_vec)
2129
      || (abfd->xvec == &bfd_elf32_littlemips_vec))
2130
    return ict_irix5;
2131
  else
2132
    return ict_none;
2133
}
2134
 
2135
/* ECOFF swapping routines.  These are used when dealing with the
2136
   .mdebug section, which is in the ECOFF debugging format.  */
2137
static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
2138
  /* Symbol table magic number.  */
2139
  magicSym,
2140
  /* Alignment of debugging information.  E.g., 4.  */
2141
  4,
2142
  /* Sizes of external symbolic information.  */
2143
  sizeof (struct hdr_ext),
2144
  sizeof (struct dnr_ext),
2145
  sizeof (struct pdr_ext),
2146
  sizeof (struct sym_ext),
2147
  sizeof (struct opt_ext),
2148
  sizeof (struct fdr_ext),
2149
  sizeof (struct rfd_ext),
2150
  sizeof (struct ext_ext),
2151
  /* Functions to swap in external symbolic data.  */
2152
  ecoff_swap_hdr_in,
2153
  ecoff_swap_dnr_in,
2154
  ecoff_swap_pdr_in,
2155
  ecoff_swap_sym_in,
2156
  ecoff_swap_opt_in,
2157
  ecoff_swap_fdr_in,
2158
  ecoff_swap_rfd_in,
2159
  ecoff_swap_ext_in,
2160
  _bfd_ecoff_swap_tir_in,
2161
  _bfd_ecoff_swap_rndx_in,
2162
  /* Functions to swap out external symbolic data.  */
2163
  ecoff_swap_hdr_out,
2164
  ecoff_swap_dnr_out,
2165
  ecoff_swap_pdr_out,
2166
  ecoff_swap_sym_out,
2167
  ecoff_swap_opt_out,
2168
  ecoff_swap_fdr_out,
2169
  ecoff_swap_rfd_out,
2170
  ecoff_swap_ext_out,
2171
  _bfd_ecoff_swap_tir_out,
2172
  _bfd_ecoff_swap_rndx_out,
2173
  /* Function to read in symbolic data.  */
2174
  _bfd_mips_elf_read_ecoff_info
2175
};
2176
 
2177
#define ELF_ARCH                        bfd_arch_mips
2178
#define ELF_TARGET_ID                   MIPS_ELF_DATA
2179
#define ELF_MACHINE_CODE                EM_MIPS
2180
 
2181
#define elf_backend_collect             TRUE
2182
#define elf_backend_type_change_ok      TRUE
2183
#define elf_backend_can_gc_sections     TRUE
2184
#define elf_info_to_howto               mips_info_to_howto_rela
2185
#define elf_info_to_howto_rel           mips_info_to_howto_rel
2186
#define elf_backend_sym_is_global       mips_elf_sym_is_global
2187
#define elf_backend_object_p            mips_elf32_object_p
2188
#define elf_backend_symbol_processing   _bfd_mips_elf_symbol_processing
2189
#define elf_backend_section_processing  _bfd_mips_elf_section_processing
2190
#define elf_backend_section_from_shdr   _bfd_mips_elf_section_from_shdr
2191
#define elf_backend_fake_sections       _bfd_mips_elf_fake_sections
2192
#define elf_backend_section_from_bfd_section \
2193
                                        _bfd_mips_elf_section_from_bfd_section
2194
#define elf_backend_add_symbol_hook     _bfd_mips_elf_add_symbol_hook
2195
#define elf_backend_link_output_symbol_hook \
2196
                                        _bfd_mips_elf_link_output_symbol_hook
2197
#define elf_backend_create_dynamic_sections \
2198
                                        _bfd_mips_elf_create_dynamic_sections
2199
#define elf_backend_check_relocs        _bfd_mips_elf_check_relocs
2200
#define elf_backend_merge_symbol_attribute \
2201
                                        _bfd_mips_elf_merge_symbol_attribute
2202
#define elf_backend_get_target_dtag     _bfd_mips_elf_get_target_dtag
2203
#define elf_backend_adjust_dynamic_symbol \
2204
                                        _bfd_mips_elf_adjust_dynamic_symbol
2205
#define elf_backend_always_size_sections \
2206
                                        _bfd_mips_elf_always_size_sections
2207
#define elf_backend_size_dynamic_sections \
2208
                                        _bfd_mips_elf_size_dynamic_sections
2209
#define elf_backend_init_index_section  _bfd_elf_init_1_index_section
2210
#define elf_backend_relocate_section    _bfd_mips_elf_relocate_section
2211
#define elf_backend_finish_dynamic_symbol \
2212
                                        _bfd_mips_elf_finish_dynamic_symbol
2213
#define elf_backend_finish_dynamic_sections \
2214
                                        _bfd_mips_elf_finish_dynamic_sections
2215
#define elf_backend_final_write_processing \
2216
                                        _bfd_mips_elf_final_write_processing
2217
#define elf_backend_additional_program_headers \
2218
                                        _bfd_mips_elf_additional_program_headers
2219
#define elf_backend_modify_segment_map  _bfd_mips_elf_modify_segment_map
2220
#define elf_backend_gc_mark_hook        _bfd_mips_elf_gc_mark_hook
2221
#define elf_backend_gc_sweep_hook       _bfd_mips_elf_gc_sweep_hook
2222
#define elf_backend_copy_indirect_symbol \
2223
                                        _bfd_mips_elf_copy_indirect_symbol
2224
#define elf_backend_grok_prstatus       elf32_mips_grok_prstatus
2225
#define elf_backend_grok_psinfo         elf32_mips_grok_psinfo
2226
#define elf_backend_ecoff_debug_swap    &mips_elf32_ecoff_debug_swap
2227
 
2228
#define elf_backend_got_header_size     (4 * MIPS_RESERVED_GOTNO)
2229
#define elf_backend_may_use_rel_p       1
2230
#define elf_backend_may_use_rela_p      0
2231
#define elf_backend_default_use_rela_p  0
2232
#define elf_backend_sign_extend_vma     TRUE
2233
#define elf_backend_plt_readonly        1
2234
#define elf_backend_plt_sym_val         _bfd_mips_elf_plt_sym_val
2235
 
2236
#define elf_backend_discard_info        _bfd_mips_elf_discard_info
2237
#define elf_backend_ignore_discarded_relocs \
2238
                                        _bfd_mips_elf_ignore_discarded_relocs
2239
#define elf_backend_write_section       _bfd_mips_elf_write_section
2240
#define elf_backend_mips_irix_compat    elf32_mips_irix_compat
2241
#define elf_backend_mips_rtype_to_howto mips_elf32_rtype_to_howto
2242
#define bfd_elf32_bfd_is_local_label_name \
2243
                                        mips_elf_is_local_label_name
2244 161 khays
#define bfd_elf32_bfd_is_target_special_symbol \
2245
                                        _bfd_mips_elf_is_target_special_symbol
2246 14 khays
#define bfd_elf32_find_nearest_line     _bfd_mips_elf_find_nearest_line
2247
#define bfd_elf32_find_inliner_info     _bfd_mips_elf_find_inliner_info
2248
#define bfd_elf32_new_section_hook      _bfd_mips_elf_new_section_hook
2249
#define bfd_elf32_set_section_contents  _bfd_mips_elf_set_section_contents
2250
#define bfd_elf32_bfd_get_relocated_section_contents \
2251
                                _bfd_elf_mips_get_relocated_section_contents
2252
#define bfd_elf32_bfd_link_hash_table_create \
2253
                                        _bfd_mips_elf_link_hash_table_create
2254
#define bfd_elf32_bfd_final_link        _bfd_mips_elf_final_link
2255
#define bfd_elf32_bfd_merge_private_bfd_data \
2256
                                        _bfd_mips_elf_merge_private_bfd_data
2257
#define bfd_elf32_bfd_set_private_flags _bfd_mips_elf_set_private_flags
2258
#define bfd_elf32_bfd_print_private_bfd_data \
2259
                                        _bfd_mips_elf_print_private_bfd_data
2260 161 khays
#define bfd_elf32_bfd_relax_section     _bfd_mips_elf_relax_section
2261 14 khays
 
2262
/* Support for SGI-ish mips targets.  */
2263
#define TARGET_LITTLE_SYM               bfd_elf32_littlemips_vec
2264
#define TARGET_LITTLE_NAME              "elf32-littlemips"
2265
#define TARGET_BIG_SYM                  bfd_elf32_bigmips_vec
2266
#define TARGET_BIG_NAME                 "elf32-bigmips"
2267
 
2268
/* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
2269
   a value of 0x1000, and we are compatible.  */
2270
#define ELF_MAXPAGESIZE                 0x1000
2271
#define ELF_COMMONPAGESIZE              0x1000
2272
 
2273
#include "elf32-target.h"
2274
 
2275
/* Support for traditional mips targets.  */
2276
#undef TARGET_LITTLE_SYM
2277
#undef TARGET_LITTLE_NAME
2278
#undef TARGET_BIG_SYM
2279
#undef TARGET_BIG_NAME
2280
 
2281
#undef ELF_MAXPAGESIZE
2282
#undef ELF_COMMONPAGESIZE
2283
 
2284
#define TARGET_LITTLE_SYM               bfd_elf32_tradlittlemips_vec
2285
#define TARGET_LITTLE_NAME              "elf32-tradlittlemips"
2286
#define TARGET_BIG_SYM                  bfd_elf32_tradbigmips_vec
2287
#define TARGET_BIG_NAME                 "elf32-tradbigmips"
2288
 
2289
/* The MIPS ABI says at Page 5-1:
2290
   Virtual addresses and file offsets for MIPS segments are congruent
2291
   modulo 64 KByte (0x10000) or larger powers of 2.  Because 64 KBytes
2292
   is the maximum page size, the files are suitable for paging
2293
   regardless of physical page size.  */
2294
#define ELF_MAXPAGESIZE                 0x10000
2295
#define ELF_COMMONPAGESIZE              0x1000
2296
#define elf32_bed                       elf32_tradbed
2297
 
2298
/* Include the target file again for this target.  */
2299
#include "elf32-target.h"
2300
 
2301
/* FreeBSD support.  */
2302
 
2303
#undef TARGET_LITTLE_SYM
2304
#undef TARGET_LITTLE_NAME
2305
#undef TARGET_BIG_SYM
2306
#undef TARGET_BIG_NAME
2307
 
2308
#define TARGET_LITTLE_SYM               bfd_elf32_tradlittlemips_freebsd_vec
2309
#define TARGET_LITTLE_NAME              "elf32-tradlittlemips-freebsd"
2310
#define TARGET_BIG_SYM                  bfd_elf32_tradbigmips_freebsd_vec
2311
#define TARGET_BIG_NAME                 "elf32-tradbigmips-freebsd"
2312
 
2313
#undef  ELF_OSABI
2314
#define ELF_OSABI                       ELFOSABI_FREEBSD
2315
 
2316
/* The kernel recognizes executables as valid only if they carry a
2317
   "FreeBSD" label in the ELF header.  So we put this label on all
2318
   executables and (for simplicity) also all other object files.  */
2319
 
2320
static void
2321
elf_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info)
2322
{
2323
  _bfd_elf_set_osabi (abfd, info);
2324
}
2325
 
2326
#undef  elf_backend_post_process_headers
2327
#define elf_backend_post_process_headers        elf_fbsd_post_process_headers
2328
#undef  elf32_bed
2329
#define elf32_bed                               elf32_fbsd_tradbed
2330
 
2331
#include "elf32-target.h"
2332
/* Implement elf_backend_final_write_processing for VxWorks.  */
2333
 
2334
static void
2335
mips_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
2336
{
2337
  _bfd_mips_elf_final_write_processing (abfd, linker);
2338
  elf_vxworks_final_write_processing (abfd, linker);
2339
}
2340
 
2341
#undef TARGET_LITTLE_SYM
2342
#undef TARGET_LITTLE_NAME
2343
#undef TARGET_BIG_SYM
2344
#undef TARGET_BIG_NAME
2345
 
2346
#undef ELF_MAXPAGESIZE
2347
#undef ELF_COMMONPAGESIZE
2348
 
2349
#define TARGET_LITTLE_SYM               bfd_elf32_littlemips_vxworks_vec
2350
#define TARGET_LITTLE_NAME              "elf32-littlemips-vxworks"
2351
#define TARGET_BIG_SYM                  bfd_elf32_bigmips_vxworks_vec
2352
#define TARGET_BIG_NAME                 "elf32-bigmips-vxworks"
2353
 
2354
#undef elf32_bed
2355
#define elf32_bed                       elf32_mips_vxworks_bed
2356
 
2357
#define ELF_MAXPAGESIZE                 0x1000
2358
#define ELF_COMMONPAGESIZE              0x1000
2359
 
2360
#undef elf_backend_want_got_plt
2361
#define elf_backend_want_got_plt                1
2362
#undef elf_backend_want_plt_sym
2363
#define elf_backend_want_plt_sym                1
2364
#undef elf_backend_may_use_rel_p
2365
#define elf_backend_may_use_rel_p               0
2366
#undef elf_backend_may_use_rela_p
2367
#define elf_backend_may_use_rela_p              1
2368
#undef elf_backend_default_use_rela_p
2369
#define elf_backend_default_use_rela_p          1
2370
#undef elf_backend_got_header_size
2371
#define elf_backend_got_header_size             (4 * 3)
2372
#undef elf_backend_plt_sym_val
2373
 
2374
#undef elf_backend_finish_dynamic_symbol
2375
#define elf_backend_finish_dynamic_symbol \
2376
  _bfd_mips_vxworks_finish_dynamic_symbol
2377
#undef bfd_elf32_bfd_link_hash_table_create
2378
#define bfd_elf32_bfd_link_hash_table_create \
2379
  _bfd_mips_vxworks_link_hash_table_create
2380
#undef elf_backend_add_symbol_hook
2381
#define elf_backend_add_symbol_hook \
2382
  elf_vxworks_add_symbol_hook
2383
#undef elf_backend_link_output_symbol_hook
2384
#define elf_backend_link_output_symbol_hook \
2385
  elf_vxworks_link_output_symbol_hook
2386
#undef elf_backend_emit_relocs
2387
#define elf_backend_emit_relocs \
2388
  elf_vxworks_emit_relocs
2389
#undef elf_backend_final_write_processing
2390
#define elf_backend_final_write_processing \
2391
  mips_vxworks_final_write_processing
2392
 
2393
#undef elf_backend_additional_program_headers
2394
#undef elf_backend_modify_segment_map
2395
#undef elf_backend_symbol_processing
2396
/* NOTE: elf_backend_rela_normal is not defined for MIPS.  */
2397
 
2398
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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