2001-05-16 Jeff Johnston <jjohnstn@redhat.com>
[binutils.git] / bfd / cpu-ns32k.c
blobc01599e080aa47f2fc3eb4dc6db893ba362ab201
1 /* BFD support for the ns32k architecture.
2 Copyright 1990, 1991, 1994, 1995, 1998, 2000
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 long
40 ns32k_sign_extend(value, bits)
41 int value;
42 int bits;
44 value = value & ((1 << bits) - 1);
45 return (value & (1 << (bits-1))
46 ? value | (~((1 << bits) - 1))
47 : value);
50 long
51 _bfd_ns32k_get_displacement(buffer, offset, size)
52 bfd_byte *buffer;
53 long offset;
54 long size;
56 long value;
57 buffer += offset;
58 switch (size)
60 case 1:
61 value = ns32k_sign_extend (*buffer, 7);
62 break;
63 case 2:
64 value = ns32k_sign_extend(*buffer++, 6);
65 value = (value << 8) | (0xff & *buffer);
66 break;
67 case 4:
68 value = ns32k_sign_extend(*buffer++, 6);
69 value = (value << 8) | (0xff & *buffer++);
70 value = (value << 8) | (0xff & *buffer++);
71 value = (value << 8) | (0xff & *buffer);
72 break;
73 default:
74 abort ();
75 return 0;
77 return value;
80 int
81 _bfd_ns32k_put_displacement(value, buffer, offset, size)
82 long value;
83 bfd_byte *buffer;
84 long offset;
85 long size;
87 buffer += offset;
88 switch (size)
90 case 1:
91 if (value < -64 || value > 63)
92 return -1;
93 value&=0x7f;
94 *buffer++=value;
95 break;
96 case 2:
97 if (value < -8192 || value > 8191)
98 return -1;
99 value&=0x3fff;
100 value|=0x8000;
101 *buffer++=(value>>8);
102 *buffer++=value;
103 break;
104 case 4:
105 if (value < -0x1f000000 || value >= 0x20000000)
106 return -1;
107 value|=0xc0000000;
108 *buffer++=(value>>24);
109 *buffer++=(value>>16);
110 *buffer++=(value>>8);
111 *buffer++=value;
112 break;
113 default:
114 return -1;
116 return 0;
119 long
120 _bfd_ns32k_get_immediate (buffer, offset, size)
121 bfd_byte *buffer;
122 long offset;
123 long size;
125 long value = 0;
126 buffer += offset;
127 switch (size)
129 case 4:
130 value = (value << 8) | (*buffer++ & 0xff);
131 case 3:
132 value = (value << 8) | (*buffer++ & 0xff);
133 case 2:
134 value = (value << 8) | (*buffer++ & 0xff);
135 case 1:
136 value = (value << 8) | (*buffer++ & 0xff);
138 return value;
142 _bfd_ns32k_put_immediate (value, buffer, offset, size)
143 long value;
144 bfd_byte *buffer;
145 long offset;
146 long size;
148 buffer += offset + size - 1;
149 switch (size)
151 case 4:
152 *buffer-- = (value & 0xff); value >>= 8;
153 case 3:
154 *buffer-- = (value & 0xff); value >>= 8;
155 case 2:
156 *buffer-- = (value & 0xff); value >>= 8;
157 case 1:
158 *buffer-- = (value & 0xff); value >>= 8;
160 return 0;
163 /* This is just like the standard perform_relocation except we
164 * use get_data and put_data which know about the ns32k
165 * storage methods.
166 * This is probably a lot more complicated than it needs to be!
168 static bfd_reloc_status_type
169 do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
170 error_message, get_data, put_data)
171 bfd *abfd;
172 arelent *reloc_entry;
173 struct symbol_cache_entry *symbol;
174 PTR data;
175 asection *input_section;
176 bfd *output_bfd;
177 char **error_message ATTRIBUTE_UNUSED;
178 long (*get_data) ();
179 int (*put_data) ();
181 int overflow = 0;
182 bfd_vma relocation;
183 bfd_reloc_status_type flag = bfd_reloc_ok;
184 bfd_size_type addr = reloc_entry->address;
185 bfd_vma output_base = 0;
186 reloc_howto_type *howto = reloc_entry->howto;
187 asection *reloc_target_output_section;
189 if ((symbol->section == &bfd_abs_section)
190 && output_bfd != (bfd *) NULL)
192 reloc_entry->address += input_section->output_offset;
193 return bfd_reloc_ok;
196 /* If we are not producing relocateable output, return an error if
197 the symbol is not defined. An undefined weak symbol is
198 considered to have a value of zero (SVR4 ABI, p. 4-27). */
199 if (symbol->section == &bfd_und_section
200 && (symbol->flags & BSF_WEAK) == 0
201 && output_bfd == (bfd *) NULL)
202 flag = bfd_reloc_undefined;
204 /* Is the address of the relocation really within the section? */
205 if (reloc_entry->address > input_section->_cooked_size)
206 return bfd_reloc_outofrange;
208 /* Work out which section the relocation is targetted at and the
209 initial relocation command value. */
211 /* Get symbol value. (Common symbols are special.) */
212 if (bfd_is_com_section (symbol->section))
213 relocation = 0;
214 else
215 relocation = symbol->value;
217 reloc_target_output_section = symbol->section->output_section;
219 /* Convert input-section-relative symbol value to absolute. */
220 if (output_bfd && howto->partial_inplace == false)
221 output_base = 0;
222 else
223 output_base = reloc_target_output_section->vma;
225 relocation += output_base + symbol->section->output_offset;
227 /* Add in supplied addend. */
228 relocation += reloc_entry->addend;
230 /* Here the variable relocation holds the final address of the
231 symbol we are relocating against, plus any addend. */
233 if (howto->pc_relative == true)
235 /* This is a PC relative relocation. We want to set RELOCATION
236 to the distance between the address of the symbol and the
237 location. RELOCATION is already the address of the symbol.
239 We start by subtracting the address of the section containing
240 the location.
242 If pcrel_offset is set, we must further subtract the position
243 of the location within the section. Some targets arrange for
244 the addend to be the negative of the position of the location
245 within the section; for example, i386-aout does this. For
246 i386-aout, pcrel_offset is false. Some other targets do not
247 include the position of the location; for example, m88kbcs,
248 or ELF. For those targets, pcrel_offset is true.
250 If we are producing relocateable output, then we must ensure
251 that this reloc will be correctly computed when the final
252 relocation is done. If pcrel_offset is false we want to wind
253 up with the negative of the location within the section,
254 which means we must adjust the existing addend by the change
255 in the location within the section. If pcrel_offset is true
256 we do not want to adjust the existing addend at all.
258 FIXME: This seems logical to me, but for the case of
259 producing relocateable output it is not what the code
260 actually does. I don't want to change it, because it seems
261 far too likely that something will break. */
263 relocation -=
264 input_section->output_section->vma + input_section->output_offset;
266 if (howto->pcrel_offset == true)
267 relocation -= reloc_entry->address;
270 if (output_bfd != (bfd *) NULL)
272 if (howto->partial_inplace == false)
274 /* This is a partial relocation, and we want to apply the relocation
275 to the reloc entry rather than the raw data. Modify the reloc
276 inplace to reflect what we now know. */
277 reloc_entry->addend = relocation;
278 reloc_entry->address += input_section->output_offset;
279 return flag;
281 else
283 /* This is a partial relocation, but inplace, so modify the
284 reloc record a bit.
286 If we've relocated with a symbol with a section, change
287 into a ref to the section belonging to the symbol. */
289 reloc_entry->address += input_section->output_offset;
291 /* WTF?? */
292 if (abfd->xvec->flavour == bfd_target_coff_flavour)
294 #if 1
295 /* For m68k-coff, the addend was being subtracted twice during
296 relocation with -r. Removing the line below this comment
297 fixes that problem; see PR 2953.
299 However, Ian wrote the following, regarding removing the line below,
300 which explains why it is still enabled: --djm
302 If you put a patch like that into BFD you need to check all the COFF
303 linkers. I am fairly certain that patch will break coff-i386 (e.g.,
304 SCO); see coff_i386_reloc in coff-i386.c where I worked around the
305 problem in a different way. There may very well be a reason that the
306 code works as it does.
308 Hmmm. The first obvious point is that bfd_perform_relocation should
309 not have any tests that depend upon the flavour. It's seem like
310 entirely the wrong place for such a thing. The second obvious point
311 is that the current code ignores the reloc addend when producing
312 relocateable output for COFF. That's peculiar. In fact, I really
313 have no idea what the point of the line you want to remove is.
315 A typical COFF reloc subtracts the old value of the symbol and adds in
316 the new value to the location in the object file (if it's a pc
317 relative reloc it adds the difference between the symbol value and the
318 location). When relocating we need to preserve that property.
320 BFD handles this by setting the addend to the negative of the old
321 value of the symbol. Unfortunately it handles common symbols in a
322 non-standard way (it doesn't subtract the old value) but that's a
323 different story (we can't change it without losing backward
324 compatibility with old object files) (coff-i386 does subtract the old
325 value, to be compatible with existing coff-i386 targets, like SCO).
327 So everything works fine when not producing relocateable output. When
328 we are producing relocateable output, logically we should do exactly
329 what we do when not producing relocateable output. Therefore, your
330 patch is correct. In fact, it should probably always just set
331 reloc_entry->addend to 0 for all cases, since it is, in fact, going to
332 add the value into the object file. This won't hurt the COFF code,
333 which doesn't use the addend; I'm not sure what it will do to other
334 formats (the thing to check for would be whether any formats both use
335 the addend and set partial_inplace).
337 When I wanted to make coff-i386 produce relocateable output, I ran
338 into the problem that you are running into: I wanted to remove that
339 line. Rather than risk it, I made the coff-i386 relocs use a special
340 function; it's coff_i386_reloc in coff-i386.c. The function
341 specifically adds the addend field into the object file, knowing that
342 bfd_perform_relocation is not going to. If you remove that line, then
343 coff-i386.c will wind up adding the addend field in twice. It's
344 trivial to fix; it just needs to be done.
346 The problem with removing the line is just that it may break some
347 working code. With BFD it's hard to be sure of anything. The right
348 way to deal with this is simply to build and test at least all the
349 supported COFF targets. It should be straightforward if time and disk
350 space consuming. For each target:
351 1) build the linker
352 2) generate some executable, and link it using -r (I would
353 probably use paranoia.o and link against newlib/libc.a, which
354 for all the supported targets would be available in
355 /usr/cygnus/progressive/H-host/target/lib/libc.a).
356 3) make the change to reloc.c
357 4) rebuild the linker
358 5) repeat step 2
359 6) if the resulting object files are the same, you have at least
360 made it no worse
361 7) if they are different you have to figure out which version is
362 right
364 relocation -= reloc_entry->addend;
365 #endif
366 reloc_entry->addend = 0;
368 else
370 reloc_entry->addend = relocation;
374 else
376 reloc_entry->addend = 0;
379 /* FIXME: This overflow checking is incomplete, because the value
380 might have overflowed before we get here. For a correct check we
381 need to compute the value in a size larger than bitsize, but we
382 can't reasonably do that for a reloc the same size as a host
383 machine word.
384 FIXME: We should also do overflow checking on the result after
385 adding in the value contained in the object file. */
386 if (howto->complain_on_overflow != complain_overflow_dont)
388 bfd_vma check;
390 /* Get the value that will be used for the relocation, but
391 starting at bit position zero. */
392 if (howto->rightshift > howto->bitpos)
393 check = relocation >> (howto->rightshift - howto->bitpos);
394 else
395 check = relocation << (howto->bitpos - howto->rightshift);
396 switch (howto->complain_on_overflow)
398 case complain_overflow_signed:
400 /* Assumes two's complement. */
401 bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
402 bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
404 /* The above right shift is incorrect for a signed value.
405 Fix it up by forcing on the upper bits. */
406 if (howto->rightshift > howto->bitpos
407 && (bfd_signed_vma) relocation < 0)
408 check |= ((bfd_vma) - 1
409 & ~((bfd_vma) - 1
410 >> (howto->rightshift - howto->bitpos)));
411 if ((bfd_signed_vma) check > reloc_signed_max
412 || (bfd_signed_vma) check < reloc_signed_min)
413 flag = bfd_reloc_overflow;
415 break;
416 case complain_overflow_unsigned:
418 /* Assumes two's complement. This expression avoids
419 overflow if howto->bitsize is the number of bits in
420 bfd_vma. */
421 bfd_vma reloc_unsigned_max =
422 (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
424 if ((bfd_vma) check > reloc_unsigned_max)
425 flag = bfd_reloc_overflow;
427 break;
428 case complain_overflow_bitfield:
430 /* Assumes two's complement. This expression avoids
431 overflow if howto->bitsize is the number of bits in
432 bfd_vma. */
433 bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
435 if (((bfd_vma) check & ~reloc_bits) != 0
436 && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
438 /* The above right shift is incorrect for a signed
439 value. See if turning on the upper bits fixes the
440 overflow. */
441 if (howto->rightshift > howto->bitpos
442 && (bfd_signed_vma) relocation < 0)
444 check |= ((bfd_vma) - 1
445 & ~((bfd_vma) - 1
446 >> (howto->rightshift - howto->bitpos)));
447 if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
448 flag = bfd_reloc_overflow;
450 else
451 flag = bfd_reloc_overflow;
454 break;
455 default:
456 abort ();
461 Either we are relocating all the way, or we don't want to apply
462 the relocation to the reloc entry (probably because there isn't
463 any room in the output format to describe addends to relocs)
466 /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler
467 (OSF version 1.3, compiler version 3.11). It miscompiles the
468 following program:
470 struct str
472 unsigned int i0;
473 } s = { 0 };
476 main ()
478 unsigned long x;
480 x = 0x100000000;
481 x <<= (unsigned long) s.i0;
482 if (x == 0)
483 printf ("failed\n");
484 else
485 printf ("succeeded (%lx)\n", x);
489 relocation >>= (bfd_vma) howto->rightshift;
491 /* Shift everything up to where it's going to be used */
493 relocation <<= (bfd_vma) howto->bitpos;
495 /* Wait for the day when all have the mask in them */
497 /* What we do:
498 i instruction to be left alone
499 o offset within instruction
500 r relocation offset to apply
501 S src mask
502 D dst mask
503 N ~dst mask
504 A part 1
505 B part 2
506 R result
508 Do this:
509 i i i i i o o o o o from bfd_get<size>
510 and S S S S S to get the size offset we want
511 + r r r r r r r r r r to get the final value to place
512 and D D D D D to chop to right size
513 -----------------------
514 A A A A A
515 And this:
516 ... i i i i i o o o o o from bfd_get<size>
517 and N N N N N get instruction
518 -----------------------
519 ... B B B B B
521 And then:
522 B B B B B
523 or A A A A A
524 -----------------------
525 R R R R R R R R R R put into bfd_put<size>
528 #define DOIT(x) \
529 x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
531 switch (howto->size)
533 case 0:
535 char x = get_data (data, addr, 1);
536 DOIT (x);
537 overflow = put_data(x, data, addr, 1);
539 break;
541 case 1:
542 if (relocation)
544 short x = get_data (data, addr, 2);
545 DOIT (x);
546 overflow = put_data(x, (unsigned char *) data, addr, 2);
548 break;
549 case 2:
550 if (relocation)
552 long x = get_data (data, addr, 4);
553 DOIT (x);
554 overflow = put_data(x, data, addr, 4);
556 break;
557 case -2:
559 long x = get_data(data, addr, 4);
560 relocation = -relocation;
561 DOIT(x);
562 overflow = put_data(x, data , addr, 4);
564 break;
566 case 3:
567 /* Do nothing */
568 break;
570 case 4:
571 #ifdef BFD64
572 if (relocation)
574 bfd_vma x = get_data (data, addr, 8);
575 DOIT (x);
576 overflow = put_data(x, data, addr, 8);
578 #else
579 abort ();
580 #endif
581 break;
582 default:
583 return bfd_reloc_other;
585 if ((howto->complain_on_overflow != complain_overflow_dont) && overflow)
586 return bfd_reloc_overflow;
588 return flag;
591 /* Relocate a given location using a given value and howto. */
593 bfd_reloc_status_type
594 _bfd_do_ns32k_reloc_contents ( howto, input_bfd, relocation, location,
595 get_data, put_data)
596 reloc_howto_type *howto;
597 bfd *input_bfd ATTRIBUTE_UNUSED;
598 bfd_vma relocation;
599 bfd_byte *location;
600 long (*get_data) ();
601 int (*put_data) ();
603 int size;
604 bfd_vma x;
605 boolean overflow;
607 /* If the size is negative, negate RELOCATION. This isn't very
608 general. */
609 if (howto->size < 0)
610 relocation = -relocation;
612 /* Get the value we are going to relocate. */
613 size = bfd_get_reloc_size (howto);
614 switch (size)
616 default:
617 case 0:
618 abort ();
619 case 1:
620 case 2:
621 case 4:
622 #ifdef BFD64
623 case 8:
624 #endif
625 x = get_data (location, 0, size);
626 break;
629 /* Check for overflow. FIXME: We may drop bits during the addition
630 which we don't check for. We must either check at every single
631 operation, which would be tedious, or we must do the computations
632 in a type larger than bfd_vma, which would be inefficient. */
633 overflow = false;
634 if (howto->complain_on_overflow != complain_overflow_dont)
636 bfd_vma check;
637 bfd_signed_vma signed_check;
638 bfd_vma add;
639 bfd_signed_vma signed_add;
641 if (howto->rightshift == 0)
643 check = relocation;
644 signed_check = (bfd_signed_vma) relocation;
646 else
648 /* Drop unwanted bits from the value we are relocating to. */
649 check = relocation >> howto->rightshift;
651 /* If this is a signed value, the rightshift just dropped
652 leading 1 bits (assuming twos complement). */
653 if ((bfd_signed_vma) relocation >= 0)
654 signed_check = check;
655 else
656 signed_check = (check
657 | ((bfd_vma) - 1
658 & ~((bfd_vma) - 1 >> howto->rightshift)));
661 /* Get the value from the object file. */
662 add = x & howto->src_mask;
664 /* Get the value from the object file with an appropriate sign.
665 The expression involving howto->src_mask isolates the upper
666 bit of src_mask. If that bit is set in the value we are
667 adding, it is negative, and we subtract out that number times
668 two. If src_mask includes the highest possible bit, then we
669 can not get the upper bit, but that does not matter since
670 signed_add needs no adjustment to become negative in that
671 case. */
672 signed_add = add;
673 if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
674 signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
676 /* Add the value from the object file, shifted so that it is a
677 straight number. */
678 if (howto->bitpos == 0)
680 check += add;
681 signed_check += signed_add;
683 else
685 check += add >> howto->bitpos;
687 /* For the signed case we use ADD, rather than SIGNED_ADD,
688 to avoid warnings from SVR4 cc. This is OK since we
689 explictly handle the sign bits. */
690 if (signed_add >= 0)
691 signed_check += add >> howto->bitpos;
692 else
693 signed_check += ((add >> howto->bitpos)
694 | ((bfd_vma) - 1
695 & ~((bfd_vma) - 1 >> howto->bitpos)));
698 switch (howto->complain_on_overflow)
700 case complain_overflow_signed:
702 /* Assumes two's complement. */
703 bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
704 bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
706 if (signed_check > reloc_signed_max
707 || signed_check < reloc_signed_min)
708 overflow = true;
710 break;
711 case complain_overflow_unsigned:
713 /* Assumes two's complement. This expression avoids
714 overflow if howto->bitsize is the number of bits in
715 bfd_vma. */
716 bfd_vma reloc_unsigned_max =
717 (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
719 if (check > reloc_unsigned_max)
720 overflow = true;
722 break;
723 case complain_overflow_bitfield:
725 /* Assumes two's complement. This expression avoids
726 overflow if howto->bitsize is the number of bits in
727 bfd_vma. */
728 bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
730 if ((check & ~reloc_bits) != 0
731 && (((bfd_vma) signed_check & ~reloc_bits)
732 != (-1 & ~reloc_bits)))
733 overflow = true;
735 break;
736 default:
737 abort ();
741 /* Put RELOCATION in the right bits. */
742 relocation >>= (bfd_vma) howto->rightshift;
743 relocation <<= (bfd_vma) howto->bitpos;
745 /* Add RELOCATION to the right bits of X. */
746 x = ((x & ~howto->dst_mask)
747 | (((x & howto->src_mask) + relocation) & howto->dst_mask));
749 /* Put the relocated value back in the object file. */
750 switch (size)
752 default:
753 case 0:
754 abort ();
755 case 1:
756 case 2:
757 case 4:
758 #ifdef BFD64
759 case 8:
760 #endif
761 put_data(x, location, 0, size);
762 break;
765 return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
768 bfd_reloc_status_type
769 _bfd_ns32k_reloc_disp (abfd, reloc_entry, symbol, data, input_section,
770 output_bfd, error_message)
771 bfd *abfd;
772 arelent *reloc_entry;
773 struct symbol_cache_entry *symbol;
774 PTR data;
775 asection *input_section;
776 bfd *output_bfd;
777 char **error_message;
779 return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
780 output_bfd, error_message,
781 _bfd_ns32k_get_displacement,
782 _bfd_ns32k_put_displacement);
785 bfd_reloc_status_type
786 _bfd_ns32k_reloc_imm (abfd, reloc_entry, symbol, data, input_section,
787 output_bfd, error_message)
788 bfd *abfd;
789 arelent *reloc_entry;
790 struct symbol_cache_entry *symbol;
791 PTR data;
792 asection *input_section;
793 bfd *output_bfd;
794 char **error_message;
796 return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
797 output_bfd, error_message, _bfd_ns32k_get_immediate,
798 _bfd_ns32k_put_immediate);
801 bfd_reloc_status_type
802 _bfd_ns32k_final_link_relocate (howto, input_bfd, input_section, contents,
803 address, value, addend)
804 reloc_howto_type *howto;
805 bfd *input_bfd;
806 asection *input_section;
807 bfd_byte *contents;
808 bfd_vma address;
809 bfd_vma value;
810 bfd_vma addend;
812 bfd_vma relocation;
814 /* Sanity check the address. */
815 if (address > input_section->_cooked_size)
816 return bfd_reloc_outofrange;
818 /* This function assumes that we are dealing with a basic relocation
819 against a symbol. We want to compute the value of the symbol to
820 relocate to. This is just VALUE, the value of the symbol, plus
821 ADDEND, any addend associated with the reloc. */
822 relocation = value + addend;
824 /* If the relocation is PC relative, we want to set RELOCATION to
825 the distance between the symbol (currently in RELOCATION) and the
826 location we are relocating. Some targets (e.g., i386-aout)
827 arrange for the contents of the section to be the negative of the
828 offset of the location within the section; for such targets
829 pcrel_offset is false. Other targets (e.g., m88kbcs or ELF)
830 simply leave the contents of the section as zero; for such
831 targets pcrel_offset is true. If pcrel_offset is false we do not
832 need to subtract out the offset of the location within the
833 section (which is just ADDRESS). */
834 if (howto->pc_relative)
836 relocation -= (input_section->output_section->vma
837 + input_section->output_offset);
838 if (howto->pcrel_offset)
839 relocation -= address;
842 return _bfd_ns32k_relocate_contents (howto, input_bfd, relocation,
843 contents + address);