2001-03-22 Philip Blundell <philb@gnu.org>
[binutils.git] / bfd / cpu-ns32k.c
blob6083a7ddc3192c62eae2247a3e2b15054f719291
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;
203 /* Is the address of the relocation really within the section? */
204 if (reloc_entry->address > input_section->_cooked_size)
205 return bfd_reloc_outofrange;
207 /* Work out which section the relocation is targetted at and the
208 initial relocation command value. */
210 /* Get symbol value. (Common symbols are special.) */
211 if (bfd_is_com_section (symbol->section))
212 relocation = 0;
213 else
214 relocation = symbol->value;
216 reloc_target_output_section = symbol->section->output_section;
218 /* Convert input-section-relative symbol value to absolute. */
219 if (output_bfd && howto->partial_inplace == false)
220 output_base = 0;
221 else
222 output_base = reloc_target_output_section->vma;
224 relocation += output_base + symbol->section->output_offset;
226 /* Add in supplied addend. */
227 relocation += reloc_entry->addend;
229 /* Here the variable relocation holds the final address of the
230 symbol we are relocating against, plus any addend. */
232 if (howto->pc_relative == true)
234 /* This is a PC relative relocation. We want to set RELOCATION
235 to the distance between the address of the symbol and the
236 location. RELOCATION is already the address of the symbol.
238 We start by subtracting the address of the section containing
239 the location.
241 If pcrel_offset is set, we must further subtract the position
242 of the location within the section. Some targets arrange for
243 the addend to be the negative of the position of the location
244 within the section; for example, i386-aout does this. For
245 i386-aout, pcrel_offset is false. Some other targets do not
246 include the position of the location; for example, m88kbcs,
247 or ELF. For those targets, pcrel_offset is true.
249 If we are producing relocateable output, then we must ensure
250 that this reloc will be correctly computed when the final
251 relocation is done. If pcrel_offset is false we want to wind
252 up with the negative of the location within the section,
253 which means we must adjust the existing addend by the change
254 in the location within the section. If pcrel_offset is true
255 we do not want to adjust the existing addend at all.
257 FIXME: This seems logical to me, but for the case of
258 producing relocateable output it is not what the code
259 actually does. I don't want to change it, because it seems
260 far too likely that something will break. */
262 relocation -=
263 input_section->output_section->vma + input_section->output_offset;
265 if (howto->pcrel_offset == true)
266 relocation -= reloc_entry->address;
269 if (output_bfd != (bfd *) NULL)
271 if (howto->partial_inplace == false)
273 /* This is a partial relocation, and we want to apply the relocation
274 to the reloc entry rather than the raw data. Modify the reloc
275 inplace to reflect what we now know. */
276 reloc_entry->addend = relocation;
277 reloc_entry->address += input_section->output_offset;
278 return flag;
280 else
282 /* This is a partial relocation, but inplace, so modify the
283 reloc record a bit.
285 If we've relocated with a symbol with a section, change
286 into a ref to the section belonging to the symbol. */
288 reloc_entry->address += input_section->output_offset;
290 /* WTF?? */
291 if (abfd->xvec->flavour == bfd_target_coff_flavour)
293 #if 1
294 /* For m68k-coff, the addend was being subtracted twice during
295 relocation with -r. Removing the line below this comment
296 fixes that problem; see PR 2953.
298 However, Ian wrote the following, regarding removing the line below,
299 which explains why it is still enabled: --djm
301 If you put a patch like that into BFD you need to check all the COFF
302 linkers. I am fairly certain that patch will break coff-i386 (e.g.,
303 SCO); see coff_i386_reloc in coff-i386.c where I worked around the
304 problem in a different way. There may very well be a reason that the
305 code works as it does.
307 Hmmm. The first obvious point is that bfd_perform_relocation should
308 not have any tests that depend upon the flavour. It's seem like
309 entirely the wrong place for such a thing. The second obvious point
310 is that the current code ignores the reloc addend when producing
311 relocateable output for COFF. That's peculiar. In fact, I really
312 have no idea what the point of the line you want to remove is.
314 A typical COFF reloc subtracts the old value of the symbol and adds in
315 the new value to the location in the object file (if it's a pc
316 relative reloc it adds the difference between the symbol value and the
317 location). When relocating we need to preserve that property.
319 BFD handles this by setting the addend to the negative of the old
320 value of the symbol. Unfortunately it handles common symbols in a
321 non-standard way (it doesn't subtract the old value) but that's a
322 different story (we can't change it without losing backward
323 compatibility with old object files) (coff-i386 does subtract the old
324 value, to be compatible with existing coff-i386 targets, like SCO).
326 So everything works fine when not producing relocateable output. When
327 we are producing relocateable output, logically we should do exactly
328 what we do when not producing relocateable output. Therefore, your
329 patch is correct. In fact, it should probably always just set
330 reloc_entry->addend to 0 for all cases, since it is, in fact, going to
331 add the value into the object file. This won't hurt the COFF code,
332 which doesn't use the addend; I'm not sure what it will do to other
333 formats (the thing to check for would be whether any formats both use
334 the addend and set partial_inplace).
336 When I wanted to make coff-i386 produce relocateable output, I ran
337 into the problem that you are running into: I wanted to remove that
338 line. Rather than risk it, I made the coff-i386 relocs use a special
339 function; it's coff_i386_reloc in coff-i386.c. The function
340 specifically adds the addend field into the object file, knowing that
341 bfd_perform_relocation is not going to. If you remove that line, then
342 coff-i386.c will wind up adding the addend field in twice. It's
343 trivial to fix; it just needs to be done.
345 The problem with removing the line is just that it may break some
346 working code. With BFD it's hard to be sure of anything. The right
347 way to deal with this is simply to build and test at least all the
348 supported COFF targets. It should be straightforward if time and disk
349 space consuming. For each target:
350 1) build the linker
351 2) generate some executable, and link it using -r (I would
352 probably use paranoia.o and link against newlib/libc.a, which
353 for all the supported targets would be available in
354 /usr/cygnus/progressive/H-host/target/lib/libc.a).
355 3) make the change to reloc.c
356 4) rebuild the linker
357 5) repeat step 2
358 6) if the resulting object files are the same, you have at least
359 made it no worse
360 7) if they are different you have to figure out which version is
361 right
363 relocation -= reloc_entry->addend;
364 #endif
365 reloc_entry->addend = 0;
367 else
369 reloc_entry->addend = relocation;
373 else
375 reloc_entry->addend = 0;
378 /* FIXME: This overflow checking is incomplete, because the value
379 might have overflowed before we get here. For a correct check we
380 need to compute the value in a size larger than bitsize, but we
381 can't reasonably do that for a reloc the same size as a host
382 machine word.
383 FIXME: We should also do overflow checking on the result after
384 adding in the value contained in the object file. */
385 if (howto->complain_on_overflow != complain_overflow_dont)
387 bfd_vma check;
389 /* Get the value that will be used for the relocation, but
390 starting at bit position zero. */
391 if (howto->rightshift > howto->bitpos)
392 check = relocation >> (howto->rightshift - howto->bitpos);
393 else
394 check = relocation << (howto->bitpos - howto->rightshift);
395 switch (howto->complain_on_overflow)
397 case complain_overflow_signed:
399 /* Assumes two's complement. */
400 bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
401 bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
403 /* The above right shift is incorrect for a signed value.
404 Fix it up by forcing on the upper bits. */
405 if (howto->rightshift > howto->bitpos
406 && (bfd_signed_vma) relocation < 0)
407 check |= ((bfd_vma) - 1
408 & ~((bfd_vma) - 1
409 >> (howto->rightshift - howto->bitpos)));
410 if ((bfd_signed_vma) check > reloc_signed_max
411 || (bfd_signed_vma) check < reloc_signed_min)
412 flag = bfd_reloc_overflow;
414 break;
415 case complain_overflow_unsigned:
417 /* Assumes two's complement. This expression avoids
418 overflow if howto->bitsize is the number of bits in
419 bfd_vma. */
420 bfd_vma reloc_unsigned_max =
421 (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
423 if ((bfd_vma) check > reloc_unsigned_max)
424 flag = bfd_reloc_overflow;
426 break;
427 case complain_overflow_bitfield:
429 /* Assumes two's complement. This expression avoids
430 overflow if howto->bitsize is the number of bits in
431 bfd_vma. */
432 bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
434 if (((bfd_vma) check & ~reloc_bits) != 0
435 && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
437 /* The above right shift is incorrect for a signed
438 value. See if turning on the upper bits fixes the
439 overflow. */
440 if (howto->rightshift > howto->bitpos
441 && (bfd_signed_vma) relocation < 0)
443 check |= ((bfd_vma) - 1
444 & ~((bfd_vma) - 1
445 >> (howto->rightshift - howto->bitpos)));
446 if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
447 flag = bfd_reloc_overflow;
449 else
450 flag = bfd_reloc_overflow;
453 break;
454 default:
455 abort ();
460 Either we are relocating all the way, or we don't want to apply
461 the relocation to the reloc entry (probably because there isn't
462 any room in the output format to describe addends to relocs)
465 /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler
466 (OSF version 1.3, compiler version 3.11). It miscompiles the
467 following program:
469 struct str
471 unsigned int i0;
472 } s = { 0 };
475 main ()
477 unsigned long x;
479 x = 0x100000000;
480 x <<= (unsigned long) s.i0;
481 if (x == 0)
482 printf ("failed\n");
483 else
484 printf ("succeeded (%lx)\n", x);
488 relocation >>= (bfd_vma) howto->rightshift;
490 /* Shift everything up to where it's going to be used */
492 relocation <<= (bfd_vma) howto->bitpos;
494 /* Wait for the day when all have the mask in them */
496 /* What we do:
497 i instruction to be left alone
498 o offset within instruction
499 r relocation offset to apply
500 S src mask
501 D dst mask
502 N ~dst mask
503 A part 1
504 B part 2
505 R result
507 Do this:
508 i i i i i o o o o o from bfd_get<size>
509 and S S S S S to get the size offset we want
510 + r r r r r r r r r r to get the final value to place
511 and D D D D D to chop to right size
512 -----------------------
513 A A A A A
514 And this:
515 ... i i i i i o o o o o from bfd_get<size>
516 and N N N N N get instruction
517 -----------------------
518 ... B B B B B
520 And then:
521 B B B B B
522 or A A A A A
523 -----------------------
524 R R R R R R R R R R put into bfd_put<size>
527 #define DOIT(x) \
528 x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
530 switch (howto->size)
532 case 0:
534 char x = get_data (data, addr, 1);
535 DOIT (x);
536 overflow = put_data(x, data, addr, 1);
538 break;
540 case 1:
541 if (relocation)
543 short x = get_data (data, addr, 2);
544 DOIT (x);
545 overflow = put_data(x, (unsigned char *) data, addr, 2);
547 break;
548 case 2:
549 if (relocation)
551 long x = get_data (data, addr, 4);
552 DOIT (x);
553 overflow = put_data(x, data, addr, 4);
555 break;
556 case -2:
558 long x = get_data(data, addr, 4);
559 relocation = -relocation;
560 DOIT(x);
561 overflow = put_data(x, data , addr, 4);
563 break;
565 case 3:
566 /* Do nothing */
567 break;
569 case 4:
570 #ifdef BFD64
571 if (relocation)
573 bfd_vma x = get_data (data, addr, 8);
574 DOIT (x);
575 overflow = put_data(x, data, addr, 8);
577 #else
578 abort ();
579 #endif
580 break;
581 default:
582 return bfd_reloc_other;
584 if ((howto->complain_on_overflow != complain_overflow_dont) && overflow)
585 return bfd_reloc_overflow;
587 return flag;
590 /* Relocate a given location using a given value and howto. */
592 bfd_reloc_status_type
593 _bfd_do_ns32k_reloc_contents ( howto, input_bfd, relocation, location,
594 get_data, put_data)
595 reloc_howto_type *howto;
596 bfd *input_bfd ATTRIBUTE_UNUSED;
597 bfd_vma relocation;
598 bfd_byte *location;
599 long (*get_data) ();
600 int (*put_data) ();
602 int size;
603 bfd_vma x;
604 boolean overflow;
606 /* If the size is negative, negate RELOCATION. This isn't very
607 general. */
608 if (howto->size < 0)
609 relocation = -relocation;
611 /* Get the value we are going to relocate. */
612 size = bfd_get_reloc_size (howto);
613 switch (size)
615 default:
616 case 0:
617 abort ();
618 case 1:
619 case 2:
620 case 4:
621 #ifdef BFD64
622 case 8:
623 #endif
624 x = get_data (location, 0, size);
625 break;
628 /* Check for overflow. FIXME: We may drop bits during the addition
629 which we don't check for. We must either check at every single
630 operation, which would be tedious, or we must do the computations
631 in a type larger than bfd_vma, which would be inefficient. */
632 overflow = false;
633 if (howto->complain_on_overflow != complain_overflow_dont)
635 bfd_vma check;
636 bfd_signed_vma signed_check;
637 bfd_vma add;
638 bfd_signed_vma signed_add;
640 if (howto->rightshift == 0)
642 check = relocation;
643 signed_check = (bfd_signed_vma) relocation;
645 else
647 /* Drop unwanted bits from the value we are relocating to. */
648 check = relocation >> howto->rightshift;
650 /* If this is a signed value, the rightshift just dropped
651 leading 1 bits (assuming twos complement). */
652 if ((bfd_signed_vma) relocation >= 0)
653 signed_check = check;
654 else
655 signed_check = (check
656 | ((bfd_vma) - 1
657 & ~((bfd_vma) - 1 >> howto->rightshift)));
660 /* Get the value from the object file. */
661 add = x & howto->src_mask;
663 /* Get the value from the object file with an appropriate sign.
664 The expression involving howto->src_mask isolates the upper
665 bit of src_mask. If that bit is set in the value we are
666 adding, it is negative, and we subtract out that number times
667 two. If src_mask includes the highest possible bit, then we
668 can not get the upper bit, but that does not matter since
669 signed_add needs no adjustment to become negative in that
670 case. */
671 signed_add = add;
672 if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
673 signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
675 /* Add the value from the object file, shifted so that it is a
676 straight number. */
677 if (howto->bitpos == 0)
679 check += add;
680 signed_check += signed_add;
682 else
684 check += add >> howto->bitpos;
686 /* For the signed case we use ADD, rather than SIGNED_ADD,
687 to avoid warnings from SVR4 cc. This is OK since we
688 explictly handle the sign bits. */
689 if (signed_add >= 0)
690 signed_check += add >> howto->bitpos;
691 else
692 signed_check += ((add >> howto->bitpos)
693 | ((bfd_vma) - 1
694 & ~((bfd_vma) - 1 >> howto->bitpos)));
697 switch (howto->complain_on_overflow)
699 case complain_overflow_signed:
701 /* Assumes two's complement. */
702 bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
703 bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
705 if (signed_check > reloc_signed_max
706 || signed_check < reloc_signed_min)
707 overflow = true;
709 break;
710 case complain_overflow_unsigned:
712 /* Assumes two's complement. This expression avoids
713 overflow if howto->bitsize is the number of bits in
714 bfd_vma. */
715 bfd_vma reloc_unsigned_max =
716 (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
718 if (check > reloc_unsigned_max)
719 overflow = true;
721 break;
722 case complain_overflow_bitfield:
724 /* Assumes two's complement. This expression avoids
725 overflow if howto->bitsize is the number of bits in
726 bfd_vma. */
727 bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
729 if ((check & ~reloc_bits) != 0
730 && (((bfd_vma) signed_check & ~reloc_bits)
731 != (-1 & ~reloc_bits)))
732 overflow = true;
734 break;
735 default:
736 abort ();
740 /* Put RELOCATION in the right bits. */
741 relocation >>= (bfd_vma) howto->rightshift;
742 relocation <<= (bfd_vma) howto->bitpos;
744 /* Add RELOCATION to the right bits of X. */
745 x = ((x & ~howto->dst_mask)
746 | (((x & howto->src_mask) + relocation) & howto->dst_mask));
748 /* Put the relocated value back in the object file. */
749 switch (size)
751 default:
752 case 0:
753 abort ();
754 case 1:
755 case 2:
756 case 4:
757 #ifdef BFD64
758 case 8:
759 #endif
760 put_data(x, location, 0, size);
761 break;
764 return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
767 bfd_reloc_status_type
768 _bfd_ns32k_reloc_disp (abfd, reloc_entry, symbol, data, input_section,
769 output_bfd, error_message)
770 bfd *abfd;
771 arelent *reloc_entry;
772 struct symbol_cache_entry *symbol;
773 PTR data;
774 asection *input_section;
775 bfd *output_bfd;
776 char **error_message;
778 return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
779 output_bfd, error_message,
780 _bfd_ns32k_get_displacement,
781 _bfd_ns32k_put_displacement);
784 bfd_reloc_status_type
785 _bfd_ns32k_reloc_imm (abfd, reloc_entry, symbol, data, input_section,
786 output_bfd, error_message)
787 bfd *abfd;
788 arelent *reloc_entry;
789 struct symbol_cache_entry *symbol;
790 PTR data;
791 asection *input_section;
792 bfd *output_bfd;
793 char **error_message;
795 return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
796 output_bfd, error_message, _bfd_ns32k_get_immediate,
797 _bfd_ns32k_put_immediate);
800 bfd_reloc_status_type
801 _bfd_ns32k_final_link_relocate (howto, input_bfd, input_section, contents,
802 address, value, addend)
803 reloc_howto_type *howto;
804 bfd *input_bfd;
805 asection *input_section;
806 bfd_byte *contents;
807 bfd_vma address;
808 bfd_vma value;
809 bfd_vma addend;
811 bfd_vma relocation;
813 /* Sanity check the address. */
814 if (address > input_section->_cooked_size)
815 return bfd_reloc_outofrange;
817 /* This function assumes that we are dealing with a basic relocation
818 against a symbol. We want to compute the value of the symbol to
819 relocate to. This is just VALUE, the value of the symbol, plus
820 ADDEND, any addend associated with the reloc. */
821 relocation = value + addend;
823 /* If the relocation is PC relative, we want to set RELOCATION to
824 the distance between the symbol (currently in RELOCATION) and the
825 location we are relocating. Some targets (e.g., i386-aout)
826 arrange for the contents of the section to be the negative of the
827 offset of the location within the section; for such targets
828 pcrel_offset is false. Other targets (e.g., m88kbcs or ELF)
829 simply leave the contents of the section as zero; for such
830 targets pcrel_offset is true. If pcrel_offset is false we do not
831 need to subtract out the offset of the location within the
832 section (which is just ADDRESS). */
833 if (howto->pc_relative)
835 relocation -= (input_section->output_section->vma
836 + input_section->output_offset);
837 if (howto->pcrel_offset)
838 relocation -= address;
841 return _bfd_ns32k_relocate_contents (howto, input_bfd, relocation,
842 contents + address);