1179404Sobrien/* MIPS-specific support for 32-bit ELF
2179404Sobrien   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3218822Sdim   2003, 2004, 2005, 2007 Free Software Foundation, Inc.
4179404Sobrien
5179404Sobrien   Most of the information added by Ian Lance Taylor, Cygnus Support,
6179404Sobrien   <ian@cygnus.com>.
7179404Sobrien   N32/64 ABI support added by Mark Mitchell, CodeSourcery, LLC.
8179404Sobrien   <mark@codesourcery.com>
9179404Sobrien   Traditional MIPS targets support added by Koundinya.K, Dansk Data
10179404Sobrien   Elektronik & Operations Research Group. <kk@ddeorg.soft.net>
11179404Sobrien
12179404SobrienThis file is part of BFD, the Binary File Descriptor library.
13179404Sobrien
14179404SobrienThis program is free software; you can redistribute it and/or modify
15179404Sobrienit under the terms of the GNU General Public License as published by
16179404Sobrienthe Free Software Foundation; either version 2 of the License, or
17179404Sobrien(at your option) any later version.
18179404Sobrien
19179404SobrienThis program is distributed in the hope that it will be useful,
20179404Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
21179404SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22179404SobrienGNU General Public License for more details.
23179404Sobrien
24179404SobrienYou should have received a copy of the GNU General Public License
25179404Sobrienalong with this program; if not, write to the Free Software
26218822SdimFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
27179404Sobrien
28179404Sobrien/* This file handles MIPS ELF targets.  SGI Irix 5 uses a slightly
29179404Sobrien   different MIPS ELF from other targets.  This matters when linking.
30179404Sobrien   This file supports both, switching at runtime.  */
31179404Sobrien
32218822Sdim#include "sysdep.h"
33179404Sobrien#include "bfd.h"
34179404Sobrien#include "libbfd.h"
35179404Sobrien#include "bfdlink.h"
36179404Sobrien#include "genlink.h"
37179404Sobrien#include "elf-bfd.h"
38179404Sobrien#include "elfxx-mips.h"
39179404Sobrien#include "elf/mips.h"
40179404Sobrien
41179404Sobrien/* Get the ECOFF swapping routines.  */
42179404Sobrien#include "coff/sym.h"
43179404Sobrien#include "coff/symconst.h"
44179404Sobrien#include "coff/internal.h"
45179404Sobrien#include "coff/ecoff.h"
46179404Sobrien#include "coff/mips.h"
47179404Sobrien#define ECOFF_SIGNED_32
48179404Sobrien#include "ecoffswap.h"
49179404Sobrien
50179404Sobrienstatic bfd_boolean mips_elf_assign_gp
51179404Sobrien  (bfd *, bfd_vma *);
52179404Sobrienstatic bfd_reloc_status_type mips_elf_final_gp
53179404Sobrien  (bfd *, asymbol *, bfd_boolean, char **, bfd_vma *);
54179404Sobrienstatic bfd_reloc_status_type mips_elf_gprel16_reloc
55179404Sobrien  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
56179404Sobrienstatic bfd_reloc_status_type mips_elf_literal_reloc
57179404Sobrien  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
58179404Sobrienstatic bfd_reloc_status_type mips_elf_gprel32_reloc
59179404Sobrien  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
60179404Sobrienstatic bfd_reloc_status_type gprel32_with_gp
61179404Sobrien  (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma);
62179404Sobrienstatic bfd_reloc_status_type mips_elf_shift6_reloc
63179404Sobrien  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
64179404Sobrienstatic bfd_reloc_status_type mips16_gprel_reloc
65179404Sobrien  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
66179404Sobrienstatic reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
67179404Sobrien  (bfd *, bfd_reloc_code_real_type);
68179404Sobrienstatic reloc_howto_type *mips_elf_n32_rtype_to_howto
69179404Sobrien  (unsigned int, bfd_boolean);
70179404Sobrienstatic void mips_info_to_howto_rel
71179404Sobrien  (bfd *, arelent *, Elf_Internal_Rela *);
72179404Sobrienstatic void mips_info_to_howto_rela
73179404Sobrien  (bfd *, arelent *, Elf_Internal_Rela *);
74179404Sobrienstatic bfd_boolean mips_elf_sym_is_global
75179404Sobrien  (bfd *, asymbol *);
76179404Sobrienstatic bfd_boolean mips_elf_n32_object_p
77179404Sobrien  (bfd *);
78179404Sobrienstatic bfd_boolean elf32_mips_grok_prstatus
79179404Sobrien  (bfd *, Elf_Internal_Note *);
80179404Sobrienstatic bfd_boolean elf32_mips_grok_psinfo
81179404Sobrien  (bfd *, Elf_Internal_Note *);
82179404Sobrienstatic irix_compat_t elf_n32_mips_irix_compat
83179404Sobrien  (bfd *);
84179404Sobrien
85179404Sobrienextern const bfd_target bfd_elf32_nbigmips_vec;
86179404Sobrienextern const bfd_target bfd_elf32_nlittlemips_vec;
87179404Sobrien
88179404Sobrien/* Nonzero if ABFD is using the N32 ABI.  */
89179404Sobrien#define ABI_N32_P(abfd) \
90179404Sobrien  ((elf_elfheader (abfd)->e_flags & EF_MIPS_ABI2) != 0)
91179404Sobrien
92179404Sobrien/* Whether we are trying to be compatible with IRIX at all.  */
93179404Sobrien#define SGI_COMPAT(abfd) \
94179404Sobrien  (elf_n32_mips_irix_compat (abfd) != ict_none)
95179404Sobrien
96179404Sobrien/* The number of local .got entries we reserve.  */
97179404Sobrien#define MIPS_RESERVED_GOTNO (2)
98179404Sobrien
99179404Sobrien/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
100179404Sobrien   from smaller values.  Start with zero, widen, *then* decrement.  */
101179404Sobrien#define MINUS_ONE	(((bfd_vma)0) - 1)
102179404Sobrien
103179404Sobrien/* The relocation table used for SHT_REL sections.  */
104179404Sobrien
105179404Sobrienstatic reloc_howto_type elf_mips_howto_table_rel[] =
106179404Sobrien{
107179404Sobrien  /* No relocation.  */
108179404Sobrien  HOWTO (R_MIPS_NONE,		/* type */
109179404Sobrien	 0,			/* rightshift */
110179404Sobrien	 0,			/* size (0 = byte, 1 = short, 2 = long) */
111179404Sobrien	 0,			/* bitsize */
112179404Sobrien	 FALSE,			/* pc_relative */
113179404Sobrien	 0,			/* bitpos */
114179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
115179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
116179404Sobrien	 "R_MIPS_NONE",		/* name */
117179404Sobrien	 FALSE,			/* partial_inplace */
118179404Sobrien	 0,			/* src_mask */
119179404Sobrien	 0,			/* dst_mask */
120179404Sobrien	 FALSE),		/* pcrel_offset */
121179404Sobrien
122179404Sobrien  /* 16 bit relocation.  */
123179404Sobrien  HOWTO (R_MIPS_16,		/* type */
124179404Sobrien	 0,			/* rightshift */
125179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
126179404Sobrien	 16,			/* bitsize */
127179404Sobrien	 FALSE,			/* pc_relative */
128179404Sobrien	 0,			/* bitpos */
129179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
130179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
131179404Sobrien	 "R_MIPS_16",		/* name */
132179404Sobrien	 TRUE,			/* partial_inplace */
133179404Sobrien	 0x0000ffff,		/* src_mask */
134179404Sobrien	 0x0000ffff,		/* dst_mask */
135179404Sobrien	 FALSE),		/* pcrel_offset */
136179404Sobrien
137179404Sobrien  /* 32 bit relocation.  */
138179404Sobrien  HOWTO (R_MIPS_32,		/* type */
139179404Sobrien	 0,			/* rightshift */
140179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
141179404Sobrien	 32,			/* bitsize */
142179404Sobrien	 FALSE,			/* pc_relative */
143179404Sobrien	 0,			/* bitpos */
144179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
145179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
146179404Sobrien	 "R_MIPS_32",		/* name */
147179404Sobrien	 TRUE,			/* partial_inplace */
148179404Sobrien	 0xffffffff,		/* src_mask */
149179404Sobrien	 0xffffffff,		/* dst_mask */
150179404Sobrien	 FALSE),		/* pcrel_offset */
151179404Sobrien
152179404Sobrien  /* 32 bit symbol relative relocation.  */
153179404Sobrien  HOWTO (R_MIPS_REL32,		/* type */
154179404Sobrien	 0,			/* rightshift */
155179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
156179404Sobrien	 32,			/* bitsize */
157179404Sobrien	 FALSE,			/* pc_relative */
158179404Sobrien	 0,			/* bitpos */
159179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
160179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
161179404Sobrien	 "R_MIPS_REL32",	/* name */
162179404Sobrien	 TRUE,			/* partial_inplace */
163179404Sobrien	 0xffffffff,		/* src_mask */
164179404Sobrien	 0xffffffff,		/* dst_mask */
165179404Sobrien	 FALSE),		/* pcrel_offset */
166179404Sobrien
167179404Sobrien  /* 26 bit jump address.  */
168179404Sobrien  HOWTO (R_MIPS_26,		/* type */
169179404Sobrien	 2,			/* rightshift */
170179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
171179404Sobrien	 26,			/* bitsize */
172179404Sobrien	 FALSE,			/* pc_relative */
173179404Sobrien	 0,			/* bitpos */
174179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
175179404Sobrien	 			/* This needs complex overflow
176179404Sobrien				   detection, because the upper four
177179404Sobrien				   bits must match the PC + 4.  */
178179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
179179404Sobrien	 "R_MIPS_26",		/* name */
180179404Sobrien	 TRUE,			/* partial_inplace */
181179404Sobrien	 0x03ffffff,		/* src_mask */
182179404Sobrien	 0x03ffffff,		/* dst_mask */
183179404Sobrien	 FALSE),		/* pcrel_offset */
184179404Sobrien
185179404Sobrien  /* R_MIPS_HI16 and R_MIPS_LO16 are unsupported for NewABI REL.
186179404Sobrien     However, the native IRIX6 tools use them, so we try our best. */
187179404Sobrien
188179404Sobrien  /* High 16 bits of symbol value.  */
189179404Sobrien  HOWTO (R_MIPS_HI16,		/* type */
190179404Sobrien	 16,			/* rightshift */
191179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
192179404Sobrien	 16,			/* bitsize */
193179404Sobrien	 FALSE,			/* pc_relative */
194179404Sobrien	 0,			/* bitpos */
195179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
196179404Sobrien	 _bfd_mips_elf_hi16_reloc, /* special_function */
197179404Sobrien	 "R_MIPS_HI16",		/* name */
198179404Sobrien	 TRUE,			/* partial_inplace */
199179404Sobrien	 0x0000ffff,		/* src_mask */
200179404Sobrien	 0x0000ffff,		/* dst_mask */
201179404Sobrien	 FALSE),		/* pcrel_offset */
202179404Sobrien
203179404Sobrien  /* Low 16 bits of symbol value.  */
204179404Sobrien  HOWTO (R_MIPS_LO16,		/* type */
205179404Sobrien	 0,			/* rightshift */
206179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
207179404Sobrien	 16,			/* bitsize */
208179404Sobrien	 FALSE,			/* pc_relative */
209179404Sobrien	 0,			/* bitpos */
210179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
211179404Sobrien	 _bfd_mips_elf_lo16_reloc, /* special_function */
212179404Sobrien	 "R_MIPS_LO16",		/* name */
213179404Sobrien	 TRUE,			/* partial_inplace */
214179404Sobrien	 0x0000ffff,		/* src_mask */
215179404Sobrien	 0x0000ffff,		/* dst_mask */
216179404Sobrien	 FALSE),		/* pcrel_offset */
217179404Sobrien
218179404Sobrien  /* GP relative reference.  */
219179404Sobrien  HOWTO (R_MIPS_GPREL16,	/* type */
220179404Sobrien	 0,			/* rightshift */
221179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
222179404Sobrien	 16,			/* bitsize */
223179404Sobrien	 FALSE,			/* pc_relative */
224179404Sobrien	 0,			/* bitpos */
225179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
226179404Sobrien	 mips_elf_gprel16_reloc, /* special_function */
227179404Sobrien	 "R_MIPS_GPREL16",	/* name */
228179404Sobrien	 TRUE,			/* partial_inplace */
229179404Sobrien	 0x0000ffff,		/* src_mask */
230179404Sobrien	 0x0000ffff,		/* dst_mask */
231179404Sobrien	 FALSE),		/* pcrel_offset */
232179404Sobrien
233179404Sobrien  /* Reference to literal section.  */
234179404Sobrien  HOWTO (R_MIPS_LITERAL,	/* type */
235179404Sobrien	 0,			/* rightshift */
236179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
237179404Sobrien	 16,			/* bitsize */
238179404Sobrien	 FALSE,			/* pc_relative */
239179404Sobrien	 0,			/* bitpos */
240179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
241179404Sobrien	 mips_elf_literal_reloc, /* special_function */
242179404Sobrien	 "R_MIPS_LITERAL",	/* name */
243179404Sobrien	 TRUE,			/* partial_inplace */
244179404Sobrien	 0x0000ffff,		/* src_mask */
245179404Sobrien	 0x0000ffff,		/* dst_mask */
246179404Sobrien	 FALSE),		/* pcrel_offset */
247179404Sobrien
248179404Sobrien  /* Reference to global offset table.  */
249179404Sobrien  HOWTO (R_MIPS_GOT16,		/* type */
250179404Sobrien	 0,			/* rightshift */
251179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
252179404Sobrien	 16,			/* bitsize */
253179404Sobrien	 FALSE,			/* pc_relative */
254179404Sobrien	 0,			/* bitpos */
255179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
256179404Sobrien	 _bfd_mips_elf_got16_reloc, /* special_function */
257179404Sobrien	 "R_MIPS_GOT16",	/* name */
258179404Sobrien	 TRUE,			/* partial_inplace */
259179404Sobrien	 0x0000ffff,		/* src_mask */
260179404Sobrien	 0x0000ffff,		/* dst_mask */
261179404Sobrien	 FALSE),		/* pcrel_offset */
262179404Sobrien
263218822Sdim  /* 16 bit PC relative reference.  Note that the ABI document has a typo
264218822Sdim     and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
265218822Sdim     We do the right thing here.  */
266179404Sobrien  HOWTO (R_MIPS_PC16,		/* type */
267218822Sdim	 2,			/* rightshift */
268179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
269179404Sobrien	 16,			/* bitsize */
270179404Sobrien	 TRUE,			/* pc_relative */
271179404Sobrien	 0,			/* bitpos */
272179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
273179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
274179404Sobrien	 "R_MIPS_PC16",		/* name */
275179404Sobrien	 TRUE,			/* partial_inplace */
276179404Sobrien	 0x0000ffff,		/* src_mask */
277179404Sobrien	 0x0000ffff,		/* dst_mask */
278179404Sobrien	 TRUE),			/* pcrel_offset */
279179404Sobrien
280179404Sobrien  /* 16 bit call through global offset table.  */
281179404Sobrien  HOWTO (R_MIPS_CALL16,		/* type */
282179404Sobrien	 0,			/* rightshift */
283179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
284179404Sobrien	 16,			/* bitsize */
285179404Sobrien	 FALSE,			/* pc_relative */
286179404Sobrien	 0,			/* bitpos */
287179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
288179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
289179404Sobrien	 "R_MIPS_CALL16",	/* name */
290179404Sobrien	 TRUE,			/* partial_inplace */
291179404Sobrien	 0x0000ffff,		/* src_mask */
292179404Sobrien	 0x0000ffff,		/* dst_mask */
293179404Sobrien	 FALSE),		/* pcrel_offset */
294179404Sobrien
295179404Sobrien  /* 32 bit GP relative reference.  */
296179404Sobrien  HOWTO (R_MIPS_GPREL32,	/* type */
297179404Sobrien	 0,			/* rightshift */
298179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
299179404Sobrien	 32,			/* bitsize */
300179404Sobrien	 FALSE,			/* pc_relative */
301179404Sobrien	 0,			/* bitpos */
302179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
303179404Sobrien	 mips_elf_gprel32_reloc, /* special_function */
304179404Sobrien	 "R_MIPS_GPREL32",	/* name */
305179404Sobrien	 TRUE,			/* partial_inplace */
306179404Sobrien	 0xffffffff,		/* src_mask */
307179404Sobrien	 0xffffffff,		/* dst_mask */
308179404Sobrien	 FALSE),		/* pcrel_offset */
309179404Sobrien
310179404Sobrien  /* The remaining relocs are defined on Irix 5, although they are
311179404Sobrien     not defined by the ABI.  */
312179404Sobrien  EMPTY_HOWTO (13),
313179404Sobrien  EMPTY_HOWTO (14),
314179404Sobrien  EMPTY_HOWTO (15),
315179404Sobrien
316179404Sobrien  /* A 5 bit shift field.  */
317179404Sobrien  HOWTO (R_MIPS_SHIFT5,		/* type */
318179404Sobrien	 0,			/* rightshift */
319179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
320179404Sobrien	 5,			/* bitsize */
321179404Sobrien	 FALSE,			/* pc_relative */
322179404Sobrien	 6,			/* bitpos */
323179404Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
324179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
325179404Sobrien	 "R_MIPS_SHIFT5",	/* name */
326179404Sobrien	 TRUE,			/* partial_inplace */
327179404Sobrien	 0x000007c0,		/* src_mask */
328179404Sobrien	 0x000007c0,		/* dst_mask */
329179404Sobrien	 FALSE),		/* pcrel_offset */
330179404Sobrien
331179404Sobrien  /* A 6 bit shift field.  */
332179404Sobrien  HOWTO (R_MIPS_SHIFT6,		/* type */
333179404Sobrien	 0,			/* rightshift */
334179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
335179404Sobrien	 6,			/* bitsize */
336179404Sobrien	 FALSE,			/* pc_relative */
337179404Sobrien	 6,			/* bitpos */
338179404Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
339179404Sobrien	 mips_elf_shift6_reloc,	/* special_function */
340179404Sobrien	 "R_MIPS_SHIFT6",	/* name */
341179404Sobrien	 TRUE,			/* partial_inplace */
342179404Sobrien	 0x000007c4,		/* src_mask */
343179404Sobrien	 0x000007c4,		/* dst_mask */
344179404Sobrien	 FALSE),		/* pcrel_offset */
345179404Sobrien
346179404Sobrien  /* A 64 bit relocation.  */
347179404Sobrien  HOWTO (R_MIPS_64,		/* type */
348179404Sobrien	 0,			/* rightshift */
349179404Sobrien	 4,			/* size (0 = byte, 1 = short, 2 = long) */
350179404Sobrien	 64,			/* bitsize */
351179404Sobrien	 FALSE,			/* pc_relative */
352179404Sobrien	 0,			/* bitpos */
353179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
354179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
355179404Sobrien	 "R_MIPS_64",		/* name */
356179404Sobrien	 TRUE,			/* partial_inplace */
357179404Sobrien	 MINUS_ONE,		/* src_mask */
358179404Sobrien	 MINUS_ONE,		/* dst_mask */
359179404Sobrien	 FALSE),		/* pcrel_offset */
360179404Sobrien
361179404Sobrien  /* Displacement in the global offset table.  */
362179404Sobrien  HOWTO (R_MIPS_GOT_DISP,	/* type */
363179404Sobrien	 0,			/* rightshift */
364179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
365179404Sobrien	 16,			/* bitsize */
366179404Sobrien	 FALSE,			/* pc_relative */
367179404Sobrien	 0,			/* bitpos */
368179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
369179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
370179404Sobrien	 "R_MIPS_GOT_DISP",	/* name */
371179404Sobrien	 TRUE,			/* partial_inplace */
372179404Sobrien	 0x0000ffff,		/* src_mask */
373179404Sobrien	 0x0000ffff,		/* dst_mask */
374179404Sobrien	 FALSE),		/* pcrel_offset */
375179404Sobrien
376179404Sobrien  /* Displacement to page pointer in the global offset table.  */
377179404Sobrien  HOWTO (R_MIPS_GOT_PAGE,	/* type */
378179404Sobrien	 0,			/* rightshift */
379179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
380179404Sobrien	 16,			/* bitsize */
381179404Sobrien	 FALSE,			/* pc_relative */
382179404Sobrien	 0,			/* bitpos */
383179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
384179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
385179404Sobrien	 "R_MIPS_GOT_PAGE",	/* name */
386179404Sobrien	 TRUE,			/* partial_inplace */
387179404Sobrien	 0x0000ffff,		/* src_mask */
388179404Sobrien	 0x0000ffff,		/* dst_mask */
389179404Sobrien	 FALSE),		/* pcrel_offset */
390179404Sobrien
391179404Sobrien  /* Offset from page pointer in the global offset table.  */
392179404Sobrien  HOWTO (R_MIPS_GOT_OFST,	/* type */
393179404Sobrien	 0,			/* rightshift */
394179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
395179404Sobrien	 16,			/* bitsize */
396179404Sobrien	 FALSE,			/* pc_relative */
397179404Sobrien	 0,			/* bitpos */
398179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
399179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
400179404Sobrien	 "R_MIPS_GOT_OFST",	/* name */
401179404Sobrien	 TRUE,			/* partial_inplace */
402179404Sobrien	 0x0000ffff,		/* src_mask */
403179404Sobrien	 0x0000ffff,		/* dst_mask */
404179404Sobrien	 FALSE),		/* pcrel_offset */
405179404Sobrien
406179404Sobrien  /* High 16 bits of displacement in global offset table.  */
407179404Sobrien  HOWTO (R_MIPS_GOT_HI16,	/* type */
408179404Sobrien	 0,			/* rightshift */
409179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
410179404Sobrien	 16,			/* bitsize */
411179404Sobrien	 FALSE,			/* pc_relative */
412179404Sobrien	 0,			/* bitpos */
413179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
414179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
415179404Sobrien	 "R_MIPS_GOT_HI16",	/* name */
416179404Sobrien	 TRUE,			/* partial_inplace */
417179404Sobrien	 0x0000ffff,		/* src_mask */
418179404Sobrien	 0x0000ffff,		/* dst_mask */
419179404Sobrien	 FALSE),		/* pcrel_offset */
420179404Sobrien
421179404Sobrien  /* Low 16 bits of displacement in global offset table.  */
422179404Sobrien  HOWTO (R_MIPS_GOT_LO16,	/* type */
423179404Sobrien	 0,			/* rightshift */
424179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
425179404Sobrien	 16,			/* bitsize */
426179404Sobrien	 FALSE,			/* pc_relative */
427179404Sobrien	 0,			/* bitpos */
428179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
429179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
430179404Sobrien	 "R_MIPS_GOT_LO16",	/* name */
431179404Sobrien	 TRUE,			/* partial_inplace */
432179404Sobrien	 0x0000ffff,		/* src_mask */
433179404Sobrien	 0x0000ffff,		/* dst_mask */
434179404Sobrien	 FALSE),		/* pcrel_offset */
435179404Sobrien
436179404Sobrien  /* 64 bit subtraction.  */
437179404Sobrien  HOWTO (R_MIPS_SUB,		/* type */
438179404Sobrien	 0,			/* rightshift */
439179404Sobrien	 4,			/* size (0 = byte, 1 = short, 2 = long) */
440179404Sobrien	 64,			/* bitsize */
441179404Sobrien	 FALSE,			/* pc_relative */
442179404Sobrien	 0,			/* bitpos */
443179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
444179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
445179404Sobrien	 "R_MIPS_SUB",		/* name */
446179404Sobrien	 TRUE,			/* partial_inplace */
447179404Sobrien	 MINUS_ONE,		/* src_mask */
448179404Sobrien	 MINUS_ONE,		/* dst_mask */
449179404Sobrien	 FALSE),		/* pcrel_offset */
450179404Sobrien
451179404Sobrien  /* Insert the addend as an instruction.  */
452179404Sobrien  /* FIXME: Not handled correctly.  */
453179404Sobrien  HOWTO (R_MIPS_INSERT_A,	/* type */
454179404Sobrien	 0,			/* rightshift */
455179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
456179404Sobrien	 32,			/* bitsize */
457179404Sobrien	 FALSE,			/* pc_relative */
458179404Sobrien	 0,			/* bitpos */
459179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
460179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
461179404Sobrien	 "R_MIPS_INSERT_A",	/* name */
462179404Sobrien	 TRUE,			/* partial_inplace */
463179404Sobrien	 0xffffffff,		/* src_mask */
464179404Sobrien	 0xffffffff,		/* dst_mask */
465179404Sobrien	 FALSE),		/* pcrel_offset */
466179404Sobrien
467179404Sobrien  /* Insert the addend as an instruction, and change all relocations
468179404Sobrien     to refer to the old instruction at the address.  */
469179404Sobrien  /* FIXME: Not handled correctly.  */
470179404Sobrien  HOWTO (R_MIPS_INSERT_B,	/* type */
471179404Sobrien	 0,			/* rightshift */
472179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
473179404Sobrien	 32,			/* bitsize */
474179404Sobrien	 FALSE,			/* pc_relative */
475179404Sobrien	 0,			/* bitpos */
476179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
477179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
478179404Sobrien	 "R_MIPS_INSERT_B",	/* name */
479179404Sobrien	 TRUE,			/* partial_inplace */
480179404Sobrien	 0xffffffff,		/* src_mask */
481179404Sobrien	 0xffffffff,		/* dst_mask */
482179404Sobrien	 FALSE),		/* pcrel_offset */
483179404Sobrien
484179404Sobrien  /* Delete a 32 bit instruction.  */
485179404Sobrien  /* FIXME: Not handled correctly.  */
486179404Sobrien  HOWTO (R_MIPS_DELETE,		/* type */
487179404Sobrien	 0,			/* rightshift */
488179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
489179404Sobrien	 32,			/* bitsize */
490179404Sobrien	 FALSE,			/* pc_relative */
491179404Sobrien	 0,			/* bitpos */
492179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
493179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
494179404Sobrien	 "R_MIPS_DELETE",	/* name */
495179404Sobrien	 TRUE,			/* partial_inplace */
496179404Sobrien	 0xffffffff,		/* src_mask */
497179404Sobrien	 0xffffffff,		/* dst_mask */
498179404Sobrien	 FALSE),		/* pcrel_offset */
499179404Sobrien
500179404Sobrien  /* The MIPS ELF64 ABI Draft wants us to support these for REL relocations.
501179404Sobrien     We don't, because
502179404Sobrien       a) It means building the addend from a R_MIPS_HIGHEST/R_MIPS_HIGHER/
503179404Sobrien	  R_MIPS_HI16/R_MIPS_LO16 sequence with varying ordering, using
504179404Sobrien	  fallable heuristics.
505218822Sdim       b) No other NewABI toolchain actually emits such relocations.  */
506179404Sobrien  EMPTY_HOWTO (R_MIPS_HIGHER),
507179404Sobrien  EMPTY_HOWTO (R_MIPS_HIGHEST),
508179404Sobrien
509179404Sobrien  /* High 16 bits of displacement in global offset table.  */
510179404Sobrien  HOWTO (R_MIPS_CALL_HI16,	/* type */
511179404Sobrien	 0,			/* rightshift */
512179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
513179404Sobrien	 16,			/* bitsize */
514179404Sobrien	 FALSE,			/* pc_relative */
515179404Sobrien	 0,			/* bitpos */
516179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
517179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
518179404Sobrien	 "R_MIPS_CALL_HI16",	/* name */
519179404Sobrien	 TRUE,			/* partial_inplace */
520179404Sobrien	 0x0000ffff,		/* src_mask */
521179404Sobrien	 0x0000ffff,		/* dst_mask */
522179404Sobrien	 FALSE),		/* pcrel_offset */
523179404Sobrien
524179404Sobrien  /* Low 16 bits of displacement in global offset table.  */
525179404Sobrien  HOWTO (R_MIPS_CALL_LO16,	/* type */
526179404Sobrien	 0,			/* rightshift */
527179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
528179404Sobrien	 16,			/* bitsize */
529179404Sobrien	 FALSE,			/* pc_relative */
530179404Sobrien	 0,			/* bitpos */
531179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
532179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
533179404Sobrien	 "R_MIPS_CALL_LO16",	/* name */
534179404Sobrien	 TRUE,			/* partial_inplace */
535179404Sobrien	 0x0000ffff,		/* src_mask */
536179404Sobrien	 0x0000ffff,		/* dst_mask */
537179404Sobrien	 FALSE),		/* pcrel_offset */
538179404Sobrien
539179404Sobrien  /* Section displacement.  */
540179404Sobrien  HOWTO (R_MIPS_SCN_DISP,       /* type */
541179404Sobrien	 0,			/* rightshift */
542179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
543179404Sobrien	 32,			/* bitsize */
544179404Sobrien	 FALSE,			/* pc_relative */
545179404Sobrien	 0,			/* bitpos */
546179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
547179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
548179404Sobrien	 "R_MIPS_SCN_DISP",     /* name */
549179404Sobrien	 TRUE,			/* partial_inplace */
550179404Sobrien	 0xffffffff,		/* src_mask */
551179404Sobrien	 0xffffffff,		/* dst_mask */
552179404Sobrien	 FALSE),		/* pcrel_offset */
553179404Sobrien
554179404Sobrien  HOWTO (R_MIPS_REL16,		/* type */
555179404Sobrien	 0,			/* rightshift */
556179404Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
557179404Sobrien	 16,			/* bitsize */
558179404Sobrien	 FALSE,			/* pc_relative */
559179404Sobrien	 0,			/* bitpos */
560179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
561179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
562179404Sobrien	 "R_MIPS_REL16",	/* name */
563179404Sobrien	 TRUE,			/* partial_inplace */
564179404Sobrien	 0xffff,		/* src_mask */
565179404Sobrien	 0xffff,		/* dst_mask */
566179404Sobrien	 FALSE),		/* pcrel_offset */
567179404Sobrien
568179404Sobrien  /* These two are obsolete.  */
569179404Sobrien  EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
570179404Sobrien  EMPTY_HOWTO (R_MIPS_PJUMP),
571179404Sobrien
572179404Sobrien  /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
573179404Sobrien     It must be used for multigot GOT's (and only there).  */
574179404Sobrien  HOWTO (R_MIPS_RELGOT,		/* type */
575179404Sobrien	 0,			/* rightshift */
576179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
577179404Sobrien	 32,			/* bitsize */
578179404Sobrien	 FALSE,			/* pc_relative */
579179404Sobrien	 0,			/* bitpos */
580179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
581179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
582179404Sobrien	 "R_MIPS_RELGOT",	/* name */
583179404Sobrien	 TRUE,			/* partial_inplace */
584179404Sobrien	 0xffffffff,		/* src_mask */
585179404Sobrien	 0xffffffff,		/* dst_mask */
586179404Sobrien	 FALSE),		/* pcrel_offset */
587179404Sobrien
588179404Sobrien  /* Protected jump conversion.  This is an optimization hint.  No
589179404Sobrien     relocation is required for correctness.  */
590179404Sobrien  HOWTO (R_MIPS_JALR,	        /* type */
591179404Sobrien	 0,			/* rightshift */
592179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
593179404Sobrien	 32,			/* bitsize */
594179404Sobrien	 FALSE,			/* pc_relative */
595179404Sobrien	 0,			/* bitpos */
596179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
597179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
598179404Sobrien	 "R_MIPS_JALR",	        /* name */
599179404Sobrien	 FALSE,			/* partial_inplace */
600179404Sobrien	 0x00000000,		/* src_mask */
601179404Sobrien	 0x00000000,		/* dst_mask */
602179404Sobrien	 FALSE),		/* pcrel_offset */
603218822Sdim
604218822Sdim  /* TLS GD/LD dynamic relocations.  */
605218822Sdim  HOWTO (R_MIPS_TLS_DTPMOD32,	/* type */
606218822Sdim	 0,			/* rightshift */
607218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
608218822Sdim	 32,			/* bitsize */
609218822Sdim	 FALSE,			/* pc_relative */
610218822Sdim	 0,			/* bitpos */
611218822Sdim	 complain_overflow_dont, /* complain_on_overflow */
612218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
613218822Sdim	 "R_MIPS_TLS_DTPMOD32",	/* name */
614218822Sdim	 TRUE,			/* partial_inplace */
615218822Sdim	 0xffffffff,		/* src_mask */
616218822Sdim	 0xffffffff,		/* dst_mask */
617218822Sdim	 FALSE),		/* pcrel_offset */
618218822Sdim
619218822Sdim  HOWTO (R_MIPS_TLS_DTPREL32,	/* type */
620218822Sdim	 0,			/* rightshift */
621218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
622218822Sdim	 32,			/* bitsize */
623218822Sdim	 FALSE,			/* pc_relative */
624218822Sdim	 0,			/* bitpos */
625218822Sdim	 complain_overflow_dont, /* complain_on_overflow */
626218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
627218822Sdim	 "R_MIPS_TLS_DTPREL32",	/* name */
628218822Sdim	 TRUE,			/* partial_inplace */
629218822Sdim	 0xffffffff,		/* src_mask */
630218822Sdim	 0xffffffff,		/* dst_mask */
631218822Sdim	 FALSE),		/* pcrel_offset */
632218822Sdim
633218822Sdim  EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
634218822Sdim  EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
635218822Sdim
636218822Sdim  /* TLS general dynamic variable reference.  */
637218822Sdim  HOWTO (R_MIPS_TLS_GD,		/* type */
638218822Sdim	 0,			/* rightshift */
639218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
640218822Sdim	 16,			/* bitsize */
641218822Sdim	 FALSE,			/* pc_relative */
642218822Sdim	 0,			/* bitpos */
643218822Sdim	 complain_overflow_signed, /* complain_on_overflow */
644218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
645218822Sdim	 "R_MIPS_TLS_GD",	/* name */
646218822Sdim	 TRUE,			/* partial_inplace */
647218822Sdim	 0x0000ffff,		/* src_mask */
648218822Sdim	 0x0000ffff,		/* dst_mask */
649218822Sdim	 FALSE),		/* pcrel_offset */
650218822Sdim
651218822Sdim  /* TLS local dynamic variable reference.  */
652218822Sdim  HOWTO (R_MIPS_TLS_LDM,	/* type */
653218822Sdim	 0,			/* rightshift */
654218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
655218822Sdim	 16,			/* bitsize */
656218822Sdim	 FALSE,			/* pc_relative */
657218822Sdim	 0,			/* bitpos */
658218822Sdim	 complain_overflow_signed, /* complain_on_overflow */
659218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
660218822Sdim	 "R_MIPS_TLS_LDM",	/* name */
661218822Sdim	 TRUE,			/* partial_inplace */
662218822Sdim	 0x0000ffff,		/* src_mask */
663218822Sdim	 0x0000ffff,		/* dst_mask */
664218822Sdim	 FALSE),		/* pcrel_offset */
665218822Sdim
666218822Sdim  /* TLS local dynamic offset.  */
667218822Sdim  HOWTO (R_MIPS_TLS_DTPREL_HI16,	/* type */
668218822Sdim	 0,			/* rightshift */
669218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
670218822Sdim	 16,			/* bitsize */
671218822Sdim	 FALSE,			/* pc_relative */
672218822Sdim	 0,			/* bitpos */
673218822Sdim	 complain_overflow_signed, /* complain_on_overflow */
674218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
675218822Sdim	 "R_MIPS_TLS_DTPREL_HI16",	/* name */
676218822Sdim	 TRUE,			/* partial_inplace */
677218822Sdim	 0x0000ffff,		/* src_mask */
678218822Sdim	 0x0000ffff,		/* dst_mask */
679218822Sdim	 FALSE),		/* pcrel_offset */
680218822Sdim
681218822Sdim  /* TLS local dynamic offset.  */
682218822Sdim  HOWTO (R_MIPS_TLS_DTPREL_LO16,	/* type */
683218822Sdim	 0,			/* rightshift */
684218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
685218822Sdim	 16,			/* bitsize */
686218822Sdim	 FALSE,			/* pc_relative */
687218822Sdim	 0,			/* bitpos */
688218822Sdim	 complain_overflow_signed, /* complain_on_overflow */
689218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
690218822Sdim	 "R_MIPS_TLS_DTPREL_LO16",	/* name */
691218822Sdim	 TRUE,			/* partial_inplace */
692218822Sdim	 0x0000ffff,		/* src_mask */
693218822Sdim	 0x0000ffff,		/* dst_mask */
694218822Sdim	 FALSE),		/* pcrel_offset */
695218822Sdim
696218822Sdim  /* TLS thread pointer offset.  */
697218822Sdim  HOWTO (R_MIPS_TLS_GOTTPREL,	/* type */
698218822Sdim	 0,			/* rightshift */
699218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
700218822Sdim	 16,			/* bitsize */
701218822Sdim	 FALSE,			/* pc_relative */
702218822Sdim	 0,			/* bitpos */
703218822Sdim	 complain_overflow_signed, /* complain_on_overflow */
704218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
705218822Sdim	 "R_MIPS_TLS_GOTTPREL",	/* name */
706218822Sdim	 TRUE,			/* partial_inplace */
707218822Sdim	 0x0000ffff,		/* src_mask */
708218822Sdim	 0x0000ffff,		/* dst_mask */
709218822Sdim	 FALSE),		/* pcrel_offset */
710218822Sdim
711218822Sdim  /* TLS IE dynamic relocations.  */
712218822Sdim  HOWTO (R_MIPS_TLS_TPREL32,	/* type */
713218822Sdim	 0,			/* rightshift */
714218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
715218822Sdim	 32,			/* bitsize */
716218822Sdim	 FALSE,			/* pc_relative */
717218822Sdim	 0,			/* bitpos */
718218822Sdim	 complain_overflow_dont, /* complain_on_overflow */
719218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
720218822Sdim	 "R_MIPS_TLS_TPREL32",	/* name */
721218822Sdim	 TRUE,			/* partial_inplace */
722218822Sdim	 0xffffffff,		/* src_mask */
723218822Sdim	 0xffffffff,		/* dst_mask */
724218822Sdim	 FALSE),		/* pcrel_offset */
725218822Sdim
726218822Sdim  EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
727218822Sdim
728218822Sdim  /* TLS thread pointer offset.  */
729218822Sdim  HOWTO (R_MIPS_TLS_TPREL_HI16,	/* type */
730218822Sdim	 0,			/* rightshift */
731218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
732218822Sdim	 16,			/* bitsize */
733218822Sdim	 FALSE,			/* pc_relative */
734218822Sdim	 0,			/* bitpos */
735218822Sdim	 complain_overflow_signed, /* complain_on_overflow */
736218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
737218822Sdim	 "R_MIPS_TLS_TPREL_HI16", /* name */
738218822Sdim	 TRUE,			/* partial_inplace */
739218822Sdim	 0x0000ffff,		/* src_mask */
740218822Sdim	 0x0000ffff,		/* dst_mask */
741218822Sdim	 FALSE),		/* pcrel_offset */
742218822Sdim
743218822Sdim  /* TLS thread pointer offset.  */
744218822Sdim  HOWTO (R_MIPS_TLS_TPREL_LO16,	/* type */
745218822Sdim	 0,			/* rightshift */
746218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
747218822Sdim	 16,			/* bitsize */
748218822Sdim	 FALSE,			/* pc_relative */
749218822Sdim	 0,			/* bitpos */
750218822Sdim	 complain_overflow_signed, /* complain_on_overflow */
751218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
752218822Sdim	 "R_MIPS_TLS_TPREL_LO16", /* name */
753218822Sdim	 TRUE,			/* partial_inplace */
754218822Sdim	 0x0000ffff,		/* src_mask */
755218822Sdim	 0x0000ffff,		/* dst_mask */
756218822Sdim	 FALSE),		/* pcrel_offset */
757218822Sdim
758218822Sdim  /* 32 bit relocation with no addend.  */
759218822Sdim  HOWTO (R_MIPS_GLOB_DAT,	/* type */
760218822Sdim	 0,			/* rightshift */
761218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
762218822Sdim	 32,			/* bitsize */
763218822Sdim	 FALSE,			/* pc_relative */
764218822Sdim	 0,			/* bitpos */
765218822Sdim	 complain_overflow_dont, /* complain_on_overflow */
766218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
767218822Sdim	 "R_MIPS_GLOB_DAT",	/* name */
768218822Sdim	 FALSE,			/* partial_inplace */
769218822Sdim	 0x0,			/* src_mask */
770218822Sdim	 0xffffffff,		/* dst_mask */
771218822Sdim	 FALSE),		/* pcrel_offset */
772179404Sobrien};
773179404Sobrien
774179404Sobrien/* The relocation table used for SHT_RELA sections.  */
775179404Sobrien
776179404Sobrienstatic reloc_howto_type elf_mips_howto_table_rela[] =
777179404Sobrien{
778179404Sobrien  /* No relocation.  */
779179404Sobrien  HOWTO (R_MIPS_NONE,		/* type */
780179404Sobrien	 0,			/* rightshift */
781179404Sobrien	 0,			/* size (0 = byte, 1 = short, 2 = long) */
782179404Sobrien	 0,			/* bitsize */
783179404Sobrien	 FALSE,			/* pc_relative */
784179404Sobrien	 0,			/* bitpos */
785179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
786179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
787179404Sobrien	 "R_MIPS_NONE",		/* name */
788179404Sobrien	 FALSE,			/* partial_inplace */
789179404Sobrien	 0,			/* src_mask */
790179404Sobrien	 0,			/* dst_mask */
791179404Sobrien	 FALSE),		/* pcrel_offset */
792179404Sobrien
793179404Sobrien  /* 16 bit relocation.  */
794179404Sobrien  HOWTO (R_MIPS_16,		/* type */
795179404Sobrien	 0,			/* rightshift */
796179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
797179404Sobrien	 16,			/* bitsize */
798179404Sobrien	 FALSE,			/* pc_relative */
799179404Sobrien	 0,			/* bitpos */
800179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
801179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
802179404Sobrien	 "R_MIPS_16",		/* name */
803179404Sobrien	 FALSE,			/* partial_inplace */
804179404Sobrien	 0,			/* src_mask */
805179404Sobrien	 0x0000,		/* dst_mask */
806179404Sobrien	 FALSE),		/* pcrel_offset */
807179404Sobrien
808179404Sobrien  /* 32 bit relocation.  */
809179404Sobrien  HOWTO (R_MIPS_32,		/* type */
810179404Sobrien	 0,			/* rightshift */
811179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
812179404Sobrien	 32,			/* bitsize */
813179404Sobrien	 FALSE,			/* pc_relative */
814179404Sobrien	 0,			/* bitpos */
815179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
816179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
817179404Sobrien	 "R_MIPS_32",		/* name */
818179404Sobrien	 FALSE,			/* partial_inplace */
819179404Sobrien	 0,			/* src_mask */
820179404Sobrien	 0xffffffff,		/* dst_mask */
821179404Sobrien	 FALSE),		/* pcrel_offset */
822179404Sobrien
823179404Sobrien  /* 32 bit symbol relative relocation.  */
824179404Sobrien  HOWTO (R_MIPS_REL32,		/* type */
825179404Sobrien	 0,			/* rightshift */
826179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
827179404Sobrien	 32,			/* bitsize */
828179404Sobrien	 FALSE,			/* pc_relative */
829179404Sobrien	 0,			/* bitpos */
830179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
831179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
832179404Sobrien	 "R_MIPS_REL32",	/* name */
833179404Sobrien	 FALSE,			/* partial_inplace */
834179404Sobrien	 0,			/* src_mask */
835179404Sobrien	 0xffffffff,		/* dst_mask */
836179404Sobrien	 FALSE),		/* pcrel_offset */
837179404Sobrien
838179404Sobrien  /* 26 bit jump address.  */
839179404Sobrien  HOWTO (R_MIPS_26,		/* type */
840179404Sobrien	 2,			/* rightshift */
841179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
842179404Sobrien	 26,			/* bitsize */
843179404Sobrien	 FALSE,			/* pc_relative */
844179404Sobrien	 0,			/* bitpos */
845179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
846179404Sobrien				/* This needs complex overflow
847179404Sobrien				   detection, because the upper 36
848179404Sobrien				   bits must match the PC + 4.  */
849179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
850179404Sobrien	 "R_MIPS_26",		/* name */
851179404Sobrien	 FALSE,			/* partial_inplace */
852179404Sobrien	 0,			/* src_mask */
853179404Sobrien	 0x03ffffff,		/* dst_mask */
854179404Sobrien	 FALSE),		/* pcrel_offset */
855179404Sobrien
856179404Sobrien  /* High 16 bits of symbol value.  */
857179404Sobrien  HOWTO (R_MIPS_HI16,		/* type */
858179404Sobrien	 0,			/* rightshift */
859179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
860179404Sobrien	 16,			/* bitsize */
861179404Sobrien	 FALSE,			/* pc_relative */
862179404Sobrien	 0,			/* bitpos */
863179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
864179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
865179404Sobrien	 "R_MIPS_HI16",		/* name */
866179404Sobrien	 FALSE,			/* partial_inplace */
867179404Sobrien	 0,			/* src_mask */
868179404Sobrien	 0x0000ffff,		/* dst_mask */
869179404Sobrien	 FALSE),		/* pcrel_offset */
870179404Sobrien
871179404Sobrien  /* Low 16 bits of symbol value.  */
872179404Sobrien  HOWTO (R_MIPS_LO16,		/* type */
873179404Sobrien	 0,			/* rightshift */
874179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
875179404Sobrien	 16,			/* bitsize */
876179404Sobrien	 FALSE,			/* pc_relative */
877179404Sobrien	 0,			/* bitpos */
878179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
879179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
880179404Sobrien	 "R_MIPS_LO16",		/* name */
881179404Sobrien	 FALSE,			/* partial_inplace */
882179404Sobrien	 0,			/* src_mask */
883179404Sobrien	 0x0000ffff,		/* dst_mask */
884179404Sobrien	 FALSE),		/* pcrel_offset */
885179404Sobrien
886179404Sobrien  /* GP relative reference.  */
887179404Sobrien  HOWTO (R_MIPS_GPREL16,	/* type */
888179404Sobrien	 0,			/* rightshift */
889179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
890179404Sobrien	 16,			/* bitsize */
891179404Sobrien	 FALSE,			/* pc_relative */
892179404Sobrien	 0,			/* bitpos */
893179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
894179404Sobrien	 mips_elf_gprel16_reloc, /* special_function */
895179404Sobrien	 "R_MIPS_GPREL16",	/* name */
896179404Sobrien	 FALSE,			/* partial_inplace */
897179404Sobrien	 0,			/* src_mask */
898179404Sobrien	 0x0000ffff,		/* dst_mask */
899179404Sobrien	 FALSE),		/* pcrel_offset */
900179404Sobrien
901179404Sobrien  /* Reference to literal section.  */
902179404Sobrien  HOWTO (R_MIPS_LITERAL,	/* type */
903179404Sobrien	 0,			/* rightshift */
904179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
905179404Sobrien	 16,			/* bitsize */
906179404Sobrien	 FALSE,			/* pc_relative */
907179404Sobrien	 0,			/* bitpos */
908179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
909179404Sobrien	 mips_elf_literal_reloc, /* special_function */
910179404Sobrien	 "R_MIPS_LITERAL",	/* name */
911179404Sobrien	 FALSE,			/* partial_inplace */
912179404Sobrien	 0,			/* src_mask */
913179404Sobrien	 0x0000ffff,		/* dst_mask */
914179404Sobrien	 FALSE),		/* pcrel_offset */
915179404Sobrien
916179404Sobrien  /* Reference to global offset table.  */
917179404Sobrien  HOWTO (R_MIPS_GOT16,		/* type */
918179404Sobrien	 0,			/* rightshift */
919179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
920179404Sobrien	 16,			/* bitsize */
921179404Sobrien	 FALSE,			/* pc_relative */
922179404Sobrien	 0,			/* bitpos */
923179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
924179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
925179404Sobrien	 "R_MIPS_GOT16",	/* name */
926179404Sobrien	 FALSE,			/* partial_inplace */
927179404Sobrien	 0,			/* src_mask */
928179404Sobrien	 0x0000ffff,		/* dst_mask */
929179404Sobrien	 FALSE),		/* pcrel_offset */
930179404Sobrien
931218822Sdim  /* 16 bit PC relative reference.  Note that the ABI document has a typo
932218822Sdim     and claims R_MIPS_PC16 to be not rightshifted, rendering it useless.
933218822Sdim     We do the right thing here.  */
934179404Sobrien  HOWTO (R_MIPS_PC16,		/* type */
935218822Sdim	 2,			/* rightshift */
936179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
937179404Sobrien	 16,			/* bitsize */
938179404Sobrien	 TRUE,			/* pc_relative */
939179404Sobrien	 0,			/* bitpos */
940179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
941179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
942179404Sobrien	 "R_MIPS_PC16",		/* name */
943179404Sobrien	 FALSE,			/* partial_inplace */
944179404Sobrien	 0,			/* src_mask */
945179404Sobrien	 0x0000ffff,		/* dst_mask */
946179404Sobrien	 TRUE),			/* pcrel_offset */
947179404Sobrien
948179404Sobrien  /* 16 bit call through global offset table.  */
949179404Sobrien  HOWTO (R_MIPS_CALL16,		/* type */
950179404Sobrien	 0,			/* rightshift */
951179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
952179404Sobrien	 16,			/* bitsize */
953179404Sobrien	 FALSE,			/* pc_relative */
954179404Sobrien	 0,			/* bitpos */
955179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
956179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
957179404Sobrien	 "R_MIPS_CALL16",	/* name */
958179404Sobrien	 FALSE,			/* partial_inplace */
959179404Sobrien	 0,			/* src_mask */
960179404Sobrien	 0x0000ffff,		/* dst_mask */
961179404Sobrien	 FALSE),		/* pcrel_offset */
962179404Sobrien
963179404Sobrien  /* 32 bit GP relative reference.  */
964179404Sobrien  HOWTO (R_MIPS_GPREL32,	/* type */
965179404Sobrien	 0,			/* rightshift */
966179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
967179404Sobrien	 32,			/* bitsize */
968179404Sobrien	 FALSE,			/* pc_relative */
969179404Sobrien	 0,			/* bitpos */
970179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
971179404Sobrien	 mips_elf_gprel32_reloc, /* special_function */
972179404Sobrien	 "R_MIPS_GPREL32",	/* name */
973179404Sobrien	 FALSE,			/* partial_inplace */
974179404Sobrien	 0,			/* src_mask */
975179404Sobrien	 0xffffffff,		/* dst_mask */
976179404Sobrien	 FALSE),		/* pcrel_offset */
977179404Sobrien
978179404Sobrien  EMPTY_HOWTO (13),
979179404Sobrien  EMPTY_HOWTO (14),
980179404Sobrien  EMPTY_HOWTO (15),
981179404Sobrien
982179404Sobrien  /* A 5 bit shift field.  */
983179404Sobrien  HOWTO (R_MIPS_SHIFT5,		/* type */
984179404Sobrien	 0,			/* rightshift */
985179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
986179404Sobrien	 5,			/* bitsize */
987179404Sobrien	 FALSE,			/* pc_relative */
988179404Sobrien	 6,			/* bitpos */
989179404Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
990179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
991179404Sobrien	 "R_MIPS_SHIFT5",	/* name */
992179404Sobrien	 FALSE,			/* partial_inplace */
993179404Sobrien	 0,			/* src_mask */
994179404Sobrien	 0x000007c0,		/* dst_mask */
995179404Sobrien	 FALSE),		/* pcrel_offset */
996179404Sobrien
997179404Sobrien  /* A 6 bit shift field.  */
998179404Sobrien  HOWTO (R_MIPS_SHIFT6,		/* type */
999179404Sobrien	 0,			/* rightshift */
1000179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1001179404Sobrien	 6,			/* bitsize */
1002179404Sobrien	 FALSE,			/* pc_relative */
1003179404Sobrien	 6,			/* bitpos */
1004179404Sobrien	 complain_overflow_bitfield, /* complain_on_overflow */
1005179404Sobrien	 mips_elf_shift6_reloc,	/* special_function */
1006179404Sobrien	 "R_MIPS_SHIFT6",	/* name */
1007179404Sobrien	 FALSE,			/* partial_inplace */
1008179404Sobrien	 0,			/* src_mask */
1009179404Sobrien	 0x000007c4,		/* dst_mask */
1010179404Sobrien	 FALSE),		/* pcrel_offset */
1011179404Sobrien
1012179404Sobrien  /* 64 bit relocation.  */
1013179404Sobrien  HOWTO (R_MIPS_64,		/* type */
1014179404Sobrien	 0,			/* rightshift */
1015179404Sobrien	 4,			/* size (0 = byte, 1 = short, 2 = long) */
1016179404Sobrien	 64,			/* bitsize */
1017179404Sobrien	 FALSE,			/* pc_relative */
1018179404Sobrien	 0,			/* bitpos */
1019179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1020179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1021179404Sobrien	 "R_MIPS_64",		/* name */
1022179404Sobrien	 FALSE,			/* partial_inplace */
1023179404Sobrien	 0,			/* src_mask */
1024179404Sobrien	 MINUS_ONE,		/* dst_mask */
1025179404Sobrien	 FALSE),		/* pcrel_offset */
1026179404Sobrien
1027179404Sobrien  /* Displacement in the global offset table.  */
1028179404Sobrien  HOWTO (R_MIPS_GOT_DISP,	/* type */
1029179404Sobrien	 0,			/* rightshift */
1030179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1031179404Sobrien	 16,			/* bitsize */
1032179404Sobrien	 FALSE,			/* pc_relative */
1033179404Sobrien	 0,			/* bitpos */
1034179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
1035179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1036179404Sobrien	 "R_MIPS_GOT_DISP",	/* name */
1037179404Sobrien	 FALSE,			/* partial_inplace */
1038179404Sobrien	 0,			/* src_mask */
1039179404Sobrien	 0x0000ffff,		/* dst_mask */
1040179404Sobrien	 FALSE),		/* pcrel_offset */
1041179404Sobrien
1042179404Sobrien  /* Displacement to page pointer in the global offset table.  */
1043179404Sobrien  HOWTO (R_MIPS_GOT_PAGE,	/* type */
1044179404Sobrien	 0,			/* rightshift */
1045179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1046179404Sobrien	 16,			/* bitsize */
1047179404Sobrien	 FALSE,			/* pc_relative */
1048179404Sobrien	 0,			/* bitpos */
1049179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
1050179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1051179404Sobrien	 "R_MIPS_GOT_PAGE",	/* name */
1052179404Sobrien	 FALSE,			/* partial_inplace */
1053179404Sobrien	 0,			/* src_mask */
1054179404Sobrien	 0x0000ffff,		/* dst_mask */
1055179404Sobrien	 FALSE),		/* pcrel_offset */
1056179404Sobrien
1057179404Sobrien  /* Offset from page pointer in the global offset table.  */
1058179404Sobrien  HOWTO (R_MIPS_GOT_OFST,	/* type */
1059179404Sobrien	 0,			/* rightshift */
1060179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1061179404Sobrien	 16,			/* bitsize */
1062179404Sobrien	 FALSE,			/* pc_relative */
1063179404Sobrien	 0,			/* bitpos */
1064179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
1065179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1066179404Sobrien	 "R_MIPS_GOT_OFST",	/* name */
1067179404Sobrien	 FALSE,			/* partial_inplace */
1068179404Sobrien	 0,			/* src_mask */
1069179404Sobrien	 0x0000ffff,		/* dst_mask */
1070179404Sobrien	 FALSE),		/* pcrel_offset */
1071179404Sobrien
1072179404Sobrien  /* High 16 bits of displacement in global offset table.  */
1073179404Sobrien  HOWTO (R_MIPS_GOT_HI16,	/* type */
1074179404Sobrien	 0,			/* rightshift */
1075179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1076179404Sobrien	 16,			/* bitsize */
1077179404Sobrien	 FALSE,			/* pc_relative */
1078179404Sobrien	 0,			/* bitpos */
1079179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1080179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1081179404Sobrien	 "R_MIPS_GOT_HI16",	/* name */
1082179404Sobrien	 FALSE,			/* partial_inplace */
1083179404Sobrien	 0,			/* src_mask */
1084179404Sobrien	 0x0000ffff,		/* dst_mask */
1085179404Sobrien	 FALSE),		/* pcrel_offset */
1086179404Sobrien
1087179404Sobrien  /* Low 16 bits of displacement in global offset table.  */
1088179404Sobrien  HOWTO (R_MIPS_GOT_LO16,	/* type */
1089179404Sobrien	 0,			/* rightshift */
1090179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1091179404Sobrien	 16,			/* bitsize */
1092179404Sobrien	 FALSE,			/* pc_relative */
1093179404Sobrien	 0,			/* bitpos */
1094179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1095179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1096179404Sobrien	 "R_MIPS_GOT_LO16",	/* name */
1097179404Sobrien	 FALSE,			/* partial_inplace */
1098179404Sobrien	 0,			/* src_mask */
1099179404Sobrien	 0x0000ffff,		/* dst_mask */
1100179404Sobrien	 FALSE),		/* pcrel_offset */
1101179404Sobrien
1102179404Sobrien  /* 64 bit subtraction.  */
1103179404Sobrien  HOWTO (R_MIPS_SUB,		/* type */
1104179404Sobrien	 0,			/* rightshift */
1105179404Sobrien	 4,			/* size (0 = byte, 1 = short, 2 = long) */
1106179404Sobrien	 64,			/* bitsize */
1107179404Sobrien	 FALSE,			/* pc_relative */
1108179404Sobrien	 0,			/* bitpos */
1109179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1110179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1111179404Sobrien	 "R_MIPS_SUB",		/* name */
1112179404Sobrien	 FALSE,			/* partial_inplace */
1113179404Sobrien	 0,			/* src_mask */
1114179404Sobrien	 MINUS_ONE,		/* dst_mask */
1115179404Sobrien	 FALSE),		/* pcrel_offset */
1116179404Sobrien
1117179404Sobrien  /* Insert the addend as an instruction.  */
1118179404Sobrien  /* FIXME: Not handled correctly.  */
1119179404Sobrien  HOWTO (R_MIPS_INSERT_A,	/* type */
1120179404Sobrien	 0,			/* rightshift */
1121179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1122179404Sobrien	 32,			/* bitsize */
1123179404Sobrien	 FALSE,			/* pc_relative */
1124179404Sobrien	 0,			/* bitpos */
1125179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1126179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1127179404Sobrien	 "R_MIPS_INSERT_A",	/* name */
1128179404Sobrien	 FALSE,			/* partial_inplace */
1129179404Sobrien	 0,			/* src_mask */
1130179404Sobrien	 0xffffffff,		/* dst_mask */
1131179404Sobrien	 FALSE),		/* pcrel_offset */
1132179404Sobrien
1133179404Sobrien  /* Insert the addend as an instruction, and change all relocations
1134179404Sobrien     to refer to the old instruction at the address.  */
1135179404Sobrien  /* FIXME: Not handled correctly.  */
1136179404Sobrien  HOWTO (R_MIPS_INSERT_B,	/* type */
1137179404Sobrien	 0,			/* rightshift */
1138179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1139179404Sobrien	 32,			/* bitsize */
1140179404Sobrien	 FALSE,			/* pc_relative */
1141179404Sobrien	 0,			/* bitpos */
1142179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1143179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1144179404Sobrien	 "R_MIPS_INSERT_B",	/* name */
1145179404Sobrien	 FALSE,			/* partial_inplace */
1146179404Sobrien	 0,			/* src_mask */
1147179404Sobrien	 0xffffffff,		/* dst_mask */
1148179404Sobrien	 FALSE),		/* pcrel_offset */
1149179404Sobrien
1150179404Sobrien  /* Delete a 32 bit instruction.  */
1151179404Sobrien  /* FIXME: Not handled correctly.  */
1152179404Sobrien  HOWTO (R_MIPS_DELETE,		/* type */
1153179404Sobrien	 0,			/* rightshift */
1154179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1155179404Sobrien	 32,			/* bitsize */
1156179404Sobrien	 FALSE,			/* pc_relative */
1157179404Sobrien	 0,			/* bitpos */
1158179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1159179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1160179404Sobrien	 "R_MIPS_DELETE",	/* name */
1161179404Sobrien	 FALSE,			/* partial_inplace */
1162179404Sobrien	 0,			/* src_mask */
1163179404Sobrien	 0xffffffff,		/* dst_mask */
1164179404Sobrien	 FALSE),		/* pcrel_offset */
1165179404Sobrien
1166179404Sobrien  /* Get the higher value of a 64 bit addend.  */
1167179404Sobrien  HOWTO (R_MIPS_HIGHER,		/* type */
1168179404Sobrien	 0,			/* rightshift */
1169179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1170179404Sobrien	 16,			/* bitsize */
1171179404Sobrien	 FALSE,			/* pc_relative */
1172179404Sobrien	 0,			/* bitpos */
1173179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1174179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1175179404Sobrien	 "R_MIPS_HIGHER",	/* name */
1176179404Sobrien	 FALSE,			/* partial_inplace */
1177179404Sobrien	 0,			/* src_mask */
1178179404Sobrien	 0x0000ffff,		/* dst_mask */
1179179404Sobrien	 FALSE),		/* pcrel_offset */
1180179404Sobrien
1181179404Sobrien  /* Get the highest value of a 64 bit addend.  */
1182179404Sobrien  HOWTO (R_MIPS_HIGHEST,	/* type */
1183179404Sobrien	 0,			/* rightshift */
1184179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1185179404Sobrien	 16,			/* bitsize */
1186179404Sobrien	 FALSE,			/* pc_relative */
1187179404Sobrien	 0,			/* bitpos */
1188179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1189179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1190179404Sobrien	 "R_MIPS_HIGHEST",	/* name */
1191179404Sobrien	 FALSE,			/* partial_inplace */
1192179404Sobrien	 0,			/* src_mask */
1193179404Sobrien	 0x0000ffff,		/* dst_mask */
1194179404Sobrien	 FALSE),		/* pcrel_offset */
1195179404Sobrien
1196179404Sobrien  /* High 16 bits of displacement in global offset table.  */
1197179404Sobrien  HOWTO (R_MIPS_CALL_HI16,	/* type */
1198179404Sobrien	 0,			/* rightshift */
1199179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1200179404Sobrien	 16,			/* bitsize */
1201179404Sobrien	 FALSE,			/* pc_relative */
1202179404Sobrien	 0,			/* bitpos */
1203179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1204179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1205179404Sobrien	 "R_MIPS_CALL_HI16",	/* name */
1206179404Sobrien	 FALSE,			/* partial_inplace */
1207179404Sobrien	 0,			/* src_mask */
1208179404Sobrien	 0x0000ffff,		/* dst_mask */
1209179404Sobrien	 FALSE),		/* pcrel_offset */
1210179404Sobrien
1211179404Sobrien  /* Low 16 bits of displacement in global offset table.  */
1212179404Sobrien  HOWTO (R_MIPS_CALL_LO16,	/* type */
1213179404Sobrien	 0,			/* rightshift */
1214179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1215179404Sobrien	 16,			/* bitsize */
1216179404Sobrien	 FALSE,			/* pc_relative */
1217179404Sobrien	 0,			/* bitpos */
1218179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1219179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1220179404Sobrien	 "R_MIPS_CALL_LO16",	/* name */
1221179404Sobrien	 FALSE,			/* partial_inplace */
1222179404Sobrien	 0,			/* src_mask */
1223179404Sobrien	 0x0000ffff,		/* dst_mask */
1224179404Sobrien	 FALSE),		/* pcrel_offset */
1225179404Sobrien
1226179404Sobrien  /* Section displacement, used by an associated event location section.  */
1227179404Sobrien  HOWTO (R_MIPS_SCN_DISP,	/* type */
1228179404Sobrien	 0,			/* rightshift */
1229179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1230179404Sobrien	 32,			/* bitsize */
1231179404Sobrien	 FALSE,			/* pc_relative */
1232179404Sobrien	 0,			/* bitpos */
1233179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1234179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1235179404Sobrien	 "R_MIPS_SCN_DISP",	/* name */
1236179404Sobrien	 FALSE,			/* partial_inplace */
1237179404Sobrien	 0,			/* src_mask */
1238179404Sobrien	 0xffffffff,		/* dst_mask */
1239179404Sobrien	 FALSE),		/* pcrel_offset */
1240179404Sobrien
1241179404Sobrien  /* 16 bit relocation.  */
1242179404Sobrien  HOWTO (R_MIPS_REL16,		/* type */
1243179404Sobrien	 0,			/* rightshift */
1244179404Sobrien	 1,			/* size (0 = byte, 1 = short, 2 = long) */
1245179404Sobrien	 16,			/* bitsize */
1246179404Sobrien	 FALSE,			/* pc_relative */
1247179404Sobrien	 0,			/* bitpos */
1248179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
1249179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1250179404Sobrien	 "R_MIPS_REL16",	/* name */
1251179404Sobrien	 FALSE,			/* partial_inplace */
1252179404Sobrien	 0,			/* src_mask */
1253179404Sobrien	 0xffff,		/* dst_mask */
1254179404Sobrien	 FALSE),		/* pcrel_offset */
1255179404Sobrien
1256179404Sobrien  /* These two are obsolete.  */
1257179404Sobrien  EMPTY_HOWTO (R_MIPS_ADD_IMMEDIATE),
1258179404Sobrien  EMPTY_HOWTO (R_MIPS_PJUMP),
1259179404Sobrien
1260179404Sobrien  /* Similiar to R_MIPS_REL32, but used for relocations in a GOT section.
1261179404Sobrien     It must be used for multigot GOT's (and only there).  */
1262179404Sobrien  HOWTO (R_MIPS_RELGOT,		/* type */
1263179404Sobrien	 0,			/* rightshift */
1264179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1265179404Sobrien	 32,			/* bitsize */
1266179404Sobrien	 FALSE,			/* pc_relative */
1267179404Sobrien	 0,			/* bitpos */
1268179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1269179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1270179404Sobrien	 "R_MIPS_RELGOT",	/* name */
1271179404Sobrien	 FALSE,			/* partial_inplace */
1272179404Sobrien	 0,			/* src_mask */
1273179404Sobrien	 0xffffffff,		/* dst_mask */
1274179404Sobrien	 FALSE),		/* pcrel_offset */
1275179404Sobrien
1276179404Sobrien  /* Protected jump conversion.  This is an optimization hint.  No
1277179404Sobrien     relocation is required for correctness.  */
1278179404Sobrien  HOWTO (R_MIPS_JALR,	        /* type */
1279179404Sobrien	 0,			/* rightshift */
1280179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1281179404Sobrien	 32,			/* bitsize */
1282179404Sobrien	 FALSE,			/* pc_relative */
1283179404Sobrien	 0,			/* bitpos */
1284179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1285179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1286179404Sobrien	 "R_MIPS_JALR",	        /* name */
1287179404Sobrien	 FALSE,			/* partial_inplace */
1288179404Sobrien	 0,			/* src_mask */
1289218822Sdim	 0,			/* dst_mask */
1290218822Sdim	 FALSE),		/* pcrel_offset */
1291218822Sdim
1292218822Sdim  /* TLS GD/LD dynamic relocations.  */
1293218822Sdim  HOWTO (R_MIPS_TLS_DTPMOD32,	/* type */
1294218822Sdim	 0,			/* rightshift */
1295218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1296218822Sdim	 32,			/* bitsize */
1297218822Sdim	 FALSE,			/* pc_relative */
1298218822Sdim	 0,			/* bitpos */
1299218822Sdim	 complain_overflow_dont, /* complain_on_overflow */
1300218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
1301218822Sdim	 "R_MIPS_TLS_DTPMOD32",	/* name */
1302218822Sdim	 TRUE,			/* partial_inplace */
1303218822Sdim	 0xffffffff,		/* src_mask */
1304179404Sobrien	 0xffffffff,		/* dst_mask */
1305179404Sobrien	 FALSE),		/* pcrel_offset */
1306218822Sdim
1307218822Sdim  HOWTO (R_MIPS_TLS_DTPREL32,	/* type */
1308218822Sdim	 0,			/* rightshift */
1309218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1310218822Sdim	 32,			/* bitsize */
1311218822Sdim	 FALSE,			/* pc_relative */
1312218822Sdim	 0,			/* bitpos */
1313218822Sdim	 complain_overflow_dont, /* complain_on_overflow */
1314218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
1315218822Sdim	 "R_MIPS_TLS_DTPREL32",	/* name */
1316218822Sdim	 TRUE,			/* partial_inplace */
1317218822Sdim	 0xffffffff,		/* src_mask */
1318218822Sdim	 0xffffffff,		/* dst_mask */
1319218822Sdim	 FALSE),		/* pcrel_offset */
1320218822Sdim
1321218822Sdim  EMPTY_HOWTO (R_MIPS_TLS_DTPMOD64),
1322218822Sdim  EMPTY_HOWTO (R_MIPS_TLS_DTPREL64),
1323218822Sdim
1324218822Sdim  /* TLS general dynamic variable reference.  */
1325218822Sdim  HOWTO (R_MIPS_TLS_GD,		/* type */
1326218822Sdim	 0,			/* rightshift */
1327218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1328218822Sdim	 16,			/* bitsize */
1329218822Sdim	 FALSE,			/* pc_relative */
1330218822Sdim	 0,			/* bitpos */
1331218822Sdim	 complain_overflow_signed, /* complain_on_overflow */
1332218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
1333218822Sdim	 "R_MIPS_TLS_GD",	/* name */
1334218822Sdim	 TRUE,			/* partial_inplace */
1335218822Sdim	 0x0000ffff,		/* src_mask */
1336218822Sdim	 0x0000ffff,		/* dst_mask */
1337218822Sdim	 FALSE),		/* pcrel_offset */
1338218822Sdim
1339218822Sdim  /* TLS local dynamic variable reference.  */
1340218822Sdim  HOWTO (R_MIPS_TLS_LDM,	/* type */
1341218822Sdim	 0,			/* rightshift */
1342218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1343218822Sdim	 16,			/* bitsize */
1344218822Sdim	 FALSE,			/* pc_relative */
1345218822Sdim	 0,			/* bitpos */
1346218822Sdim	 complain_overflow_signed, /* complain_on_overflow */
1347218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
1348218822Sdim	 "R_MIPS_TLS_LDM",	/* name */
1349218822Sdim	 TRUE,			/* partial_inplace */
1350218822Sdim	 0x0000ffff,		/* src_mask */
1351218822Sdim	 0x0000ffff,		/* dst_mask */
1352218822Sdim	 FALSE),		/* pcrel_offset */
1353218822Sdim
1354218822Sdim  /* TLS local dynamic offset.  */
1355218822Sdim  HOWTO (R_MIPS_TLS_DTPREL_HI16,	/* type */
1356218822Sdim	 0,			/* rightshift */
1357218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1358218822Sdim	 16,			/* bitsize */
1359218822Sdim	 FALSE,			/* pc_relative */
1360218822Sdim	 0,			/* bitpos */
1361218822Sdim	 complain_overflow_signed, /* complain_on_overflow */
1362218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
1363218822Sdim	 "R_MIPS_TLS_DTPREL_HI16",	/* name */
1364218822Sdim	 TRUE,			/* partial_inplace */
1365218822Sdim	 0x0000ffff,		/* src_mask */
1366218822Sdim	 0x0000ffff,		/* dst_mask */
1367218822Sdim	 FALSE),		/* pcrel_offset */
1368218822Sdim
1369218822Sdim  /* TLS local dynamic offset.  */
1370218822Sdim  HOWTO (R_MIPS_TLS_DTPREL_LO16,	/* type */
1371218822Sdim	 0,			/* rightshift */
1372218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1373218822Sdim	 16,			/* bitsize */
1374218822Sdim	 FALSE,			/* pc_relative */
1375218822Sdim	 0,			/* bitpos */
1376218822Sdim	 complain_overflow_signed, /* complain_on_overflow */
1377218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
1378218822Sdim	 "R_MIPS_TLS_DTPREL_LO16",	/* name */
1379218822Sdim	 TRUE,			/* partial_inplace */
1380218822Sdim	 0x0000ffff,		/* src_mask */
1381218822Sdim	 0x0000ffff,		/* dst_mask */
1382218822Sdim	 FALSE),		/* pcrel_offset */
1383218822Sdim
1384218822Sdim  /* TLS thread pointer offset.  */
1385218822Sdim  HOWTO (R_MIPS_TLS_GOTTPREL,	/* type */
1386218822Sdim	 0,			/* rightshift */
1387218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1388218822Sdim	 16,			/* bitsize */
1389218822Sdim	 FALSE,			/* pc_relative */
1390218822Sdim	 0,			/* bitpos */
1391218822Sdim	 complain_overflow_signed, /* complain_on_overflow */
1392218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
1393218822Sdim	 "R_MIPS_TLS_GOTTPREL",	/* name */
1394218822Sdim	 TRUE,			/* partial_inplace */
1395218822Sdim	 0x0000ffff,		/* src_mask */
1396218822Sdim	 0x0000ffff,		/* dst_mask */
1397218822Sdim	 FALSE),		/* pcrel_offset */
1398218822Sdim
1399218822Sdim  /* TLS IE dynamic relocations.  */
1400218822Sdim  HOWTO (R_MIPS_TLS_TPREL32,	/* type */
1401218822Sdim	 0,			/* rightshift */
1402218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1403218822Sdim	 32,			/* bitsize */
1404218822Sdim	 FALSE,			/* pc_relative */
1405218822Sdim	 0,			/* bitpos */
1406218822Sdim	 complain_overflow_dont, /* complain_on_overflow */
1407218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
1408218822Sdim	 "R_MIPS_TLS_TPREL32",	/* name */
1409218822Sdim	 TRUE,			/* partial_inplace */
1410218822Sdim	 0xffffffff,		/* src_mask */
1411218822Sdim	 0xffffffff,		/* dst_mask */
1412218822Sdim	 FALSE),		/* pcrel_offset */
1413218822Sdim
1414218822Sdim  EMPTY_HOWTO (R_MIPS_TLS_TPREL64),
1415218822Sdim
1416218822Sdim  /* TLS thread pointer offset.  */
1417218822Sdim  HOWTO (R_MIPS_TLS_TPREL_HI16,	/* type */
1418218822Sdim	 0,			/* rightshift */
1419218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1420218822Sdim	 16,			/* bitsize */
1421218822Sdim	 FALSE,			/* pc_relative */
1422218822Sdim	 0,			/* bitpos */
1423218822Sdim	 complain_overflow_signed, /* complain_on_overflow */
1424218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
1425218822Sdim	 "R_MIPS_TLS_TPREL_HI16", /* name */
1426218822Sdim	 TRUE,			/* partial_inplace */
1427218822Sdim	 0x0000ffff,		/* src_mask */
1428218822Sdim	 0x0000ffff,		/* dst_mask */
1429218822Sdim	 FALSE),		/* pcrel_offset */
1430218822Sdim
1431218822Sdim  /* TLS thread pointer offset.  */
1432218822Sdim  HOWTO (R_MIPS_TLS_TPREL_LO16,	/* type */
1433218822Sdim	 0,			/* rightshift */
1434218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1435218822Sdim	 16,			/* bitsize */
1436218822Sdim	 FALSE,			/* pc_relative */
1437218822Sdim	 0,			/* bitpos */
1438218822Sdim	 complain_overflow_signed, /* complain_on_overflow */
1439218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
1440218822Sdim	 "R_MIPS_TLS_TPREL_LO16", /* name */
1441218822Sdim	 TRUE,			/* partial_inplace */
1442218822Sdim	 0x0000ffff,		/* src_mask */
1443218822Sdim	 0x0000ffff,		/* dst_mask */
1444218822Sdim	 FALSE),		/* pcrel_offset */
1445218822Sdim
1446218822Sdim  /* 32 bit relocation with no addend.  */
1447218822Sdim  HOWTO (R_MIPS_GLOB_DAT,	/* type */
1448218822Sdim	 0,			/* rightshift */
1449218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1450218822Sdim	 32,			/* bitsize */
1451218822Sdim	 FALSE,			/* pc_relative */
1452218822Sdim	 0,			/* bitpos */
1453218822Sdim	 complain_overflow_dont, /* complain_on_overflow */
1454218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
1455218822Sdim	 "R_MIPS_GLOB_DAT",	/* name */
1456218822Sdim	 FALSE,			/* partial_inplace */
1457218822Sdim	 0x0,			/* src_mask */
1458218822Sdim	 0xffffffff,		/* dst_mask */
1459218822Sdim	 FALSE),		/* pcrel_offset */
1460179404Sobrien};
1461179404Sobrien
1462218822Sdimstatic reloc_howto_type elf_mips16_howto_table_rel[] =
1463218822Sdim{
1464218822Sdim  /* The reloc used for the mips16 jump instruction.  */
1465179404Sobrien  HOWTO (R_MIPS16_26,		/* type */
1466179404Sobrien	 2,			/* rightshift */
1467179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1468179404Sobrien	 26,			/* bitsize */
1469179404Sobrien	 FALSE,			/* pc_relative */
1470179404Sobrien	 0,			/* bitpos */
1471179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1472179404Sobrien	 			/* This needs complex overflow
1473179404Sobrien				   detection, because the upper four
1474179404Sobrien				   bits must match the PC.  */
1475218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
1476179404Sobrien	 "R_MIPS16_26",		/* name */
1477179404Sobrien	 TRUE,			/* partial_inplace */
1478179404Sobrien	 0x3ffffff,		/* src_mask */
1479179404Sobrien	 0x3ffffff,		/* dst_mask */
1480218822Sdim	 FALSE),		/* pcrel_offset */
1481179404Sobrien
1482218822Sdim  /* The reloc used for the mips16 gprel instruction.  */
1483179404Sobrien  HOWTO (R_MIPS16_GPREL,	/* type */
1484179404Sobrien	 0,			/* rightshift */
1485179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1486179404Sobrien	 16,			/* bitsize */
1487179404Sobrien	 FALSE,			/* pc_relative */
1488179404Sobrien	 0,			/* bitpos */
1489179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
1490179404Sobrien	 mips16_gprel_reloc,	/* special_function */
1491179404Sobrien	 "R_MIPS16_GPREL",	/* name */
1492179404Sobrien	 TRUE,			/* partial_inplace */
1493218822Sdim	 0x0000ffff,		/* src_mask */
1494218822Sdim	 0x0000ffff,	        /* dst_mask */
1495218822Sdim	 FALSE),		/* pcrel_offset */
1496179404Sobrien
1497218822Sdim  /* A placeholder for MIPS16 reference to global offset table.  */
1498218822Sdim  EMPTY_HOWTO (R_MIPS16_GOT16),
1499218822Sdim
1500218822Sdim  /* A placeholder for MIPS16 16 bit call through global offset table.  */
1501218822Sdim  EMPTY_HOWTO (R_MIPS16_CALL16),
1502218822Sdim
1503218822Sdim  /* MIPS16 high 16 bits of symbol value.  */
1504218822Sdim  HOWTO (R_MIPS16_HI16,		/* type */
1505218822Sdim	 16,			/* rightshift */
1506218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1507218822Sdim	 16,			/* bitsize */
1508218822Sdim	 FALSE,			/* pc_relative */
1509218822Sdim	 0,			/* bitpos */
1510218822Sdim	 complain_overflow_dont, /* complain_on_overflow */
1511218822Sdim	 _bfd_mips_elf_hi16_reloc, /* special_function */
1512218822Sdim	 "R_MIPS16_HI16",	/* name */
1513218822Sdim	 TRUE,			/* partial_inplace */
1514218822Sdim	 0x0000ffff,		/* src_mask */
1515218822Sdim	 0x0000ffff,		/* dst_mask */
1516218822Sdim	 FALSE),		/* pcrel_offset */
1517218822Sdim
1518218822Sdim  /* MIPS16 low 16 bits of symbol value.  */
1519218822Sdim  HOWTO (R_MIPS16_LO16,		/* type */
1520218822Sdim	 0,			/* rightshift */
1521218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1522218822Sdim	 16,			/* bitsize */
1523218822Sdim	 FALSE,			/* pc_relative */
1524218822Sdim	 0,			/* bitpos */
1525218822Sdim	 complain_overflow_dont, /* complain_on_overflow */
1526218822Sdim	 _bfd_mips_elf_lo16_reloc, /* special_function */
1527218822Sdim	 "R_MIPS16_LO16",	/* name */
1528218822Sdim	 TRUE,			/* partial_inplace */
1529218822Sdim	 0x0000ffff,		/* src_mask */
1530218822Sdim	 0x0000ffff,		/* dst_mask */
1531218822Sdim	 FALSE),		/* pcrel_offset */
1532218822Sdim};
1533218822Sdim
1534218822Sdimstatic reloc_howto_type elf_mips16_howto_table_rela[] =
1535218822Sdim{
1536218822Sdim  /* The reloc used for the mips16 jump instruction.  */
1537218822Sdim  HOWTO (R_MIPS16_26,		/* type */
1538218822Sdim	 2,			/* rightshift */
1539218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1540218822Sdim	 26,			/* bitsize */
1541218822Sdim	 FALSE,			/* pc_relative */
1542218822Sdim	 0,			/* bitpos */
1543218822Sdim	 complain_overflow_dont, /* complain_on_overflow */
1544218822Sdim	 			/* This needs complex overflow
1545218822Sdim				   detection, because the upper four
1546218822Sdim				   bits must match the PC.  */
1547218822Sdim	 _bfd_mips_elf_generic_reloc, /* special_function */
1548218822Sdim	 "R_MIPS16_26",		/* name */
1549218822Sdim	 FALSE,			/* partial_inplace */
1550218822Sdim	 0x3ffffff,		/* src_mask */
1551218822Sdim	 0x3ffffff,		/* dst_mask */
1552218822Sdim	 FALSE),		/* pcrel_offset */
1553218822Sdim
1554218822Sdim  /* The reloc used for the mips16 gprel instruction.  */
1555218822Sdim  HOWTO (R_MIPS16_GPREL,	/* type */
1556218822Sdim	 0,			/* rightshift */
1557218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1558218822Sdim	 16,			/* bitsize */
1559218822Sdim	 FALSE,			/* pc_relative */
1560218822Sdim	 0,			/* bitpos */
1561218822Sdim	 complain_overflow_signed, /* complain_on_overflow */
1562218822Sdim	 mips16_gprel_reloc,	/* special_function */
1563218822Sdim	 "R_MIPS16_GPREL",	/* name */
1564218822Sdim	 FALSE,			/* partial_inplace */
1565218822Sdim	 0x0000ffff,		/* src_mask */
1566218822Sdim	 0x0000ffff,	        /* dst_mask */
1567218822Sdim	 FALSE),		/* pcrel_offset */
1568218822Sdim
1569218822Sdim  /* A placeholder for MIPS16 reference to global offset table.  */
1570218822Sdim  EMPTY_HOWTO (R_MIPS16_GOT16),
1571218822Sdim
1572218822Sdim  /* A placeholder for MIPS16 16 bit call through global offset table.  */
1573218822Sdim  EMPTY_HOWTO (R_MIPS16_CALL16),
1574218822Sdim
1575218822Sdim  /* MIPS16 high 16 bits of symbol value.  */
1576218822Sdim  HOWTO (R_MIPS16_HI16,		/* type */
1577218822Sdim	 16,			/* rightshift */
1578218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1579218822Sdim	 16,			/* bitsize */
1580218822Sdim	 FALSE,			/* pc_relative */
1581218822Sdim	 0,			/* bitpos */
1582218822Sdim	 complain_overflow_dont, /* complain_on_overflow */
1583218822Sdim	 _bfd_mips_elf_hi16_reloc, /* special_function */
1584218822Sdim	 "R_MIPS16_HI16",	/* name */
1585218822Sdim	 FALSE,			/* partial_inplace */
1586218822Sdim	 0x0000ffff,		/* src_mask */
1587218822Sdim	 0x0000ffff,		/* dst_mask */
1588218822Sdim	 FALSE),		/* pcrel_offset */
1589218822Sdim
1590218822Sdim  /* MIPS16 low 16 bits of symbol value.  */
1591218822Sdim  HOWTO (R_MIPS16_LO16,		/* type */
1592218822Sdim	 0,			/* rightshift */
1593218822Sdim	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1594218822Sdim	 16,			/* bitsize */
1595218822Sdim	 FALSE,			/* pc_relative */
1596218822Sdim	 0,			/* bitpos */
1597218822Sdim	 complain_overflow_dont, /* complain_on_overflow */
1598218822Sdim	 _bfd_mips_elf_lo16_reloc, /* special_function */
1599218822Sdim	 "R_MIPS16_LO16",	/* name */
1600218822Sdim	 FALSE,			/* partial_inplace */
1601218822Sdim	 0x0000ffff,		/* src_mask */
1602218822Sdim	 0x0000ffff,		/* dst_mask */
1603218822Sdim	 FALSE),		/* pcrel_offset */
1604218822Sdim};
1605218822Sdim
1606179404Sobrien/* GNU extension to record C++ vtable hierarchy */
1607179404Sobrienstatic reloc_howto_type elf_mips_gnu_vtinherit_howto =
1608179404Sobrien  HOWTO (R_MIPS_GNU_VTINHERIT,	/* type */
1609179404Sobrien	 0,			/* rightshift */
1610179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1611179404Sobrien	 0,			/* bitsize */
1612179404Sobrien	 FALSE,			/* pc_relative */
1613179404Sobrien	 0,			/* bitpos */
1614179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1615179404Sobrien	 NULL,			/* special_function */
1616179404Sobrien	 "R_MIPS_GNU_VTINHERIT", /* name */
1617179404Sobrien	 FALSE,			/* partial_inplace */
1618179404Sobrien	 0,			/* src_mask */
1619179404Sobrien	 0,			/* dst_mask */
1620179404Sobrien	 FALSE);		/* pcrel_offset */
1621179404Sobrien
1622179404Sobrien/* GNU extension to record C++ vtable member usage */
1623179404Sobrienstatic reloc_howto_type elf_mips_gnu_vtentry_howto =
1624179404Sobrien  HOWTO (R_MIPS_GNU_VTENTRY,	/* type */
1625179404Sobrien	 0,			/* rightshift */
1626179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1627179404Sobrien	 0,			/* bitsize */
1628179404Sobrien	 FALSE,			/* pc_relative */
1629179404Sobrien	 0,			/* bitpos */
1630179404Sobrien	 complain_overflow_dont, /* complain_on_overflow */
1631179404Sobrien	 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
1632179404Sobrien	 "R_MIPS_GNU_VTENTRY",	/* name */
1633179404Sobrien	 FALSE,			/* partial_inplace */
1634179404Sobrien	 0,			/* src_mask */
1635179404Sobrien	 0,			/* dst_mask */
1636179404Sobrien	 FALSE);		/* pcrel_offset */
1637179404Sobrien
1638179404Sobrien/* 16 bit offset for pc-relative branches.  */
1639179404Sobrienstatic reloc_howto_type elf_mips_gnu_rel16_s2 =
1640179404Sobrien  HOWTO (R_MIPS_GNU_REL16_S2,	/* type */
1641179404Sobrien	 2,			/* rightshift */
1642179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1643179404Sobrien	 16,			/* bitsize */
1644179404Sobrien	 TRUE,			/* pc_relative */
1645179404Sobrien	 0,			/* bitpos */
1646179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
1647179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1648179404Sobrien	 "R_MIPS_GNU_REL16_S2",	/* name */
1649179404Sobrien	 TRUE,			/* partial_inplace */
1650179404Sobrien	 0x0000ffff,		/* src_mask */
1651179404Sobrien	 0x0000ffff,		/* dst_mask */
1652179404Sobrien	 TRUE);			/* pcrel_offset */
1653179404Sobrien
1654179404Sobrien/* 16 bit offset for pc-relative branches.  */
1655179404Sobrienstatic reloc_howto_type elf_mips_gnu_rela16_s2 =
1656179404Sobrien  HOWTO (R_MIPS_GNU_REL16_S2,	/* type */
1657179404Sobrien	 2,			/* rightshift */
1658179404Sobrien	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1659179404Sobrien	 16,			/* bitsize */
1660179404Sobrien	 TRUE,			/* pc_relative */
1661179404Sobrien	 0,			/* bitpos */
1662179404Sobrien	 complain_overflow_signed, /* complain_on_overflow */
1663179404Sobrien	 _bfd_mips_elf_generic_reloc, /* special_function */
1664179404Sobrien	 "R_MIPS_GNU_REL16_S2",	/* name */
1665179404Sobrien	 FALSE,			/* partial_inplace */
1666179404Sobrien	 0,			/* src_mask */
1667179404Sobrien	 0x0000ffff,		/* dst_mask */
1668179404Sobrien	 TRUE);			/* pcrel_offset */
1669179404Sobrien
1670179404Sobrien/* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
1671179404Sobrien   dangerous relocation.  */
1672179404Sobrien
1673179404Sobrienstatic bfd_boolean
1674179404Sobrienmips_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
1675179404Sobrien{
1676179404Sobrien  unsigned int count;
1677179404Sobrien  asymbol **sym;
1678179404Sobrien  unsigned int i;
1679179404Sobrien
1680179404Sobrien  /* If we've already figured out what GP will be, just return it.  */
1681179404Sobrien  *pgp = _bfd_get_gp_value (output_bfd);
1682179404Sobrien  if (*pgp)
1683179404Sobrien    return TRUE;
1684179404Sobrien
1685179404Sobrien  count = bfd_get_symcount (output_bfd);
1686179404Sobrien  sym = bfd_get_outsymbols (output_bfd);
1687179404Sobrien
1688179404Sobrien  /* The linker script will have created a symbol named `_gp' with the
1689179404Sobrien     appropriate value.  */
1690179404Sobrien  if (sym == NULL)
1691179404Sobrien    i = count;
1692179404Sobrien  else
1693179404Sobrien    {
1694179404Sobrien      for (i = 0; i < count; i++, sym++)
1695179404Sobrien	{
1696179404Sobrien	  register const char *name;
1697179404Sobrien
1698179404Sobrien	  name = bfd_asymbol_name (*sym);
1699179404Sobrien	  if (*name == '_' && strcmp (name, "_gp") == 0)
1700179404Sobrien	    {
1701179404Sobrien	      *pgp = bfd_asymbol_value (*sym);
1702179404Sobrien	      _bfd_set_gp_value (output_bfd, *pgp);
1703179404Sobrien	      break;
1704179404Sobrien	    }
1705179404Sobrien	}
1706179404Sobrien    }
1707179404Sobrien
1708179404Sobrien  if (i >= count)
1709179404Sobrien    {
1710179404Sobrien      /* Only get the error once.  */
1711179404Sobrien      *pgp = 4;
1712179404Sobrien      _bfd_set_gp_value (output_bfd, *pgp);
1713179404Sobrien      return FALSE;
1714179404Sobrien    }
1715179404Sobrien
1716179404Sobrien  return TRUE;
1717179404Sobrien}
1718179404Sobrien
1719179404Sobrien/* We have to figure out the gp value, so that we can adjust the
1720179404Sobrien   symbol value correctly.  We look up the symbol _gp in the output
1721179404Sobrien   BFD.  If we can't find it, we're stuck.  We cache it in the ELF
1722179404Sobrien   target data.  We don't need to adjust the symbol value for an
1723179404Sobrien   external symbol if we are producing relocatable output.  */
1724179404Sobrien
1725179404Sobrienstatic bfd_reloc_status_type
1726179404Sobrienmips_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
1727179404Sobrien		   char **error_message, bfd_vma *pgp)
1728179404Sobrien{
1729179404Sobrien  if (bfd_is_und_section (symbol->section)
1730179404Sobrien      && ! relocatable)
1731179404Sobrien    {
1732179404Sobrien      *pgp = 0;
1733179404Sobrien      return bfd_reloc_undefined;
1734179404Sobrien    }
1735179404Sobrien
1736179404Sobrien  *pgp = _bfd_get_gp_value (output_bfd);
1737179404Sobrien  if (*pgp == 0
1738179404Sobrien      && (! relocatable
1739179404Sobrien	  || (symbol->flags & BSF_SECTION_SYM) != 0))
1740179404Sobrien    {
1741179404Sobrien      if (relocatable)
1742179404Sobrien	{
1743179404Sobrien	  /* Make up a value.  */
1744179404Sobrien	  *pgp = symbol->section->output_section->vma /*+ 0x4000*/;
1745179404Sobrien	  _bfd_set_gp_value (output_bfd, *pgp);
1746179404Sobrien	}
1747179404Sobrien      else if (!mips_elf_assign_gp (output_bfd, pgp))
1748179404Sobrien	{
1749179404Sobrien	  *error_message =
1750179404Sobrien	    (char *) _("GP relative relocation when _gp not defined");
1751179404Sobrien	  return bfd_reloc_dangerous;
1752179404Sobrien	}
1753179404Sobrien    }
1754179404Sobrien
1755179404Sobrien  return bfd_reloc_ok;
1756179404Sobrien}
1757179404Sobrien
1758179404Sobrien/* Do a R_MIPS_GPREL16 relocation.  This is a 16 bit value which must
1759179404Sobrien   become the offset from the gp register.  */
1760179404Sobrien
1761179404Sobrienstatic bfd_reloc_status_type
1762179404Sobrienmips_elf_gprel16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
1763179404Sobrien			asymbol *symbol, void *data ATTRIBUTE_UNUSED,
1764179404Sobrien			asection *input_section, bfd *output_bfd,
1765179404Sobrien			char **error_message ATTRIBUTE_UNUSED)
1766179404Sobrien{
1767179404Sobrien  bfd_boolean relocatable;
1768179404Sobrien  bfd_reloc_status_type ret;
1769179404Sobrien  bfd_vma gp;
1770179404Sobrien
1771179404Sobrien  if (output_bfd != NULL)
1772179404Sobrien    relocatable = TRUE;
1773179404Sobrien  else
1774179404Sobrien    {
1775179404Sobrien      relocatable = FALSE;
1776179404Sobrien      output_bfd = symbol->section->output_section->owner;
1777179404Sobrien    }
1778179404Sobrien
1779179404Sobrien  ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
1780179404Sobrien			   &gp);
1781179404Sobrien  if (ret != bfd_reloc_ok)
1782179404Sobrien    return ret;
1783179404Sobrien
1784179404Sobrien  return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1785179404Sobrien					input_section, relocatable,
1786179404Sobrien					data, gp);
1787179404Sobrien}
1788179404Sobrien
1789179404Sobrien/* Do a R_MIPS_LITERAL relocation.  */
1790179404Sobrien
1791179404Sobrienstatic bfd_reloc_status_type
1792179404Sobrienmips_elf_literal_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1793179404Sobrien			void *data, asection *input_section, bfd *output_bfd,
1794179404Sobrien			char **error_message)
1795179404Sobrien{
1796179404Sobrien  bfd_boolean relocatable;
1797179404Sobrien  bfd_reloc_status_type ret;
1798179404Sobrien  bfd_vma gp;
1799179404Sobrien
1800218822Sdim  /* R_MIPS_LITERAL relocations are defined for local symbols only.  */
1801218822Sdim  if (output_bfd != NULL
1802218822Sdim      && (symbol->flags & BSF_SECTION_SYM) == 0
1803218822Sdim      && (symbol->flags & BSF_LOCAL) != 0)
1804218822Sdim    {
1805218822Sdim      *error_message = (char *)
1806218822Sdim	_("literal relocation occurs for an external symbol");
1807218822Sdim      return bfd_reloc_outofrange;
1808218822Sdim    }
1809218822Sdim
1810179404Sobrien  /* FIXME: The entries in the .lit8 and .lit4 sections should be merged.  */
1811179404Sobrien  if (output_bfd != NULL)
1812179404Sobrien    relocatable = TRUE;
1813179404Sobrien  else
1814179404Sobrien    {
1815179404Sobrien      relocatable = FALSE;
1816179404Sobrien      output_bfd = symbol->section->output_section->owner;
1817179404Sobrien    }
1818179404Sobrien
1819179404Sobrien  ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
1820179404Sobrien			   &gp);
1821179404Sobrien  if (ret != bfd_reloc_ok)
1822179404Sobrien    return ret;
1823179404Sobrien
1824179404Sobrien  return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1825179404Sobrien					input_section, relocatable,
1826179404Sobrien					data, gp);
1827179404Sobrien}
1828179404Sobrien
1829179404Sobrien/* Do a R_MIPS_GPREL32 relocation.  This is a 32 bit value which must
1830179404Sobrien   become the offset from the gp register.  */
1831179404Sobrien
1832179404Sobrienstatic bfd_reloc_status_type
1833179404Sobrienmips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1834179404Sobrien			void *data, asection *input_section, bfd *output_bfd,
1835179404Sobrien			char **error_message)
1836179404Sobrien{
1837179404Sobrien  bfd_boolean relocatable;
1838179404Sobrien  bfd_reloc_status_type ret;
1839179404Sobrien  bfd_vma gp;
1840179404Sobrien
1841179404Sobrien  /* R_MIPS_GPREL32 relocations are defined for local symbols only.  */
1842179404Sobrien  if (output_bfd != NULL
1843179404Sobrien      && (symbol->flags & BSF_SECTION_SYM) == 0
1844179404Sobrien      && (symbol->flags & BSF_LOCAL) != 0)
1845179404Sobrien    {
1846179404Sobrien      *error_message = (char *)
1847179404Sobrien	_("32bits gp relative relocation occurs for an external symbol");
1848179404Sobrien      return bfd_reloc_outofrange;
1849179404Sobrien    }
1850179404Sobrien
1851179404Sobrien  if (output_bfd != NULL)
1852179404Sobrien    {
1853179404Sobrien      relocatable = TRUE;
1854179404Sobrien      gp = _bfd_get_gp_value (output_bfd);
1855179404Sobrien    }
1856179404Sobrien  else
1857179404Sobrien    {
1858179404Sobrien      relocatable = FALSE;
1859179404Sobrien      output_bfd = symbol->section->output_section->owner;
1860179404Sobrien
1861179404Sobrien      ret = mips_elf_final_gp (output_bfd, symbol, relocatable,
1862179404Sobrien			       error_message, &gp);
1863179404Sobrien      if (ret != bfd_reloc_ok)
1864179404Sobrien	return ret;
1865179404Sobrien    }
1866179404Sobrien
1867179404Sobrien  return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
1868179404Sobrien			  relocatable, data, gp);
1869179404Sobrien}
1870179404Sobrien
1871179404Sobrienstatic bfd_reloc_status_type
1872179404Sobriengprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
1873179404Sobrien		 asection *input_section, bfd_boolean relocatable,
1874179404Sobrien		 void *data, bfd_vma gp)
1875179404Sobrien{
1876179404Sobrien  bfd_vma relocation;
1877179404Sobrien  unsigned long val;
1878179404Sobrien
1879179404Sobrien  if (bfd_is_com_section (symbol->section))
1880179404Sobrien    relocation = 0;
1881179404Sobrien  else
1882179404Sobrien    relocation = symbol->value;
1883179404Sobrien
1884179404Sobrien  relocation += symbol->section->output_section->vma;
1885179404Sobrien  relocation += symbol->section->output_offset;
1886179404Sobrien
1887218822Sdim  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
1888179404Sobrien    return bfd_reloc_outofrange;
1889179404Sobrien
1890179404Sobrien  if (reloc_entry->howto->src_mask == 0)
1891179404Sobrien    val = 0;
1892179404Sobrien  else
1893179404Sobrien    val = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1894179404Sobrien
1895179404Sobrien  /* Set val to the offset into the section or symbol.  */
1896179404Sobrien  val += reloc_entry->addend;
1897179404Sobrien
1898179404Sobrien  /* Adjust val for the final section location and GP value.  If we
1899179404Sobrien     are producing relocatable output, we don't want to do this for
1900179404Sobrien     an external symbol.  */
1901179404Sobrien  if (! relocatable
1902179404Sobrien      || (symbol->flags & BSF_SECTION_SYM) != 0)
1903179404Sobrien    val += relocation - gp;
1904179404Sobrien
1905179404Sobrien  bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
1906179404Sobrien
1907179404Sobrien  if (relocatable)
1908179404Sobrien    reloc_entry->address += input_section->output_offset;
1909179404Sobrien
1910179404Sobrien  return bfd_reloc_ok;
1911179404Sobrien}
1912179404Sobrien
1913179404Sobrien/* Do a R_MIPS_SHIFT6 relocation. The MSB of the shift is stored at bit 2,
1914179404Sobrien   the rest is at bits 6-10. The bitpos already got right by the howto.  */
1915179404Sobrien
1916179404Sobrienstatic bfd_reloc_status_type
1917179404Sobrienmips_elf_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1918179404Sobrien		       void *data, asection *input_section, bfd *output_bfd,
1919179404Sobrien		       char **error_message)
1920179404Sobrien{
1921179404Sobrien  if (reloc_entry->howto->partial_inplace)
1922179404Sobrien    {
1923179404Sobrien      reloc_entry->addend = ((reloc_entry->addend & 0x00007c0)
1924179404Sobrien			     | (reloc_entry->addend & 0x00000800) >> 9);
1925179404Sobrien    }
1926179404Sobrien
1927179404Sobrien  return _bfd_mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
1928179404Sobrien				      input_section, output_bfd,
1929179404Sobrien				      error_message);
1930179404Sobrien}
1931179404Sobrien
1932179404Sobrien/* Handle a mips16 GP relative reloc.  */
1933179404Sobrien
1934179404Sobrienstatic bfd_reloc_status_type
1935179404Sobrienmips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1936179404Sobrien		    void *data, asection *input_section, bfd *output_bfd,
1937179404Sobrien		    char **error_message)
1938179404Sobrien{
1939179404Sobrien  bfd_boolean relocatable;
1940179404Sobrien  bfd_reloc_status_type ret;
1941218822Sdim  bfd_byte *location;
1942179404Sobrien  bfd_vma gp;
1943179404Sobrien
1944218822Sdim  /* If we're relocating, and this is an external symbol, we don't want
1945218822Sdim     to change anything.  */
1946218822Sdim  if (output_bfd != NULL
1947218822Sdim      && (symbol->flags & BSF_SECTION_SYM) == 0
1948218822Sdim      && (symbol->flags & BSF_LOCAL) != 0)
1949218822Sdim    {
1950218822Sdim      reloc_entry->address += input_section->output_offset;
1951218822Sdim      return bfd_reloc_ok;
1952218822Sdim    }
1953218822Sdim
1954179404Sobrien  if (output_bfd != NULL)
1955179404Sobrien    relocatable = TRUE;
1956179404Sobrien  else
1957179404Sobrien    {
1958179404Sobrien      relocatable = FALSE;
1959179404Sobrien      output_bfd = symbol->section->output_section->owner;
1960179404Sobrien    }
1961179404Sobrien
1962179404Sobrien  ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
1963179404Sobrien			   &gp);
1964179404Sobrien  if (ret != bfd_reloc_ok)
1965179404Sobrien    return ret;
1966179404Sobrien
1967218822Sdim  location = (bfd_byte *) data + reloc_entry->address;
1968218822Sdim  _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
1969218822Sdim				   location);
1970218822Sdim  ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1971218822Sdim				       input_section, relocatable,
1972218822Sdim				       data, gp);
1973218822Sdim  _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
1974218822Sdim				 location);
1975179404Sobrien
1976218822Sdim  return ret;
1977179404Sobrien}
1978179404Sobrien
1979179404Sobrien/* A mapping from BFD reloc types to MIPS ELF reloc types.  */
1980179404Sobrien
1981179404Sobrienstruct elf_reloc_map {
1982179404Sobrien  bfd_reloc_code_real_type bfd_val;
1983179404Sobrien  enum elf_mips_reloc_type elf_val;
1984179404Sobrien};
1985179404Sobrien
1986179404Sobrienstatic const struct elf_reloc_map mips_reloc_map[] =
1987179404Sobrien{
1988179404Sobrien  { BFD_RELOC_NONE, R_MIPS_NONE },
1989179404Sobrien  { BFD_RELOC_16, R_MIPS_16 },
1990179404Sobrien  { BFD_RELOC_32, R_MIPS_32 },
1991179404Sobrien  /* There is no BFD reloc for R_MIPS_REL32.  */
1992179404Sobrien  { BFD_RELOC_CTOR, R_MIPS_32 },
1993179404Sobrien  { BFD_RELOC_64, R_MIPS_64 },
1994218822Sdim  { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
1995179404Sobrien  { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1996179404Sobrien  { BFD_RELOC_LO16, R_MIPS_LO16 },
1997179404Sobrien  { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
1998179404Sobrien  { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
1999179404Sobrien  { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
2000179404Sobrien  { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
2001179404Sobrien  { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
2002179404Sobrien  { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
2003179404Sobrien  { BFD_RELOC_MIPS_SHIFT5, R_MIPS_SHIFT5 },
2004179404Sobrien  { BFD_RELOC_MIPS_SHIFT6, R_MIPS_SHIFT6 },
2005179404Sobrien  { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
2006179404Sobrien  { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
2007179404Sobrien  { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
2008179404Sobrien  { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
2009179404Sobrien  { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
2010179404Sobrien  { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
2011179404Sobrien  { BFD_RELOC_MIPS_INSERT_A, R_MIPS_INSERT_A },
2012179404Sobrien  { BFD_RELOC_MIPS_INSERT_B, R_MIPS_INSERT_B },
2013179404Sobrien  { BFD_RELOC_MIPS_DELETE, R_MIPS_DELETE },
2014179404Sobrien  { BFD_RELOC_MIPS_HIGHEST, R_MIPS_HIGHEST },
2015179404Sobrien  { BFD_RELOC_MIPS_HIGHER, R_MIPS_HIGHER },
2016179404Sobrien  { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
2017179404Sobrien  { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
2018179404Sobrien  { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
2019179404Sobrien  { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
2020179404Sobrien  /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated.  */
2021179404Sobrien  { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
2022218822Sdim  { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
2023218822Sdim  { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
2024218822Sdim  { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
2025218822Sdim  { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
2026218822Sdim  { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
2027218822Sdim  { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
2028218822Sdim  { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
2029218822Sdim  { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
2030218822Sdim  { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
2031218822Sdim  { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
2032218822Sdim  { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
2033218822Sdim  { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
2034218822Sdim  { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
2035218822Sdim  { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
2036179404Sobrien};
2037179404Sobrien
2038218822Sdimstatic const struct elf_reloc_map mips16_reloc_map[] =
2039218822Sdim{
2040218822Sdim  { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
2041218822Sdim  { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
2042218822Sdim  { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
2043218822Sdim  { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
2044218822Sdim};
2045218822Sdim
2046179404Sobrien/* Given a BFD reloc type, return a howto structure.  */
2047179404Sobrien
2048179404Sobrienstatic reloc_howto_type *
2049179404Sobrienbfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
2050179404Sobrien				 bfd_reloc_code_real_type code)
2051179404Sobrien{
2052179404Sobrien  unsigned int i;
2053179404Sobrien  /* FIXME: We default to RELA here instead of choosing the right
2054179404Sobrien     relocation variant.  */
2055179404Sobrien  reloc_howto_type *howto_table = elf_mips_howto_table_rela;
2056218822Sdim  reloc_howto_type *howto16_table = elf_mips16_howto_table_rela;
2057179404Sobrien
2058179404Sobrien  for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
2059179404Sobrien       i++)
2060179404Sobrien    {
2061179404Sobrien      if (mips_reloc_map[i].bfd_val == code)
2062179404Sobrien	return &howto_table[(int) mips_reloc_map[i].elf_val];
2063179404Sobrien    }
2064179404Sobrien
2065218822Sdim  for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
2066218822Sdim       i++)
2067218822Sdim    {
2068218822Sdim      if (mips16_reloc_map[i].bfd_val == code)
2069218822Sdim	return &howto16_table[(int) mips16_reloc_map[i].elf_val];
2070218822Sdim    }
2071218822Sdim
2072179404Sobrien  switch (code)
2073179404Sobrien    {
2074179404Sobrien    case BFD_RELOC_VTABLE_INHERIT:
2075179404Sobrien      return &elf_mips_gnu_vtinherit_howto;
2076179404Sobrien    case BFD_RELOC_VTABLE_ENTRY:
2077179404Sobrien      return &elf_mips_gnu_vtentry_howto;
2078179404Sobrien    default:
2079179404Sobrien      bfd_set_error (bfd_error_bad_value);
2080179404Sobrien      return NULL;
2081179404Sobrien    }
2082179404Sobrien}
2083179404Sobrien
2084218822Sdimstatic reloc_howto_type *
2085218822Sdimbfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
2086218822Sdim				 const char *r_name)
2087218822Sdim{
2088218822Sdim  unsigned int i;
2089218822Sdim
2090218822Sdim  for (i = 0;
2091218822Sdim       i < (sizeof (elf_mips_howto_table_rela)
2092218822Sdim	    / sizeof (elf_mips_howto_table_rela[0]));
2093218822Sdim       i++)
2094218822Sdim    if (elf_mips_howto_table_rela[i].name != NULL
2095218822Sdim	&& strcasecmp (elf_mips_howto_table_rela[i].name, r_name) == 0)
2096218822Sdim      return &elf_mips_howto_table_rela[i];
2097218822Sdim
2098218822Sdim  for (i = 0;
2099218822Sdim       i < (sizeof (elf_mips16_howto_table_rela)
2100218822Sdim	    / sizeof (elf_mips16_howto_table_rela[0]));
2101218822Sdim       i++)
2102218822Sdim    if (elf_mips16_howto_table_rela[i].name != NULL
2103218822Sdim	&& strcasecmp (elf_mips16_howto_table_rela[i].name, r_name) == 0)
2104218822Sdim      return &elf_mips16_howto_table_rela[i];
2105218822Sdim
2106218822Sdim  if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
2107218822Sdim    return &elf_mips_gnu_vtinherit_howto;
2108218822Sdim  if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
2109218822Sdim    return &elf_mips_gnu_vtentry_howto;
2110218822Sdim  if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
2111218822Sdim    return &elf_mips_gnu_rel16_s2;
2112218822Sdim  if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0)
2113218822Sdim    return &elf_mips_gnu_rela16_s2;
2114218822Sdim
2115218822Sdim  return NULL;
2116218822Sdim}
2117218822Sdim
2118179404Sobrien/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
2119179404Sobrien
2120179404Sobrienstatic reloc_howto_type *
2121179404Sobrienmips_elf_n32_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
2122179404Sobrien{
2123179404Sobrien  switch (r_type)
2124179404Sobrien    {
2125179404Sobrien    case R_MIPS_GNU_VTINHERIT:
2126179404Sobrien      return &elf_mips_gnu_vtinherit_howto;
2127179404Sobrien    case R_MIPS_GNU_VTENTRY:
2128179404Sobrien      return &elf_mips_gnu_vtentry_howto;
2129179404Sobrien    case R_MIPS_GNU_REL16_S2:
2130179404Sobrien      if (rela_p)
2131179404Sobrien	return &elf_mips_gnu_rela16_s2;
2132179404Sobrien      else
2133179404Sobrien	return &elf_mips_gnu_rel16_s2;
2134179404Sobrien    default:
2135218822Sdim      if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
2136218822Sdim	{
2137218822Sdim	  if (rela_p)
2138218822Sdim	    return &elf_mips16_howto_table_rela[r_type - R_MIPS16_min];
2139218822Sdim	  else
2140218822Sdim	    return &elf_mips16_howto_table_rel[r_type - R_MIPS16_min];
2141218822Sdim	}
2142179404Sobrien      BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
2143179404Sobrien      if (rela_p)
2144179404Sobrien	return &elf_mips_howto_table_rela[r_type];
2145179404Sobrien      else
2146179404Sobrien	return &elf_mips_howto_table_rel[r_type];
2147179404Sobrien      break;
2148179404Sobrien    }
2149179404Sobrien}
2150179404Sobrien
2151179404Sobrien/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
2152179404Sobrien
2153179404Sobrienstatic void
2154179404Sobrienmips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
2155179404Sobrien{
2156179404Sobrien  unsigned int r_type;
2157179404Sobrien
2158179404Sobrien  r_type = ELF32_R_TYPE (dst->r_info);
2159179404Sobrien  cache_ptr->howto = mips_elf_n32_rtype_to_howto (r_type, FALSE);
2160179404Sobrien
2161179404Sobrien  /* The addend for a GPREL16 or LITERAL relocation comes from the GP
2162179404Sobrien     value for the object file.  We get the addend now, rather than
2163179404Sobrien     when we do the relocation, because the symbol manipulations done
2164179404Sobrien     by the linker may cause us to lose track of the input BFD.  */
2165179404Sobrien  if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
2166179404Sobrien      && (r_type == (unsigned int) R_MIPS_GPREL16
2167179404Sobrien	  || r_type == (unsigned int) R_MIPS_LITERAL))
2168179404Sobrien    cache_ptr->addend = elf_gp (abfd);
2169179404Sobrien}
2170179404Sobrien
2171179404Sobrien/* Given a MIPS Elf_Internal_Rela, fill in an arelent structure.  */
2172179404Sobrien
2173179404Sobrienstatic void
2174179404Sobrienmips_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
2175179404Sobrien			 arelent *cache_ptr, Elf_Internal_Rela *dst)
2176179404Sobrien{
2177179404Sobrien  unsigned int r_type;
2178179404Sobrien
2179179404Sobrien  r_type = ELF32_R_TYPE (dst->r_info);
2180179404Sobrien  cache_ptr->howto = mips_elf_n32_rtype_to_howto (r_type, TRUE);
2181179404Sobrien  cache_ptr->addend = dst->r_addend;
2182179404Sobrien}
2183179404Sobrien
2184179404Sobrien/* Determine whether a symbol is global for the purposes of splitting
2185179404Sobrien   the symbol table into global symbols and local symbols.  At least
2186179404Sobrien   on Irix 5, this split must be between section symbols and all other
2187179404Sobrien   symbols.  On most ELF targets the split is between static symbols
2188179404Sobrien   and externally visible symbols.  */
2189179404Sobrien
2190179404Sobrienstatic bfd_boolean
2191179404Sobrienmips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
2192179404Sobrien{
2193179404Sobrien  if (SGI_COMPAT (abfd))
2194179404Sobrien    return (sym->flags & BSF_SECTION_SYM) == 0;
2195179404Sobrien  else
2196179404Sobrien    return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
2197179404Sobrien	    || bfd_is_und_section (bfd_get_section (sym))
2198179404Sobrien	    || bfd_is_com_section (bfd_get_section (sym)));
2199179404Sobrien}
2200179404Sobrien
2201179404Sobrien/* Set the right machine number for a MIPS ELF file.  */
2202179404Sobrien
2203179404Sobrienstatic bfd_boolean
2204179404Sobrienmips_elf_n32_object_p (bfd *abfd)
2205179404Sobrien{
2206179404Sobrien  unsigned long mach;
2207179404Sobrien
2208179404Sobrien  /* Irix 5 and 6 are broken.  Object file symbol tables are not always
2209179404Sobrien     sorted correctly such that local symbols precede global symbols,
2210179404Sobrien     and the sh_info field in the symbol table is not always right.  */
2211179404Sobrien  if (SGI_COMPAT (abfd))
2212179404Sobrien    elf_bad_symtab (abfd) = TRUE;
2213179404Sobrien
2214179404Sobrien  mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
2215179404Sobrien  bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
2216179404Sobrien
2217179404Sobrien  if (! ABI_N32_P(abfd))
2218179404Sobrien    return FALSE;
2219179404Sobrien
2220179404Sobrien  return TRUE;
2221179404Sobrien}
2222179404Sobrien
2223179404Sobrien/* Support for core dump NOTE sections.  */
2224179404Sobrienstatic bfd_boolean
2225179404Sobrienelf32_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
2226179404Sobrien{
2227179404Sobrien  int offset;
2228218822Sdim  unsigned int size;
2229179404Sobrien
2230179404Sobrien  switch (note->descsz)
2231179404Sobrien    {
2232179404Sobrien      default:
2233179404Sobrien	return FALSE;
2234179404Sobrien
2235179404Sobrien      case 440:		/* Linux/MIPS N32 */
2236179404Sobrien	/* pr_cursig */
2237179404Sobrien	elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
2238179404Sobrien
2239179404Sobrien	/* pr_pid */
2240179404Sobrien	elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
2241179404Sobrien
2242179404Sobrien	/* pr_reg */
2243179404Sobrien	offset = 72;
2244218822Sdim	size = 360;
2245179404Sobrien
2246179404Sobrien	break;
2247179404Sobrien    }
2248179404Sobrien
2249179404Sobrien  /* Make a ".reg/999" section.  */
2250218822Sdim  return _bfd_elfcore_make_pseudosection (abfd, ".reg", size,
2251179404Sobrien					  note->descpos + offset);
2252179404Sobrien}
2253179404Sobrien
2254179404Sobrienstatic bfd_boolean
2255179404Sobrienelf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
2256179404Sobrien{
2257179404Sobrien  switch (note->descsz)
2258179404Sobrien    {
2259179404Sobrien      default:
2260179404Sobrien	return FALSE;
2261179404Sobrien
2262179404Sobrien      case 128:		/* Linux/MIPS elf_prpsinfo */
2263179404Sobrien	elf_tdata (abfd)->core_program
2264179404Sobrien	 = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
2265179404Sobrien	elf_tdata (abfd)->core_command
2266179404Sobrien	 = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
2267179404Sobrien    }
2268179404Sobrien
2269179404Sobrien  /* Note that for some reason, a spurious space is tacked
2270179404Sobrien     onto the end of the args in some (at least one anyway)
2271179404Sobrien     implementations, so strip it off if it exists.  */
2272179404Sobrien
2273179404Sobrien  {
2274179404Sobrien    char *command = elf_tdata (abfd)->core_command;
2275179404Sobrien    int n = strlen (command);
2276179404Sobrien
2277179404Sobrien    if (0 < n && command[n - 1] == ' ')
2278179404Sobrien      command[n - 1] = '\0';
2279179404Sobrien  }
2280179404Sobrien
2281179404Sobrien  return TRUE;
2282179404Sobrien}
2283179404Sobrien
2284179404Sobrien/* Depending on the target vector we generate some version of Irix
2285179404Sobrien   executables or "normal" MIPS ELF ABI executables.  */
2286179404Sobrienstatic irix_compat_t
2287179404Sobrienelf_n32_mips_irix_compat (bfd *abfd)
2288179404Sobrien{
2289179404Sobrien  if ((abfd->xvec == &bfd_elf32_nbigmips_vec)
2290179404Sobrien      || (abfd->xvec == &bfd_elf32_nlittlemips_vec))
2291179404Sobrien    return ict_irix6;
2292179404Sobrien  else
2293179404Sobrien    return ict_none;
2294179404Sobrien}
2295179404Sobrien
2296179404Sobrien/* ECOFF swapping routines.  These are used when dealing with the
2297179404Sobrien   .mdebug section, which is in the ECOFF debugging format.  */
2298179404Sobrienstatic const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
2299179404Sobrien  /* Symbol table magic number.  */
2300179404Sobrien  magicSym,
2301179404Sobrien  /* Alignment of debugging information.  E.g., 4.  */
2302179404Sobrien  4,
2303179404Sobrien  /* Sizes of external symbolic information.  */
2304179404Sobrien  sizeof (struct hdr_ext),
2305179404Sobrien  sizeof (struct dnr_ext),
2306179404Sobrien  sizeof (struct pdr_ext),
2307179404Sobrien  sizeof (struct sym_ext),
2308179404Sobrien  sizeof (struct opt_ext),
2309179404Sobrien  sizeof (struct fdr_ext),
2310179404Sobrien  sizeof (struct rfd_ext),
2311179404Sobrien  sizeof (struct ext_ext),
2312179404Sobrien  /* Functions to swap in external symbolic data.  */
2313179404Sobrien  ecoff_swap_hdr_in,
2314179404Sobrien  ecoff_swap_dnr_in,
2315179404Sobrien  ecoff_swap_pdr_in,
2316179404Sobrien  ecoff_swap_sym_in,
2317179404Sobrien  ecoff_swap_opt_in,
2318179404Sobrien  ecoff_swap_fdr_in,
2319179404Sobrien  ecoff_swap_rfd_in,
2320179404Sobrien  ecoff_swap_ext_in,
2321179404Sobrien  _bfd_ecoff_swap_tir_in,
2322179404Sobrien  _bfd_ecoff_swap_rndx_in,
2323179404Sobrien  /* Functions to swap out external symbolic data.  */
2324179404Sobrien  ecoff_swap_hdr_out,
2325179404Sobrien  ecoff_swap_dnr_out,
2326179404Sobrien  ecoff_swap_pdr_out,
2327179404Sobrien  ecoff_swap_sym_out,
2328179404Sobrien  ecoff_swap_opt_out,
2329179404Sobrien  ecoff_swap_fdr_out,
2330179404Sobrien  ecoff_swap_rfd_out,
2331179404Sobrien  ecoff_swap_ext_out,
2332179404Sobrien  _bfd_ecoff_swap_tir_out,
2333179404Sobrien  _bfd_ecoff_swap_rndx_out,
2334179404Sobrien  /* Function to read in symbolic data.  */
2335179404Sobrien  _bfd_mips_elf_read_ecoff_info
2336179404Sobrien};
2337179404Sobrien
2338179404Sobrien#define ELF_ARCH			bfd_arch_mips
2339179404Sobrien#define ELF_MACHINE_CODE		EM_MIPS
2340179404Sobrien
2341179404Sobrien#define elf_backend_collect		TRUE
2342179404Sobrien#define elf_backend_type_change_ok	TRUE
2343179404Sobrien#define elf_backend_can_gc_sections	TRUE
2344179404Sobrien#define elf_info_to_howto		mips_info_to_howto_rela
2345179404Sobrien#define elf_info_to_howto_rel		mips_info_to_howto_rel
2346179404Sobrien#define elf_backend_sym_is_global	mips_elf_sym_is_global
2347179404Sobrien#define elf_backend_object_p		mips_elf_n32_object_p
2348179404Sobrien#define elf_backend_symbol_processing	_bfd_mips_elf_symbol_processing
2349179404Sobrien#define elf_backend_section_processing	_bfd_mips_elf_section_processing
2350179404Sobrien#define elf_backend_section_from_shdr	_bfd_mips_elf_section_from_shdr
2351179404Sobrien#define elf_backend_fake_sections	_bfd_mips_elf_fake_sections
2352179404Sobrien#define elf_backend_section_from_bfd_section \
2353179404Sobrien					_bfd_mips_elf_section_from_bfd_section
2354179404Sobrien#define elf_backend_add_symbol_hook	_bfd_mips_elf_add_symbol_hook
2355179404Sobrien#define elf_backend_link_output_symbol_hook \
2356179404Sobrien					_bfd_mips_elf_link_output_symbol_hook
2357179404Sobrien#define elf_backend_create_dynamic_sections \
2358179404Sobrien					_bfd_mips_elf_create_dynamic_sections
2359179404Sobrien#define elf_backend_check_relocs	_bfd_mips_elf_check_relocs
2360218822Sdim#define elf_backend_merge_symbol_attribute \
2361218822Sdim					_bfd_mips_elf_merge_symbol_attribute
2362179404Sobrien#define elf_backend_adjust_dynamic_symbol \
2363179404Sobrien					_bfd_mips_elf_adjust_dynamic_symbol
2364179404Sobrien#define elf_backend_always_size_sections \
2365179404Sobrien					_bfd_mips_elf_always_size_sections
2366179404Sobrien#define elf_backend_size_dynamic_sections \
2367179404Sobrien					_bfd_mips_elf_size_dynamic_sections
2368218822Sdim#define elf_backend_init_index_section	_bfd_elf_init_1_index_section
2369179404Sobrien#define elf_backend_relocate_section	_bfd_mips_elf_relocate_section
2370179404Sobrien#define elf_backend_finish_dynamic_symbol \
2371179404Sobrien					_bfd_mips_elf_finish_dynamic_symbol
2372179404Sobrien#define elf_backend_finish_dynamic_sections \
2373179404Sobrien					_bfd_mips_elf_finish_dynamic_sections
2374179404Sobrien#define elf_backend_final_write_processing \
2375179404Sobrien					_bfd_mips_elf_final_write_processing
2376179404Sobrien#define elf_backend_additional_program_headers \
2377179404Sobrien					_bfd_mips_elf_additional_program_headers
2378179404Sobrien#define elf_backend_modify_segment_map	_bfd_mips_elf_modify_segment_map
2379179404Sobrien#define elf_backend_gc_mark_hook	_bfd_mips_elf_gc_mark_hook
2380179404Sobrien#define elf_backend_gc_sweep_hook	_bfd_mips_elf_gc_sweep_hook
2381179404Sobrien#define elf_backend_copy_indirect_symbol \
2382179404Sobrien					_bfd_mips_elf_copy_indirect_symbol
2383179404Sobrien#define elf_backend_hide_symbol		_bfd_mips_elf_hide_symbol
2384179404Sobrien#define elf_backend_grok_prstatus	elf32_mips_grok_prstatus
2385179404Sobrien#define elf_backend_grok_psinfo		elf32_mips_grok_psinfo
2386179404Sobrien#define elf_backend_ecoff_debug_swap	&mips_elf32_ecoff_debug_swap
2387179404Sobrien
2388179404Sobrien#define elf_backend_got_header_size	(4 * MIPS_RESERVED_GOTNO)
2389179404Sobrien
2390179404Sobrien/* MIPS n32 ELF can use a mixture of REL and RELA, but some Relocations
2391179404Sobrien   work better/work only in RELA, so we default to this.  */
2392179404Sobrien#define elf_backend_may_use_rel_p	1
2393179404Sobrien#define elf_backend_may_use_rela_p	1
2394179404Sobrien#define elf_backend_default_use_rela_p	1
2395179404Sobrien#define elf_backend_sign_extend_vma	TRUE
2396179404Sobrien
2397179404Sobrien#define elf_backend_discard_info	_bfd_mips_elf_discard_info
2398179404Sobrien#define elf_backend_ignore_discarded_relocs \
2399179404Sobrien					_bfd_mips_elf_ignore_discarded_relocs
2400179404Sobrien#define elf_backend_write_section	_bfd_mips_elf_write_section
2401179404Sobrien#define elf_backend_mips_irix_compat	elf_n32_mips_irix_compat
2402179404Sobrien#define elf_backend_mips_rtype_to_howto	mips_elf_n32_rtype_to_howto
2403179404Sobrien#define bfd_elf32_find_nearest_line	_bfd_mips_elf_find_nearest_line
2404218822Sdim#define bfd_elf32_find_inliner_info	_bfd_mips_elf_find_inliner_info
2405179404Sobrien#define bfd_elf32_new_section_hook	_bfd_mips_elf_new_section_hook
2406179404Sobrien#define bfd_elf32_set_section_contents	_bfd_mips_elf_set_section_contents
2407179404Sobrien#define bfd_elf32_bfd_get_relocated_section_contents \
2408179404Sobrien				_bfd_elf_mips_get_relocated_section_contents
2409179404Sobrien#define bfd_elf32_bfd_link_hash_table_create \
2410179404Sobrien					_bfd_mips_elf_link_hash_table_create
2411179404Sobrien#define bfd_elf32_bfd_final_link	_bfd_mips_elf_final_link
2412179404Sobrien#define bfd_elf32_bfd_merge_private_bfd_data \
2413179404Sobrien					_bfd_mips_elf_merge_private_bfd_data
2414179404Sobrien#define bfd_elf32_bfd_set_private_flags	_bfd_mips_elf_set_private_flags
2415179404Sobrien#define bfd_elf32_bfd_print_private_bfd_data \
2416179404Sobrien					_bfd_mips_elf_print_private_bfd_data
2417179404Sobrien#define bfd_elf32_bfd_relax_section     _bfd_mips_relax_section
2418179404Sobrien
2419179404Sobrien/* Support for SGI-ish mips targets using n32 ABI.  */
2420179404Sobrien
2421179404Sobrien#define TARGET_LITTLE_SYM               bfd_elf32_nlittlemips_vec
2422179404Sobrien#define TARGET_LITTLE_NAME              "elf32-nlittlemips"
2423179404Sobrien#define TARGET_BIG_SYM                  bfd_elf32_nbigmips_vec
2424179404Sobrien#define TARGET_BIG_NAME                 "elf32-nbigmips"
2425179404Sobrien
2426218822Sdim#define ELF_MAXPAGESIZE			0x10000
2427218822Sdim#define ELF_COMMONPAGESIZE		0x1000
2428179404Sobrien
2429179404Sobrien#include "elf32-target.h"
2430179404Sobrien
2431179404Sobrien/* Support for traditional mips targets using n32 ABI.  */
2432179404Sobrien#undef TARGET_LITTLE_SYM
2433179404Sobrien#undef TARGET_LITTLE_NAME
2434179404Sobrien#undef TARGET_BIG_SYM
2435179404Sobrien#undef TARGET_BIG_NAME
2436179404Sobrien
2437179404Sobrien#undef ELF_MAXPAGESIZE
2438218822Sdim#undef ELF_COMMONPAGESIZE
2439179404Sobrien
2440179404Sobrien#define TARGET_LITTLE_SYM               bfd_elf32_ntradlittlemips_vec
2441179404Sobrien#define TARGET_LITTLE_NAME              "elf32-ntradlittlemips"
2442179404Sobrien#define TARGET_BIG_SYM                  bfd_elf32_ntradbigmips_vec
2443179404Sobrien#define TARGET_BIG_NAME                 "elf32-ntradbigmips"
2444179404Sobrien
2445179404Sobrien#define ELF_MAXPAGESIZE			0x10000
2446218822Sdim#define ELF_COMMONPAGESIZE		0x1000
2447179404Sobrien#define elf32_bed			elf32_tradbed
2448179404Sobrien
2449179404Sobrien/* Include the target file again for this target.  */
2450179404Sobrien#include "elf32-target.h"
2451