This is the mail archive of the binutils@sourceware.cygnus.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

reloc overflows


I've just been looking at ways to fix the 16-bit reloc overflow problem
discussed in the thread starting at
http://sourceware.cygnus.com/ml/binutils/2000-02/msg00198.html  My
conclusion is that it's not easy to fix without either massive hacks or a
fairly simple change in bitfield overflow handling.

Actually, the problem isn't limited to 16-bit relocs.  It also shows up in
32-bit relocs when compiling bfd with --enable-64-bit-bfd (or with some
target requiring BFD64).  Using an x86 example

$ cat jmp.s
.extern foo
 jmp foo
$ gas/gas/as-new -o jmp.o jmp.s
$ gas/ld/ld-new -Ttext 0x80000000 -e 0x80000000 -defsym foo=0 jmp.o
jmp.o(.text+0x1): relocation truncated to fit: R_386_PC32 foo
$ 

This testcase doesn't fail when using a 32-bit bfd because Ian put in a
hack
	  /* We explicitly permit wrap around if this relocation
	     covers the high bit of an address.  The Linux kernel
	     relies on it, and it is the only way to write assembler
	     code which can run when loaded at a location 0x80000000
	     away from the location at which it is linked.  */
	  if (howto->bitsize + rightshift
	      == bfd_arch_bits_per_address (input_bfd))
	    break;

to circumvent some of the checks in _bfd_relocate_contents (case
complain_overflow_bitfield), but this isn't sufficient when compiling with
64-bit bfd.  Moving the hack up a little will cure the problem by
effectively saying that if bits_per_address == 32 then a 32-bit bitfield
reloc can't overflow (which is what you get when compiling with a 32-bit
bfd).  I don't particularly like this solution though as we might as well
remove all the bitfield overflow checking.

My alternative solution, which also fixes the 16-bit reloc problem, is to
say that a bitfield reloc of n bits can represent numbers in the range
-(2**n) to 2**n-1.  The current range allowed is -(2**(n-1)) to 2**n-1,
ie. overlap of n bit signed and unsigned numbers.

What do you all think of this?


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]