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