19990502 sourceware import
[external/binutils.git] / bfd / cpu-ns32k.c
1 /* BFD support for the ns32k architecture.
2    Copyright (C) 1990, 91, 94, 95, 96, 1998 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;
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               && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0)
295             {
296 #if 1
297               /* For m68k-coff, the addend was being subtracted twice during
298                  relocation with -r.  Removing the line below this comment
299                  fixes that problem; see PR 2953.
300
301 However, Ian wrote the following, regarding removing the line below,
302 which explains why it is still enabled:  --djm
303
304 If you put a patch like that into BFD you need to check all the COFF
305 linkers.  I am fairly certain that patch will break coff-i386 (e.g.,
306 SCO); see coff_i386_reloc in coff-i386.c where I worked around the
307 problem in a different way.  There may very well be a reason that the
308 code works as it does.
309
310 Hmmm.  The first obvious point is that bfd_perform_relocation should
311 not have any tests that depend upon the flavour.  It's seem like
312 entirely the wrong place for such a thing.  The second obvious point
313 is that the current code ignores the reloc addend when producing
314 relocateable output for COFF.  That's peculiar.  In fact, I really
315 have no idea what the point of the line you want to remove is.
316
317 A typical COFF reloc subtracts the old value of the symbol and adds in
318 the new value to the location in the object file (if it's a pc
319 relative reloc it adds the difference between the symbol value and the
320 location).  When relocating we need to preserve that property.
321
322 BFD handles this by setting the addend to the negative of the old
323 value of the symbol.  Unfortunately it handles common symbols in a
324 non-standard way (it doesn't subtract the old value) but that's a
325 different story (we can't change it without losing backward
326 compatibility with old object files) (coff-i386 does subtract the old
327 value, to be compatible with existing coff-i386 targets, like SCO).
328
329 So everything works fine when not producing relocateable output.  When
330 we are producing relocateable output, logically we should do exactly
331 what we do when not producing relocateable output.  Therefore, your
332 patch is correct.  In fact, it should probably always just set
333 reloc_entry->addend to 0 for all cases, since it is, in fact, going to
334 add the value into the object file.  This won't hurt the COFF code,
335 which doesn't use the addend; I'm not sure what it will do to other
336 formats (the thing to check for would be whether any formats both use
337 the addend and set partial_inplace).
338
339 When I wanted to make coff-i386 produce relocateable output, I ran
340 into the problem that you are running into: I wanted to remove that
341 line.  Rather than risk it, I made the coff-i386 relocs use a special
342 function; it's coff_i386_reloc in coff-i386.c.  The function
343 specifically adds the addend field into the object file, knowing that
344 bfd_perform_relocation is not going to.  If you remove that line, then
345 coff-i386.c will wind up adding the addend field in twice.  It's
346 trivial to fix; it just needs to be done.
347
348 The problem with removing the line is just that it may break some
349 working code.  With BFD it's hard to be sure of anything.  The right
350 way to deal with this is simply to build and test at least all the
351 supported COFF targets.  It should be straightforward if time and disk
352 space consuming.  For each target:
353     1) build the linker
354     2) generate some executable, and link it using -r (I would
355        probably use paranoia.o and link against newlib/libc.a, which
356        for all the supported targets would be available in
357        /usr/cygnus/progressive/H-host/target/lib/libc.a).
358     3) make the change to reloc.c
359     4) rebuild the linker
360     5) repeat step 2
361     6) if the resulting object files are the same, you have at least
362        made it no worse
363     7) if they are different you have to figure out which version is
364        right
365 */
366               relocation -= reloc_entry->addend;
367 #endif
368               reloc_entry->addend = 0;
369             }
370           else
371             {
372               reloc_entry->addend = relocation;
373             }
374         }
375     }
376   else
377     {
378       reloc_entry->addend = 0;
379     }
380
381   /* FIXME: This overflow checking is incomplete, because the value
382      might have overflowed before we get here.  For a correct check we
383      need to compute the value in a size larger than bitsize, but we
384      can't reasonably do that for a reloc the same size as a host
385      machine word.
386      FIXME: We should also do overflow checking on the result after
387      adding in the value contained in the object file.  */
388   if (howto->complain_on_overflow != complain_overflow_dont)
389     {
390       bfd_vma check;
391
392       /* Get the value that will be used for the relocation, but
393          starting at bit position zero.  */
394       if (howto->rightshift > howto->bitpos)
395         check = relocation >> (howto->rightshift - howto->bitpos);
396       else
397         check = relocation << (howto->bitpos - howto->rightshift);
398       switch (howto->complain_on_overflow)
399         {
400         case complain_overflow_signed:
401           {
402             /* Assumes two's complement.  */
403             bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
404             bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
405
406             /* The above right shift is incorrect for a signed value.
407                Fix it up by forcing on the upper bits.  */
408             if (howto->rightshift > howto->bitpos
409                 && (bfd_signed_vma) relocation < 0)
410               check |= ((bfd_vma) - 1
411                         & ~((bfd_vma) - 1
412                             >> (howto->rightshift - howto->bitpos)));
413             if ((bfd_signed_vma) check > reloc_signed_max
414                 || (bfd_signed_vma) check < reloc_signed_min)
415               flag = bfd_reloc_overflow;
416           }
417           break;
418         case complain_overflow_unsigned:
419           {
420             /* Assumes two's complement.  This expression avoids
421                overflow if howto->bitsize is the number of bits in
422                bfd_vma.  */
423             bfd_vma reloc_unsigned_max =
424             (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
425
426             if ((bfd_vma) check > reloc_unsigned_max)
427               flag = bfd_reloc_overflow;
428           }
429           break;
430         case complain_overflow_bitfield:
431           {
432             /* Assumes two's complement.  This expression avoids
433                overflow if howto->bitsize is the number of bits in
434                bfd_vma.  */
435             bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
436
437             if (((bfd_vma) check & ~reloc_bits) != 0
438                 && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
439               {
440                 /* The above right shift is incorrect for a signed
441                    value.  See if turning on the upper bits fixes the
442                    overflow.  */
443                 if (howto->rightshift > howto->bitpos
444                     && (bfd_signed_vma) relocation < 0)
445                   {
446                     check |= ((bfd_vma) - 1
447                               & ~((bfd_vma) - 1
448                                   >> (howto->rightshift - howto->bitpos)));
449                     if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits))
450                       flag = bfd_reloc_overflow;
451                   }
452                 else
453                   flag = bfd_reloc_overflow;
454               }
455           }
456           break;
457         default:
458           abort ();
459         }
460     }
461
462   /*
463     Either we are relocating all the way, or we don't want to apply
464     the relocation to the reloc entry (probably because there isn't
465     any room in the output format to describe addends to relocs)
466     */
467
468   /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler
469      (OSF version 1.3, compiler version 3.11).  It miscompiles the
470      following program:
471
472      struct str
473      {
474        unsigned int i0;
475      } s = { 0 };
476
477      int
478      main ()
479      {
480        unsigned long x;
481
482        x = 0x100000000;
483        x <<= (unsigned long) s.i0;
484        if (x == 0)
485          printf ("failed\n");
486        else
487          printf ("succeeded (%lx)\n", x);
488      }
489      */
490
491   relocation >>= (bfd_vma) howto->rightshift;
492
493   /* Shift everything up to where it's going to be used */
494
495   relocation <<= (bfd_vma) howto->bitpos;
496
497   /* Wait for the day when all have the mask in them */
498
499   /* What we do:
500      i instruction to be left alone
501      o offset within instruction
502      r relocation offset to apply
503      S src mask
504      D dst mask
505      N ~dst mask
506      A part 1
507      B part 2
508      R result
509
510      Do this:
511      i i i i i o o o o o        from bfd_get<size>
512      and           S S S S S    to get the size offset we want
513      +   r r r r r r r r r r  to get the final value to place
514      and           D D D D D  to chop to right size
515      -----------------------
516      A A A A A
517      And this:
518      ...   i i i i i o o o o o  from bfd_get<size>
519      and   N N N N N            get instruction
520      -----------------------
521      ...   B B B B B
522
523      And then:
524      B B B B B
525      or              A A A A A
526      -----------------------
527      R R R R R R R R R R        put into bfd_put<size>
528      */
529
530 #define DOIT(x) \
531   x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) +  relocation) & howto->dst_mask))
532
533   switch (howto->size)
534     {
535     case 0:
536       {
537         char x = get_data (data, addr, 1);
538         DOIT (x);
539         overflow = put_data(x, data, addr, 1);
540       }
541       break;
542
543     case 1:
544       if (relocation)
545         {
546           short x = get_data (data, addr, 2);
547           DOIT (x);
548           overflow = put_data(x, (unsigned char *) data, addr, 2);
549         }
550       break;
551     case 2:
552       if (relocation)
553         {
554           long x = get_data (data, addr, 4);
555           DOIT (x);
556           overflow = put_data(x, data, addr, 4);
557         }
558       break;
559     case -2:
560       {
561         long  x = get_data(data, addr, 4);
562         relocation = -relocation;
563         DOIT(x);
564         overflow = put_data(x, data , addr, 4);
565       }
566       break;
567
568     case 3:
569       /* Do nothing */
570       break;
571
572     case 4:
573 #ifdef BFD64
574       if (relocation)
575         {
576           bfd_vma x = get_data (data, addr, 8);
577           DOIT (x);
578           overflow = put_data(x, data, addr, 8);
579         }
580 #else
581       abort ();
582 #endif
583       break;
584     default:
585       return bfd_reloc_other;
586     }
587   if ((howto->complain_on_overflow != complain_overflow_dont) && overflow)
588     return bfd_reloc_overflow;
589
590   return flag;
591 }
592
593 /* Relocate a given location using a given value and howto.  */
594
595 bfd_reloc_status_type
596 _bfd_do_ns32k_reloc_contents ( howto, input_bfd, relocation, location,
597                               get_data, put_data)
598      reloc_howto_type *howto;
599      bfd *input_bfd;
600      bfd_vma relocation;
601      bfd_byte *location;
602      long (*get_data)();
603      int (*put_data)();
604 {
605   int size;
606   bfd_vma x;
607   boolean overflow;
608
609   /* If the size is negative, negate RELOCATION.  This isn't very
610      general.  */
611   if (howto->size < 0)
612     relocation = -relocation;
613
614   /* Get the value we are going to relocate.  */
615   size = bfd_get_reloc_size (howto);
616   switch (size)
617     {
618     default:
619     case 0:
620       abort ();
621     case 1:
622     case 2:
623     case 4:
624 #ifdef BFD64
625     case 8:
626 #endif
627       x = get_data (location, 0, size);
628       break;
629     }
630
631   /* Check for overflow.  FIXME: We may drop bits during the addition
632      which we don't check for.  We must either check at every single
633      operation, which would be tedious, or we must do the computations
634      in a type larger than bfd_vma, which would be inefficient.  */
635   overflow = false;
636   if (howto->complain_on_overflow != complain_overflow_dont)
637     {
638       bfd_vma check;
639       bfd_signed_vma signed_check;
640       bfd_vma add;
641       bfd_signed_vma signed_add;
642
643       if (howto->rightshift == 0)
644         {
645           check = relocation;
646           signed_check = (bfd_signed_vma) relocation;
647         }
648       else
649         {
650           /* Drop unwanted bits from the value we are relocating to.  */
651           check = relocation >> howto->rightshift;
652
653           /* If this is a signed value, the rightshift just dropped
654              leading 1 bits (assuming twos complement).  */
655           if ((bfd_signed_vma) relocation >= 0)
656             signed_check = check;
657           else
658             signed_check = (check
659                             | ((bfd_vma) - 1
660                                & ~((bfd_vma) - 1 >> howto->rightshift)));
661         }
662
663       /* Get the value from the object file.  */
664       add = x & howto->src_mask;
665
666       /* Get the value from the object file with an appropriate sign.
667          The expression involving howto->src_mask isolates the upper
668          bit of src_mask.  If that bit is set in the value we are
669          adding, it is negative, and we subtract out that number times
670          two.  If src_mask includes the highest possible bit, then we
671          can not get the upper bit, but that does not matter since
672          signed_add needs no adjustment to become negative in that
673          case.  */
674       signed_add = add;
675       if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
676         signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
677
678       /* Add the value from the object file, shifted so that it is a
679          straight number.  */
680       if (howto->bitpos == 0)
681         {
682           check += add;
683           signed_check += signed_add;
684         }
685       else
686         {
687           check += add >> howto->bitpos;
688
689           /* For the signed case we use ADD, rather than SIGNED_ADD,
690              to avoid warnings from SVR4 cc.  This is OK since we
691              explictly handle the sign bits.  */
692           if (signed_add >= 0)
693             signed_check += add >> howto->bitpos;
694           else
695             signed_check += ((add >> howto->bitpos)
696                              | ((bfd_vma) - 1
697                                 & ~((bfd_vma) - 1 >> howto->bitpos)));
698         }
699
700       switch (howto->complain_on_overflow)
701         {
702         case complain_overflow_signed:
703           {
704             /* Assumes two's complement.  */
705             bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
706             bfd_signed_vma reloc_signed_min = ~reloc_signed_max;
707
708             if (signed_check > reloc_signed_max
709                 || signed_check < reloc_signed_min)
710               overflow = true;
711           }
712           break;
713         case complain_overflow_unsigned:
714           {
715             /* Assumes two's complement.  This expression avoids
716                overflow if howto->bitsize is the number of bits in
717                bfd_vma.  */
718             bfd_vma reloc_unsigned_max =
719             (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
720
721             if (check > reloc_unsigned_max)
722               overflow = true;
723           }
724           break;
725         case complain_overflow_bitfield:
726           {
727             /* Assumes two's complement.  This expression avoids
728                overflow if howto->bitsize is the number of bits in
729                bfd_vma.  */
730             bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1;
731
732             if ((check & ~reloc_bits) != 0
733                 && (((bfd_vma) signed_check & ~reloc_bits)
734                     != (-1 & ~reloc_bits)))
735               overflow = true;
736           }
737           break;
738         default:
739           abort ();
740         }
741     }
742
743   /* Put RELOCATION in the right bits.  */
744   relocation >>= (bfd_vma) howto->rightshift;
745   relocation <<= (bfd_vma) howto->bitpos;
746
747   /* Add RELOCATION to the right bits of X.  */
748   x = ((x & ~howto->dst_mask)
749        | (((x & howto->src_mask) + relocation) & howto->dst_mask));
750
751   /* Put the relocated value back in the object file.  */
752   switch (size)
753     {
754     default:
755     case 0:
756       abort ();
757     case 1:
758     case 2:
759     case 4:
760 #ifdef BFD64
761     case 8:
762 #endif
763       put_data(x, location, 0, size);
764       break;
765     }
766
767   return overflow ? bfd_reloc_overflow : bfd_reloc_ok;
768 }
769
770 bfd_reloc_status_type
771 _bfd_ns32k_reloc_disp (abfd, reloc_entry, symbol, data, input_section,
772                        output_bfd, error_message)
773      bfd *abfd;
774      arelent *reloc_entry;
775      struct symbol_cache_entry *symbol;
776      PTR data;
777      asection *input_section;
778      bfd *output_bfd;
779      char **error_message;
780 {
781   return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
782                          output_bfd, error_message,
783                          _bfd_ns32k_get_displacement,
784                          _bfd_ns32k_put_displacement);
785 }
786
787 bfd_reloc_status_type
788 _bfd_ns32k_reloc_imm (abfd, reloc_entry, symbol, data, input_section,
789                       output_bfd, error_message)
790      bfd *abfd;
791      arelent *reloc_entry;
792      struct symbol_cache_entry *symbol;
793      PTR data;
794      asection *input_section;
795      bfd *output_bfd;
796      char **error_message;
797 {
798   return do_ns32k_reloc (abfd, reloc_entry, symbol, data, input_section,
799                          output_bfd, error_message, _bfd_ns32k_get_immediate,
800                          _bfd_ns32k_put_immediate);
801 }
802
803 bfd_reloc_status_type
804 _bfd_ns32k_final_link_relocate (howto, input_bfd, input_section, contents,
805                                 address, value, addend)
806      reloc_howto_type *howto;
807      bfd *input_bfd;
808      asection *input_section;
809      bfd_byte *contents;
810      bfd_vma address;
811      bfd_vma value;
812      bfd_vma addend;
813 {
814   bfd_vma relocation;
815
816   /* Sanity check the address.  */
817   if (address > input_section->_cooked_size)
818     return bfd_reloc_outofrange;
819
820   /* This function assumes that we are dealing with a basic relocation
821      against a symbol.  We want to compute the value of the symbol to
822      relocate to.  This is just VALUE, the value of the symbol, plus
823      ADDEND, any addend associated with the reloc.  */
824   relocation = value + addend;
825
826   /* If the relocation is PC relative, we want to set RELOCATION to
827      the distance between the symbol (currently in RELOCATION) and the
828      location we are relocating.  Some targets (e.g., i386-aout)
829      arrange for the contents of the section to be the negative of the
830      offset of the location within the section; for such targets
831      pcrel_offset is false.  Other targets (e.g., m88kbcs or ELF)
832      simply leave the contents of the section as zero; for such
833      targets pcrel_offset is true.  If pcrel_offset is false we do not
834      need to subtract out the offset of the location within the
835      section (which is just ADDRESS).  */
836   if (howto->pc_relative)
837     {
838       relocation -= (input_section->output_section->vma
839                      + input_section->output_offset);
840       if (howto->pcrel_offset)
841         relocation -= address;
842     }
843
844   return _bfd_ns32k_relocate_contents (howto, input_bfd, relocation,
845                                        contents + address);
846 }