* ns32k.h: New file.
[external/binutils.git] / bfd / cpu-ns32k.c
1 /* BFD support for the ns32k architecture.
2    Copyright (C) 1990, 1991, 1994, 1995 Free Software Foundation, Inc.
3    Almost totally rewritten by Ian Dall from initial work
4    by Andrew Cagney.
5
6 This file is part of BFD, the Binary File Descriptor library.
7
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.
12
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.
17
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.  */
21
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "libbfd.h"
25 #include "ns32k.h"
26
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, }
29
30 static const bfd_arch_info_type arch_info_struct[] =
31
32   N(32532,"ns32k:32532",true, 0), /* the word ns32k will match this too */
33 };
34
35 const bfd_arch_info_type bfd_ns32k_arch =
36   N(32032,"ns32k:32032",false, &arch_info_struct[0]);
37
38 static long
39 ns32k_sign_extend(value, bits)
40      int value;
41      int bits;
42 {
43   value = value & ((1 << bits) - 1);
44   return (value & (1 << (bits-1))
45           ? value | (~((1 << bits) - 1))
46           : value);
47 }
48
49 long
50 _bfd_ns32k_get_displacement(buffer, offset, size)
51      bfd_byte *buffer;
52      long offset;
53      long size;
54 {
55   long value;
56   buffer += offset;
57   switch (size)
58     {
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     }
73   return value;
74 }
75
76 int
77 _bfd_ns32k_put_displacement(value, buffer, offset, size)
78      long value;
79      bfd_byte *buffer;
80      long offset;
81      long size;
82 {
83   buffer += offset;
84   switch (size)
85     {
86     case 1:
87       if (value < -64 || value > 63)
88         return -1;
89       value&=0x7f;
90       *buffer++=value;
91       break;
92     case 2:
93       if (value < -8192 || value > 8191)
94         return -1;
95       value&=0x3fff;
96       value|=0x8000;
97       *buffer++=(value>>8);
98       *buffer++=value;
99       break;
100     case 4:
101       if (value < -0x1f000000 || value >= 0x20000000)
102         return -1;
103       value|=0xc0000000;
104       *buffer++=(value>>24);
105       *buffer++=(value>>16);
106       *buffer++=(value>>8);
107       *buffer++=value;
108       break;
109     default:
110       return -1;
111   }
112   return 0;
113 }
114
115 long
116 _bfd_ns32k_get_immediate (buffer, offset, size)
117      bfd_byte *buffer;
118      long offset;
119      long size;
120 {
121   long value = 0;
122   buffer += offset;
123   switch (size)
124     {
125     case 4:
126       value = (value << 8) | (*buffer++ & 0xff);
127     case 3:
128       value = (value << 8) | (*buffer++ & 0xff);
129     case 2:
130       value = (value << 8) | (*buffer++ & 0xff);
131     case 1:
132       value = (value << 8) | (*buffer++ & 0xff);
133     }
134   return value;
135 }
136
137 int
138 _bfd_ns32k_put_immediate (value, buffer, offset, size)
139      long value;
140      bfd_byte *buffer;
141      long offset;
142      long size;
143 {
144   buffer += offset + size - 1;
145   switch (size)
146     {
147     case 4:
148       *buffer-- = (value & 0xff); value >>= 8;
149     case 3:
150       *buffer-- = (value & 0xff); value >>= 8;
151     case 2:
152       *buffer-- = (value & 0xff); value >>= 8;
153     case 1:
154       *buffer-- = (value & 0xff); value >>= 8;
155     }
156   return 0;
157 }
158
159 /* This is just like the standard perform_relocation except we
160  * use get_data and put_data which know about the ns32k
161  * storage methods.
162  * This is probably a lot more complicated than it needs to be!
163  */
164 static bfd_reloc_status_type
165 do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
166                 error_message, get_data, put_data)
167      bfd *abfd;
168      arelent *reloc_entry;
169      struct symbol_cache_entry *symbol;
170      PTR data;
171      asection *input_section;
172      bfd *output_bfd;
173      char **error_message;
174      long (*get_data)();
175      int (*put_data)();
176 {
177   int overflow = 0;
178   bfd_vma relocation;
179   bfd_reloc_status_type flag = bfd_reloc_ok;
180   bfd_size_type addr = reloc_entry->address;
181   bfd_vma output_base = 0;
182   reloc_howto_type *howto = reloc_entry->howto;
183   asection *reloc_target_output_section;
184
185   if ((symbol->section == &bfd_abs_section)
186       && output_bfd != (bfd *) NULL)
187     {
188       reloc_entry->address += input_section->output_offset;
189       return bfd_reloc_ok;
190     }
191
192   /* If we are not producing relocateable output, return an error if
193      the symbol is not defined.  An undefined weak symbol is
194      considered to have a value of zero (SVR4 ABI, p. 4-27).  */
195   if (symbol->section == &bfd_und_section
196       && (symbol->flags & BSF_WEAK) == 0
197       && output_bfd == (bfd *) NULL)
198     flag = bfd_reloc_undefined;
199
200
201   /* Is the address of the relocation really within the section?  */
202   if (reloc_entry->address > input_section->_cooked_size)
203     return bfd_reloc_outofrange;
204
205   /* Work out which section the relocation is targetted at and the
206      initial relocation command value.  */
207
208   /* Get symbol value.  (Common symbols are special.)  */
209   if (bfd_is_com_section (symbol->section))
210     relocation = 0;
211   else
212     relocation = symbol->value;
213
214
215   reloc_target_output_section = symbol->section->output_section;
216
217   /* Convert input-section-relative symbol value to absolute.  */
218   if (output_bfd && howto->partial_inplace == false)
219     output_base = 0;
220   else
221     output_base = reloc_target_output_section->vma;
222
223   relocation += output_base + symbol->section->output_offset;
224
225   /* Add in supplied addend.  */
226   relocation += reloc_entry->addend;
227
228   /* Here the variable relocation holds the final address of the
229      symbol we are relocating against, plus any addend.  */
230
231   if (howto->pc_relative == true)
232     {
233       /* This is a PC relative relocation.  We want to set RELOCATION
234          to the distance between the address of the symbol and the
235          location.  RELOCATION is already the address of the symbol.
236
237          We start by subtracting the address of the section containing
238          the location.
239
240          If pcrel_offset is set, we must further subtract the position
241          of the location within the section.  Some targets arrange for
242          the addend to be the negative of the position of the location
243          within the section; for example, i386-aout does this.  For
244          i386-aout, pcrel_offset is false.  Some other targets do not
245          include the position of the location; for example, m88kbcs,
246          or ELF.  For those targets, pcrel_offset is true.
247
248          If we are producing relocateable output, then we must ensure
249          that this reloc will be correctly computed when the final
250          relocation is done.  If pcrel_offset is false we want to wind
251          up with the negative of the location within the section,
252          which means we must adjust the existing addend by the change
253          in the location within the section.  If pcrel_offset is true
254          we do not want to adjust the existing addend at all.
255
256          FIXME: This seems logical to me, but for the case of
257          producing relocateable output it is not what the code
258          actually does.  I don't want to change it, because it seems
259          far too likely that something will break.  */
260
261       relocation -=
262         input_section->output_section->vma + input_section->output_offset;
263
264       if (howto->pcrel_offset == true)
265         relocation -= reloc_entry->address;
266     }
267
268   if (output_bfd != (bfd *) NULL)
269     {
270       if (howto->partial_inplace == false)
271         {
272           /* This is a partial relocation, and we want to apply the relocation
273              to the reloc entry rather than the raw data. Modify the reloc
274              inplace to reflect what we now know.  */
275           reloc_entry->addend = relocation;
276           reloc_entry->address += input_section->output_offset;
277           return flag;
278         }
279       else
280         {
281           /* This is a partial relocation, but inplace, so modify the
282              reloc record a bit.
283
284              If we've relocated with a symbol with a section, change
285              into a ref to the section belonging to the symbol.  */
286
287           reloc_entry->address += input_section->output_offset;
288
289           /* WTF?? */
290           if (abfd->xvec->flavour == bfd_target_coff_flavour
291               && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0)
292             {
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.
297
298 However, Ian wrote the following, regarding removing the line below,
299 which explains why it is still enabled:  --djm
300
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.
306
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.
313
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.
318
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).
325
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).
335
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.
344
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
362 */
363               relocation -= reloc_entry->addend;
364 #endif
365               reloc_entry->addend = 0;
366             }
367           else
368             {
369               reloc_entry->addend = relocation;
370             }
371         }
372     }
373   else
374     {
375       reloc_entry->addend = 0;
376     }
377
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)
386     {
387       bfd_vma check;
388
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)
396         {
397         case complain_overflow_signed:
398           {
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;
402
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;
413           }
414           break;
415         case complain_overflow_unsigned:
416           {
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;
422
423             if ((bfd_vma) check > reloc_unsigned_max)
424               flag = bfd_reloc_overflow;
425           }
426           break;
427         case complain_overflow_bitfield:
428           {
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;
433
434             if (((bfd_vma) check & ~reloc_bits) != 0
435                 && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
436               {
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)
442                   {
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;
448                   }
449                 else
450                   flag = bfd_reloc_overflow;
451               }
452           }
453           break;
454         default:
455           abort ();
456         }
457     }
458
459   /*
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)
463     */
464
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:
468
469      struct str
470      {
471        unsigned int i0;
472      } s = { 0 };
473
474      int
475      main ()
476      {
477        unsigned long x;
478
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);
485      }
486      */
487
488   relocation >>= (bfd_vma) howto->rightshift;
489
490   /* Shift everything up to where it's going to be used */
491
492   relocation <<= (bfd_vma) howto->bitpos;
493
494   /* Wait for the day when all have the mask in them */
495
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
506
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
519
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>
525      */
526
527 #define DOIT(x) \
528   x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) +  relocation) & howto->dst_mask))
529
530   switch (howto->size)
531     {
532     case 0:
533       {
534         char x = get_data (data, addr, 1);
535         DOIT (x);
536         overflow = put_data(x, data, addr, 1);
537       }
538       break;
539
540     case 1:
541       if (relocation)
542         {
543           short x = get_data (data, addr, 2);
544           DOIT (x);
545           overflow = put_data(x, (unsigned char *) data, addr, 2);
546         }
547       break;
548     case 2:
549       if (relocation)
550         {
551           long x = get_data (data, addr, 4);
552           DOIT (x);
553           overflow = put_data(x, data, addr, 4);
554         }
555       break;
556     case -2:
557       {
558         long  x = get_data(data, addr, 4);
559         relocation = -relocation;
560         DOIT(x);
561         overflow = put_data(x, data , addr, 4);
562       }
563       break;
564
565     case 3:
566       /* Do nothing */
567       break;
568
569     case 4:
570 #ifdef BFD64
571       if (relocation)
572         {
573           bfd_vma x = get_data (data, addr, 8);
574           DOIT (x);
575           overflow = put_data(x, data, addr, 8);
576         }
577 #else
578       abort ();
579 #endif
580       break;
581     default:
582       return bfd_reloc_other;
583     }
584   if ((howto->complain_on_overflow != complain_overflow_dont) && overflow)
585     return bfd_reloc_overflow;
586
587   return flag;
588 }
589
590 /* Relocate a given location using a given value and howto.  */
591
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;
597      bfd_vma relocation;
598      bfd_byte *location;
599      long (*get_data)();
600      int (*put_data)();
601 {
602   int size;
603   bfd_vma x;
604   boolean overflow;
605
606   /* If the size is negative, negate RELOCATION.  This isn't very
607      general.  */
608   if (howto->size < 0)
609     relocation = -relocation;
610
611   /* Get the value we are going to relocate.  */
612   size = bfd_get_reloc_size (howto);
613   switch (size)
614     {
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;
626     }
627
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)
634     {
635       bfd_vma check;
636       bfd_signed_vma signed_check;
637       bfd_vma add;
638       bfd_signed_vma signed_add;
639
640       if (howto->rightshift == 0)
641         {
642           check = relocation;
643           signed_check = (bfd_signed_vma) relocation;
644         }
645       else
646         {
647           /* Drop unwanted bits from the value we are relocating to.  */
648           check = relocation >> howto->rightshift;
649
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)));
658         }
659
660       /* Get the value from the object file.  */
661       add = x & howto->src_mask;
662
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;
674
675       /* Add the value from the object file, shifted so that it is a
676          straight number.  */
677       if (howto->bitpos == 0)
678         {
679           check += add;
680           signed_check += signed_add;
681         }
682       else
683         {
684           check += add >> howto->bitpos;
685
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)));
695         }
696
697       switch (howto->complain_on_overflow)
698         {
699         case complain_overflow_signed:
700           {
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;
704
705             if (signed_check > reloc_signed_max
706                 || signed_check < reloc_signed_min)
707               overflow = true;
708           }
709           break;
710         case complain_overflow_unsigned:
711           {
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;
717
718             if (check > reloc_unsigned_max)
719               overflow = true;
720           }
721           break;
722         case complain_overflow_bitfield:
723           {
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;
728
729             if ((check & ~reloc_bits) != 0
730                 && (((bfd_vma) signed_check & ~reloc_bits)
731                     != (-1 & ~reloc_bits)))
732               overflow = true;
733           }
734           break;
735         default:
736           abort ();
737         }
738     }
739
740   /* Put RELOCATION in the right bits.  */
741   relocation >>= (bfd_vma) howto->rightshift;
742   relocation <<= (bfd_vma) howto->bitpos;
743
744   /* Add RELOCATION to the right bits of X.  */
745   x = ((x & ~howto->dst_mask)
746        | (((x & howto->src_mask) + relocation) & howto->dst_mask));
747
748   /* Put the relocated value back in the object file.  */
749   switch (size)
750     {
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;
762     }
763
764   return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
765 }
766
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;
777 {
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);
782 }
783
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;
794 {
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);
798 }
799
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;
810 {
811   bfd_vma relocation;
812
813   /* Sanity check the address.  */
814   if (address > input_section->_cooked_size)
815     return bfd_reloc_outofrange;
816
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;
822
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)
834     {
835       relocation -= (input_section->output_section->vma
836                      + input_section->output_offset);
837       if (howto->pcrel_offset)
838         relocation -= address;
839     }
840
841   return _bfd_ns32k_relocate_contents (howto, input_bfd, relocation,
842                                        contents + address);
843 }