From: Willy Tarreau <w@1wt.eu>
To: "Thomas Weißschuh" <linux@weissschuh.net>
Cc: Rodrigo Campos <rodrigo@sdfg.com.ar>, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 0/1] tools/nolibc/string: export strlen()
Date: Sat, 27 Jan 2024 17:24:00 +0100 [thread overview]
Message-ID: <20240127162400.GA14079@1wt.eu> (raw)
In-Reply-To: <9abed5e3-cd61-474e-bb16-13243709f5c5@t-8ch.de>
Hi!
On Sat, Jan 27, 2024 at 03:53:32PM +0100, Thomas Weißschuh wrote:
> Hi!
>
> On 2024-01-26 15:24:10+0100, Rodrigo Campos wrote:
> > Hi, while using nolibc on debian testing, I found that compilation fails when using strlcat().
> >
> > The compilation fails with:
> >
> > cc -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib -lgcc -static -o test test.c
> > /usr/bin/ld: /tmp/cccIasKL.o: in function `main':
> > test.c:(.text.startup+0x1e): undefined reference to `strlen'
> > collect2: error: ld returned 1 exit status
> >
> > This is using debian testing, with gcc 13.2.0.
>
> I can reproduce the issue with gcc 13.2.1 on Arch.
>
> > A small repro case that fails with this error on debian is:
> >
> > int main(void) {
> > char dst[6] = "12";
> > char *src = "abc";
> > strlcat(dst, src, 6);
> >
> > printf("dst is: %s\n", dst);
> >
> > return 0;
> > }
> >
> > Please note that this code is not using strlen() and strlcat() doesn't seems to use it either.
>
> I think the comment in strlen() explains it:
>
> Note that gcc12 recognizes an strlen() pattern and replaces it with a
> jump to strlen().
>
> strlcat() indeed contains this pattern.
>
> I was able to fix the issue by replacing the open-coded strlen() in
> strlcat() with a call to the function and that also fixed the issue.
>
> It seems nicer to me as a fix, on the other hand the change to a weak
> definition will also catch other instances of the issue.
> Maybe we do both.
Yes, once we have the proof that the compiler may produce such a call, it
can also happen in whatever user code so we need to export the function,
there's no other solution.
> > First I noted that removing the attribute unused in strlen(), the compilation worked fine. And then
> > I noticied that other functions had the attribute weak, a custom section and export the function.
> >
> > In particular, what happens here seems to be the same as in commit "tools/nolibc/string: export memset() and
> > memmove()" (8d304a374023), as removing the -Os or adding the -ffreestanding seem to fix the issue.
> > So, I did the same as that commit, for strlen().
> >
> > However, I'm not 100% confident on how to check that this is done by the compiler to later replace
> > it and provide a builtin. I'm not sure how that was verified for commit 8d304a374023, but if you let
> > me know, I can verify it too.
> >
> > What do you think?
>
> Personally I don't know how it was verified, we'll have to wait for
> Willy on that.
Oh it's very simple, just build a small code that doesn't contain any
such explicit nor implicit call and check that it doesn't contain the
function.
E.g.:
$ printf "int main(void) { }\n" | gcc -nostdlib -static -Isysroot/x86/include -include nolibc.h -Os -Wl,--gc-sections -xc -
$ nm --size a.out
0000000000000003 T main
0000000000000004 V errno
0000000000000008 V _auxv
0000000000000008 V environ
000000000000000f W _start
0000000000000042 W _start_c
and:
$ printf "int main(void) { return (long)&strlen;}\n" | gcc -nostdlib -static -Isysroot/x86/include -include nolibc.h -Os -Wl,--gc-sections -xc -
$ nm --size a.out
0000000000000004 V errno
0000000000000006 T main
0000000000000008 V _auxv
0000000000000008 V environ
000000000000000e t strlen
000000000000000f W _start
0000000000000042 W _start_c
> > As a side note, it seems strlcat()/strlcpy() fail to set the terminating null byte on some cases,
Indeed I've just checked and you're right, that defeats their purpose!
> > and the return code is not always the same as when using libbsd. It seems to be only on "error"
> > cases, and not sure if it's worth fixing all/some of those cases.
OK.
> > Let me know if you think it is worth adding some _simple_ patches (I don't think it is worth fixing
> > all the cases, the code is to fix all of the cases is probably not nice and not worth it).
>
> Souns reasonable to me to fix the return values.
> And get some tests for it.
Seconded!
Thanks!
Willy
next prev parent reply other threads:[~2024-01-27 16:34 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-26 14:24 [PATCH 0/1] tools/nolibc/string: export strlen() Rodrigo Campos
2024-01-26 14:24 ` [PATCH 1/1] " Rodrigo Campos
2024-01-27 14:53 ` [PATCH 0/1] " Thomas Weißschuh
2024-01-27 16:24 ` Willy Tarreau [this message]
2024-01-27 17:28 ` Rodrigo Campos
2024-01-27 21:23 ` David Laight
2024-01-27 21:27 ` Willy Tarreau
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240127162400.GA14079@1wt.eu \
--to=w@1wt.eu \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@weissschuh.net \
--cc=rodrigo@sdfg.com.ar \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox