Subject: Haifa scheduler bug in egcs 1.0.2

From: [email-masked]
Date: Wed, 21 Oct 1998 01:50:47 +0200

Hi all,

I've resolved a bug report of Ulf Carlson whose kernel compiles resulted
died with:

gcc -D__KERNEL__ -I/home/ulfc/kernels/sgi-lin/linux/include -Wall \
-Wstrict-prototypes -O2 -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic \
-mcpu=r4600 -mips2 -pipe    arch/mips/mm/r6000.c   -o arch/mips/mm/r6000

{standard input}: Assembler messages:
{standard input}:385: Warning: Unmatched %hi reloc
{standard input}:488: Internal error!
Assertion failure in tc_gen_reloc at ./config/tc-mips.c line 10203.
Please report this bug.
make: *** [arch/mips/mm/r6000] Error 1

This is caused by bad assembler code like:

[...]
        lui     $11,%hi(r6000_flush_cache_mm) # high
        lui     $12,%hi(r6000_flush_cache_range) # high
        lui     $17,%hi(r6000_flush_tlb_all) # high
        lui     $2,%hi(r6000_flush_tlb_mm) # high
        lui     $3,%hi(r6000_flush_tlb_range) # high
        lui     $4,%hi(r6000_flush_tlb_page) # high
        lui     $5,%hi(r6000_load_pgd) # high
        lui     $6,%hi(r6000_pgd_init) # high
        lui     $7,%hi(r6000_update_mmu_cache) # high
        lui     $8,%hi(r6000_show_regs) # high
        lui     $9,%hi(r6000_add_wired_entry) # high
        lui     $10,%hi(r6000_user_mode) # high
[...]

Relocating the code generated from this source later on will not be
possible for ld.  As knows this and dies ungracefully.

I was able to track this down to the Haifa scheduler which seems to be
incompatible with the -msplit-addresses used for kernel compiles.  For
now I suggest to recompile egcs without the Haifa scheduler.  Egcs by
default doesn't enable the Haifa scheduler and there is a reason why.

This egcs 1.0.2 bug is a platform independent bug.  Since currently
egcs does not support -msplit-addresses for PIC code, that is all userland
this bug will only hit some low level stuff.

Alex or somebody else, could you make an update to the egcs package
with the haifa scheduler disabled?  Thanks!

  Ralf

---

From: [email-masked]
Date: Thu, 22 Oct 1998 02:44:08 +0200

On Tue, Oct 20, 1998 at 06:39:21PM -0700, David S. Miller wrote:

> Then why is this a supposed bug in Haifa?  It looks to me there is a
> problem with how %hi relocs are assosciated with %lo ones in binutils.

It's not necessarily a bug in Haida itself but it gets visible when Haifa
is enabled.  I haven't looked closely at the involved egcs code yet.

> The code you showed me looks perfectly legal.

For ECOFF and ELF, relocations against symbols are done in two parts, with
a hi16 relocation and a lo16 relocation.  Each relocation has only 16 bits of
space to store an addend and a carry may have to be propagated between
the two.  This means that in order for the linker to handle carries
correctly, it must be able to locate both the hi16 and the lo16 relocation.
Object files which don't contain any other information except the order in
the relocation table which could be used to find the hi16 / lo16 relocs which
belong together.

The code I showed cannot be represented in a ELF or ECOFF object such that
the linker still knows which hi16 and which lo16 relocations are associated
with each other.  Therefore it is not possible for the linker to correctly
do the hi16 relocations.  Btw, all MIPS assemblers I know of will warn or
even error about that fragment.

The ABI is quite strict in that aspect, it wants one lo16 per hi16 for the
same symbol.  Binutils relax that by allowing an arbitrary number of hi16
and one lo16 for the same symbol.

  Ralf