daily update
[deliverable/binutils-gdb.git] / bfd / elf32-mips.c
CommitLineData
efcbd82c 1/* MIPS-specific support for 32-bit ELF
f0abc2a1
AM
2 Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 2003 Free Software Foundation, Inc.
252b5132
RH
4
5 Most of the information added by Ian Lance Taylor, Cygnus Support,
6 <ian@cygnus.com>.
103186c6
MM
7 N32/64 ABI support added by Mark Mitchell, CodeSourcery, LLC.
8 <mark@codesourcery.com>
f7cb7d68
UC
9 Traditional MIPS targets support added by Koundinya.K, Dansk Data
10 Elektronik & Operations Research Group. <kk@ddeorg.soft.net>
252b5132
RH
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"
c6e90b02 38#include "elfxx-mips.h"
252b5132
RH
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"
23e2c83b 47#define ECOFF_SIGNED_32
252b5132
RH
48#include "ecoffswap.h"
49
a7ebbfdf 50static bfd_reloc_status_type mips_elf_generic_reloc
11a2be4d 51 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
c6e90b02 52static bfd_reloc_status_type mips_elf_hi16_reloc
11a2be4d 53 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
c6e90b02 54static bfd_reloc_status_type mips_elf_lo16_reloc
11a2be4d 55 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
c6e90b02 56static bfd_reloc_status_type mips_elf_got16_reloc
11a2be4d 57 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
a7ebbfdf 58static bfd_reloc_status_type gprel32_with_gp
11a2be4d 59 (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma);
c6e90b02 60static bfd_reloc_status_type mips_elf_gprel32_reloc
11a2be4d 61 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
252b5132 62static bfd_reloc_status_type mips32_64bit_reloc
11a2be4d 63 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
252b5132 64static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
11a2be4d 65 (bfd *, bfd_reloc_code_real_type);
c6e90b02 66static reloc_howto_type *mips_elf32_rtype_to_howto
11a2be4d 67 (unsigned int, bfd_boolean);
252b5132 68static void mips_info_to_howto_rel
11a2be4d 69 (bfd *, arelent *, Elf_Internal_Rela *);
3f830999 70static void mips_info_to_howto_rela
11a2be4d 71 (bfd *, arelent *, Elf_Internal_Rela *);
b34976b6 72static bfd_boolean mips_elf_sym_is_global
11a2be4d 73 (bfd *, asymbol *);
b34976b6 74static bfd_boolean mips_elf32_object_p
11a2be4d 75 (bfd *);
b34976b6 76static bfd_boolean mips_elf_is_local_label_name
11a2be4d 77 (bfd *, const char *);
252b5132 78static bfd_reloc_status_type mips16_jump_reloc
11a2be4d 79 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
252b5132 80static bfd_reloc_status_type mips16_gprel_reloc
11a2be4d 81 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
252b5132 82static bfd_reloc_status_type mips_elf_final_gp
11a2be4d 83 (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
b34976b6 84static bfd_boolean mips_elf_assign_gp
11a2be4d 85 (bfd *, bfd_vma *);
b34976b6 86static bfd_boolean elf32_mips_grok_prstatus
11a2be4d 87 (bfd *, Elf_Internal_Note *);
b34976b6 88static bfd_boolean elf32_mips_grok_psinfo
11a2be4d 89 (bfd *, Elf_Internal_Note *);
c6e90b02 90static irix_compat_t elf32_mips_irix_compat
11a2be4d 91 (bfd *);
252b5132 92
cb7394f2
TS
93extern const bfd_target bfd_elf32_bigmips_vec;
94extern const bfd_target bfd_elf32_littlemips_vec;
adb76a3e 95
a94a7c1c 96/* Nonzero if ABFD is using the N32 ABI. */
a94a7c1c
MM
97#define ABI_N32_P(abfd) \
98 ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
99
4e8a9624 100/* Whether we are trying to be compatible with IRIX at all. */
a94a7c1c 101#define SGI_COMPAT(abfd) \
c6e90b02 102 (elf32_mips_irix_compat (abfd) != ict_none)
103186c6 103
252b5132
RH
104/* The number of local .got entries we reserve. */
105#define MIPS_RESERVED_GOTNO (2)
106
3f830999
MM
107/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
108 from smaller values. Start with zero, widen, *then* decrement. */
109#define MINUS_ONE (((bfd_vma)0) - 1)
110
d75bc93d
TS
111/* The relocation table used for SHT_REL sections. */
112
113static reloc_howto_type elf_mips_howto_table_rel[] =
114{
115 /* No relocation. */
116 HOWTO (R_MIPS_NONE, /* type */
117 0, /* rightshift */
118 0, /* size (0 = byte, 1 = short, 2 = long) */
119 0, /* bitsize */
b34976b6 120 FALSE, /* pc_relative */
d75bc93d
TS
121 0, /* bitpos */
122 complain_overflow_dont, /* complain_on_overflow */
a7ebbfdf 123 mips_elf_generic_reloc, /* special_function */
d75bc93d 124 "R_MIPS_NONE", /* name */
b34976b6 125 FALSE, /* partial_inplace */
d75bc93d
TS
126 0, /* src_mask */
127 0, /* dst_mask */
b34976b6 128 FALSE), /* pcrel_offset */
d75bc93d
TS
129
130 /* 16 bit relocation. */
131 HOWTO (R_MIPS_16, /* type */
132 0, /* rightshift */
133 2, /* size (0 = byte, 1 = short, 2 = long) */
134 16, /* bitsize */
b34976b6 135 FALSE, /* pc_relative */
d75bc93d
TS
136 0, /* bitpos */
137 complain_overflow_signed, /* complain_on_overflow */
a7ebbfdf 138 mips_elf_generic_reloc, /* special_function */
d75bc93d 139 "R_MIPS_16", /* name */
b34976b6 140 TRUE, /* partial_inplace */
d75bc93d
TS
141 0x0000ffff, /* src_mask */
142 0x0000ffff, /* dst_mask */
b34976b6 143 FALSE), /* pcrel_offset */
d75bc93d
TS
144
145 /* 32 bit relocation. */
146 HOWTO (R_MIPS_32, /* type */
147 0, /* rightshift */
148 2, /* size (0 = byte, 1 = short, 2 = long) */
149 32, /* bitsize */
b34976b6 150 FALSE, /* pc_relative */
d75bc93d
TS
151 0, /* bitpos */
152 complain_overflow_dont, /* complain_on_overflow */
a7ebbfdf 153 mips_elf_generic_reloc, /* special_function */
d75bc93d 154 "R_MIPS_32", /* name */
b34976b6 155 TRUE, /* partial_inplace */
d75bc93d
TS
156 0xffffffff, /* src_mask */
157 0xffffffff, /* dst_mask */
b34976b6 158 FALSE), /* pcrel_offset */
d75bc93d
TS
159
160 /* 32 bit symbol relative relocation. */
161 HOWTO (R_MIPS_REL32, /* type */
162 0, /* rightshift */
163 2, /* size (0 = byte, 1 = short, 2 = long) */
164 32, /* bitsize */
b34976b6 165 FALSE, /* pc_relative */
d75bc93d
TS
166 0, /* bitpos */
167 complain_overflow_dont, /* complain_on_overflow */
a7ebbfdf 168 mips_elf_generic_reloc, /* special_function */
d75bc93d 169 "R_MIPS_REL32", /* name */
b34976b6 170 TRUE, /* partial_inplace */
d75bc93d
TS
171 0xffffffff, /* src_mask */
172 0xffffffff, /* dst_mask */
b34976b6 173 FALSE), /* pcrel_offset */
d75bc93d
TS
174
175 /* 26 bit jump address. */
176 HOWTO (R_MIPS_26, /* type */
177 2, /* rightshift */
178 2, /* size (0 = byte, 1 = short, 2 = long) */
179 26, /* bitsize */
b34976b6 180 FALSE, /* pc_relative */
d75bc93d
TS
181 0, /* bitpos */
182 complain_overflow_dont, /* complain_on_overflow */
183 /* This needs complex overflow
184 detection, because the upper four
185 bits must match the PC + 4. */
a7ebbfdf 186 mips_elf_generic_reloc, /* special_function */
d75bc93d 187 "R_MIPS_26", /* name */
b34976b6 188 TRUE, /* partial_inplace */
d75bc93d
TS
189 0x03ffffff, /* src_mask */
190 0x03ffffff, /* dst_mask */
b34976b6 191 FALSE), /* pcrel_offset */
d75bc93d
TS
192
193 /* High 16 bits of symbol value. */
194 HOWTO (R_MIPS_HI16, /* type */
195 0, /* rightshift */
196 2, /* size (0 = byte, 1 = short, 2 = long) */
197 16, /* bitsize */
b34976b6 198 FALSE, /* pc_relative */
d75bc93d
TS
199 0, /* bitpos */
200 complain_overflow_dont, /* complain_on_overflow */
c6e90b02 201 mips_elf_hi16_reloc, /* special_function */
d75bc93d 202 "R_MIPS_HI16", /* name */
b34976b6 203 TRUE, /* partial_inplace */
d75bc93d
TS
204 0x0000ffff, /* src_mask */
205 0x0000ffff, /* dst_mask */
b34976b6 206 FALSE), /* pcrel_offset */
d75bc93d
TS
207
208 /* Low 16 bits of symbol value. */
209 HOWTO (R_MIPS_LO16, /* type */
210 0, /* rightshift */
211 2, /* size (0 = byte, 1 = short, 2 = long) */
212 16, /* bitsize */
b34976b6 213 FALSE, /* pc_relative */
d75bc93d
TS
214 0, /* bitpos */
215 complain_overflow_dont, /* complain_on_overflow */
c6e90b02 216 mips_elf_lo16_reloc, /* special_function */
d75bc93d 217 "R_MIPS_LO16", /* name */
b34976b6 218 TRUE, /* partial_inplace */
d75bc93d
TS
219 0x0000ffff, /* src_mask */
220 0x0000ffff, /* dst_mask */
b34976b6 221 FALSE), /* pcrel_offset */
d75bc93d
TS
222
223 /* GP relative reference. */
224 HOWTO (R_MIPS_GPREL16, /* type */
225 0, /* rightshift */
226 2, /* size (0 = byte, 1 = short, 2 = long) */
227 16, /* bitsize */
b34976b6 228 FALSE, /* pc_relative */
d75bc93d
TS
229 0, /* bitpos */
230 complain_overflow_signed, /* complain_on_overflow */
c6e90b02 231 _bfd_mips_elf32_gprel16_reloc, /* special_function */
d75bc93d 232 "R_MIPS_GPREL16", /* name */
b34976b6 233 TRUE, /* partial_inplace */
d75bc93d
TS
234 0x0000ffff, /* src_mask */
235 0x0000ffff, /* dst_mask */
b34976b6 236 FALSE), /* pcrel_offset */
d75bc93d
TS
237
238 /* Reference to literal section. */
239 HOWTO (R_MIPS_LITERAL, /* type */
240 0, /* rightshift */
241 2, /* size (0 = byte, 1 = short, 2 = long) */
242 16, /* bitsize */
b34976b6 243 FALSE, /* pc_relative */
d75bc93d
TS
244 0, /* bitpos */
245 complain_overflow_signed, /* complain_on_overflow */
c6e90b02 246 _bfd_mips_elf32_gprel16_reloc, /* special_function */
d75bc93d 247 "R_MIPS_LITERAL", /* name */
b34976b6 248 TRUE, /* partial_inplace */
d75bc93d
TS
249 0x0000ffff, /* src_mask */
250 0x0000ffff, /* dst_mask */
b34976b6 251 FALSE), /* pcrel_offset */
d75bc93d
TS
252
253 /* Reference to global offset table. */
254 HOWTO (R_MIPS_GOT16, /* type */
255 0, /* rightshift */
256 2, /* size (0 = byte, 1 = short, 2 = long) */
257 16, /* bitsize */
b34976b6 258 FALSE, /* pc_relative */
d75bc93d
TS
259 0, /* bitpos */
260 complain_overflow_signed, /* complain_on_overflow */
c6e90b02 261 mips_elf_got16_reloc, /* special_function */
d75bc93d 262 "R_MIPS_GOT16", /* name */
b34976b6 263 TRUE, /* partial_inplace */
d75bc93d
TS
264 0x0000ffff, /* src_mask */
265 0x0000ffff, /* dst_mask */
b34976b6 266 FALSE), /* pcrel_offset */
d75bc93d 267
0b25d3e6 268 /* 16 bit PC relative reference. */
d75bc93d 269 HOWTO (R_MIPS_PC16, /* type */
0b25d3e6 270 0, /* rightshift */
d75bc93d
TS
271 2, /* size (0 = byte, 1 = short, 2 = long) */
272 16, /* bitsize */
b34976b6 273 TRUE, /* pc_relative */
d75bc93d
TS
274 0, /* bitpos */
275 complain_overflow_signed, /* complain_on_overflow */
a7ebbfdf 276 mips_elf_generic_reloc, /* special_function */
d75bc93d 277 "R_MIPS_PC16", /* name */
b34976b6 278 TRUE, /* partial_inplace */
d75bc93d
TS
279 0x0000ffff, /* src_mask */
280 0x0000ffff, /* dst_mask */
b34976b6 281 TRUE), /* pcrel_offset */
d75bc93d
TS
282
283 /* 16 bit call through global offset table. */
284 HOWTO (R_MIPS_CALL16, /* type */
285 0, /* rightshift */
286 2, /* size (0 = byte, 1 = short, 2 = long) */
287 16, /* bitsize */
b34976b6 288 FALSE, /* pc_relative */
d75bc93d
TS
289 0, /* bitpos */
290 complain_overflow_signed, /* complain_on_overflow */
a7ebbfdf 291 mips_elf_generic_reloc, /* special_function */
d75bc93d 292 "R_MIPS_CALL16", /* name */
b34976b6 293 TRUE, /* partial_inplace */
d75bc93d
TS
294 0x0000ffff, /* src_mask */
295 0x0000ffff, /* dst_mask */
b34976b6 296 FALSE), /* pcrel_offset */
d75bc93d
TS
297
298 /* 32 bit GP relative reference. */
299 HOWTO (R_MIPS_GPREL32, /* type */
300 0, /* rightshift */
301 2, /* size (0 = byte, 1 = short, 2 = long) */
302 32, /* bitsize */
b34976b6 303 FALSE, /* pc_relative */
d75bc93d
TS
304 0, /* bitpos */
305 complain_overflow_dont, /* complain_on_overflow */
c6e90b02 306 mips_elf_gprel32_reloc, /* special_function */
d75bc93d 307 "R_MIPS_GPREL32", /* name */
b34976b6 308 TRUE, /* partial_inplace */
d75bc93d
TS
309 0xffffffff, /* src_mask */
310 0xffffffff, /* dst_mask */
b34976b6 311 FALSE), /* pcrel_offset */
d75bc93d
TS
312
313 /* The remaining relocs are defined on Irix 5, although they are
314 not defined by the ABI. */
315 EMPTY_HOWTO (13),
316 EMPTY_HOWTO (14),
317 EMPTY_HOWTO (15),
318
319 /* A 5 bit shift field. */
320 HOWTO (R_MIPS_SHIFT5, /* type */
321 0, /* rightshift */
322 2, /* size (0 = byte, 1 = short, 2 = long) */
323 5, /* bitsize */
b34976b6 324 FALSE, /* pc_relative */
d75bc93d
TS
325 6, /* bitpos */
326 complain_overflow_bitfield, /* complain_on_overflow */
a7ebbfdf 327 mips_elf_generic_reloc, /* special_function */
d75bc93d 328 "R_MIPS_SHIFT5", /* name */
b34976b6 329 TRUE, /* partial_inplace */
d75bc93d
TS
330 0x000007c0, /* src_mask */
331 0x000007c0, /* dst_mask */
b34976b6 332 FALSE), /* pcrel_offset */
d75bc93d
TS
333
334 /* A 6 bit shift field. */
335 /* FIXME: This is not handled correctly; a special function is
336 needed to put the most significant bit in the right place. */
337 HOWTO (R_MIPS_SHIFT6, /* type */
338 0, /* rightshift */
339 2, /* size (0 = byte, 1 = short, 2 = long) */
340 6, /* bitsize */
b34976b6 341 FALSE, /* pc_relative */
d75bc93d
TS
342 6, /* bitpos */
343 complain_overflow_bitfield, /* complain_on_overflow */
a7ebbfdf 344 mips_elf_generic_reloc, /* special_function */
d75bc93d 345 "R_MIPS_SHIFT6", /* name */
b34976b6 346 TRUE, /* partial_inplace */
d75bc93d
TS
347 0x000007c4, /* src_mask */
348 0x000007c4, /* dst_mask */
b34976b6 349 FALSE), /* pcrel_offset */
d75bc93d
TS
350
351 /* A 64 bit relocation. */
352 HOWTO (R_MIPS_64, /* type */
353 0, /* rightshift */
354 4, /* size (0 = byte, 1 = short, 2 = long) */
355 64, /* bitsize */
b34976b6 356 FALSE, /* pc_relative */
d75bc93d
TS
357 0, /* bitpos */
358 complain_overflow_dont, /* complain_on_overflow */
359 mips32_64bit_reloc, /* special_function */
360 "R_MIPS_64", /* name */
b34976b6 361 TRUE, /* partial_inplace */
d75bc93d
TS
362 MINUS_ONE, /* src_mask */
363 MINUS_ONE, /* dst_mask */
b34976b6 364 FALSE), /* pcrel_offset */
d75bc93d
TS
365
366 /* Displacement in the global offset table. */
367 HOWTO (R_MIPS_GOT_DISP, /* type */
368 0, /* rightshift */
369 2, /* size (0 = byte, 1 = short, 2 = long) */
370 16, /* bitsize */
b34976b6 371 FALSE, /* pc_relative */
d75bc93d
TS
372 0, /* bitpos */
373 complain_overflow_signed, /* complain_on_overflow */
a7ebbfdf 374 mips_elf_generic_reloc, /* special_function */
d75bc93d 375 "R_MIPS_GOT_DISP", /* name */
b34976b6 376 TRUE, /* partial_inplace */
d75bc93d
TS
377 0x0000ffff, /* src_mask */
378 0x0000ffff, /* dst_mask */
b34976b6 379 FALSE), /* pcrel_offset */
d75bc93d
TS
380
381 /* Displacement to page pointer in the global offset table. */
382 HOWTO (R_MIPS_GOT_PAGE, /* type */
383 0, /* rightshift */
384 2, /* size (0 = byte, 1 = short, 2 = long) */
385 16, /* bitsize */
b34976b6 386 FALSE, /* pc_relative */
d75bc93d
TS
387 0, /* bitpos */
388 complain_overflow_signed, /* complain_on_overflow */
a7ebbfdf 389 mips_elf_generic_reloc, /* special_function */
d75bc93d 390 "R_MIPS_GOT_PAGE", /* name */
b34976b6 391 TRUE, /* partial_inplace */
d75bc93d
TS
392 0x0000ffff, /* src_mask */
393 0x0000ffff, /* dst_mask */
b34976b6 394 FALSE), /* pcrel_offset */
d75bc93d
TS
395
396 /* Offset from page pointer in the global offset table. */
397 HOWTO (R_MIPS_GOT_OFST, /* type */
398 0, /* rightshift */
399 2, /* size (0 = byte, 1 = short, 2 = long) */
400 16, /* bitsize */
b34976b6 401 FALSE, /* pc_relative */
d75bc93d
TS
402 0, /* bitpos */
403 complain_overflow_signed, /* complain_on_overflow */
a7ebbfdf 404 mips_elf_generic_reloc, /* special_function */
d75bc93d 405 "R_MIPS_GOT_OFST", /* name */
b34976b6 406 TRUE, /* partial_inplace */
d75bc93d
TS
407 0x0000ffff, /* src_mask */
408 0x0000ffff, /* dst_mask */
b34976b6 409 FALSE), /* pcrel_offset */
d75bc93d
TS
410
411 /* High 16 bits of displacement in global offset table. */
412 HOWTO (R_MIPS_GOT_HI16, /* type */
413 0, /* rightshift */
414 2, /* size (0 = byte, 1 = short, 2 = long) */
415 16, /* bitsize */
b34976b6 416 FALSE, /* pc_relative */
d75bc93d
TS
417 0, /* bitpos */
418 complain_overflow_dont, /* complain_on_overflow */
a7ebbfdf 419 mips_elf_generic_reloc, /* special_function */
d75bc93d 420 "R_MIPS_GOT_HI16", /* name */
b34976b6 421 TRUE, /* partial_inplace */
d75bc93d
TS
422 0x0000ffff, /* src_mask */
423 0x0000ffff, /* dst_mask */
b34976b6 424 FALSE), /* pcrel_offset */
d75bc93d
TS
425
426 /* Low 16 bits of displacement in global offset table. */
427 HOWTO (R_MIPS_GOT_LO16, /* type */
428 0, /* rightshift */
429 2, /* size (0 = byte, 1 = short, 2 = long) */
430 16, /* bitsize */
b34976b6 431 FALSE, /* pc_relative */
d75bc93d
TS
432 0, /* bitpos */
433 complain_overflow_dont, /* complain_on_overflow */
a7ebbfdf 434 mips_elf_generic_reloc, /* special_function */
d75bc93d 435 "R_MIPS_GOT_LO16", /* name */
b34976b6 436 TRUE, /* partial_inplace */
d75bc93d
TS
437 0x0000ffff, /* src_mask */
438 0x0000ffff, /* dst_mask */
b34976b6 439 FALSE), /* pcrel_offset */
d75bc93d
TS
440
441 /* 64 bit subtraction. Used in the N32 ABI. */
442 HOWTO (R_MIPS_SUB, /* type */
443 0, /* rightshift */
444 4, /* size (0 = byte, 1 = short, 2 = long) */
445 64, /* bitsize */
b34976b6 446 FALSE, /* pc_relative */
d75bc93d
TS
447 0, /* bitpos */
448 complain_overflow_dont, /* complain_on_overflow */
a7ebbfdf 449 mips_elf_generic_reloc, /* special_function */
d75bc93d 450 "R_MIPS_SUB", /* name */
b34976b6 451 TRUE, /* partial_inplace */
d75bc93d
TS
452 MINUS_ONE, /* src_mask */
453 MINUS_ONE, /* dst_mask */
b34976b6 454 FALSE), /* pcrel_offset */
d75bc93d
TS
455
456 /* Used to cause the linker to insert and delete instructions? */
457 EMPTY_HOWTO (R_MIPS_INSERT_A),
458 EMPTY_HOWTO (R_MIPS_INSERT_B),
459 EMPTY_HOWTO (R_MIPS_DELETE),
460
461 /* Get the higher value of a 64 bit addend. */
462 HOWTO (R_MIPS_HIGHER, /* type */
463 0, /* rightshift */
464 2, /* size (0 = byte, 1 = short, 2 = long) */
465 16, /* bitsize */
b34976b6 466 FALSE, /* pc_relative */
d75bc93d
TS
467 0, /* bitpos */
468 complain_overflow_dont, /* complain_on_overflow */
a7ebbfdf 469 mips_elf_generic_reloc, /* special_function */
d75bc93d 470 "R_MIPS_HIGHER", /* name */
b34976b6 471 TRUE, /* partial_inplace */
d75bc93d
TS
472 0x0000ffff, /* src_mask */
473 0x0000ffff, /* dst_mask */
b34976b6 474 FALSE), /* pcrel_offset */
d75bc93d
TS
475
476 /* Get the highest value of a 64 bit addend. */
477 HOWTO (R_MIPS_HIGHEST, /* type */
478 0, /* rightshift */
479 2, /* size (0 = byte, 1 = short, 2 = long) */
480 16, /* bitsize */
b34976b6 481 FALSE, /* pc_relative */
d75bc93d
TS
482 0, /* bitpos */
483 complain_overflow_dont, /* complain_on_overflow */
a7ebbfdf 484 mips_elf_generic_reloc, /* special_function */
d75bc93d 485 "R_MIPS_HIGHEST", /* name */
b34976b6 486 TRUE, /* partial_inplace */
d75bc93d
TS
487 0x0000ffff, /* src_mask */
488 0x0000ffff, /* dst_mask */
b34976b6 489 FALSE), /* pcrel_offset */
d75bc93d
TS
490
491 /* High 16 bits of displacement in global offset table. */
492 HOWTO (R_MIPS_CALL_HI16, /* type */
493 0, /* rightshift */
494 2, /* size (0 = byte, 1 = short, 2 = long) */
495 16, /* bitsize */
b34976b6 496 FALSE, /* pc_relative */
d75bc93d
TS
497 0, /* bitpos */
498 complain_overflow_dont, /* complain_on_overflow */
a7ebbfdf 499 mips_elf_generic_reloc, /* special_function */
d75bc93d 500 "R_MIPS_CALL_HI16", /* name */
b34976b6 501 TRUE, /* partial_inplace */
d75bc93d
TS
502 0x0000ffff, /* src_mask */
503 0x0000ffff, /* dst_mask */
b34976b6 504 FALSE), /* pcrel_offset */
d75bc93d
TS
505
506 /* Low 16 bits of displacement in global offset table. */
507 HOWTO (R_MIPS_CALL_LO16, /* type */
508 0, /* rightshift */
509 2, /* size (0 = byte, 1 = short, 2 = long) */
510 16, /* bitsize */
b34976b6 511 FALSE, /* pc_relative */
d75bc93d
TS
512 0, /* bitpos */
513 complain_overflow_dont, /* complain_on_overflow */
a7ebbfdf 514 mips_elf_generic_reloc, /* special_function */
d75bc93d 515 "R_MIPS_CALL_LO16", /* name */
b34976b6 516 TRUE, /* partial_inplace */
d75bc93d
TS
517 0x0000ffff, /* src_mask */
518 0x0000ffff, /* dst_mask */
b34976b6 519 FALSE), /* pcrel_offset */
d75bc93d
TS
520
521 /* Section displacement. */
522 HOWTO (R_MIPS_SCN_DISP, /* type */
523 0, /* rightshift */
524 2, /* size (0 = byte, 1 = short, 2 = long) */
525 32, /* bitsize */
b34976b6 526 FALSE, /* pc_relative */
d75bc93d
TS
527 0, /* bitpos */
528 complain_overflow_dont, /* complain_on_overflow */
a7ebbfdf 529 mips_elf_generic_reloc, /* special_function */
d75bc93d 530 "R_MIPS_SCN_DISP", /* name */
b34976b6 531 TRUE, /* partial_inplace */
d75bc93d
TS
532 0xffffffff, /* src_mask */
533 0xffffffff, /* dst_mask */
b34976b6 534 FALSE), /* pcrel_offset */
d75bc93d
TS
535
536 EMPTY_HOWTO (R_MIPS_REL16),
537 EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
538 EMPTY_HOWTO (R_MIPS_PJUMP),
539 EMPTY_HOWTO (R_MIPS_RELGOT),
540
541 /* Protected jump conversion. This is an optimization hint. No
542 relocation is required for correctness. */
543 HOWTO (R_MIPS_JALR, /* type */
544 0, /* rightshift */
545 2, /* size (0 = byte, 1 = short, 2 = long) */
546 32, /* bitsize */
b34976b6 547 FALSE, /* pc_relative */
d75bc93d
TS
548 0, /* bitpos */
549 complain_overflow_dont, /* complain_on_overflow */
a7ebbfdf 550 mips_elf_generic_reloc, /* special_function */
d75bc93d 551 "R_MIPS_JALR", /* name */
b34976b6 552 FALSE, /* partial_inplace */
d75bc93d
TS
553 0x00000000, /* src_mask */
554 0x00000000, /* dst_mask */
b34976b6 555 FALSE), /* pcrel_offset */
d75bc93d
TS
556};
557
c6e90b02
TS
558/* The reloc used for BFD_RELOC_CTOR when doing a 64 bit link. This
559 is a hack to make the linker think that we need 64 bit values. */
560static reloc_howto_type elf_mips_ctor64_howto =
561 HOWTO (R_MIPS_64, /* type */
252b5132 562 0, /* rightshift */
c6e90b02 563 4, /* size (0 = byte, 1 = short, 2 = long) */
252b5132 564 32, /* bitsize */
b34976b6 565 FALSE, /* pc_relative */
252b5132 566 0, /* bitpos */
c6e90b02
TS
567 complain_overflow_signed, /* complain_on_overflow */
568 mips32_64bit_reloc, /* special_function */
569 "R_MIPS_64", /* name */
b34976b6 570 TRUE, /* partial_inplace */
c6e90b02 571 0xffffffff, /* src_mask */
252b5132 572 0xffffffff, /* dst_mask */
b34976b6 573 FALSE); /* pcrel_offset */
252b5132 574
c6e90b02
TS
575/* The reloc used for the mips16 jump instruction. */
576static reloc_howto_type elf_mips16_jump_howto =
577 HOWTO (R_MIPS16_26, /* type */
252b5132
RH
578 2, /* rightshift */
579 2, /* size (0 = byte, 1 = short, 2 = long) */
580 26, /* bitsize */
b34976b6 581 FALSE, /* pc_relative */
252b5132
RH
582 0, /* bitpos */
583 complain_overflow_dont, /* complain_on_overflow */
c6e90b02
TS
584 /* This needs complex overflow
585 detection, because the upper four
586 bits must match the PC. */
587 mips16_jump_reloc, /* special_function */
588 "R_MIPS16_26", /* name */
b34976b6 589 TRUE, /* partial_inplace */
c6e90b02
TS
590 0x3ffffff, /* src_mask */
591 0x3ffffff, /* dst_mask */
b34976b6 592 FALSE); /* pcrel_offset */
252b5132 593
c6e90b02
TS
594/* The reloc used for the mips16 gprel instruction. */
595static reloc_howto_type elf_mips16_gprel_howto =
596 HOWTO (R_MIPS16_GPREL, /* type */
252b5132
RH
597 0, /* rightshift */
598 2, /* size (0 = byte, 1 = short, 2 = long) */
599 16, /* bitsize */
b34976b6 600 FALSE, /* pc_relative */
252b5132 601 0, /* bitpos */
c6e90b02
TS
602 complain_overflow_signed, /* complain_on_overflow */
603 mips16_gprel_reloc, /* special_function */
604 "R_MIPS16_GPREL", /* name */
b34976b6 605 TRUE, /* partial_inplace */
c6e90b02
TS
606 0x07ff001f, /* src_mask */
607 0x07ff001f, /* dst_mask */
b34976b6 608 FALSE); /* pcrel_offset */
252b5132 609
c6e90b02
TS
610/* GNU extensions for embedded-pic. */
611/* High 16 bits of symbol value, pc-relative. */
612static reloc_howto_type elf_mips_gnu_rel_hi16 =
613 HOWTO (R_MIPS_GNU_REL_HI16, /* type */
252b5132
RH
614 0, /* rightshift */
615 2, /* size (0 = byte, 1 = short, 2 = long) */
616 16, /* bitsize */
b34976b6 617 TRUE, /* pc_relative */
252b5132
RH
618 0, /* bitpos */
619 complain_overflow_dont, /* complain_on_overflow */
c6e90b02
TS
620 mips_elf_hi16_reloc, /* special_function */
621 "R_MIPS_GNU_REL_HI16", /* name */
b34976b6 622 TRUE, /* partial_inplace */
c6e90b02
TS
623 0xffff, /* src_mask */
624 0xffff, /* dst_mask */
b34976b6 625 TRUE); /* pcrel_offset */
252b5132 626
c6e90b02
TS
627/* Low 16 bits of symbol value, pc-relative. */
628static reloc_howto_type elf_mips_gnu_rel_lo16 =
629 HOWTO (R_MIPS_GNU_REL_LO16, /* type */
252b5132
RH
630 0, /* rightshift */
631 2, /* size (0 = byte, 1 = short, 2 = long) */
632 16, /* bitsize */
b34976b6 633 TRUE, /* pc_relative */
252b5132 634 0, /* bitpos */
c6e90b02
TS
635 complain_overflow_dont, /* complain_on_overflow */
636 mips_elf_lo16_reloc, /* special_function */
637 "R_MIPS_GNU_REL_LO16", /* name */
b34976b6 638 TRUE, /* partial_inplace */
c6e90b02
TS
639 0xffff, /* src_mask */
640 0xffff, /* dst_mask */
b34976b6 641 TRUE); /* pcrel_offset */
252b5132 642
c6e90b02
TS
643/* 16 bit offset for pc-relative branches. */
644static reloc_howto_type elf_mips_gnu_rel16_s2 =
645 HOWTO (R_MIPS_GNU_REL16_S2, /* type */
646 2, /* rightshift */
252b5132
RH
647 2, /* size (0 = byte, 1 = short, 2 = long) */
648 16, /* bitsize */
b34976b6 649 TRUE, /* pc_relative */
252b5132
RH
650 0, /* bitpos */
651 complain_overflow_signed, /* complain_on_overflow */
a7ebbfdf 652 mips_elf_generic_reloc, /* special_function */
c6e90b02 653 "R_MIPS_GNU_REL16_S2", /* name */
b34976b6 654 TRUE, /* partial_inplace */
c6e90b02
TS
655 0xffff, /* src_mask */
656 0xffff, /* dst_mask */
b34976b6 657 TRUE); /* pcrel_offset */
252b5132 658
c6e90b02
TS
659/* 64 bit pc-relative. */
660static reloc_howto_type elf_mips_gnu_pcrel64 =
661 HOWTO (R_MIPS_PC64, /* type */
252b5132 662 0, /* rightshift */
c6e90b02
TS
663 4, /* size (0 = byte, 1 = short, 2 = long) */
664 64, /* bitsize */
b34976b6 665 TRUE, /* pc_relative */
252b5132
RH
666 0, /* bitpos */
667 complain_overflow_signed, /* complain_on_overflow */
a7ebbfdf 668 mips_elf_generic_reloc, /* special_function */
c6e90b02 669 "R_MIPS_PC64", /* name */
b34976b6 670 TRUE, /* partial_inplace */
c6e90b02
TS
671 MINUS_ONE, /* src_mask */
672 MINUS_ONE, /* dst_mask */
b34976b6 673 TRUE); /* pcrel_offset */
252b5132 674
c6e90b02
TS
675/* 32 bit pc-relative. */
676static reloc_howto_type elf_mips_gnu_pcrel32 =
677 HOWTO (R_MIPS_PC32, /* type */
252b5132
RH
678 0, /* rightshift */
679 2, /* size (0 = byte, 1 = short, 2 = long) */
c6e90b02 680 32, /* bitsize */
b34976b6 681 TRUE, /* pc_relative */
252b5132
RH
682 0, /* bitpos */
683 complain_overflow_signed, /* complain_on_overflow */
a7ebbfdf 684 mips_elf_generic_reloc, /* special_function */
c6e90b02 685 "R_MIPS_PC32", /* name */
b34976b6 686 TRUE, /* partial_inplace */
c6e90b02
TS
687 0xffffffff, /* src_mask */
688 0xffffffff, /* dst_mask */
b34976b6 689 TRUE); /* pcrel_offset */
252b5132 690
c6e90b02
TS
691/* GNU extension to record C++ vtable hierarchy */
692static reloc_howto_type elf_mips_gnu_vtinherit_howto =
693 HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
252b5132
RH
694 0, /* rightshift */
695 2, /* size (0 = byte, 1 = short, 2 = long) */
c6e90b02 696 0, /* bitsize */
b34976b6 697 FALSE, /* pc_relative */
252b5132 698 0, /* bitpos */
c6e90b02
TS
699 complain_overflow_dont, /* complain_on_overflow */
700 NULL, /* special_function */
701 "R_MIPS_GNU_VTINHERIT", /* name */
b34976b6 702 FALSE, /* partial_inplace */
d75bc93d 703 0, /* src_mask */
c6e90b02 704 0, /* dst_mask */
b34976b6 705 FALSE); /* pcrel_offset */
252b5132 706
c6e90b02
TS
707/* GNU extension to record C++ vtable member usage */
708static reloc_howto_type elf_mips_gnu_vtentry_howto =
709 HOWTO (R_MIPS_GNU_VTENTRY, /* type */
252b5132
RH
710 0, /* rightshift */
711 2, /* size (0 = byte, 1 = short, 2 = long) */
c6e90b02 712 0, /* bitsize */
b34976b6 713 FALSE, /* pc_relative */
252b5132
RH
714 0, /* bitpos */
715 complain_overflow_dont, /* complain_on_overflow */
c6e90b02
TS
716 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
717 "R_MIPS_GNU_VTENTRY", /* name */
b34976b6 718 FALSE, /* partial_inplace */
d75bc93d 719 0, /* src_mask */
c6e90b02 720 0, /* dst_mask */
b34976b6 721 FALSE); /* pcrel_offset */
252b5132 722
a7ebbfdf
TS
723/* We use this instead of bfd_elf_generic_reloc because the latter
724 gets the handling of zero addends wrong. */
725static bfd_reloc_status_type
11a2be4d
RS
726mips_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
727 asymbol *symbol, void *data ATTRIBUTE_UNUSED,
728 asection *input_section, bfd *output_bfd,
729 char **error_message ATTRIBUTE_UNUSED)
a7ebbfdf
TS
730{
731 /* If we're relocating, and this is an external symbol, we don't want
732 to change anything. */
11a2be4d 733 if (output_bfd != NULL
a7ebbfdf
TS
734 && (symbol->flags & BSF_SECTION_SYM) == 0
735 && (symbol->flags & BSF_LOCAL) != 0)
736 {
737 reloc_entry->address += input_section->output_offset;
738 return bfd_reloc_ok;
739 }
740
741 /* Just go on, nothing to see here. */
742 return bfd_reloc_continue;
743}
744
252b5132 745/* Do a R_MIPS_HI16 relocation. This has to be done in combination
c6e90b02
TS
746 with a R_MIPS_LO16 reloc, because there is a carry from the LO16 to
747 the HI16. Here we just save the information we need; we do the
748 actual relocation when we see the LO16.
c6142e5d 749
c6e90b02
TS
750 MIPS ELF requires that the LO16 immediately follow the HI16. As a
751 GNU extension, for non-pc-relative relocations, we permit an
752 arbitrary number of HI16 relocs to be associated with a single LO16
753 reloc. This extension permits gcc to output the HI and LO relocs
754 itself.
c6142e5d 755
c6e90b02
TS
756 This cannot be done for PC-relative relocations because both the HI16
757 and LO16 parts of the relocations must be done relative to the LO16
758 part, and there can be carry to or borrow from the HI16 part. */
103186c6 759
c6e90b02 760struct mips_hi16
103186c6 761{
c6e90b02
TS
762 struct mips_hi16 *next;
763 bfd_byte *addr;
764 bfd_vma addend;
765};
be3ccd9c 766
c6e90b02 767/* FIXME: This should not be a static variable. */
103186c6 768
c6e90b02 769static struct mips_hi16 *mips_hi16_list;
252b5132 770
c6e90b02 771static bfd_reloc_status_type
11a2be4d
RS
772mips_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
773 asymbol *symbol, void *data, asection *input_section,
774 bfd *output_bfd, char **error_message)
252b5132 775{
c6e90b02
TS
776 bfd_reloc_status_type ret;
777 bfd_vma relocation;
778 struct mips_hi16 *n;
252b5132 779
cb7394f2 780 /* If we're relocating, and this is an external symbol, we don't want
c6e90b02 781 to change anything. */
11a2be4d 782 if (output_bfd != NULL
c6e90b02 783 && (symbol->flags & BSF_SECTION_SYM) == 0
a7ebbfdf 784 && (symbol->flags & BSF_LOCAL) != 0)
252b5132 785 {
c6e90b02
TS
786 reloc_entry->address += input_section->output_offset;
787 return bfd_reloc_ok;
252b5132 788 }
252b5132 789
c6e90b02 790 ret = bfd_reloc_ok;
252b5132 791
c6e90b02
TS
792 if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0)
793 {
1049f94e 794 bfd_boolean relocatable;
c6e90b02 795 bfd_vma gp;
252b5132 796
c6e90b02
TS
797 if (ret == bfd_reloc_undefined)
798 abort ();
252b5132 799
c6e90b02 800 if (output_bfd != NULL)
1049f94e 801 relocatable = TRUE;
252b5132 802 else
252b5132 803 {
1049f94e 804 relocatable = FALSE;
c6e90b02 805 output_bfd = symbol->section->output_section->owner;
252b5132
RH
806 }
807
1049f94e 808 ret = mips_elf_final_gp (output_bfd, symbol, relocatable,
c6e90b02
TS
809 error_message, &gp);
810 if (ret != bfd_reloc_ok)
811 return ret;
252b5132 812
c6e90b02 813 relocation = gp - reloc_entry->address;
252b5132
RH
814 }
815 else
816 {
11a2be4d 817 if (bfd_is_und_section (symbol->section) && output_bfd == NULL)
c6e90b02 818 ret = bfd_reloc_undefined;
252b5132 819
c6e90b02
TS
820 if (bfd_is_com_section (symbol->section))
821 relocation = 0;
252b5132 822 else
c6e90b02
TS
823 relocation = symbol->value;
824 }
252b5132 825
c6e90b02
TS
826 relocation += symbol->section->output_section->vma;
827 relocation += symbol->section->output_offset;
828 relocation += reloc_entry->addend;
9117d219 829
c6e90b02
TS
830 if (reloc_entry->address > input_section->_cooked_size)
831 return bfd_reloc_outofrange;
9117d219 832
c6e90b02 833 /* Save the information, and let LO16 do the actual relocation. */
11a2be4d 834 n = bfd_malloc (sizeof *n);
c6e90b02
TS
835 if (n == NULL)
836 return bfd_reloc_outofrange;
837 n->addr = (bfd_byte *) data + reloc_entry->address;
838 n->addend = relocation;
839 n->next = mips_hi16_list;
840 mips_hi16_list = n;
252b5132 841
11a2be4d 842 if (output_bfd != NULL)
c6e90b02 843 reloc_entry->address += input_section->output_offset;
252b5132 844
c6e90b02 845 return ret;
252b5132
RH
846}
847
c6e90b02
TS
848/* Do a R_MIPS_LO16 relocation. This is a straightforward 16 bit
849 inplace relocation; this function exists in order to do the
850 R_MIPS_HI16 relocation described above. */
252b5132 851
c6e90b02 852static bfd_reloc_status_type
11a2be4d
RS
853mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
854 void *data, asection *input_section, bfd *output_bfd,
855 char **error_message)
252b5132 856{
c6e90b02 857 arelent gp_disp_relent;
252b5132 858
c6e90b02 859 if (mips_hi16_list != NULL)
252b5132 860 {
c6e90b02 861 struct mips_hi16 *l;
252b5132 862
c6e90b02
TS
863 l = mips_hi16_list;
864 while (l != NULL)
865 {
866 unsigned long insn;
867 unsigned long val;
868 unsigned long vallo;
869 struct mips_hi16 *next;
252b5132 870
c6e90b02
TS
871 if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0)
872 {
873 gp_disp_relent = *reloc_entry;
874 reloc_entry = &gp_disp_relent;
875 reloc_entry->addend = l->addend;
876 }
91709090
TS
877 else
878 {
879 /* Do the HI16 relocation. Note that we actually don't need
880 to know anything about the LO16 itself, except where to
881 find the low 16 bits of the addend needed by the LO16. */
882 insn = bfd_get_32 (abfd, l->addr);
883 vallo = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
884 /* The low order 16 bits are always treated as a signed
885 value. */
886 vallo = ((vallo & 0xffff) ^ 0x8000) - 0x8000;
887 val = ((insn & 0xffff) << 16) + vallo;
888 val += l->addend;
889
890 /* If PC-relative, we need to subtract out the address of the LO
891 half of the HI/LO. (The actual relocation is relative
892 to that instruction.) */
893 if (reloc_entry->howto->pc_relative)
894 val -= reloc_entry->address;
895
896 /* At this point, "val" has the value of the combined HI/LO
897 pair. If the low order 16 bits (which will be used for
898 the LO16 insn) are negative, then we will need an
899 adjustment for the high order 16 bits. */
900 val += 0x8000;
901 val = (val >> 16) & 0xffff;
902
903 insn &= ~ (bfd_vma) 0xffff;
904 insn |= val;
11a2be4d 905 bfd_put_32 (abfd, insn, l->addr);
91709090 906 }
8a20f077 907
c6e90b02
TS
908 next = l->next;
909 free (l);
910 l = next;
911 }
252b5132 912
c6e90b02 913 mips_hi16_list = NULL;
43917054 914 }
c6e90b02 915 else if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0)
252b5132 916 {
c6e90b02
TS
917 bfd_reloc_status_type ret;
918 bfd_vma gp, relocation;
252b5132 919
c6e90b02 920 /* FIXME: Does this case ever occur? */
252b5132 921
b34976b6 922 ret = mips_elf_final_gp (output_bfd, symbol, TRUE, error_message, &gp);
c6e90b02
TS
923 if (ret != bfd_reloc_ok)
924 return ret;
252b5132 925
c6e90b02
TS
926 relocation = gp - reloc_entry->address;
927 relocation += symbol->section->output_section->vma;
928 relocation += symbol->section->output_offset;
929 relocation += reloc_entry->addend;
252b5132 930
c6e90b02
TS
931 if (reloc_entry->address > input_section->_cooked_size)
932 return bfd_reloc_outofrange;
252b5132 933
c6e90b02
TS
934 gp_disp_relent = *reloc_entry;
935 reloc_entry = &gp_disp_relent;
936 reloc_entry->addend = relocation - 4;
252b5132
RH
937 }
938
c6e90b02 939 /* Now do the LO16 reloc in the usual way. */
a7ebbfdf
TS
940 return mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
941 input_section, output_bfd, error_message);
252b5132
RH
942}
943
c6e90b02
TS
944/* Do a R_MIPS_GOT16 reloc. This is a reloc against the global offset
945 table used for PIC code. If the symbol is an external symbol, the
946 instruction is modified to contain the offset of the appropriate
947 entry in the global offset table. If the symbol is a section
948 symbol, the next reloc is a R_MIPS_LO16 reloc. The two 16 bit
949 addends are combined to form the real addend against the section
950 symbol; the GOT16 is modified to contain the offset of an entry in
951 the global offset table, and the LO16 is modified to offset it
952 appropriately. Thus an offset larger than 16 bits requires a
953 modified value in the global offset table.
252b5132 954
c6e90b02
TS
955 This implementation suffices for the assembler, but the linker does
956 not yet know how to create global offset tables. */
252b5132 957
c6e90b02 958static bfd_reloc_status_type
11a2be4d
RS
959mips_elf_got16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
960 void *data, asection *input_section, bfd *output_bfd,
961 char **error_message)
252b5132 962{
cb7394f2 963 /* If we're relocating, and this is an external symbol, we don't want
c6e90b02 964 to change anything. */
11a2be4d 965 if (output_bfd != NULL
c6e90b02 966 && (symbol->flags & BSF_SECTION_SYM) == 0
a7ebbfdf 967 && (symbol->flags & BSF_LOCAL) != 0)
c6e90b02
TS
968 {
969 reloc_entry->address += input_section->output_offset;
970 return bfd_reloc_ok;
971 }
252b5132 972
a7ebbfdf
TS
973 return mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
974 input_section, output_bfd, error_message);
252b5132
RH
975}
976
b34976b6 977/* Set the GP value for OUTPUT_BFD. Returns FALSE if this is a
c6e90b02 978 dangerous relocation. */
252b5132 979
b34976b6 980static bfd_boolean
11a2be4d 981mips_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
252b5132 982{
c6e90b02
TS
983 unsigned int count;
984 asymbol **sym;
985 unsigned int i;
e92d460e 986
c6e90b02
TS
987 /* If we've already figured out what GP will be, just return it. */
988 *pgp = _bfd_get_gp_value (output_bfd);
989 if (*pgp)
b34976b6 990 return TRUE;
c6e90b02
TS
991
992 count = bfd_get_symcount (output_bfd);
993 sym = bfd_get_outsymbols (output_bfd);
252b5132 994
c6e90b02
TS
995 /* The linker script will have created a symbol named `_gp' with the
996 appropriate value. */
11a2be4d 997 if (sym == NULL)
c6e90b02
TS
998 i = count;
999 else
252b5132 1000 {
c6e90b02
TS
1001 for (i = 0; i < count; i++, sym++)
1002 {
1003 register const char *name;
1004
1005 name = bfd_asymbol_name (*sym);
1006 if (*name == '_' && strcmp (name, "_gp") == 0)
1007 {
1008 *pgp = bfd_asymbol_value (*sym);
1009 _bfd_set_gp_value (output_bfd, *pgp);
1010 break;
1011 }
1012 }
252b5132
RH
1013 }
1014
c6e90b02 1015 if (i >= count)
252b5132 1016 {
c6e90b02
TS
1017 /* Only get the error once. */
1018 *pgp = 4;
1019 _bfd_set_gp_value (output_bfd, *pgp);
b34976b6 1020 return FALSE;
252b5132
RH
1021 }
1022
b34976b6 1023 return TRUE;
252b5132
RH
1024}
1025
c6e90b02
TS
1026/* We have to figure out the gp value, so that we can adjust the
1027 symbol value correctly. We look up the symbol _gp in the output
1028 BFD. If we can't find it, we're stuck. We cache it in the ELF
1029 target data. We don't need to adjust the symbol value for an
1049f94e 1030 external symbol if we are producing relocatable output. */
252b5132 1031
c6e90b02 1032static bfd_reloc_status_type
11a2be4d
RS
1033mips_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
1034 char **error_message, bfd_vma *pgp)
252b5132 1035{
c6e90b02 1036 if (bfd_is_und_section (symbol->section)
1049f94e 1037 && ! relocatable)
252b5132 1038 {
c6e90b02
TS
1039 *pgp = 0;
1040 return bfd_reloc_undefined;
252b5132
RH
1041 }
1042
c6e90b02
TS
1043 *pgp = _bfd_get_gp_value (output_bfd);
1044 if (*pgp == 0
1049f94e 1045 && (! relocatable
c6e90b02 1046 || (symbol->flags & BSF_SECTION_SYM) != 0))
252b5132 1047 {
1049f94e 1048 if (relocatable)
252b5132 1049 {
c6e90b02
TS
1050 /* Make up a value. */
1051 *pgp = symbol->section->output_section->vma + 0x4000;
1052 _bfd_set_gp_value (output_bfd, *pgp);
252b5132 1053 }
c6e90b02 1054 else if (!mips_elf_assign_gp (output_bfd, pgp))
252b5132 1055 {
c6e90b02
TS
1056 *error_message =
1057 (char *) _("GP relative relocation when _gp not defined");
1058 return bfd_reloc_dangerous;
252b5132 1059 }
252b5132
RH
1060 }
1061
c6e90b02
TS
1062 return bfd_reloc_ok;
1063}
252b5132 1064
c6e90b02
TS
1065/* Do a R_MIPS_GPREL16 relocation. This is a 16 bit value which must
1066 become the offset from the gp register. This function also handles
1067 R_MIPS_LITERAL relocations, although those can be handled more
1068 cleverly because the entries in the .lit8 and .lit4 sections can be
1069 merged. */
252b5132 1070
c6e90b02 1071bfd_reloc_status_type
11a2be4d
RS
1072_bfd_mips_elf32_gprel16_reloc (bfd *abfd, arelent *reloc_entry,
1073 asymbol *symbol, void *data,
1074 asection *input_section, bfd *output_bfd,
1075 char **error_message)
c6e90b02 1076{
1049f94e 1077 bfd_boolean relocatable;
c6e90b02
TS
1078 bfd_reloc_status_type ret;
1079 bfd_vma gp;
252b5132 1080
a7ebbfdf
TS
1081 /* If we're relocating, and this is an external symbol, we don't want
1082 to change anything. */
11a2be4d 1083 if (output_bfd != NULL
c6e90b02 1084 && (symbol->flags & BSF_SECTION_SYM) == 0
a7ebbfdf 1085 && (symbol->flags & BSF_LOCAL) != 0)
c6e90b02
TS
1086 {
1087 reloc_entry->address += input_section->output_offset;
1088 return bfd_reloc_ok;
1089 }
252b5132 1090
11a2be4d 1091 if (output_bfd != NULL)
1049f94e 1092 relocatable = TRUE;
c6e90b02
TS
1093 else
1094 {
1049f94e 1095 relocatable = FALSE;
c6e90b02
TS
1096 output_bfd = symbol->section->output_section->owner;
1097 }
252b5132 1098
1049f94e 1099 ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
c6e90b02
TS
1100 &gp);
1101 if (ret != bfd_reloc_ok)
1102 return ret;
252b5132 1103
c6e90b02 1104 return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1049f94e 1105 input_section, relocatable,
c6e90b02
TS
1106 data, gp);
1107}
252b5132 1108
cb7394f2
TS
1109/* Do a R_MIPS_GPREL32 relocation. This is a 32 bit value which must
1110 become the offset from the gp register. */
252b5132 1111
c6e90b02 1112static bfd_reloc_status_type
11a2be4d
RS
1113mips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1114 void *data, asection *input_section, bfd *output_bfd,
1115 char **error_message)
c6e90b02 1116{
1049f94e 1117 bfd_boolean relocatable;
c6e90b02
TS
1118 bfd_reloc_status_type ret;
1119 bfd_vma gp;
252b5132 1120
a7ebbfdf
TS
1121 /* If we're relocating, and this is an external symbol, we don't want
1122 to change anything. */
11a2be4d 1123 if (output_bfd != NULL
c6e90b02 1124 && (symbol->flags & BSF_SECTION_SYM) == 0
a7ebbfdf 1125 && (symbol->flags & BSF_LOCAL) != 0)
c6e90b02
TS
1126 {
1127 *error_message = (char *)
1128 _("32bits gp relative relocation occurs for an external symbol");
1129 return bfd_reloc_outofrange;
1130 }
252b5132 1131
11a2be4d 1132 if (output_bfd != NULL)
1049f94e 1133 relocatable = TRUE;
c6e90b02
TS
1134 else
1135 {
1049f94e 1136 relocatable = FALSE;
c6e90b02 1137 output_bfd = symbol->section->output_section->owner;
c6e90b02 1138 }
252b5132 1139
1049f94e 1140 ret = mips_elf_final_gp (output_bfd, symbol, relocatable,
a7ebbfdf
TS
1141 error_message, &gp);
1142 if (ret != bfd_reloc_ok)
1143 return ret;
1144
c6e90b02 1145 return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
1049f94e 1146 relocatable, data, gp);
c6e90b02 1147}
252b5132 1148
c6e90b02 1149static bfd_reloc_status_type
11a2be4d
RS
1150gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
1151 asection *input_section, bfd_boolean relocatable,
1152 void *data, bfd_vma gp)
c6e90b02
TS
1153{
1154 bfd_vma relocation;
a7ebbfdf 1155 bfd_vma val;
252b5132 1156
c6e90b02
TS
1157 if (bfd_is_com_section (symbol->section))
1158 relocation = 0;
1159 else
1160 relocation = symbol->value;
252b5132 1161
c6e90b02
TS
1162 relocation += symbol->section->output_section->vma;
1163 relocation += symbol->section->output_offset;
252b5132 1164
c6e90b02
TS
1165 if (reloc_entry->address > input_section->_cooked_size)
1166 return bfd_reloc_outofrange;
252b5132 1167
c6e90b02 1168 /* Set val to the offset into the section or symbol. */
a7ebbfdf
TS
1169 val = reloc_entry->addend;
1170
1171 if (reloc_entry->howto->partial_inplace)
1172 val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
252b5132 1173
c6e90b02 1174 /* Adjust val for the final section location and GP value. If we
1049f94e 1175 are producing relocatable output, we don't want to do this for
c6e90b02 1176 an external symbol. */
1049f94e 1177 if (! relocatable
c6e90b02
TS
1178 || (symbol->flags & BSF_SECTION_SYM) != 0)
1179 val += relocation - gp;
252b5132 1180
a7ebbfdf
TS
1181 if (reloc_entry->howto->partial_inplace)
1182 bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
1183 else
1184 reloc_entry->addend = val;
c6142e5d 1185
1049f94e 1186 if (relocatable)
c6e90b02 1187 reloc_entry->address += input_section->output_offset;
252b5132 1188
c6e90b02 1189 return bfd_reloc_ok;
252b5132
RH
1190}
1191
c6e90b02
TS
1192/* Handle a 64 bit reloc in a 32 bit MIPS ELF file. These are
1193 generated when addresses are 64 bits. The upper 32 bits are a simple
1194 sign extension. */
7403cb63 1195
c6e90b02 1196static bfd_reloc_status_type
11a2be4d
RS
1197mips32_64bit_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1198 void *data, asection *input_section, bfd *output_bfd,
1199 char **error_message)
7403cb63 1200{
c6e90b02
TS
1201 bfd_reloc_status_type r;
1202 arelent reloc32;
1203 unsigned long val;
1204 bfd_size_type addr;
7403cb63 1205
a7ebbfdf
TS
1206 r = mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
1207 input_section, output_bfd, error_message);
c6e90b02
TS
1208 if (r != bfd_reloc_continue)
1209 return r;
be3ccd9c 1210
c6e90b02
TS
1211 /* Do a normal 32 bit relocation on the lower 32 bits. */
1212 reloc32 = *reloc_entry;
1213 if (bfd_big_endian (abfd))
1214 reloc32.address += 4;
1215 reloc32.howto = &elf_mips_howto_table_rel[R_MIPS_32];
1216 r = bfd_perform_relocation (abfd, &reloc32, data, input_section,
1217 output_bfd, error_message);
be3ccd9c 1218
c6e90b02
TS
1219 /* Sign extend into the upper 32 bits. */
1220 val = bfd_get_32 (abfd, (bfd_byte *) data + reloc32.address);
1221 if ((val & 0x80000000) != 0)
1222 val = 0xffffffff;
1223 else
1224 val = 0;
1225 addr = reloc_entry->address;
1226 if (bfd_little_endian (abfd))
1227 addr += 4;
11a2be4d 1228 bfd_put_32 (abfd, val, (bfd_byte *) data + addr);
c6e90b02
TS
1229
1230 return r;
7403cb63
MM
1231}
1232
c6e90b02 1233/* Handle a mips16 jump. */
252b5132 1234
c6e90b02 1235static bfd_reloc_status_type
11a2be4d
RS
1236mips16_jump_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
1237 asymbol *symbol, void *data ATTRIBUTE_UNUSED,
1238 asection *input_section, bfd *output_bfd,
1239 char **error_message ATTRIBUTE_UNUSED)
252b5132 1240{
11a2be4d 1241 if (output_bfd != NULL
c6e90b02
TS
1242 && (symbol->flags & BSF_SECTION_SYM) == 0
1243 && reloc_entry->addend == 0)
252b5132 1244 {
c6e90b02
TS
1245 reloc_entry->address += input_section->output_offset;
1246 return bfd_reloc_ok;
1247 }
252b5132 1248
c6e90b02
TS
1249 /* FIXME. */
1250 {
b34976b6 1251 static bfd_boolean warned;
252b5132 1252
c6e90b02
TS
1253 if (! warned)
1254 (*_bfd_error_handler)
1255 (_("Linking mips16 objects into %s format is not supported"),
1256 bfd_get_target (input_section->output_section->owner));
b34976b6 1257 warned = TRUE;
c6e90b02 1258 }
252b5132 1259
c6e90b02
TS
1260 return bfd_reloc_undefined;
1261}
252b5132 1262
c6e90b02 1263/* Handle a mips16 GP relative reloc. */
252b5132 1264
c6e90b02 1265static bfd_reloc_status_type
11a2be4d
RS
1266mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1267 void *data, asection *input_section, bfd *output_bfd,
1268 char **error_message)
c6e90b02 1269{
1049f94e 1270 bfd_boolean relocatable;
c6e90b02
TS
1271 bfd_reloc_status_type ret;
1272 bfd_vma gp;
a7ebbfdf
TS
1273 unsigned short extend = 0;
1274 unsigned short insn = 0;
1275 bfd_signed_vma val;
1276 bfd_vma relocation;
252b5132 1277
a7ebbfdf
TS
1278 /* If we're relocating, and this is an external symbol, we don't want
1279 to change anything. */
c6e90b02
TS
1280 if (output_bfd != NULL
1281 && (symbol->flags & BSF_SECTION_SYM) == 0
a7ebbfdf 1282 && (symbol->flags & BSF_LOCAL) != 0)
c6e90b02
TS
1283 {
1284 reloc_entry->address += input_section->output_offset;
1285 return bfd_reloc_ok;
1286 }
252b5132 1287
c6e90b02 1288 if (output_bfd != NULL)
1049f94e 1289 relocatable = TRUE;
c6e90b02
TS
1290 else
1291 {
1049f94e 1292 relocatable = FALSE;
c6e90b02 1293 output_bfd = symbol->section->output_section->owner;
252b5132
RH
1294 }
1295
1049f94e 1296 ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
c6e90b02
TS
1297 &gp);
1298 if (ret != bfd_reloc_ok)
1299 return ret;
252b5132 1300
c6e90b02
TS
1301 if (reloc_entry->address > input_section->_cooked_size)
1302 return bfd_reloc_outofrange;
252b5132 1303
a7ebbfdf
TS
1304 if (bfd_is_com_section (symbol->section))
1305 relocation = 0;
1306 else
1307 relocation = symbol->value;
252b5132 1308
a7ebbfdf
TS
1309 relocation += symbol->section->output_section->vma;
1310 relocation += symbol->section->output_offset;
1311
1312 /* Set val to the offset into the section or symbol. */
1313 val = reloc_entry->addend;
1314
1315 if (reloc_entry->howto->partial_inplace)
1316 {
1317 /* Pick up the mips16 extend instruction and the real instruction. */
1318 extend = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);
1319 insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address + 2);
1320 val += ((extend & 0x1f) << 11) | (extend & 0x7e0) | (insn & 0x1f);
1321 }
1322
1323 _bfd_mips_elf_sign_extend(val, 16);
1324
1325 /* Adjust val for the final section location and GP value. If we
1049f94e 1326 are producing relocatable output, we don't want to do this for
a7ebbfdf 1327 an external symbol. */
1049f94e 1328 if (! relocatable
a7ebbfdf
TS
1329 || (symbol->flags & BSF_SECTION_SYM) != 0)
1330 val += relocation - gp;
1331
1332 if (reloc_entry->howto->partial_inplace)
1333 {
1334 bfd_put_16 (abfd,
11a2be4d 1335 (extend & 0xf800) | ((val >> 11) & 0x1f) | (val & 0x7e0),
a7ebbfdf
TS
1336 (bfd_byte *) data + reloc_entry->address);
1337 bfd_put_16 (abfd,
11a2be4d 1338 (insn & 0xffe0) | (val & 0x1f),
a7ebbfdf
TS
1339 (bfd_byte *) data + reloc_entry->address + 2);
1340 }
1341 else
1342 reloc_entry->addend = val;
1343
1049f94e 1344 if (relocatable)
a7ebbfdf
TS
1345 reloc_entry->address += input_section->output_offset;
1346 else if (((val & ~0xffff) != ~0xffff) && ((val & ~0xffff) != 0))
1347 return bfd_reloc_overflow;
1348
1349 return bfd_reloc_ok;
c6e90b02 1350}
7403cb63 1351
c6e90b02 1352/* A mapping from BFD reloc types to MIPS ELF reloc types. */
252b5132 1353
c6e90b02 1354struct elf_reloc_map {
cb7394f2
TS
1355 bfd_reloc_code_real_type bfd_val;
1356 enum elf_mips_reloc_type elf_val;
c6e90b02 1357};
252b5132 1358
c6e90b02
TS
1359static const struct elf_reloc_map mips_reloc_map[] =
1360{
28458e7e 1361 { BFD_RELOC_NONE, R_MIPS_NONE },
c6e90b02
TS
1362 { BFD_RELOC_16, R_MIPS_16 },
1363 { BFD_RELOC_32, R_MIPS_32 },
cb7394f2 1364 /* There is no BFD reloc for R_MIPS_REL32. */
c6e90b02
TS
1365 { BFD_RELOC_64, R_MIPS_64 },
1366 { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1367 { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1368 { BFD_RELOC_LO16, R_MIPS_LO16 },
1369 { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
1370 { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1371 { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
0b25d3e6 1372 { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
c6e90b02
TS
1373 { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1374 { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
1375 { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1376 { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1377 { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
1378 { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1379 { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1380 { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1381 { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1382 { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP }
1383};
252b5132 1384
c6e90b02 1385/* Given a BFD reloc type, return a howto structure. */
252b5132 1386
c6e90b02 1387static reloc_howto_type *
11a2be4d 1388bfd_elf32_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
252b5132 1389{
c6e90b02 1390 unsigned int i;
cb7394f2 1391 reloc_howto_type *howto_table = elf_mips_howto_table_rel;
252b5132 1392
cb7394f2
TS
1393 for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
1394 i++)
252b5132 1395 {
cb7394f2
TS
1396 if (mips_reloc_map[i].bfd_val == code)
1397 return &howto_table[(int) mips_reloc_map[i].elf_val];
252b5132
RH
1398 }
1399
c6e90b02 1400 switch (code)
252b5132 1401 {
c6e90b02
TS
1402 default:
1403 bfd_set_error (bfd_error_bad_value);
1404 return NULL;
252b5132 1405
c6e90b02
TS
1406 case BFD_RELOC_CTOR:
1407 /* We need to handle BFD_RELOC_CTOR specially.
1408 Select the right relocation (R_MIPS_32 or R_MIPS_64) based on the
69931e60
AO
1409 size of addresses of the ABI. */
1410 if ((elf_elfheader (abfd)->e_flags & (E_MIPS_ABI_O64
1411 | E_MIPS_ABI_EABI64)) != 0)
c6e90b02 1412 return &elf_mips_ctor64_howto;
69931e60
AO
1413 else
1414 return &howto_table[(int) R_MIPS_32];
252b5132 1415
c6e90b02
TS
1416 case BFD_RELOC_MIPS16_JMP:
1417 return &elf_mips16_jump_howto;
1418 case BFD_RELOC_MIPS16_GPREL:
1419 return &elf_mips16_gprel_howto;
1420 case BFD_RELOC_VTABLE_INHERIT:
1421 return &elf_mips_gnu_vtinherit_howto;
1422 case BFD_RELOC_VTABLE_ENTRY:
1423 return &elf_mips_gnu_vtentry_howto;
1424 case BFD_RELOC_PCREL_HI16_S:
1425 return &elf_mips_gnu_rel_hi16;
1426 case BFD_RELOC_PCREL_LO16:
1427 return &elf_mips_gnu_rel_lo16;
0b25d3e6 1428 case BFD_RELOC_16_PCREL_S2:
c6e90b02
TS
1429 return &elf_mips_gnu_rel16_s2;
1430 case BFD_RELOC_64_PCREL:
1431 return &elf_mips_gnu_pcrel64;
1432 case BFD_RELOC_32_PCREL:
1433 return &elf_mips_gnu_pcrel32;
1434 }
1435}
252b5132 1436
947216bf 1437/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
252b5132 1438
c6e90b02 1439static reloc_howto_type *
11a2be4d
RS
1440mips_elf32_rtype_to_howto (unsigned int r_type,
1441 bfd_boolean rela_p ATTRIBUTE_UNUSED)
c6e90b02
TS
1442{
1443 switch (r_type)
1444 {
1445 case R_MIPS16_26:
1446 return &elf_mips16_jump_howto;
c6e90b02
TS
1447 case R_MIPS16_GPREL:
1448 return &elf_mips16_gprel_howto;
c6e90b02
TS
1449 case R_MIPS_GNU_VTINHERIT:
1450 return &elf_mips_gnu_vtinherit_howto;
c6e90b02
TS
1451 case R_MIPS_GNU_VTENTRY:
1452 return &elf_mips_gnu_vtentry_howto;
c6e90b02
TS
1453 case R_MIPS_GNU_REL_HI16:
1454 return &elf_mips_gnu_rel_hi16;
c6e90b02
TS
1455 case R_MIPS_GNU_REL_LO16:
1456 return &elf_mips_gnu_rel_lo16;
c6e90b02
TS
1457 case R_MIPS_GNU_REL16_S2:
1458 return &elf_mips_gnu_rel16_s2;
c6e90b02
TS
1459 case R_MIPS_PC64:
1460 return &elf_mips_gnu_pcrel64;
c6e90b02
TS
1461 case R_MIPS_PC32:
1462 return &elf_mips_gnu_pcrel32;
c6e90b02
TS
1463 default:
1464 BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
1465 return &elf_mips_howto_table_rel[r_type];
1466 }
1467}
252b5132 1468
947216bf 1469/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */
252b5132 1470
c6e90b02 1471static void
11a2be4d 1472mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
c6e90b02
TS
1473{
1474 unsigned int r_type;
252b5132 1475
c6e90b02 1476 r_type = ELF32_R_TYPE (dst->r_info);
b34976b6 1477 cache_ptr->howto = mips_elf32_rtype_to_howto (r_type, FALSE);
252b5132 1478
c6e90b02
TS
1479 /* The addend for a GPREL16 or LITERAL relocation comes from the GP
1480 value for the object file. We get the addend now, rather than
1481 when we do the relocation, because the symbol manipulations done
1482 by the linker may cause us to lose track of the input BFD. */
1483 if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
1484 && (r_type == (unsigned int) R_MIPS_GPREL16
1485 || r_type == (unsigned int) R_MIPS_LITERAL))
1486 cache_ptr->addend = elf_gp (abfd);
1487}
5499724a 1488
947216bf 1489/* Given a MIPS Elf_Internal_Rela, fill in an arelent structure. */
252b5132 1490
c6e90b02 1491static void
11a2be4d 1492mips_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
c6e90b02 1493{
947216bf 1494 mips_info_to_howto_rel (abfd, cache_ptr, dst);
252b5132 1495
c6e90b02 1496 /* If we ever need to do any extra processing with dst->r_addend
947216bf 1497 (the field omitted in an Elf_Internal_Rel) we can do it here. */
c6e90b02
TS
1498}
1499\f
1500/* Determine whether a symbol is global for the purposes of splitting
1501 the symbol table into global symbols and local symbols. At least
1502 on Irix 5, this split must be between section symbols and all other
1503 symbols. On most ELF targets the split is between static symbols
1504 and externally visible symbols. */
252b5132 1505
b34976b6 1506static bfd_boolean
11a2be4d 1507mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
c6e90b02
TS
1508{
1509 if (SGI_COMPAT (abfd))
1510 return (sym->flags & BSF_SECTION_SYM) == 0;
1511 else
1512 return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
1513 || bfd_is_und_section (bfd_get_section (sym))
1514 || bfd_is_com_section (bfd_get_section (sym)));
1515}
1516\f
1517/* Set the right machine number for a MIPS ELF file. */
7403cb63 1518
b34976b6 1519static bfd_boolean
11a2be4d 1520mips_elf32_object_p (bfd *abfd)
c6e90b02
TS
1521{
1522 unsigned long mach;
103186c6 1523
c6e90b02
TS
1524 /* Irix 5 and 6 are broken. Object file symbol tables are not always
1525 sorted correctly such that local symbols precede global symbols,
1526 and the sh_info field in the symbol table is not always right. */
1527 if (SGI_COMPAT (abfd))
b34976b6 1528 elf_bad_symtab (abfd) = TRUE;
103186c6 1529
8a397dad 1530 if (ABI_N32_P (abfd))
b34976b6 1531 return FALSE;
8a397dad 1532
c6e90b02
TS
1533 mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
1534 bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
252b5132 1535
b34976b6 1536 return TRUE;
c6e90b02
TS
1537}
1538\f
1539/* MIPS ELF local labels start with '$', not 'L'. */
252b5132 1540
b34976b6 1541static bfd_boolean
11a2be4d 1542mips_elf_is_local_label_name (bfd *abfd, const char *name)
c6e90b02
TS
1543{
1544 if (name[0] == '$')
b34976b6 1545 return TRUE;
252b5132 1546
c6e90b02
TS
1547 /* On Irix 6, the labels go back to starting with '.', so we accept
1548 the generic ELF local label syntax as well. */
1549 return _bfd_elf_is_local_label_name (abfd, name);
252b5132
RH
1550}
1551\f
c6e90b02 1552/* Support for core dump NOTE sections. */
b34976b6 1553static bfd_boolean
11a2be4d 1554elf32_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
bb0082d6
AM
1555{
1556 int offset;
dc810e39 1557 unsigned int raw_size;
bb0082d6
AM
1558
1559 switch (note->descsz)
1560 {
1561 default:
b34976b6 1562 return FALSE;
bb0082d6
AM
1563
1564 case 256: /* Linux/MIPS */
1565 /* pr_cursig */
1566 elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
1567
1568 /* pr_pid */
1569 elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
1570
1571 /* pr_reg */
1572 offset = 72;
1573 raw_size = 180;
1574
1575 break;
1576 }
1577
1578 /* Make a ".reg/999" section. */
936e320b
AM
1579 return _bfd_elfcore_make_pseudosection (abfd, ".reg",
1580 raw_size, note->descpos + offset);
bb0082d6
AM
1581}
1582
b34976b6 1583static bfd_boolean
11a2be4d 1584elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
bb0082d6
AM
1585{
1586 switch (note->descsz)
1587 {
1588 default:
b34976b6 1589 return FALSE;
bb0082d6
AM
1590
1591 case 128: /* Linux/MIPS elf_prpsinfo */
1592 elf_tdata (abfd)->core_program
1593 = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
1594 elf_tdata (abfd)->core_command
1595 = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
1596 }
1597
1598 /* Note that for some reason, a spurious space is tacked
1599 onto the end of the args in some (at least one anyway)
1600 implementations, so strip it off if it exists. */
1601
1602 {
1603 char *command = elf_tdata (abfd)->core_command;
1604 int n = strlen (command);
1605
1606 if (0 < n && command[n - 1] == ' ')
1607 command[n - 1] = '\0';
1608 }
1609
b34976b6 1610 return TRUE;
bb0082d6
AM
1611}
1612\f
c6e90b02
TS
1613/* Depending on the target vector we generate some version of Irix
1614 executables or "normal" MIPS ELF ABI executables. */
1615static irix_compat_t
11a2be4d 1616elf32_mips_irix_compat (bfd *abfd)
c6e90b02 1617{
cb7394f2
TS
1618 if ((abfd->xvec == &bfd_elf32_bigmips_vec)
1619 || (abfd->xvec == &bfd_elf32_littlemips_vec))
c6e90b02 1620 return ict_irix5;
cb7394f2
TS
1621 else
1622 return ict_none;
c6e90b02 1623}
73d074b4 1624\f
030d18fb
CD
1625/* Given a data section and an in-memory embedded reloc section, store
1626 relocation information into the embedded reloc section which can be
1627 used at runtime to relocate the data section. This is called by the
1628 linker when the --embedded-relocs switch is used. This is called
1629 after the add_symbols entry point has been called for all the
1630 objects, and before the final_link entry point is called. */
1631
b34976b6 1632bfd_boolean
11a2be4d
RS
1633bfd_mips_elf32_create_embedded_relocs (bfd *abfd, struct bfd_link_info *info,
1634 asection *datasec, asection *relsec,
1635 char **errmsg)
030d18fb
CD
1636{
1637 Elf_Internal_Shdr *symtab_hdr;
6cdc0ccc
AM
1638 Elf_Internal_Sym *isymbuf = NULL;
1639 Elf_Internal_Rela *internal_relocs = NULL;
030d18fb
CD
1640 Elf_Internal_Rela *irel, *irelend;
1641 bfd_byte *p;
030d18fb 1642
1049f94e 1643 BFD_ASSERT (! info->relocatable);
030d18fb
CD
1644
1645 *errmsg = NULL;
1646
1647 if (datasec->reloc_count == 0)
b34976b6 1648 return TRUE;
030d18fb 1649
030d18fb
CD
1650 /* Read this BFD's symbols if we haven't done so already, or get the cached
1651 copy if it exists. */
6cdc0ccc
AM
1652 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1653 if (symtab_hdr->sh_info != 0)
030d18fb 1654 {
6cdc0ccc
AM
1655 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1656 if (isymbuf == NULL)
1657 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1658 symtab_hdr->sh_info, 0,
1659 NULL, NULL, NULL);
1660 if (isymbuf == NULL)
030d18fb
CD
1661 goto error_return;
1662 }
1663
1664 /* Get a copy of the native relocations. */
11a2be4d
RS
1665 internal_relocs = _bfd_elf_link_read_relocs (abfd, datasec, NULL, NULL,
1666 info->keep_memory);
030d18fb
CD
1667 if (internal_relocs == NULL)
1668 goto error_return;
030d18fb 1669
11a2be4d 1670 relsec->contents = bfd_alloc (abfd, datasec->reloc_count * 12);
030d18fb
CD
1671 if (relsec->contents == NULL)
1672 goto error_return;
1673
1674 p = relsec->contents;
1675
1676 irelend = internal_relocs + datasec->reloc_count;
1677
1678 for (irel = internal_relocs; irel < irelend; irel++, p += 12)
1679 {
1680 asection *targetsec;
1681
1682 /* We are going to write a four byte longword into the runtime
c6e90b02
TS
1683 reloc section. The longword will be the address in the data
1684 section which must be relocated. It is followed by the name
1685 of the target section NUL-padded or truncated to 8
1686 characters. */
030d18fb
CD
1687
1688 /* We can only relocate absolute longword relocs at run time. */
1689 if ((ELF32_R_TYPE (irel->r_info) != (int) R_MIPS_32) &&
1690 (ELF32_R_TYPE (irel->r_info) != (int) R_MIPS_64))
1691 {
1692 *errmsg = _("unsupported reloc type");
1693 bfd_set_error (bfd_error_bad_value);
1694 goto error_return;
1695 }
1696 /* Get the target section referred to by the reloc. */
1697 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1698 {
6cdc0ccc 1699 Elf_Internal_Sym *isym;
030d18fb
CD
1700
1701 /* A local symbol. */
6cdc0ccc
AM
1702 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1703 targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
030d18fb
CD
1704 }
1705 else
1706 {
1707 unsigned long indx;
1708 struct elf_link_hash_entry *h;
1709
1710 /* An external symbol. */
1711 indx = ELF32_R_SYM (irel->r_info);
1712 h = elf_sym_hashes (abfd)[indx];
1713 targetsec = NULL;
1714 /*
c6e90b02
TS
1715 For some reason, in certain programs, the symbol will
1716 not be in the hash table. It seems to happen when you
1717 declare a static table of pointers to const external structures.
1718 In this case, the relocs are relative to data, not
1719 text, so just treating it like an undefined link
1720 should be sufficient. */
030d18fb
CD
1721 BFD_ASSERT(h != NULL);
1722 if (h->root.type == bfd_link_hash_defined
1723 || h->root.type == bfd_link_hash_defweak)
1724 targetsec = h->root.u.def.section;
1725 }
1726
1727
1728 /*
c6e90b02
TS
1729 Set the low bit of the relocation offset if it's a MIPS64 reloc.
1730 Relocations will always be on (at least) 32-bit boundaries. */
030d18fb
CD
1731
1732 bfd_put_32 (abfd, ((irel->r_offset + datasec->output_offset) +
1733 ((ELF32_R_TYPE (irel->r_info) == (int) R_MIPS_64) ? 1 : 0)),
1734 p);
1735 memset (p + 4, 0, 8);
1736 if (targetsec != NULL)
1737 strncpy (p + 4, targetsec->output_section->name, 8);
1738 }
1739
6cdc0ccc
AM
1740 if (internal_relocs != NULL
1741 && elf_section_data (datasec)->relocs != internal_relocs)
1742 free (internal_relocs);
1743 if (isymbuf != NULL
1744 && symtab_hdr->contents != (unsigned char *) isymbuf)
1745 free (isymbuf);
b34976b6 1746 return TRUE;
030d18fb
CD
1747
1748 error_return:
6cdc0ccc
AM
1749 if (internal_relocs != NULL
1750 && elf_section_data (datasec)->relocs != internal_relocs)
1751 free (internal_relocs);
1752 if (isymbuf != NULL
1753 && symtab_hdr->contents != (unsigned char *) isymbuf)
1754 free (isymbuf);
b34976b6 1755 return FALSE;
030d18fb
CD
1756}
1757\f
252b5132
RH
1758/* ECOFF swapping routines. These are used when dealing with the
1759 .mdebug section, which is in the ECOFF debugging format. */
be3ccd9c 1760static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
252b5132
RH
1761 /* Symbol table magic number. */
1762 magicSym,
1763 /* Alignment of debugging information. E.g., 4. */
1764 4,
1765 /* Sizes of external symbolic information. */
1766 sizeof (struct hdr_ext),
1767 sizeof (struct dnr_ext),
1768 sizeof (struct pdr_ext),
1769 sizeof (struct sym_ext),
1770 sizeof (struct opt_ext),
1771 sizeof (struct fdr_ext),
1772 sizeof (struct rfd_ext),
1773 sizeof (struct ext_ext),
1774 /* Functions to swap in external symbolic data. */
1775 ecoff_swap_hdr_in,
1776 ecoff_swap_dnr_in,
1777 ecoff_swap_pdr_in,
1778 ecoff_swap_sym_in,
1779 ecoff_swap_opt_in,
1780 ecoff_swap_fdr_in,
1781 ecoff_swap_rfd_in,
1782 ecoff_swap_ext_in,
1783 _bfd_ecoff_swap_tir_in,
1784 _bfd_ecoff_swap_rndx_in,
1785 /* Functions to swap out external symbolic data. */
1786 ecoff_swap_hdr_out,
1787 ecoff_swap_dnr_out,
1788 ecoff_swap_pdr_out,
1789 ecoff_swap_sym_out,
1790 ecoff_swap_opt_out,
1791 ecoff_swap_fdr_out,
1792 ecoff_swap_rfd_out,
1793 ecoff_swap_ext_out,
1794 _bfd_ecoff_swap_tir_out,
1795 _bfd_ecoff_swap_rndx_out,
1796 /* Function to read in symbolic data. */
1797 _bfd_mips_elf_read_ecoff_info
1798};
1799\f
252b5132
RH
1800#define ELF_ARCH bfd_arch_mips
1801#define ELF_MACHINE_CODE EM_MIPS
1802
1803/* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
1804 a value of 0x1000, and we are compatible. */
1805#define ELF_MAXPAGESIZE 0x1000
1806
b34976b6
AM
1807#define elf_backend_collect TRUE
1808#define elf_backend_type_change_ok TRUE
1809#define elf_backend_can_gc_sections TRUE
3f830999 1810#define elf_info_to_howto mips_info_to_howto_rela
252b5132
RH
1811#define elf_info_to_howto_rel mips_info_to_howto_rel
1812#define elf_backend_sym_is_global mips_elf_sym_is_global
c6e90b02 1813#define elf_backend_object_p mips_elf32_object_p
d75bc93d
TS
1814#define elf_backend_symbol_processing _bfd_mips_elf_symbol_processing
1815#define elf_backend_section_processing _bfd_mips_elf_section_processing
103186c6 1816#define elf_backend_section_from_shdr _bfd_mips_elf_section_from_shdr
252b5132
RH
1817#define elf_backend_fake_sections _bfd_mips_elf_fake_sections
1818#define elf_backend_section_from_bfd_section \
1819 _bfd_mips_elf_section_from_bfd_section
103186c6 1820#define elf_backend_add_symbol_hook _bfd_mips_elf_add_symbol_hook
d75bc93d
TS
1821#define elf_backend_link_output_symbol_hook \
1822 _bfd_mips_elf_link_output_symbol_hook
103186c6
MM
1823#define elf_backend_create_dynamic_sections \
1824 _bfd_mips_elf_create_dynamic_sections
1825#define elf_backend_check_relocs _bfd_mips_elf_check_relocs
1826#define elf_backend_adjust_dynamic_symbol \
1827 _bfd_mips_elf_adjust_dynamic_symbol
1828#define elf_backend_always_size_sections \
1829 _bfd_mips_elf_always_size_sections
1830#define elf_backend_size_dynamic_sections \
1831 _bfd_mips_elf_size_dynamic_sections
1832#define elf_backend_relocate_section _bfd_mips_elf_relocate_section
103186c6
MM
1833#define elf_backend_finish_dynamic_symbol \
1834 _bfd_mips_elf_finish_dynamic_symbol
1835#define elf_backend_finish_dynamic_sections \
1836 _bfd_mips_elf_finish_dynamic_sections
d75bc93d
TS
1837#define elf_backend_final_write_processing \
1838 _bfd_mips_elf_final_write_processing
1839#define elf_backend_additional_program_headers \
1840 _bfd_mips_elf_additional_program_headers
1841#define elf_backend_modify_segment_map _bfd_mips_elf_modify_segment_map
103186c6
MM
1842#define elf_backend_gc_mark_hook _bfd_mips_elf_gc_mark_hook
1843#define elf_backend_gc_sweep_hook _bfd_mips_elf_gc_sweep_hook
8a20f077
UC
1844#define elf_backend_copy_indirect_symbol \
1845 _bfd_mips_elf_copy_indirect_symbol
b305ef96 1846#define elf_backend_hide_symbol _bfd_mips_elf_hide_symbol
c6e90b02
TS
1847#define elf_backend_grok_prstatus elf32_mips_grok_prstatus
1848#define elf_backend_grok_psinfo elf32_mips_grok_psinfo
d75bc93d
TS
1849#define elf_backend_ecoff_debug_swap &mips_elf32_ecoff_debug_swap
1850
1851#define elf_backend_got_header_size (4 * MIPS_RESERVED_GOTNO)
d75bc93d
TS
1852#define elf_backend_may_use_rel_p 1
1853#define elf_backend_may_use_rela_p 0
1854#define elf_backend_default_use_rela_p 0
b34976b6 1855#define elf_backend_sign_extend_vma TRUE
b305ef96 1856
d01414a5 1857#define elf_backend_discard_info _bfd_mips_elf_discard_info
73d074b4 1858#define elf_backend_ignore_discarded_relocs \
53bfd6b4 1859 _bfd_mips_elf_ignore_discarded_relocs
c6e90b02
TS
1860#define elf_backend_mips_irix_compat elf32_mips_irix_compat
1861#define elf_backend_mips_rtype_to_howto mips_elf32_rtype_to_howto
252b5132
RH
1862#define bfd_elf32_bfd_is_local_label_name \
1863 mips_elf_is_local_label_name
1864#define bfd_elf32_find_nearest_line _bfd_mips_elf_find_nearest_line
f0abc2a1 1865#define bfd_elf32_new_section_hook _bfd_mips_elf_new_section_hook
252b5132 1866#define bfd_elf32_set_section_contents _bfd_mips_elf_set_section_contents
c6e90b02
TS
1867#define bfd_elf32_bfd_get_relocated_section_contents \
1868 _bfd_elf_mips_get_relocated_section_contents
252b5132 1869#define bfd_elf32_bfd_link_hash_table_create \
103186c6
MM
1870 _bfd_mips_elf_link_hash_table_create
1871#define bfd_elf32_bfd_final_link _bfd_mips_elf_final_link
252b5132
RH
1872#define bfd_elf32_bfd_merge_private_bfd_data \
1873 _bfd_mips_elf_merge_private_bfd_data
1874#define bfd_elf32_bfd_set_private_flags _bfd_mips_elf_set_private_flags
1875#define bfd_elf32_bfd_print_private_bfd_data \
1876 _bfd_mips_elf_print_private_bfd_data
e364195d 1877
d75bc93d
TS
1878/* Support for SGI-ish mips targets. */
1879#define TARGET_LITTLE_SYM bfd_elf32_littlemips_vec
1880#define TARGET_LITTLE_NAME "elf32-littlemips"
1881#define TARGET_BIG_SYM bfd_elf32_bigmips_vec
1882#define TARGET_BIG_NAME "elf32-bigmips"
1883
1884#include "elf32-target.h"
e364195d 1885
d75bc93d
TS
1886/* Support for traditional mips targets. */
1887#define INCLUDED_TARGET_FILE /* More a type of flag. */
e364195d
UC
1888
1889#undef TARGET_LITTLE_SYM
1890#undef TARGET_LITTLE_NAME
1891#undef TARGET_BIG_SYM
1892#undef TARGET_BIG_NAME
1893
1894#define TARGET_LITTLE_SYM bfd_elf32_tradlittlemips_vec
1895#define TARGET_LITTLE_NAME "elf32-tradlittlemips"
1896#define TARGET_BIG_SYM bfd_elf32_tradbigmips_vec
1897#define TARGET_BIG_NAME "elf32-tradbigmips"
1898
c6e90b02 1899/* Include the target file again for this target. */
e364195d 1900#include "elf32-target.h"
This page took 0.436896 seconds and 4 git commands to generate.