public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
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

  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