[v2] tools/nolibc: completely remove optional environ support

Message ID 20230710-nolibc-environ-v2-1-78b0c465338f@weissschuh.net
State New
Headers
Series [v2] tools/nolibc: completely remove optional environ support |

Commit Message

Thomas Weißschuh July 10, 2023, 6:01 p.m. UTC
  In commit 52e423f5b93e ("tools/nolibc: export environ as a weak symbol on i386")
and friends the asm startup logic was extended to directly populate the
"environ" array.

This makes it impossible for "environ" to be dropped by the linker.
Therefore also drop the other logic to handle non-present "environ".

Also add a testcase to validate the initialization of environ.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
Changes in v2:
- add testcase to validate initialization and naming of environ as
  suggested by Willy
- Link to v1: https://lore.kernel.org/r/20230710-nolibc-environ-v1-1-173831573af6@weissschuh.net
---
 tools/include/nolibc/stdlib.h                | 12 ++----------
 tools/testing/selftests/nolibc/nolibc-test.c |  7 ++++---
 2 files changed, 6 insertions(+), 13 deletions(-)


---
base-commit: c9851cc968ac2ed87b83aee0cbec476b07d53a4c
change-id: 20230710-nolibc-environ-79f425ce6354

Best regards,
  

Comments

Willy Tarreau July 11, 2023, 7:16 a.m. UTC | #1
On Mon, Jul 10, 2023 at 08:01:34PM +0200, Thomas Weißschuh wrote:
> In commit 52e423f5b93e ("tools/nolibc: export environ as a weak symbol on i386")
> and friends the asm startup logic was extended to directly populate the
> "environ" array.
> 
> This makes it impossible for "environ" to be dropped by the linker.
> Therefore also drop the other logic to handle non-present "environ".
> 
> Also add a testcase to validate the initialization of environ.

Thank you Thomas, now pushed to the same branch.

Willy
  

Patch

diff --git a/tools/include/nolibc/stdlib.h b/tools/include/nolibc/stdlib.h
index 902162f80337..bacfd35c5156 100644
--- a/tools/include/nolibc/stdlib.h
+++ b/tools/include/nolibc/stdlib.h
@@ -83,11 +83,10 @@  void free(void *ptr)
  * declared as a char **, and must be terminated by a NULL (it is recommended
  * to set this variable to the "envp" argument of main()). If the requested
  * environment variable exists its value is returned otherwise NULL is
- * returned. getenv() is forcefully inlined so that the reference to "environ"
- * will be dropped if unused, even at -O0.
+ * returned.
  */
 static __attribute__((unused))
-char *_getenv(const char *name, char **environ)
+char *getenv(const char *name)
 {
 	int idx, i;
 
@@ -102,13 +101,6 @@  char *_getenv(const char *name, char **environ)
 	return NULL;
 }
 
-static __inline__ __attribute__((unused,always_inline))
-char *getenv(const char *name)
-{
-	extern char **environ;
-	return _getenv(name, environ);
-}
-
 static __attribute__((unused))
 unsigned long getauxval(unsigned long type)
 {
diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index ec0c20df76b2..f357bd815abc 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -44,8 +44,8 @@ 
 #define SINT_MAX_OF_TYPE(type) (((type)1 << (sizeof(type) * 8 - 2)) - (type)1 + ((type)1 << (sizeof(type) * 8 - 2)))
 #define SINT_MIN_OF_TYPE(type) (-SINT_MAX_OF_TYPE(type) - 1)
 
-/* will be used by nolibc by getenv() */
-char **environ;
+/* will be used to test initialization of environ */
+static char **test_envp;
 
 /* will be used by some test cases as readable file, please don't write it */
 static const char *argv0;
@@ -786,6 +786,7 @@  int run_stdlib(int min, int max)
 		 * test numbers.
 		 */
 		switch (test + __LINE__ + 1) {
+		CASE_TEST(environ);            EXPECT_PTREQ(1, environ, test_envp); break;
 		CASE_TEST(getenv_TERM);        EXPECT_STRNZ(1, getenv("TERM")); break;
 		CASE_TEST(getenv_blah);        EXPECT_STRZR(1, getenv("blah")); break;
 		CASE_TEST(setcmp_blah_blah);   EXPECT_EQ(1, strcmp("blah", "blah"), 0); break;
@@ -1119,7 +1120,7 @@  int main(int argc, char **argv, char **envp)
 	char *test;
 
 	argv0 = argv[0];
-	environ = envp;
+	test_envp = envp;
 
 	/* when called as init, it's possible that no console was opened, for
 	 * example if no /dev file system was provided. We'll check that fd#1