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