Subject: Re: Problems generating shared library for MIPS using binutils-2.13...

From: "Steven J. Hill" <[email-masked]>
Date: Mon, 04 Nov 2002 08:49:43 -0600

Maciej W. Rozycki wrote:
> 
>>>Is every object or library mentioned on that line already marked as
>>>MIPS-2 by readelf?  Even crt*, libc*?
>>>
>>
>>I knew I was being stupid, crt* and libc* are mips1 *sigh*. Looks
>>like I have more work to do for my build system. Below is the verbose
>>output, but I think that's the problem for sure.
> 
> 
>  Hmm, that's strange as a single mips2 object among mips1 ones should make
> an executable/shared library be marked as mips2 and not mips1.  I wouldn't
> worry in the long run, though, as I think this should be fixed in the
> trunk as Richard Sandiford was working in these areas recently.  You might
> want to do a verification to be sure, though. 
> 
I tried the trunk and got the same thing. I have made some additional
progress. First, I used H.J.Lu's patch for the most part:

    http://sources.redhat.com/ml/binutils/2001-10/msg00526.html

Specifically the part:

-  elf_elfheader (abfd)->e_flags &= ~(EF_MIPS_ARCH | EF_MIPS_MACH);
-  elf_elfheader (abfd)->e_flags |= val;
+  if (isa != 0 && (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == 0)
+    {
+      elf_elfheader (abfd)->e_flags &= ~EF_MIPS_ARCH;
+      elf_elfheader (abfd)->e_flags |= isa;
+    }
+
+  if (cpu != 0)
+    {
+      elf_elfheader (abfd)->e_flags &= ~EF_MIPS_MACH;
+      elf_elfheader (abfd)->e_flags |= cpu;
+    }

So, now when I am building 'zlib', the object files get built with:

   mipsel-linux-gcc -march=r6000 -fPIC -O3 -DHAVE_UNISTD_H -DUSE_MMAP

and then shared object creation uses:

   mipsel-linux-gcc -shared -Wl,-A,r6000,-v,-soname,libz.so.1 \
     -march=r6000 -o libz.so.1.1.4 adler32.o compress.o crc32.o gzio.o \
     compr.o deflate.o trees.o zutil.o inflate.o infblock.o inftrees.o \
     infcodes.o infutil.o inffast.o

with the verbose output of:

collect2 version 3.2 (MIPSel GNU/Linux with ELF)
/opt/toolchains/uclibc/bin/../lib/gcc-lib/mipsel-linux/3.2/../../../../mipsel-linux/bin/ld 
--eh-frame-hdr -EL -shared -o libz.so.1.1.4 
/opt/toolchains/uclibc/bin/../lib/gcc-lib/mipsel-linux/3.2/../../../../mipsel-linux/lib/crti.o 
/opt/toolchains/uclibc/bin/../lib/gcc-lib/mipsel-linux/3.2/crtbeginS.o 
-L/opt/toolchains/uclibc/bin/../lib/gcc-lib/mipsel-linux/3.2 
-L/opt/toolchains/uclibc/bin/../lib/gcc-lib 
-L/opt/toolchains/uclibc-crosstools-1.0.0/lib/gcc-lib/mipsel-linux/3.2 
-L/opt/toolchains/uclibc/bin/../lib/gcc-lib/mipsel-linux/3.2/../../../../mipsel-linux/lib 
-L/opt/toolchains/uclibc-crosstools-1.0.0/lib/gcc-lib/mipsel-linux/3.2/../../../../mipsel-linux/lib 
-L/opt/toolchains/uclibc/bin/../lib/gcc-lib/mipsel-linux/3.2/../../.. -A 
r6000 -v -soname libz.so.1 adler32.o compress.o crc32.o gzio.o uncompr.o 
deflate.o trees.o zutil.o inflate.o infblock.o inftrees.o infcodes.o 
infutil.o inffast.o -lgcc -lc -lgcc 
/opt/toolchains/uclibc/bin/../lib/gcc-lib/mipsel-linux/3.2/crtendS.o 
/opt/toolchains/uclibc/bin/../lib/gcc-lib/mipsel-linux/3.2/../../../../mipsel-linux/lib/crtn.o

The 'crt*' files and my C runtime are compiled with 'mips1', but as
Maciej correctly states in his reply, the output binary should be
the highest ISA value when mixing differing ISA objects.

I'm convinced the linker completely ignores '-A' for MIPS. In the 
'_bfd_mips_elf_final_write_processing' function in 'bfd/elfxx-mips.c'
If I print out the EF_MIPS_ARCH flags for the input BFD descriptor. It
is properly set to 'MIPS2', but when the case statement in 
'_bfd_mips_elf_final_write_processing' is traversed, it
uses the R3000/default case which means that the target CPU architecture
didn't get put into the BFD descriptor. So, I instead changed the ISA
if statement above to be:

   if (((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) != isa) && (isa 
!= 0))
     {
       elf_elfheader (abfd)->e_flags &= ~EF_MIPS_ARCH;
       elf_elfheader (abfd)->e_flags |= isa;
     }

which then properly sets the ISA in the ELF header. My gut feeling
though is that we shouldn't have to do this as the target CPU
architecture should have been set properly for the incoming BFD.
Comments and suggestions welcome. Thanks.

-Steve

---

From: "H. J. Lu" <[email-masked]>
Date: Mon, 4 Nov 2002 07:02:33 -0800

> I'm convinced the linker completely ignores '-A' for MIPS. In the 

-A is for assembler, not linker.

H.J.

---

From: "Steven J. Hill" <[email-masked]>
Date: Mon, 04 Nov 2002 10:57:11 -0600

> -A is for assembler, not linker.
Fine. Still, that doesn't solve the problem, or what I perceive to
be a problem. I'll submit my patch and watch it be ignored or for
someone to say something.

-Steve

---

From: "H. J. Lu" <[email-masked]>
Date: Mon, 4 Nov 2002 09:11:19 -0800

> someone to say something.

The Linux binutils works fine for me.

H.J.

---

From: "Steven J. Hill" <[email-masked]>
Date: Mon, 04 Nov 2002 11:16:18 -0600

> The Linux binutils works fine for me.
Really? Good. Go get this tarball:

     ftp://ftp.realitydiluted.com/Linux/MIPS/zlib-1.1.4-mips-prob.tar.bz2

make sure your tools are in your path and just do 'make' and see
what ISA your 'libz.so.1.1.4' is. Thanks.

-Steve

---

From: "H. J. Lu" <[email-masked]>
Date: Mon, 4 Nov 2002 09:24:13 -0800

> what ISA your 'libz.so.1.1.4' is. Thanks.

# readelf -h libz.so.1.1.4
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           MIPS R3000
  Version:                           0x1
  Entry point address:               0x14d0
  Start of program headers:          52 (bytes into file)
  Start of section headers:          66196 (bytes into file)
  Flags:                             0x10000003, noreorder, pic, mips2
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         4
  Size of section headers:           40 (bytes)
  Number of section headers:         25
  Section header string table index: 22

H.J.

---

From: Richard Sandiford <[email-masked]>
Date: 05 Nov 2002 15:19:04 +0000

"Steven J. Hill" <[email-masked]> writes:
> In the '_bfd_mips_elf_final_write_processing' function in 'bfd/elfxx-mips.c'
> didn't get put into the BFD descriptor.

Is it related to this?

    <http://sources.redhat.com/ml/binutils/2002-10/msg00248.html>

(In the message body, I accidentally copied the code after
the patch rather than before.  Sorry about that.)

Anyway, that patch won't solve your problem, but the issue
seems to be the same: _bfd_mips_elf_merge_private_bfd_data()
merges the EF_MIPS_ARCH and EF_MIPS_MACH bits, but
_bfd_mips_elf_final_write_processing() overwrites them
based on the BFD mach.

Personally, I think _bfd_mips_elf_final_write_processing()
is doing the right thing.  Surely we ought to be able to
set EF_MIPS_ARCH and EF_MIPS_MACH based on the value of
bfd_get_mach?

I wonder whether _bfd_mips_elf_merge_private_bfd_data() should
be checking for compatibility based on the BFD machs rather
than the header flags.  It seems a bit odd that we check the
ISA level and "machine" separately.

In other words, replace:

  /* Compare the ISA's.  */
  if ((new_flags & (EF_MIPS_ARCH | EF_MIPS_MACH))
      != (old_flags & (EF_MIPS_ARCH | EF_MIPS_MACH)))
    {
      ...
    }

with code that checks bfd_get_mach (ibfd) against bfd_get_mach (obfd).
If ibfd's architecture is an extension of obfd's, copy it to obfd.

Richard

---

From: "H. J. Lu" <[email-masked]>
Date: Tue, 5 Nov 2002 09:15:00 -0800

> If ibfd's architecture is an extension of obfd's, copy it to obfd.

The FSF binutils has never been right. I have fixed it in my Linux
binutils. See my followups on this thread.

H.J.

---

From: Daniel Jacobowitz <[email-masked]>
Date: Tue, 5 Nov 2002 12:26:27 -0500

> set EF_MIPS_ARCH and EF_MIPS_MACH based on the value of

Surely we can't...  Remember what EF_MIPS_ARCH says: it's actually what
we call ISA level elsewhere!  I just spent a day beating on this and
settled for untagged instead of correctly-tagged binaries; I was trying
to built SB-1 binaries (that's EF_MIPS_MACH of EF_MIPS_MACH_SB1) for a
32-bit userland (that's EF_MIPS_ARCH_2).  Not just E_MIPS_ABI_O32, but
actually -mips2 code.

We can't infer that from the result of bfd_get_mach, I don't think! 
You're moving in the wrong direction.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

---

From: "H. J. Lu" <[email-masked]>
Date: Tue, 5 Nov 2002 09:33:33 -0800

> 32-bit userland (that's EF_MIPS_ARCH_2).  Not just E_MIPS_ABI_O32, but

Have you tried my Linux binutils? If you follow the release note, it
may just work.

H.J.

---

From: Richard Sandiford <[email-masked]>
Date: 05 Nov 2002 18:17:55 +0000

> 32-bit userland (that's EF_MIPS_ARCH_2).  Not just E_MIPS_ABI_O32, but

I'm not sure what you want from a MIPS II SB-1 binary, though.
Does it mean that you can't use instructions that are defined
in the MIPS32 ISA but not the MIPS II one?  But you can use
the SB-1-specific instructions (i.e. those not defined in the
MIPS64 ISA)?

Richard

---

From: Daniel Jacobowitz <[email-masked]>
Date: Tue, 5 Nov 2002 13:32:20 -0500

> the SB-1-specific instructions (i.e. those not defined in the

Maybe I'm barking up the wrong tree... yes, it seems that I am....

The principal thing is that I want O32 code.  You can't use a higher
ISA level than MIPS2 and still use O32, as far as I understand. And
this setup has a 32-bit kernel, so using MIPS3/4/64 instructions in
userspace is a real losing proposition.

I obviously want -mtune=sb1.  So probably I should just be using
-mtune=sb1 -mips2.  And hack the GENERATE_BRANCHLIKELY test to honor
-mtune.  Blech, I wish these options were less confusing!

---

From: Eric Christopher <[email-masked]>
Date: 05 Nov 2002 11:21:37 -0800

> userspace is a real losing proposition.

You should be able to do -mips32 -mabi=32, however, I wouldn't bet on
this working atm :)

> -mtune.  Blech, I wish these options were less confusing!

:) Good idea on the GENERATE_BRANCHLIKELY. I think it probably should be
dependent on mtune anyhow.

-eric

-- 
Yeah, I used to play basketball...