Update copyright notices
[platform/upstream/binutils.git] / bfd / cpu-ns32k.c
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.
6
7 This file is part of BFD, the Binary File Descriptor library.
8
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.
13
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.
18
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.  */
22
23 #include "bfd.h"
24 #include "sysdep.h"
25 #include "libbfd.h"
26 #include "ns32k.h"
27
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, }
30
31 static const bfd_arch_info_type arch_info_struct[] =
32 {
33   N(32532,"ns32k:32532",true, 0), /* the word ns32k will match this too */
34 };
35
36 const bfd_arch_info_type bfd_ns32k_arch =
37   N(32032,"ns32k:32032",false, &arch_info_struct[0]);
38
39 static long
40 ns32k_sign_extend(value, bits)
41      int value;
42      int bits;
43 {
44   value = value & ((1 << bits) - 1);
45   return (value & (1 << (bits-1))
46           ? value | (~((1 << bits) - 1))
47           : value);
48 }
49
50 long
51 _bfd_ns32k_get_displacement(buffer, offset, size)
52      bfd_byte *buffer;
53      long offset;
54      long size;
55 {
56   long value;
57   buffer += offset;
58   switch (size)
59     {
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;
76     }
77   return value;
78 }
79
80 int
81 _bfd_ns32k_put_displacement(value, buffer, offset, size)
82      long value;
83      bfd_byte *buffer;
84      long offset;
85      long size;
86 {
87   buffer += offset;
88   switch (size)
89     {
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;
115   }
116   return 0;
117 }
118
119 long
120 _bfd_ns32k_get_immediate (buffer, offset, size)
121      bfd_byte *buffer;
122      long offset;
123      long size;
124 {
125   long value = 0;
126   buffer += offset;
127   switch (size)
128     {
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);
137     }
138   return value;
139 }
140
141 int
142 _bfd_ns32k_put_immediate (value, buffer, offset, size)
143      long value;
144      bfd_byte *buffer;
145      long offset;
146      long size;
147 {
148   buffer += offset + size - 1;
149   switch (size)
150     {
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;
159     }
160   return 0;
161 }
162
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!
167  */
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) ();
180 {
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;
188
189   if ((symbol->section == &bfd_abs_section)
190       && output_bfd != (bfd *) NULL)
191     {
192       reloc_entry->address += input_section->output_offset;
193       return bfd_reloc_ok;
194     }
195
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;
203
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;
207
208   /* Work out which section the relocation is targetted at and the
209      initial relocation command value.  */
210
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;
216
217   reloc_target_output_section = symbol->section->output_section;
218
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;
224
225   relocation += output_base + symbol->section->output_offset;
226
227   /* Add in supplied addend.  */
228   relocation += reloc_entry->addend;
229
230   /* Here the variable relocation holds the final address of the
231      symbol we are relocating against, plus any addend.  */
232
233   if (howto->pc_relative == true)
234     {
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.
238
239          We start by subtracting the address of the section containing
240          the location.
241
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.
249
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.
257
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.  */
262
263       relocation -=
264         input_section->output_section->vma + input_section->output_offset;
265
266       if (howto->pcrel_offset == true)
267         relocation -= reloc_entry->address;
268     }
269
270   if (output_bfd != (bfd *) NULL)
271     {
272       if (howto->partial_inplace == false)
273         {
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;
280         }
281       else
282         {
283           /* This is a partial relocation, but inplace, so modify the
284              reloc record a bit.
285
286              If we've relocated with a symbol with a section, change
287              into a ref to the section belonging to the symbol.  */
288
289           reloc_entry->address += input_section->output_offset;
290
291           /* WTF?? */
292           if (abfd->xvec->flavour == bfd_target_coff_flavour)
293             {
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.
298
299 However, Ian wrote the following, regarding removing the line below,
300 which explains why it is still enabled:  --djm
301
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.
307
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.
314
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.
319
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).
326
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).
336
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.
345
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
363 */
364               relocation -= reloc_entry->addend;
365 #endif
366               reloc_entry->addend = 0;
367             }
368           else
369             {
370               reloc_entry->addend = relocation;
371             }
372         }
373     }
374   else
375     {
376       reloc_entry->addend = 0;
377     }
378
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)
387     {
388       bfd_vma check;
389
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)
397         {
398         case complain_overflow_signed:
399           {
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;
403
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;
414           }
415           break;
416         case complain_overflow_unsigned:
417           {
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;
423
424             if ((bfd_vma) check > reloc_unsigned_max)
425               flag = bfd_reloc_overflow;
426           }
427           break;
428         case complain_overflow_bitfield:
429           {
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;
434
435             if (((bfd_vma) check & ~reloc_bits) != 0
436                 && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
437               {
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)
443                   {
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;
449                   }
450                 else
451                   flag = bfd_reloc_overflow;
452               }
453           }
454           break;
455         default:
456           abort ();
457         }
458     }
459
460   /*
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)
464     */
465
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:
469
470      struct str
471      {
472        unsigned int i0;
473      } s = { 0 };
474
475      int
476      main ()
477      {
478        unsigned long x;
479
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);
486      }
487      */
488
489   relocation >>= (bfd_vma) howto->rightshift;
490
491   /* Shift everything up to where it's going to be used */
492
493   relocation <<= (bfd_vma) howto->bitpos;
494
495   /* Wait for the day when all have the mask in them */
496
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
507
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
520
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>
526      */
527
528 #define DOIT(x) \
529   x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) +  relocation) & howto->dst_mask))
530
531   switch (howto->size)
532     {
533     case 0:
534       {
535         char x = get_data (data, addr, 1);
536         DOIT (x);
537         overflow = put_data(x, data, addr, 1);
538       }
539       break;
540
541     case 1:
542       if (relocation)
543         {
544           short x = get_data (data, addr, 2);
545           DOIT (x);
546           overflow = put_data(x, (unsigned char *) data, addr, 2);
547         }
548       break;
549     case 2:
550       if (relocation)
551         {
552           long x = get_data (data, addr, 4);
553           DOIT (x);
554           overflow = put_data(x, data, addr, 4);
555         }
556       break;
557     case -2:
558       {
559         long  x = get_data(data, addr, 4);
560         relocation = -relocation;
561         DOIT(x);
562         overflow = put_data(x, data , addr, 4);
563       }
564       break;
565
566     case 3:
567       /* Do nothing */
568       break;
569
570     case 4:
571 #ifdef BFD64
572       if (relocation)
573         {
574           bfd_vma x = get_data (data, addr, 8);
575           DOIT (x);
576           overflow = put_data(x, data, addr, 8);
577         }
578 #else
579       abort ();
580 #endif
581       break;
582     default:
583       return bfd_reloc_other;
584     }
585   if ((howto->complain_on_overflow != complain_overflow_dont) && overflow)
586     return bfd_reloc_overflow;
587
588   return flag;
589 }
590
591 /* Relocate a given location using a given value and howto.  */
592
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) ();
602 {
603   int size;
604   bfd_vma x;
605   boolean overflow;
606
607   /* If the size is negative, negate RELOCATION.  This isn't very
608      general.  */
609   if (howto->size < 0)
610     relocation = -relocation;
611
612   /* Get the value we are going to relocate.  */
613   size = bfd_get_reloc_size (howto);
614   switch (size)
615     {
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;
627     }
628
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)
635     {
636       bfd_vma check;
637       bfd_signed_vma signed_check;
638       bfd_vma add;
639       bfd_signed_vma signed_add;
640
641       if (howto->rightshift == 0)
642         {
643           check = relocation;
644           signed_check = (bfd_signed_vma) relocation;
645         }
646       else
647         {
648           /* Drop unwanted bits from the value we are relocating to.  */
649           check = relocation >> howto->rightshift;
650
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)));
659         }
660
661       /* Get the value from the object file.  */
662       add = x & howto->src_mask;
663
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;
675
676       /* Add the value from the object file, shifted so that it is a
677          straight number.  */
678       if (howto->bitpos == 0)
679         {
680           check += add;
681           signed_check += signed_add;
682         }
683       else
684         {
685           check += add >> howto->bitpos;
686
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)));
696         }
697
698       switch (howto->complain_on_overflow)
699         {
700         case complain_overflow_signed:
701           {
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;
705
706             if (signed_check > reloc_signed_max
707                 || signed_check < reloc_signed_min)
708               overflow = true;
709           }
710           break;
711         case complain_overflow_unsigned:
712           {
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;
718
719             if (check > reloc_unsigned_max)
720               overflow = true;
721           }
722           break;
723         case complain_overflow_bitfield:
724           {
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;
729
730             if ((check & ~reloc_bits) != 0
731                 && (((bfd_vma) signed_check & ~reloc_bits)
732                     != (-1 & ~reloc_bits)))
733               overflow = true;
734           }
735           break;
736         default:
737           abort ();
738         }
739     }
740
741   /* Put RELOCATION in the right bits.  */
742   relocation >>= (bfd_vma) howto->rightshift;
743   relocation <<= (bfd_vma) howto->bitpos;
744
745   /* Add RELOCATION to the right bits of X.  */
746   x = ((x & ~howto->dst_mask)
747        | (((x & howto->src_mask) + relocation) & howto->dst_mask));
748
749   /* Put the relocated value back in the object file.  */
750   switch (size)
751     {
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;
763     }
764
765   return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
766 }
767
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;
778 {
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);
783 }
784
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;
795 {
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);
799 }
800
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;
811 {
812   bfd_vma relocation;
813
814   /* Sanity check the address.  */
815   if (address > input_section->_cooked_size)
816     return bfd_reloc_outofrange;
817
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;
823
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)
835     {
836       relocation -= (input_section->output_section->vma
837                      + input_section->output_offset);
838       if (howto->pcrel_offset)
839         relocation -= address;
840     }
841
842   return _bfd_ns32k_relocate_contents (howto, input_bfd, relocation,
843                                        contents + address);
844 }