From mboxrd@z Thu Jan 1 00:00:00 1970 From: hjl@lucon.org (H.J. Lu) To: ian@cygnus.com (Ian Lance Taylor) Cc: gas2@cygnus.com, libc-hacker@cygnus.com Subject: Re: Has anyone looked at ELF 4.1? Date: Sun, 16 Aug 1998 19:30:00 -0000 Message-id: References: <199808170128.VAA23677@subrogation.cygnus.com> X-SW-Source: 1998/msg00207.html > > From: hjl@lucon.org (H.J. Lu) > Date: Sun, 16 Aug 1998 17:42:55 -0700 (PDT) > > > The purpose of EI_OSABI and EI_ABIVERSION is to tag the OS and ABI. > > I think we should register ELFOSABI_LINUX and define it as 1. It may > > make many things easier for us. Right now, after I upgrade from > > glibc 2.0 to 2.1, groff (man) no longer works since the C++ ABI in > > glibc is changed. > > > > This should work anyhow, using the mechanisms we already have. I > > believe it would be a mistake to attempt to characterize library > > versions using EI_ABIVERSION. > > > > How precisely would you use ELFOSABI_LINUX to fix this problem? > > The problem with groff is the symbols in libstdc++ are not versioned. > The result is the new stdin/stdout/stderr defined in libstdc++ have > the linkage for the old stdin/stdout/stderr. I don't know how hard > to add symbol versioning to libstdc++. With more and more commercial > softwares available for Linux while glibc 2.1 is still in beta, the > 100% backward binary compatibility is a major concern. I'd like to > address with the new ELF specs. > > You don't have to use symbol versioning. You can just change the name > of the library in the usual ELF way. That is easy, and it prevents > any versioning problems due to library code. # ldd /usr/bin/groff libstdc++.so.2.8 => /usr/lib/libstdc++.so.2.8 (0x40007000) libm.so.6 => /lib/libm.so.6 (0x4004c000) libc.so.6 => /lib/libc.so.6 (0x40065000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000) The problem is /usr/lib/libstdc++.so.2.8 was compiled again glibc 2.0.x. When running on a glibc 2.1 machine, /lib/libc.so.6 is glibc 2.1, which supports the same C ABI in glibc 2.0 using the symbol versioning. But glibc 2.1 has a different C++ ABI. Please keep in mind that libio in glibc has 2 ABIs, one for C and the other for C++. > > If groff once worked, and then broke, then it sounds as though > somebody must have made an incompatible change to the libstdc++ > library interface. Anybody who makes an incompatible change must > change the library version number. Using the new ELF specs won't save > us from that sort of failure; it is equivalent to failing to increase > the version number in the ELF specs. The problem is the incompatible C++ ABIs in libio between glibc 2.0 and glibc 2.1. > > What do the new ELF specs give us that we don't get from symbol > versioning and changing library names? We didn't change the library name of libc since the C ABI is ok. The problem is the C++ ABI in libc. It is very unique to Linux since we use the same code in libio for both libc and libstdc++. > > May I suggest: > > 1. Add switchs to ld to set EI_OSABI and EI_ABIVERSION. > 2. For Linux, set EI_ABIVERSION with C ABI and C++ ABI. > > EI_ABIVERSION = (0xf & C_ABI) | (0xf0 & C++_ABI) > > What precisely do you mean here by C_ABI and C++_ABI? You presumably > do not mean the version of the library, because there is no need to > record that. No. I mean the ABI version, like #ifdef glibc 2.0 #define CXX_ABI 0 #define C_ABI 0 #elif defined glibc 2.1 #define CXX_ABI 1 #define C_ABI 0 #endif > > Four bits only gives you sixteen versions, which is not a lot. I think 16 is more than enough. We may want 3 bits for C++ and 5 bits for C. > > 3. ld sets EI_OSABI depending on target if it is not set at the command > line. > > How does ld determine EI_OSABI? Linker script? We already pass "-dynamic-linker /lib/ld-linux.so.2" to ld for Linux. We can pass another one if necessary. > > 4. ld sets EI_ABIVERSION depending on EI_ABIVERSION in the shared > library used to build an ELF binary if it is not set at the command > line. > > This seems pointless. The library version number is already recorded > in the DT_SONAME entry. If it isn't, then where is it, and how does I am talking about C/C++ ABI version. soname is mainly for C programs which don't care about the C++ ABI. > ld determine EI_ABIVERSION? When we build a dynamic ELF object on Linux, we should always pass -lc to it. ld can get EI_ABIVERSION from libc.so. > > 5. The dynamic linker will check both EI_OSABI and EI_ABIVERSION when > choosing which shared library to load. With that, we can have both 2 > libc.so.6 with different EI_ABIVERSIONs in different directories. > > Why would we want such a thing? > > How precisely will this approach help with groff? > > I think we have a problem with using multiple libraries which are > linked against different versions of libc. However, I don't see how > EI_OSABI and EI_ABIVERSION can help with that. > > We already have two library versioning schemes: DT_SONAME, and symbol > versioning. Why do we need a third? What deficiency in the existing > schemes does it address? > We may want to load a different libc.so.6 depending on the C++/C ABI version. For groff, on glibc 2.1, we want # ldd /usr/bin/groff libstdc++.so.2.8 => /usr/lib/libstdc++.so.2.8 (0x40007000) libm.so.6 => /usr/glibc-2.0/lib/libm.so.6 (0x4004c000) libc.so.6 => /usr/glibc-2.0/libc.so.6 (0x40065000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000) -- H.J. Lu (hjl@gnu.org)