1/* MIPS-specific support for 32-bit ELF
2   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3   2003, 2004, 2005, 2007 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
12   This file is part of BFD, the Binary File Descriptor library.
13
14   This program is free software; you can redistribute it and/or modify
15   it under the terms of the GNU General Public License as published by
16   the Free Software Foundation; either version 3 of the License, or
17   (at your option) any later version.
18
19   This program is distributed in the hope that it will be useful,
20   but WITHOUT ANY WARRANTY; without even the implied warranty of
21   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22   GNU General Public License for more details.
23
24   You should have received a copy of the GNU General Public License
25   along with this program; if not, write to the Free Software
26   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
27   MA 02110-1301, USA.  */
28
29
30/* This file handles MIPS ELF targets.  SGI Irix 5 uses a slightly
31   different MIPS ELF from other targets.  This matters when linking.
32   This file supports both, switching at runtime.  */
33
34#include "sysdep.h"
35#include "bfd.h"
36#include "libbfd.h"
37#include "bfdlink.h"
38#include "genlink.h"
39#include "elf-bfd.h"
40#include "elfxx-mips.h"
41#include "elf/mips.h"
42#include "elf-vxworks.h"
43
44/* Get the ECOFF swapping routines.  */
45#include "coff/sym.h"
46#include "coff/symconst.h"
47#include "coff/internal.h"
48#include "coff/ecoff.h"
49#include "coff/mips.h"
50#define ECOFF_SIGNED_32
51#include "ecoffswap.h"
52
53static bfd_reloc_status_type gprel32_with_gp
54  (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma);
55static bfd_reloc_status_type mips_elf_gprel32_reloc
56  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
57static bfd_reloc_status_type mips32_64bit_reloc
58  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
59static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
60  (bfd *, bfd_reloc_code_real_type);
61static reloc_howto_type *mips_elf32_rtype_to_howto
62  (unsigned int, bfd_boolean);
63static void mips_info_to_howto_rel
64  (bfd *, arelent *, Elf_Internal_Rela *);
65static void mips_info_to_howto_rela
66  (bfd *, arelent *, Elf_Internal_Rela *);
67static bfd_boolean mips_elf_sym_is_global
68  (bfd *, asymbol *);
69static bfd_boolean mips_elf32_object_p
70  (bfd *);
71static bfd_boolean mips_elf_is_local_label_name
72  (bfd *, const 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  /* 32 bit relocation with no addend.  */
707  HOWTO (R_MIPS_GLOB_DAT,	/* type */
708	 0,			/* rightshift */
709	 2,			/* size (0 = byte, 1 = short, 2 = long) */
710	 32,			/* bitsize */
711	 FALSE,			/* pc_relative */
712	 0,			/* bitpos */
713	 complain_overflow_dont, /* complain_on_overflow */
714	 _bfd_mips_elf_generic_reloc, /* special_function */
715	 "R_MIPS_GLOB_DAT",	/* name */
716	 FALSE,			/* partial_inplace */
717	 0x0,			/* src_mask */
718	 0xffffffff,		/* dst_mask */
719	 FALSE),		/* pcrel_offset */
720};
721
722/* The reloc used for BFD_RELOC_CTOR when doing a 64 bit link.  This
723   is a hack to make the linker think that we need 64 bit values.  */
724static reloc_howto_type elf_mips_ctor64_howto =
725  HOWTO (R_MIPS_64,		/* type */
726	 0,			/* rightshift */
727	 4,			/* size (0 = byte, 1 = short, 2 = long) */
728	 32,			/* bitsize */
729	 FALSE,			/* pc_relative */
730	 0,			/* bitpos */
731	 complain_overflow_signed, /* complain_on_overflow */
732	 mips32_64bit_reloc,	/* special_function */
733	 "R_MIPS_64",		/* name */
734	 TRUE,			/* partial_inplace */
735	 0xffffffff,		/* src_mask */
736	 0xffffffff,		/* dst_mask */
737	 FALSE);		/* pcrel_offset */
738
739static reloc_howto_type elf_mips16_howto_table_rel[] =
740{
741  /* The reloc used for the mips16 jump instruction.  */
742  HOWTO (R_MIPS16_26,		/* type */
743	 2,			/* rightshift */
744	 2,			/* size (0 = byte, 1 = short, 2 = long) */
745	 26,			/* bitsize */
746	 FALSE,			/* pc_relative */
747	 0,			/* bitpos */
748	 complain_overflow_dont, /* complain_on_overflow */
749	 			/* This needs complex overflow
750				   detection, because the upper four
751				   bits must match the PC.  */
752	 _bfd_mips_elf_generic_reloc, /* special_function */
753	 "R_MIPS16_26",		/* name */
754	 TRUE,			/* partial_inplace */
755	 0x3ffffff,		/* src_mask */
756	 0x3ffffff,		/* dst_mask */
757	 FALSE),		/* pcrel_offset */
758
759  /* The reloc used for the mips16 gprel instruction.  */
760  HOWTO (R_MIPS16_GPREL,	/* type */
761	 0,			/* rightshift */
762	 2,			/* size (0 = byte, 1 = short, 2 = long) */
763	 16,			/* bitsize */
764	 FALSE,			/* pc_relative */
765	 0,			/* bitpos */
766	 complain_overflow_signed, /* complain_on_overflow */
767	 mips16_gprel_reloc,	/* special_function */
768	 "R_MIPS16_GPREL",	/* name */
769	 TRUE,			/* partial_inplace */
770	 0x0000ffff,		/* src_mask */
771	 0x0000ffff,	        /* dst_mask */
772	 FALSE),		/* pcrel_offset */
773
774  /* A placeholder for MIPS16 reference to global offset table.  */
775  EMPTY_HOWTO (R_MIPS16_GOT16),
776
777  /* A placeholder for MIPS16 16 bit call through global offset table.  */
778  EMPTY_HOWTO (R_MIPS16_CALL16),
779
780  /* MIPS16 high 16 bits of symbol value.  */
781  HOWTO (R_MIPS16_HI16,		/* type */
782	 16,			/* 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_hi16_reloc, /* special_function */
789	 "R_MIPS16_HI16",	/* name */
790	 TRUE,			/* partial_inplace */
791	 0x0000ffff,		/* src_mask */
792	 0x0000ffff,	        /* dst_mask */
793	 FALSE),		/* pcrel_offset */
794
795  /* MIPS16 low 16 bits of symbol value.  */
796  HOWTO (R_MIPS16_LO16,		/* type */
797	 0,			/* rightshift */
798	 2,			/* size (0 = byte, 1 = short, 2 = long) */
799	 16,			/* bitsize */
800	 FALSE,			/* pc_relative */
801	 0,			/* bitpos */
802	 complain_overflow_dont, /* complain_on_overflow */
803	 _bfd_mips_elf_lo16_reloc, /* special_function */
804	 "R_MIPS16_LO16",	/* name */
805	 TRUE,			/* partial_inplace */
806	 0x0000ffff,		/* src_mask */
807	 0x0000ffff,	        /* dst_mask */
808	 FALSE),		/* pcrel_offset */
809};
810
811/* 16 bit offset for pc-relative branches.  */
812static reloc_howto_type elf_mips_gnu_rel16_s2 =
813  HOWTO (R_MIPS_GNU_REL16_S2,	/* type */
814	 2,			/* rightshift */
815	 2,			/* size (0 = byte, 1 = short, 2 = long) */
816	 16,			/* bitsize */
817	 TRUE,			/* pc_relative */
818	 0,			/* bitpos */
819	 complain_overflow_signed, /* complain_on_overflow */
820	 _bfd_mips_elf_generic_reloc, /* special_function */
821	 "R_MIPS_GNU_REL16_S2",	/* name */
822	 TRUE,			/* partial_inplace */
823	 0xffff,		/* src_mask */
824	 0xffff,		/* dst_mask */
825	 TRUE);			/* pcrel_offset */
826
827/* 32 bit pc-relative.  This was a GNU extension used by embedded-PIC.
828   It was co-opted by mips-linux for exception-handling data.  It is no
829   longer used, but should continue to be supported by the linker for
830   backward compatibility.  (GCC stopped using it in May, 2004.)  */
831static reloc_howto_type elf_mips_gnu_pcrel32 =
832  HOWTO (R_MIPS_PC32,		/* type */
833	 0,			/* rightshift */
834	 2,			/* size (0 = byte, 1 = short, 2 = long) */
835	 32,			/* bitsize */
836	 TRUE,			/* pc_relative */
837	 0,			/* bitpos */
838	 complain_overflow_signed, /* complain_on_overflow */
839	 _bfd_mips_elf_generic_reloc, /* special_function */
840	 "R_MIPS_PC32",		/* name */
841	 TRUE,			/* partial_inplace */
842	 0xffffffff,		/* src_mask */
843	 0xffffffff,		/* dst_mask */
844	 TRUE);			/* pcrel_offset */
845
846/* GNU extension to record C++ vtable hierarchy */
847static reloc_howto_type elf_mips_gnu_vtinherit_howto =
848  HOWTO (R_MIPS_GNU_VTINHERIT,	/* type */
849	 0,			/* rightshift */
850	 2,			/* size (0 = byte, 1 = short, 2 = long) */
851	 0,			/* bitsize */
852	 FALSE,			/* pc_relative */
853	 0,			/* bitpos */
854	 complain_overflow_dont, /* complain_on_overflow */
855	 NULL,			/* special_function */
856	 "R_MIPS_GNU_VTINHERIT", /* name */
857	 FALSE,			/* partial_inplace */
858	 0,			/* src_mask */
859	 0,			/* dst_mask */
860	 FALSE);		/* pcrel_offset */
861
862/* GNU extension to record C++ vtable member usage */
863static reloc_howto_type elf_mips_gnu_vtentry_howto =
864  HOWTO (R_MIPS_GNU_VTENTRY,	/* type */
865	 0,			/* rightshift */
866	 2,			/* size (0 = byte, 1 = short, 2 = long) */
867	 0,			/* bitsize */
868	 FALSE,			/* pc_relative */
869	 0,			/* bitpos */
870	 complain_overflow_dont, /* complain_on_overflow */
871	 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
872	 "R_MIPS_GNU_VTENTRY",	/* name */
873	 FALSE,			/* partial_inplace */
874	 0,			/* src_mask */
875	 0,			/* dst_mask */
876	 FALSE);		/* pcrel_offset */
877
878/* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
879   dangerous relocation.  */
880
881static bfd_boolean
882mips_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp)
883{
884  unsigned int count;
885  asymbol **sym;
886  unsigned int i;
887
888  /* If we've already figured out what GP will be, just return it.  */
889  *pgp = _bfd_get_gp_value (output_bfd);
890  if (*pgp)
891    return TRUE;
892
893  count = bfd_get_symcount (output_bfd);
894  sym = bfd_get_outsymbols (output_bfd);
895
896  /* The linker script will have created a symbol named `_gp' with the
897     appropriate value.  */
898  if (sym == NULL)
899    i = count;
900  else
901    {
902      for (i = 0; i < count; i++, sym++)
903	{
904	  register const char *name;
905
906	  name = bfd_asymbol_name (*sym);
907	  if (*name == '_' && strcmp (name, "_gp") == 0)
908	    {
909	      *pgp = bfd_asymbol_value (*sym);
910	      _bfd_set_gp_value (output_bfd, *pgp);
911	      break;
912	    }
913	}
914    }
915
916  if (i >= count)
917    {
918      /* Only get the error once.  */
919      *pgp = 4;
920      _bfd_set_gp_value (output_bfd, *pgp);
921      return FALSE;
922    }
923
924  return TRUE;
925}
926
927/* We have to figure out the gp value, so that we can adjust the
928   symbol value correctly.  We look up the symbol _gp in the output
929   BFD.  If we can't find it, we're stuck.  We cache it in the ELF
930   target data.  We don't need to adjust the symbol value for an
931   external symbol if we are producing relocatable output.  */
932
933static bfd_reloc_status_type
934mips_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable,
935		   char **error_message, bfd_vma *pgp)
936{
937  if (bfd_is_und_section (symbol->section)
938      && ! relocatable)
939    {
940      *pgp = 0;
941      return bfd_reloc_undefined;
942    }
943
944  *pgp = _bfd_get_gp_value (output_bfd);
945  if (*pgp == 0
946      && (! relocatable
947	  || (symbol->flags & BSF_SECTION_SYM) != 0))
948    {
949      if (relocatable)
950	{
951	  /* Make up a value.  */
952	  *pgp = symbol->section->output_section->vma + 0x4000;
953	  _bfd_set_gp_value (output_bfd, *pgp);
954	}
955      else if (!mips_elf_assign_gp (output_bfd, pgp))
956	{
957	  *error_message =
958	    (char *) _("GP relative relocation when _gp not defined");
959	  return bfd_reloc_dangerous;
960	}
961    }
962
963  return bfd_reloc_ok;
964}
965
966/* Do a R_MIPS_GPREL16 relocation.  This is a 16 bit value which must
967   become the offset from the gp register.  This function also handles
968   R_MIPS_LITERAL relocations, although those can be handled more
969   cleverly because the entries in the .lit8 and .lit4 sections can be
970   merged.  */
971
972bfd_reloc_status_type
973_bfd_mips_elf32_gprel16_reloc (bfd *abfd, arelent *reloc_entry,
974			       asymbol *symbol, void *data,
975			       asection *input_section, bfd *output_bfd,
976			       char **error_message)
977{
978  bfd_boolean relocatable;
979  bfd_reloc_status_type ret;
980  bfd_vma gp;
981
982  /* R_MIPS_LITERAL relocations are defined for local symbols only.  */
983  if (reloc_entry->howto->type == R_MIPS_LITERAL
984      && output_bfd != NULL
985      && (symbol->flags & BSF_SECTION_SYM) == 0
986      && (symbol->flags & BSF_LOCAL) != 0)
987    {
988      *error_message = (char *)
989	_("literal relocation occurs for an external symbol");
990      return bfd_reloc_outofrange;
991    }
992
993  if (output_bfd != NULL)
994    relocatable = TRUE;
995  else
996    {
997      relocatable = FALSE;
998      output_bfd = symbol->section->output_section->owner;
999    }
1000
1001  ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
1002			   &gp);
1003  if (ret != bfd_reloc_ok)
1004    return ret;
1005
1006  return _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1007					input_section, relocatable,
1008					data, gp);
1009}
1010
1011/* Do a R_MIPS_GPREL32 relocation.  This is a 32 bit value which must
1012   become the offset from the gp register.  */
1013
1014static bfd_reloc_status_type
1015mips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1016			void *data, asection *input_section, bfd *output_bfd,
1017			char **error_message)
1018{
1019  bfd_boolean relocatable;
1020  bfd_reloc_status_type ret;
1021  bfd_vma gp;
1022
1023  /* R_MIPS_GPREL32 relocations are defined for local symbols only.  */
1024  if (output_bfd != NULL
1025      && (symbol->flags & BSF_SECTION_SYM) == 0
1026      && (symbol->flags & BSF_LOCAL) != 0)
1027    {
1028      *error_message = (char *)
1029	_("32bits gp relative relocation occurs for an external symbol");
1030      return bfd_reloc_outofrange;
1031    }
1032
1033  if (output_bfd != NULL)
1034    relocatable = TRUE;
1035  else
1036    {
1037      relocatable = FALSE;
1038      output_bfd = symbol->section->output_section->owner;
1039    }
1040
1041  ret = mips_elf_final_gp (output_bfd, symbol, relocatable,
1042			   error_message, &gp);
1043  if (ret != bfd_reloc_ok)
1044    return ret;
1045
1046  return gprel32_with_gp (abfd, symbol, reloc_entry, input_section,
1047			  relocatable, data, gp);
1048}
1049
1050static bfd_reloc_status_type
1051gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
1052		 asection *input_section, bfd_boolean relocatable,
1053		 void *data, bfd_vma gp)
1054{
1055  bfd_vma relocation;
1056  bfd_vma val;
1057
1058  if (bfd_is_com_section (symbol->section))
1059    relocation = 0;
1060  else
1061    relocation = symbol->value;
1062
1063  relocation += symbol->section->output_section->vma;
1064  relocation += symbol->section->output_offset;
1065
1066  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
1067    return bfd_reloc_outofrange;
1068
1069  /* Set val to the offset into the section or symbol.  */
1070  val = reloc_entry->addend;
1071
1072  if (reloc_entry->howto->partial_inplace)
1073    val += bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
1074
1075  /* Adjust val for the final section location and GP value.  If we
1076     are producing relocatable output, we don't want to do this for
1077     an external symbol.  */
1078  if (! relocatable
1079      || (symbol->flags & BSF_SECTION_SYM) != 0)
1080    val += relocation - gp;
1081
1082  if (reloc_entry->howto->partial_inplace)
1083    bfd_put_32 (abfd, val, (bfd_byte *) data + reloc_entry->address);
1084  else
1085    reloc_entry->addend = val;
1086
1087  if (relocatable)
1088    reloc_entry->address += input_section->output_offset;
1089
1090  return bfd_reloc_ok;
1091}
1092
1093/* Handle a 64 bit reloc in a 32 bit MIPS ELF file.  These are
1094   generated when addresses are 64 bits.  The upper 32 bits are a simple
1095   sign extension.  */
1096
1097static bfd_reloc_status_type
1098mips32_64bit_reloc (bfd *abfd, arelent *reloc_entry,
1099		    asymbol *symbol ATTRIBUTE_UNUSED,
1100		    void *data, asection *input_section,
1101		    bfd *output_bfd, char **error_message)
1102{
1103  bfd_reloc_status_type r;
1104  arelent reloc32;
1105  unsigned long val;
1106  bfd_size_type addr;
1107
1108  /* Do a normal 32 bit relocation on the lower 32 bits.  */
1109  reloc32 = *reloc_entry;
1110  if (bfd_big_endian (abfd))
1111    reloc32.address += 4;
1112  reloc32.howto = &elf_mips_howto_table_rel[R_MIPS_32];
1113  r = bfd_perform_relocation (abfd, &reloc32, data, input_section,
1114			      output_bfd, error_message);
1115
1116  /* Sign extend into the upper 32 bits.  */
1117  val = bfd_get_32 (abfd, (bfd_byte *) data + reloc32.address);
1118  if ((val & 0x80000000) != 0)
1119    val = 0xffffffff;
1120  else
1121    val = 0;
1122  addr = reloc_entry->address;
1123  if (bfd_little_endian (abfd))
1124    addr += 4;
1125  bfd_put_32 (abfd, val, (bfd_byte *) data + addr);
1126
1127  return r;
1128}
1129
1130/* Handle a mips16 GP relative reloc.  */
1131
1132static bfd_reloc_status_type
1133mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
1134		    void *data, asection *input_section, bfd *output_bfd,
1135		    char **error_message)
1136{
1137  bfd_boolean relocatable;
1138  bfd_reloc_status_type ret;
1139  bfd_byte *location;
1140  bfd_vma gp;
1141
1142  /* If we're relocating, and this is an external symbol, we don't want
1143     to change anything.  */
1144  if (output_bfd != NULL
1145      && (symbol->flags & BSF_SECTION_SYM) == 0
1146      && (symbol->flags & BSF_LOCAL) != 0)
1147    {
1148      reloc_entry->address += input_section->output_offset;
1149      return bfd_reloc_ok;
1150    }
1151
1152  if (output_bfd != NULL)
1153    relocatable = TRUE;
1154  else
1155    {
1156      relocatable = FALSE;
1157      output_bfd = symbol->section->output_section->owner;
1158    }
1159
1160  ret = mips_elf_final_gp (output_bfd, symbol, relocatable, error_message,
1161			   &gp);
1162  if (ret != bfd_reloc_ok)
1163    return ret;
1164
1165  location = (bfd_byte *) data + reloc_entry->address;
1166  _bfd_mips16_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, FALSE,
1167				   location);
1168  ret = _bfd_mips_elf_gprel16_with_gp (abfd, symbol, reloc_entry,
1169				       input_section, relocatable,
1170				       data, gp);
1171  _bfd_mips16_elf_reloc_shuffle (abfd, reloc_entry->howto->type, !relocatable,
1172				 location);
1173
1174  return ret;
1175}
1176
1177/* A mapping from BFD reloc types to MIPS ELF reloc types.  */
1178
1179struct elf_reloc_map {
1180  bfd_reloc_code_real_type bfd_val;
1181  enum elf_mips_reloc_type elf_val;
1182};
1183
1184static const struct elf_reloc_map mips_reloc_map[] =
1185{
1186  { BFD_RELOC_NONE, R_MIPS_NONE },
1187  { BFD_RELOC_16, R_MIPS_16 },
1188  { BFD_RELOC_32, R_MIPS_32 },
1189  /* There is no BFD reloc for R_MIPS_REL32.  */
1190  { BFD_RELOC_64, R_MIPS_64 },
1191  { BFD_RELOC_MIPS_JMP, R_MIPS_26 },
1192  { BFD_RELOC_HI16_S, R_MIPS_HI16 },
1193  { BFD_RELOC_LO16, R_MIPS_LO16 },
1194  { BFD_RELOC_GPREL16, R_MIPS_GPREL16 },
1195  { BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
1196  { BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
1197  { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
1198  { BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
1199  { BFD_RELOC_GPREL32, R_MIPS_GPREL32 },
1200  { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
1201  { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
1202  { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
1203  { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
1204  { BFD_RELOC_MIPS_SUB, R_MIPS_SUB },
1205  { BFD_RELOC_MIPS_GOT_PAGE, R_MIPS_GOT_PAGE },
1206  { BFD_RELOC_MIPS_GOT_OFST, R_MIPS_GOT_OFST },
1207  { BFD_RELOC_MIPS_GOT_DISP, R_MIPS_GOT_DISP },
1208  { BFD_RELOC_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPMOD32 },
1209  { BFD_RELOC_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL32 },
1210  { BFD_RELOC_MIPS_TLS_DTPMOD64, R_MIPS_TLS_DTPMOD64 },
1211  { BFD_RELOC_MIPS_TLS_DTPREL64, R_MIPS_TLS_DTPREL64 },
1212  { BFD_RELOC_MIPS_TLS_GD, R_MIPS_TLS_GD },
1213  { BFD_RELOC_MIPS_TLS_LDM, R_MIPS_TLS_LDM },
1214  { BFD_RELOC_MIPS_TLS_DTPREL_HI16, R_MIPS_TLS_DTPREL_HI16 },
1215  { BFD_RELOC_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_DTPREL_LO16 },
1216  { BFD_RELOC_MIPS_TLS_GOTTPREL, R_MIPS_TLS_GOTTPREL },
1217  { BFD_RELOC_MIPS_TLS_TPREL32, R_MIPS_TLS_TPREL32 },
1218  { BFD_RELOC_MIPS_TLS_TPREL64, R_MIPS_TLS_TPREL64 },
1219  { BFD_RELOC_MIPS_TLS_TPREL_HI16, R_MIPS_TLS_TPREL_HI16 },
1220  { BFD_RELOC_MIPS_TLS_TPREL_LO16, R_MIPS_TLS_TPREL_LO16 }
1221};
1222
1223static const struct elf_reloc_map mips16_reloc_map[] =
1224{
1225  { BFD_RELOC_MIPS16_JMP, R_MIPS16_26 - R_MIPS16_min },
1226  { BFD_RELOC_MIPS16_GPREL, R_MIPS16_GPREL - R_MIPS16_min },
1227  { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min },
1228  { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min },
1229};
1230
1231/* Given a BFD reloc type, return a howto structure.  */
1232
1233static reloc_howto_type *
1234bfd_elf32_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
1235{
1236  unsigned int i;
1237  reloc_howto_type *howto_table = elf_mips_howto_table_rel;
1238  reloc_howto_type *howto16_table = elf_mips16_howto_table_rel;
1239
1240  for (i = 0; i < sizeof (mips_reloc_map) / sizeof (struct elf_reloc_map);
1241       i++)
1242    {
1243      if (mips_reloc_map[i].bfd_val == code)
1244	return &howto_table[(int) mips_reloc_map[i].elf_val];
1245    }
1246
1247  for (i = 0; i < sizeof (mips16_reloc_map) / sizeof (struct elf_reloc_map);
1248       i++)
1249    {
1250      if (mips16_reloc_map[i].bfd_val == code)
1251	return &howto16_table[(int) mips16_reloc_map[i].elf_val];
1252    }
1253
1254  switch (code)
1255    {
1256    default:
1257      bfd_set_error (bfd_error_bad_value);
1258      return NULL;
1259
1260    case BFD_RELOC_CTOR:
1261      /* We need to handle BFD_RELOC_CTOR specially.
1262	 Select the right relocation (R_MIPS_32 or R_MIPS_64) based on the
1263	 size of addresses of the ABI.  */
1264      if ((elf_elfheader (abfd)->e_flags & (E_MIPS_ABI_O64
1265					    | E_MIPS_ABI_EABI64)) != 0)
1266	return &elf_mips_ctor64_howto;
1267      else
1268	return &howto_table[(int) R_MIPS_32];
1269
1270    case BFD_RELOC_VTABLE_INHERIT:
1271      return &elf_mips_gnu_vtinherit_howto;
1272    case BFD_RELOC_VTABLE_ENTRY:
1273      return &elf_mips_gnu_vtentry_howto;
1274    case BFD_RELOC_32_PCREL:
1275      return &elf_mips_gnu_pcrel32;
1276    }
1277}
1278
1279static reloc_howto_type *
1280bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
1281				 const char *r_name)
1282{
1283  unsigned int i;
1284
1285  for (i = 0;
1286       i < (sizeof (elf_mips_howto_table_rel)
1287	    / sizeof (elf_mips_howto_table_rel[0]));
1288       i++)
1289    if (elf_mips_howto_table_rel[i].name != NULL
1290	&& strcasecmp (elf_mips_howto_table_rel[i].name, r_name) == 0)
1291      return &elf_mips_howto_table_rel[i];
1292
1293  for (i = 0;
1294       i < (sizeof (elf_mips16_howto_table_rel)
1295	    / sizeof (elf_mips16_howto_table_rel[0]));
1296       i++)
1297    if (elf_mips16_howto_table_rel[i].name != NULL
1298	&& strcasecmp (elf_mips16_howto_table_rel[i].name, r_name) == 0)
1299      return &elf_mips16_howto_table_rel[i];
1300
1301  if (strcasecmp (elf_mips_gnu_pcrel32.name, r_name) == 0)
1302    return &elf_mips_gnu_pcrel32;
1303  if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0)
1304    return &elf_mips_gnu_rel16_s2;
1305  if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0)
1306    return &elf_mips_gnu_vtinherit_howto;
1307  if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0)
1308    return &elf_mips_gnu_vtentry_howto;
1309
1310  return NULL;
1311}
1312
1313/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
1314
1315static reloc_howto_type *
1316mips_elf32_rtype_to_howto (unsigned int r_type,
1317			   bfd_boolean rela_p ATTRIBUTE_UNUSED)
1318{
1319  switch (r_type)
1320    {
1321    case R_MIPS_GNU_VTINHERIT:
1322      return &elf_mips_gnu_vtinherit_howto;
1323    case R_MIPS_GNU_VTENTRY:
1324      return &elf_mips_gnu_vtentry_howto;
1325    case R_MIPS_GNU_REL16_S2:
1326      return &elf_mips_gnu_rel16_s2;
1327    case R_MIPS_PC32:
1328      return &elf_mips_gnu_pcrel32;
1329    default:
1330      if (r_type >= R_MIPS16_min && r_type < R_MIPS16_max)
1331        return &elf_mips16_howto_table_rel[r_type - R_MIPS16_min];
1332      BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
1333      return &elf_mips_howto_table_rel[r_type];
1334    }
1335}
1336
1337/* Given a MIPS Elf_Internal_Rel, fill in an arelent structure.  */
1338
1339static void
1340mips_info_to_howto_rel (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
1341{
1342  const struct elf_backend_data *bed;
1343  unsigned int r_type;
1344
1345  r_type = ELF32_R_TYPE (dst->r_info);
1346  bed = get_elf_backend_data (abfd);
1347  cache_ptr->howto = bed->elf_backend_mips_rtype_to_howto (r_type, FALSE);
1348
1349  /* The addend for a GPREL16 or LITERAL relocation comes from the GP
1350     value for the object file.  We get the addend now, rather than
1351     when we do the relocation, because the symbol manipulations done
1352     by the linker may cause us to lose track of the input BFD.  */
1353  if (((*cache_ptr->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
1354      && (r_type == (unsigned int) R_MIPS_GPREL16
1355	  || r_type == (unsigned int) R_MIPS_LITERAL))
1356    cache_ptr->addend = elf_gp (abfd);
1357}
1358
1359/* Given a MIPS Elf_Internal_Rela, fill in an arelent structure.  */
1360
1361static void
1362mips_info_to_howto_rela (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
1363{
1364  mips_info_to_howto_rel (abfd, cache_ptr, dst);
1365
1366  /* If we ever need to do any extra processing with dst->r_addend
1367     (the field omitted in an Elf_Internal_Rel) we can do it here.  */
1368}
1369
1370/* Determine whether a symbol is global for the purposes of splitting
1371   the symbol table into global symbols and local symbols.  At least
1372   on Irix 5, this split must be between section symbols and all other
1373   symbols.  On most ELF targets the split is between static symbols
1374   and externally visible symbols.  */
1375
1376static bfd_boolean
1377mips_elf_sym_is_global (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym)
1378{
1379  if (SGI_COMPAT (abfd))
1380    return (sym->flags & BSF_SECTION_SYM) == 0;
1381  else
1382    return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
1383	    || bfd_is_und_section (bfd_get_section (sym))
1384	    || bfd_is_com_section (bfd_get_section (sym)));
1385}
1386
1387/* Set the right machine number for a MIPS ELF file.  */
1388
1389static bfd_boolean
1390mips_elf32_object_p (bfd *abfd)
1391{
1392  unsigned long mach;
1393
1394  /* Irix 5 and 6 are broken.  Object file symbol tables are not always
1395     sorted correctly such that local symbols precede global symbols,
1396     and the sh_info field in the symbol table is not always right.  */
1397  if (SGI_COMPAT (abfd))
1398    elf_bad_symtab (abfd) = TRUE;
1399
1400  if (ABI_N32_P (abfd))
1401    return FALSE;
1402
1403  mach = _bfd_elf_mips_mach (elf_elfheader (abfd)->e_flags);
1404  bfd_default_set_arch_mach (abfd, bfd_arch_mips, mach);
1405
1406  return TRUE;
1407}
1408
1409/* MIPS ELF local labels start with '$', not 'L'.  */
1410
1411static bfd_boolean
1412mips_elf_is_local_label_name (bfd *abfd, const char *name)
1413{
1414  if (name[0] == '$')
1415    return TRUE;
1416
1417  /* On Irix 6, the labels go back to starting with '.', so we accept
1418     the generic ELF local label syntax as well.  */
1419  return _bfd_elf_is_local_label_name (abfd, name);
1420}
1421
1422/* Support for core dump NOTE sections.  */
1423static bfd_boolean
1424elf32_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
1425{
1426  int offset;
1427  unsigned int size;
1428
1429  switch (note->descsz)
1430    {
1431      default:
1432	return FALSE;
1433
1434      case 256:		/* Linux/MIPS */
1435	/* pr_cursig */
1436	elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
1437
1438	/* pr_pid */
1439	elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
1440
1441	/* pr_reg */
1442	offset = 72;
1443	size = 180;
1444
1445	break;
1446    }
1447
1448  /* Make a ".reg/999" section.  */
1449  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
1450					  size, note->descpos + offset);
1451}
1452
1453static bfd_boolean
1454elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
1455{
1456  switch (note->descsz)
1457    {
1458      default:
1459	return FALSE;
1460
1461      case 128:		/* Linux/MIPS elf_prpsinfo */
1462	elf_tdata (abfd)->core_program
1463	 = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
1464	elf_tdata (abfd)->core_command
1465	 = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
1466    }
1467
1468  /* Note that for some reason, a spurious space is tacked
1469     onto the end of the args in some (at least one anyway)
1470     implementations, so strip it off if it exists.  */
1471
1472  {
1473    char *command = elf_tdata (abfd)->core_command;
1474    int n = strlen (command);
1475
1476    if (0 < n && command[n - 1] == ' ')
1477      command[n - 1] = '\0';
1478  }
1479
1480  return TRUE;
1481}
1482
1483/* Depending on the target vector we generate some version of Irix
1484   executables or "normal" MIPS ELF ABI executables.  */
1485static irix_compat_t
1486elf32_mips_irix_compat (bfd *abfd)
1487{
1488  if ((abfd->xvec == &bfd_elf32_bigmips_vec)
1489      || (abfd->xvec == &bfd_elf32_littlemips_vec))
1490    return ict_irix5;
1491  else
1492    return ict_none;
1493}
1494
1495/* ECOFF swapping routines.  These are used when dealing with the
1496   .mdebug section, which is in the ECOFF debugging format.  */
1497static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
1498  /* Symbol table magic number.  */
1499  magicSym,
1500  /* Alignment of debugging information.  E.g., 4.  */
1501  4,
1502  /* Sizes of external symbolic information.  */
1503  sizeof (struct hdr_ext),
1504  sizeof (struct dnr_ext),
1505  sizeof (struct pdr_ext),
1506  sizeof (struct sym_ext),
1507  sizeof (struct opt_ext),
1508  sizeof (struct fdr_ext),
1509  sizeof (struct rfd_ext),
1510  sizeof (struct ext_ext),
1511  /* Functions to swap in external symbolic data.  */
1512  ecoff_swap_hdr_in,
1513  ecoff_swap_dnr_in,
1514  ecoff_swap_pdr_in,
1515  ecoff_swap_sym_in,
1516  ecoff_swap_opt_in,
1517  ecoff_swap_fdr_in,
1518  ecoff_swap_rfd_in,
1519  ecoff_swap_ext_in,
1520  _bfd_ecoff_swap_tir_in,
1521  _bfd_ecoff_swap_rndx_in,
1522  /* Functions to swap out external symbolic data.  */
1523  ecoff_swap_hdr_out,
1524  ecoff_swap_dnr_out,
1525  ecoff_swap_pdr_out,
1526  ecoff_swap_sym_out,
1527  ecoff_swap_opt_out,
1528  ecoff_swap_fdr_out,
1529  ecoff_swap_rfd_out,
1530  ecoff_swap_ext_out,
1531  _bfd_ecoff_swap_tir_out,
1532  _bfd_ecoff_swap_rndx_out,
1533  /* Function to read in symbolic data.  */
1534  _bfd_mips_elf_read_ecoff_info
1535};
1536
1537#define ELF_ARCH			bfd_arch_mips
1538#define ELF_MACHINE_CODE		EM_MIPS
1539
1540#define elf_backend_collect		TRUE
1541#define elf_backend_type_change_ok	TRUE
1542#define elf_backend_can_gc_sections	TRUE
1543#define elf_info_to_howto		mips_info_to_howto_rela
1544#define elf_info_to_howto_rel		mips_info_to_howto_rel
1545#define elf_backend_sym_is_global	mips_elf_sym_is_global
1546#define elf_backend_object_p		mips_elf32_object_p
1547#define elf_backend_symbol_processing	_bfd_mips_elf_symbol_processing
1548#define elf_backend_section_processing	_bfd_mips_elf_section_processing
1549#define elf_backend_section_from_shdr	_bfd_mips_elf_section_from_shdr
1550#define elf_backend_fake_sections	_bfd_mips_elf_fake_sections
1551#define elf_backend_section_from_bfd_section \
1552					_bfd_mips_elf_section_from_bfd_section
1553#define elf_backend_add_symbol_hook	_bfd_mips_elf_add_symbol_hook
1554#define elf_backend_link_output_symbol_hook \
1555					_bfd_mips_elf_link_output_symbol_hook
1556#define elf_backend_create_dynamic_sections \
1557					_bfd_mips_elf_create_dynamic_sections
1558#define elf_backend_check_relocs	_bfd_mips_elf_check_relocs
1559#define elf_backend_merge_symbol_attribute \
1560					_bfd_mips_elf_merge_symbol_attribute
1561#define elf_backend_adjust_dynamic_symbol \
1562					_bfd_mips_elf_adjust_dynamic_symbol
1563#define elf_backend_always_size_sections \
1564					_bfd_mips_elf_always_size_sections
1565#define elf_backend_size_dynamic_sections \
1566					_bfd_mips_elf_size_dynamic_sections
1567#define elf_backend_init_index_section	_bfd_elf_init_1_index_section
1568#define elf_backend_relocate_section	_bfd_mips_elf_relocate_section
1569#define elf_backend_finish_dynamic_symbol \
1570					_bfd_mips_elf_finish_dynamic_symbol
1571#define elf_backend_finish_dynamic_sections \
1572					_bfd_mips_elf_finish_dynamic_sections
1573#define elf_backend_final_write_processing \
1574					_bfd_mips_elf_final_write_processing
1575#define elf_backend_additional_program_headers \
1576					_bfd_mips_elf_additional_program_headers
1577#define elf_backend_modify_segment_map	_bfd_mips_elf_modify_segment_map
1578#define elf_backend_gc_mark_hook	_bfd_mips_elf_gc_mark_hook
1579#define elf_backend_gc_sweep_hook	_bfd_mips_elf_gc_sweep_hook
1580#define elf_backend_copy_indirect_symbol \
1581					_bfd_mips_elf_copy_indirect_symbol
1582#define elf_backend_hide_symbol		_bfd_mips_elf_hide_symbol
1583#define elf_backend_grok_prstatus	elf32_mips_grok_prstatus
1584#define elf_backend_grok_psinfo		elf32_mips_grok_psinfo
1585#define elf_backend_ecoff_debug_swap	&mips_elf32_ecoff_debug_swap
1586
1587#define elf_backend_got_header_size	(4 * MIPS_RESERVED_GOTNO)
1588#define elf_backend_may_use_rel_p	1
1589#define elf_backend_may_use_rela_p	0
1590#define elf_backend_default_use_rela_p	0
1591#define elf_backend_sign_extend_vma	TRUE
1592
1593#define elf_backend_discard_info	_bfd_mips_elf_discard_info
1594#define elf_backend_ignore_discarded_relocs \
1595					_bfd_mips_elf_ignore_discarded_relocs
1596#define elf_backend_mips_irix_compat	elf32_mips_irix_compat
1597#define elf_backend_mips_rtype_to_howto	mips_elf32_rtype_to_howto
1598#define bfd_elf32_bfd_is_local_label_name \
1599					mips_elf_is_local_label_name
1600#define bfd_elf32_find_nearest_line	_bfd_mips_elf_find_nearest_line
1601#define bfd_elf32_find_inliner_info	_bfd_mips_elf_find_inliner_info
1602#define bfd_elf32_new_section_hook	_bfd_mips_elf_new_section_hook
1603#define bfd_elf32_set_section_contents	_bfd_mips_elf_set_section_contents
1604#define bfd_elf32_bfd_get_relocated_section_contents \
1605				_bfd_elf_mips_get_relocated_section_contents
1606#define bfd_elf32_bfd_link_hash_table_create \
1607					_bfd_mips_elf_link_hash_table_create
1608#define bfd_elf32_bfd_final_link	_bfd_mips_elf_final_link
1609#define bfd_elf32_bfd_merge_private_bfd_data \
1610					_bfd_mips_elf_merge_private_bfd_data
1611#define bfd_elf32_bfd_set_private_flags	_bfd_mips_elf_set_private_flags
1612#define bfd_elf32_bfd_print_private_bfd_data \
1613					_bfd_mips_elf_print_private_bfd_data
1614
1615/* Support for SGI-ish mips targets.  */
1616#define TARGET_LITTLE_SYM		bfd_elf32_littlemips_vec
1617#define TARGET_LITTLE_NAME		"elf32-littlemips"
1618#define TARGET_BIG_SYM			bfd_elf32_bigmips_vec
1619#define TARGET_BIG_NAME			"elf32-bigmips"
1620
1621/* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
1622   a value of 0x1000, and we are compatible.  */
1623#define ELF_MAXPAGESIZE			0x1000
1624#define ELF_COMMONPAGESIZE		0x1000
1625
1626#include "elf32-target.h"
1627
1628/* Support for traditional mips targets.  */
1629#undef TARGET_LITTLE_SYM
1630#undef TARGET_LITTLE_NAME
1631#undef TARGET_BIG_SYM
1632#undef TARGET_BIG_NAME
1633
1634#undef ELF_MAXPAGESIZE
1635#undef ELF_COMMONPAGESIZE
1636
1637#define TARGET_LITTLE_SYM               bfd_elf32_tradlittlemips_vec
1638#define TARGET_LITTLE_NAME              "elf32-tradlittlemips"
1639#define TARGET_BIG_SYM                  bfd_elf32_tradbigmips_vec
1640#define TARGET_BIG_NAME                 "elf32-tradbigmips"
1641
1642/* The MIPS ABI says at Page 5-1:
1643   Virtual addresses and file offsets for MIPS segments are congruent
1644   modulo 64 KByte (0x10000) or larger powers of 2.  Because 64 KBytes
1645   is the maximum page size, the files are suitable for paging
1646   regardless of physical page size.  */
1647#define ELF_MAXPAGESIZE			0x10000
1648#define ELF_COMMONPAGESIZE		0x1000
1649#define elf32_bed			elf32_tradbed
1650
1651/* Include the target file again for this target.  */
1652#include "elf32-target.h"
1653
1654
1655/* Specific to VxWorks.  */
1656static reloc_howto_type mips_vxworks_copy_howto_rela =
1657  HOWTO (R_MIPS_COPY,		/* type */
1658	 0,			/* rightshift */
1659	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1660	 32,			/* bitsize */
1661	 FALSE,			/* pc_relative */
1662	 0,			/* bitpos */
1663	 complain_overflow_bitfield, /* complain_on_overflow */
1664	 bfd_elf_generic_reloc,	/* special_function */
1665	 "R_MIPS_COPY",		/* name */
1666	 FALSE,			/* partial_inplace */
1667	 0x0,         		/* src_mask */
1668	 0x0,		        /* dst_mask */
1669	 FALSE);		/* pcrel_offset */
1670
1671/* Specific to VxWorks.  */
1672static reloc_howto_type mips_vxworks_jump_slot_howto_rela =
1673  HOWTO (R_MIPS_JUMP_SLOT,	/* type */
1674	 0,			/* rightshift */
1675	 2,			/* size (0 = byte, 1 = short, 2 = long) */
1676	 32,			/* bitsize */
1677	 FALSE,			/* pc_relative */
1678	 0,			/* bitpos */
1679	 complain_overflow_bitfield, /* complain_on_overflow */
1680	 bfd_elf_generic_reloc,	/* special_function */
1681	 "R_MIPS_JUMP_SLOT",	/* name */
1682	 FALSE,			/* partial_inplace */
1683	 0x0,         		/* src_mask */
1684	 0x0,		        /* dst_mask */
1685	 FALSE);		/* pcrel_offset */
1686
1687/* Implement elf_backend_bfd_reloc_type_lookup for VxWorks.  */
1688
1689static reloc_howto_type *
1690mips_vxworks_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
1691{
1692  switch (code)
1693    {
1694    case BFD_RELOC_MIPS_COPY:
1695      return &mips_vxworks_copy_howto_rela;
1696    case BFD_RELOC_MIPS_JUMP_SLOT:
1697      return &mips_vxworks_jump_slot_howto_rela;
1698    default:
1699      return bfd_elf32_bfd_reloc_type_lookup (abfd, code);
1700    }
1701}
1702
1703static reloc_howto_type *
1704mips_vxworks_bfd_reloc_name_lookup (bfd *abfd, const char *r_name)
1705{
1706  if (strcasecmp (mips_vxworks_copy_howto_rela.name, r_name) == 0)
1707    return &mips_vxworks_copy_howto_rela;
1708  if (strcasecmp (mips_vxworks_jump_slot_howto_rela.name, r_name) == 0)
1709    return &mips_vxworks_jump_slot_howto_rela;
1710
1711  return bfd_elf32_bfd_reloc_name_lookup (abfd, r_name);
1712}
1713
1714/* Implement elf_backend_mips_rtype_to_lookup for VxWorks.  */
1715
1716static reloc_howto_type *
1717mips_vxworks_rtype_to_howto (unsigned int r_type, bfd_boolean rela_p)
1718{
1719  switch (r_type)
1720    {
1721    case R_MIPS_COPY:
1722      return &mips_vxworks_copy_howto_rela;
1723    case R_MIPS_JUMP_SLOT:
1724      return &mips_vxworks_jump_slot_howto_rela;
1725    default:
1726      return mips_elf32_rtype_to_howto (r_type, rela_p);
1727    }
1728}
1729
1730/* Implement elf_backend_final_write_processing for VxWorks.  */
1731
1732static void
1733mips_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
1734{
1735  _bfd_mips_elf_final_write_processing (abfd, linker);
1736  elf_vxworks_final_write_processing (abfd, linker);
1737}
1738
1739#undef TARGET_LITTLE_SYM
1740#undef TARGET_LITTLE_NAME
1741#undef TARGET_BIG_SYM
1742#undef TARGET_BIG_NAME
1743
1744#undef ELF_MAXPAGESIZE
1745#undef ELF_COMMONPAGESIZE
1746
1747#define TARGET_LITTLE_SYM               bfd_elf32_littlemips_vxworks_vec
1748#define TARGET_LITTLE_NAME              "elf32-littlemips-vxworks"
1749#define TARGET_BIG_SYM                  bfd_elf32_bigmips_vxworks_vec
1750#define TARGET_BIG_NAME                 "elf32-bigmips-vxworks"
1751
1752#undef elf32_bed
1753#define elf32_bed			elf32_mips_vxworks_bed
1754
1755#define ELF_MAXPAGESIZE			0x1000
1756#define ELF_COMMONPAGESIZE		0x1000
1757
1758#undef elf_backend_want_got_plt
1759#define elf_backend_want_got_plt		1
1760#undef elf_backend_want_plt_sym
1761#define elf_backend_want_plt_sym		1
1762#undef elf_backend_got_symbol_offset
1763#define elf_backend_got_symbol_offset		0
1764#undef elf_backend_want_dynbss
1765#define elf_backend_want_dynbss			1
1766#undef elf_backend_may_use_rel_p
1767#define elf_backend_may_use_rel_p		0
1768#undef elf_backend_may_use_rela_p
1769#define elf_backend_may_use_rela_p		1
1770#undef elf_backend_default_use_rela_p
1771#define elf_backend_default_use_rela_p		1
1772#undef elf_backend_got_header_size
1773#define elf_backend_got_header_size		(4 * 3)
1774#undef elf_backend_plt_readonly
1775#define elf_backend_plt_readonly		1
1776
1777#undef bfd_elf32_bfd_reloc_type_lookup
1778#define bfd_elf32_bfd_reloc_type_lookup \
1779  mips_vxworks_bfd_reloc_type_lookup
1780#undef bfd_elf32_bfd_reloc_name_lookup
1781#define bfd_elf32_bfd_reloc_name_lookup \
1782  mips_vxworks_bfd_reloc_name_lookup
1783#undef elf_backend_mips_rtype_to_howto
1784#define elf_backend_mips_rtype_to_howto	\
1785  mips_vxworks_rtype_to_howto
1786#undef elf_backend_adjust_dynamic_symbol
1787#define elf_backend_adjust_dynamic_symbol \
1788  _bfd_mips_vxworks_adjust_dynamic_symbol
1789#undef elf_backend_finish_dynamic_symbol
1790#define elf_backend_finish_dynamic_symbol \
1791  _bfd_mips_vxworks_finish_dynamic_symbol
1792#undef bfd_elf32_bfd_link_hash_table_create
1793#define bfd_elf32_bfd_link_hash_table_create \
1794  _bfd_mips_vxworks_link_hash_table_create
1795#undef elf_backend_add_symbol_hook
1796#define elf_backend_add_symbol_hook \
1797  elf_vxworks_add_symbol_hook
1798#undef elf_backend_link_output_symbol_hook
1799#define elf_backend_link_output_symbol_hook \
1800  elf_vxworks_link_output_symbol_hook
1801#undef elf_backend_emit_relocs
1802#define elf_backend_emit_relocs \
1803  elf_vxworks_emit_relocs
1804#undef elf_backend_final_write_processing
1805#define elf_backend_final_write_processing \
1806  mips_vxworks_final_write_processing
1807
1808#undef elf_backend_additional_program_headers
1809#undef elf_backend_modify_segment_map
1810#undef elf_backend_symbol_processing
1811/* NOTE: elf_backend_rela_normal is not defined for MIPS.  */
1812
1813#include "elf32-target.h"
1814