* acinclude.m4: Include libtool and gettext macros from the
[binutils.git] / bfd / cpu-ns32k.c
blobc49630ca5e4e94b57b64e235f3784e3cb7c38386
1 /* BFD support for the ns32k architecture.
2 Copyright (C) 1990, 91, 94, 95, 96, 98, 1999 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 ATTRIBUTE_UNUSED;
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)
295 #if 1
296 /* For m68k-coff, the addend was being subtracted twice during
297 relocation with -r. Removing the line below this comment
298 fixes that problem; see PR 2953.
300 However, Ian wrote the following, regarding removing the line below,
301 which explains why it is still enabled: --djm
303 If you put a patch like that into BFD you need to check all the COFF
304 linkers. I am fairly certain that patch will break coff-i386 (e.g.,
305 SCO); see coff_i386_reloc in coff-i386.c where I worked around the
306 problem in a different way. There may very well be a reason that the
307 code works as it does.
309 Hmmm. The first obvious point is that bfd_perform_relocation should
310 not have any tests that depend upon the flavour. It's seem like
311 entirely the wrong place for such a thing. The second obvious point
312 is that the current code ignores the reloc addend when producing
313 relocateable output for COFF. That's peculiar. In fact, I really
314 have no idea what the point of the line you want to remove is.
316 A typical COFF reloc subtracts the old value of the symbol and adds in
317 the new value to the location in the object file (if it's a pc
318 relative reloc it adds the difference between the symbol value and the
319 location). When relocating we need to preserve that property.
321 BFD handles this by setting the addend to the negative of the old
322 value of the symbol. Unfortunately it handles common symbols in a
323 non-standard way (it doesn't subtract the old value) but that's a
324 different story (we can't change it without losing backward
325 compatibility with old object files) (coff-i386 does subtract the old
326 value, to be compatible with existing coff-i386 targets, like SCO).
328 So everything works fine when not producing relocateable output. When
329 we are producing relocateable output, logically we should do exactly
330 what we do when not producing relocateable output. Therefore, your
331 patch is correct. In fact, it should probably always just set
332 reloc_entry->addend to 0 for all cases, since it is, in fact, going to
333 add the value into the object file. This won't hurt the COFF code,
334 which doesn't use the addend; I'm not sure what it will do to other
335 formats (the thing to check for would be whether any formats both use
336 the addend and set partial_inplace).
338 When I wanted to make coff-i386 produce relocateable output, I ran
339 into the problem that you are running into: I wanted to remove that
340 line. Rather than risk it, I made the coff-i386 relocs use a special
341 function; it's coff_i386_reloc in coff-i386.c. The function
342 specifically adds the addend field into the object file, knowing that
343 bfd_perform_relocation is not going to. If you remove that line, then
344 coff-i386.c will wind up adding the addend field in twice. It's
345 trivial to fix; it just needs to be done.
347 The problem with removing the line is just that it may break some
348 working code. With BFD it's hard to be sure of anything. The right
349 way to deal with this is simply to build and test at least all the
350 supported COFF targets. It should be straightforward if time and disk
351 space consuming. For each target:
352 1) build the linker
353 2) generate some executable, and link it using -r (I would
354 probably use paranoia.o and link against newlib/libc.a, which
355 for all the supported targets would be available in
356 /usr/cygnus/progressive/H-host/target/lib/libc.a).
357 3) make the change to reloc.c
358 4) rebuild the linker
359 5) repeat step 2
360 6) if the resulting object files are the same, you have at least
361 made it no worse
362 7) if they are different you have to figure out which version is
363 right
365 relocation -= reloc_entry->addend;
366 #endif
367 reloc_entry->addend = 0;
369 else
371 reloc_entry->addend = relocation;
375 else
377 reloc_entry->addend = 0;
380 /* FIXME: This overflow checking is incomplete, because the value
381 might have overflowed before we get here. For a correct check we
382 need to compute the value in a size larger than bitsize, but we
383 can't reasonably do that for a reloc the same size as a host
384 machine word.
385 FIXME: We should also do overflow checking on the result after
386 adding in the value contained in the object file. */
387 if (howto->complain_on_overflow != complain_overflow_dont)
389 bfd_vma check;
391 /* Get the value that will be used for the relocation, but
392 starting at bit position zero. */
393 if (howto->rightshift > howto->bitpos)
394 check = relocation >> (howto->rightshift - howto->bitpos);
395 else
396 check = relocation << (howto->bitpos - howto->rightshift);
397 switch (howto->complain_on_overflow)
399 case complain_overflow_signed:
401 /* Assumes two's complement. */
402 bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
403 bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
405 /* The above right shift is incorrect for a signed value.
406 Fix it up by forcing on the upper bits. */
407 if (howto->rightshift > howto->bitpos
408 && (bfd_signed_vma) relocation < 0)
409 check |= ((bfd_vma) - 1
410 & ~((bfd_vma) - 1
411 >> (howto->rightshift - howto->bitpos)));
412 if ((bfd_signed_vma) check > reloc_signed_max
413 || (bfd_signed_vma) check < reloc_signed_min)
414 flag = bfd_reloc_overflow;
416 break;
417 case complain_overflow_unsigned:
419 /* Assumes two's complement. This expression avoids
420 overflow if howto->bitsize is the number of bits in
421 bfd_vma. */
422 bfd_vma reloc_unsigned_max =
423 (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
425 if ((bfd_vma) check > reloc_unsigned_max)
426 flag = bfd_reloc_overflow;
428 break;
429 case complain_overflow_bitfield:
431 /* Assumes two's complement. This expression avoids
432 overflow if howto->bitsize is the number of bits in
433 bfd_vma. */
434 bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
436 if (((bfd_vma) check & ~reloc_bits) != 0
437 && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
439 /* The above right shift is incorrect for a signed
440 value. See if turning on the upper bits fixes the
441 overflow. */
442 if (howto->rightshift > howto->bitpos
443 && (bfd_signed_vma) relocation < 0)
445 check |= ((bfd_vma) - 1
446 & ~((bfd_vma) - 1
447 >> (howto->rightshift - howto->bitpos)));
448 if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
449 flag = bfd_reloc_overflow;
451 else
452 flag = bfd_reloc_overflow;
455 break;
456 default:
457 abort ();
462 Either we are relocating all the way, or we don't want to apply
463 the relocation to the reloc entry (probably because there isn't
464 any room in the output format to describe addends to relocs)
467 /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler
468 (OSF version 1.3, compiler version 3.11). It miscompiles the
469 following program:
471 struct str
473 unsigned int i0;
474 } s = { 0 };
477 main ()
479 unsigned long x;
481 x = 0x100000000;
482 x <<= (unsigned long) s.i0;
483 if (x == 0)
484 printf ("failed\n");
485 else
486 printf ("succeeded (%lx)\n", x);
490 relocation >>= (bfd_vma) howto->rightshift;
492 /* Shift everything up to where it's going to be used */
494 relocation <<= (bfd_vma) howto->bitpos;
496 /* Wait for the day when all have the mask in them */
498 /* What we do:
499 i instruction to be left alone
500 o offset within instruction
501 r relocation offset to apply
502 S src mask
503 D dst mask
504 N ~dst mask
505 A part 1
506 B part 2
507 R result
509 Do this:
510 i i i i i o o o o o from bfd_get<size>
511 and S S S S S to get the size offset we want
512 + r r r r r r r r r r to get the final value to place
513 and D D D D D to chop to right size
514 -----------------------
515 A A A A A
516 And this:
517 ... i i i i i o o o o o from bfd_get<size>
518 and N N N N N get instruction
519 -----------------------
520 ... B B B B B
522 And then:
523 B B B B B
524 or A A A A A
525 -----------------------
526 R R R R R R R R R R put into bfd_put<size>
529 #define DOIT(x) \
530 x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
532 switch (howto->size)
534 case 0:
536 char x = get_data (data, addr, 1);
537 DOIT (x);
538 overflow = put_data(x, data, addr, 1);
540 break;
542 case 1:
543 if (relocation)
545 short x = get_data (data, addr, 2);
546 DOIT (x);
547 overflow = put_data(x, (unsigned char *) data, addr, 2);
549 break;
550 case 2:
551 if (relocation)
553 long x = get_data (data, addr, 4);
554 DOIT (x);
555 overflow = put_data(x, data, addr, 4);
557 break;
558 case -2:
560 long x = get_data(data, addr, 4);
561 relocation = -relocation;
562 DOIT(x);
563 overflow = put_data(x, data , addr, 4);
565 break;
567 case 3:
568 /* Do nothing */
569 break;
571 case 4:
572 #ifdef BFD64
573 if (relocation)
575 bfd_vma x = get_data (data, addr, 8);
576 DOIT (x);
577 overflow = put_data(x, data, addr, 8);
579 #else
580 abort ();
581 #endif
582 break;
583 default:
584 return bfd_reloc_other;
586 if ((howto->complain_on_overflow != complain_overflow_dont) && overflow)
587 return bfd_reloc_overflow;
589 return flag;
592 /* Relocate a given location using a given value and howto. */
594 bfd_reloc_status_type
595 _bfd_do_ns32k_reloc_contents ( howto, input_bfd, relocation, location,
596 get_data, put_data)
597 reloc_howto_type *howto;
598 bfd *input_bfd ATTRIBUTE_UNUSED;
599 bfd_vma relocation;
600 bfd_byte *location;
601 long (*get_data)();
602 int (*put_data)();
604 int size;
605 bfd_vma x;
606 boolean overflow;
608 /* If the size is negative, negate RELOCATION. This isn't very
609 general. */
610 if (howto->size < 0)
611 relocation = -relocation;
613 /* Get the value we are going to relocate. */
614 size = bfd_get_reloc_size (howto);
615 switch (size)
617 default:
618 case 0:
619 abort ();
620 case 1:
621 case 2:
622 case 4:
623 #ifdef BFD64
624 case 8:
625 #endif
626 x = get_data (location, 0, size);
627 break;
630 /* Check for overflow. FIXME: We may drop bits during the addition
631 which we don't check for. We must either check at every single
632 operation, which would be tedious, or we must do the computations
633 in a type larger than bfd_vma, which would be inefficient. */
634 overflow = false;
635 if (howto->complain_on_overflow != complain_overflow_dont)
637 bfd_vma check;
638 bfd_signed_vma signed_check;
639 bfd_vma add;
640 bfd_signed_vma signed_add;
642 if (howto->rightshift == 0)
644 check = relocation;
645 signed_check = (bfd_signed_vma) relocation;
647 else
649 /* Drop unwanted bits from the value we are relocating to. */
650 check = relocation >> howto->rightshift;
652 /* If this is a signed value, the rightshift just dropped
653 leading 1 bits (assuming twos complement). */
654 if ((bfd_signed_vma) relocation >= 0)
655 signed_check = check;
656 else
657 signed_check = (check
658 | ((bfd_vma) - 1
659 & ~((bfd_vma) - 1 >> howto->rightshift)));
662 /* Get the value from the object file. */
663 add = x & howto->src_mask;
665 /* Get the value from the object file with an appropriate sign.
666 The expression involving howto->src_mask isolates the upper
667 bit of src_mask. If that bit is set in the value we are
668 adding, it is negative, and we subtract out that number times
669 two. If src_mask includes the highest possible bit, then we
670 can not get the upper bit, but that does not matter since
671 signed_add needs no adjustment to become negative in that
672 case. */
673 signed_add = add;
674 if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
675 signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
677 /* Add the value from the object file, shifted so that it is a
678 straight number. */
679 if (howto->bitpos == 0)
681 check += add;
682 signed_check += signed_add;
684 else
686 check += add >> howto->bitpos;
688 /* For the signed case we use ADD, rather than SIGNED_ADD,
689 to avoid warnings from SVR4 cc. This is OK since we
690 explictly handle the sign bits. */
691 if (signed_add >= 0)
692 signed_check += add >> howto->bitpos;
693 else
694 signed_check += ((add >> howto->bitpos)
695 | ((bfd_vma) - 1
696 & ~((bfd_vma) - 1 >> howto->bitpos)));
699 switch (howto->complain_on_overflow)
701 case complain_overflow_signed:
703 /* Assumes two's complement. */
704 bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
705 bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
707 if (signed_check > reloc_signed_max
708 || signed_check < reloc_signed_min)
709 overflow = true;
711 break;
712 case complain_overflow_unsigned:
714 /* Assumes two's complement. This expression avoids
715 overflow if howto->bitsize is the number of bits in
716 bfd_vma. */
717 bfd_vma reloc_unsigned_max =
718 (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
720 if (check > reloc_unsigned_max)
721 overflow = true;
723 break;
724 case complain_overflow_bitfield:
726 /* Assumes two's complement. This expression avoids
727 overflow if howto->bitsize is the number of bits in
728 bfd_vma. */
729 bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
731 if ((check & ~reloc_bits) != 0
732 && (((bfd_vma) signed_check & ~reloc_bits)
733 != (-1 & ~reloc_bits)))
734 overflow = true;
736 break;
737 default:
738 abort ();
742 /* Put RELOCATION in the right bits. */
743 relocation >>= (bfd_vma) howto->rightshift;
744 relocation <<= (bfd_vma) howto->bitpos;
746 /* Add RELOCATION to the right bits of X. */
747 x = ((x & ~howto->dst_mask)
748 | (((x & howto->src_mask) + relocation) & howto->dst_mask));
750 /* Put the relocated value back in the object file. */
751 switch (size)
753 default:
754 case 0:
755 abort ();
756 case 1:
757 case 2:
758 case 4:
759 #ifdef BFD64
760 case 8:
761 #endif
762 put_data(x, location, 0, size);
763 break;
766 return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
769 bfd_reloc_status_type
770 _bfd_ns32k_reloc_disp (abfd, reloc_entry, symbol, data, input_section,
771 output_bfd, error_message)
772 bfd *abfd;
773 arelent *reloc_entry;
774 struct symbol_cache_entry *symbol;
775 PTR data;
776 asection *input_section;
777 bfd *output_bfd;
778 char **error_message;
780 return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
781 output_bfd, error_message,
782 _bfd_ns32k_get_displacement,
783 _bfd_ns32k_put_displacement);
786 bfd_reloc_status_type
787 _bfd_ns32k_reloc_imm (abfd, reloc_entry, symbol, data, input_section,
788 output_bfd, error_message)
789 bfd *abfd;
790 arelent *reloc_entry;
791 struct symbol_cache_entry *symbol;
792 PTR data;
793 asection *input_section;
794 bfd *output_bfd;
795 char **error_message;
797 return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
798 output_bfd, error_message, _bfd_ns32k_get_immediate,
799 _bfd_ns32k_put_immediate);
802 bfd_reloc_status_type
803 _bfd_ns32k_final_link_relocate (howto, input_bfd, input_section, contents,
804 address, value, addend)
805 reloc_howto_type *howto;
806 bfd *input_bfd;
807 asection *input_section;
808 bfd_byte *contents;
809 bfd_vma address;
810 bfd_vma value;
811 bfd_vma addend;
813 bfd_vma relocation;
815 /* Sanity check the address. */
816 if (address > input_section->_cooked_size)
817 return bfd_reloc_outofrange;
819 /* This function assumes that we are dealing with a basic relocation
820 against a symbol. We want to compute the value of the symbol to
821 relocate to. This is just VALUE, the value of the symbol, plus
822 ADDEND, any addend associated with the reloc. */
823 relocation = value + addend;
825 /* If the relocation is PC relative, we want to set RELOCATION to
826 the distance between the symbol (currently in RELOCATION) and the
827 location we are relocating. Some targets (e.g., i386-aout)
828 arrange for the contents of the section to be the negative of the
829 offset of the location within the section; for such targets
830 pcrel_offset is false. Other targets (e.g., m88kbcs or ELF)
831 simply leave the contents of the section as zero; for such
832 targets pcrel_offset is true. If pcrel_offset is false we do not
833 need to subtract out the offset of the location within the
834 section (which is just ADDRESS). */
835 if (howto->pc_relative)
837 relocation -= (input_section->output_section->vma
838 + input_section->output_offset);
839 if (howto->pcrel_offset)
840 relocation -= address;
843 return _bfd_ns32k_relocate_contents (howto, input_bfd, relocation,
844 contents + address);