Re: [PATCH 2/3] selftests/nolibc: cast execve() argv string to character pointer

From: Thomas Weißschuh

Date: Sun May 24 2026 - 04:19:04 EST


On 2026-05-23 10:53:42+0100, David Laight wrote:
> On Fri, 22 May 2026 23:40:17 +0200
> Thomas Weißschuh <linux@xxxxxxxxxxxxxx> wrote:
>
> > On 2026-05-22 19:48:07+0100, David Laight wrote:
> > > On Fri, 22 May 2026 16:39:58 +0200
> > > Thomas Weißschuh <linux@xxxxxxxxxxxxxx> wrote:
> > > > On 2026-05-21 19:15:58+0100, David Laight wrote:
> > > > > On Thu, 21 May 2026 18:29:30 +0200
> > > > > Thomas Weißschuh <linux@xxxxxxxxxxxxxx> wrote:
> > > > >
> > > > > > The existing code would trigger a warning under -Wwrite-strings which is
> > > > > > about to be enabled. execve() is specified as not modifying the argv
> > > > > > array, but the exact semantics are not representable in the type system.
> > > > >
> > > > > I suspect you'll have to fix it again to avoid 'casting away const'.
> > > >
> > > > Where would this warning be coming from? Which compiler flags are needed?
> > > > Afaik it is legal to cast away const.
> > >
> > > IIRC -Wcast-qual
> >
> > Yes that's it, thanks.
> >
> > > Lots of things are legal :-)
> > > The problem with enabling -Wcast-qual (NetBSD's kernel does/did) it is makes
> > > life annoying when you really do have to do it.
> > > (From what I remember there weren't really that many.)
> > > You sort of want an (unconst foo *) cast that won't generate a warning when
> > > a simple (foo *) cast would.
> >
> > There seem to be a fair amount of standard C APIs which require such
> > casts, for example strstr(). Also the UAPI headers currently emit such
> > warnings. So I am not sure if it makes sense to try to get nolibc
> > compile with this warning.
>
> It ought to be an aim :-)

Absolutely.

> Very recent headers use _Generic() so that the return type of strchr()
> and strstr() is the same as the argument.
> It should be possibly to get the linker to use the same symbol for both
> so the code only exists once.

_Generic() seems to work in GCC 4.9 and clang 3.0, even in C89 mode.
So we could indeed make use of it. IIRC there were some other casts
which would not be avoided with it. But still nice on its own.

(...)

> > > > > Can you use something like (char[]){"/"} ?
> > > >
> > > > That looks good.
>
> Given that the exec() test does the same for argv[] (mostly to get
> it all one one line) and object size doesn't really matter there
> that one could be done that was - almost for consistency.

Ack, will do.

> > > > However if this issue is real we will also have it in
> > > > nolibc's errno.h. There I don't want to use this pattern, as it requires
> > > > more memory.
> > >
> > > You can move a string from .rodata to .data easily enough.
> > > Doesn't change the memory footprint.
> >
> > When using the proposed pattern in errno.h I get plus 4 bytes of .bss
> > usage for each variable. While it doesn't make a difference in the
> > binary, at runtime these bytes are quite wasted.
> > I didn't look closely at it yet, but the compiler could be reusing a
> > single empty string in .rodata for all different users, while the .data
> > one needs to be duplicated for each one.
>
> That will happen, and the linker might merge the string with another '\0'
> in .rodata.str.1
> You'd need to have a named 'char null[] = ""'.

As long as there are no other users, it's still more memory for this
very edge case. Something to keep in mind though, if we need to add
such a shared variable for another usecase. With a better name though.
:-)

(...)


Thomas