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