Hi, I wonder what is the right way to target an old glibc? I have a machine which is up to date (glibc 2.32 and clang+lld 10.0.1). So far I've been able to target older glibc by having a C file containing: __asm__(".symver powf,powf at GLIBC_2.2.5"); __asm__(".symver expf,expf at GLIBC_2.2.5"); __asm__(".symver exp2f,exp2f at GLIBC_2.2.5"); __asm__(".symver log2f,log2f at GLIBC_2.2.5"); __asm__(".symver logf,logf at GLIBC_2.2.5"); __asm__(".symver log,log at GLIBC_2.2.5"); __asm__(".symver log2,log2 at GLIBC_2.2.5"); __asm__(".symver exp,exp at GLIBC_2.2.5"); __asm__(".symver exp2,exp2 at GLIBC_2.2.5"); __asm__(".symver pow,pow at GLIBC_2.2.5"); But after updating clang and re-creating the cmake build directory it does not work anymore and I have dependencies toward glibc 2.29: nm -D /home/abique/.u-he/Zebra2/Zebra2.64.so | grep GLIBC.*29 U exp@@GLIBC_2.29 U exp2@@GLIBC_2.29 U log@@GLIBC_2.29 U pow@@GLIBC_2.29 At first I thought that it was due to LTO, but even after disabling LTO the problem still occurs. How to solve it? Is there a better approach to this problem? Maybe lld never supported it, and now it is using lld to link instead of the GNU linker? Anyway, I'd like to solve this with the LLVM tools while full LTO is enabled, which requires lld right? Many thanks. Regards, Alexandre Bique
On 2020-10-28, Alexandre Bique via llvm-dev wrote:>Hi, > >I wonder what is the right way to target an old glibc? > >I have a machine which is up to date (glibc 2.32 and clang+lld 10.0.1). > >So far I've been able to target older glibc by having a C file containing: > >__asm__(".symver powf,powf at GLIBC_2.2.5"); >__asm__(".symver expf,expf at GLIBC_2.2.5"); >__asm__(".symver exp2f,exp2f at GLIBC_2.2.5"); >__asm__(".symver log2f,log2f at GLIBC_2.2.5"); >__asm__(".symver logf,logf at GLIBC_2.2.5"); > >__asm__(".symver log,log at GLIBC_2.2.5"); >__asm__(".symver log2,log2 at GLIBC_2.2.5"); >__asm__(".symver exp,exp at GLIBC_2.2.5"); >__asm__(".symver exp2,exp2 at GLIBC_2.2.5"); >__asm__(".symver pow,pow at GLIBC_2.2.5");This works. This approach is used by https://github.com/wheybags/glibc_version_header>But after updating clang and re-creating the cmake build directory it >does not work anymore and I have dependencies toward glibc 2.29: > >nm -D /home/abique/.u-he/Zebra2/Zebra2.64.so | grep GLIBC.*29 > U exp@@GLIBC_2.29 > U exp2@@GLIBC_2.29 > U log@@GLIBC_2.29 > U pow@@GLIBC_2.29I reported a display problem. top-of-trunk binutils will display undefined versioned symbols as @ instead of @@.>At first I thought that it was due to LTO, but even after disabling >LTO the problem still occurs. > >How to solve it? >Is there a better approach to this problem? > >Maybe lld never supported it, and now it is using lld to link instead >of the GNU linker?LLD has good support for version symbols (you need a commit after https://reviews.llvm.org/D80059 (in 11.0.0, but not in 10.x)). There is insufficient information to form a solution. You may add -Wl,-y,exp,-y,exp at GLIBC_2.29,-y,exp at GLIBC_2.2.5 to figure out why exp at GLIBC_2.29 instead of exp at GLIBC_2.2.5 is picked.>Anyway, I'd like to solve this with the LLVM tools while full LTO is >enabled, which requires lld right? > >Many thanks. > >Regards, >Alexandre Bique >_______________________________________________ >LLVM Developers mailing list >llvm-dev at lists.llvm.org >https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
On Wed, Oct 28, 2020 at 6:07 PM Fangrui Song <maskray at google.com> wrote:> > On 2020-10-28, Alexandre Bique via llvm-dev wrote: > >Hi, > > > >I wonder what is the right way to target an old glibc? > > > >I have a machine which is up to date (glibc 2.32 and clang+lld 10.0.1). > > > >So far I've been able to target older glibc by having a C file containing: > > > >__asm__(".symver powf,powf at GLIBC_2.2.5"); > >__asm__(".symver expf,expf at GLIBC_2.2.5"); > >__asm__(".symver exp2f,exp2f at GLIBC_2.2.5"); > >__asm__(".symver log2f,log2f at GLIBC_2.2.5"); > >__asm__(".symver logf,logf at GLIBC_2.2.5"); > > > >__asm__(".symver log,log at GLIBC_2.2.5"); > >__asm__(".symver log2,log2 at GLIBC_2.2.5"); > >__asm__(".symver exp,exp at GLIBC_2.2.5"); > >__asm__(".symver exp2,exp2 at GLIBC_2.2.5"); > >__asm__(".symver pow,pow at GLIBC_2.2.5"); > > This works. This approach is used by https://github.com/wheybags/glibc_version_headerThank you, that is something useful!> >But after updating clang and re-creating the cmake build directory it > >does not work anymore and I have dependencies toward glibc 2.29: > > > >nm -D /home/abique/.u-he/Zebra2/Zebra2.64.so | grep GLIBC.*29 > > U exp@@GLIBC_2.29 > > U exp2@@GLIBC_2.29 > > U log@@GLIBC_2.29 > > U pow@@GLIBC_2.29 > > I reported a display problem. top-of-trunk binutils will display > undefined versioned symbols as @ instead of @@.Thank you, I wondered why there were two @.> >At first I thought that it was due to LTO, but even after disabling > >LTO the problem still occurs. > > > >How to solve it? > >Is there a better approach to this problem? > > > >Maybe lld never supported it, and now it is using lld to link instead > >of the GNU linker? > > LLD has good support for version symbols (you need a commit after https://reviews.llvm.org/D80059 (in 11.0.0, but not in 10.x)).I'm using Archlinux, and llvm 11 is in staging, I'll see if I can install it.> There is insufficient information to form a solution. > You may add -Wl,-y,exp,-y,exp at GLIBC_2.29,-y,exp at GLIBC_2.2.5 to figure > out why exp at GLIBC_2.29 instead of exp at GLIBC_2.2.5 is picked.Thank you very much. I'll try first with llvm 11 and if it does not work, I'll come back with more information. Regards, Alexandre
On Wed, Oct 28, 2020 at 9:54 AM Alexandre Bique via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Hi, > > I wonder what is the right way to target an old glibc? >The correct way is to compile against a sysroot which has an old glibc (both headers and libraries!) installed in it, rather than the new glibc. Anything else you try -- such as everything being recommended in the rest of the thread -- is an unsupportable hack, and should not be done. Possibly you can get it to work, for some particular sets of glibc versions, but there can be no guarantee. (Also, this isn't really a llvm question, it's a glibc question). -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20201111/ea74eba6/attachment.html>
On Wed, Nov 11, 2020 at 10:04 PM James Y Knight <jyknight at google.com> wrote:> The correct way is to compile against a sysroot which has an old glibc (both headers and libraries!) installed in it, rather than the new glibc. > > Anything else you try -- such as everything being recommended in the rest of the thread -- is an unsupportable hack, and should not be done. Possibly you can get it to work, for some particular sets of glibc versions, but there can be no guarantee. (Also, this isn't really a llvm question, it's a glibc question).Following your advice, I've tried to prepare a sysroot with various approaches: - debootstrap ubuntu xenial and use --sysroot pointing to that chroot; it did not work because of absolute path and symbolic link using absolute path. And if I were to chroot in it, it would mean that I have to replicate all the tools and their configuration (jenkins, ...) and I'd need to do more work to get a recent clang. - use the oldest freedesktop sdk sysroot from flatpak, yet it did not work for the same reason (absolute path and absolute symlink) - compiling and old glibc (they don't build because -Werror catches more problems with recent compilers than they did at the time of gcc 5) - now I'm about to use crosstool-ng to prepare a sysroot, but I'm afraid that I might have other surprises as it goes beyond providing a libc. You're correct it is now going beyond the scope of llvm-dev, so I'll start a discussion in libc-help. Yet I think it would be great to be able to build using a modern OS with the latest tools and target and older OS. It is not a crazy request isn't it? Thank you very much, Alexandre