From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5CB136923C for ; Wed, 25 Feb 2026 22:58:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.47 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772060297; cv=none; b=XJWvw0y9RPS9xwyt3copa2Yo1AGYrRsPkyL9BAFDNpd1dlsqnDe2pLAPqx/AnSUVmJXHMUEBSqsskCNaiEFLx6yrjNeL+UePxLvhDcUu51kg9vivWCVJg/1BKfJSyE6ytO86pT4WkI8QfoniSLfDrVdjkjgu6SX1U2oqELGiHqE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772060297; c=relaxed/simple; bh=BCtEp/LczVOtSdTVjmoKS92rLulk0XmgNB0LCR5XnNA=; h=Date:From:To:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=JdhhuW5QVDWZpeQhlU/NoLnhwZAn18Sf9ae5SzqpahZ9W2Ihg829rcQV/lfhSMYxfo3KcSp/lNa5Ljh9pHfOAjaE5+rrG7rBH4j9m5Uhu/Yih78SWd7qUnoCREDXnewlNBgaAZgrYmJcdIu0z5gbt1P+k5BHwpotWSBkGW1L6sI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=BFBhhn2H; arc=none smtp.client-ip=209.85.128.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BFBhhn2H" Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-48375f1defeso1887275e9.0 for ; Wed, 25 Feb 2026 14:58:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772060294; x=1772665094; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:subject:cc:to:from:date:from:to:cc:subject:date :message-id:reply-to; bh=KDlu2MU6otwoSbCkU+fftZ3FYtld2RFagUahdPSvMkA=; b=BFBhhn2HpFaWhAkohsWiducc8pdOB/o6famN93O9QbT5bGOe7wEjpV4Vn5o8xKgvIU PaegjdXARMS058b8K0jreIVaoyt1o1wFqNI/CreAPIhZhVtY8QXJKnBdLD7cZ98XWSsR rXz/P5T0IOQTwBWFe/oMTY0yOBU/h4bG2uoSXNfSZ8SkmTLiHqtPxlklUfEfGQtAmB9x yh2y+xysaaJn1342yQSIt7yY0WnDfRvec6O2xereJoPd/mGI+WMJe7wCYQPu01a6dLjT ECFENlZdke6Hh30lDJwddZcobnV52KvmoYi+xo69f1QwOOZuvcirqf9X84zRlTaWN+OY 4/yw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772060294; x=1772665094; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=KDlu2MU6otwoSbCkU+fftZ3FYtld2RFagUahdPSvMkA=; b=VX226waJzECz4hWB/jr/mMu0JoFbFRIUrz/0c4g7oY9lrE9KEefUZt3HfJFO6Pncxj j4m5udUMmKq+1OrV54/5i2D6WsV/JacKBs/Y33ikvbPqG/Kdu32dU9oiPt58Ppefz2hJ 6A5lCZcZs2P2abn2gUP5TQqEQT1cOJZ/0UDPklBgUTvUb3BX/lR/rWaTWHS+hCXbFico T3+5nNZUqKAhH/q1BfUtnZ62+4Av4QGZAvp7n5Q7EFTS4jSuU/cwvfteTDhklnfJ89Co Vg56xZ8mpNz940cOXZ/3ILeDeKbAaiDvBnJi9LoJOD71OJAGjV/DCIMXA3lrl/cFBN00 sgcw== X-Forwarded-Encrypted: i=1; AJvYcCUDydxtHadfxSzGtj0PFLuHNHmx+qNwNnXRAYK9tYXdbGROEpopkGrMdVbjTHFD2F3D/GyNix6SVV9pm/U=@vger.kernel.org X-Gm-Message-State: AOJu0YxX2I6pNkSgoHtz7uUPISMYo2/ud0MsyukCK+742wZm/XoGvhei VrbeYf8ZyK60tm7qNi/MCXAkPIBu5yFVjNiHpYB6QAYudpGn1XXHoS+J X-Gm-Gg: ATEYQzxQIIQELsfmPTiM1GE2NQ5Y7uP4EXdXIli8JQe6VpVC41y7loDK9+NJQqNbB6V +3T9fO5XuHM/w0FL+XzDAzkAQ/rfG25Ez4GiEekfU28RaMyi1NQ2QJUZrTWgIz9pH7HyxYwykso Zy1Qo8gyCeEmSp2IbygT5aHQ49C2Q51ioJNGZbTx3iuHqa9x2dHv4Tf/0sv/blqglJm4TbSE/37 jTOKWZCqsfsbMgilhj4sV2LWsjUjLTgNfCuwLC/KquQgaLedNLNpKEJVnac1jlP3vuSCxlUrurl kEXNm9Z0rP4I04fnj6C7O8gw/G/lIARFbaUgaTeAySwto/g3X3n9q/59gZ8exAyPkYt9nPV5zn1 RsUybdkbMWhuQqZe6HXwtBJDrnonAgvs+Z/j3UAQrb34z4mooVTn4cpUOICRKHvheQ0YxakQfEG JZOHy0pYdwW8dpiZI1M606ukrbKBGOes6rIBs5f4yuOUcozSQkayhk7D1E0XV8a64hK1kBcF7oH u0= X-Received: by 2002:a05:600c:5020:b0:483:b01c:9508 with SMTP id 5b1f17b1804b1-483c3da0abdmr989395e9.2.1772060294043; Wed, 25 Feb 2026 14:58:14 -0800 (PST) Received: from pumpkin (82-69-66-36.dsl.in-addr.zen.co.uk. [82.69.66.36]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43990c38516sm6590969f8f.30.2026.02.25.14.58.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Feb 2026 14:58:13 -0800 (PST) Date: Wed, 25 Feb 2026 22:58:12 +0000 From: David Laight To: Thomas =?UTF-8?B?V2Vpw59zY2h1aA==?= Cc: Willy Tarreau , linux-kernel@vger.kernel.org, Cheng Li Subject: Re: [PATCH v3 next 05/17] tools/nolibc: Implement strerror() in terms of strerror_r() Message-ID: <20260225225812.2e781973@pumpkin> In-Reply-To: <1637d7b3-986f-45fe-a253-9b53187bf397@t-8ch.de> References: <20260223101735.2922-1-david.laight.linux@gmail.com> <20260223101735.2922-6-david.laight.linux@gmail.com> <1637d7b3-986f-45fe-a253-9b53187bf397@t-8ch.de> X-Mailer: Claws Mail 4.1.1 (GTK 3.24.38; arm-unknown-linux-gnueabihf) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On Wed, 25 Feb 2026 23:09:25 +0100 Thomas Wei=C3=9Fschuh wrote: > On 2026-02-23 10:17:23+0000, david.laight.linux@gmail.com wrote: > > From: David Laight > >=20 > > strerror() can be the only part of a program that has a .data section. > > This requres 4k in the program file. > >=20 > > Add a simple implementation of strerror_r() (ignores the length) and > > use that in strerror() so that the "errno=3D" string is copied at run-t= ime. > > Use __builtin_memcpy() because that optimises away the input string > > and just writes the required constants to the target buffer. > >=20 > > Put the check for NOLIBC_IGNORE_ERRNO into strerror_r(). > > Always call strerror() from __nolibc_printf(). =20 >=20 > Why? >=20 > > Code size change largely depends on whether the inlining decision for > > strerror() changes. > >=20 > > Change the tests to use the normal EXPECT_VFPRINTF() when testing %m. > > Skip the tests when !is_nolibc. > >=20 > > Signed-off-by: David Laight > > --- > >=20 > > New patch for v3. > >=20 > > tools/include/nolibc/stdio.h | 29 ++++++++++++++------ > > tools/testing/selftests/nolibc/nolibc-test.c | 20 ++------------ > > 2 files changed, 23 insertions(+), 26 deletions(-) > >=20 > > diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h > > index 233318b0d0f0..2267f50d03b4 100644 > > --- a/tools/include/nolibc/stdio.h > > +++ b/tools/include/nolibc/stdio.h > > @@ -373,11 +373,7 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_= t state, size_t n, const char > > outstr=3D"(null)"; > > } > > else if (c =3D=3D 'm') { > > -#ifdef NOLIBC_IGNORE_ERRNO > > - outstr =3D "unknown error"; > > -#else > > outstr =3D strerror(errno); > > -#endif /* NOLIBC_IGNORE_ERRNO */ > > } > > else if (c =3D=3D '%') { > > /* queue it verbatim */ > > @@ -682,14 +678,31 @@ int setvbuf(FILE *stream __attribute__((unused)), > > return 0; > > } > > =20 > > +static __attribute__((unused,)) > > +int strerror_r(int errnum, char *buf, size_t buflen __attribute__((unu= sed))) =20 >=20 > This is the GNU variant, but the XSI variant would be better. man strerror gives me: int strerror_r(int errnum, char buf[.buflen], size_t buflen); /* XSI-compliant */ char *strerror_r(int errnum, char buf[.buflen], size_t buflen); /* GNU-specific */ so I implemented the one that returns the length. >=20 > Why is the buflen parameter not used? Because the i64toa_r() code doesn't have a buffer length parameter. I could add one, but it would be effectively unused everywhere else. Or I could add extra code that did extra copies (etc), but in practise the buffer will be long enough (given the short output) and the limited number of programs that use nolibc. Not that truncating the output makes any sense. The best would be "?", "errno=3D?" or "errno=3Dvalue" for len > 17. Using strerror_r() came from a discussion with Willy. He wanted to avoid the static initialised data and it looks better to have strerror() implemented using strerror_r(). =20 >=20 > > +{ > > +#ifdef NOLIBC_IGNORE_ERRNO =20 >=20 > Why did this move here? > The application can have error numbers without errno. Where would they come from. ISTR there are a small number of unusual functions that do return an errno value - but nothing common. >=20 > > + __builtin_memcpy(buf, "unknown error", 14); > > + return 13; =20 >=20 > > +#else > > + __builtin_memcpy(buf, "errno=3D", 6); > > + return 6 + i64toa_r(errnum, buf + 6); > > +#endif > > +} > > + > > static __attribute__((unused)) > > -const char *strerror(int errno) > > +const char *strerror(int errnum) =20 >=20 > Good point. But also a candidate for its own patch. >=20 > > { > > - static char buf[18] =3D "errno=3D"; > > + static char buf[18]; > > + char *b =3D buf; > > + > > + /* Force gcc to use 'register offset' to access buf[]. */ > > + _NOLIBC_OPTIMIZER_HIDE_VAR(b); > > =20 > > - i64toa_r(errno, &buf[6]); > > + /* Use strerror_r() to avoid having the only .data in small programs.= */ > > + strerror_r(errnum, b, sizeof(buf)); > > =20 > > - return buf; > > + return b; > > } > > =20 > > #endif /* _NOLIBC_STDIO_H */ > > diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testi= ng/selftests/nolibc/nolibc-test.c > > index 029ed63e1ae4..61968fdfeec0 100644 > > --- a/tools/testing/selftests/nolibc/nolibc-test.c > > +++ b/tools/testing/selftests/nolibc/nolibc-test.c > > @@ -1793,23 +1793,6 @@ static int test_scanf(void) > > return 0; > > } > > =20 > > -int test_strerror(void) > > -{ > > - char buf[100]; > > - ssize_t ret; > > - > > - memset(buf, 'A', sizeof(buf)); > > - > > - errno =3D EINVAL; > > - ret =3D snprintf(buf, sizeof(buf), "%m"); > > - if (is_nolibc) { > > - if (ret < 6 || memcmp(buf, "errno=3D", 6)) > > - return 1; > > - } > > - > > - return 0; > > -} > > - > > static int test_printf_error(void) > > { > > int fd, ret, saved_errno; > > @@ -1859,8 +1842,9 @@ static int run_printf(int min, int max) > > CASE_TEST(string_width); EXPECT_VFPRINTF(1, " 1", "%10s", "1= "); break; > > CASE_TEST(number_width); EXPECT_VFPRINTF(1, " 1", "%10d", 1)= ; break; > > CASE_TEST(width_trunc); EXPECT_VFPRINTF(1, " = 1", "%30d", 1); break; > > + CASE_TEST(errno); EXPECT_VFPRINTF(is_nolibc, "22:errno=3D22",= "%d:%m", errno=3D22); break; > > + CASE_TEST(errno-neg); EXPECT_VFPRINTF(is_nolibc, "-22: errno=3D= -22", "%d:%12m", errno=3D-22); break; =20 >=20 > Assigning errno from the printf argument is sneaky. That's not 'sneaky', I can do 'proper sneaky' :-) > Please avoid sneakyness. How about: CASE_TEST(errno); errno =3D 22; EXPECT_VFPRINTF(is_nolibc, "errno= =3D22", "%m"); break; David >=20 > > CASE_TEST(scanf); EXPECT_ZR(1, test_scanf()); break; > > - CASE_TEST(strerror); EXPECT_ZR(1, test_strerror()); break; > > CASE_TEST(printf_error); EXPECT_ZR(1, test_printf_error()); break; > > case __LINE__: > > return ret; /* must be last */ > > --=20 > > 2.39.5 > > =20