OSDN Git Service

bfd/
[pf3gnuchains/pf3gnuchains3x.git] / bfd / cpu-ns32k.c
1 /* BFD support for the ns32k architecture.
2    Copyright 1990, 1991, 1994, 1995, 1998, 2000, 2001, 2002, 2003, 2004
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 bfd_reloc_status_type do_ns32k_reloc
40   PARAMS ((bfd *, arelent *, struct bfd_symbol *, PTR, asection *,
41            bfd *, char **,
42            bfd_vma (*) (bfd_byte *, int),
43            void (*) (bfd_vma, bfd_byte *, int)));
44
45 bfd_vma
46 _bfd_ns32k_get_displacement (buffer, size)
47      bfd_byte *buffer;
48      int size;
49 {
50   bfd_signed_vma value;
51
52   switch (size)
53     {
54     case 1:
55       value = ((*buffer & 0x7f) ^ 0x40) - 0x40;
56       break;
57
58     case 2:
59       value = ((*buffer++ & 0x3f) ^ 0x20) - 0x20;
60       value = (value << 8) | (0xff & *buffer);
61       break;
62
63     case 4:
64       value = ((*buffer++ & 0x3f) ^ 0x20) - 0x20;
65       value = (value << 8) | (0xff & *buffer++);
66       value = (value << 8) | (0xff & *buffer++);
67       value = (value << 8) | (0xff & *buffer);
68       break;
69
70     default:
71       abort ();
72       return 0;
73     }
74
75   return value;
76 }
77
78 void
79 _bfd_ns32k_put_displacement (value, buffer, size)
80      bfd_vma value;
81      bfd_byte *buffer;
82      int size;
83 {
84   switch (size)
85     {
86     case 1:
87       value &= 0x7f;
88       *buffer++ = value;
89       break;
90
91     case 2:
92       value &= 0x3fff;
93       value |= 0x8000;
94       *buffer++ = (value >> 8);
95       *buffer++ = value;
96       break;
97
98     case 4:
99       value |= (bfd_vma) 0xc0000000;
100       *buffer++ = (value >> 24);
101       *buffer++ = (value >> 16);
102       *buffer++ = (value >> 8);
103       *buffer++ = value;
104       break;
105   }
106   return;
107 }
108
109 bfd_vma
110 _bfd_ns32k_get_immediate (buffer, size)
111      bfd_byte *buffer;
112      int size;
113 {
114   bfd_vma value = 0;
115
116   switch (size)
117     {
118     case 4:
119       value = (value << 8) | (*buffer++ & 0xff);
120       value = (value << 8) | (*buffer++ & 0xff);
121     case 2:
122       value = (value << 8) | (*buffer++ & 0xff);
123     case 1:
124       value = (value << 8) | (*buffer++ & 0xff);
125       break;
126     default:
127       abort ();
128     }
129   return value;
130 }
131
132 void
133 _bfd_ns32k_put_immediate (value, buffer, size)
134      bfd_vma value;
135      bfd_byte *buffer;
136      int size;
137 {
138   buffer += size - 1;
139   switch (size)
140     {
141     case 4:
142       *buffer-- = (value & 0xff); value >>= 8;
143       *buffer-- = (value & 0xff); value >>= 8;
144     case 2:
145       *buffer-- = (value & 0xff); value >>= 8;
146     case 1:
147       *buffer-- = (value & 0xff); value >>= 8;
148     }
149 }
150
151 /* This is just like the standard perform_relocation except we
152    use get_data and put_data which know about the ns32k storage
153    methods.  This is probably a lot more complicated than it
154    needs to be!  */
155
156 static bfd_reloc_status_type
157 do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
158                 error_message, get_data, put_data)
159      bfd *abfd;
160      arelent *reloc_entry;
161      struct bfd_symbol *symbol;
162      PTR data;
163      asection *input_section;
164      bfd *output_bfd;
165      char **error_message ATTRIBUTE_UNUSED;
166      bfd_vma (*get_data) PARAMS ((bfd_byte *, int));
167      void (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
168 {
169   int overflow = 0;
170   bfd_vma relocation;
171   bfd_reloc_status_type flag = bfd_reloc_ok;
172   bfd_size_type addr = reloc_entry->address;
173   bfd_size_type sz;
174   bfd_vma output_base = 0;
175   reloc_howto_type *howto = reloc_entry->howto;
176   asection *reloc_target_output_section;
177   bfd_byte *location;
178
179   if ((symbol->section == &bfd_abs_section)
180       && output_bfd != (bfd *) NULL)
181     {
182       reloc_entry->address += input_section->output_offset;
183       return bfd_reloc_ok;
184     }
185
186   /* If we are not producing relocatable output, return an error if
187      the symbol is not defined.  An undefined weak symbol is
188      considered to have a value of zero (SVR4 ABI, p. 4-27).  */
189   if (symbol->section == &bfd_und_section
190       && (symbol->flags & BSF_WEAK) == 0
191       && output_bfd == (bfd *) NULL)
192     flag = bfd_reloc_undefined;
193
194   /* Is the address of the relocation really within the section?  */
195   sz = input_section->rawsize ? input_section->rawsize : input_section->size;
196   if (reloc_entry->address > sz)
197     return bfd_reloc_outofrange;
198
199   /* Work out which section the relocation is targeted at and the
200      initial relocation command value.  */
201
202   /* Get symbol value.  (Common symbols are special.)  */
203   if (bfd_is_com_section (symbol->section))
204     relocation = 0;
205   else
206     relocation = symbol->value;
207
208   reloc_target_output_section = symbol->section->output_section;
209
210   /* Convert input-section-relative symbol value to absolute.  */
211   if (output_bfd != NULL && ! howto->partial_inplace)
212     output_base = 0;
213   else
214     output_base = reloc_target_output_section->vma;
215
216   relocation += output_base + symbol->section->output_offset;
217
218   /* Add in supplied addend.  */
219   relocation += reloc_entry->addend;
220
221   /* Here the variable relocation holds the final address of the
222      symbol we are relocating against, plus any addend.  */
223
224   if (howto->pc_relative)
225     {
226       /* This is a PC relative relocation.  We want to set RELOCATION
227          to the distance between the address of the symbol and the
228          location.  RELOCATION is already the address of the symbol.
229
230          We start by subtracting the address of the section containing
231          the location.
232
233          If pcrel_offset is set, we must further subtract the position
234          of the location within the section.  Some targets arrange for
235          the addend to be the negative of the position of the location
236          within the section; for example, i386-aout does this.  For
237          i386-aout, pcrel_offset is FALSE.  Some other targets do not
238          include the position of the location; for example, m88kbcs,
239          or ELF.  For those targets, pcrel_offset is TRUE.
240
241          If we are producing relocatable output, then we must ensure
242          that this reloc will be correctly computed when the final
243          relocation is done.  If pcrel_offset is FALSE we want to wind
244          up with the negative of the location within the section,
245          which means we must adjust the existing addend by the change
246          in the location within the section.  If pcrel_offset is TRUE
247          we do not want to adjust the existing addend at all.
248
249          FIXME: This seems logical to me, but for the case of
250          producing relocatable output it is not what the code
251          actually does.  I don't want to change it, because it seems
252          far too likely that something will break.  */
253       relocation -=
254         input_section->output_section->vma + input_section->output_offset;
255
256       if (howto->pcrel_offset)
257         relocation -= reloc_entry->address;
258     }
259
260   if (output_bfd != (bfd *) NULL)
261     {
262       if (! howto->partial_inplace)
263         {
264           /* This is a partial relocation, and we want to apply the relocation
265              to the reloc entry rather than the raw data. Modify the reloc
266              inplace to reflect what we now know.  */
267           reloc_entry->addend = relocation;
268           reloc_entry->address += input_section->output_offset;
269           return flag;
270         }
271       else
272         {
273           /* This is a partial relocation, but inplace, so modify the
274              reloc record a bit.
275
276              If we've relocated with a symbol with a section, change
277              into a ref to the section belonging to the symbol.  */
278
279           reloc_entry->address += input_section->output_offset;
280
281           /* WTF?? */
282           if (abfd->xvec->flavour == bfd_target_coff_flavour)
283             {
284 #if 1
285               /* For m68k-coff, the addend was being subtracted twice during
286                  relocation with -r.  Removing the line below this comment
287                  fixes that problem; see PR 2953.
288
289                  However, Ian wrote the following, regarding removing the line
290                  below, which explains why it is still enabled:  --djm
291
292                  If you put a patch like that into BFD you need to check all
293                  the COFF linkers.  I am fairly certain that patch will break
294                  coff-i386 (e.g., SCO); see coff_i386_reloc in coff-i386.c
295                  where I worked around the problem in a different way.  There
296                  may very well be a reason that the code works as it does.
297
298                  Hmmm.  The first obvious point is that bfd_perform_relocation
299                  should not have any tests that depend upon the flavour.  It's
300                  seem like entirely the wrong place for such a thing.  The
301                  second obvious point is that the current code ignores the
302                  reloc addend when producing relocatable output for COFF.
303                  That's peculiar.  In fact, I really have no idea what the
304                  point of the line you want to remove is.
305
306                  A typical COFF reloc subtracts the old value of the symbol
307                  and adds in the new value to the location in the object file
308                  (if it's a pc relative reloc it adds the difference between
309                  the symbol value and the location).  When relocating we need
310                  to preserve that property.
311
312                  BFD handles this by setting the addend to the negative of the
313                  old value of the symbol.  Unfortunately it handles common
314                  symbols in a non-standard way (it doesn't subtract the old
315                  value) but that's a different story (we can't change it
316                  without losing backward compatibility with old object files)
317                  (coff-i386 does subtract the old value, to be compatible with
318                  existing coff-i386 targets, like SCO).
319
320                  So everything works fine when not producing relocatable
321                  output.  When we are producing relocatable output, logically
322                  we should do exactly what we do when not producing
323                  relocatable output.  Therefore, your patch is correct.  In
324                  fact, it should probably always just set reloc_entry->addend
325                  to 0 for all cases, since it is, in fact, going to add the
326                  value into the object file.  This won't hurt the COFF code,
327                  which doesn't use the addend; I'm not sure what it will do
328                  to other formats (the thing to check for would be whether
329                  any formats both use the addend and set partial_inplace).
330
331                  When I wanted to make coff-i386 produce relocatable output,
332                  I ran into the problem that you are running into: I wanted
333                  to remove that line.  Rather than risk it, I made the
334                  coff-i386 relocs use a special function; it's coff_i386_reloc
335                  in coff-i386.c.  The function specifically adds the addend
336                  field into the object file, knowing that bfd_perform_relocation
337                  is not going to.  If you remove that line, then coff-i386.c
338                  will wind up adding the addend field in twice.  It's trivial
339                  to fix; it just needs to be done.
340
341                  The problem with removing the line is just that it may break
342                  some working code.  With BFD it's hard to be sure of anything.
343                  The right way to deal with this is simply to build and test at
344                  least all the supported COFF targets.  It should be
345                  straightforward if time and disk space consuming.  For each
346                  target:
347                    1) build the linker
348                    2) generate some executable, and link it using -r (I would
349                       probably use paranoia.o and link against newlib/libc.a,
350                       which for all the supported targets would be available in
351                       /usr/cygnus/progressive/H-host/target/lib/libc.a).
352                    3) make the change to reloc.c
353                    4) rebuild the linker
354                    5) repeat step 2
355                    6) if the resulting object files are the same, you have at
356                       least made it no worse
357                    7) if they are different you have to figure out which
358                       version is right.  */
359               relocation -= reloc_entry->addend;
360 #endif
361               reloc_entry->addend = 0;
362             }
363           else
364             {
365               reloc_entry->addend = relocation;
366             }
367         }
368     }
369   else
370     {
371       reloc_entry->addend = 0;
372     }
373
374   /* FIXME: This overflow checking is incomplete, because the value
375      might have overflowed before we get here.  For a correct check we
376      need to compute the value in a size larger than bitsize, but we
377      can't reasonably do that for a reloc the same size as a host
378      machine word.
379      FIXME: We should also do overflow checking on the result after
380      adding in the value contained in the object file.  */
381   if (howto->complain_on_overflow != complain_overflow_dont)
382     {
383       bfd_vma check;
384
385       /* Get the value that will be used for the relocation, but
386          starting at bit position zero.  */
387       if (howto->rightshift > howto->bitpos)
388         check = relocation >> (howto->rightshift - howto->bitpos);
389       else
390         check = relocation << (howto->bitpos - howto->rightshift);
391       switch (howto->complain_on_overflow)
392         {
393         case complain_overflow_signed:
394           {
395             /* Assumes two's complement.  */
396             bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
397             bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
398
399             /* The above right shift is incorrect for a signed value.
400                Fix it up by forcing on the upper bits.  */
401             if (howto->rightshift > howto->bitpos
402                 && (bfd_signed_vma) relocation < 0)
403               check |= ((bfd_vma) - 1
404                         & ~((bfd_vma) - 1
405                             >> (howto->rightshift - howto->bitpos)));
406             if ((bfd_signed_vma) check > reloc_signed_max
407                 || (bfd_signed_vma) check < reloc_signed_min)
408               flag = bfd_reloc_overflow;
409           }
410           break;
411         case complain_overflow_unsigned:
412           {
413             /* Assumes two's complement.  This expression avoids
414                overflow if howto->bitsize is the number of bits in
415                bfd_vma.  */
416             bfd_vma reloc_unsigned_max =
417             (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
418
419             if ((bfd_vma) check > reloc_unsigned_max)
420               flag = bfd_reloc_overflow;
421           }
422           break;
423         case complain_overflow_bitfield:
424           {
425             /* Assumes two's complement.  This expression avoids
426                overflow if howto->bitsize is the number of bits in
427                bfd_vma.  */
428             bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
429
430             if (((bfd_vma) check & ~reloc_bits) != 0
431                 && (((bfd_vma) check & ~reloc_bits)
432                     != (-(bfd_vma) 1 & ~reloc_bits)))
433               {
434                 /* The above right shift is incorrect for a signed
435                    value.  See if turning on the upper bits fixes the
436                    overflow.  */
437                 if (howto->rightshift > howto->bitpos
438                     && (bfd_signed_vma) relocation < 0)
439                   {
440                     check |= ((bfd_vma) - 1
441                               & ~((bfd_vma) - 1
442                                   >> (howto->rightshift - howto->bitpos)));
443                     if (((bfd_vma) check & ~reloc_bits)
444                         != (-(bfd_vma) 1 & ~reloc_bits))
445                       flag = bfd_reloc_overflow;
446                   }
447                 else
448                   flag = bfd_reloc_overflow;
449               }
450           }
451           break;
452         default:
453           abort ();
454         }
455     }
456
457   /* Either we are relocating all the way, or we don't want to apply
458      the relocation to the reloc entry (probably because there isn't
459      any room in the output format to describe addends to relocs).  */
460
461   /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler
462      (OSF version 1.3, compiler version 3.11).  It miscompiles the
463      following program:
464
465      struct str
466      {
467        unsigned int i0;
468      } s = { 0 };
469
470      int
471      main ()
472      {
473        unsigned long x;
474
475        x = 0x100000000;
476        x <<= (unsigned long) s.i0;
477        if (x == 0)
478          printf ("failed\n");
479        else
480          printf ("succeeded (%lx)\n", x);
481      }
482      */
483
484   relocation >>= (bfd_vma) howto->rightshift;
485
486   /* Shift everything up to where it's going to be used.  */
487   relocation <<= (bfd_vma) howto->bitpos;
488
489   /* Wait for the day when all have the mask in them.  */
490
491   /* What we do:
492      i instruction to be left alone
493      o offset within instruction
494      r relocation offset to apply
495      S src mask
496      D dst mask
497      N ~dst mask
498      A part 1
499      B part 2
500      R result
501
502      Do this:
503      i i i i i o o o o o        from bfd_get<size>
504      and           S S S S S    to get the size offset we want
505      +   r r r r r r r r r r  to get the final value to place
506      and           D D D D D  to chop to right size
507      -----------------------
508      A A A A A
509      And this:
510      ...   i i i i i o o o o o  from bfd_get<size>
511      and   N N N N N            get instruction
512      -----------------------
513      ...   B B B B B
514
515      And then:
516      B B B B B
517      or              A A A A A
518      -----------------------
519      R R R R R R R R R R        put into bfd_put<size>.  */
520
521 #define DOIT(x) \
522   x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) +  relocation) & howto->dst_mask))
523
524   location = (bfd_byte *) data + addr;
525   switch (howto->size)
526     {
527     case 0:
528       {
529         bfd_vma x = get_data (location, 1);
530         DOIT (x);
531         put_data ((bfd_vma) x, location, 1);
532       }
533       break;
534
535     case 1:
536       if (relocation)
537         {
538           bfd_vma x = get_data (location, 2);
539           DOIT (x);
540           put_data ((bfd_vma) x, location, 2);
541         }
542       break;
543     case 2:
544       if (relocation)
545         {
546           bfd_vma x = get_data (location, 4);
547           DOIT (x);
548           put_data ((bfd_vma) x, location, 4);
549         }
550       break;
551     case -2:
552       {
553         bfd_vma x = get_data (location, 4);
554         relocation = -relocation;
555         DOIT(x);
556         put_data ((bfd_vma) x, location, 4);
557       }
558       break;
559
560     case 3:
561       /* Do nothing.  */
562       break;
563
564     case 4:
565 #ifdef BFD64
566       if (relocation)
567         {
568           bfd_vma x = get_data (location, 8);
569           DOIT (x);
570           put_data (x, location, 8);
571         }
572 #else
573       abort ();
574 #endif
575       break;
576     default:
577       return bfd_reloc_other;
578     }
579   if ((howto->complain_on_overflow != complain_overflow_dont) && overflow)
580     return bfd_reloc_overflow;
581
582   return flag;
583 }
584
585 /* Relocate a given location using a given value and howto.  */
586
587 bfd_reloc_status_type
588 _bfd_do_ns32k_reloc_contents (howto, input_bfd, relocation, location,
589                               get_data, put_data)
590      reloc_howto_type *howto;
591      bfd *input_bfd ATTRIBUTE_UNUSED;
592      bfd_vma relocation;
593      bfd_byte *location;
594      bfd_vma (*get_data) PARAMS ((bfd_byte *, int));
595      void (*put_data) PARAMS ((bfd_vma, bfd_byte *, int));
596 {
597   int size;
598   bfd_vma x;
599   bfd_boolean overflow;
600
601   /* If the size is negative, negate RELOCATION.  This isn't very
602      general.  */
603   if (howto->size < 0)
604     relocation = -relocation;
605
606   /* Get the value we are going to relocate.  */
607   size = bfd_get_reloc_size (howto);
608   switch (size)
609     {
610     default:
611     case 0:
612       abort ();
613     case 1:
614     case 2:
615     case 4:
616 #ifdef BFD64
617     case 8:
618 #endif
619       x = get_data (location, size);
620       break;
621     }
622
623   /* Check for overflow.  FIXME: We may drop bits during the addition
624      which we don't check for.  We must either check at every single
625      operation, which would be tedious, or we must do the computations
626      in a type larger than bfd_vma, which would be inefficient.  */
627   overflow = FALSE;
628   if (howto->complain_on_overflow != complain_overflow_dont)
629     {
630       bfd_vma check;
631       bfd_signed_vma signed_check;
632       bfd_vma add;
633       bfd_signed_vma signed_add;
634
635       if (howto->rightshift == 0)
636         {
637           check = relocation;
638           signed_check = (bfd_signed_vma) relocation;
639         }
640       else
641         {
642           /* Drop unwanted bits from the value we are relocating to.  */
643           check = relocation >> howto->rightshift;
644
645           /* If this is a signed value, the rightshift just dropped
646              leading 1 bits (assuming twos complement).  */
647           if ((bfd_signed_vma) relocation >= 0)
648             signed_check = check;
649           else
650             signed_check = (check
651                             | ((bfd_vma) - 1
652                                & ~((bfd_vma) - 1 >> howto->rightshift)));
653         }
654
655       /* Get the value from the object file.  */
656       add = x & howto->src_mask;
657
658       /* Get the value from the object file with an appropriate sign.
659          The expression involving howto->src_mask isolates the upper
660          bit of src_mask.  If that bit is set in the value we are
661          adding, it is negative, and we subtract out that number times
662          two.  If src_mask includes the highest possible bit, then we
663          can not get the upper bit, but that does not matter since
664          signed_add needs no adjustment to become negative in that
665          case.  */
666       signed_add = add;
667       if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
668         signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
669
670       /* Add the value from the object file, shifted so that it is a
671          straight number.  */
672       if (howto->bitpos == 0)
673         {
674           check += add;
675           signed_check += signed_add;
676         }
677       else
678         {
679           check += add >> howto->bitpos;
680
681           /* For the signed case we use ADD, rather than SIGNED_ADD,
682              to avoid warnings from SVR4 cc.  This is OK since we
683              explicitly handle the sign bits.  */
684           if (signed_add >= 0)
685             signed_check += add >> howto->bitpos;
686           else
687             signed_check += ((add >> howto->bitpos)
688                              | ((bfd_vma) - 1
689                                 & ~((bfd_vma) - 1 >> howto->bitpos)));
690         }
691
692       switch (howto->complain_on_overflow)
693         {
694         case complain_overflow_signed:
695           {
696             /* Assumes two's complement.  */
697             bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
698             bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
699
700             if (signed_check > reloc_signed_max
701                 || signed_check < reloc_signed_min)
702               overflow = TRUE;
703           }
704           break;
705         case complain_overflow_unsigned:
706           {
707             /* Assumes two's complement.  This expression avoids
708                overflow if howto->bitsize is the number of bits in
709                bfd_vma.  */
710             bfd_vma reloc_unsigned_max =
711             (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
712
713             if (check > reloc_unsigned_max)
714               overflow = TRUE;
715           }
716           break;
717         case complain_overflow_bitfield:
718           {
719             /* Assumes two's complement.  This expression avoids
720                overflow if howto->bitsize is the number of bits in
721                bfd_vma.  */
722             bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
723
724             if ((check & ~reloc_bits) != 0
725                 && (((bfd_vma) signed_check & ~reloc_bits)
726                     != (-(bfd_vma) 1 & ~reloc_bits)))
727               overflow = TRUE;
728           }
729           break;
730         default:
731           abort ();
732         }
733     }
734
735   /* Put RELOCATION in the right bits.  */
736   relocation >>= (bfd_vma) howto->rightshift;
737   relocation <<= (bfd_vma) howto->bitpos;
738
739   /* Add RELOCATION to the right bits of X.  */
740   x = ((x & ~howto->dst_mask)
741        | (((x & howto->src_mask) + relocation) & howto->dst_mask));
742
743   /* Put the relocated value back in the object file.  */
744   switch (size)
745     {
746     default:
747     case 0:
748       abort ();
749     case 1:
750     case 2:
751     case 4:
752 #ifdef BFD64
753     case 8:
754 #endif
755       put_data (x, location, size);
756       break;
757     }
758
759   return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
760 }
761
762 bfd_reloc_status_type
763 _bfd_ns32k_reloc_disp (abfd, reloc_entry, symbol, data, input_section,
764                        output_bfd, error_message)
765      bfd *abfd;
766      arelent *reloc_entry;
767      struct bfd_symbol *symbol;
768      PTR data;
769      asection *input_section;
770      bfd *output_bfd;
771      char **error_message;
772 {
773   return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
774                          output_bfd, error_message,
775                          _bfd_ns32k_get_displacement,
776                          _bfd_ns32k_put_displacement);
777 }
778
779 bfd_reloc_status_type
780 _bfd_ns32k_reloc_imm (abfd, reloc_entry, symbol, data, input_section,
781                       output_bfd, error_message)
782      bfd *abfd;
783      arelent *reloc_entry;
784      struct bfd_symbol *symbol;
785      PTR data;
786      asection *input_section;
787      bfd *output_bfd;
788      char **error_message;
789 {
790   return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
791                          output_bfd, error_message, _bfd_ns32k_get_immediate,
792                          _bfd_ns32k_put_immediate);
793 }
794
795 bfd_reloc_status_type
796 _bfd_ns32k_final_link_relocate (howto, input_bfd, input_section, contents,
797                                 address, value, addend)
798      reloc_howto_type *howto;
799      bfd *input_bfd;
800      asection *input_section;
801      bfd_byte *contents;
802      bfd_vma address;
803      bfd_vma value;
804      bfd_vma addend;
805 {
806   bfd_vma relocation;
807   bfd_size_type sz;
808
809   /* Sanity check the address.  */
810   sz = input_section->rawsize ? input_section->rawsize : input_section->size;
811   if (address > sz)
812     return bfd_reloc_outofrange;
813
814   /* This function assumes that we are dealing with a basic relocation
815      against a symbol.  We want to compute the value of the symbol to
816      relocate to.  This is just VALUE, the value of the symbol, plus
817      ADDEND, any addend associated with the reloc.  */
818   relocation = value + addend;
819
820   /* If the relocation is PC relative, we want to set RELOCATION to
821      the distance between the symbol (currently in RELOCATION) and the
822      location we are relocating.  Some targets (e.g., i386-aout)
823      arrange for the contents of the section to be the negative of the
824      offset of the location within the section; for such targets
825      pcrel_offset is FALSE.  Other targets (e.g., m88kbcs or ELF)
826      simply leave the contents of the section as zero; for such
827      targets pcrel_offset is TRUE.  If pcrel_offset is FALSE we do not
828      need to subtract out the offset of the location within the
829      section (which is just ADDRESS).  */
830   if (howto->pc_relative)
831     {
832       relocation -= (input_section->output_section->vma
833                      + input_section->output_offset);
834       if (howto->pcrel_offset)
835         relocation -= address;
836     }
837
838   return _bfd_ns32k_relocate_contents (howto, input_bfd, relocation,
839                                        contents + address);
840 }