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