This is the mail archive of the binutils@sources.redhat.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]

Re: new gas cannot grok new gcc output


Alan Modra <alan@linuxcare.com.au> wrote:

> On Thu, 8 Feb 2001, Aaron J. Grier wrote:
>
> >[about m68k-rtems-elf]
> > /tmp/cckO515f.s:1890: Error: Value of -1202 too large for field of 1 bytes at 1201
> > /tmp/cckO515f.s:1890: Error: Value of -1276 too large for field of 1 bytes at 1275
> > /tmp/cckO515f.s:1890: Error: Value of -1374 too large for field of 1 bytes at 1373
>
> These errors are due to problems during m68k relaxation, which is why
> the line number is at the end of file.
>
> [...]
>
> Sorry this isn't a fix, but maybe someone else will take it from here.

I have spent the past few days analysing this problem (which is why I'm
responding with such a delay), and here is what I have found.

The failures building gcc started occuring last September when I made a big
change to clean up the m68k gas relaxer and make it more uniform and
consistent. See cvs log gas/config/tc-m68k.c revision 1.11. However, my change
is not the bug, it merely exposed a problem elsewhere.

The error message is generated in gas/write.c (fixup_segment). It occurs only
on ELF (COFF and a.out are unaffected), and the exact triggering condition is
an internal fixup referencing to an externally visible symbol and located far
enough down the segment. Specifically, an internal PC-relative fixup with a
byte-sized displacement field located past 128 bytes from the beginning of the
segment referencing an externally visible symbol on an ELF target will trigger
the bogus error. Similarly for an internal PC-relative fixup with a word-sized
displacement field located past 32768 bytes from the beginning of the segment.

The reason this problem didn't show up before my relaxer change is because the
old relaxer often bypassed the generic fixup mechanism and smacked in the
displacement directly. I changed it to use the generic fixup mechanism to
support my planned linker relaxation. My change was perfectly legitimate,
however, many other targets have relaxers that always use the generic fixup
mechanism, and this mechanism must work. It is used by more than just the
relaxer. While compilers normally always generate relaxed mnemonics and thus go
through the relaxer, one can very legitimately use the non-relaxed menmonics
which never go through the relaxer and have always generated fixups handled
through the generic mechanism. Consider this testcase:

	.text
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	.globl	func1
func1:
	movel	#0xDEADBEEF,%d0
	rts
	.globl	func2
func2:
	bsrs	func1

(The nops are to put the interesting part far enough from the beginning of the
segment.) Assembling this testcase with m68k-elf-as fails with:

nonrelax.s: Assembler messages:
nonrelax.s:78: Error: Value of -150 too large for field of 1 bytes at 149

I've made my very first m68k binutils change on 2000-05-08. I have checked out
binutils as of two days before that, 2000-05-06, and it fails in exactly the
same way on this testcase.

The clue as to the source of the problem is that it's ELF specific. Basically,
gas/write.c (fixup_segment) spits out the error message because it thinks that
the fixup is targeting address 0 rather than its real target when the real
target is an externally visible symbol. This happens when the
TC_RELOC_RTSYM_LOC_FIXUP macro returns false. This macro is defined in
gas/config/tc-m68k.h for ELF only as:

/* This expression evaluates to false if the relocation is for a local object
   for which we still want to do the relocation at runtime.  True if we
   are willing to perform this relocation while building the .o file.  If
   the reloc is against an externally visible symbol, then the assembler
   should never do the relocation.  */

#define TC_RELOC_RTSYM_LOC_FIXUP(FIX)			\
	((FIX)->fx_addsy == NULL			\
	 || (! S_IS_EXTERNAL ((FIX)->fx_addsy)		\
	     && ! S_IS_WEAK ((FIX)->fx_addsy)		\
	     && S_IS_DEFINED ((FIX)->fx_addsy)		\
	     && ! S_IS_COMMON ((FIX)->fx_addsy)))

It has been this way ever since the import of binutils into sourceware (not
being a Red Hatter I can't trace it past this point in the real Cygnus tree).

I do not understand the reason behind this definition, and it seems bogus to
me. m68k gas has always emitted object files with all internal references
completely resolved like all traditional assemblers, it has never emitted
relocs for internal references, even if they refer to externally visible
symbols. This has never been any different for ELF from COFF or a.out. So if
this TC_RELOC_RTSYM_LOC_FIXUP definition was supposed to achieve that effect,
it never worked. But I don't really understand why such behavior would be
desirable. The only reason I see not to resolve an internal reference in the
assembler without emitting a reloc is for symbols to be overridable at link
time in objects that are going to be linked into DSOs. However in such objects
the code is supposed to use @PLTPC constructs on all calls, and for these gas
always generates the special PLT relocs.

My first guess suggestion would be to try removing the TC_RELOC_RTSYM_LOC_FIXUP
definition and seeing what happens. Now I'm not going to ask anyone to even
consider this change until I try it myself and give it some testing, including
a binutils testsuite run, and that will take me some time.

-- 
Michael Sokolov
Public Service Agent
International Engineering and Science Task Force

1351 VINE AVE APT 27		Phone: +1-714-738-5409
FULLERTON CA 92833-4291 USA	(home office)

E-mail: msokolov@ivan.Harhan.ORG (ARPA TCP/SMTP)


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