Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 707332 - dev-libs/gmp : USE=static-libs should set --with-pic
Summary: dev-libs/gmp : USE=static-libs should set --with-pic
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Current packages (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Gentoo Toolchain Maintainers
URL: https://www.openwall.com/lists/musl/2...
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-01-29 23:01 UTC by Andrew Aladjev
Modified: 2020-01-31 08:00 UTC (History)
2 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
emerge glibc info (emerge-glibc-info.log,12.84 KB, text/x-log)
2020-01-30 11:51 UTC, Andrew Aladjev
Details
emerge musl info (emerge-musl-info.log,12.97 KB, text/x-log)
2020-01-30 11:51 UTC, Andrew Aladjev
Details
emerge gmp gcc info glibc (emerge-gmp-gcc-info.glibc.log,13.86 KB, text/x-log)
2020-01-30 21:06 UTC, Andrew Aladjev
Details
emerge gmp gcc info musl (emerge-gmp-gcc-info.musl.log,13.98 KB, text/x-log)
2020-01-30 21:06 UTC, Andrew Aladjev
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Aladjev 2020-01-29 23:01:51 UTC
Hello. GMP is popular library with its own --enable-assembly use. Unfortunately default configuration options allows GMP to provide PIC-incompatible static library.

This issue is deadly important for musl. See link https://www.openwall.com/lists/musl/2020/01/29/12. Musl returns segfault for applications trying to do static link against PIC-incompatible static library. Glibc somehow ignores it, but it is broken in the same way. Workarounds like "-fno-pie" and "-static" doesn't looks very good. BTW these workarounds are not compatible with some sanitizers.

This issue is very popular. You can find tons of information in google by searching about '--disable-assembly static "gmp"'.

GMP authors provided a right solution for this issue silently. We need just to pass "--with-pic" configuration option. Both v6.1 and 6.2 support this option.

So please add the following line '$(usex static-libs "--with-pic" "")' into ebuilds:

ECONF_SOURCE="${S}" econf \
  --localstatedir="${EPREFIX}"/var/state/gmp \
  --enable-shared \
  $(use_enable asm assembly) \
  $(use_enable cxx) \
  $(use_enable static-libs static) \
  $(usex static-libs "--with-pic" "")

Thank you.

Reproducible: Always
Comment 1 Sergei Trofimovich (RETIRED) gentoo-dev 2020-01-30 09:32:39 UTC
Please provide an example of a tool/test that breaks in gentoo.
Comment 2 Andrew Aladjev 2020-01-30 10:35:36 UTC
We can use the following test:

echo -e \
  "#include <gmp.h>\n void main () { mpz_t a; mpz_init(a); mpz_mul(a, a, a); mpz_clear(a); }" > main.c && \
  gcc main.c /usr/lib64/libgmp.a -o main && ./main

/usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../x86_64-pc-linux-gnu/bin/ld: /usr/lib64/libgmp.a(bdiv_q_1.o): warning: relocation against `__gmp_binvert_limb_table' in read-only section `.text'
/usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../x86_64-pc-linux-gnu/bin/ld: warning: creating a DT_TEXTREL in object

This warning is deadly for musl system, segfault. Glibc somehow is working, but binary is broken too. Please see here https://www.openwall.com/lists/musl/2020/01/29/19. Developers said that it will better to add some link flag that throws error instead of warning. But I can't find this flag: "-Wl,-z,relro,-z,now" doesn't make error from warning.
Comment 3 Sergei Trofimovich (RETIRED) gentoo-dev 2020-01-30 11:19:55 UTC
(In reply to Andrew Aladjev from comment #2)
> We can use the following test:
> 
> echo -e \
>   "#include <gmp.h>\n void main () { mpz_t a; mpz_init(a); mpz_mul(a, a, a);
> mpz_clear(a); }" > main.c && \
>   gcc main.c /usr/lib64/libgmp.a -o main && ./main
> 
> /usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../x86_64-pc-linux-gnu/bin/
> ld: /usr/lib64/libgmp.a(bdiv_q_1.o): warning: relocation against
> `__gmp_binvert_limb_table' in read-only section `.text'
> /usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../x86_64-pc-linux-gnu/bin/
> ld: warning: creating a DT_TEXTREL in object
> 
> This warning is deadly for musl system, segfault.

please provide emerge '--info gcc gmp' from systems where you see the crash.

It means musl does not support TEXTRELs. It's not a gmp-specific but a wider problem. Instead of SIGSEGVing if feasible musl should report a nice error to build binaries without TEXTRELs.

We can add USE=pic to dev-libs/gmp to workaround the musl deficiency.

> Glibc somehow is working

glibc just performs TEXTREl relocation.

> but binary is broken too.

What does it mean?

> Please see here
> https://www.openwall.com/lists/musl/2020/01/29/19. Developers said that it
> will better to add some link flag that throws error instead of warning. But
> I can't find this flag: "-Wl,-z,relro,-z,now" doesn't make error from
> warning.

I think you are looking for -Wl,-z,text option (see 'man ld').
Comment 4 Andrew Aladjev 2020-01-30 11:51:02 UTC
> please provide emerge '--info gcc gmp' from systems where you see the crash.

Yes, I've uploaded docker images: "puchuu/test_x86_64-pc-linux-gnu" and "puchuu/test_x86_64-gentoo-linux-musl", everybody can reproduce this bug. GMP version is 6.1.2-r1. I will attach emerge info.

> It means musl does not support TEXTRELs. It's not a gmp-specific but a wider problem. Instead of SIGSEGVing if feasible musl should report a nice error to build binaries without TEXTRELs.

Yes, and not only TEXTREL. Please see this link https://github.com/ifduyue/musl/blob/master/ldso/dynlink.c#L391-L433. Every relocaton type that tryies to write into "reloc_addr" may be broken, because address may be readonly. I will try later to create a patch for musl that returns some reasonable error message like "not supported relocation in readonly mode" before crash.

> We can add USE=pic to dev-libs/gmp to workaround the musl deficiency.

This will be a good solution, thank you.

> glibc just performs TEXTREl relocation.

This relocation is a part a readonly segment, glibc may remap this segment as writable, maybe just ignores it. I will investigate glibc source later about this question.

> I think you are looking for -Wl,-z,text option (see 'man ld').

Yes, that's it. I've receved "read-only segment has dynamic relocations" error. It may be good to include this flag into any musl profile.
Comment 5 Andrew Aladjev 2020-01-30 11:51:31 UTC
Created attachment 608594 [details]
emerge glibc info
Comment 6 Andrew Aladjev 2020-01-30 11:51:50 UTC
Created attachment 608596 [details]
emerge musl info
Comment 7 Sergei Trofimovich (RETIRED) gentoo-dev 2020-01-30 14:21:06 UTC
(In reply to Andrew Aladjev from comment #2)
> We can use the following test:
> 
> echo -e \
>   "#include <gmp.h>\n void main () { mpz_t a; mpz_init(a); mpz_mul(a, a, a);
> mpz_clear(a); }" > main.c && \
>   gcc main.c /usr/lib64/libgmp.a -o main && ./main
> 
> /usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../x86_64-pc-linux-gnu/bin/
> ld: /usr/lib64/libgmp.a(bdiv_q_1.o): warning: relocation against
> `__gmp_binvert_limb_table' in read-only section `.text'
> /usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../x86_64-pc-linux-gnu/bin/
> ld: warning: creating a DT_TEXTREL in object

This warning does not happen for me. Your toolchain must be different enough from mine.

(In reply to Andrew Aladjev from comment #5)
> Created attachment 608594 [details]
> emerge glibc info

1. Please provide 'emerge --info sys-devel/gcc dev-libs/gmp'. I'd like to see USE-flags gcc was built with and gcc/gmp versions. gcc somehow generates code it's not supposed to.
2. Please post 'gcc -v' output to make sure.

(In reply to Andrew Aladjev from comment #6)
> Created attachment 608596 [details]
> emerge musl info

Same here. Please attach the same [1.] and [2.] above.

(In reply to Andrew Aladjev from comment #4)
> > I think you are looking for -Wl,-z,text option (see 'man ld').
> 
> Yes, that's it. I've receved "read-only segment has dynamic relocations"
> error. It may be good to include this flag into any musl profile.

I suggest filing a separate bug against musl@ to consider it.
Comment 8 Andrew Aladjev 2020-01-30 21:06:05 UTC
Created attachment 609398 [details]
emerge gmp gcc info glibc
Comment 9 Andrew Aladjev 2020-01-30 21:06:21 UTC
Created attachment 609400 [details]
emerge gmp gcc info musl
Comment 10 Andrew Aladjev 2020-01-30 21:08:24 UTC
Attached emerge -v --info gmp gcc for each container. My containers are super basic, it was compiled with default uses from profiles.
Comment 11 Sergei Trofimovich (RETIRED) gentoo-dev 2020-01-30 21:50:32 UTC
(In reply to Andrew Aladjev from comment #8)
> Created attachment 609398 [details]
> emerge gmp gcc info glibc

I don't see how you can get /usr/lib64/libgmp.a with your gmp USE="-static-libs":

> dev-libs/gmp-6.1.2-r1::gentoo was built with the following:
> USE="asm cxx -doc -static-libs"

Are you sure /usr/lib64/libgmp.a is up to date and not some ancient leftover?

(In reply to Andrew Aladjev from comment #10)
> Attached emerge -v --info gmp gcc for each container. My containers are
> super basic, it was compiled with default uses from profiles.

Same here:

> dev-libs/gmp-6.1.2-r1::gentoo was built with the following:
> USE="asm cxx -doc -static-libs"
Comment 12 Andrew Aladjev 2020-01-30 22:08:15 UTC
> I don't see how you can get /usr/lib64/libgmp.a with your gmp USE="-static-libs"

I've just recreated new container from image. It is ok. You can 100% reproduce this error by using the following commands:

docker run -it puchuu/test_x86_64-gentoo-linux-musl bash
env-update && source /etc/profile
echo "dev-libs/gmp static-libs" > /etc/portage/package.use/gmp
MAKEOPTS='-j16' emerge -v dev-libs/gmp
echo -e \
  "#include <gmp.h>\n void main () { mpz_t a; mpz_init(a); mpz_mul(a, a, a); mpz_clear(a); }" > main.c && \
  gcc main.c /usr/lib64/libgmp.a -o main && ./main

It will segfault.
Comment 13 Sergei Trofimovich (RETIRED) gentoo-dev 2020-01-30 23:07:17 UTC
(In reply to Andrew Aladjev from comment #12)
> > I don't see how you can get /usr/lib64/libgmp.a with your gmp USE="-static-libs"
> 
> I've just recreated new container from image. It is ok. You can 100%
> reproduce this error by using the following commands:
> 
> docker run -it puchuu/test_x86_64-gentoo-linux-musl bash
> env-update && source /etc/profile
> echo "dev-libs/gmp static-libs" > /etc/portage/package.use/gmp
> MAKEOPTS='-j16' emerge -v dev-libs/gmp
> echo -e \
>   "#include <gmp.h>\n void main () { mpz_t a; mpz_init(a); mpz_mul(a, a, a);
> mpz_clear(a); }" > main.c && \
>   gcc main.c /usr/lib64/libgmp.a -o main && ./main
> 
> It will segfault.

Are you sure?

"""
# echo -e   "#include <gmp.h>\n void main () { mpz_t a; mpz_init(a); mpz_mul(a, a, a); mpz_clear(a); }" > main.c &&   gcc main.c /usr/lib64/libgmp.a -o main && ./main
gcc: error: /usr/lib64/libgmp.a: No such file or directory
"""

Which makes sense. musl does not use /usr/lib64/ diretory.
Comment 14 Andrew Aladjev 2020-01-30 23:33:12 UTC
Sorry, please replace lib64 with lib in the sample above. lib64 reproduced warning in glibc container, lib warning and segfault in musl one.
Comment 15 Sergei Trofimovich (RETIRED) gentoo-dev 2020-01-31 00:08:39 UTC
Aha. Finally got the crash and the warning. It looks like the affected version is only gmp-6.1.2, but not gmp-6.2.0 (That's why I kept failing to reproduce it).

At a superficial glance TEXTREL comes from a single file: gcd_1.o. The rest of default assembly is TEXTREL-clean.

On gmp-6.1.2 it was provided from:
    gmp-6.1.2-r1/work/gmp-6.1.2/mpn/x86_64/gcd_1.asm
That code is probably not TEXTREL-clean.

On gmp-6.2.0 the same function is provided by:
    gmp-6.2.0-r1/work/gmp-6.2.0/mpn/generic/gcd_1.c
That code handles TEXTREL as good as gcc can do for you.

https://gmplib.org/repo/gmp/rev/f5fc3e7389b4 removed assembly implementations:
  changeset:   17981:f5fc3e7389b4
  user:        Torbjorn Granlund <tg@gmplib.org>
  date:        Fri Nov 29 00:53:11 2019 +0100
  summary:     Remove all gcd_1.asm files.

The change does not say why. Probably due to presence of TEXTRELs?

Note: ideally --with-pic should not influence TEXTREL cleanliness. All code should be TEXTREL-free. Practically it might not be, but it should be fixed on assembly level if reasonably possible.

Specifically --with-pic=pic-only does not fix gmp:
    # EXTRA_ECONF=--with-pic=pic-only emerge -av1 dev-libs/gmp
    /usr/lib/gcc/x86_64-gentoo-linux-musl/9.2.0/../../../../x86_64-gentoo-linux-musl/bin/ld: warning: creating a DT_TEXTREL in object
TEXTREL does not go away.

Thus I suggest using gmp-6.2.0 or USE=-asm.
Comment 16 Sergei Trofimovich (RETIRED) gentoo-dev 2020-01-31 00:16:50 UTC
Fun fact on i686 code still has a few TEXTRELs in addition:

# ar x /usr/lib/libgmp.a
# LANG=C gcc *.o -o ../main -Wl,--defsym=main=42
/usr/lib/gcc/i686-pc-linux-gnu/9.2.0/../../../../i686-pc-linux-gnu/bin/ld: add_n.o: warning: relocation in read-only section `.text'
/usr/lib/gcc/i686-pc-linux-gnu/9.2.0/../../../../i686-pc-linux-gnu/bin/ld: warning: creating a DT_TEXTREL in object
sf /tmp/z # scanelf -t ../main
 TYPE   TEXTREL FILE
ET_DYN TEXTREL ../main
sf /tmp/z # scanelf -T ../main
 TYPE   TEXTRELS FILE
  main: (memory/data?) [0x1E7E] in (optimized out: previous __gmpn_add_n) [0x1E50]
  main: (memory/data?) [0x25FF] in (optimized out: previous __gmpn_addmul_1) [0x25A7]
  main: (memory/data?) [0x41FD] in (optimized out: previous __gmpn_bdiv_q_1) [0x41D0]
  main: (memory/data?) [0xDB5E] in (optimized out: previous __gmpn_divexact_1) [0xDB30]
  main: (memory/data?) [0x2D55C] in (optimized out: previous __gmpn_modexact_1_odd) [0x2D540]
  main: (memory/data?) [0x30931] in (optimized out: previous __gmpn_mul_basecase) [0x30780]
  main: (memory/data?) [0x403A0] in (optimized out: previous __gmpn_sqr_basecase) [0x40240]
  main: (memory/data?) [0x4301E] in (optimized out: previous __gmpn_sub_n) [0x42FF0]
  main: (memory/data?) [0x4319F] in (optimized out: previous __gmpn_submul_1) [0x43147]
ET_DYN  ../main
Comment 17 Andrew Aladjev 2020-01-31 07:18:58 UTC
--with-pic helps to make both x86_64 and i686 working. The following image "puchuu/test-ruby-lzws_i686-gentoo-linux-musl" was created to test software depends on gmp v6.1.2. We can use the following example:

docker run -it --entrypoint bash puchuu/test-ruby-lzws_i686-gentoo-linux-musl
env-update && source /etc/profile
echo -e \
  "#include <gmp.h>\n void main () { mpz_t a; mpz_init(a); mpz_mul(a, a, a); mpz_clear(a); }" > main.c && \
  gcc main.c /usr/lib/libgmp.a -o main && ./main

Work good. So please add "pic" use, it can help sometimes.
Comment 18 Sergei Trofimovich (RETIRED) gentoo-dev 2020-01-31 07:31:27 UTC
(In reply to Sergei Trofimovich from comment #15)
> Specifically --with-pic=pic-only does not fix gmp:
>     # EXTRA_ECONF=--with-pic=pic-only emerge -av1 dev-libs/gmp

Oh, --with-pic=pic-only is an invalid syntax. --with-pic works, yes.
Comment 19 Larry the Git Cow gentoo-dev 2020-01-31 07:57:23 UTC
The bug has been closed via the following commit(s):

https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=10a57644d5a354baac5d1018fe2dbb34342a14fd

commit 10a57644d5a354baac5d1018fe2dbb34342a14fd
Author:     Sergei Trofimovich <slyfox@gentoo.org>
AuthorDate: 2020-01-31 07:56:56 +0000
Commit:     Sergei Trofimovich <slyfox@gentoo.org>
CommitDate: 2020-01-31 07:57:17 +0000

    dev-libs/gmp: add USE=pic for static libraries, bug #707332
    
    gmp makes a decision to use PIC or non-PIC assemply at
    ./configure time instead of (typical) build time.
    
    On top of that non-PIC assembly also has TEXTRELs in it
    which musl can't handle and crashes binaries at relocation
    setup time. For gmp is it relevant only for static linking.
    
    The change adds USE=pic to force static libraries to generate
    assembly code without TEXTRELs.
    
    Reported-by: Andrew Aladjev
    Closes: https://bugs.gentoo.org/707332
    Package-Manager: Portage-2.3.86, Repoman-2.3.20
    Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>

 dev-libs/gmp/gmp-6.1.2-r1.ebuild | 7 +++++--
 dev-libs/gmp/gmp-6.1.2.ebuild    | 7 +++++--
 dev-libs/gmp/gmp-6.2.0-r1.ebuild | 5 ++++-
 dev-libs/gmp/gmp-6.2.0.ebuild    | 5 ++++-
 dev-libs/gmp/metadata.xml        | 1 +
 5 files changed, 19 insertions(+), 6 deletions(-)
Comment 20 Sergei Trofimovich (RETIRED) gentoo-dev 2020-01-31 08:00:43 UTC
(In reply to Andrew Aladjev from comment #17)
> --with-pic helps to make both x86_64 and i686 working. The following image
> "puchuu/test-ruby-lzws_i686-gentoo-linux-musl" was created to test software
> depends on gmp v6.1.2. We can use the following example:
> 
> docker run -it --entrypoint bash puchuu/test-ruby-lzws_i686-gentoo-linux-musl
> env-update && source /etc/profile
> echo -e \
>   "#include <gmp.h>\n void main () { mpz_t a; mpz_init(a); mpz_mul(a, a, a);
> mpz_clear(a); }" > main.c && \
>   gcc main.c /usr/lib/libgmp.a -o main && ./main
> 
> Work good. So please add "pic" use, it can help sometimes.

In future please void posting docker scenarios and actually attach patches to the ebuilds/envidonment you do.