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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [bfd/] [elf32-mips.c] - Blame information for rev 818

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

Line No. Rev Author Line
1 24 jeremybenn
/* MIPS-specific support for 32-bit ELF
2
   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 225 jeremybenn
   2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4 24 jeremybenn
 
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 225 jeremybenn
  /* 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 24 jeremybenn
 
789 225 jeremybenn
  /* 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 24 jeremybenn
 
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
/* 16 bit offset for pc-relative branches.  */
836
static reloc_howto_type elf_mips_gnu_rel16_s2 =
837
  HOWTO (R_MIPS_GNU_REL16_S2,   /* type */
838
         2,                     /* rightshift */
839
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
840
         16,                    /* bitsize */
841
         TRUE,                  /* pc_relative */
842
         0,                      /* bitpos */
843
         complain_overflow_signed, /* complain_on_overflow */
844
         _bfd_mips_elf_generic_reloc, /* special_function */
845
         "R_MIPS_GNU_REL16_S2", /* name */
846
         TRUE,                  /* partial_inplace */
847
         0xffff,                /* src_mask */
848
         0xffff,                /* dst_mask */
849
         TRUE);                 /* pcrel_offset */
850
 
851
/* 32 bit pc-relative.  This was a GNU extension used by embedded-PIC.
852
   It was co-opted by mips-linux for exception-handling data.  It is no
853
   longer used, but should continue to be supported by the linker for
854
   backward compatibility.  (GCC stopped using it in May, 2004.)  */
855
static reloc_howto_type elf_mips_gnu_pcrel32 =
856
  HOWTO (R_MIPS_PC32,           /* type */
857
         0,                      /* rightshift */
858
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
859
         32,                    /* bitsize */
860
         TRUE,                  /* pc_relative */
861
         0,                      /* bitpos */
862
         complain_overflow_signed, /* complain_on_overflow */
863
         _bfd_mips_elf_generic_reloc, /* special_function */
864
         "R_MIPS_PC32",         /* name */
865
         TRUE,                  /* partial_inplace */
866
         0xffffffff,            /* src_mask */
867
         0xffffffff,            /* dst_mask */
868
         TRUE);                 /* pcrel_offset */
869
 
870
/* GNU extension to record C++ vtable hierarchy */
871
static reloc_howto_type elf_mips_gnu_vtinherit_howto =
872
  HOWTO (R_MIPS_GNU_VTINHERIT,  /* type */
873
         0,                      /* rightshift */
874
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
875
         0,                      /* bitsize */
876
         FALSE,                 /* pc_relative */
877
         0,                      /* bitpos */
878
         complain_overflow_dont, /* complain_on_overflow */
879
         NULL,                  /* special_function */
880
         "R_MIPS_GNU_VTINHERIT", /* name */
881
         FALSE,                 /* partial_inplace */
882
         0,                      /* src_mask */
883
         0,                      /* dst_mask */
884
         FALSE);                /* pcrel_offset */
885
 
886
/* GNU extension to record C++ vtable member usage */
887
static reloc_howto_type elf_mips_gnu_vtentry_howto =
888
  HOWTO (R_MIPS_GNU_VTENTRY,    /* type */
889
         0,                      /* rightshift */
890
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
891
         0,                      /* bitsize */
892
         FALSE,                 /* pc_relative */
893
         0,                      /* bitpos */
894
         complain_overflow_dont, /* complain_on_overflow */
895
         _bfd_elf_rel_vtable_reloc_fn, /* special_function */
896
         "R_MIPS_GNU_VTENTRY",  /* name */
897
         FALSE,                 /* partial_inplace */
898
         0,                      /* src_mask */
899
         0,                      /* dst_mask */
900
         FALSE);                /* pcrel_offset */
901
 
902 225 jeremybenn
/* Originally a VxWorks extension, but now used for other systems too.  */
903
static reloc_howto_type elf_mips_copy_howto =
904
  HOWTO (R_MIPS_COPY,           /* type */
905
         0,                      /* rightshift */
906
         0,                      /* this one is variable size */
907
         0,                      /* bitsize */
908
         FALSE,                 /* pc_relative */
909
         0,                      /* bitpos */
910
         complain_overflow_bitfield, /* complain_on_overflow */
911
         bfd_elf_generic_reloc, /* special_function */
912
         "R_MIPS_COPY",         /* name */
913
         FALSE,                 /* partial_inplace */
914
         0x0,                   /* src_mask */
915
         0x0,                   /* dst_mask */
916
         FALSE);                /* pcrel_offset */
917
 
918
/* Originally a VxWorks extension, but now used for other systems too.  */
919
static reloc_howto_type elf_mips_jump_slot_howto =
920
  HOWTO (R_MIPS_JUMP_SLOT,      /* type */
921
         0,                      /* rightshift */
922
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
923
         32,                    /* bitsize */
924
         FALSE,                 /* pc_relative */
925
         0,                      /* bitpos */
926
         complain_overflow_bitfield, /* complain_on_overflow */
927
         bfd_elf_generic_reloc, /* special_function */
928
         "R_MIPS_JUMP_SLOT",    /* name */
929
         FALSE,                 /* partial_inplace */
930
         0x0,                   /* src_mask */
931
         0x0,                   /* dst_mask */
932
         FALSE);                /* pcrel_offset */
933
 
934 24 jeremybenn
/* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
935
   dangerous relocation.  */
936
 
937
static bfd_boolean
938
mips_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
939
{
940
  unsigned int count;
941
  asymbol **sym;
942
  unsigned int i;
943
 
944
  /* If we've already figured out what GP will be, just return it.  */
945
  *pgp = _bfd_get_gp_value (output_bfd);
946
  if (*pgp)
947
    return TRUE;
948
 
949
  count = bfd_get_symcount (output_bfd);
950
  sym = bfd_get_outsymbols (output_bfd);
951
 
952
  /* The linker script will have created a symbol named `_gp' with the
953
     appropriate value.  */
954
  if (sym == NULL)
955
    i = count;
956
  else
957
    {
958
      for (i = 0; i < count; i++, sym++)
959
        {
960
          register const char *name;
961
 
962
          name = bfd_asymbol_name (*sym);
963
          if (*name == '_' && strcmp (name, "_gp") == 0)
964
            {
965
              *pgp = bfd_asymbol_value (*sym);
966
              _bfd_set_gp_value (output_bfd, *pgp);
967
              break;
968
            }
969
        }
970
    }
971
 
972
  if (i >= count)
973
    {
974
      /* Only get the error once.  */
975
      *pgp = 4;
976
      _bfd_set_gp_value (output_bfd, *pgp);
977
      return FALSE;
978
    }
979
 
980
  return TRUE;
981
}
982
 
983
/* We have to figure out the gp value, so that we can adjust the
984
   symbol value correctly.  We look up the symbol _gp in the output
985
   BFD.  If we can't find it, we're stuck.  We cache it in the ELF
986
   target data.  We don't need to adjust the symbol value for an
987
   external symbol if we are producing relocatable output.  */
988
 
989
static bfd_reloc_status_type
990
mips_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
991
                   char **error_message, bfd_vma *pgp)
992
{
993
  if (bfd_is_und_section (symbol->section)
994
      && ! relocatable)
995
    {
996
      *pgp = 0;
997
      return bfd_reloc_undefined;
998
    }
999
 
1000
  *pgp = _bfd_get_gp_value (output_bfd);
1001
  if (*pgp == 0
1002
      && (! relocatable
1003
          || (symbol->flags & BSF_SECTION_SYM) != 0))
1004
    {
1005
      if (relocatable)
1006
        {
1007
          /* Make up a value.  */
1008 225 jeremybenn
          *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
1009 24 jeremybenn
          _bfd_set_gp_value (output_bfd, *pgp);
1010
        }
1011
      else if (!mips_elf_assign_gp (output_bfd, pgp))
1012
        {
1013
          *error_message =
1014
            (char *) _("GP relative relocation when _gp not defined");
1015
          return bfd_reloc_dangerous;
1016
        }
1017
    }
1018
 
1019
  return bfd_reloc_ok;
1020
}
1021
 
1022
/* Do a R_MIPS_GPREL16 relocation.  This is a 16 bit value which must
1023
   become the offset from the gp register.  This function also handles
1024
   R_MIPS_LITERAL relocations, although those can be handled more
1025
   cleverly because the entries in the .lit8 and .lit4 sections can be
1026
   merged.  */
1027
 
1028
bfd_reloc_status_type
1029
_bfd_mips_elf32_gprel16_reloc (bfd *abfd, arelent *reloc_entry,
1030
                               asymbol *symbol, void *data,
1031
                               asection *input_section, bfd *output_bfd,
1032
                               char **error_message)
1033
{
1034
  bfd_boolean relocatable;
1035
  bfd_reloc_status_type ret;
1036
  bfd_vma gp;
1037
 
1038
  /* R_MIPS_LITERAL relocations are defined for local symbols only.  */
1039
  if (reloc_entry->howto->type == R_MIPS_LITERAL
1040
      && output_bfd != NULL
1041
      && (symbol->flags & BSF_SECTION_SYM) == 0
1042
      && (symbol->flags & BSF_LOCAL) != 0)
1043
    {
1044
      *error_message = (char *)
1045
        _("literal relocation occurs for an external symbol");
1046
      return bfd_reloc_outofrange;
1047
    }
1048
 
1049
  if (output_bfd != NULL)
1050
    relocatable = TRUE;
1051
  else
1052
    {
1053
      relocatable = FALSE;
1054
      output_bfd = symbol->section->output_section->owner;
1055
    }
1056
 
1057
  ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
1058
                           &gp);
1059
  if (ret != bfd_reloc_ok)
1060
    return ret;
1061
 
1062
  return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1063
                                        input_section, relocatable,
1064
                                        data, gp);
1065
}
1066
 
1067
/* Do a R_MIPS_GPREL32 relocation.  This is a 32 bit value which must
1068
   become the offset from the gp register.  */
1069
 
1070
static bfd_reloc_status_type
1071
mips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1072
                        void *data, asection *input_section, bfd *output_bfd,
1073
                        char **error_message)
1074
{
1075
  bfd_boolean relocatable;
1076
  bfd_reloc_status_type ret;
1077
  bfd_vma gp;
1078
 
1079
  /* R_MIPS_GPREL32 relocations are defined for local symbols only.  */
1080
  if (output_bfd != NULL
1081
      && (symbol->flags & BSF_SECTION_SYM) == 0
1082
      && (symbol->flags & BSF_LOCAL) != 0)
1083
    {
1084
      *error_message = (char *)
1085
        _("32bits gp relative relocation occurs for an external symbol");
1086
      return bfd_reloc_outofrange;
1087
    }
1088
 
1089
  if (output_bfd != NULL)
1090
    relocatable = TRUE;
1091
  else
1092
    {
1093
      relocatable = FALSE;
1094
      output_bfd = symbol->section->output_section->owner;
1095
    }
1096
 
1097
  ret = mips_elf_final_gp (output_bfd, symbol, relocatable,
1098
                           error_message, &gp);
1099
  if (ret != bfd_reloc_ok)
1100
    return ret;
1101
 
1102
  return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
1103
                          relocatable, data, gp);
1104
}
1105
 
1106
static bfd_reloc_status_type
1107
gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
1108
                 asection *input_section, bfd_boolean relocatable,
1109
                 void *data, bfd_vma gp)
1110
{
1111
  bfd_vma relocation;
1112
  bfd_vma val;
1113
 
1114
  if (bfd_is_com_section (symbol->section))
1115
    relocation = 0;
1116
  else
1117
    relocation = symbol->value;
1118
 
1119
  relocation += symbol->section->output_section->vma;
1120
  relocation += symbol->section->output_offset;
1121
 
1122
  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
1123
    return bfd_reloc_outofrange;
1124
 
1125
  /* Set val to the offset into the section or symbol.  */
1126
  val = reloc_entry->addend;
1127
 
1128
  if (reloc_entry->howto->partial_inplace)
1129
    val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1130
 
1131
  /* Adjust val for the final section location and GP value.  If we
1132
     are producing relocatable output, we don't want to do this for
1133
     an external symbol.  */
1134
  if (! relocatable
1135
      || (symbol->flags & BSF_SECTION_SYM) != 0)
1136
    val += relocation - gp;
1137
 
1138
  if (reloc_entry->howto->partial_inplace)
1139
    bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
1140
  else
1141
    reloc_entry->addend = val;
1142
 
1143
  if (relocatable)
1144
    reloc_entry->address += input_section->output_offset;
1145
 
1146
  return bfd_reloc_ok;
1147
}
1148
 
1149
/* Handle a 64 bit reloc in a 32 bit MIPS ELF file.  These are
1150
   generated when addresses are 64 bits.  The upper 32 bits are a simple
1151
   sign extension.  */
1152
 
1153
static bfd_reloc_status_type
1154
mips32_64bit_reloc (bfd *abfd, arelent *reloc_entry,
1155
                    asymbol *symbol ATTRIBUTE_UNUSED,
1156
                    void *data, asection *input_section,
1157
                    bfd *output_bfd, char **error_message)
1158
{
1159
  bfd_reloc_status_type r;
1160
  arelent reloc32;
1161
  unsigned long val;
1162
  bfd_size_type addr;
1163
 
1164
  /* Do a normal 32 bit relocation on the lower 32 bits.  */
1165
  reloc32 = *reloc_entry;
1166
  if (bfd_big_endian (abfd))
1167
    reloc32.address += 4;
1168
  reloc32.howto = &elf_mips_howto_table_rel[R_MIPS_32];
1169
  r = bfd_perform_relocation (abfd, &reloc32, data, input_section,
1170
                              output_bfd, error_message);
1171
 
1172
  /* Sign extend into the upper 32 bits.  */
1173
  val = bfd_get_32 (abfd, (bfd_byte *) data + reloc32.address);
1174
  if ((val & 0x80000000) != 0)
1175
    val = 0xffffffff;
1176
  else
1177
    val = 0;
1178
  addr = reloc_entry->address;
1179
  if (bfd_little_endian (abfd))
1180
    addr += 4;
1181
  bfd_put_32 (abfd, val, (bfd_byte *) data + addr);
1182
 
1183
  return r;
1184
}
1185
 
1186
/* Handle a mips16 GP relative reloc.  */
1187
 
1188
static bfd_reloc_status_type
1189
mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1190
                    void *data, asection *input_section, bfd *output_bfd,
1191
                    char **error_message)
1192
{
1193
  bfd_boolean relocatable;
1194
  bfd_reloc_status_type ret;
1195
  bfd_byte *location;
1196
  bfd_vma gp;
1197
 
1198
  /* If we're relocating, and this is an external symbol, we don't want
1199
     to change anything.  */
1200
  if (output_bfd != NULL
1201
      && (symbol->flags & BSF_SECTION_SYM) == 0
1202
      && (symbol->flags & BSF_LOCAL) != 0)
1203
    {
1204
      reloc_entry->address += input_section->output_offset;
1205
      return bfd_reloc_ok;
1206
    }
1207
 
1208
  if (output_bfd != NULL)
1209
    relocatable = TRUE;
1210
  else
1211
    {
1212
      relocatable = FALSE;
1213
      output_bfd = symbol->section->output_section->owner;
1214
    }
1215
 
1216
  ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
1217
                           &gp);
1218
  if (ret != bfd_reloc_ok)
1219
    return ret;
1220
 
1221
  location = (bfd_byte *) data + reloc_entry->address;
1222
  _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
1223
                                   location);
1224
  ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1225
                                       input_section, relocatable,
1226
                                       data, gp);
1227
  _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
1228
                                 location);
1229
 
1230
  return ret;
1231
}
1232
 
1233
/* A mapping from BFD reloc types to MIPS ELF reloc types.  */
1234
 
1235
struct elf_reloc_map {
1236
  bfd_reloc_code_real_type bfd_val;
1237
  enum elf_mips_reloc_type elf_val;
1238
};
1239
 
1240
static const struct elf_reloc_map mips_reloc_map[] =
1241
{
1242
  { BFD_RELOC_NONE, R_MIPS_NONE },
1243
  { BFD_RELOC_16, R_MIPS_16 },
1244
  { BFD_RELOC_32, R_MIPS_32 },
1245
  /* There is no BFD reloc for R_MIPS_REL32.  */
1246
  { BFD_RELOC_64, R_MIPS_64 },
1247
  { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1248
  { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1249
  { BFD_RELOC_LO16, R_MIPS_LO16 },
1250
  { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
1251
  { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1252
  { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1253
  { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
1254
  { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1255
  { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
1256
  { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1257
  { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1258
  { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
1259
  { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1260
  { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1261
  { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1262
  { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1263
  { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
1264 225 jeremybenn
  { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
1265 24 jeremybenn
  { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
1266
  { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
1267
  { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
1268
  { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
1269
  { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
1270
  { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
1271
  { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
1272
  { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
1273
  { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
1274
  { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
1275
  { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
1276
  { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
1277
  { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
1278
};
1279
 
1280
static const struct elf_reloc_map mips16_reloc_map[] =
1281
{
1282
  { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
1283
  { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
1284 225 jeremybenn
  { BFD_RELOC_MIPS16_GOT16, R_MIPS16_GOT16 - R_MIPS16_min },
1285
  { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min },
1286 24 jeremybenn
  { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
1287
  { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
1288
};
1289
 
1290
/* Given a BFD reloc type, return a howto structure.  */
1291
 
1292
static reloc_howto_type *
1293
bfd_elf32_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
1294
{
1295
  unsigned int i;
1296
  reloc_howto_type *howto_table = elf_mips_howto_table_rel;
1297
  reloc_howto_type *howto16_table = elf_mips16_howto_table_rel;
1298
 
1299
  for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
1300
       i++)
1301
    {
1302
      if (mips_reloc_map[i].bfd_val == code)
1303
        return &howto_table[(int) mips_reloc_map[i].elf_val];
1304
    }
1305
 
1306
  for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
1307
       i++)
1308
    {
1309
      if (mips16_reloc_map[i].bfd_val == code)
1310
        return &howto16_table[(int) mips16_reloc_map[i].elf_val];
1311
    }
1312
 
1313
  switch (code)
1314
    {
1315
    default:
1316
      bfd_set_error (bfd_error_bad_value);
1317
      return NULL;
1318
 
1319
    case BFD_RELOC_CTOR:
1320
      /* We need to handle BFD_RELOC_CTOR specially.
1321
         Select the right relocation (R_MIPS_32 or R_MIPS_64) based on the
1322
         size of addresses of the ABI.  */
1323
      if ((elf_elfheader (abfd)->e_flags & (E_MIPS_ABI_O64
1324
                                            | E_MIPS_ABI_EABI64)) != 0)
1325
        return &elf_mips_ctor64_howto;
1326
      else
1327
        return &howto_table[(int) R_MIPS_32];
1328
 
1329
    case BFD_RELOC_VTABLE_INHERIT:
1330
      return &elf_mips_gnu_vtinherit_howto;
1331
    case BFD_RELOC_VTABLE_ENTRY:
1332
      return &elf_mips_gnu_vtentry_howto;
1333
    case BFD_RELOC_32_PCREL:
1334
      return &elf_mips_gnu_pcrel32;
1335 225 jeremybenn
    case BFD_RELOC_MIPS_COPY:
1336
      return &elf_mips_copy_howto;
1337
    case BFD_RELOC_MIPS_JUMP_SLOT:
1338
      return &elf_mips_jump_slot_howto;
1339 24 jeremybenn
    }
1340
}
1341
 
1342
static reloc_howto_type *
1343
bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1344
                                 const char *r_name)
1345
{
1346
  unsigned int i;
1347
 
1348
  for (i = 0;
1349
       i < (sizeof (elf_mips_howto_table_rel)
1350
            / sizeof (elf_mips_howto_table_rel[0]));
1351
       i++)
1352
    if (elf_mips_howto_table_rel[i].name != NULL
1353
        && strcasecmp (elf_mips_howto_table_rel[i].name, r_name) == 0)
1354
      return &elf_mips_howto_table_rel[i];
1355
 
1356
  for (i = 0;
1357
       i < (sizeof (elf_mips16_howto_table_rel)
1358
            / sizeof (elf_mips16_howto_table_rel[0]));
1359
       i++)
1360
    if (elf_mips16_howto_table_rel[i].name != NULL
1361
        && strcasecmp (elf_mips16_howto_table_rel[i].name, r_name) == 0)
1362
      return &elf_mips16_howto_table_rel[i];
1363
 
1364
  if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
1365
    return &elf_mips_gnu_pcrel32;
1366
  if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
1367
    return &elf_mips_gnu_rel16_s2;
1368
  if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
1369
    return &elf_mips_gnu_vtinherit_howto;
1370
  if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
1371
    return &elf_mips_gnu_vtentry_howto;
1372 225 jeremybenn
  if (strcasecmp (elf_mips_copy_howto.name, r_name) == 0)
1373
    return &elf_mips_copy_howto;
1374
  if (strcasecmp (elf_mips_jump_slot_howto.name, r_name) == 0)
1375
    return &elf_mips_jump_slot_howto;
1376 24 jeremybenn
 
1377
  return NULL;
1378
}
1379
 
1380
/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
1381
 
1382
static reloc_howto_type *
1383
mips_elf32_rtype_to_howto (unsigned int r_type,
1384
                           bfd_boolean rela_p ATTRIBUTE_UNUSED)
1385
{
1386
  switch (r_type)
1387
    {
1388
    case R_MIPS_GNU_VTINHERIT:
1389
      return &elf_mips_gnu_vtinherit_howto;
1390
    case R_MIPS_GNU_VTENTRY:
1391
      return &elf_mips_gnu_vtentry_howto;
1392
    case R_MIPS_GNU_REL16_S2:
1393
      return &elf_mips_gnu_rel16_s2;
1394
    case R_MIPS_PC32:
1395
      return &elf_mips_gnu_pcrel32;
1396 225 jeremybenn
    case R_MIPS_COPY:
1397
      return &elf_mips_copy_howto;
1398
    case R_MIPS_JUMP_SLOT:
1399
      return &elf_mips_jump_slot_howto;
1400 24 jeremybenn
    default:
1401
      if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
1402
        return &elf_mips16_howto_table_rel[r_type - R_MIPS16_min];
1403
      BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
1404
      return &elf_mips_howto_table_rel[r_type];
1405
    }
1406
}
1407
 
1408
/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
1409
 
1410
static void
1411
mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
1412
{
1413
  const struct elf_backend_data *bed;
1414
  unsigned int r_type;
1415
 
1416
  r_type = ELF32_R_TYPE (dst->r_info);
1417
  bed = get_elf_backend_data (abfd);
1418
  cache_ptr->howto = bed->elf_backend_mips_rtype_to_howto (r_type, FALSE);
1419
 
1420
  /* The addend for a GPREL16 or LITERAL relocation comes from the GP
1421
     value for the object file.  We get the addend now, rather than
1422
     when we do the relocation, because the symbol manipulations done
1423
     by the linker may cause us to lose track of the input BFD.  */
1424
  if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
1425
      && (r_type == (unsigned int) R_MIPS_GPREL16
1426
          || r_type == (unsigned int) R_MIPS_LITERAL))
1427
    cache_ptr->addend = elf_gp (abfd);
1428
}
1429
 
1430
/* Given a MIPS Elf_Internal_Rela, fill in an arelent structure.  */
1431
 
1432
static void
1433
mips_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
1434
{
1435
  mips_info_to_howto_rel (abfd, cache_ptr, dst);
1436
 
1437
  /* If we ever need to do any extra processing with dst->r_addend
1438
     (the field omitted in an Elf_Internal_Rel) we can do it here.  */
1439
}
1440
 
1441
/* Determine whether a symbol is global for the purposes of splitting
1442
   the symbol table into global symbols and local symbols.  At least
1443
   on Irix 5, this split must be between section symbols and all other
1444
   symbols.  On most ELF targets the split is between static symbols
1445
   and externally visible symbols.  */
1446
 
1447
static bfd_boolean
1448
mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
1449
{
1450
  if (SGI_COMPAT (abfd))
1451
    return (sym->flags & BSF_SECTION_SYM) == 0;
1452
  else
1453 225 jeremybenn
    return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0
1454 24 jeremybenn
            || bfd_is_und_section (bfd_get_section (sym))
1455
            || bfd_is_com_section (bfd_get_section (sym)));
1456
}
1457
 
1458
/* Set the right machine number for a MIPS ELF file.  */
1459
 
1460
static bfd_boolean
1461
mips_elf32_object_p (bfd *abfd)
1462
{
1463
  unsigned long mach;
1464
 
1465
  /* Irix 5 and 6 are broken.  Object file symbol tables are not always
1466
     sorted correctly such that local symbols precede global symbols,
1467
     and the sh_info field in the symbol table is not always right.  */
1468
  if (SGI_COMPAT (abfd))
1469
    elf_bad_symtab (abfd) = TRUE;
1470
 
1471
  if (ABI_N32_P (abfd))
1472
    return FALSE;
1473
 
1474
  mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
1475
  bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
1476
 
1477
  return TRUE;
1478
}
1479
 
1480
/* MIPS ELF local labels start with '$', not 'L'.  */
1481
 
1482
static bfd_boolean
1483
mips_elf_is_local_label_name (bfd *abfd, const char *name)
1484
{
1485
  if (name[0] == '$')
1486
    return TRUE;
1487
 
1488
  /* On Irix 6, the labels go back to starting with '.', so we accept
1489
     the generic ELF local label syntax as well.  */
1490
  return _bfd_elf_is_local_label_name (abfd, name);
1491
}
1492
 
1493
/* Support for core dump NOTE sections.  */
1494
static bfd_boolean
1495
elf32_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
1496
{
1497
  int offset;
1498
  unsigned int size;
1499
 
1500
  switch (note->descsz)
1501
    {
1502
      default:
1503
        return FALSE;
1504
 
1505
      case 256:         /* Linux/MIPS */
1506
        /* pr_cursig */
1507
        elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
1508
 
1509
        /* pr_pid */
1510
        elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
1511
 
1512
        /* pr_reg */
1513
        offset = 72;
1514
        size = 180;
1515
 
1516
        break;
1517
    }
1518
 
1519
  /* Make a ".reg/999" section.  */
1520
  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
1521
                                          size, note->descpos + offset);
1522
}
1523
 
1524
static bfd_boolean
1525
elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
1526
{
1527
  switch (note->descsz)
1528
    {
1529
      default:
1530
        return FALSE;
1531
 
1532
      case 128:         /* Linux/MIPS elf_prpsinfo */
1533
        elf_tdata (abfd)->core_program
1534
         = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
1535
        elf_tdata (abfd)->core_command
1536
         = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
1537
    }
1538
 
1539
  /* Note that for some reason, a spurious space is tacked
1540
     onto the end of the args in some (at least one anyway)
1541
     implementations, so strip it off if it exists.  */
1542
 
1543
  {
1544
    char *command = elf_tdata (abfd)->core_command;
1545
    int n = strlen (command);
1546
 
1547
    if (0 < n && command[n - 1] == ' ')
1548
      command[n - 1] = '\0';
1549
  }
1550
 
1551
  return TRUE;
1552
}
1553
 
1554
/* Depending on the target vector we generate some version of Irix
1555
   executables or "normal" MIPS ELF ABI executables.  */
1556
static irix_compat_t
1557
elf32_mips_irix_compat (bfd *abfd)
1558
{
1559
  if ((abfd->xvec == &bfd_elf32_bigmips_vec)
1560
      || (abfd->xvec == &bfd_elf32_littlemips_vec))
1561
    return ict_irix5;
1562
  else
1563
    return ict_none;
1564
}
1565
 
1566
/* ECOFF swapping routines.  These are used when dealing with the
1567
   .mdebug section, which is in the ECOFF debugging format.  */
1568
static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
1569
  /* Symbol table magic number.  */
1570
  magicSym,
1571
  /* Alignment of debugging information.  E.g., 4.  */
1572
  4,
1573
  /* Sizes of external symbolic information.  */
1574
  sizeof (struct hdr_ext),
1575
  sizeof (struct dnr_ext),
1576
  sizeof (struct pdr_ext),
1577
  sizeof (struct sym_ext),
1578
  sizeof (struct opt_ext),
1579
  sizeof (struct fdr_ext),
1580
  sizeof (struct rfd_ext),
1581
  sizeof (struct ext_ext),
1582
  /* Functions to swap in external symbolic data.  */
1583
  ecoff_swap_hdr_in,
1584
  ecoff_swap_dnr_in,
1585
  ecoff_swap_pdr_in,
1586
  ecoff_swap_sym_in,
1587
  ecoff_swap_opt_in,
1588
  ecoff_swap_fdr_in,
1589
  ecoff_swap_rfd_in,
1590
  ecoff_swap_ext_in,
1591
  _bfd_ecoff_swap_tir_in,
1592
  _bfd_ecoff_swap_rndx_in,
1593
  /* Functions to swap out external symbolic data.  */
1594
  ecoff_swap_hdr_out,
1595
  ecoff_swap_dnr_out,
1596
  ecoff_swap_pdr_out,
1597
  ecoff_swap_sym_out,
1598
  ecoff_swap_opt_out,
1599
  ecoff_swap_fdr_out,
1600
  ecoff_swap_rfd_out,
1601
  ecoff_swap_ext_out,
1602
  _bfd_ecoff_swap_tir_out,
1603
  _bfd_ecoff_swap_rndx_out,
1604
  /* Function to read in symbolic data.  */
1605
  _bfd_mips_elf_read_ecoff_info
1606
};
1607
 
1608
#define ELF_ARCH                        bfd_arch_mips
1609
#define ELF_MACHINE_CODE                EM_MIPS
1610
 
1611
#define elf_backend_collect             TRUE
1612
#define elf_backend_type_change_ok      TRUE
1613
#define elf_backend_can_gc_sections     TRUE
1614
#define elf_info_to_howto               mips_info_to_howto_rela
1615
#define elf_info_to_howto_rel           mips_info_to_howto_rel
1616
#define elf_backend_sym_is_global       mips_elf_sym_is_global
1617
#define elf_backend_object_p            mips_elf32_object_p
1618
#define elf_backend_symbol_processing   _bfd_mips_elf_symbol_processing
1619
#define elf_backend_section_processing  _bfd_mips_elf_section_processing
1620
#define elf_backend_section_from_shdr   _bfd_mips_elf_section_from_shdr
1621
#define elf_backend_fake_sections       _bfd_mips_elf_fake_sections
1622
#define elf_backend_section_from_bfd_section \
1623
                                        _bfd_mips_elf_section_from_bfd_section
1624
#define elf_backend_add_symbol_hook     _bfd_mips_elf_add_symbol_hook
1625
#define elf_backend_link_output_symbol_hook \
1626
                                        _bfd_mips_elf_link_output_symbol_hook
1627
#define elf_backend_create_dynamic_sections \
1628
                                        _bfd_mips_elf_create_dynamic_sections
1629
#define elf_backend_check_relocs        _bfd_mips_elf_check_relocs
1630
#define elf_backend_merge_symbol_attribute \
1631
                                        _bfd_mips_elf_merge_symbol_attribute
1632 225 jeremybenn
#define elf_backend_get_target_dtag     _bfd_mips_elf_get_target_dtag
1633 24 jeremybenn
#define elf_backend_adjust_dynamic_symbol \
1634
                                        _bfd_mips_elf_adjust_dynamic_symbol
1635
#define elf_backend_always_size_sections \
1636
                                        _bfd_mips_elf_always_size_sections
1637
#define elf_backend_size_dynamic_sections \
1638
                                        _bfd_mips_elf_size_dynamic_sections
1639
#define elf_backend_init_index_section  _bfd_elf_init_1_index_section
1640
#define elf_backend_relocate_section    _bfd_mips_elf_relocate_section
1641
#define elf_backend_finish_dynamic_symbol \
1642
                                        _bfd_mips_elf_finish_dynamic_symbol
1643
#define elf_backend_finish_dynamic_sections \
1644
                                        _bfd_mips_elf_finish_dynamic_sections
1645
#define elf_backend_final_write_processing \
1646
                                        _bfd_mips_elf_final_write_processing
1647
#define elf_backend_additional_program_headers \
1648
                                        _bfd_mips_elf_additional_program_headers
1649
#define elf_backend_modify_segment_map  _bfd_mips_elf_modify_segment_map
1650
#define elf_backend_gc_mark_hook        _bfd_mips_elf_gc_mark_hook
1651
#define elf_backend_gc_sweep_hook       _bfd_mips_elf_gc_sweep_hook
1652
#define elf_backend_copy_indirect_symbol \
1653
                                        _bfd_mips_elf_copy_indirect_symbol
1654
#define elf_backend_grok_prstatus       elf32_mips_grok_prstatus
1655
#define elf_backend_grok_psinfo         elf32_mips_grok_psinfo
1656
#define elf_backend_ecoff_debug_swap    &mips_elf32_ecoff_debug_swap
1657
 
1658
#define elf_backend_got_header_size     (4 * MIPS_RESERVED_GOTNO)
1659
#define elf_backend_may_use_rel_p       1
1660
#define elf_backend_may_use_rela_p      0
1661
#define elf_backend_default_use_rela_p  0
1662
#define elf_backend_sign_extend_vma     TRUE
1663 225 jeremybenn
#define elf_backend_plt_readonly        1
1664
#define elf_backend_plt_sym_val         _bfd_mips_elf_plt_sym_val
1665 24 jeremybenn
 
1666
#define elf_backend_discard_info        _bfd_mips_elf_discard_info
1667
#define elf_backend_ignore_discarded_relocs \
1668
                                        _bfd_mips_elf_ignore_discarded_relocs
1669 225 jeremybenn
#define elf_backend_write_section       _bfd_mips_elf_write_section
1670 24 jeremybenn
#define elf_backend_mips_irix_compat    elf32_mips_irix_compat
1671
#define elf_backend_mips_rtype_to_howto mips_elf32_rtype_to_howto
1672
#define bfd_elf32_bfd_is_local_label_name \
1673
                                        mips_elf_is_local_label_name
1674
#define bfd_elf32_find_nearest_line     _bfd_mips_elf_find_nearest_line
1675
#define bfd_elf32_find_inliner_info     _bfd_mips_elf_find_inliner_info
1676
#define bfd_elf32_new_section_hook      _bfd_mips_elf_new_section_hook
1677
#define bfd_elf32_set_section_contents  _bfd_mips_elf_set_section_contents
1678
#define bfd_elf32_bfd_get_relocated_section_contents \
1679
                                _bfd_elf_mips_get_relocated_section_contents
1680 225 jeremybenn
#define bfd_elf32_mkobject              _bfd_mips_elf_mkobject
1681 24 jeremybenn
#define bfd_elf32_bfd_link_hash_table_create \
1682
                                        _bfd_mips_elf_link_hash_table_create
1683
#define bfd_elf32_bfd_final_link        _bfd_mips_elf_final_link
1684
#define bfd_elf32_bfd_merge_private_bfd_data \
1685
                                        _bfd_mips_elf_merge_private_bfd_data
1686
#define bfd_elf32_bfd_set_private_flags _bfd_mips_elf_set_private_flags
1687
#define bfd_elf32_bfd_print_private_bfd_data \
1688
                                        _bfd_mips_elf_print_private_bfd_data
1689
 
1690
/* Support for SGI-ish mips targets.  */
1691
#define TARGET_LITTLE_SYM               bfd_elf32_littlemips_vec
1692
#define TARGET_LITTLE_NAME              "elf32-littlemips"
1693
#define TARGET_BIG_SYM                  bfd_elf32_bigmips_vec
1694
#define TARGET_BIG_NAME                 "elf32-bigmips"
1695
 
1696
/* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
1697
   a value of 0x1000, and we are compatible.  */
1698
#define ELF_MAXPAGESIZE                 0x1000
1699
#define ELF_COMMONPAGESIZE              0x1000
1700
 
1701
#include "elf32-target.h"
1702
 
1703
/* Support for traditional mips targets.  */
1704
#undef TARGET_LITTLE_SYM
1705
#undef TARGET_LITTLE_NAME
1706
#undef TARGET_BIG_SYM
1707
#undef TARGET_BIG_NAME
1708
 
1709
#undef ELF_MAXPAGESIZE
1710
#undef ELF_COMMONPAGESIZE
1711
 
1712
#define TARGET_LITTLE_SYM               bfd_elf32_tradlittlemips_vec
1713
#define TARGET_LITTLE_NAME              "elf32-tradlittlemips"
1714
#define TARGET_BIG_SYM                  bfd_elf32_tradbigmips_vec
1715
#define TARGET_BIG_NAME                 "elf32-tradbigmips"
1716
 
1717
/* The MIPS ABI says at Page 5-1:
1718
   Virtual addresses and file offsets for MIPS segments are congruent
1719
   modulo 64 KByte (0x10000) or larger powers of 2.  Because 64 KBytes
1720
   is the maximum page size, the files are suitable for paging
1721
   regardless of physical page size.  */
1722
#define ELF_MAXPAGESIZE                 0x10000
1723
#define ELF_COMMONPAGESIZE              0x1000
1724
#define elf32_bed                       elf32_tradbed
1725
 
1726
/* Include the target file again for this target.  */
1727
#include "elf32-target.h"
1728
 
1729
/* Implement elf_backend_final_write_processing for VxWorks.  */
1730
 
1731
static void
1732
mips_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
1733
{
1734
  _bfd_mips_elf_final_write_processing (abfd, linker);
1735
  elf_vxworks_final_write_processing (abfd, linker);
1736
}
1737
 
1738
#undef TARGET_LITTLE_SYM
1739
#undef TARGET_LITTLE_NAME
1740
#undef TARGET_BIG_SYM
1741
#undef TARGET_BIG_NAME
1742
 
1743
#undef ELF_MAXPAGESIZE
1744
#undef ELF_COMMONPAGESIZE
1745
 
1746
#define TARGET_LITTLE_SYM               bfd_elf32_littlemips_vxworks_vec
1747
#define TARGET_LITTLE_NAME              "elf32-littlemips-vxworks"
1748
#define TARGET_BIG_SYM                  bfd_elf32_bigmips_vxworks_vec
1749
#define TARGET_BIG_NAME                 "elf32-bigmips-vxworks"
1750
 
1751
#undef elf32_bed
1752
#define elf32_bed                       elf32_mips_vxworks_bed
1753
 
1754
#define ELF_MAXPAGESIZE                 0x1000
1755
#define ELF_COMMONPAGESIZE              0x1000
1756
 
1757
#undef elf_backend_want_got_plt
1758
#define elf_backend_want_got_plt                1
1759
#undef elf_backend_want_plt_sym
1760
#define elf_backend_want_plt_sym                1
1761
#undef elf_backend_may_use_rel_p
1762
#define elf_backend_may_use_rel_p               0
1763
#undef elf_backend_may_use_rela_p
1764
#define elf_backend_may_use_rela_p              1
1765
#undef elf_backend_default_use_rela_p
1766
#define elf_backend_default_use_rela_p          1
1767
#undef elf_backend_got_header_size
1768
#define elf_backend_got_header_size             (4 * 3)
1769 225 jeremybenn
#undef elf_backend_plt_sym_val
1770 24 jeremybenn
 
1771
#undef elf_backend_finish_dynamic_symbol
1772
#define elf_backend_finish_dynamic_symbol \
1773
  _bfd_mips_vxworks_finish_dynamic_symbol
1774
#undef bfd_elf32_bfd_link_hash_table_create
1775
#define bfd_elf32_bfd_link_hash_table_create \
1776
  _bfd_mips_vxworks_link_hash_table_create
1777
#undef elf_backend_add_symbol_hook
1778
#define elf_backend_add_symbol_hook \
1779
  elf_vxworks_add_symbol_hook
1780
#undef elf_backend_link_output_symbol_hook
1781
#define elf_backend_link_output_symbol_hook \
1782
  elf_vxworks_link_output_symbol_hook
1783
#undef elf_backend_emit_relocs
1784
#define elf_backend_emit_relocs \
1785
  elf_vxworks_emit_relocs
1786
#undef elf_backend_final_write_processing
1787
#define elf_backend_final_write_processing \
1788
  mips_vxworks_final_write_processing
1789
 
1790
#undef elf_backend_additional_program_headers
1791
#undef elf_backend_modify_segment_map
1792
#undef elf_backend_symbol_processing
1793
/* NOTE: elf_backend_rela_normal is not defined for MIPS.  */
1794
 
1795
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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