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
7 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
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, }
31 static const bfd_arch_info_type arch_info_struct
[] =
33 N(32532,"ns32k:32532",TRUE
, 0), /* The word ns32k will match this too. */
36 const bfd_arch_info_type bfd_ns32k_arch
=
37 N(32032,"ns32k:32032",FALSE
, &arch_info_struct
[0]);
39 static bfd_reloc_status_type do_ns32k_reloc
40 PARAMS ((bfd
*, arelent
*, struct bfd_symbol
*, PTR
, asection
*,
42 bfd_vma (*) (bfd_byte
*, int),
43 void (*) (bfd_vma
, bfd_byte
*, int)));
46 _bfd_ns32k_get_displacement (buffer
, size
)
55 value
= ((*buffer
& 0x7f) ^ 0x40) - 0x40;
59 value
= ((*buffer
++ & 0x3f) ^ 0x20) - 0x20;
60 value
= (value
<< 8) | (0xff & *buffer
);
64 value
= ((*buffer
++ & 0x3f) ^ 0x20) - 0x20;
65 value
= (value
<< 8) | (0xff & *buffer
++);
66 value
= (value
<< 8) | (0xff & *buffer
++);
67 value
= (value
<< 8) | (0xff & *buffer
);
79 _bfd_ns32k_put_displacement (value
, buffer
, size
)
94 *buffer
++ = (value
>> 8);
99 value
|= (bfd_vma
) 0xc0000000;
100 *buffer
++ = (value
>> 24);
101 *buffer
++ = (value
>> 16);
102 *buffer
++ = (value
>> 8);
110 _bfd_ns32k_get_immediate (buffer
, size
)
119 value
= (value
<< 8) | (*buffer
++ & 0xff);
120 value
= (value
<< 8) | (*buffer
++ & 0xff);
122 value
= (value
<< 8) | (*buffer
++ & 0xff);
124 value
= (value
<< 8) | (*buffer
++ & 0xff);
133 _bfd_ns32k_put_immediate (value
, buffer
, size
)
142 *buffer
-- = (value
& 0xff); value
>>= 8;
143 *buffer
-- = (value
& 0xff); value
>>= 8;
145 *buffer
-- = (value
& 0xff); value
>>= 8;
147 *buffer
-- = (value
& 0xff); value
>>= 8;
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
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
)
160 arelent
*reloc_entry
;
161 struct bfd_symbol
*symbol
;
163 asection
*input_section
;
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));
171 bfd_reloc_status_type flag
= bfd_reloc_ok
;
172 bfd_size_type addr
= reloc_entry
->address
;
174 bfd_vma output_base
= 0;
175 reloc_howto_type
*howto
= reloc_entry
->howto
;
176 asection
*reloc_target_output_section
;
179 if ((symbol
->section
== &bfd_abs_section
)
180 && output_bfd
!= (bfd
*) NULL
)
182 reloc_entry
->address
+= input_section
->output_offset
;
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
;
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
;
199 /* Work out which section the relocation is targeted at and the
200 initial relocation command value. */
202 /* Get symbol value. (Common symbols are special.) */
203 if (bfd_is_com_section (symbol
->section
))
206 relocation
= symbol
->value
;
208 reloc_target_output_section
= symbol
->section
->output_section
;
210 /* Convert input-section-relative symbol value to absolute. */
211 if (output_bfd
!= NULL
&& ! howto
->partial_inplace
)
214 output_base
= reloc_target_output_section
->vma
;
216 relocation
+= output_base
+ symbol
->section
->output_offset
;
218 /* Add in supplied addend. */
219 relocation
+= reloc_entry
->addend
;
221 /* Here the variable relocation holds the final address of the
222 symbol we are relocating against, plus any addend. */
224 if (howto
->pc_relative
)
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.
230 We start by subtracting the address of the section containing
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.
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.
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. */
254 input_section
->output_section
->vma
+ input_section
->output_offset
;
256 if (howto
->pcrel_offset
)
257 relocation
-= reloc_entry
->address
;
260 if (output_bfd
!= (bfd
*) NULL
)
262 if (! howto
->partial_inplace
)
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
;
273 /* This is a partial relocation, but inplace, so modify the
276 If we've relocated with a symbol with a section, change
277 into a ref to the section belonging to the symbol. */
279 reloc_entry
->address
+= input_section
->output_offset
;
282 if (abfd
->xvec
->flavour
== bfd_target_coff_flavour
)
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.
289 However, Ian wrote the following, regarding removing the line
290 below, which explains why it is still enabled: --djm
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.
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.
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.
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).
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).
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.
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
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
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
359 relocation
-= reloc_entry
->addend
;
361 reloc_entry
->addend
= 0;
365 reloc_entry
->addend
= relocation
;
371 reloc_entry
->addend
= 0;
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
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
)
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
);
390 check
= relocation
<< (howto
->bitpos
- howto
->rightshift
);
391 switch (howto
->complain_on_overflow
)
393 case complain_overflow_signed
:
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
;
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
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
;
411 case complain_overflow_unsigned
:
413 /* Assumes two's complement. This expression avoids
414 overflow if howto->bitsize is the number of bits in
416 bfd_vma reloc_unsigned_max
=
417 (((1 << (howto
->bitsize
- 1)) - 1) << 1) | 1;
419 if ((bfd_vma
) check
> reloc_unsigned_max
)
420 flag
= bfd_reloc_overflow
;
423 case complain_overflow_bitfield
:
425 /* Assumes two's complement. This expression avoids
426 overflow if howto->bitsize is the number of bits in
428 bfd_vma reloc_bits
= (((1 << (howto
->bitsize
- 1)) - 1) << 1) | 1;
430 if (((bfd_vma
) check
& ~reloc_bits
) != 0
431 && (((bfd_vma
) check
& ~reloc_bits
)
432 != (-(bfd_vma
) 1 & ~reloc_bits
)))
434 /* The above right shift is incorrect for a signed
435 value. See if turning on the upper bits fixes the
437 if (howto
->rightshift
> howto
->bitpos
438 && (bfd_signed_vma
) relocation
< 0)
440 check
|= ((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
;
448 flag
= bfd_reloc_overflow
;
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). */
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
476 x <<= (unsigned long) s.i0;
480 printf ("succeeded (%lx)\n", x);
484 relocation
>>= (bfd_vma
) howto
->rightshift
;
486 /* Shift everything up to where it's going to be used. */
487 relocation
<<= (bfd_vma
) howto
->bitpos
;
489 /* Wait for the day when all have the mask in them. */
492 i instruction to be left alone
493 o offset within instruction
494 r relocation offset to apply
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 -----------------------
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 -----------------------
518 -----------------------
519 R R R R R R R R R R put into bfd_put<size>. */
522 x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
524 location
= (bfd_byte
*) data
+ addr
;
529 bfd_vma x
= get_data (location
, 1);
531 put_data ((bfd_vma
) x
, location
, 1);
538 bfd_vma x
= get_data (location
, 2);
540 put_data ((bfd_vma
) x
, location
, 2);
546 bfd_vma x
= get_data (location
, 4);
548 put_data ((bfd_vma
) x
, location
, 4);
553 bfd_vma x
= get_data (location
, 4);
554 relocation
= -relocation
;
556 put_data ((bfd_vma
) x
, location
, 4);
568 bfd_vma x
= get_data (location
, 8);
570 put_data (x
, location
, 8);
577 return bfd_reloc_other
;
579 if ((howto
->complain_on_overflow
!= complain_overflow_dont
) && overflow
)
580 return bfd_reloc_overflow
;
585 /* Relocate a given location using a given value and howto. */
587 bfd_reloc_status_type
588 _bfd_do_ns32k_reloc_contents (howto
, input_bfd
, relocation
, location
,
590 reloc_howto_type
*howto
;
591 bfd
*input_bfd ATTRIBUTE_UNUSED
;
594 bfd_vma (*get_data
) PARAMS ((bfd_byte
*, int));
595 void (*put_data
) PARAMS ((bfd_vma
, bfd_byte
*, int));
599 bfd_boolean overflow
;
601 /* If the size is negative, negate RELOCATION. This isn't very
604 relocation
= -relocation
;
606 /* Get the value we are going to relocate. */
607 size
= bfd_get_reloc_size (howto
);
619 x
= get_data (location
, size
);
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. */
628 if (howto
->complain_on_overflow
!= complain_overflow_dont
)
631 bfd_signed_vma signed_check
;
633 bfd_signed_vma signed_add
;
635 if (howto
->rightshift
== 0)
638 signed_check
= (bfd_signed_vma
) relocation
;
642 /* Drop unwanted bits from the value we are relocating to. */
643 check
= relocation
>> howto
->rightshift
;
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
;
650 signed_check
= (check
652 & ~((bfd_vma
) - 1 >> howto
->rightshift
)));
655 /* Get the value from the object file. */
656 add
= x
& howto
->src_mask
;
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
667 if ((add
& (((~howto
->src_mask
) >> 1) & howto
->src_mask
)) != 0)
668 signed_add
-= (((~howto
->src_mask
) >> 1) & howto
->src_mask
) << 1;
670 /* Add the value from the object file, shifted so that it is a
672 if (howto
->bitpos
== 0)
675 signed_check
+= signed_add
;
679 check
+= add
>> howto
->bitpos
;
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. */
685 signed_check
+= add
>> howto
->bitpos
;
687 signed_check
+= ((add
>> howto
->bitpos
)
689 & ~((bfd_vma
) - 1 >> howto
->bitpos
)));
692 switch (howto
->complain_on_overflow
)
694 case complain_overflow_signed
:
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
;
700 if (signed_check
> reloc_signed_max
701 || signed_check
< reloc_signed_min
)
705 case complain_overflow_unsigned
:
707 /* Assumes two's complement. This expression avoids
708 overflow if howto->bitsize is the number of bits in
710 bfd_vma reloc_unsigned_max
=
711 (((1 << (howto
->bitsize
- 1)) - 1) << 1) | 1;
713 if (check
> reloc_unsigned_max
)
717 case complain_overflow_bitfield
:
719 /* Assumes two's complement. This expression avoids
720 overflow if howto->bitsize is the number of bits in
722 bfd_vma reloc_bits
= (((1 << (howto
->bitsize
- 1)) - 1) << 1) | 1;
724 if ((check
& ~reloc_bits
) != 0
725 && (((bfd_vma
) signed_check
& ~reloc_bits
)
726 != (-(bfd_vma
) 1 & ~reloc_bits
)))
735 /* Put RELOCATION in the right bits. */
736 relocation
>>= (bfd_vma
) howto
->rightshift
;
737 relocation
<<= (bfd_vma
) howto
->bitpos
;
739 /* Add RELOCATION to the right bits of X. */
740 x
= ((x
& ~howto
->dst_mask
)
741 | (((x
& howto
->src_mask
) + relocation
) & howto
->dst_mask
));
743 /* Put the relocated value back in the object file. */
755 put_data (x
, location
, size
);
759 return overflow
? bfd_reloc_overflow
: bfd_reloc_ok
;
762 bfd_reloc_status_type
763 _bfd_ns32k_reloc_disp (abfd
, reloc_entry
, symbol
, data
, input_section
,
764 output_bfd
, error_message
)
766 arelent
*reloc_entry
;
767 struct bfd_symbol
*symbol
;
769 asection
*input_section
;
771 char **error_message
;
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
);
779 bfd_reloc_status_type
780 _bfd_ns32k_reloc_imm (abfd
, reloc_entry
, symbol
, data
, input_section
,
781 output_bfd
, error_message
)
783 arelent
*reloc_entry
;
784 struct bfd_symbol
*symbol
;
786 asection
*input_section
;
788 char **error_message
;
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
);
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
;
800 asection
*input_section
;
809 /* Sanity check the address. */
810 sz
= input_section
->rawsize
? input_section
->rawsize
: input_section
->size
;
812 return bfd_reloc_outofrange
;
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
;
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
)
832 relocation
-= (input_section
->output_section
->vma
833 + input_section
->output_offset
);
834 if (howto
->pcrel_offset
)
835 relocation
-= address
;
838 return _bfd_ns32k_relocate_contents (howto
, input_bfd
, relocation
,