Bug 100096 - libgccjit.so.0: Cannot write-enable text segment: Permission denied on NetBSD 9.1
Summary: libgccjit.so.0: Cannot write-enable text segment: Permission denied on NetBSD...
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: jit (show other bugs)
Version: 12.1.0
: P3 normal
Target Milestone: 8.5
Assignee: David Malcolm
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-04-15 11:14 UTC by Sascha Wilde
Modified: 2023-07-24 08:54 UTC (History)
2 users (show)

See Also:
Host: i386-unknown-netbsdelf9.1
Target: i386-unknown-netbsdelf9.1
Build: i386-unknown-netbsdelf9.1
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Output of: readelf -Wa /usr/local/lib/libgccjit.so (908.64 KB, application/x-bzip)
2021-04-15 13:30 UTC, Sascha Wilde
Details
tut01-hello-world log output (1.57 KB, text/plain)
2021-04-15 14:42 UTC, Sascha Wilde
Details
Output of: readelf -wi libgccjit.so.0 | grep -A4 DW_AT_producer (18.65 KB, application/x-bzip)
2021-04-16 09:37 UTC, Sascha Wilde
Details
gcc11-pr100096.patch (1.18 KB, patch)
2021-04-16 11:28 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sascha Wilde 2021-04-15 11:14:00 UTC
On NetBSD 9.1 i386 the Hello World example from
https://gcc.gnu.org/onlinedocs/jit/intro/tutorial01.html
fails with:

% ./tut01-hello-world
/usr/local/lib/libgccjit.so.0: text relocations
/usr/local/lib/libgccjit.so.0: Cannot write-enable text segment: Permission denied

when security.pax.mprotect.global is enabled, which is the default on the system.
When disabelin global memory protection (as root) with:

sysctl -w security.pax.mprotect.global=0

The example works (still emitting a warning:

% ./tut01-hello-world
/usr/local/lib/libgccjit.so.0: text relocations
hello world

Turning of security.pax.mprotect.global shouldn't be required for libgccjit
to work.

Also the warning "/usr/local/lib/libgccjit.so.0: text relocations" should
be prevented if possible.
Comment 1 Jakub Jelinek 2021-04-15 12:18:35 UTC
How did you build libgccjit.so.0?
Have you used --enable-host-shared during configure?
Comment 2 Sascha Wilde 2021-04-15 13:21:52 UTC
> How did you build libgccjit.so.0?
> Have you used --enable-host-shared during configure?

Yes, AFAIK this is mandatory?

Here is the configuration I used:

../gcc-10.2.0/configure \
  --with-bugurl='https://github.com/jashandeep-sohi/libgccjit-pkg/issues' \
  --enable-shared \
  --enable-host-shared \
  --enable-checking=release \
  --enable-languages=jit \
  --disable-multilib \
  --disable-libssp \
  --disable-lto \
  --disable-libquadmath \
  --disable-liboffloadmic \
  --disable-libada \
  --disable-libsanitizer \
  --disable-libquadmath-support \
  --disable-libgomp \
  --disable-libvtv \
  --disable-libsanitizer \
  --with-gmp=/usr/local \
  --with-mpc=/usr/local \
  --with-mpfr=/usr/local
Comment 3 Jakub Jelinek 2021-04-15 13:23:29 UTC
So, how many text relocations do you see?
E.g. readelf -Wa libgccjit.so.0 output attached here would be useful.
Comment 4 Sascha Wilde 2021-04-15 13:30:53 UTC
Created attachment 50602 [details]
Output of: readelf -Wa /usr/local/lib/libgccjit.so
Comment 5 Sascha Wilde 2021-04-15 13:32:43 UTC
(In reply to Jakub Jelinek from comment #3)
> So, how many text relocations do you see?
> E.g. readelf -Wa libgccjit.so.0 output attached here would be useful.

I attached the requested output (its nearly 9MiB uncompressed, so used bzip2 
to stay below the file size limit of 1000K)
Comment 6 Sascha Wilde 2021-04-15 13:36:44 UTC
However, please note that
"Cannot write-enable text segment: Permission denied"
is the more pressing problem, as it prevents libgccjit to be used
on NetBSD with default security settings.
Comment 7 Andreas Schwab 2021-04-15 13:38:52 UTC
That's just the consequence of text relocations.
Comment 8 David Malcolm 2021-04-15 13:47:29 UTC
(In reply to Sascha Wilde from comment #6)
> However, please note that
> "Cannot write-enable text segment: Permission denied"
> is the more pressing problem, as it prevents libgccjit to be used
> on NetBSD with default security settings.

It would be good to know exactly where that error message is being emitted.

If you add:
  gcc_jit_context_set_logfile (ctxt, stderr, 0, 0);
to the test code (e.g. immediately after the call to gcc_jit_context_acquire), libgccjit ought to spew out a copious amount of logging (see https://gcc.gnu.org/onlinedocs/jit/internals/index.html#example-of-log-file)

Can you attach the log you get please?
Comment 9 Jakub Jelinek 2021-04-15 14:03:34 UTC
So I see 236 R_386_RELATIVE text relocations and 231 other text relocations.
Seems the compiler itself is built with -fpic/-fPIC, but some of the libraries that are linked into it are not, e.g. libintl.a, at least parts of libgcc (the dfp stuff), libbacktrace.
Perhaps
readelf -wi libgccjit.so.0 | grep DW_AT_producer
would make it clearer on what is and what is not built with -fpic/-fPIC.
On i686-linux I certainly can't reproduce this, there are no text relocations.
Comment 10 Sascha Wilde 2021-04-15 14:41:00 UTC
(In reply to David Malcolm from comment #8)
> It would be good to know exactly where that error message is being emitted.
> 
> If you add:
>   gcc_jit_context_set_logfile (ctxt, stderr, 0, 0);
> to the test code (e.g. immediately after the call to
> gcc_jit_context_acquire), libgccjit ought to spew out a copious amount of
> logging (see
> https://gcc.gnu.org/onlinedocs/jit/internals/index.html#example-of-log-file)
> 
> Can you attach the log you get please?

With security.pax.mprotect.global=1 it produces no extra output.
I'll attach the output produced when security.pax.mprotect.global is
disabled.
Comment 11 Sascha Wilde 2021-04-15 14:42:22 UTC
Created attachment 50603 [details]
tut01-hello-world log output
Comment 12 Sascha Wilde 2021-04-15 14:58:21 UTC
(In reply to Jakub Jelinek from comment #9)
> Perhaps
> readelf -wi libgccjit.so.0 | grep DW_AT_producer
> would make it clearer on what is and what is not built with -fpic/-fPIC.

This runs quite long and only yields lines like:

    <d>   DW_AT_producer    : (indirect string, offset: 0x155c1): GNU C++14 10.2.0 -mtune=generic -march=i486 -g -O2 -fPIC -fno-exceptions -fno-rtti -fasynchronous-unwind-tables
    <30387>   DW_AT_producer    : (indirect string, offset: 0x155c1): GNU C++14 10.2.0 -mtune=generic -march=i486 -g -O2 -fPIC -fno-exceptions -fno-rtti -fasynchronous-unwind-tables
    <3ccf4>   DW_AT_producer    : (indirect string, offset: 0x155c1): GNU C++14 10.2.0 -mtune=generic -march=i486 -g -O2 -fPIC -fno-exceptions -fno-rtti -fasynchronous-unwind-tables

[...]

If this is really helpful to you, I'm fully willing to let it run through all 
the way and provide you with the complete output, of course.
Comment 13 Jakub Jelinek 2021-04-15 15:00:53 UTC
The important question is what TUs are compiled without -fPIC/-fpic, those with those options are fine.
So perhaps
readelf -wi libgccjit.so.0 | grep DW_AT_producer | grep -v 'fPIC\|fpic'
?
Comment 14 Jakub Jelinek 2021-04-15 15:08:37 UTC
Though, DW_AT_producer lines don't really provide the filename and comp_dir,
so guess what I need is better
readelf -wi libgccjit.so.0 | grep -A4 DW_AT_producer | bzip2 -9
output.
Comment 15 Sascha Wilde 2021-04-15 16:13:02 UTC
(In reply to Jakub Jelinek from comment #13)
> readelf -wi libgccjit.so.0 | grep DW_AT_producer | grep -v 'fPIC\|fpic'

FWIW, I had the command running for quite some while without spotting any
line not containing -fPIC -- but these might still come though...


(In reply to Jakub Jelinek from comment #14)
> Though, DW_AT_producer lines don't really provide the filename and comp_dir,
> so guess what I need is better
> readelf -wi libgccjit.so.0 | grep -A4 DW_AT_producer | bzip2 -9
> output.

Ill provide you with the output.  Please allow me some time, as this really 
runs _long_ on the system in question (a small Atom CPU N270).

I hope to provide the output tomorrow...
Comment 16 David Malcolm 2021-04-15 17:44:29 UTC
(In reply to Sascha Wilde from comment #10)
> (In reply to David Malcolm from comment #8)
> > It would be good to know exactly where that error message is being emitted.
> > 
> > If you add:
> >   gcc_jit_context_set_logfile (ctxt, stderr, 0, 0);
> > to the test code (e.g. immediately after the call to
> > gcc_jit_context_acquire), libgccjit ought to spew out a copious amount of
> > logging (see
> > https://gcc.gnu.org/onlinedocs/jit/internals/index.html#example-of-log-file)
> > 
> > Can you attach the log you get please?
> 
> With security.pax.mprotect.global=1 it produces no extra output.
> I'll attach the output produced when security.pax.mprotect.global is
> disabled.

Thanks!  I was wondering if the error message was:
  (a) due to a problem dynamically linking libgccjit into the process, or
  (b) a later problem with linking the code that libgccjit generates into the process.

Given that there's no extra log output at all with the protection flag, it sounds like it's (a) - though you may run into a similar problem with (b) if/when (a) gets solved.
Comment 17 Sascha Wilde 2021-04-15 20:07:39 UTC
(In reply to David Malcolm from comment #16)
> (In reply to Sascha Wilde from comment #10)
> > (In reply to David Malcolm from comment #8)
> > > It would be good to know exactly where that error message is being emitted.
> > > 
> > > If you add:
> > >   gcc_jit_context_set_logfile (ctxt, stderr, 0, 0);
> > > to the test code (e.g. immediately after the call to
> > > gcc_jit_context_acquire), libgccjit ought to spew out a copious amount of
> > > logging (see
> > > https://gcc.gnu.org/onlinedocs/jit/internals/index.html#example-of-log-file)
> > > 
> > > Can you attach the log you get please?
> > 
> > With security.pax.mprotect.global=1 it produces no extra output.
> > I'll attach the output produced when security.pax.mprotect.global is
> > disabled.
> 
> Thanks!  I was wondering if the error message was:
>   (a) due to a problem dynamically linking libgccjit into the process, or
>   (b) a later problem with linking the code that libgccjit generates into
> the process.
> 
> Given that there's no extra log output at all with the protection flag, it
> sounds like it's (a) - though you may run into a similar problem with (b)
> if/when (a) gets solved.

FWIW, the reason why I stumbled upon this problem is that I am testing
the native compiling GNU Emacs branch[0] on the NetBSD system.
(Which, by the way, can be build and works great once
security.pax.mprotect.global is disabled)

When security.pax.mprotect.global is enable the Emacs, linked with
libgccjit can not be started at all, failing with the same error as
the hello-world example.  So this matches your analysis that the
problem is triggered by dynamically linking libgccjit.

[0] https://akrl.sdf.org/gccemacs.html
Comment 18 Sascha Wilde 2021-04-16 09:37:48 UTC
Created attachment 50612 [details]
Output of: readelf -wi libgccjit.so.0 | grep -A4 DW_AT_producer
Comment 19 Sascha Wilde 2021-04-16 09:38:39 UTC
(In reply to Jakub Jelinek from comment #14)
> Though, DW_AT_producer lines don't really provide the filename and comp_dir,
> so guess what I need is better
> readelf -wi libgccjit.so.0 | grep -A4 DW_AT_producer | bzip2 -9
> output.

I now attached the requested output to the issue.
Comment 20 Jakub Jelinek 2021-04-16 11:28:00 UTC
Created attachment 50614 [details]
gcc11-pr100096.patch

Thanks.  So, from your readelf -wi dump it seems it is only libintl.a that doesn't have --enable-host-shared support.

So, can you please test this patch and see if all libgccjit.so* text relocations are gone with that?

Can't test myself as on Linux libintl.a is never built - gettext is in the C library.
Comment 21 wilde 2021-04-16 12:18:59 UTC
"jakub at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org> wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100096
>
> --- Comment #20 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
> Created attachment 50614 [details]
>   --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50614&action=edit
> gcc11-pr100096.patch
>
> Thanks.  So, from your readelf -wi dump it seems it is only libintl.a that
> doesn't have --enable-host-shared support.
>
> So, can you please test this patch and see if all libgccjit.so* text
> relocations are gone with that?

I will test the patch, given the hardware this will take some time
(I'll consider setting up a vm on a faster hardware).

The patch needs to be applied to gcc11, right?  If it were usable with
10.2.0 I could apply it to my existing build, which of course would be
much faster to rebuild...
Comment 22 Jakub Jelinek 2021-04-16 12:25:41 UTC
It applies cleanly to gcc 10 too.  intl/ isn't really changing all that much...
Comment 23 wilde 2021-04-16 14:32:56 UTC
"jakub at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org> wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100096
>
> --- Comment #22 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
> It applies cleanly to gcc 10 too.  intl/ isn't really changing all that much...

I am very happy to confirm, that the patch completely solves the issue
for me.  The hello-world example as well as the native compiling GNU
Emacs both do now work perfectly fine and without any warnings with
security.pax.mprotect.global enabled.

Thanks a lot for the fast and friendly reply!
Comment 24 GCC Commits 2021-04-16 16:35:14 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:4a1493f0603262a7dc1114d9827353e9810e63dc

commit r11-8225-g4a1493f0603262a7dc1114d9827353e9810e63dc
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri Apr 16 18:32:27 2021 +0200

    intl: Add --enable-host-shared support [PR100096]
    
    As mentioned in the PR, building gcc with jit enabled and
    --enable-host-shared doesn't work on NetBSD/i?86, as libgccjit.so.0
    has text relocations.
    The r0-125846-g459260ecf8b420b029601a664cdb21c185268ecb changes
    added --enable-host-shared support to various libraries, but didn't
    add it to intl/ subdirectory; on Linux it isn't really needed, because
    all: all-no
    all-no: #nothing
    but on other OSes intl/libintl.a is built.
    
    The following patch makes sure it is built with -fPIC when
    --enable-host-shared is used.
    
    2021-04-16  Jakub Jelinek  <jakub@redhat.com>
    
            PR jit/100096
            * configure.ac: Add --enable-host-shared support.
            * Makefile.in: Update copyright.  Add @PICFLAG@ to CFLAGS.
            * configure: Regenerated.
Comment 25 GCC Commits 2021-04-20 09:46:35 UTC
The releases/gcc-10 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:a11f31102706e33f66b60367d6863613ab3bd051

commit r10-9731-ga11f31102706e33f66b60367d6863613ab3bd051
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri Apr 16 18:32:27 2021 +0200

    intl: Add --enable-host-shared support [PR100096]
    
    As mentioned in the PR, building gcc with jit enabled and
    --enable-host-shared doesn't work on NetBSD/i?86, as libgccjit.so.0
    has text relocations.
    The r0-125846-g459260ecf8b420b029601a664cdb21c185268ecb changes
    added --enable-host-shared support to various libraries, but didn't
    add it to intl/ subdirectory; on Linux it isn't really needed, because
    all: all-no
    all-no: #nothing
    but on other OSes intl/libintl.a is built.
    
    The following patch makes sure it is built with -fPIC when
    --enable-host-shared is used.
    
    2021-04-16  Jakub Jelinek  <jakub@redhat.com>
    
            PR jit/100096
            * configure.ac: Add --enable-host-shared support.
            * Makefile.in: Update copyright.  Add @PICFLAG@ to CFLAGS.
            * configure: Regenerated.
    
    (cherry picked from commit 4a1493f0603262a7dc1114d9827353e9810e63dc)
Comment 26 GCC Commits 2021-04-20 23:34:59 UTC
The releases/gcc-9 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:e173d85243b7732aa3ef29ebf7ecc6a54d21320c

commit r9-9449-ge173d85243b7732aa3ef29ebf7ecc6a54d21320c
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri Apr 16 18:32:27 2021 +0200

    intl: Add --enable-host-shared support [PR100096]
    
    As mentioned in the PR, building gcc with jit enabled and
    --enable-host-shared doesn't work on NetBSD/i?86, as libgccjit.so.0
    has text relocations.
    The r0-125846-g459260ecf8b420b029601a664cdb21c185268ecb changes
    added --enable-host-shared support to various libraries, but didn't
    add it to intl/ subdirectory; on Linux it isn't really needed, because
    all: all-no
    all-no: #nothing
    but on other OSes intl/libintl.a is built.
    
    The following patch makes sure it is built with -fPIC when
    --enable-host-shared is used.
    
    2021-04-16  Jakub Jelinek  <jakub@redhat.com>
    
            PR jit/100096
            * configure.ac: Add --enable-host-shared support.
            * Makefile.in: Update copyright.  Add @PICFLAG@ to CFLAGS.
            * configure: Regenerated.
    
    (cherry picked from commit a11f31102706e33f66b60367d6863613ab3bd051)
Comment 27 GCC Commits 2021-04-22 16:53:08 UTC
The releases/gcc-8 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:db80752e02b765dfc129892377aebf18bcb7fc8a

commit r8-10911-gdb80752e02b765dfc129892377aebf18bcb7fc8a
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri Apr 16 18:32:27 2021 +0200

    intl: Add --enable-host-shared support [PR100096]
    
    As mentioned in the PR, building gcc with jit enabled and
    --enable-host-shared doesn't work on NetBSD/i?86, as libgccjit.so.0
    has text relocations.
    The r0-125846-g459260ecf8b420b029601a664cdb21c185268ecb changes
    added --enable-host-shared support to various libraries, but didn't
    add it to intl/ subdirectory; on Linux it isn't really needed, because
    all: all-no
    all-no: #nothing
    but on other OSes intl/libintl.a is built.
    
    The following patch makes sure it is built with -fPIC when
    --enable-host-shared is used.
    
    2021-04-16  Jakub Jelinek  <jakub@redhat.com>
    
            PR jit/100096
            * configure.ac: Add --enable-host-shared support.
            * Makefile.in: Update copyright.  Add @PICFLAG@ to CFLAGS.
            * configure: Regenerated.
    
    (cherry picked from commit a11f31102706e33f66b60367d6863613ab3bd051)
Comment 28 Jakub Jelinek 2021-04-22 17:12:21 UTC
Fixed.
Comment 29 Sascha Wilde 2022-06-27 08:28:25 UTC
Unfortunately the problem is still not fully resolved.
When bootstrapping the compiler (tested with 12.1 on NetBSD 9.2) libintl is
still build without -fPIC, however, when manually rebuilding libintl it is build
correctly without any changes to the Makefile:

gmake BOOT_CFLAGS='-O' -j2 bootstrap   # wrong result, due to libintl w/o -fPIC
cd intl
gmake -j2 clean
gmake -j2  # builds a sane libintl with -fPIC
cd ..
gmake BOOT_CFLAGS='-O' -j2  # now results in a woring compiler and libgccjit.so

No idea why that is, but it's fully reproachable...
Comment 30 Sascha Wilde 2023-07-24 08:54:28 UTC
Anything else I should test?