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