Subject: mips64 linker bug?

From: Lars Munch Christensen <[email-masked]>
Date: Sat, 21 Jul 2001 11:27:15 +0200

Hi All

I think I have found a linker bug!

I use the following cross compilers from sgi's ftp:

binutils-mips64-linux-2.9.5-3.i386.rpm
egcs-mips64-linux-1.1.2-4.i386.rpm
binutils-mips64el-linux-2.9.5-3.i386.rpm
egcs-mips64el-linux-1.1.2-4.i386.rpm

Anyway the bug is that static functions get linked wrongly.
Test program:
---------------------
/* This function has to be here to get the error */
int test1(void) {
	return 1;
}

static int test2(void) { /* <---- notice this static */
	return 2;
}

int main() {

	test2();
	return 1;
}

---------------------

Compile and link with:

mips64-linux-gcc -mcpu=r4600 -mabi=64 -mips3 -g -c -O2  -o main.o main.c
mips64-linux-ld -m elf64btsmip  -nostdlib -e main main.o -o main.elf

Now I see the bug where main calls test2:

Doing a 'mips64-linux-objdump -S test.elf' gives me:

main.elf:     file format elf64-bigmips

Disassembly of section .text:

00000000100000f0 <test1>:
        return 1;
    100000f0:   03e00008        jr      $ra
    100000f4:   24020001        li      $v0,1

00000000100000f8 <test2>:
}

static int test2(void) {
        return 2;
    100000f8:   03e00008        jr      $ra
    100000fc:   24020002        li      $v0,2

0000000010000100 <main>:
}

int main() {
    10000100:   67bdfff0        0x67bdfff0
    10000104:   ffbf0000        0xffbf0000

0000000010000108 <$LM6>:

        test2();
    10000108:   0c000044        jal     10000110 <$LM7> <-- 110 ????????????
    1000010c:   00000000        nop

0000000010000110 <$LM7>:
        return 1;
    10000110:   dfbf0000        0xdfbf0000
    10000114:   24020001        li      $v0,1
    10000118:   03e00008        jr      $ra
    1000011c:   67bd0010        0x67bd0010

When removing the static I get the correct address 100000f8 ?!?

Am I missing something. Please help me, I have spend 3 days
chasing this bug, until I figures out it was related to 
static functions.

btw why isn't everything disassembled?

Thanks
Lars Munch

---

From: Ralf Baechle <[email-masked]>
Date: Sat, 21 Jul 2001 17:23:09 +0200

On Sat, Jul 21, 2001 at 11:27:15AM +0200, Lars Munch Christensen wrote:

> Am I missing something.

Gas and ld of the published 64-bit binutils are entirely useless for 64-bit
code.  Various people are working on fixing that but that takes time,
especially the non-pic case is a bit hairy.

> btw why isn't everything disassembled?

Executive summary: because binutils is a stupid.  Technical answer, objdump
only disassembles MIPS I instructions by default.

  Ralf

---

From: Lars Munch Christensen <[email-masked]>
Date: Sat, 21 Jul 2001 18:17:33 +0200

> especially the non-pic case is a bit hairy.

Thanks...What should I do now? Change my code to mips32 or are there some
patches to binutils that I can use, to get it working?

Thanks for your help
Regards
Lars Munch

---

From: Ralf Baechle <[email-masked]>
Date: Sat, 21 Jul 2001 21:07:37 +0200

> patches to binutils that I can use, to get it working?

Depends on what you want to do?

  Ralf

---

From: Lars Munch Christensen <[email-masked]>
Date: Sun, 22 Jul 2001 11:39:23 +0200

> Depends on what you want to do?

I'm working on a very small, single address space, microkernel and I have
the MIPS Malta with a 5Kc CPU to develop it on. The 5Kc is compatible
with mips32 but I must admit, I really like to have my kernel
running 64bit :). Is there a working binutils for 64 bit code floating
around somewhere or should I stick with the mips32 stuff?

I tried the binutil from ftp://ftp.ds2.pg.gda.pl/pub/macro/SRPMS/ but
they where unable to compile with target mips64-linux.

Thanks
Lars Munch

---

From: Thiemo Seufer <[email-masked]>
Date: Sun, 22 Jul 2001 12:35:26 +0200

Lars Munch Christensen wrote:
> running 64bit :).

An Kernel with 64bit addresses is less compact and likely to run slower.
OTOH, a 64bit Kernel has certainly some hack value. :-)

> Is there a working binutils for 64 bit code floating

Using 32bit is surely the easier way to go.

You might try the toolchain I use for my mips64-linux development.
Be warned: It's barely good enough to compile a linux kernel, no
pic code and therefore no libc. You have to compile it yourself,
the source is available at
http://www.csv.ica.uni-stuttgart.de/homes/ths/linux-mips/

Have fun. :-)

Thiemo

---

From: "Kevin D. Kissell" <[email-masked]>
Date: Sun, 22 Jul 2001 13:02:21 +0200

> OTOH, a 64bit Kernel has certainly some hack value. :-)

Note that the 5Kc is one of the new generation of MIPS64 parts
that can enable 64-bit integer and floating point instructions without
requiring that 64-bit addressing also be enabled in the kernel.
Making Linux kernel support for this capability available is
one of the things that we're working on.  But it's not there yet.

            Kevin K.

---

From: Thiemo Seufer <[email-masked]>
Date: Sun, 22 Jul 2001 13:15:25 +0200

Kevin D. Kissell wrote:
[snip]
> requiring that 64-bit addressing also be enabled in the kernel.

Sorry, but I can't see what's new here. AFAICS this possibility existed
already in MIPS III.

> one of the things that we're working on.  But it's not there yet.

I know. :-)

Thiemo

---

From: "Kevin D. Kissell" <[email-masked]>
Date: Sun, 22 Jul 2001 13:44:37 +0200

> Sorry, but I can't see what's new here. AFAICS this possibility existed

Sorry if I wasn't clear.  It is only the newer parts that can enable the
use of the 64-bit instructions *in user mode* without also enabling
64-bit addressng.  It's true that MIPS III/IV parts provide access to
those instructions in kernel regardless of the state of the Status.KX
bit,  but in user mode they are only available if the Status.UX bit is set,
enabling 64-bit addressing.  MIPS64 CPU's have an additional
bit in the Status register (Bit 23, "PX") to enable 64-bit instructions
without enabling 64-bit addressing.

            Regards,

            Kevin K.

---

From: Ralf Baechle <[email-masked]>
Date: Sun, 22 Jul 2001 23:23:01 +0200

> they where unable to compile with target mips64-linux.

Afaik the mips64-linux binutils are the only one that more (or more less ;)
work for building a 64-bit kernel.  What we have to do to get around the
bugs and missing features is building a 64-bit kernel but passing -32 to
the assembler so we never use 64-bit ELF.  In the end we convert the
resulting 32-bit ELF executable into 64-ELF using objcopy.  That's about
as much as 64-bit binutils are usable for.  For details see
arch/mips64/Makefile.

  Ralf