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
6 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
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, }
30 static const bfd_arch_info_type arch_info_struct
[] =
32 N(32532,"ns32k:32532",true, 0), /* the word ns32k will match this too */
35 const bfd_arch_info_type bfd_ns32k_arch
=
36 N(32032,"ns32k:32032",false, &arch_info_struct
[0]);
39 ns32k_sign_extend(value
, bits
)
43 value
= value
& ((1 << bits
) - 1);
44 return (value
& (1 << (bits
-1))
45 ? value
| (~((1 << bits
) - 1))
50 _bfd_ns32k_get_displacement(buffer
, offset
, size
)
60 value
= ns32k_sign_extend (*buffer
, 7);
63 value
= ns32k_sign_extend(*buffer
++, 6);
64 value
= (value
<< 8) | (0xff & *buffer
);
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
);
80 _bfd_ns32k_put_displacement(value
, buffer
, offset
, size
)
90 if (value
< -64 || value
> 63)
96 if (value
< -8192 || value
> 8191)
100 *buffer
++=(value
>>8);
104 if (value
< -0x1f000000 || value
>= 0x20000000)
107 *buffer
++=(value
>>24);
108 *buffer
++=(value
>>16);
109 *buffer
++=(value
>>8);
119 _bfd_ns32k_get_immediate (buffer
, offset
, size
)
129 value
= (value
<< 8) | (*buffer
++ & 0xff);
131 value
= (value
<< 8) | (*buffer
++ & 0xff);
133 value
= (value
<< 8) | (*buffer
++ & 0xff);
135 value
= (value
<< 8) | (*buffer
++ & 0xff);
141 _bfd_ns32k_put_immediate (value
, buffer
, offset
, size
)
147 buffer
+= offset
+ size
- 1;
151 *buffer
-- = (value
& 0xff); value
>>= 8;
153 *buffer
-- = (value
& 0xff); value
>>= 8;
155 *buffer
-- = (value
& 0xff); value
>>= 8;
157 *buffer
-- = (value
& 0xff); value
>>= 8;
162 /* This is just like the standard perform_relocation except we
163 * use get_data and put_data which know about the ns32k
165 * This is probably a lot more complicated than it needs to be!
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
)
171 arelent
*reloc_entry
;
172 struct symbol_cache_entry
*symbol
;
174 asection
*input_section
;
176 char **error_message
;
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
;
188 if ((symbol
->section
== &bfd_abs_section
)
189 && output_bfd
!= (bfd
*) NULL
)
191 reloc_entry
->address
+= input_section
->output_offset
;
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
;
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
;
208 /* Work out which section the relocation is targetted at and the
209 initial relocation command value. */
211 /* Get symbol value. (Common symbols are special.) */
212 if (bfd_is_com_section (symbol
->section
))
215 relocation
= symbol
->value
;
218 reloc_target_output_section
= symbol
->section
->output_section
;
220 /* Convert input-section-relative symbol value to absolute. */
221 if (output_bfd
&& howto
->partial_inplace
== false)
224 output_base
= reloc_target_output_section
->vma
;
226 relocation
+= output_base
+ symbol
->section
->output_offset
;
228 /* Add in supplied addend. */
229 relocation
+= reloc_entry
->addend
;
231 /* Here the variable relocation holds the final address of the
232 symbol we are relocating against, plus any addend. */
234 if (howto
->pc_relative
== true)
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.
240 We start by subtracting the address of the section containing
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.
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.
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. */
265 input_section
->output_section
->vma
+ input_section
->output_offset
;
267 if (howto
->pcrel_offset
== true)
268 relocation
-= reloc_entry
->address
;
271 if (output_bfd
!= (bfd
*) NULL
)
273 if (howto
->partial_inplace
== false)
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
;
284 /* This is a partial relocation, but inplace, so modify the
287 If we've relocated with a symbol with a section, change
288 into a ref to the section belonging to the symbol. */
290 reloc_entry
->address
+= input_section
->output_offset
;
293 if (abfd
->xvec
->flavour
== bfd_target_coff_flavour
294 && strcmp (abfd
->xvec
->name
, "aixcoff-rs6000") != 0)
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.
301 However, Ian wrote the following, regarding removing the line below,
302 which explains why it is still enabled: --djm
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.
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.
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.
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).
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).
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.
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:
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
361 6) if the resulting object files are the same, you have at least
363 7) if they are different you have to figure out which version is
366 relocation
-= reloc_entry
->addend
;
368 reloc_entry
->addend
= 0;
372 reloc_entry
->addend
= relocation
;
378 reloc_entry
->addend
= 0;
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
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
)
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
);
397 check
= relocation
<< (howto
->bitpos
- howto
->rightshift
);
398 switch (howto
->complain_on_overflow
)
400 case complain_overflow_signed
:
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
;
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
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
;
418 case complain_overflow_unsigned
:
420 /* Assumes two's complement. This expression avoids
421 overflow if howto->bitsize is the number of bits in
423 bfd_vma reloc_unsigned_max
=
424 (((1 << (howto
->bitsize
- 1)) - 1) << 1) | 1;
426 if ((bfd_vma
) check
> reloc_unsigned_max
)
427 flag
= bfd_reloc_overflow
;
430 case complain_overflow_bitfield
:
432 /* Assumes two's complement. This expression avoids
433 overflow if howto->bitsize is the number of bits in
435 bfd_vma reloc_bits
= (((1 << (howto
->bitsize
- 1)) - 1) << 1) | 1;
437 if (((bfd_vma
) check
& ~reloc_bits
) != 0
438 && ((bfd_vma
) check
& ~reloc_bits
) != (-1 & ~reloc_bits
))
440 /* The above right shift is incorrect for a signed
441 value. See if turning on the upper bits fixes the
443 if (howto
->rightshift
> howto
->bitpos
444 && (bfd_signed_vma
) relocation
< 0)
446 check
|= ((bfd_vma
) - 1
448 >> (howto
->rightshift
- howto
->bitpos
)));
449 if (((bfd_vma
) check
& ~reloc_bits
) != (-1 & ~reloc_bits
))
450 flag
= bfd_reloc_overflow
;
453 flag
= bfd_reloc_overflow
;
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)
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
483 x <<= (unsigned long) s.i0;
487 printf ("succeeded (%lx)\n", x);
491 relocation
>>= (bfd_vma
) howto
->rightshift
;
493 /* Shift everything up to where it's going to be used */
495 relocation
<<= (bfd_vma
) howto
->bitpos
;
497 /* Wait for the day when all have the mask in them */
500 i instruction to be left alone
501 o offset within instruction
502 r relocation offset to apply
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 -----------------------
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 -----------------------
526 -----------------------
527 R R R R R R R R R R put into bfd_put<size>
531 x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
537 char x
= get_data (data
, addr
, 1);
539 overflow
= put_data(x
, data
, addr
, 1);
546 short x
= get_data (data
, addr
, 2);
548 overflow
= put_data(x
, (unsigned char *) data
, addr
, 2);
554 long x
= get_data (data
, addr
, 4);
556 overflow
= put_data(x
, data
, addr
, 4);
561 long x
= get_data(data
, addr
, 4);
562 relocation
= -relocation
;
564 overflow
= put_data(x
, data
, addr
, 4);
576 bfd_vma x
= get_data (data
, addr
, 8);
578 overflow
= put_data(x
, data
, addr
, 8);
585 return bfd_reloc_other
;
587 if ((howto
->complain_on_overflow
!= complain_overflow_dont
) && overflow
)
588 return bfd_reloc_overflow
;
593 /* Relocate a given location using a given value and howto. */
595 bfd_reloc_status_type
596 _bfd_do_ns32k_reloc_contents ( howto
, input_bfd
, relocation
, location
,
598 reloc_howto_type
*howto
;
609 /* If the size is negative, negate RELOCATION. This isn't very
612 relocation
= -relocation
;
614 /* Get the value we are going to relocate. */
615 size
= bfd_get_reloc_size (howto
);
627 x
= get_data (location
, 0, size
);
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. */
636 if (howto
->complain_on_overflow
!= complain_overflow_dont
)
639 bfd_signed_vma signed_check
;
641 bfd_signed_vma signed_add
;
643 if (howto
->rightshift
== 0)
646 signed_check
= (bfd_signed_vma
) relocation
;
650 /* Drop unwanted bits from the value we are relocating to. */
651 check
= relocation
>> howto
->rightshift
;
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
;
658 signed_check
= (check
660 & ~((bfd_vma
) - 1 >> howto
->rightshift
)));
663 /* Get the value from the object file. */
664 add
= x
& howto
->src_mask
;
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
675 if ((add
& (((~howto
->src_mask
) >> 1) & howto
->src_mask
)) != 0)
676 signed_add
-= (((~howto
->src_mask
) >> 1) & howto
->src_mask
) << 1;
678 /* Add the value from the object file, shifted so that it is a
680 if (howto
->bitpos
== 0)
683 signed_check
+= signed_add
;
687 check
+= add
>> howto
->bitpos
;
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. */
693 signed_check
+= add
>> howto
->bitpos
;
695 signed_check
+= ((add
>> howto
->bitpos
)
697 & ~((bfd_vma
) - 1 >> howto
->bitpos
)));
700 switch (howto
->complain_on_overflow
)
702 case complain_overflow_signed
:
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
;
708 if (signed_check
> reloc_signed_max
709 || signed_check
< reloc_signed_min
)
713 case complain_overflow_unsigned
:
715 /* Assumes two's complement. This expression avoids
716 overflow if howto->bitsize is the number of bits in
718 bfd_vma reloc_unsigned_max
=
719 (((1 << (howto
->bitsize
- 1)) - 1) << 1) | 1;
721 if (check
> reloc_unsigned_max
)
725 case complain_overflow_bitfield
:
727 /* Assumes two's complement. This expression avoids
728 overflow if howto->bitsize is the number of bits in
730 bfd_vma reloc_bits
= (((1 << (howto
->bitsize
- 1)) - 1) << 1) | 1;
732 if ((check
& ~reloc_bits
) != 0
733 && (((bfd_vma
) signed_check
& ~reloc_bits
)
734 != (-1 & ~reloc_bits
)))
743 /* Put RELOCATION in the right bits. */
744 relocation
>>= (bfd_vma
) howto
->rightshift
;
745 relocation
<<= (bfd_vma
) howto
->bitpos
;
747 /* Add RELOCATION to the right bits of X. */
748 x
= ((x
& ~howto
->dst_mask
)
749 | (((x
& howto
->src_mask
) + relocation
) & howto
->dst_mask
));
751 /* Put the relocated value back in the object file. */
763 put_data(x
, location
, 0, size
);
767 return overflow
? bfd_reloc_overflow
: bfd_reloc_ok
;
770 bfd_reloc_status_type
771 _bfd_ns32k_reloc_disp (abfd
, reloc_entry
, symbol
, data
, input_section
,
772 output_bfd
, error_message
)
774 arelent
*reloc_entry
;
775 struct symbol_cache_entry
*symbol
;
777 asection
*input_section
;
779 char **error_message
;
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
);
787 bfd_reloc_status_type
788 _bfd_ns32k_reloc_imm (abfd
, reloc_entry
, symbol
, data
, input_section
,
789 output_bfd
, error_message
)
791 arelent
*reloc_entry
;
792 struct symbol_cache_entry
*symbol
;
794 asection
*input_section
;
796 char **error_message
;
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
);
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
;
808 asection
*input_section
;
816 /* Sanity check the address. */
817 if (address
> input_section
->_cooked_size
)
818 return bfd_reloc_outofrange
;
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
;
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
)
838 relocation
-= (input_section
->output_section
->vma
839 + input_section
->output_offset
);
840 if (howto
->pcrel_offset
)
841 relocation
-= address
;
844 return _bfd_ns32k_relocate_contents (howto
, input_bfd
, relocation
,