Initial revision
[binutils.git] / bfd / cpu-ns32k.c
blob1b0a18d5c5213f9828b36bc010463d507433d324
1 /* BFD support for the ns32k architecture.
2 Copyright (C) 1990, 91, 94, 95, 96, 1998 Free Software Foundation, Inc.
3 Almost totally rewritten by Ian Dall from initial work
4 by Andrew Cagney.
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "libbfd.h"
25 #include "ns32k.h"
27 #define N(machine, printable, d, next) \
28 { 32, 32, 8, bfd_arch_ns32k, machine, "ns32k",printable,3,d,bfd_default_compatible,bfd_default_scan, next, }
30 static const bfd_arch_info_type arch_info_struct[] =
32 N(32532,"ns32k:32532",true, 0), /* the word ns32k will match this too */
35 const bfd_arch_info_type bfd_ns32k_arch =
36 N(32032,"ns32k:32032",false, &arch_info_struct[0]);
38 static long
39 ns32k_sign_extend(value, bits)
40 int value;
41 int bits;
43 value = value & ((1 << bits) - 1);
44 return (value & (1 << (bits-1))
45 ? value | (~((1 << bits) - 1))
46 : value);
49 long
50 _bfd_ns32k_get_displacement(buffer, offset, size)
51 bfd_byte *buffer;
52 long offset;
53 long size;
55 long value;
56 buffer += offset;
57 switch (size)
59 case 1:
60 value = ns32k_sign_extend (*buffer, 7);
61 break;
62 case 2:
63 value = ns32k_sign_extend(*buffer++, 6);
64 value = (value << 8) | (0xff & *buffer);
65 break;
66 case 4:
67 value = ns32k_sign_extend(*buffer++, 6);
68 value = (value << 8) | (0xff & *buffer++);
69 value = (value << 8) | (0xff & *buffer++);
70 value = (value << 8) | (0xff & *buffer);
71 break;
72 default:
73 abort ();
74 return 0;
76 return value;
79 int
80 _bfd_ns32k_put_displacement(value, buffer, offset, size)
81 long value;
82 bfd_byte *buffer;
83 long offset;
84 long size;
86 buffer += offset;
87 switch (size)
89 case 1:
90 if (value < -64 || value > 63)
91 return -1;
92 value&=0x7f;
93 *buffer++=value;
94 break;
95 case 2:
96 if (value < -8192 || value > 8191)
97 return -1;
98 value&=0x3fff;
99 value|=0x8000;
100 *buffer++=(value>>8);
101 *buffer++=value;
102 break;
103 case 4:
104 if (value < -0x1f000000 || value >= 0x20000000)
105 return -1;
106 value|=0xc0000000;
107 *buffer++=(value>>24);
108 *buffer++=(value>>16);
109 *buffer++=(value>>8);
110 *buffer++=value;
111 break;
112 default:
113 return -1;
115 return 0;
118 long
119 _bfd_ns32k_get_immediate (buffer, offset, size)
120 bfd_byte *buffer;
121 long offset;
122 long size;
124 long value = 0;
125 buffer += offset;
126 switch (size)
128 case 4:
129 value = (value << 8) | (*buffer++ & 0xff);
130 case 3:
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, offset, size)
142 long value;
143 bfd_byte *buffer;
144 long offset;
145 long size;
147 buffer += offset + size - 1;
148 switch (size)
150 case 4:
151 *buffer-- = (value & 0xff); value >>= 8;
152 case 3:
153 *buffer-- = (value & 0xff); value >>= 8;
154 case 2:
155 *buffer-- = (value & 0xff); value >>= 8;
156 case 1:
157 *buffer-- = (value & 0xff); value >>= 8;
159 return 0;
162 /* This is just like the standard perform_relocation except we
163 * use get_data and put_data which know about the ns32k
164 * storage methods.
165 * This is probably a lot more complicated than it needs to be!
167 static bfd_reloc_status_type
168 do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
169 error_message, get_data, put_data)
170 bfd *abfd;
171 arelent *reloc_entry;
172 struct symbol_cache_entry *symbol;
173 PTR data;
174 asection *input_section;
175 bfd *output_bfd;
176 char **error_message;
177 long (*get_data)();
178 int (*put_data)();
180 int overflow = 0;
181 bfd_vma relocation;
182 bfd_reloc_status_type flag = bfd_reloc_ok;
183 bfd_size_type addr = reloc_entry->address;
184 bfd_vma output_base = 0;
185 reloc_howto_type *howto = reloc_entry->howto;
186 asection *reloc_target_output_section;
188 if ((symbol->section == &bfd_abs_section)
189 && output_bfd != (bfd *) NULL)
191 reloc_entry->address += input_section->output_offset;
192 return bfd_reloc_ok;
195 /* If we are not producing relocateable output, return an error if
196 the symbol is not defined. An undefined weak symbol is
197 considered to have a value of zero (SVR4 ABI, p. 4-27). */
198 if (symbol->section == &bfd_und_section
199 && (symbol->flags & BSF_WEAK) == 0
200 && output_bfd == (bfd *) NULL)
201 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;
218 reloc_target_output_section = symbol->section->output_section;
220 /* Convert input-section-relative symbol value to absolute. */
221 if (output_bfd && howto->partial_inplace == false)
222 output_base = 0;
223 else
224 output_base = reloc_target_output_section->vma;
226 relocation += output_base + symbol->section->output_offset;
228 /* Add in supplied addend. */
229 relocation += reloc_entry->addend;
231 /* Here the variable relocation holds the final address of the
232 symbol we are relocating against, plus any addend. */
234 if (howto->pc_relative == true)
236 /* This is a PC relative relocation. We want to set RELOCATION
237 to the distance between the address of the symbol and the
238 location. RELOCATION is already the address of the symbol.
240 We start by subtracting the address of the section containing
241 the location.
243 If pcrel_offset is set, we must further subtract the position
244 of the location within the section. Some targets arrange for
245 the addend to be the negative of the position of the location
246 within the section; for example, i386-aout does this. For
247 i386-aout, pcrel_offset is false. Some other targets do not
248 include the position of the location; for example, m88kbcs,
249 or ELF. For those targets, pcrel_offset is true.
251 If we are producing relocateable output, then we must ensure
252 that this reloc will be correctly computed when the final
253 relocation is done. If pcrel_offset is false we want to wind
254 up with the negative of the location within the section,
255 which means we must adjust the existing addend by the change
256 in the location within the section. If pcrel_offset is true
257 we do not want to adjust the existing addend at all.
259 FIXME: This seems logical to me, but for the case of
260 producing relocateable output it is not what the code
261 actually does. I don't want to change it, because it seems
262 far too likely that something will break. */
264 relocation -=
265 input_section->output_section->vma + input_section->output_offset;
267 if (howto->pcrel_offset == true)
268 relocation -= reloc_entry->address;
271 if (output_bfd != (bfd *) NULL)
273 if (howto->partial_inplace == false)
275 /* This is a partial relocation, and we want to apply the relocation
276 to the reloc entry rather than the raw data. Modify the reloc
277 inplace to reflect what we now know. */
278 reloc_entry->addend = relocation;
279 reloc_entry->address += input_section->output_offset;
280 return flag;
282 else
284 /* This is a partial relocation, but inplace, so modify the
285 reloc record a bit.
287 If we've relocated with a symbol with a section, change
288 into a ref to the section belonging to the symbol. */
290 reloc_entry->address += input_section->output_offset;
292 /* WTF?? */
293 if (abfd->xvec->flavour == bfd_target_coff_flavour
294 && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0)
296 #if 1
297 /* For m68k-coff, the addend was being subtracted twice during
298 relocation with -r. Removing the line below this comment
299 fixes that problem; see PR 2953.
301 However, Ian wrote the following, regarding removing the line below,
302 which explains why it is still enabled: --djm
304 If you put a patch like that into BFD you need to check all the COFF
305 linkers. I am fairly certain that patch will break coff-i386 (e.g.,
306 SCO); see coff_i386_reloc in coff-i386.c where I worked around the
307 problem in a different way. There may very well be a reason that the
308 code works as it does.
310 Hmmm. The first obvious point is that bfd_perform_relocation should
311 not have any tests that depend upon the flavour. It's seem like
312 entirely the wrong place for such a thing. The second obvious point
313 is that the current code ignores the reloc addend when producing
314 relocateable output for COFF. That's peculiar. In fact, I really
315 have no idea what the point of the line you want to remove is.
317 A typical COFF reloc subtracts the old value of the symbol and adds in
318 the new value to the location in the object file (if it's a pc
319 relative reloc it adds the difference between the symbol value and the
320 location). When relocating we need to preserve that property.
322 BFD handles this by setting the addend to the negative of the old
323 value of the symbol. Unfortunately it handles common symbols in a
324 non-standard way (it doesn't subtract the old value) but that's a
325 different story (we can't change it without losing backward
326 compatibility with old object files) (coff-i386 does subtract the old
327 value, to be compatible with existing coff-i386 targets, like SCO).
329 So everything works fine when not producing relocateable output. When
330 we are producing relocateable output, logically we should do exactly
331 what we do when not producing relocateable output. Therefore, your
332 patch is correct. In fact, it should probably always just set
333 reloc_entry->addend to 0 for all cases, since it is, in fact, going to
334 add the value into the object file. This won't hurt the COFF code,
335 which doesn't use the addend; I'm not sure what it will do to other
336 formats (the thing to check for would be whether any formats both use
337 the addend and set partial_inplace).
339 When I wanted to make coff-i386 produce relocateable output, I ran
340 into the problem that you are running into: I wanted to remove that
341 line. Rather than risk it, I made the coff-i386 relocs use a special
342 function; it's coff_i386_reloc in coff-i386.c. The function
343 specifically adds the addend field into the object file, knowing that
344 bfd_perform_relocation is not going to. If you remove that line, then
345 coff-i386.c will wind up adding the addend field in twice. It's
346 trivial to fix; it just needs to be done.
348 The problem with removing the line is just that it may break some
349 working code. With BFD it's hard to be sure of anything. The right
350 way to deal with this is simply to build and test at least all the
351 supported COFF targets. It should be straightforward if time and disk
352 space consuming. For each target:
353 1) build the linker
354 2) generate some executable, and link it using -r (I would
355 probably use paranoia.o and link against newlib/libc.a, which
356 for all the supported targets would be available in
357 /usr/cygnus/progressive/H-host/target/lib/libc.a).
358 3) make the change to reloc.c
359 4) rebuild the linker
360 5) repeat step 2
361 6) if the resulting object files are the same, you have at least
362 made it no worse
363 7) if they are different you have to figure out which version is
364 right
366 relocation -= reloc_entry->addend;
367 #endif
368 reloc_entry->addend = 0;
370 else
372 reloc_entry->addend = relocation;
376 else
378 reloc_entry->addend = 0;
381 /* FIXME: This overflow checking is incomplete, because the value
382 might have overflowed before we get here. For a correct check we
383 need to compute the value in a size larger than bitsize, but we
384 can't reasonably do that for a reloc the same size as a host
385 machine word.
386 FIXME: We should also do overflow checking on the result after
387 adding in the value contained in the object file. */
388 if (howto->complain_on_overflow != complain_overflow_dont)
390 bfd_vma check;
392 /* Get the value that will be used for the relocation, but
393 starting at bit position zero. */
394 if (howto->rightshift > howto->bitpos)
395 check = relocation >> (howto->rightshift - howto->bitpos);
396 else
397 check = relocation << (howto->bitpos - howto->rightshift);
398 switch (howto->complain_on_overflow)
400 case complain_overflow_signed:
402 /* Assumes two's complement. */
403 bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
404 bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
406 /* The above right shift is incorrect for a signed value.
407 Fix it up by forcing on the upper bits. */
408 if (howto->rightshift > howto->bitpos
409 && (bfd_signed_vma) relocation < 0)
410 check |= ((bfd_vma) - 1
411 & ~((bfd_vma) - 1
412 >> (howto->rightshift - howto->bitpos)));
413 if ((bfd_signed_vma) check > reloc_signed_max
414 || (bfd_signed_vma) check < reloc_signed_min)
415 flag = bfd_reloc_overflow;
417 break;
418 case complain_overflow_unsigned:
420 /* Assumes two's complement. This expression avoids
421 overflow if howto->bitsize is the number of bits in
422 bfd_vma. */
423 bfd_vma reloc_unsigned_max =
424 (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
426 if ((bfd_vma) check > reloc_unsigned_max)
427 flag = bfd_reloc_overflow;
429 break;
430 case complain_overflow_bitfield:
432 /* Assumes two's complement. This expression avoids
433 overflow if howto->bitsize is the number of bits in
434 bfd_vma. */
435 bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
437 if (((bfd_vma) check & ~reloc_bits) != 0
438 && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
440 /* The above right shift is incorrect for a signed
441 value. See if turning on the upper bits fixes the
442 overflow. */
443 if (howto->rightshift > howto->bitpos
444 && (bfd_signed_vma) relocation < 0)
446 check |= ((bfd_vma) - 1
447 & ~((bfd_vma) - 1
448 >> (howto->rightshift - howto->bitpos)));
449 if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
450 flag = bfd_reloc_overflow;
452 else
453 flag = bfd_reloc_overflow;
456 break;
457 default:
458 abort ();
463 Either we are relocating all the way, or we don't want to apply
464 the relocation to the reloc entry (probably because there isn't
465 any room in the output format to describe addends to relocs)
468 /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler
469 (OSF version 1.3, compiler version 3.11). It miscompiles the
470 following program:
472 struct str
474 unsigned int i0;
475 } s = { 0 };
478 main ()
480 unsigned long x;
482 x = 0x100000000;
483 x <<= (unsigned long) s.i0;
484 if (x == 0)
485 printf ("failed\n");
486 else
487 printf ("succeeded (%lx)\n", x);
491 relocation >>= (bfd_vma) howto->rightshift;
493 /* Shift everything up to where it's going to be used */
495 relocation <<= (bfd_vma) howto->bitpos;
497 /* Wait for the day when all have the mask in them */
499 /* What we do:
500 i instruction to be left alone
501 o offset within instruction
502 r relocation offset to apply
503 S src mask
504 D dst mask
505 N ~dst mask
506 A part 1
507 B part 2
508 R result
510 Do this:
511 i i i i i o o o o o from bfd_get<size>
512 and S S S S S to get the size offset we want
513 + r r r r r r r r r r to get the final value to place
514 and D D D D D to chop to right size
515 -----------------------
516 A A A A A
517 And this:
518 ... i i i i i o o o o o from bfd_get<size>
519 and N N N N N get instruction
520 -----------------------
521 ... B B B B B
523 And then:
524 B B B B B
525 or A A A A A
526 -----------------------
527 R R R R R R R R R R put into bfd_put<size>
530 #define DOIT(x) \
531 x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
533 switch (howto->size)
535 case 0:
537 char x = get_data (data, addr, 1);
538 DOIT (x);
539 overflow = put_data(x, data, addr, 1);
541 break;
543 case 1:
544 if (relocation)
546 short x = get_data (data, addr, 2);
547 DOIT (x);
548 overflow = put_data(x, (unsigned char *) data, addr, 2);
550 break;
551 case 2:
552 if (relocation)
554 long x = get_data (data, addr, 4);
555 DOIT (x);
556 overflow = put_data(x, data, addr, 4);
558 break;
559 case -2:
561 long x = get_data(data, addr, 4);
562 relocation = -relocation;
563 DOIT(x);
564 overflow = put_data(x, data , addr, 4);
566 break;
568 case 3:
569 /* Do nothing */
570 break;
572 case 4:
573 #ifdef BFD64
574 if (relocation)
576 bfd_vma x = get_data (data, addr, 8);
577 DOIT (x);
578 overflow = put_data(x, data, addr, 8);
580 #else
581 abort ();
582 #endif
583 break;
584 default:
585 return bfd_reloc_other;
587 if ((howto->complain_on_overflow != complain_overflow_dont) && overflow)
588 return bfd_reloc_overflow;
590 return flag;
593 /* Relocate a given location using a given value and howto. */
595 bfd_reloc_status_type
596 _bfd_do_ns32k_reloc_contents ( howto, input_bfd, relocation, location,
597 get_data, put_data)
598 reloc_howto_type *howto;
599 bfd *input_bfd;
600 bfd_vma relocation;
601 bfd_byte *location;
602 long (*get_data)();
603 int (*put_data)();
605 int size;
606 bfd_vma x;
607 boolean overflow;
609 /* If the size is negative, negate RELOCATION. This isn't very
610 general. */
611 if (howto->size < 0)
612 relocation = -relocation;
614 /* Get the value we are going to relocate. */
615 size = bfd_get_reloc_size (howto);
616 switch (size)
618 default:
619 case 0:
620 abort ();
621 case 1:
622 case 2:
623 case 4:
624 #ifdef BFD64
625 case 8:
626 #endif
627 x = get_data (location, 0, size);
628 break;
631 /* Check for overflow. FIXME: We may drop bits during the addition
632 which we don't check for. We must either check at every single
633 operation, which would be tedious, or we must do the computations
634 in a type larger than bfd_vma, which would be inefficient. */
635 overflow = false;
636 if (howto->complain_on_overflow != complain_overflow_dont)
638 bfd_vma check;
639 bfd_signed_vma signed_check;
640 bfd_vma add;
641 bfd_signed_vma signed_add;
643 if (howto->rightshift == 0)
645 check = relocation;
646 signed_check = (bfd_signed_vma) relocation;
648 else
650 /* Drop unwanted bits from the value we are relocating to. */
651 check = relocation >> howto->rightshift;
653 /* If this is a signed value, the rightshift just dropped
654 leading 1 bits (assuming twos complement). */
655 if ((bfd_signed_vma) relocation >= 0)
656 signed_check = check;
657 else
658 signed_check = (check
659 | ((bfd_vma) - 1
660 & ~((bfd_vma) - 1 >> howto->rightshift)));
663 /* Get the value from the object file. */
664 add = x & howto->src_mask;
666 /* Get the value from the object file with an appropriate sign.
667 The expression involving howto->src_mask isolates the upper
668 bit of src_mask. If that bit is set in the value we are
669 adding, it is negative, and we subtract out that number times
670 two. If src_mask includes the highest possible bit, then we
671 can not get the upper bit, but that does not matter since
672 signed_add needs no adjustment to become negative in that
673 case. */
674 signed_add = add;
675 if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
676 signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
678 /* Add the value from the object file, shifted so that it is a
679 straight number. */
680 if (howto->bitpos == 0)
682 check += add;
683 signed_check += signed_add;
685 else
687 check += add >> howto->bitpos;
689 /* For the signed case we use ADD, rather than SIGNED_ADD,
690 to avoid warnings from SVR4 cc. This is OK since we
691 explictly handle the sign bits. */
692 if (signed_add >= 0)
693 signed_check += add >> howto->bitpos;
694 else
695 signed_check += ((add >> howto->bitpos)
696 | ((bfd_vma) - 1
697 & ~((bfd_vma) - 1 >> howto->bitpos)));
700 switch (howto->complain_on_overflow)
702 case complain_overflow_signed:
704 /* Assumes two's complement. */
705 bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
706 bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
708 if (signed_check > reloc_signed_max
709 || signed_check < reloc_signed_min)
710 overflow = true;
712 break;
713 case complain_overflow_unsigned:
715 /* Assumes two's complement. This expression avoids
716 overflow if howto->bitsize is the number of bits in
717 bfd_vma. */
718 bfd_vma reloc_unsigned_max =
719 (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
721 if (check > reloc_unsigned_max)
722 overflow = true;
724 break;
725 case complain_overflow_bitfield:
727 /* Assumes two's complement. This expression avoids
728 overflow if howto->bitsize is the number of bits in
729 bfd_vma. */
730 bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
732 if ((check & ~reloc_bits) != 0
733 && (((bfd_vma) signed_check & ~reloc_bits)
734 != (-1 & ~reloc_bits)))
735 overflow = true;
737 break;
738 default:
739 abort ();
743 /* Put RELOCATION in the right bits. */
744 relocation >>= (bfd_vma) howto->rightshift;
745 relocation <<= (bfd_vma) howto->bitpos;
747 /* Add RELOCATION to the right bits of X. */
748 x = ((x & ~howto->dst_mask)
749 | (((x & howto->src_mask) + relocation) & howto->dst_mask));
751 /* Put the relocated value back in the object file. */
752 switch (size)
754 default:
755 case 0:
756 abort ();
757 case 1:
758 case 2:
759 case 4:
760 #ifdef BFD64
761 case 8:
762 #endif
763 put_data(x, location, 0, size);
764 break;
767 return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
770 bfd_reloc_status_type
771 _bfd_ns32k_reloc_disp (abfd, reloc_entry, symbol, data, input_section,
772 output_bfd, error_message)
773 bfd *abfd;
774 arelent *reloc_entry;
775 struct symbol_cache_entry *symbol;
776 PTR data;
777 asection *input_section;
778 bfd *output_bfd;
779 char **error_message;
781 return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
782 output_bfd, error_message,
783 _bfd_ns32k_get_displacement,
784 _bfd_ns32k_put_displacement);
787 bfd_reloc_status_type
788 _bfd_ns32k_reloc_imm (abfd, reloc_entry, symbol, data, input_section,
789 output_bfd, error_message)
790 bfd *abfd;
791 arelent *reloc_entry;
792 struct symbol_cache_entry *symbol;
793 PTR data;
794 asection *input_section;
795 bfd *output_bfd;
796 char **error_message;
798 return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
799 output_bfd, error_message, _bfd_ns32k_get_immediate,
800 _bfd_ns32k_put_immediate);
803 bfd_reloc_status_type
804 _bfd_ns32k_final_link_relocate (howto, input_bfd, input_section, contents,
805 address, value, addend)
806 reloc_howto_type *howto;
807 bfd *input_bfd;
808 asection *input_section;
809 bfd_byte *contents;
810 bfd_vma address;
811 bfd_vma value;
812 bfd_vma addend;
814 bfd_vma relocation;
816 /* Sanity check the address. */
817 if (address > input_section->_cooked_size)
818 return bfd_reloc_outofrange;
820 /* This function assumes that we are dealing with a basic relocation
821 against a symbol. We want to compute the value of the symbol to
822 relocate to. This is just VALUE, the value of the symbol, plus
823 ADDEND, any addend associated with the reloc. */
824 relocation = value + addend;
826 /* If the relocation is PC relative, we want to set RELOCATION to
827 the distance between the symbol (currently in RELOCATION) and the
828 location we are relocating. Some targets (e.g., i386-aout)
829 arrange for the contents of the section to be the negative of the
830 offset of the location within the section; for such targets
831 pcrel_offset is false. Other targets (e.g., m88kbcs or ELF)
832 simply leave the contents of the section as zero; for such
833 targets pcrel_offset is true. If pcrel_offset is false we do not
834 need to subtract out the offset of the location within the
835 section (which is just ADDRESS). */
836 if (howto->pc_relative)
838 relocation -= (input_section->output_section->vma
839 + input_section->output_offset);
840 if (howto->pcrel_offset)
841 relocation -= address;
844 return _bfd_ns32k_relocate_contents (howto, input_bfd, relocation,
845 contents + address);