All of lore.kernel.org
 help / color / mirror / Atom feed
From: Charles Mirabile <cmirabil@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: "Charles Mirabile" <cmirabil@redhat.com>,
	"Willy Tarreau" <w@1wt.eu>,
	"Thomas Weißschuh" <linux@weissschuh.net>,
	"Ammar Faizi" <ammarfaizi2@gnuweeb.org>
Subject: [PATCH] nolibc/stdlib: Improve `getauxval(3)` implementation
Date: Tue, 16 Jan 2024 13:11:47 -0500	[thread overview]
Message-ID: <20240116181147.2230944-1-cmirabil@redhat.com> (raw)

Previously the getauxval function checked for a doubly null entry (i.e.
one whose type and value both were 0) in the auxv array before exiting
the loop.

At least on x86-64, the ABI only specifies that one more long will be
present with value 0 (type AT_NULL) after the pairs of auxv entries.
Whether or not it has a corresponding value is unspecified. This value is
present on linux, but there is no reason to check it as simply seeing an
auxv entry whose type value is AT_NULL should be enough.

This is a matter of taste, but I think processing the data in a structured
way by coercing it into an array of type value pairs, using multiple
return style, and a for loop with a clear exit condition is more readable
than the existing infinite loop with multiple exit points and a return
value variable.

I also added a call to set errno to ENOENT when the entry is not found as
glibc does which allows programs to disambiguate between the case of an
auxv that is not present, and one that is, but with value zero.

Fixes: c61a078015f3 ("nolibc/stdlib: Implement `getauxval(3)` function")
Signed-off-by: Charles Mirabile <cmirabil@redhat.com>
---
 tools/include/nolibc/stdlib.h | 34 +++++++++++++---------------------
 1 file changed, 13 insertions(+), 21 deletions(-)

diff --git a/tools/include/nolibc/stdlib.h b/tools/include/nolibc/stdlib.h
index bacfd35c5156..47be99c5a539 100644
--- a/tools/include/nolibc/stdlib.h
+++ b/tools/include/nolibc/stdlib.h
@@ -104,27 +104,19 @@ char *getenv(const char *name)
 static __attribute__((unused))
 unsigned long getauxval(unsigned long type)
 {
-	const unsigned long *auxv = _auxv;
-	unsigned long ret;
-
-	if (!auxv)
-		return 0;
-
-	while (1) {
-		if (!auxv[0] && !auxv[1]) {
-			ret = 0;
-			break;
-		}
-
-		if (auxv[0] == type) {
-			ret = auxv[1];
-			break;
-		}
-
-		auxv += 2;
-	}
-
-	return ret;
+	const struct {
+		unsigned long type, val;
+	} *auxv = (void *)_auxv;
+
+	if (!auxv || !type)
+		goto out;
+
+	for (; auxv->type; ++auxv)
+		if (auxv->type == type)
+			return auxv->val;
+out:
+	SET_ERRNO(ENOENT);
+	return 0;
 }
 
 static __attribute__((unused))
-- 
2.41.0


             reply	other threads:[~2024-01-16 18:12 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-16 18:11 Charles Mirabile [this message]
2024-01-16 18:52 ` [PATCH] nolibc/stdlib: Improve `getauxval(3)` implementation Ammar Faizi
2024-01-16 18:58   ` Willy Tarreau
2024-01-16 18:59     ` Willy Tarreau
2024-01-16 19:11       ` Ammar Faizi
2024-01-16 19:23         ` Ammar Faizi
2024-01-16 19:46           ` Willy Tarreau
2024-01-16 19:51             ` Ammar Faizi

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=20240116181147.2230944-1-cmirabil@redhat.com \
    --to=cmirabil@redhat.com \
    --cc=ammarfaizi2@gnuweeb.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@weissschuh.net \
    --cc=w@1wt.eu \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.