2002-06-14 H.J. Lu <hjl@gnu.org>
[binutils.git] / bfd / cpu-ns32k.c
blob2cfa26fe7d4158ca80212b90c6748205b8d13a34
1 /* BFD support for the ns32k architecture.
2 Copyright 1990, 1991, 1994, 1995, 1998, 2000, 2001
3 Free Software Foundation, Inc.
4 Almost totally rewritten by Ian Dall from initial work
5 by Andrew Cagney.
7 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
23 #include "bfd.h"
24 #include "sysdep.h"
25 #include "libbfd.h"
26 #include "ns32k.h"
28 #define N(machine, printable, d, next) \
29 { 32, 32, 8, bfd_arch_ns32k, machine, "ns32k",printable,3,d,bfd_default_compatible,bfd_default_scan, next, }
31 static const bfd_arch_info_type arch_info_struct[] =
33 N(32532,"ns32k:32532",true, 0), /* the word ns32k will match this too */
36 const bfd_arch_info_type bfd_ns32k_arch =
37 N(32032,"ns32k:32032",false, &arch_info_struct[0]);
39 static bfd_reloc_status_type do_ns32k_reloc
40 PARAMS ((bfd *, arelent *, struct symbol_cache_entry *, PTR, asection *,
41 bfd *, char **,
42 bfd_vma (*) (bfd_byte *, int),
43 int (*) (bfd_vma, bfd_byte *, int)));
45 bfd_vma
46 _bfd_ns32k_get_displacement (buffer, size)
47 bfd_byte *buffer;
48 int size;
50 bfd_signed_vma value;
51 switch (size)
53 case 1:
54 value = ((*buffer & 0x7f) ^ 0x40) - 0x40;
55 break;
57 case 2:
58 value = ((*buffer++ & 0x3f) ^ 0x20) - 0x20;
59 value = (value << 8) | (0xff & *buffer);
60 break;
62 case 4:
63 value = ((*buffer++ & 0x3f) ^ 0x20) - 0x20;
64 value = (value << 8) | (0xff & *buffer++);
65 value = (value << 8) | (0xff & *buffer++);
66 value = (value << 8) | (0xff & *buffer);
67 break;
69 default:
70 abort ();
71 return 0;
73 return value;
76 int
77 _bfd_ns32k_put_displacement (value, buffer, size)
78 bfd_vma value;
79 bfd_byte *buffer;
80 int size;
82 switch (size)
84 case 1:
85 if (value + 0x40 > 0x7f)
86 return -1;
87 value &= 0x7f;
88 *buffer++ = value;
89 break;
91 case 2:
92 if (value + 0x2000 > 0x3fff)
93 return -1;
94 value &= 0x3fff;
95 value |= 0x8000;
96 *buffer++ = (value >> 8);
97 *buffer++ = value;
98 break;
100 case 4:
101 /* FIXME: is this correct? -0x1f000000 <= value < 0x2000000 */
102 if (value + 0x1f000000 > 0x3effffff)
103 return -1;
104 value |= (bfd_vma) 0xc0000000;
105 *buffer++ = (value >> 24);
106 *buffer++ = (value >> 16);
107 *buffer++ = (value >> 8);
108 *buffer++ = value;
109 break;
110 default:
111 return -1;
113 return 0;
116 bfd_vma
117 _bfd_ns32k_get_immediate (buffer, size)
118 bfd_byte *buffer;
119 int size;
121 bfd_vma value = 0;
122 switch (size)
124 case 8:
125 value = (value << 8) | (*buffer++ & 0xff);
126 value = (value << 8) | (*buffer++ & 0xff);
127 value = (value << 8) | (*buffer++ & 0xff);
128 value = (value << 8) | (*buffer++ & 0xff);
129 case 4:
130 value = (value << 8) | (*buffer++ & 0xff);
131 value = (value << 8) | (*buffer++ & 0xff);
132 case 2:
133 value = (value << 8) | (*buffer++ & 0xff);
134 case 1:
135 value = (value << 8) | (*buffer++ & 0xff);
137 return value;
141 _bfd_ns32k_put_immediate (value, buffer, size)
142 bfd_vma value;
143 bfd_byte *buffer;
144 int size;
146 buffer += size - 1;
147 switch (size)
149 case 8:
150 *buffer-- = (value & 0xff); value >>= 8;
151 *buffer-- = (value & 0xff); value >>= 8;
152 *buffer-- = (value & 0xff); value >>= 8;
153 *buffer-- = (value & 0xff); value >>= 8;
154 case 4:
155 *buffer-- = (value & 0xff); value >>= 8;
156 *buffer-- = (value & 0xff); value >>= 8;
157 case 2:
158 *buffer-- = (value & 0xff); value >>= 8;
159 case 1:
160 *buffer-- = (value & 0xff); value >>= 8;
162 return 0;
165 /* This is just like the standard perform_relocation except we
166 * use get_data and put_data which know about the ns32k
167 * storage methods.
168 * This is probably a lot more complicated than it needs to be!
170 static bfd_reloc_status_type
171 do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
172 error_message, get_data, put_data)
173 bfd *abfd;
174 arelent *reloc_entry;
175 struct symbol_cache_entry *symbol;
176 PTR data;
177 asection *input_section;
178 bfd *output_bfd;
179 char **error_message ATTRIBUTE_UNUSED;
180 bfd_vma (*get_data) PARAMS ((bfd_byte *, int));
181 int (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
183 int overflow = 0;
184 bfd_vma relocation;
185 bfd_reloc_status_type flag = bfd_reloc_ok;
186 bfd_size_type addr = reloc_entry->address;
187 bfd_vma output_base = 0;
188 reloc_howto_type *howto = reloc_entry->howto;
189 asection *reloc_target_output_section;
190 bfd_byte *location;
192 if ((symbol->section == &bfd_abs_section)
193 && output_bfd != (bfd *) NULL)
195 reloc_entry->address += input_section->output_offset;
196 return bfd_reloc_ok;
199 /* If we are not producing relocateable output, return an error if
200 the symbol is not defined. An undefined weak symbol is
201 considered to have a value of zero (SVR4 ABI, p. 4-27). */
202 if (symbol->section == &bfd_und_section
203 && (symbol->flags & BSF_WEAK) == 0
204 && output_bfd == (bfd *) NULL)
205 flag = bfd_reloc_undefined;
207 /* Is the address of the relocation really within the section? */
208 if (reloc_entry->address > input_section->_cooked_size)
209 return bfd_reloc_outofrange;
211 /* Work out which section the relocation is targetted at and the
212 initial relocation command value. */
214 /* Get symbol value. (Common symbols are special.) */
215 if (bfd_is_com_section (symbol->section))
216 relocation = 0;
217 else
218 relocation = symbol->value;
220 reloc_target_output_section = symbol->section->output_section;
222 /* Convert input-section-relative symbol value to absolute. */
223 if (output_bfd && howto->partial_inplace == false)
224 output_base = 0;
225 else
226 output_base = reloc_target_output_section->vma;
228 relocation += output_base + symbol->section->output_offset;
230 /* Add in supplied addend. */
231 relocation += reloc_entry->addend;
233 /* Here the variable relocation holds the final address of the
234 symbol we are relocating against, plus any addend. */
236 if (howto->pc_relative == true)
238 /* This is a PC relative relocation. We want to set RELOCATION
239 to the distance between the address of the symbol and the
240 location. RELOCATION is already the address of the symbol.
242 We start by subtracting the address of the section containing
243 the location.
245 If pcrel_offset is set, we must further subtract the position
246 of the location within the section. Some targets arrange for
247 the addend to be the negative of the position of the location
248 within the section; for example, i386-aout does this. For
249 i386-aout, pcrel_offset is false. Some other targets do not
250 include the position of the location; for example, m88kbcs,
251 or ELF. For those targets, pcrel_offset is true.
253 If we are producing relocateable output, then we must ensure
254 that this reloc will be correctly computed when the final
255 relocation is done. If pcrel_offset is false we want to wind
256 up with the negative of the location within the section,
257 which means we must adjust the existing addend by the change
258 in the location within the section. If pcrel_offset is true
259 we do not want to adjust the existing addend at all.
261 FIXME: This seems logical to me, but for the case of
262 producing relocateable output it is not what the code
263 actually does. I don't want to change it, because it seems
264 far too likely that something will break. */
266 relocation -=
267 input_section->output_section->vma + input_section->output_offset;
269 if (howto->pcrel_offset == true)
270 relocation -= reloc_entry->address;
273 if (output_bfd != (bfd *) NULL)
275 if (howto->partial_inplace == false)
277 /* This is a partial relocation, and we want to apply the relocation
278 to the reloc entry rather than the raw data. Modify the reloc
279 inplace to reflect what we now know. */
280 reloc_entry->addend = relocation;
281 reloc_entry->address += input_section->output_offset;
282 return flag;
284 else
286 /* This is a partial relocation, but inplace, so modify the
287 reloc record a bit.
289 If we've relocated with a symbol with a section, change
290 into a ref to the section belonging to the symbol. */
292 reloc_entry->address += input_section->output_offset;
294 /* WTF?? */
295 if (abfd->xvec->flavour == bfd_target_coff_flavour)
297 #if 1
298 /* For m68k-coff, the addend was being subtracted twice during
299 relocation with -r. Removing the line below this comment
300 fixes that problem; see PR 2953.
302 However, Ian wrote the following, regarding removing the line below,
303 which explains why it is still enabled: --djm
305 If you put a patch like that into BFD you need to check all the COFF
306 linkers. I am fairly certain that patch will break coff-i386 (e.g.,
307 SCO); see coff_i386_reloc in coff-i386.c where I worked around the
308 problem in a different way. There may very well be a reason that the
309 code works as it does.
311 Hmmm. The first obvious point is that bfd_perform_relocation should
312 not have any tests that depend upon the flavour. It's seem like
313 entirely the wrong place for such a thing. The second obvious point
314 is that the current code ignores the reloc addend when producing
315 relocateable output for COFF. That's peculiar. In fact, I really
316 have no idea what the point of the line you want to remove is.
318 A typical COFF reloc subtracts the old value of the symbol and adds in
319 the new value to the location in the object file (if it's a pc
320 relative reloc it adds the difference between the symbol value and the
321 location). When relocating we need to preserve that property.
323 BFD handles this by setting the addend to the negative of the old
324 value of the symbol. Unfortunately it handles common symbols in a
325 non-standard way (it doesn't subtract the old value) but that's a
326 different story (we can't change it without losing backward
327 compatibility with old object files) (coff-i386 does subtract the old
328 value, to be compatible with existing coff-i386 targets, like SCO).
330 So everything works fine when not producing relocateable output. When
331 we are producing relocateable output, logically we should do exactly
332 what we do when not producing relocateable output. Therefore, your
333 patch is correct. In fact, it should probably always just set
334 reloc_entry->addend to 0 for all cases, since it is, in fact, going to
335 add the value into the object file. This won't hurt the COFF code,
336 which doesn't use the addend; I'm not sure what it will do to other
337 formats (the thing to check for would be whether any formats both use
338 the addend and set partial_inplace).
340 When I wanted to make coff-i386 produce relocateable output, I ran
341 into the problem that you are running into: I wanted to remove that
342 line. Rather than risk it, I made the coff-i386 relocs use a special
343 function; it's coff_i386_reloc in coff-i386.c. The function
344 specifically adds the addend field into the object file, knowing that
345 bfd_perform_relocation is not going to. If you remove that line, then
346 coff-i386.c will wind up adding the addend field in twice. It's
347 trivial to fix; it just needs to be done.
349 The problem with removing the line is just that it may break some
350 working code. With BFD it's hard to be sure of anything. The right
351 way to deal with this is simply to build and test at least all the
352 supported COFF targets. It should be straightforward if time and disk
353 space consuming. For each target:
354 1) build the linker
355 2) generate some executable, and link it using -r (I would
356 probably use paranoia.o and link against newlib/libc.a, which
357 for all the supported targets would be available in
358 /usr/cygnus/progressive/H-host/target/lib/libc.a).
359 3) make the change to reloc.c
360 4) rebuild the linker
361 5) repeat step 2
362 6) if the resulting object files are the same, you have at least
363 made it no worse
364 7) if they are different you have to figure out which version is
365 right
367 relocation -= reloc_entry->addend;
368 #endif
369 reloc_entry->addend = 0;
371 else
373 reloc_entry->addend = relocation;
377 else
379 reloc_entry->addend = 0;
382 /* FIXME: This overflow checking is incomplete, because the value
383 might have overflowed before we get here. For a correct check we
384 need to compute the value in a size larger than bitsize, but we
385 can't reasonably do that for a reloc the same size as a host
386 machine word.
387 FIXME: We should also do overflow checking on the result after
388 adding in the value contained in the object file. */
389 if (howto->complain_on_overflow != complain_overflow_dont)
391 bfd_vma check;
393 /* Get the value that will be used for the relocation, but
394 starting at bit position zero. */
395 if (howto->rightshift > howto->bitpos)
396 check = relocation >> (howto->rightshift - howto->bitpos);
397 else
398 check = relocation << (howto->bitpos - howto->rightshift);
399 switch (howto->complain_on_overflow)
401 case complain_overflow_signed:
403 /* Assumes two's complement. */
404 bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
405 bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
407 /* The above right shift is incorrect for a signed value.
408 Fix it up by forcing on the upper bits. */
409 if (howto->rightshift > howto->bitpos
410 && (bfd_signed_vma) relocation < 0)
411 check |= ((bfd_vma) - 1
412 & ~((bfd_vma) - 1
413 >> (howto->rightshift - howto->bitpos)));
414 if ((bfd_signed_vma) check > reloc_signed_max
415 || (bfd_signed_vma) check < reloc_signed_min)
416 flag = bfd_reloc_overflow;
418 break;
419 case complain_overflow_unsigned:
421 /* Assumes two's complement. This expression avoids
422 overflow if howto->bitsize is the number of bits in
423 bfd_vma. */
424 bfd_vma reloc_unsigned_max =
425 (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
427 if ((bfd_vma) check > reloc_unsigned_max)
428 flag = bfd_reloc_overflow;
430 break;
431 case complain_overflow_bitfield:
433 /* Assumes two's complement. This expression avoids
434 overflow if howto->bitsize is the number of bits in
435 bfd_vma. */
436 bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
438 if (((bfd_vma) check & ~reloc_bits) != 0
439 && (((bfd_vma) check & ~reloc_bits)
440 != (-(bfd_vma) 1 & ~reloc_bits)))
442 /* The above right shift is incorrect for a signed
443 value. See if turning on the upper bits fixes the
444 overflow. */
445 if (howto->rightshift > howto->bitpos
446 && (bfd_signed_vma) relocation < 0)
448 check |= ((bfd_vma) - 1
449 & ~((bfd_vma) - 1
450 >> (howto->rightshift - howto->bitpos)));
451 if (((bfd_vma) check & ~reloc_bits)
452 != (-(bfd_vma) 1 & ~reloc_bits))
453 flag = bfd_reloc_overflow;
455 else
456 flag = bfd_reloc_overflow;
459 break;
460 default:
461 abort ();
466 Either we are relocating all the way, or we don't want to apply
467 the relocation to the reloc entry (probably because there isn't
468 any room in the output format to describe addends to relocs)
471 /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler
472 (OSF version 1.3, compiler version 3.11). It miscompiles the
473 following program:
475 struct str
477 unsigned int i0;
478 } s = { 0 };
481 main ()
483 unsigned long x;
485 x = 0x100000000;
486 x <<= (unsigned long) s.i0;
487 if (x == 0)
488 printf ("failed\n");
489 else
490 printf ("succeeded (%lx)\n", x);
494 relocation >>= (bfd_vma) howto->rightshift;
496 /* Shift everything up to where it's going to be used */
498 relocation <<= (bfd_vma) howto->bitpos;
500 /* Wait for the day when all have the mask in them */
502 /* What we do:
503 i instruction to be left alone
504 o offset within instruction
505 r relocation offset to apply
506 S src mask
507 D dst mask
508 N ~dst mask
509 A part 1
510 B part 2
511 R result
513 Do this:
514 i i i i i o o o o o from bfd_get<size>
515 and S S S S S to get the size offset we want
516 + r r r r r r r r r r to get the final value to place
517 and D D D D D to chop to right size
518 -----------------------
519 A A A A A
520 And this:
521 ... i i i i i o o o o o from bfd_get<size>
522 and N N N N N get instruction
523 -----------------------
524 ... B B B B B
526 And then:
527 B B B B B
528 or A A A A A
529 -----------------------
530 R R R R R R R R R R put into bfd_put<size>
533 #define DOIT(x) \
534 x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
536 location = (bfd_byte *) data + addr;
537 switch (howto->size)
539 case 0:
541 char x = get_data (location, 1);
542 DOIT (x);
543 overflow = put_data ((bfd_vma) x, location, 1);
545 break;
547 case 1:
548 if (relocation)
550 short x = get_data (location, 2);
551 DOIT (x);
552 overflow = put_data ((bfd_vma) x, location, 2);
554 break;
555 case 2:
556 if (relocation)
558 long x = get_data (location, 4);
559 DOIT (x);
560 overflow = put_data ((bfd_vma) x, location, 4);
562 break;
563 case -2:
565 long x = get_data (location, 4);
566 relocation = -relocation;
567 DOIT(x);
568 overflow = put_data ((bfd_vma) x, location, 4);
570 break;
572 case 3:
573 /* Do nothing */
574 break;
576 case 4:
577 #ifdef BFD64
578 if (relocation)
580 bfd_vma x = get_data (location, 8);
581 DOIT (x);
582 overflow = put_data (x, location, 8);
584 #else
585 abort ();
586 #endif
587 break;
588 default:
589 return bfd_reloc_other;
591 if ((howto->complain_on_overflow != complain_overflow_dont) && overflow)
592 return bfd_reloc_overflow;
594 return flag;
597 /* Relocate a given location using a given value and howto. */
599 bfd_reloc_status_type
600 _bfd_do_ns32k_reloc_contents (howto, input_bfd, relocation, location,
601 get_data, put_data)
602 reloc_howto_type *howto;
603 bfd *input_bfd ATTRIBUTE_UNUSED;
604 bfd_vma relocation;
605 bfd_byte *location;
606 bfd_vma (*get_data) PARAMS ((bfd_byte *, int));
607 int (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
609 int size;
610 bfd_vma x;
611 boolean overflow;
613 /* If the size is negative, negate RELOCATION. This isn't very
614 general. */
615 if (howto->size < 0)
616 relocation = -relocation;
618 /* Get the value we are going to relocate. */
619 size = bfd_get_reloc_size (howto);
620 switch (size)
622 default:
623 case 0:
624 abort ();
625 case 1:
626 case 2:
627 case 4:
628 #ifdef BFD64
629 case 8:
630 #endif
631 x = get_data (location, size);
632 break;
635 /* Check for overflow. FIXME: We may drop bits during the addition
636 which we don't check for. We must either check at every single
637 operation, which would be tedious, or we must do the computations
638 in a type larger than bfd_vma, which would be inefficient. */
639 overflow = false;
640 if (howto->complain_on_overflow != complain_overflow_dont)
642 bfd_vma check;
643 bfd_signed_vma signed_check;
644 bfd_vma add;
645 bfd_signed_vma signed_add;
647 if (howto->rightshift == 0)
649 check = relocation;
650 signed_check = (bfd_signed_vma) relocation;
652 else
654 /* Drop unwanted bits from the value we are relocating to. */
655 check = relocation >> howto->rightshift;
657 /* If this is a signed value, the rightshift just dropped
658 leading 1 bits (assuming twos complement). */
659 if ((bfd_signed_vma) relocation >= 0)
660 signed_check = check;
661 else
662 signed_check = (check
663 | ((bfd_vma) - 1
664 & ~((bfd_vma) - 1 >> howto->rightshift)));
667 /* Get the value from the object file. */
668 add = x & howto->src_mask;
670 /* Get the value from the object file with an appropriate sign.
671 The expression involving howto->src_mask isolates the upper
672 bit of src_mask. If that bit is set in the value we are
673 adding, it is negative, and we subtract out that number times
674 two. If src_mask includes the highest possible bit, then we
675 can not get the upper bit, but that does not matter since
676 signed_add needs no adjustment to become negative in that
677 case. */
678 signed_add = add;
679 if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
680 signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
682 /* Add the value from the object file, shifted so that it is a
683 straight number. */
684 if (howto->bitpos == 0)
686 check += add;
687 signed_check += signed_add;
689 else
691 check += add >> howto->bitpos;
693 /* For the signed case we use ADD, rather than SIGNED_ADD,
694 to avoid warnings from SVR4 cc. This is OK since we
695 explictly handle the sign bits. */
696 if (signed_add >= 0)
697 signed_check += add >> howto->bitpos;
698 else
699 signed_check += ((add >> howto->bitpos)
700 | ((bfd_vma) - 1
701 & ~((bfd_vma) - 1 >> howto->bitpos)));
704 switch (howto->complain_on_overflow)
706 case complain_overflow_signed:
708 /* Assumes two's complement. */
709 bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
710 bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
712 if (signed_check > reloc_signed_max
713 || signed_check < reloc_signed_min)
714 overflow = true;
716 break;
717 case complain_overflow_unsigned:
719 /* Assumes two's complement. This expression avoids
720 overflow if howto->bitsize is the number of bits in
721 bfd_vma. */
722 bfd_vma reloc_unsigned_max =
723 (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
725 if (check > reloc_unsigned_max)
726 overflow = true;
728 break;
729 case complain_overflow_bitfield:
731 /* Assumes two's complement. This expression avoids
732 overflow if howto->bitsize is the number of bits in
733 bfd_vma. */
734 bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
736 if ((check & ~reloc_bits) != 0
737 && (((bfd_vma) signed_check & ~reloc_bits)
738 != (-(bfd_vma) 1 & ~reloc_bits)))
739 overflow = true;
741 break;
742 default:
743 abort ();
747 /* Put RELOCATION in the right bits. */
748 relocation >>= (bfd_vma) howto->rightshift;
749 relocation <<= (bfd_vma) howto->bitpos;
751 /* Add RELOCATION to the right bits of X. */
752 x = ((x & ~howto->dst_mask)
753 | (((x & howto->src_mask) + relocation) & howto->dst_mask));
755 /* Put the relocated value back in the object file. */
756 switch (size)
758 default:
759 case 0:
760 abort ();
761 case 1:
762 case 2:
763 case 4:
764 #ifdef BFD64
765 case 8:
766 #endif
767 put_data (x, location, size);
768 break;
771 return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
774 bfd_reloc_status_type
775 _bfd_ns32k_reloc_disp (abfd, reloc_entry, symbol, data, input_section,
776 output_bfd, error_message)
777 bfd *abfd;
778 arelent *reloc_entry;
779 struct symbol_cache_entry *symbol;
780 PTR data;
781 asection *input_section;
782 bfd *output_bfd;
783 char **error_message;
785 return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
786 output_bfd, error_message,
787 _bfd_ns32k_get_displacement,
788 _bfd_ns32k_put_displacement);
791 bfd_reloc_status_type
792 _bfd_ns32k_reloc_imm (abfd, reloc_entry, symbol, data, input_section,
793 output_bfd, error_message)
794 bfd *abfd;
795 arelent *reloc_entry;
796 struct symbol_cache_entry *symbol;
797 PTR data;
798 asection *input_section;
799 bfd *output_bfd;
800 char **error_message;
802 return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
803 output_bfd, error_message, _bfd_ns32k_get_immediate,
804 _bfd_ns32k_put_immediate);
807 bfd_reloc_status_type
808 _bfd_ns32k_final_link_relocate (howto, input_bfd, input_section, contents,
809 address, value, addend)
810 reloc_howto_type *howto;
811 bfd *input_bfd;
812 asection *input_section;
813 bfd_byte *contents;
814 bfd_vma address;
815 bfd_vma value;
816 bfd_vma addend;
818 bfd_vma relocation;
820 /* Sanity check the address. */
821 if (address > input_section->_cooked_size)
822 return bfd_reloc_outofrange;
824 /* This function assumes that we are dealing with a basic relocation
825 against a symbol. We want to compute the value of the symbol to
826 relocate to. This is just VALUE, the value of the symbol, plus
827 ADDEND, any addend associated with the reloc. */
828 relocation = value + addend;
830 /* If the relocation is PC relative, we want to set RELOCATION to
831 the distance between the symbol (currently in RELOCATION) and the
832 location we are relocating. Some targets (e.g., i386-aout)
833 arrange for the contents of the section to be the negative of the
834 offset of the location within the section; for such targets
835 pcrel_offset is false. Other targets (e.g., m88kbcs or ELF)
836 simply leave the contents of the section as zero; for such
837 targets pcrel_offset is true. If pcrel_offset is false we do not
838 need to subtract out the offset of the location within the
839 section (which is just ADDRESS). */
840 if (howto->pc_relative)
842 relocation -= (input_section->output_section->vma
843 + input_section->output_offset);
844 if (howto->pcrel_offset)
845 relocation -= address;
848 return _bfd_ns32k_relocate_contents (howto, input_bfd, relocation,
849 contents + address);