Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 800533 - flag-o-matic.eclass ALLOWED_FLAGS changes for clang & misc fixes
Summary: flag-o-matic.eclass ALLOWED_FLAGS changes for clang & misc fixes
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Eclasses (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Gentoo Toolchain Maintainers
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-07-04 18:01 UTC by Jannik Glückert
Modified: 2022-01-22 22:19 UTC (History)
2 users (show)

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


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jannik Glückert 2021-07-04 18:01:49 UTC
ALLOWED_FLAGS currently lacks the following clang specific flags which belong into the same categories as existing ones:

Debug targets:
-gdbx
-glldb
-gsce (what even is that?)
unlike for gdb, these do not come in level flavors like -ggdb3

More debug:
-gmodules

There's more specific -g flags at https://clang.llvm.org/docs/ClangCommandLineReference.html#debug-information-generation , but I'm pretty sure those are subflags in -g[0-3] anyways. Those could be added too, but I left them out in favor of readability.

Optimization flags:
-Oz

Currently -O[12sg] are enabled - -Oz is a clang specific and can be summarized as a more aggressive -Os


Additionally, the following seems to be missing (gcc & clang):

-fuse-ld=*

Right now only -fuse-ld is allowed, but neither gcc nor clang have that option without the = behind it?


Lastly, the following is missing (gcc & clang):

-ffixed-x18

(This flag also exists with other registers, but x18 is the only one I'm aware where it's actually needed)
This causes the compiler to not use the x18 register (arm64) in operations. Hand coded assembly can still use x18, and no breakage is expected since x18 is untouched by the PCS.
x18 is defined as a platform ABI register by AAPCS64. It is reserved by many OSes and thus primarily relevant for crossdev and prefix.

The following platforms reserve x18:

Windows on ARM64: x18 points to the TEB - https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-160#integer-registers

MacOS, iOS & other Apple OSes on ARM64: "The platforms reserve register x18" - it is unknown what for exactly - https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms

Android on ARM64: x18 is used for SCS - https://developer.android.com/ndk/guides/abis#arm64-v8a


Additionally, we would like to bring SCS to Gentoo one day, and would also need x18 for that.


Best regards,
Jannik
Comment 1 Sergei Trofimovich (RETIRED) gentoo-dev 2021-07-05 21:35:49 UTC
(In reply to Jannik Glückert from comment #0)
> ALLOWED_FLAGS currently lacks the following clang specific flags which
> belong into the same categories as existing ones:

Can you clarify what you would like to achieve?

The idea of strip-flags is to get a small subset of CFLAGS that is very likely understood both by current and built compilers. Ebuilds should not normally use strip-flags. If they do we probably already break something by aggressive flag filtering.

> Debug targets:
> -gdbx
> -glldb
> -gsce (what even is that?)
> unlike for gdb, these do not come in level flavors like -ggdb3

What will happen when you build gcc with CXX=clang++ and CFLAGS=-gdbx? I would expect gcc build to fail when we pass -gdbx to gcc-stage1.

We could add USE=custom-cflags to gcc to allow people pass suspicious flags there. But it should not be a default
Comment 2 Jannik Glückert 2021-07-06 12:45:11 UTC
> Can you clarify what you would like to achieve?

Make life easier for users with specific needs without compromising the experience for others & fix deficiencies in this eclass

> The idea of strip-flags is to get a small subset of CFLAGS that is very likely understood both by current and built compilers.

Is it? It looks like the purpose of strip-flags, as utilized by ebuilds right now, is to remove "ricer" custom flags on sensitive packages, but leave debug and specific workaround flags intact.

As it is, if a user wants to utilize clang system wide, strip-flags is preventing them from debugging with lldb in some places.

> What will happen when you build gcc with CXX=clang++ and CFLAGS=-gdbx?

likely not much, because gcc is full of GNU C and only builds with gcc, regardless of clang-only debug flags.

What will happen if I build glibc with any of the -fsanitize flags? It'll likely trigger a sanitizer in some arcane UB code from the 80s. What will happen if I build gcc with "-fuse-ld bfd" (allowed by eclass, wrong syntax) instead of "-fuse-ld=bfd" (disallowed, correct syntax)?
> gcc: error: unrecognized command-line option '-fuse-ld'

Protecting users from mistakes is definitely a thing we should try to do, but if someone wants to smuggle "broken" flags through strip-flags they can easily do so. Someone setting -g* or -fsanitize* is likely doing so for a specific reason, and not because of ricer fashion or curiosity - and right now the eclass is preventing them from doing so. Similarly, someone using -Oz is likely aware that it is a clang only flag, and probably smart enough to figure out that gcc doesn't build with clang after the first attempt.


As for -fuse-ld=* and -ffixed-x18:
Those are general defects in the eclass and not compiler specific, so they should be fixed regardless of how gentoo interprets the purpose of strip-flags
Comment 3 Sergei Trofimovich (RETIRED) gentoo-dev 2021-07-06 15:01:35 UTC
(In reply to Jannik Glückert from comment #2)
> > Can you clarify what you would like to achieve?
>
> Make life easier for users with specific needs without compromising the
> experience for others & fix deficiencies in this eclass

Do you have specific examples where it was a hindrance?

> > The idea of strip-flags is to get a small subset of CFLAGS that is very likely understood both by current and built compilers.
>
> Is it? It looks like the purpose of strip-flags, as utilized by ebuilds
> right now, is to remove "ricer" custom flags on sensitive packages, but
> leave debug and specific workaround flags intact.

At the very least we should improve the documentation for strip-flags,
it's goals, typical use cases and pitfalls.

> As it is, if a user wants to utilize clang system wide, strip-flags is
> preventing them from debugging with lldb in some places.
>
> > What will happen when you build gcc with CXX=clang++ and CFLAGS=-gdbx?
>
> likely not much, because gcc is full of GNU C and only builds with gcc,
> regardless of clang-only debug flags.

gcc can be build by any c++11 compiler. Try:
    # CC=clang CXX=clang++ emerge -v1 sys-devel/gcc

The problem of gcc ebuild is in the fact that ebuild calls both $CXX and
inplace-built gcc. Both (actually mostly gcc, not $CXX in conrast to many
other ebuilds) use $CXXFLAGS. And it better be working if we want
    make.conf:CC=clang CXX=clang++ CXXFLAGS="-clang-specific-flags"
systems to Just Work. They are expected to Just Work today.

> What will happen if I build glibc with any of the -fsanitize flags? It'll
> likely trigger a sanitizer in some arcane UB code from the 80s.

I invite you to try it yourself in a chroot and try to find the cause of breakage. I can help in debugging it. My bet it will not be an UB in C code.

The problem of glibc is not a source-level UB. But the fact that C standard has not enough features to implement a runtime for standard C.

For one example glibc's runtime linker better not to call out to any external
symbols (like ones from libasan.so) until relocations are fully set up. It's
actually a big challenge to achieve even on -O0 without any sanitizers.

For another example you really don't want your libc.so.6 to be linked against
libasan.so (or even underlinked against it). You will get an unbootable system.

Similar goes for gcc's libgcc_s.so & co (like, libasan.so itself).

> What will happen if I build gcc with "-fuse-ld bfd" (allowed by eclass, wrong syntax)
> > gcc: error: unrecognized command-line option '-fuse-ld'

If LDFLAGS='-fuse-ld bfd' can't build any ebuilds I think it's fine not to build
the ones that use 'strip-flags' either. 'strip-flags' and friends don't handle
multiargument options. That's very good reason to avoid stripping when possible.

> instead of "-fuse-ld=bfd" (disallowed, correct syntax)?

What makes you think it's disallowed?

    # LDFLAGS=-fuse-ld=bfd emerge -v1 sys-libs/glibc
    ...
    x86_64-pc-linux-gnu-gcc ... -fuse-ld=bfd -nostdlib -nostartfiles -static -o .../work/build-amd64-x86_64-pc-linux-gnu-nptl/elf/ldconfig ...

You can play with the filter in eclass/tests/flag-o-matic.sh:

    --- a/eclass/tests/flag-o-matic.sh
    +++ b/eclass/tests/flag-o-matic.sh
    @@ -106,6 +106,12 @@ strip-flags
     [[ -z ${CFLAGS}${LDFLAGS}${CPPFLAGS} && ${CXXFLAGS} == "-O2" ]]
     ftend

    +tbegin "strip-flags preserved -fuse-ld="
    +CXXFLAGS+=" -fuse-ld=hello "
    +strip-flags
    +[[ -z ${CFLAGS}${LDFLAGS}${CPPFLAGS} && ${CXXFLAGS} == "-O2 -fuse-ld=hello" ]]
    +ftend
    +
     tbegin "replace-flags basic"
     CFLAGS="-O0 -foo"
     replace-flags -O0 -O1

    gentoo/eclass/tests $ ./flag-o-matic.sh
    * strip-flags: CXXFLAGS: changed '-O2 -fuse-ld=hello ' to '-O2 -fuse-ld=hello' [ ok ]

> Protecting users from mistakes is definitely a thing we should try to do

We don't filter out user's mistakes. We usually:
- bring C*FLAGS to a state that they could be used for a compiler different from $CXX
  (gcc, firefox with USE=clang, maybe wine?, a few embedded packages with cross-compilers)
- remove flags that are too special to be able to break assumptions of fragile
  programs (glibc, ghc, firefox, wine, chromium? gtk+?)

"too special" will certainly be very vague: it will depend of package version
(and bugs it has), on compiler version (and bugs and behaviour it introduces
with magic flags). Thus 'strip-flags' will always be a very blunt hammer.

> but if someone wants to smuggle "broken" flags through strip-flags they can
> easily do so. Someone setting -g* or -fsanitize* is likely doing so for a
> specific reason, and not because of ricer fashion or curiosity - and right
> now the eclass is preventing them from doing so. Similarly, someone using
> -Oz is likely aware that it is a clang only flag, and probably smart enough
> to figure out that gcc doesn't build with clang after the first attempt.

Does not USE=custom-cflags Just Work for such cases? Maybe concrete
examples from the past will help me understand why current system is so
limiting for you.

We can also consider an escape hatch like EXTRA_ALLOWED_FLAGS="" that user
could specify if they really want to pass arbitrary flags with big red
warnings in the build log when use of one of them is noticed. But at this
point it's better not to filter any flags and just expose USE=custom-cflags.

> As for -fuse-ld=* and -ffixed-x18:
> Those are general defects in the eclass and not compiler specific, so they
> should be fixed regardless of how gentoo interprets the purpose of
> strip-flags

-ffixed-* might be fine to list. I don't immediately see a use case for it though.
-fuse-ld=* should already work I believe.
Comment 4 Jannik Glückert 2021-07-06 19:16:48 UTC
> Do you have specific examples where it was a hindrance?

Personally, when I had to build gcc with -ffixed-x18 to work on SCS implementations. A more realistic usecase would be when someone wants to debug e.g. emacs, libreoffice or libsdl with lldb without having to go full custom-cflags or worse, editing the ebuild if it doesn't provide the option.

> gcc can be build by any c++11 compiler.

Sorry, I was thinking of gcc itself, not the bootstrap compiler - or is that also clang-able now?

> Does not USE=custom-cflags Just Work for such cases?

Yes, but custom-cflags in general means "you're off the rails now and doing something you probably shouldn't be doing, things will probably break horribly" - but this doesn't apply to the extra debug targets like -glldb


> What makes you think it's disallowed?

I guess I didn't understand the check function fully - allowing fuse-ld instead of fuse-ld=* (like we do for e.g. -fsanitize*) seemed unintuitive, but if this works there's no urgent reason to fix it.

> -ffixed-* might be fine to list. I don't immediately see a use case for it though.

As mentioned, without -ffixed-x18 we violate the ABI of any non linux / BSD aarch64 target - it's needed in ALLOWED_FLAGS especially so it doesn't leak into libgcc.
We will also need it in the future because we (sam and me) would like to bring SCS to aarch64 gentoo one day.

The other -ffixed-* flags should remain out of ALLOWED_FLAGS, there's no usecase since they're all either scratch or procedure call standard regs that are used on all platforms.


> My bet it will not be an UB in C code.

This was more of an example of how users can easily slip breaking flags through strip-flags, not glibc specific.

> For one example glibc's runtime linker better not to call out
> to any external symbols (like ones from libasan.so)
> until relocations are fully set up.

pre-reloc is it's own circle of hell and I do not wish it upon anyone.

Now back to topic:

> bring C*FLAGS to a state that they could be used for a compiler different from $CXX

Is strip-flags really effective at this? There are sanitizer flags that only gcc implements and vice versa for clang - same with debug flags as this request is about.
Nonetheless, a user might require these flags to debug a package, without wanting to go full custom-cflags (which may also have some weird side implications in some ebuilds), or not being able to do so at all without modifying the ebuild.

People won't go around putting -glldb or -fsanitize=something_only_gcc_implements in their make.conf and then compile everything with it out of spite - and if they do, they'll probably be able to understand the very clear compiler error that will appear immediately, and not some hours within compilation.


I don't quite get the "has to work with all compilers" requirement - from what I understand, ALLOWED_FLAGS are mostly flags that users might need to work around specific issues with their setup or platform, or that are needed to debug specific things? Using clang with lldb instead of gdb would certainly fall under these special setups.
Comment 5 Sergei Trofimovich (RETIRED) gentoo-dev 2021-07-07 18:04:18 UTC
(In reply to Jannik Glückert from comment #4)
> > Do you have specific examples where it was a hindrance?
> 
> Personally, when I had to build gcc with -ffixed-x18 to work on SCS
> implementations.

That sounds reasonable.

> A more realistic usecase would be when someone wants to
> debug e.g. emacs, libreoffice or libsdl with lldb without having to go full
> custom-cflags or worse, editing the ebuild if it doesn't provide the option.

Only now I realized #530070 already allows -fsanitize= in flag-o-matic.eclass making all my arguments moot :)

> > -ffixed-* might be fine to list. I don't immediately see a use case for it though.
> 
> As mentioned, without -ffixed-x18 we violate the ABI of any non linux / BSD
> aarch64 target - it's needed in ALLOWED_FLAGS especially so it doesn't leak
> into libgcc.

Out of curiosity which CHOST (or -march/-mabi?) is that? Sounds like ideally gcc's build system already needs to set it explicitly if it's a target requirement (as opposed to manual register picking by an end user).

> We will also need it in the future because we (sam and me) would like to
> bring SCS to aarch64 gentoo one day.
> 
> The other -ffixed-* flags should remain out of ALLOWED_FLAGS, there's no
> usecase since they're all either scratch or procedure call standard regs
> that are used on all platforms.

Picking a random register should not cause runtime problems. Worst case there will be a build time failure to allocate the register. Why not allow that?

> > My bet it will not be an UB in C code.
> 
> This was more of an example of how users can easily slip breaking flags
> through strip-flags, not glibc specific.

Ah, I think I was reading it backwards assuming that -fsanitize= was not allowed. That makes sense now.

> Now back to topic:
> 
> > bring C*FLAGS to a state that they could be used for a compiler different from $CXX
> 
> Is strip-flags really effective at this? There are sanitizer flags that only
> gcc implements and vice versa for clang - same with debug flags as this
> request is about.
> Nonetheless, a user might require these flags to debug a package, without
> wanting to go full custom-cflags (which may also have some weird side
> implications in some ebuilds), or not being able to do so at all without
> modifying the ebuild.
> 
> People won't go around putting -glldb or
> -fsanitize=something_only_gcc_implements in their make.conf and then compile
> everything with it out of spite - and if they do, they'll probably be able
> to understand the very clear compiler error that will appear immediately,
> and not some hours within compilation.
> 
> 
> I don't quite get the "has to work with all compilers" requirement - from
> what I understand, ALLOWED_FLAGS are mostly flags that users might need to
> work around specific issues with their setup or platform, or that are needed
> to debug specific things? Using clang with lldb instead of gdb would
> certainly fall under these special setups.

Yeah. Let's change the description to something like:

strip-flags:
- attempts to filter out most flags that could cause subtle and hard to debug runtime failures (flag examples: -flto, -O3)
- does NOT attempt to keep flags that cause package build breakages due to unsupported flags like -gunsupported.
Comment 6 Larry the Git Cow gentoo-dev 2022-01-22 22:19:02 UTC
The bug has been closed via the following commit(s):

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

commit a5e21edfc41b5663110f0a6dddf38975038c7009
Author:     Sam James <sam@gentoo.org>
AuthorDate: 2022-01-18 16:50:23 +0000
Commit:     Sam James <sam@gentoo.org>
CommitDate: 2022-01-22 22:18:54 +0000

    flag-o-matic.eclass: allow -ffixed-x18 for arm64
    
    Needed for shadow stack bits on ARM64.
    
    Closes: https://bugs.gentoo.org/800533
    Thanks-to: Jannik Glückert <jannik.glueckert@gmail.com>
    Signed-off-by: Sam James <sam@gentoo.org>

 eclass/flag-o-matic.eclass | 3 +++
 1 file changed, 3 insertions(+)

Additionally, it has been referenced in the following commit(s):

https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=47d20223ebfdd16c71f48fec1a6194d4a5e87096

commit 47d20223ebfdd16c71f48fec1a6194d4a5e87096
Author:     Sam James <sam@gentoo.org>
AuthorDate: 2022-01-18 16:48:02 +0000
Commit:     Sam James <sam@gentoo.org>
CommitDate: 2022-01-22 22:18:54 +0000

    flag-o-matic.eclass: allow -glldb
    
    We already allow -ggdb for GDB and this is the analogue for LLDB.
    
    Bug: https://bugs.gentoo.org/800533
    Reported-by: Jannik Glückert <jannik.glueckert@gmail.com>
    Signed-off-by: Sam James <sam@gentoo.org>

 eclass/flag-o-matic.eclass | 1 +
 1 file changed, 1 insertion(+)