Problems generating shared library for MIPS using binutils-2.13...
Greetings.
I'm doing something stupid here, so please help me out. I am trying to create a shared library with gcc passing parameters to the linker and it is not working.
I compiled all the object files with '-mips2' and then I attempt to create the shared library with:
mipsel-linux-gcc -shared -Wl,-Amips2,-soname,libz.so.1 \
-o libz.so.1.1.4 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.oThe object files are all mips2, but the generated '.so' object is mips1?! What am I not understanding? I am using binutils-2.13, gcc-3.2 and uClibc-0.9.15. The use of uClibc is not the problem.
-Steve
Quoted 9 lines · Steven J. Hill
Greetings.
I'm doing something stupid here, so please help me out. I am trying to create a shared library with gcc passing parameters to the linker and it is not working.
I compiled all the object files with '-mips2' and then I attempt to create the shared library with:
Quoted 8 lines
mipsel-linux-gcc -shared -Wl,-Amips2,-soname,libz.so.1 \ -o libz.so.1.1.4 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.oThe object files are all mips2, but the generated '.so' object is mips1?! What am I not understanding? I am using binutils-2.13, gcc-3.2 and uClibc-0.9.15. The use of uClibc is not the problem.
More information:
Add -Wl,-v and give us the linker command line.
Is every object or library mentioned on that line already marked as MIPS-2 by readelf? Even crt*, libc*?
Signature · 2 lines
Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer
Quoted 8 lines · Daniel Jacobowitz
More information:
Add -Wl,-v and give us the linker command line.
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.
-Steve
mipsel-linux-gcc -shared -Wl,-v,-Amips2,-soname,libz.so.1 -o libz.so.1.1.4 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
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/../../.. -v -Amips2 -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 GNU ld version 2.13
Quoted 6 lines · Steven J. Hill
Quoted 3 lines
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.
Signature · 3 lines
+ Maciej W. Rozycki, Technical University of Gdansk, Poland + +--------------------------------------------------------------+ + e-mail: [email protected], PGP key available +
Quoted 10 lines · Maciej W. Rozycki
Quoted 8 lines
Quoted 4 lines
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.
Quoted 6 lines
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.owith 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
Quoted 2 lines · Steven J. Hill
I'm convinced the linker completely ignores '-A' for MIPS. In the
-A is for assembler, not linker.
H.J.
Quoted 6 lines · H. J. Lu
Quoted 2 lines
I'm convinced the linker completely ignores '-A' for MIPS. In the
-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
Quoted 10 lines · Steven J. Hill
Quoted 6 lines · H. J. Lu
Quoted 2 lines
I'm convinced the linker completely ignores '-A' for MIPS. In the
-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.
The Linux binutils works fine for me.
H.J.
Quoted 8 lines · H. J. Lu
Quoted 4 lines
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.
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
Quoted 7 lines · Steven J. Hill
Quoted 6 lines · H. J. Lu
Quoted 4 lines
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.
Quoted 9 lines
Quoted 2 lines
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.bz2make sure your tools are in your path and just do 'make' and see 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.
Quoted 6 lines · Steven J. Hill
In the '
_bfd_mips_elf_final_write_processing' function in 'bfd/elfxx-mips.c' If I print out theEF_MIPS_ARCHflags 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.
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
Quoted 40 lines · Richard Sandiford
Quoted 6 lines · Steven J. Hill
In the '
_bfd_mips_elf_final_write_processing' function in 'bfd/elfxx-mips.c' If I print out theEF_MIPS_ARCHflags 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.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 theEF_MIPS_ARCHandEF_MIPS_MACHbits, 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 setEF_MIPS_ARCHandEF_MIPS_MACHbased on the value ofbfd_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))) { ... }
Quoted 2 lines
with code that checks
bfd_get_mach(ibfd) againstbfd_get_mach(obfd). 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.
Quoted 21 lines · Richard Sandiford
Quoted 6 lines · Steven J. Hill
In the '
_bfd_mips_elf_final_write_processing' function in 'bfd/elfxx-mips.c' If I print out theEF_MIPS_ARCHflags 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.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 theEF_MIPS_ARCHandEF_MIPS_MACHbits, but_bfd_mips_elf_final_write_processing()overwrites them based on the BFD mach.
Quoted 4 lines
Personally, I think
_bfd_mips_elf_final_write_processing()is doing the right thing. Surely we ought to be able to setEF_MIPS_ARCHandEF_MIPS_MACHbased on the value ofbfd_get_mach?
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.
Signature · 2 lines
Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer
Quoted 8 lines · Daniel Jacobowitz
Surely we can't... Remember what
EF_MIPS_ARCHsays: 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'sEF_MIPS_MACHofEF_MIPS_MACH_SB1) for a 32-bit userland (that'sEF_MIPS_ARCH_2). Not justE_MIPS_ABI_O32, but actually -mips2 code.
Have you tried my Linux binutils? If you follow the release note, it may just work.
H.J.
Quoted 6 lines · Daniel Jacobowitz
Surely we can't... Remember what
EF_MIPS_ARCHsays: 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'sEF_MIPS_MACHofEF_MIPS_MACH_SB1) for a 32-bit userland (that'sEF_MIPS_ARCH_2). Not justE_MIPS_ABI_O32, but actually -mips2 code.
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
Quoted 8 lines · Richard Sandiford
Quoted 6 lines · Daniel Jacobowitz
Surely we can't... Remember what
EF_MIPS_ARCHsays: 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'sEF_MIPS_MACHofEF_MIPS_MACH_SB1) for a 32-bit userland (that'sEF_MIPS_ARCH_2). Not justE_MIPS_ABI_O32, but actually -mips2 code.
Quoted 5 lines
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)?
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!
Signature · 2 lines
Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer
Quoted 6 lines
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.
You should be able to do -mips32 -mabi=32, however, I wouldn't bet on this working atm :)
Review
Quoted 4 lines
I obviously want -mtune=sb1. So probably I should just be using
(quoted diff) +0
-2-mtune=sb1 -mips2. And hack the GENERATE_BRANCHLIKELY test to honor -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
Signature · 1 line
Yeah, I used to play basketball...
Quoted 9 lines · Steven J. Hill
Greetings.
I'm doing something stupid here, so please help me out. I am trying to create a shared library with gcc passing parameters to the linker and it is not working.
I compiled all the object files with '-mips2' and then I attempt to create the shared library with:
Quoted 9 lines
mipsel-linux-gcc -shared -Wl,-Amips2,-soname,libz.so.1 \ -o libz.so.1.1.4 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.oThe object files are all mips2, but the generated '.so' object is mips1?! What am I not understanding? I am using binutils-2.13, gcc-3.2 and uClibc-0.9.15. The use of uClibc is not the problem.
That is a bug in the FSF binutils. I believe I fixed it in my Linux binutils:
http://sources.redhat.com/ml/binutils/2001-10/msg00526.html
Please try my Linux binutils.
H.J.