xref: /openbsd/gnu/usr.bin/binutils/bfd/elf32-i860.c (revision 007c2a45)
1 /* Intel i860 specific support for 32-bit ELF.
2    Copyright 1993, 1995, 1999, 2000, 2001, 2002, 2003, 2004
3    Free Software Foundation, Inc.
4 
5    Full i860 support contributed by Jason Eckhardt <jle@cygnus.com>.
6 
7 This file is part of BFD, the Binary File Descriptor library.
8 
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
22 
23 #include "bfd.h"
24 #include "sysdep.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 > input_section->_cooked_size)
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 > input_section->_cooked_size)
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 > input_section->_cooked_size)
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 > input_section->_cooked_size)
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 /* Given a ELF reloc, return the matching HOWTO structure.  */
890 static void
elf32_i860_info_to_howto_rela(bfd * abfd ATTRIBUTE_UNUSED,arelent * bfd_reloc,Elf_Internal_Rela * elf_reloc)891 elf32_i860_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
892 			       arelent *bfd_reloc,
893 			       Elf_Internal_Rela *elf_reloc)
894 {
895   bfd_reloc->howto
896     = lookup_howto ((unsigned) ELF32_R_TYPE (elf_reloc->r_info));
897 }
898 
899 /* Specialized relocation handler for R_860_SPLITn.  These relocations
900    involves a 16-bit field that is split into two contiguous parts.  */
901 static bfd_reloc_status_type
elf32_i860_relocate_splitn(bfd * input_bfd,Elf_Internal_Rela * rello,bfd_byte * contents,bfd_vma value)902 elf32_i860_relocate_splitn (bfd *input_bfd,
903 			    Elf_Internal_Rela *rello,
904 			    bfd_byte *contents,
905 			    bfd_vma value)
906 {
907   bfd_vma insn;
908   reloc_howto_type *howto;
909   howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
910   insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
911 
912   /* Relocate.  */
913   value += rello->r_addend;
914 
915   /* Separate the fields and insert.  */
916   value = (((value & 0xf800) << 5) | (value & 0x7ff)) & howto->dst_mask;
917   insn = (insn & ~howto->dst_mask) | value;
918 
919   bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
920   return bfd_reloc_ok;
921 }
922 
923 /* Specialized relocation handler for R_860_PC16.  This relocation
924    involves a 16-bit, PC-relative field that is split into two contiguous
925    parts.  */
926 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)927 elf32_i860_relocate_pc16 (bfd *input_bfd,
928 			  asection *input_section,
929 			  Elf_Internal_Rela *rello,
930 			  bfd_byte *contents,
931 			  bfd_vma value)
932 {
933   bfd_vma insn;
934   reloc_howto_type *howto;
935   howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
936   insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
937 
938   /* Adjust for PC-relative relocation.  */
939   value -= (input_section->output_section->vma
940 	    + input_section->output_offset);
941   value -= rello->r_offset;
942 
943   /* Relocate.  */
944   value += rello->r_addend;
945 
946   /* Adjust the value by 4, then separate the fields and insert.  */
947   value = (value - 4) >> howto->rightshift;
948   value = (((value & 0xf800) << 5) | (value & 0x7ff)) & howto->dst_mask;
949   insn = (insn & ~howto->dst_mask) | value;
950 
951   bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
952   return bfd_reloc_ok;
953 
954 }
955 
956 /* Specialized relocation handler for R_860_PC26.  This relocation
957    involves a 26-bit, PC-relative field which must be adjusted by 4.  */
958 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)959 elf32_i860_relocate_pc26 (bfd *input_bfd,
960 			  asection *input_section,
961 			  Elf_Internal_Rela *rello,
962 			  bfd_byte *contents,
963 			  bfd_vma value)
964 {
965   bfd_vma insn;
966   reloc_howto_type *howto;
967   howto = lookup_howto ((unsigned) ELF32_R_TYPE (rello->r_info));
968   insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
969 
970   /* Adjust for PC-relative relocation.  */
971   value -= (input_section->output_section->vma
972 	    + input_section->output_offset);
973   value -= rello->r_offset;
974 
975   /* Relocate.  */
976   value += rello->r_addend;
977 
978   /* Adjust value by 4 and insert the field.  */
979   value = ((value - 4) >> howto->rightshift) & howto->dst_mask;
980   insn = (insn & ~howto->dst_mask) | value;
981 
982   bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
983   return bfd_reloc_ok;
984 
985 }
986 
987 /* Specialized relocation handler for R_860_HIGHADJ.  */
988 static bfd_reloc_status_type
elf32_i860_relocate_highadj(bfd * input_bfd,Elf_Internal_Rela * rel,bfd_byte * contents,bfd_vma value)989 elf32_i860_relocate_highadj (bfd *input_bfd,
990 			     Elf_Internal_Rela *rel,
991 			     bfd_byte *contents,
992 			     bfd_vma value)
993 {
994   bfd_vma insn;
995 
996   insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
997 
998   value += rel->r_addend;
999   value += 0x8000;
1000   value = ((value >> 16) & 0xffff);
1001 
1002   insn = (insn & 0xffff0000) | value;
1003 
1004   bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
1005   return bfd_reloc_ok;
1006 }
1007 
1008 /* Perform a single relocation.  By default we use the standard BFD
1009    routines. However, we handle some specially.  */
1010 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)1011 i860_final_link_relocate (reloc_howto_type *howto,
1012 			  bfd *input_bfd,
1013 			  asection *input_section,
1014 			  bfd_byte *contents,
1015 			  Elf_Internal_Rela *rel,
1016 			  bfd_vma relocation)
1017 {
1018   return _bfd_final_link_relocate (howto, input_bfd, input_section,
1019 				   contents, rel->r_offset, relocation,
1020 				   rel->r_addend);
1021 }
1022 
1023 /* Relocate an i860 ELF section.
1024 
1025    This is boiler-plate code copied from fr30.
1026 
1027    The RELOCATE_SECTION function is called by the new ELF backend linker
1028    to handle the relocations for a section.
1029 
1030    The relocs are always passed as Rela structures; if the section
1031    actually uses Rel structures, the r_addend field will always be
1032    zero.
1033 
1034    This function is responsible for adjusting the section contents as
1035    necessary, and (if using Rela relocs and generating a relocatable
1036    output file) adjusting the reloc addend as necessary.
1037 
1038    This function does not have to worry about setting the reloc
1039    address or the reloc symbol index.
1040 
1041    LOCAL_SYMS is a pointer to the swapped in local symbols.
1042 
1043    LOCAL_SECTIONS is an array giving the section in the input file
1044    corresponding to the st_shndx field of each local symbol.
1045 
1046    The global hash table entry for the global symbols can be found
1047    via elf_sym_hashes (input_bfd).
1048 
1049    When generating relocatable output, this function must handle
1050    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
1051    going to be the section symbol corresponding to the output
1052    section, which means that the addend must be adjusted
1053    accordingly.  */
1054 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)1055 elf32_i860_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
1056 			     struct bfd_link_info *info,
1057 			     bfd *input_bfd,
1058 			     asection *input_section,
1059 			     bfd_byte *contents,
1060 			     Elf_Internal_Rela *relocs,
1061 			     Elf_Internal_Sym *local_syms,
1062 			     asection **local_sections)
1063 {
1064   Elf_Internal_Shdr *symtab_hdr;
1065   struct elf_link_hash_entry **sym_hashes;
1066   Elf_Internal_Rela *rel;
1067   Elf_Internal_Rela *relend;
1068 
1069   if (info->relocatable)
1070     return TRUE;
1071 
1072   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
1073   sym_hashes = elf_sym_hashes (input_bfd);
1074   relend     = relocs + input_section->reloc_count;
1075 
1076   for (rel = relocs; rel < relend; rel ++)
1077     {
1078       reloc_howto_type *           howto;
1079       unsigned long                r_symndx;
1080       Elf_Internal_Sym *           sym;
1081       asection *                   sec;
1082       struct elf_link_hash_entry * h;
1083       bfd_vma                      relocation;
1084       bfd_reloc_status_type        r;
1085       const char *                 name = NULL;
1086       int                          r_type;
1087 
1088       r_type = ELF32_R_TYPE (rel->r_info);
1089 
1090 #if 0
1091       if (   r_type == R_860_GNU_VTINHERIT
1092 	  || r_type == R_860_GNU_VTENTRY)
1093 	continue;
1094 #endif
1095 
1096       r_symndx = ELF32_R_SYM (rel->r_info);
1097 
1098       howto = lookup_howto ((unsigned) ELF32_R_TYPE (rel->r_info));
1099       h     = NULL;
1100       sym   = NULL;
1101       sec   = NULL;
1102 
1103       if (r_symndx < symtab_hdr->sh_info)
1104 	{
1105 	  sym = local_syms + r_symndx;
1106 	  sec = local_sections [r_symndx];
1107 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1108 
1109 	  name = bfd_elf_string_from_elf_section
1110 	    (input_bfd, symtab_hdr->sh_link, sym->st_name);
1111 	  name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
1112 	}
1113       else
1114 	{
1115 	  bfd_boolean unresolved_reloc, warned;
1116 
1117 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1118 				   r_symndx, symtab_hdr, sym_hashes,
1119 				   h, sec, relocation,
1120 				   unresolved_reloc, warned);
1121 	}
1122 
1123       switch (r_type)
1124 	{
1125 	default:
1126 	  r = i860_final_link_relocate (howto, input_bfd, input_section,
1127 					contents, rel, relocation);
1128 	  break;
1129 
1130 	case R_860_HIGHADJ:
1131 	  r = elf32_i860_relocate_highadj (input_bfd, rel, contents,
1132 					   relocation);
1133 	  break;
1134 
1135 	case R_860_PC16:
1136 	  r = elf32_i860_relocate_pc16 (input_bfd, input_section, rel,
1137 					contents, relocation);
1138 	  break;
1139 
1140 	case R_860_PC26:
1141 	  r = elf32_i860_relocate_pc26 (input_bfd, input_section, rel,
1142 					contents, relocation);
1143 	  break;
1144 
1145 	case R_860_SPLIT0:
1146 	case R_860_SPLIT1:
1147 	case R_860_SPLIT2:
1148 	  r = elf32_i860_relocate_splitn (input_bfd, rel, contents,
1149 					  relocation);
1150 	  break;
1151 
1152 	/* We do not yet handle GOT/PLT/Dynamic relocations.  */
1153 	case R_860_COPY:
1154 	case R_860_GLOB_DAT:
1155 	case R_860_JUMP_SLOT:
1156 	case R_860_RELATIVE:
1157 	case R_860_PLT26:
1158 	case R_860_LOGOT0:
1159 	case R_860_SPGOT0:
1160 	case R_860_LOGOT1:
1161 	case R_860_SPGOT1:
1162 	case R_860_LOGOTOFF0:
1163 	case R_860_SPGOTOFF0:
1164 	case R_860_LOGOTOFF1:
1165 	case R_860_SPGOTOFF1:
1166 	case R_860_LOGOTOFF2:
1167 	case R_860_LOGOTOFF3:
1168 	case R_860_LOPC:
1169 	case R_860_HAGOT:
1170 	case R_860_HAGOTOFF:
1171 	case R_860_HAPC:
1172 	case R_860_HIGOT:
1173 	case R_860_HIGOTOFF:
1174 	  r = bfd_reloc_notsupported;
1175 	  break;
1176 	}
1177 
1178       if (r != bfd_reloc_ok)
1179 	{
1180 	  const char * msg = (const char *) NULL;
1181 
1182 	  switch (r)
1183 	    {
1184 	    case bfd_reloc_overflow:
1185 	      r = info->callbacks->reloc_overflow
1186 		(info, name, howto->name, (bfd_vma) 0,
1187 		 input_bfd, input_section, rel->r_offset);
1188 	      break;
1189 
1190 	    case bfd_reloc_undefined:
1191 	      r = info->callbacks->undefined_symbol
1192 		(info, name, input_bfd, input_section, rel->r_offset, TRUE);
1193 	      break;
1194 
1195 	    case bfd_reloc_outofrange:
1196 	      msg = _("internal error: out of range error");
1197 	      break;
1198 
1199 	    case bfd_reloc_notsupported:
1200 	      msg = _("internal error: unsupported relocation error");
1201 	      break;
1202 
1203 	    case bfd_reloc_dangerous:
1204 	      msg = _("internal error: dangerous relocation");
1205 	      break;
1206 
1207 	    default:
1208 	      msg = _("internal error: unknown error");
1209 	      break;
1210 	    }
1211 
1212 	  if (msg)
1213 	    r = info->callbacks->warning
1214 	      (info, msg, name, input_bfd, input_section, rel->r_offset);
1215 
1216 	  if (! r)
1217 	    return FALSE;
1218 	}
1219     }
1220 
1221   return TRUE;
1222 }
1223 
1224 /* Return whether a symbol name implies a local label.  SVR4/860 compilers
1225    generate labels of the form ".ep.function_name" to denote the end of a
1226    function prolog. These should be local.
1227    ??? Do any other SVR4 compilers have this convention? If so, this should
1228    be added to the generic routine.  */
1229 static bfd_boolean
elf32_i860_is_local_label_name(bfd * abfd,const char * name)1230 elf32_i860_is_local_label_name (bfd *abfd, const char *name)
1231 {
1232   if (name[0] == '.' && name[1] == 'e' && name[2] == 'p' && name[3] == '.')
1233     return TRUE;
1234 
1235   return _bfd_elf_is_local_label_name (abfd, name);
1236 }
1237 
1238 #define TARGET_BIG_SYM		bfd_elf32_i860_vec
1239 #define TARGET_BIG_NAME		"elf32-i860"
1240 #define TARGET_LITTLE_SYM	bfd_elf32_i860_little_vec
1241 #define TARGET_LITTLE_NAME	"elf32-i860-little"
1242 #define ELF_ARCH		bfd_arch_i860
1243 #define ELF_MACHINE_CODE	EM_860
1244 #define ELF_MAXPAGESIZE		4096
1245 
1246 #define elf_backend_rela_normal			1
1247 #define elf_info_to_howto_rel                   NULL
1248 #define elf_info_to_howto			elf32_i860_info_to_howto_rela
1249 #define elf_backend_relocate_section		elf32_i860_relocate_section
1250 #define bfd_elf32_bfd_reloc_type_lookup		elf32_i860_reloc_type_lookup
1251 #define bfd_elf32_bfd_is_local_label_name	elf32_i860_is_local_label_name
1252 
1253 #include "elf32-target.h"
1254