OSDN Git Service

* bfd-in.h (bfd_family_coff): Define.
[pf3gnuchains/pf3gnuchains3x.git] / bfd / cpu-ns32k.c
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.
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     default:
73       abort ();
74       return 0;
75     }
76   return value;
77 }
78
79 int
80 _bfd_ns32k_put_displacement(value, buffer, offset, size)
81      long value;
82      bfd_byte *buffer;
83      long offset;
84      long size;
85 {
86   buffer += offset;
87   switch (size)
88     {
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;
114   }
115   return 0;
116 }
117
118 long
119 _bfd_ns32k_get_immediate (buffer, offset, size)
120      bfd_byte *buffer;
121      long offset;
122      long size;
123 {
124   long value = 0;
125   buffer += offset;
126   switch (size)
127     {
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);
136     }
137   return value;
138 }
139
140 int
141 _bfd_ns32k_put_immediate (value, buffer, offset, size)
142      long value;
143      bfd_byte *buffer;
144      long offset;
145      long size;
146 {
147   buffer += offset + size - 1;
148   switch (size)
149     {
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;
158     }
159   return 0;
160 }
161
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!
166  */
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)();
179 {
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;
187
188   if ((symbol->section == &bfd_abs_section)
189       && output_bfd != (bfd *) NULL)
190     {
191       reloc_entry->address += input_section->output_offset;
192       return bfd_reloc_ok;
193     }
194
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;
202
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
218   reloc_target_output_section = symbol->section->output_section;
219
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;
225
226   relocation += output_base + symbol->section->output_offset;
227
228   /* Add in supplied addend.  */
229   relocation += reloc_entry->addend;
230
231   /* Here the variable relocation holds the final address of the
232      symbol we are relocating against, plus any addend.  */
233
234   if (howto->pc_relative == true)
235     {
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.
239
240          We start by subtracting the address of the section containing
241          the location.
242
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.
250
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.
258
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.  */
263
264       relocation -=
265         input_section->output_section->vma + input_section->output_offset;
266
267       if (howto->pcrel_offset == true)
268         relocation -= reloc_entry->address;
269     }
270
271   if (output_bfd != (bfd *) NULL)
272     {
273       if (howto->partial_inplace == false)
274         {
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;
281         }
282       else
283         {
284           /* This is a partial relocation, but inplace, so modify the
285              reloc record a bit.
286
287              If we've relocated with a symbol with a section, change
288              into a ref to the section belonging to the symbol.  */
289
290           reloc_entry->address += input_section->output_offset;
291
292           /* WTF?? */
293           if (abfd->xvec->flavour == bfd_target_coff_flavour)
294             {
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.
299
300 However, Ian wrote the following, regarding removing the line below,
301 which explains why it is still enabled:  --djm
302
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.
308
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.
315
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.
320
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).
327
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).
337
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.
346
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
364 */
365               relocation -= reloc_entry->addend;
366 #endif
367               reloc_entry->addend = 0;
368             }
369           else
370             {
371               reloc_entry->addend = relocation;
372             }
373         }
374     }
375   else
376     {
377       reloc_entry->addend = 0;
378     }
379
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)
388     {
389       bfd_vma check;
390
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)
398         {
399         case complain_overflow_signed:
400           {
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;
404
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;
415           }
416           break;
417         case complain_overflow_unsigned:
418           {
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;
424
425             if ((bfd_vma) check > reloc_unsigned_max)
426               flag = bfd_reloc_overflow;
427           }
428           break;
429         case complain_overflow_bitfield:
430           {
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;
435
436             if (((bfd_vma) check & ~reloc_bits) != 0
437                 && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
438               {
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)
444                   {
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;
450                   }
451                 else
452                   flag = bfd_reloc_overflow;
453               }
454           }
455           break;
456         default:
457           abort ();
458         }
459     }
460
461   /*
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)
465     */
466
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:
470
471      struct str
472      {
473        unsigned int i0;
474      } s = { 0 };
475
476      int
477      main ()
478      {
479        unsigned long x;
480
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);
487      }
488      */
489
490   relocation >>= (bfd_vma) howto->rightshift;
491
492   /* Shift everything up to where it's going to be used */
493
494   relocation <<= (bfd_vma) howto->bitpos;
495
496   /* Wait for the day when all have the mask in them */
497
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
508
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
521
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>
527      */
528
529 #define DOIT(x) \
530   x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) +  relocation) & howto->dst_mask))
531
532   switch (howto->size)
533     {
534     case 0:
535       {
536         char x = get_data (data, addr, 1);
537         DOIT (x);
538         overflow = put_data(x, data, addr, 1);
539       }
540       break;
541
542     case 1:
543       if (relocation)
544         {
545           short x = get_data (data, addr, 2);
546           DOIT (x);
547           overflow = put_data(x, (unsigned char *) data, addr, 2);
548         }
549       break;
550     case 2:
551       if (relocation)
552         {
553           long x = get_data (data, addr, 4);
554           DOIT (x);
555           overflow = put_data(x, data, addr, 4);
556         }
557       break;
558     case -2:
559       {
560         long  x = get_data(data, addr, 4);
561         relocation = -relocation;
562         DOIT(x);
563         overflow = put_data(x, data , addr, 4);
564       }
565       break;
566
567     case 3:
568       /* Do nothing */
569       break;
570
571     case 4:
572 #ifdef BFD64
573       if (relocation)
574         {
575           bfd_vma x = get_data (data, addr, 8);
576           DOIT (x);
577           overflow = put_data(x, data, addr, 8);
578         }
579 #else
580       abort ();
581 #endif
582       break;
583     default:
584       return bfd_reloc_other;
585     }
586   if ((howto->complain_on_overflow != complain_overflow_dont) && overflow)
587     return bfd_reloc_overflow;
588
589   return flag;
590 }
591
592 /* Relocate a given location using a given value and howto.  */
593
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)();
603 {
604   int size;
605   bfd_vma x;
606   boolean overflow;
607
608   /* If the size is negative, negate RELOCATION.  This isn't very
609      general.  */
610   if (howto->size < 0)
611     relocation = -relocation;
612
613   /* Get the value we are going to relocate.  */
614   size = bfd_get_reloc_size (howto);
615   switch (size)
616     {
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;
628     }
629
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)
636     {
637       bfd_vma check;
638       bfd_signed_vma signed_check;
639       bfd_vma add;
640       bfd_signed_vma signed_add;
641
642       if (howto->rightshift == 0)
643         {
644           check = relocation;
645           signed_check = (bfd_signed_vma) relocation;
646         }
647       else
648         {
649           /* Drop unwanted bits from the value we are relocating to.  */
650           check = relocation >> howto->rightshift;
651
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)));
660         }
661
662       /* Get the value from the object file.  */
663       add = x & howto->src_mask;
664
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;
676
677       /* Add the value from the object file, shifted so that it is a
678          straight number.  */
679       if (howto->bitpos == 0)
680         {
681           check += add;
682           signed_check += signed_add;
683         }
684       else
685         {
686           check += add >> howto->bitpos;
687
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)));
697         }
698
699       switch (howto->complain_on_overflow)
700         {
701         case complain_overflow_signed:
702           {
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;
706
707             if (signed_check > reloc_signed_max
708                 || signed_check < reloc_signed_min)
709               overflow = true;
710           }
711           break;
712         case complain_overflow_unsigned:
713           {
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;
719
720             if (check > reloc_unsigned_max)
721               overflow = true;
722           }
723           break;
724         case complain_overflow_bitfield:
725           {
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;
730
731             if ((check & ~reloc_bits) != 0
732                 && (((bfd_vma) signed_check & ~reloc_bits)
733                     != (-1 & ~reloc_bits)))
734               overflow = true;
735           }
736           break;
737         default:
738           abort ();
739         }
740     }
741
742   /* Put RELOCATION in the right bits.  */
743   relocation >>= (bfd_vma) howto->rightshift;
744   relocation <<= (bfd_vma) howto->bitpos;
745
746   /* Add RELOCATION to the right bits of X.  */
747   x = ((x & ~howto->dst_mask)
748        | (((x & howto->src_mask) + relocation) & howto->dst_mask));
749
750   /* Put the relocated value back in the object file.  */
751   switch (size)
752     {
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;
764     }
765
766   return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
767 }
768
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;
779 {
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);
784 }
785
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;
796 {
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);
800 }
801
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;
812 {
813   bfd_vma relocation;
814
815   /* Sanity check the address.  */
816   if (address > input_section->_cooked_size)
817     return bfd_reloc_outofrange;
818
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;
824
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)
836     {
837       relocation -= (input_section->output_section->vma
838                      + input_section->output_offset);
839       if (howto->pcrel_offset)
840         relocation -= address;
841     }
842
843   return _bfd_ns32k_relocate_contents (howto, input_bfd, relocation,
844                                        contents + address);
845 }