1 /* Intel i860 specific support for 32-bit ELF.
2    Copyright (C) 1993-2014 Free Software Foundation, Inc.
3 
4    Full i860 support contributed by Jason Eckhardt <jle@cygnus.com>.
5 
6    This file is part of BFD, the Binary File Descriptor library.
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21    MA 02110-1301, USA.  */
22 
23 #include "sysdep.h"
24 #include "bfd.h"
25 #include "libbfd.h"
26 #include "elf-bfd.h"
27 #include "elf/i860.h"
28 
29 /* special_function for R_860_PC26 relocation.  */
30 static bfd_reloc_status_type
i860_howto_pc26_reloc(bfd * abfd ATTRIBUTE_UNUSED,arelent * reloc_entry,asymbol * symbol,void * data ATTRIBUTE_UNUSED,asection * input_section,bfd * output_bfd,char ** error_message ATTRIBUTE_UNUSED)31 i860_howto_pc26_reloc (bfd *abfd ATTRIBUTE_UNUSED,
32                        arelent *reloc_entry,
33                        asymbol *symbol,
34                        void *data ATTRIBUTE_UNUSED,
35                        asection *input_section,
36                        bfd *output_bfd,
37                        char **error_message ATTRIBUTE_UNUSED)
38 {
39   bfd_vma insn;
40   bfd_vma relocation;
41   bfd_byte *addr;
42 
43   if (output_bfd != NULL
44       && (symbol->flags & BSF_SECTION_SYM) == 0
45       && (! reloc_entry->howto->partial_inplace
46 	  || reloc_entry->addend == 0))
47     {
48       reloc_entry->address += input_section->output_offset;
49       return bfd_reloc_ok;
50     }
51 
52   /* Used elf32-mips.c as an example.  */
53   if (bfd_is_und_section (symbol->section)
54       && output_bfd == (bfd *) NULL)
55     return bfd_reloc_undefined;
56 
57   if (bfd_is_com_section (symbol->section))
58     relocation = 0;
59   else
60     relocation = symbol->value;
61 
62   relocation += symbol->section->output_section->vma;
63   relocation += symbol->section->output_offset;
64   relocation += reloc_entry->addend;
65 
66   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
67     return bfd_reloc_outofrange;
68 
69   /* Adjust for PC-relative relocation.  */
70   relocation -= (input_section->output_section->vma
71                  + input_section->output_offset
72                  + reloc_entry->address
73                  + 4);
74 
75   /* Check for target out of range.  */
76   if ((bfd_signed_vma)relocation > (0x3ffffff << 2)
77       || (bfd_signed_vma)relocation < (-0x4000000 << 2))
78     return bfd_reloc_outofrange;
79 
80   addr = (bfd_byte *) data + reloc_entry->address;
81   insn = bfd_get_32 (abfd, addr);
82 
83   relocation >>= reloc_entry->howto->rightshift;
84   insn = (insn & ~reloc_entry->howto->dst_mask)
85          | (relocation & reloc_entry->howto->dst_mask);
86 
87   bfd_put_32 (abfd, (bfd_vma) insn, addr);
88 
89   return bfd_reloc_ok;
90 }
91 
92 /* special_function for R_860_PC16 relocation.  */
93 static bfd_reloc_status_type
i860_howto_pc16_reloc(bfd * abfd,arelent * reloc_entry,asymbol * symbol,void * data,asection * input_section,bfd * output_bfd,char ** error_message ATTRIBUTE_UNUSED)94 i860_howto_pc16_reloc (bfd *abfd,
95                        arelent *reloc_entry,
96                        asymbol *symbol,
97                        void *data,
98                        asection *input_section,
99                        bfd *output_bfd,
100                        char **error_message ATTRIBUTE_UNUSED)
101 {
102   bfd_vma insn;
103   bfd_vma relocation;
104   bfd_byte *addr;
105 
106   if (output_bfd != NULL
107       && (symbol->flags & BSF_SECTION_SYM) == 0
108       && (! reloc_entry->howto->partial_inplace
109 	  || reloc_entry->addend == 0))
110     {
111       reloc_entry->address += input_section->output_offset;
112       return bfd_reloc_ok;
113     }
114 
115   /* Used elf32-mips.c as an example.  */
116   if (bfd_is_und_section (symbol->section)
117       && output_bfd == (bfd *) NULL)
118     return bfd_reloc_undefined;
119 
120   if (bfd_is_com_section (symbol->section))
121     relocation = 0;
122   else
123     relocation = symbol->value;
124 
125   relocation += symbol->section->output_section->vma;
126   relocation += symbol->section->output_offset;
127   relocation += reloc_entry->addend;
128 
129   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
130     return bfd_reloc_outofrange;
131 
132   /* Adjust for PC-relative relocation.  */
133   relocation -= (input_section->output_section->vma
134                  + input_section->output_offset
135                  + reloc_entry->address
136                  + 4);
137 
138   /* Check for target out of range.  */
139   if ((bfd_signed_vma)relocation > (0x7fff << 2)
140       || (bfd_signed_vma)relocation < (-0x8000 << 2))
141     return bfd_reloc_outofrange;
142 
143   addr = (bfd_byte *) data + reloc_entry->address;
144   insn = bfd_get_32 (abfd, addr);
145 
146   relocation >>= reloc_entry->howto->rightshift;
147   relocation = (((relocation & 0xf800) << 5) | (relocation & 0x7ff))
148                & reloc_entry->howto->dst_mask;
149   insn = (insn & ~reloc_entry->howto->dst_mask) | relocation;
150 
151   bfd_put_32 (abfd, (bfd_vma) insn, addr);
152 
153   return bfd_reloc_ok;
154 }
155 
156 /* special_function for R_860_HIGHADJ relocation.  */
157 static bfd_reloc_status_type
i860_howto_highadj_reloc(bfd * abfd,arelent * reloc_entry,asymbol * symbol,void * data,asection * input_section,bfd * output_bfd,char ** error_message ATTRIBUTE_UNUSED)158 i860_howto_highadj_reloc (bfd *abfd,
159                           arelent *reloc_entry,
160                           asymbol *symbol,
161                           void *data,
162                           asection *input_section,
163                           bfd *output_bfd,
164                           char **error_message ATTRIBUTE_UNUSED)
165 {
166   bfd_vma insn;
167   bfd_vma relocation;
168   bfd_byte *addr;
169 
170   if (output_bfd != NULL
171       && (symbol->flags & BSF_SECTION_SYM) == 0
172       && (! reloc_entry->howto->partial_inplace
173 	  || reloc_entry->addend == 0))
174     {
175       reloc_entry->address += input_section->output_offset;
176       return bfd_reloc_ok;
177     }
178 
179   /* Used elf32-mips.c as an example.  */
180   if (bfd_is_und_section (symbol->section)
181       && output_bfd == (bfd *) NULL)
182     return bfd_reloc_undefined;
183 
184   if (bfd_is_com_section (symbol->section))
185     relocation = 0;
186   else
187     relocation = symbol->value;
188 
189   relocation += symbol->section->output_section->vma;
190   relocation += symbol->section->output_offset;
191   relocation += reloc_entry->addend;
192   relocation += 0x8000;
193 
194   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
195     return bfd_reloc_outofrange;
196 
197   addr = (bfd_byte *) data + reloc_entry->address;
198   insn = bfd_get_32 (abfd, addr);
199 
200   relocation = ((relocation >> 16) & 0xffff);
201 
202   insn = (insn & 0xffff0000) | relocation;
203 
204   bfd_put_32 (abfd, (bfd_vma) insn, addr);
205 
206   return bfd_reloc_ok;
207 }
208 
209 /* special_function for R_860_SPLITn relocations.  */
210 static bfd_reloc_status_type
i860_howto_splitn_reloc(bfd * abfd,arelent * reloc_entry,asymbol * symbol,void * data,asection * input_section,bfd * output_bfd,char ** error_message ATTRIBUTE_UNUSED)211 i860_howto_splitn_reloc (bfd *abfd,
212                          arelent *reloc_entry,
213                          asymbol *symbol,
214                          void *data,
215                          asection *input_section,
216                          bfd *output_bfd,
217                          char **error_message ATTRIBUTE_UNUSED)
218 {
219   bfd_vma insn;
220   bfd_vma relocation;
221   bfd_byte *addr;
222 
223   if (output_bfd != NULL
224       && (symbol->flags & BSF_SECTION_SYM) == 0
225       && (! reloc_entry->howto->partial_inplace
226 	  || reloc_entry->addend == 0))
227     {
228       reloc_entry->address += input_section->output_offset;
229       return bfd_reloc_ok;
230     }
231 
232   /* Used elf32-mips.c as an example.  */
233   if (bfd_is_und_section (symbol->section)
234       && output_bfd == (bfd *) NULL)
235     return bfd_reloc_undefined;
236 
237   if (bfd_is_com_section (symbol->section))
238     relocation = 0;
239   else
240     relocation = symbol->value;
241 
242   relocation += symbol->section->output_section->vma;
243   relocation += symbol->section->output_offset;
244   relocation += reloc_entry->addend;
245 
246   if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
247     return bfd_reloc_outofrange;
248 
249   addr = (bfd_byte *) data + reloc_entry->address;
250   insn = bfd_get_32 (abfd, addr);
251 
252   relocation = (((relocation & 0xf800) << 5) | (relocation & 0x7ff))
253                & reloc_entry->howto->dst_mask;
254   insn = (insn & ~reloc_entry->howto->dst_mask) | relocation;
255 
256   bfd_put_32 (abfd, (bfd_vma) insn, addr);
257 
258   return bfd_reloc_ok;
259 }
260 
261 /* This howto table is preliminary.  */
262 static reloc_howto_type elf32_i860_howto_table [] =
263 {
264   /* This relocation does nothing.  */
265   HOWTO (R_860_NONE,		/* type */
266 	 0,			/* rightshift */
267 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
268 	 32,			/* bitsize */
269 	 FALSE,			/* pc_relative */
270 	 0,			/* bitpos */
271 	 complain_overflow_bitfield, /* complain_on_overflow */
272 	 bfd_elf_generic_reloc,	/* special_function */
273 	 "R_860_NONE",		/* name */
274 	 FALSE,			/* partial_inplace */
275 	 0,			/* src_mask */
276 	 0,			/* dst_mask */
277 	 FALSE),		/* pcrel_offset */
278 
279   /* A 32-bit absolute relocation.  */
280   HOWTO (R_860_32,		/* type */
281 	 0,			/* rightshift */
282 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
283 	 32,			/* bitsize */
284 	 FALSE,			/* pc_relative */
285 	 0,			/* bitpos */
286 	 complain_overflow_bitfield, /* complain_on_overflow */
287 	 bfd_elf_generic_reloc,	/* special_function */
288 	 "R_860_32",		/* name */
289 	 FALSE,			/* partial_inplace */
290 	 0xffffffff,		/* src_mask */
291 	 0xffffffff,		/* dst_mask */
292 	 FALSE),		/* pcrel_offset */
293 
294   HOWTO (R_860_COPY,		/* 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_bitfield, /* complain_on_overflow */
301 	 bfd_elf_generic_reloc,	/* special_function */
302 	 "R_860_COPY",		/* name */
303 	 TRUE,			/* partial_inplace */
304 	 0xffffffff,		/* src_mask */
305 	 0xffffffff,		/* dst_mask */
306 	 FALSE),		/* pcrel_offset */
307 
308   HOWTO (R_860_GLOB_DAT,	/* type */
309 	 0,			/* rightshift */
310 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
311 	 32,			/* bitsize */
312 	 FALSE,			/* pc_relative */
313 	 0,			/* bitpos */
314 	 complain_overflow_bitfield, /* complain_on_overflow */
315 	 bfd_elf_generic_reloc,	/* special_function */
316 	 "R_860_GLOB_DAT",	/* name */
317 	 TRUE,			/* partial_inplace */
318 	 0xffffffff,		/* src_mask */
319 	 0xffffffff,		/* dst_mask */
320 	 FALSE),		/* pcrel_offset */
321 
322   HOWTO (R_860_JUMP_SLOT,	/* type */
323 	 0,			/* rightshift */
324 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
325 	 32,			/* bitsize */
326 	 FALSE,			/* pc_relative */
327 	 0,			/* bitpos */
328 	 complain_overflow_bitfield, /* complain_on_overflow */
329 	 bfd_elf_generic_reloc,	/* special_function */
330 	 "R_860_JUMP_SLOT",	/* name */
331 	 TRUE,			/* partial_inplace */
332 	 0xffffffff,		/* src_mask */
333 	 0xffffffff,		/* dst_mask */
334 	 FALSE),		/* pcrel_offset */
335 
336   HOWTO (R_860_RELATIVE,	/* type */
337 	 0,			/* rightshift */
338 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
339 	 32,			/* bitsize */
340 	 FALSE,			/* pc_relative */
341 	 0,			/* bitpos */
342 	 complain_overflow_bitfield, /* complain_on_overflow */
343 	 bfd_elf_generic_reloc,	/* special_function */
344 	 "R_860_RELATIVE",	/* name */
345 	 TRUE,			/* partial_inplace */
346 	 0xffffffff,		/* src_mask */
347 	 0xffffffff,		/* dst_mask */
348 	 FALSE),		/* pcrel_offset */
349 
350   /* A 26-bit PC-relative relocation.  */
351   HOWTO (R_860_PC26,	        /* type */
352 	 2,			/* rightshift */
353 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
354 	 26,			/* bitsize */
355 	 TRUE,			/* pc_relative */
356 	 0,			/* bitpos */
357 	 complain_overflow_bitfield, /* complain_on_overflow */
358 	 i860_howto_pc26_reloc,	/* special_function */
359 	 "R_860_PC26",		/* name */
360 	 FALSE,			/* partial_inplace */
361 	 0x3ffffff,		/* src_mask */
362 	 0x3ffffff,		/* dst_mask */
363 	 TRUE),		        /* pcrel_offset */
364 
365   HOWTO (R_860_PLT26,	        /* type */
366 	 0,			/* rightshift */
367 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
368 	 26,			/* bitsize */
369 	 TRUE,			/* pc_relative */
370 	 0,			/* bitpos */
371 	 complain_overflow_bitfield, /* complain_on_overflow */
372 	 bfd_elf_generic_reloc,	/* special_function */
373 	 "R_860_PLT26",		/* name */
374 	 TRUE,			/* partial_inplace */
375 	 0xffffffff,		/* src_mask */
376 	 0xffffffff,		/* dst_mask */
377 	 TRUE),		        /* pcrel_offset */
378 
379   /* A 16-bit PC-relative relocation.  */
380   HOWTO (R_860_PC16,	        /* type */
381 	 2,			/* rightshift */
382 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
383 	 16,			/* bitsize */
384 	 TRUE,			/* pc_relative */
385 	 0,			/* bitpos */
386 	 complain_overflow_bitfield, /* complain_on_overflow */
387 	 i860_howto_pc16_reloc,	/* special_function */
388 	 "R_860_PC16",		/* name */
389 	 FALSE,			/* partial_inplace */
390 	 0x1f07ff,		/* src_mask */
391 	 0x1f07ff,		/* dst_mask */
392 	 TRUE),		        /* pcrel_offset */
393 
394   HOWTO (R_860_LOW0,	        /* type */
395 	 0,			/* rightshift */
396 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
397 	 16,			/* bitsize */
398 	 FALSE,			/* pc_relative */
399 	 0,			/* bitpos */
400 	 complain_overflow_dont, /* complain_on_overflow */
401 	 bfd_elf_generic_reloc,	/* special_function */
402 	 "R_860_LOW0",		/* name */
403 	 FALSE,			/* partial_inplace */
404 	 0xffff,		/* src_mask */
405 	 0xffff,		/* dst_mask */
406 	 FALSE),	        /* pcrel_offset */
407 
408   HOWTO (R_860_SPLIT0,	        /* type */
409 	 0,			/* rightshift */
410 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
411 	 16,			/* bitsize */
412 	 FALSE,			/* pc_relative */
413 	 0,			/* bitpos */
414 	 complain_overflow_dont, /* complain_on_overflow */
415 	 i860_howto_splitn_reloc, /* special_function */
416 	 "R_860_SPLIT0",	/* name */
417 	 FALSE,			/* partial_inplace */
418 	 0x1f07ff,		/* src_mask */
419 	 0x1f07ff,		/* dst_mask */
420 	 FALSE),	        /* pcrel_offset */
421 
422   HOWTO (R_860_LOW1,	        /* 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_elf_generic_reloc,	/* special_function */
430 	 "R_860_LOW1",		/* name */
431 	 FALSE,			/* partial_inplace */
432 	 0xfffe,		/* src_mask */
433 	 0xfffe,		/* dst_mask */
434 	 FALSE),	        /* pcrel_offset */
435 
436   HOWTO (R_860_SPLIT1,	        /* type */
437 	 0,			/* rightshift */
438 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
439 	 16,			/* bitsize */
440 	 FALSE,			/* pc_relative */
441 	 0,			/* bitpos */
442 	 complain_overflow_dont, /* complain_on_overflow */
443 	 i860_howto_splitn_reloc, /* special_function */
444 	 "R_860_SPLIT1",	/* name */
445 	 FALSE,			/* partial_inplace */
446 	 0x1f07fe,		/* src_mask */
447 	 0x1f07fe,		/* dst_mask */
448 	 FALSE),	        /* pcrel_offset */
449 
450   HOWTO (R_860_LOW2,	        /* type */
451 	 0,			/* rightshift */
452 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
453 	 16,			/* bitsize */
454 	 FALSE,			/* pc_relative */
455 	 0,			/* bitpos */
456 	 complain_overflow_dont, /* complain_on_overflow */
457 	 bfd_elf_generic_reloc,	/* special_function */
458 	 "R_860_LOW2",		/* name */
459 	 FALSE,			/* partial_inplace */
460 	 0xfffc,		/* src_mask */
461 	 0xfffc,		/* dst_mask */
462 	 FALSE),	        /* pcrel_offset */
463 
464   HOWTO (R_860_SPLIT2,	        /* type */
465 	 0,			/* rightshift */
466 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
467 	 16,			/* bitsize */
468 	 FALSE,			/* pc_relative */
469 	 0,			/* bitpos */
470 	 complain_overflow_dont, /* complain_on_overflow */
471 	 i860_howto_splitn_reloc, /* special_function */
472 	 "R_860_SPLIT2",	/* name */
473 	 FALSE,			/* partial_inplace */
474 	 0x1f07fc,		/* src_mask */
475 	 0x1f07fc,		/* dst_mask */
476 	 FALSE),	        /* pcrel_offset */
477 
478   HOWTO (R_860_LOW3,	        /* type */
479 	 0,			/* rightshift */
480 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
481 	 16,			/* bitsize */
482 	 FALSE,			/* pc_relative */
483 	 0,			/* bitpos */
484 	 complain_overflow_dont, /* complain_on_overflow */
485 	 bfd_elf_generic_reloc,	/* special_function */
486 	 "R_860_LOW3",		/* name */
487 	 FALSE,			/* partial_inplace */
488 	 0xfff8,		/* src_mask */
489 	 0xfff8,		/* dst_mask */
490 	 FALSE),	        /* pcrel_offset */
491 
492   HOWTO (R_860_LOGOT0,	        /* type */
493 	 0,			/* rightshift */
494 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
495 	 16,			/* bitsize */
496 	 FALSE,			/* pc_relative */
497 	 0,			/* bitpos */
498 	 complain_overflow_dont, /* complain_on_overflow */
499 	 bfd_elf_generic_reloc,	/* special_function */
500 	 "R_860_LOGOT0",	/* name */
501 	 FALSE,			/* partial_inplace */
502 	 0,			/* src_mask */
503 	 0xffff,		/* dst_mask */
504 	 TRUE),		        /* pcrel_offset */
505 
506   HOWTO (R_860_SPGOT0,	        /* type */
507 	 0,			/* rightshift */
508 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
509 	 16,			/* bitsize */
510 	 FALSE,			/* pc_relative */
511 	 0,			/* bitpos */
512 	 complain_overflow_dont, /* complain_on_overflow */
513 	 bfd_elf_generic_reloc,	/* special_function */
514 	 "R_860_SPGOT0",	/* name */
515 	 FALSE,			/* partial_inplace */
516 	 0,			/* src_mask */
517 	 0xffff,		/* dst_mask */
518 	 TRUE),		        /* pcrel_offset */
519 
520   HOWTO (R_860_LOGOT1,	        /* type */
521 	 0,			/* rightshift */
522 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
523 	 16,			/* bitsize */
524 	 FALSE,			/* pc_relative */
525 	 0,			/* bitpos */
526 	 complain_overflow_dont, /* complain_on_overflow */
527 	 bfd_elf_generic_reloc,	/* special_function */
528 	 "R_860_LOGOT1",	/* name */
529 	 FALSE,			/* partial_inplace */
530 	 0,			/* src_mask */
531 	 0xffff,		/* dst_mask */
532 	 TRUE),		        /* pcrel_offset */
533 
534   HOWTO (R_860_SPGOT1,	        /* type */
535 	 0,			/* rightshift */
536 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
537 	 16,			/* bitsize */
538 	 FALSE,			/* pc_relative */
539 	 0,			/* bitpos */
540 	 complain_overflow_dont, /* complain_on_overflow */
541 	 bfd_elf_generic_reloc,	/* special_function */
542 	 "R_860_SPGOT1",	/* name */
543 	 FALSE,			/* partial_inplace */
544 	 0,			/* src_mask */
545 	 0xffff,		/* dst_mask */
546 	 TRUE),		        /* pcrel_offset */
547 
548   HOWTO (R_860_LOGOTOFF0,        /* type */
549 	 0,			/* rightshift */
550 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
551 	 32,			/* bitsize */
552 	 FALSE,			/* pc_relative */
553 	 0,			/* bitpos */
554 	 complain_overflow_dont, /* complain_on_overflow */
555 	 bfd_elf_generic_reloc,	/* special_function */
556 	 "R_860_LOGOTOFF0",	/* name */
557 	 TRUE,			/* partial_inplace */
558 	 0xffffffff,		/* src_mask */
559 	 0xffffffff,		/* dst_mask */
560 	 FALSE),	        /* pcrel_offset */
561 
562   HOWTO (R_860_SPGOTOFF0,        /* type */
563 	 0,			/* rightshift */
564 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
565 	 32,			/* bitsize */
566 	 FALSE,			/* pc_relative */
567 	 0,			/* bitpos */
568 	 complain_overflow_dont, /* complain_on_overflow */
569 	 bfd_elf_generic_reloc,	/* special_function */
570 	 "R_860_SPGOTOFF0",	/* name */
571 	 TRUE,			/* partial_inplace */
572 	 0xffffffff,		/* src_mask */
573 	 0xffffffff,		/* dst_mask */
574 	 FALSE),	        /* pcrel_offset */
575 
576   HOWTO (R_860_LOGOTOFF1,        /* type */
577 	 0,			/* rightshift */
578 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
579 	 32,			/* bitsize */
580 	 FALSE,			/* pc_relative */
581 	 0,			/* bitpos */
582 	 complain_overflow_dont, /* complain_on_overflow */
583 	 bfd_elf_generic_reloc,	/* special_function */
584 	 "R_860_LOGOTOFF1",	/* name */
585 	 TRUE,			/* partial_inplace */
586 	 0xffffffff,		/* src_mask */
587 	 0xffffffff,		/* dst_mask */
588 	 FALSE),	        /* pcrel_offset */
589 
590   HOWTO (R_860_SPGOTOFF1,       /* type */
591 	 0,			/* rightshift */
592 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
593 	 32,			/* bitsize */
594 	 FALSE,			/* pc_relative */
595 	 0,			/* bitpos */
596 	 complain_overflow_dont, /* complain_on_overflow */
597 	 bfd_elf_generic_reloc,	/* special_function */
598 	 "R_860_SPGOTOFF1",	/* name */
599 	 TRUE,			/* partial_inplace */
600 	 0xffffffff,		/* src_mask */
601 	 0xffffffff,		/* dst_mask */
602 	 FALSE),	        /* pcrel_offset */
603 
604   HOWTO (R_860_LOGOTOFF2,        /* type */
605 	 0,			/* rightshift */
606 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
607 	 32,			/* bitsize */
608 	 FALSE,			/* pc_relative */
609 	 0,			/* bitpos */
610 	 complain_overflow_dont, /* complain_on_overflow */
611 	 bfd_elf_generic_reloc,	/* special_function */
612 	 "R_860_LOGOTOFF2",	/* name */
613 	 TRUE,			/* partial_inplace */
614 	 0xffffffff,		/* src_mask */
615 	 0xffffffff,		/* dst_mask */
616 	 FALSE),	        /* pcrel_offset */
617 
618   HOWTO (R_860_LOGOTOFF3,        /* type */
619 	 0,			/* rightshift */
620 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
621 	 32,			/* bitsize */
622 	 FALSE,			/* pc_relative */
623 	 0,			/* bitpos */
624 	 complain_overflow_dont, /* complain_on_overflow */
625 	 bfd_elf_generic_reloc,	/* special_function */
626 	 "R_860_LOGOTOFF3",	/* name */
627 	 TRUE,			/* partial_inplace */
628 	 0xffffffff,		/* src_mask */
629 	 0xffffffff,		/* dst_mask */
630 	 FALSE),	        /* pcrel_offset */
631 
632   HOWTO (R_860_LOPC,	        /* type */
633 	 0,			/* rightshift */
634 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
635 	 16,			/* bitsize */
636 	 TRUE,			/* pc_relative */
637 	 0,			/* bitpos */
638 	 complain_overflow_bitfield, /* complain_on_overflow */
639 	 bfd_elf_generic_reloc,	/* special_function */
640 	 "R_860_LOPC",		/* name */
641 	 FALSE,			/* partial_inplace */
642 	 0xffff,		/* src_mask */
643 	 0xffff,		/* dst_mask */
644 	 TRUE),		        /* pcrel_offset */
645 
646   HOWTO (R_860_HIGHADJ,	        /* type */
647 	 0,			/* rightshift */
648 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
649 	 16,			/* bitsize */
650 	 FALSE,			/* pc_relative */
651 	 0,			/* bitpos */
652 	 complain_overflow_dont, /* complain_on_overflow */
653 	 i860_howto_highadj_reloc, /* special_function */
654 	 "R_860_HIGHADJ",	/* name */
655 	 FALSE,			/* partial_inplace */
656 	 0xffff,		/* src_mask */
657 	 0xffff,		/* dst_mask */
658 	 FALSE),	        /* pcrel_offset */
659 
660   HOWTO (R_860_HAGOT,	        /* type */
661 	 0,			/* rightshift */
662 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
663 	 16,			/* bitsize */
664 	 FALSE,			/* pc_relative */
665 	 0,			/* bitpos */
666 	 complain_overflow_dont, /* complain_on_overflow */
667 	 bfd_elf_generic_reloc,	/* special_function */
668 	 "R_860_HAGOT",		/* name */
669 	 FALSE,			/* partial_inplace */
670 	 0,			/* src_mask */
671 	 0xffff,		/* dst_mask */
672 	 TRUE),		        /* pcrel_offset */
673 
674   HOWTO (R_860_HAGOTOFF,        /* type */
675 	 0,			/* rightshift */
676 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
677 	 32,			/* bitsize */
678 	 FALSE,			/* pc_relative */
679 	 0,			/* bitpos */
680 	 complain_overflow_dont, /* complain_on_overflow */
681 	 bfd_elf_generic_reloc,	/* special_function */
682 	 "R_860_HAGOTOFF",	/* name */
683 	 TRUE,			/* partial_inplace */
684 	 0xffffffff,		/* src_mask */
685 	 0xffffffff,		/* dst_mask */
686 	 FALSE),	        /* pcrel_offset */
687 
688   HOWTO (R_860_HAPC,	        /* type */
689 	 0,			/* rightshift */
690 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
691 	 16,			/* bitsize */
692 	 TRUE,			/* pc_relative */
693 	 0,			/* bitpos */
694 	 complain_overflow_bitfield, /* complain_on_overflow */
695 	 bfd_elf_generic_reloc,	/* special_function */
696 	 "R_860_HAPC",		/* name */
697 	 FALSE,			/* partial_inplace */
698 	 0xffff,		/* src_mask */
699 	 0xffff,		/* dst_mask */
700 	 TRUE),		        /* pcrel_offset */
701 
702   HOWTO (R_860_HIGH,	        /* type */
703 	 16,			/* rightshift */
704 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
705 	 16,			/* bitsize */
706 	 FALSE,			/* pc_relative */
707 	 0,			/* bitpos */
708 	 complain_overflow_dont, /* complain_on_overflow */
709 	 bfd_elf_generic_reloc,	/* special_function */
710 	 "R_860_HIGH",		/* name */
711 	 FALSE,			/* partial_inplace */
712 	 0xffff,		/* src_mask */
713 	 0xffff,		/* dst_mask */
714 	 FALSE),	        /* pcrel_offset */
715 
716   HOWTO (R_860_HIGOT,	        /* type */
717 	 0,			/* rightshift */
718 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
719 	 16,			/* bitsize */
720 	 FALSE,			/* pc_relative */
721 	 0,			/* bitpos */
722 	 complain_overflow_dont, /* complain_on_overflow */
723 	 bfd_elf_generic_reloc,	/* special_function */
724 	 "R_860_HIGOT",		/* name */
725 	 FALSE,			/* partial_inplace */
726 	 0,			/* src_mask */
727 	 0xffff,		/* dst_mask */
728 	 TRUE),		        /* pcrel_offset */
729 
730   HOWTO (R_860_HIGOTOFF,        /* type */
731 	 0,			/* rightshift */
732 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
733 	 32,			/* bitsize */
734 	 FALSE,			/* pc_relative */
735 	 0,			/* bitpos */
736 	 complain_overflow_dont, /* complain_on_overflow */
737 	 bfd_elf_generic_reloc,	/* special_function */
738 	 "R_860_HIGOTOFF",	/* name */
739 	 TRUE,			/* partial_inplace */
740 	 0xffffffff,		/* src_mask */
741 	 0xffffffff,		/* dst_mask */
742 	 FALSE),	        /* pcrel_offset */
743 };
744 
745 static unsigned char elf_code_to_howto_index[R_860_max + 1];
746 
747 static reloc_howto_type *
lookup_howto(unsigned int rtype)748 lookup_howto (unsigned int rtype)
749 {
750   static int initialized = 0;
751   int i;
752   int howto_tbl_size = (int) (sizeof (elf32_i860_howto_table)
753 			/ sizeof (elf32_i860_howto_table[0]));
754 
755   if (! initialized)
756     {
757       initialized = 1;
758       memset (elf_code_to_howto_index, 0xff,
759 	      sizeof (elf_code_to_howto_index));
760       for (i = 0; i < howto_tbl_size; i++)
761         elf_code_to_howto_index[elf32_i860_howto_table[i].type] = i;
762     }
763 
764   BFD_ASSERT (rtype <= R_860_max);
765   i = elf_code_to_howto_index[rtype];
766   if (i >= howto_tbl_size)
767     return 0;
768   return elf32_i860_howto_table + i;
769 }
770 
771 /* Given a BFD reloc, return the matching HOWTO structure.  */
772 static reloc_howto_type *
elf32_i860_reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)773 elf32_i860_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
774 			      bfd_reloc_code_real_type code)
775 {
776   unsigned int rtype;
777 
778   switch (code)
779     {
780     case BFD_RELOC_NONE:
781       rtype = R_860_NONE;
782       break;
783     case BFD_RELOC_32:
784       rtype = R_860_32;
785       break;
786     case BFD_RELOC_860_COPY:
787       rtype = R_860_COPY;
788       break;
789     case BFD_RELOC_860_GLOB_DAT:
790       rtype = R_860_GLOB_DAT;
791       break;
792     case BFD_RELOC_860_JUMP_SLOT:
793       rtype = R_860_JUMP_SLOT;
794       break;
795     case BFD_RELOC_860_RELATIVE:
796       rtype = R_860_RELATIVE;
797       break;
798     case BFD_RELOC_860_PC26:
799       rtype = R_860_PC26;
800       break;
801     case BFD_RELOC_860_PLT26:
802       rtype = R_860_PLT26;
803       break;
804     case BFD_RELOC_860_PC16:
805       rtype = R_860_PC16;
806       break;
807     case BFD_RELOC_860_LOW0:
808       rtype = R_860_LOW0;
809       break;
810     case BFD_RELOC_860_SPLIT0:
811       rtype = R_860_SPLIT0;
812       break;
813     case BFD_RELOC_860_LOW1:
814       rtype = R_860_LOW1;
815       break;
816     case BFD_RELOC_860_SPLIT1:
817       rtype = R_860_SPLIT1;
818       break;
819     case BFD_RELOC_860_LOW2:
820       rtype = R_860_LOW2;
821       break;
822     case BFD_RELOC_860_SPLIT2:
823       rtype = R_860_SPLIT2;
824       break;
825     case BFD_RELOC_860_LOW3:
826       rtype = R_860_LOW3;
827       break;
828     case BFD_RELOC_860_LOGOT0:
829       rtype = R_860_LOGOT0;
830       break;
831     case BFD_RELOC_860_SPGOT0:
832       rtype = R_860_SPGOT0;
833       break;
834     case BFD_RELOC_860_LOGOT1:
835       rtype = R_860_LOGOT1;
836       break;
837     case BFD_RELOC_860_SPGOT1:
838       rtype = R_860_SPGOT1;
839       break;
840     case BFD_RELOC_860_LOGOTOFF0:
841       rtype = R_860_LOGOTOFF0;
842       break;
843     case BFD_RELOC_860_SPGOTOFF0:
844       rtype = R_860_SPGOTOFF0;
845       break;
846     case BFD_RELOC_860_LOGOTOFF1:
847       rtype = R_860_LOGOTOFF1;
848       break;
849     case BFD_RELOC_860_SPGOTOFF1:
850       rtype = R_860_SPGOTOFF1;
851       break;
852     case BFD_RELOC_860_LOGOTOFF2:
853       rtype = R_860_LOGOTOFF2;
854       break;
855     case BFD_RELOC_860_LOGOTOFF3:
856       rtype = R_860_LOGOTOFF3;
857       break;
858     case BFD_RELOC_860_LOPC:
859       rtype = R_860_LOPC;
860       break;
861     case BFD_RELOC_860_HIGHADJ:
862       rtype = R_860_HIGHADJ;
863       break;
864     case BFD_RELOC_860_HAGOT:
865       rtype = R_860_HAGOT;
866       break;
867     case BFD_RELOC_860_HAGOTOFF:
868       rtype = R_860_HAGOTOFF;
869       break;
870     case BFD_RELOC_860_HAPC:
871       rtype = R_860_HAPC;
872       break;
873     case BFD_RELOC_860_HIGH:
874       rtype = R_860_HIGH;
875       break;
876     case BFD_RELOC_860_HIGOT:
877       rtype = R_860_HIGOT;
878       break;
879     case BFD_RELOC_860_HIGOTOFF:
880       rtype = R_860_HIGOTOFF;
881       break;
882     default:
883       rtype = 0;
884       break;
885     }
886   return lookup_howto (rtype);
887 }
888 
889 static reloc_howto_type *
elf32_i860_reloc_name_lookup(bfd * abfd ATTRIBUTE_UNUSED,const char * r_name)890 elf32_i860_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
891 			      const char *r_name)
892 {
893   unsigned int i;
894 
895   for (i = 0;
896        i < (sizeof (elf32_i860_howto_table)
897 	    / sizeof (elf32_i860_howto_table[0]));
898        i++)
899     if (elf32_i860_howto_table[i].name != NULL
900 	&& strcasecmp (elf32_i860_howto_table[i].name, r_name) == 0)
901       return &elf32_i860_howto_table[i];
902 
903   return NULL;
904 }
905 
906 /* Given a ELF reloc, return the matching HOWTO structure.  */
907 static void
elf32_i860_info_to_howto_rela(bfd * abfd ATTRIBUTE_UNUSED,arelent * bfd_reloc,Elf_Internal_Rela * elf_reloc)908 elf32_i860_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
909 			       arelent *bfd_reloc,
910 			       Elf_Internal_Rela *elf_reloc)
911 {
912   bfd_reloc->howto
913     = lookup_howto ((unsigned) ELF32_R_TYPE (elf_reloc->r_info));
914 }
915 
916 /* Specialized relocation handler for R_860_SPLITn.  These relocations
917    involves a 16-bit field that is split into two contiguous parts.  */
918 static bfd_reloc_status_type
elf32_i860_relocate_splitn(bfd * input_bfd,Elf_Internal_Rela * rello,bfd_byte * contents,bfd_vma value)919 elf32_i860_relocate_splitn (bfd *input_bfd,
920 			    Elf_Internal_Rela *rello,
921 			    bfd_byte *contents,
922 			    bfd_vma value)
923 {
924   bfd_vma insn;
925   reloc_howto_type *howto;
926   howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
927   insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
928 
929   /* Relocate.  */
930   value += rello->r_addend;
931 
932   /* Separate the fields and insert.  */
933   value = (((value & 0xf800) << 5) | (value & 0x7ff)) & howto->dst_mask;
934   insn = (insn & ~howto->dst_mask) | value;
935 
936   bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
937   return bfd_reloc_ok;
938 }
939 
940 /* Specialized relocation handler for R_860_PC16.  This relocation
941    involves a 16-bit, PC-relative field that is split into two contiguous
942    parts.  */
943 static bfd_reloc_status_type
elf32_i860_relocate_pc16(bfd * input_bfd,asection * input_section,Elf_Internal_Rela * rello,bfd_byte * contents,bfd_vma value)944 elf32_i860_relocate_pc16 (bfd *input_bfd,
945 			  asection *input_section,
946 			  Elf_Internal_Rela *rello,
947 			  bfd_byte *contents,
948 			  bfd_vma value)
949 {
950   bfd_vma insn;
951   reloc_howto_type *howto;
952   howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
953   insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
954 
955   /* Adjust for PC-relative relocation.  */
956   value -= (input_section->output_section->vma
957 	    + input_section->output_offset);
958   value -= rello->r_offset;
959 
960   /* Relocate.  */
961   value += rello->r_addend;
962 
963   /* Adjust the value by 4, then separate the fields and insert.  */
964   value = (value - 4) >> howto->rightshift;
965   value = (((value & 0xf800) << 5) | (value & 0x7ff)) & howto->dst_mask;
966   insn = (insn & ~howto->dst_mask) | value;
967 
968   bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
969   return bfd_reloc_ok;
970 
971 }
972 
973 /* Specialized relocation handler for R_860_PC26.  This relocation
974    involves a 26-bit, PC-relative field which must be adjusted by 4.  */
975 static bfd_reloc_status_type
elf32_i860_relocate_pc26(bfd * input_bfd,asection * input_section,Elf_Internal_Rela * rello,bfd_byte * contents,bfd_vma value)976 elf32_i860_relocate_pc26 (bfd *input_bfd,
977 			  asection *input_section,
978 			  Elf_Internal_Rela *rello,
979 			  bfd_byte *contents,
980 			  bfd_vma value)
981 {
982   bfd_vma insn;
983   reloc_howto_type *howto;
984   howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
985   insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
986 
987   /* Adjust for PC-relative relocation.  */
988   value -= (input_section->output_section->vma
989 	    + input_section->output_offset);
990   value -= rello->r_offset;
991 
992   /* Relocate.  */
993   value += rello->r_addend;
994 
995   /* Adjust value by 4 and insert the field.  */
996   value = ((value - 4) >> howto->rightshift) & howto->dst_mask;
997   insn = (insn & ~howto->dst_mask) | value;
998 
999   bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
1000   return bfd_reloc_ok;
1001 
1002 }
1003 
1004 /* Specialized relocation handler for R_860_HIGHADJ.  */
1005 static bfd_reloc_status_type
elf32_i860_relocate_highadj(bfd * input_bfd,Elf_Internal_Rela * rel,bfd_byte * contents,bfd_vma value)1006 elf32_i860_relocate_highadj (bfd *input_bfd,
1007 			     Elf_Internal_Rela *rel,
1008 			     bfd_byte *contents,
1009 			     bfd_vma value)
1010 {
1011   bfd_vma insn;
1012 
1013   insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
1014 
1015   value += rel->r_addend;
1016   value += 0x8000;
1017   value = ((value >> 16) & 0xffff);
1018 
1019   insn = (insn & 0xffff0000) | value;
1020 
1021   bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
1022   return bfd_reloc_ok;
1023 }
1024 
1025 /* Perform a single relocation.  By default we use the standard BFD
1026    routines. However, we handle some specially.  */
1027 static bfd_reloc_status_type
i860_final_link_relocate(reloc_howto_type * howto,bfd * input_bfd,asection * input_section,bfd_byte * contents,Elf_Internal_Rela * rel,bfd_vma relocation)1028 i860_final_link_relocate (reloc_howto_type *howto,
1029 			  bfd *input_bfd,
1030 			  asection *input_section,
1031 			  bfd_byte *contents,
1032 			  Elf_Internal_Rela *rel,
1033 			  bfd_vma relocation)
1034 {
1035   return _bfd_final_link_relocate (howto, input_bfd, input_section,
1036 				   contents, rel->r_offset, relocation,
1037 				   rel->r_addend);
1038 }
1039 
1040 /* Relocate an i860 ELF section.
1041 
1042    This is boiler-plate code copied from fr30.
1043 
1044    The RELOCATE_SECTION function is called by the new ELF backend linker
1045    to handle the relocations for a section.
1046 
1047    The relocs are always passed as Rela structures; if the section
1048    actually uses Rel structures, the r_addend field will always be
1049    zero.
1050 
1051    This function is responsible for adjusting the section contents as
1052    necessary, and (if using Rela relocs and generating a relocatable
1053    output file) adjusting the reloc addend as necessary.
1054 
1055    This function does not have to worry about setting the reloc
1056    address or the reloc symbol index.
1057 
1058    LOCAL_SYMS is a pointer to the swapped in local symbols.
1059 
1060    LOCAL_SECTIONS is an array giving the section in the input file
1061    corresponding to the st_shndx field of each local symbol.
1062 
1063    The global hash table entry for the global symbols can be found
1064    via elf_sym_hashes (input_bfd).
1065 
1066    When generating relocatable output, this function must handle
1067    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
1068    going to be the section symbol corresponding to the output
1069    section, which means that the addend must be adjusted
1070    accordingly.  */
1071 static bfd_boolean
elf32_i860_relocate_section(bfd * output_bfd ATTRIBUTE_UNUSED,struct bfd_link_info * info,bfd * input_bfd,asection * input_section,bfd_byte * contents,Elf_Internal_Rela * relocs,Elf_Internal_Sym * local_syms,asection ** local_sections)1072 elf32_i860_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
1073 			     struct bfd_link_info *info,
1074 			     bfd *input_bfd,
1075 			     asection *input_section,
1076 			     bfd_byte *contents,
1077 			     Elf_Internal_Rela *relocs,
1078 			     Elf_Internal_Sym *local_syms,
1079 			     asection **local_sections)
1080 {
1081   Elf_Internal_Shdr *symtab_hdr;
1082   struct elf_link_hash_entry **sym_hashes;
1083   Elf_Internal_Rela *rel;
1084   Elf_Internal_Rela *relend;
1085 
1086   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
1087   sym_hashes = elf_sym_hashes (input_bfd);
1088   relend     = relocs + input_section->reloc_count;
1089 
1090   for (rel = relocs; rel < relend; rel ++)
1091     {
1092       reloc_howto_type *           howto;
1093       unsigned long                r_symndx;
1094       Elf_Internal_Sym *           sym;
1095       asection *                   sec;
1096       struct elf_link_hash_entry * h;
1097       bfd_vma                      relocation;
1098       bfd_reloc_status_type        r;
1099       const char *                 name = NULL;
1100       int                          r_type;
1101 
1102       r_type = ELF32_R_TYPE (rel->r_info);
1103       r_symndx = ELF32_R_SYM (rel->r_info);
1104 
1105       howto = lookup_howto ((unsigned) ELF32_R_TYPE (rel->r_info));
1106       h     = NULL;
1107       sym   = NULL;
1108       sec   = NULL;
1109 
1110       if (r_symndx < symtab_hdr->sh_info)
1111 	{
1112 	  sym = local_syms + r_symndx;
1113 	  sec = local_sections [r_symndx];
1114 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1115 
1116 	  name = bfd_elf_string_from_elf_section
1117 	    (input_bfd, symtab_hdr->sh_link, sym->st_name);
1118 	  name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
1119 	}
1120       else
1121 	{
1122 	  bfd_boolean unresolved_reloc, warned, ignored;
1123 
1124 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1125 				   r_symndx, symtab_hdr, sym_hashes,
1126 				   h, sec, relocation,
1127 				   unresolved_reloc, warned, ignored);
1128 	}
1129 
1130       if (sec != NULL && discarded_section (sec))
1131 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
1132 					 rel, 1, relend, howto, 0, contents);
1133 
1134       if (info->relocatable)
1135 	continue;
1136 
1137       switch (r_type)
1138 	{
1139 	default:
1140 	  r = i860_final_link_relocate (howto, input_bfd, input_section,
1141 					contents, rel, relocation);
1142 	  break;
1143 
1144 	case R_860_HIGHADJ:
1145 	  r = elf32_i860_relocate_highadj (input_bfd, rel, contents,
1146 					   relocation);
1147 	  break;
1148 
1149 	case R_860_PC16:
1150 	  r = elf32_i860_relocate_pc16 (input_bfd, input_section, rel,
1151 					contents, relocation);
1152 	  break;
1153 
1154 	case R_860_PC26:
1155 	  r = elf32_i860_relocate_pc26 (input_bfd, input_section, rel,
1156 					contents, relocation);
1157 	  break;
1158 
1159 	case R_860_SPLIT0:
1160 	case R_860_SPLIT1:
1161 	case R_860_SPLIT2:
1162 	  r = elf32_i860_relocate_splitn (input_bfd, rel, contents,
1163 					  relocation);
1164 	  break;
1165 
1166 	/* We do not yet handle GOT/PLT/Dynamic relocations.  */
1167 	case R_860_COPY:
1168 	case R_860_GLOB_DAT:
1169 	case R_860_JUMP_SLOT:
1170 	case R_860_RELATIVE:
1171 	case R_860_PLT26:
1172 	case R_860_LOGOT0:
1173 	case R_860_SPGOT0:
1174 	case R_860_LOGOT1:
1175 	case R_860_SPGOT1:
1176 	case R_860_LOGOTOFF0:
1177 	case R_860_SPGOTOFF0:
1178 	case R_860_LOGOTOFF1:
1179 	case R_860_SPGOTOFF1:
1180 	case R_860_LOGOTOFF2:
1181 	case R_860_LOGOTOFF3:
1182 	case R_860_LOPC:
1183 	case R_860_HAGOT:
1184 	case R_860_HAGOTOFF:
1185 	case R_860_HAPC:
1186 	case R_860_HIGOT:
1187 	case R_860_HIGOTOFF:
1188 	  r = bfd_reloc_notsupported;
1189 	  break;
1190 	}
1191 
1192       if (r != bfd_reloc_ok)
1193 	{
1194 	  const char * msg = (const char *) NULL;
1195 
1196 	  switch (r)
1197 	    {
1198 	    case bfd_reloc_overflow:
1199 	      r = info->callbacks->reloc_overflow
1200 		(info, (h ? &h->root : NULL), name, howto->name,
1201 		 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
1202 	      break;
1203 
1204 	    case bfd_reloc_undefined:
1205 	      r = info->callbacks->undefined_symbol
1206 		(info, name, input_bfd, input_section, rel->r_offset, TRUE);
1207 	      break;
1208 
1209 	    case bfd_reloc_outofrange:
1210 	      msg = _("internal error: out of range error");
1211 	      break;
1212 
1213 	    case bfd_reloc_notsupported:
1214 	      msg = _("internal error: unsupported relocation error");
1215 	      break;
1216 
1217 	    case bfd_reloc_dangerous:
1218 	      msg = _("internal error: dangerous relocation");
1219 	      break;
1220 
1221 	    default:
1222 	      msg = _("internal error: unknown error");
1223 	      break;
1224 	    }
1225 
1226 	  if (msg)
1227 	    r = info->callbacks->warning
1228 	      (info, msg, name, input_bfd, input_section, rel->r_offset);
1229 
1230 	  if (! r)
1231 	    return FALSE;
1232 	}
1233     }
1234 
1235   return TRUE;
1236 }
1237 
1238 /* Return whether a symbol name implies a local label.  SVR4/860 compilers
1239    generate labels of the form ".ep.function_name" to denote the end of a
1240    function prolog. These should be local.
1241    ??? Do any other SVR4 compilers have this convention? If so, this should
1242    be added to the generic routine.  */
1243 static bfd_boolean
elf32_i860_is_local_label_name(bfd * abfd,const char * name)1244 elf32_i860_is_local_label_name (bfd *abfd, const char *name)
1245 {
1246   if (name[0] == '.' && name[1] == 'e' && name[2] == 'p' && name[3] == '.')
1247     return TRUE;
1248 
1249   return _bfd_elf_is_local_label_name (abfd, name);
1250 }
1251 
1252 #define TARGET_BIG_SYM		i860_elf32_vec
1253 #define TARGET_BIG_NAME		"elf32-i860"
1254 #define TARGET_LITTLE_SYM	i860_elf32_le_vec
1255 #define TARGET_LITTLE_NAME	"elf32-i860-little"
1256 #define ELF_ARCH		bfd_arch_i860
1257 #define ELF_MACHINE_CODE	EM_860
1258 #define ELF_MAXPAGESIZE		4096
1259 
1260 #define elf_backend_rela_normal			1
1261 #define elf_info_to_howto_rel                   NULL
1262 #define elf_info_to_howto			elf32_i860_info_to_howto_rela
1263 #define elf_backend_relocate_section		elf32_i860_relocate_section
1264 #define bfd_elf32_bfd_reloc_type_lookup		elf32_i860_reloc_type_lookup
1265 #define bfd_elf32_bfd_reloc_name_lookup	elf32_i860_reloc_name_lookup
1266 #define bfd_elf32_bfd_is_local_label_name	elf32_i860_is_local_label_name
1267 
1268 #include "elf32-target.h"
1269