Skip to content

Commit 3d3cd43

Browse files
committed
patches: Add wcslen() series to every tree that needs it
Signed-off-by: Nathan Chancellor <[email protected]>
1 parent fe4844a commit 3d3cd43

File tree

57 files changed

+3458
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+3458
-0
lines changed

patches/5.10/series

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
v3_20250328_nathan_include_move_typedefs_in_nls_h_to_their_own_header.patch
2+
v3_20250328_nathan_lib_string_c_add_wcslen.patch
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
From git@z Thu Jan 1 00:00:00 1970
2+
Subject: [PATCH v3 1/2] include: Move typedefs in nls.h to their own header
3+
From: Nathan Chancellor <[email protected]>
4+
Date: Fri, 28 Mar 2025 12:26:31 -0700
5+
Message-Id: <20250328-string-add-wcslen-for-llvm-opt-v3-1-a180b4c0c1c4@kernel.org>
6+
MIME-Version: 1.0
7+
Content-Type: text/plain; charset="utf-8"
8+
Content-Transfer-Encoding: 7bit
9+
10+
In order to allow commonly included headers such as string.h to access
11+
typedefs such as wchar_t without running into issues with the rest of
12+
the NLS library, refactor the typedefs out into their own header that
13+
can be included in a much safer manner.
14+
15+
16+
Reviewed-by: Andy Shevchenko <[email protected]>
17+
Link: https://lore.kernel.org/r/20250328-string-add-wcslen-for-llvm-opt-v3-1-a180b4c0c1c4@kernel.org
18+
Signed-off-by: Nathan Chancellor <[email protected]>
19+
---
20+
include/linux/nls.h | 19 +------------------
21+
include/linux/nls_types.h | 26 ++++++++++++++++++++++++++
22+
2 files changed, 27 insertions(+), 18 deletions(-)
23+
24+
diff --git a/include/linux/nls.h b/include/linux/nls.h
25+
index e0bf8367b274..3d416d1f60b6 100644
26+
--- a/include/linux/nls.h
27+
+++ b/include/linux/nls.h
28+
@@ -3,24 +3,7 @@
29+
#define _LINUX_NLS_H
30+
31+
#include <linux/init.h>
32+
-
33+
-/* Unicode has changed over the years. Unicode code points no longer
34+
- * fit into 16 bits; as of Unicode 5 valid code points range from 0
35+
- * to 0x10ffff (17 planes, where each plane holds 65536 code points).
36+
- *
37+
- * The original decision to represent Unicode characters as 16-bit
38+
- * wchar_t values is now outdated. But plane 0 still includes the
39+
- * most commonly used characters, so we will retain it. The newer
40+
- * 32-bit unicode_t type can be used when it is necessary to
41+
- * represent the full Unicode character set.
42+
- */
43+
-
44+
-/* Plane-0 Unicode character */
45+
-typedef u16 wchar_t;
46+
-#define MAX_WCHAR_T 0xffff
47+
-
48+
-/* Arbitrary Unicode character */
49+
-typedef u32 unicode_t;
50+
+#include <linux/nls_types.h>
51+
52+
struct nls_table {
53+
const char *charset;
54+
diff --git a/include/linux/nls_types.h b/include/linux/nls_types.h
55+
new file mode 100644
56+
index 000000000000..9479df1016da
57+
--- /dev/null
58+
+++ b/include/linux/nls_types.h
59+
@@ -0,0 +1,26 @@
60+
+/* SPDX-License-Identifier: GPL-2.0 */
61+
+#ifndef _LINUX_NLS_TYPES_H
62+
+#define _LINUX_NLS_TYPES_H
63+
+
64+
+#include <linux/types.h>
65+
+
66+
+/*
67+
+ * Unicode has changed over the years. Unicode code points no longer
68+
+ * fit into 16 bits; as of Unicode 5 valid code points range from 0
69+
+ * to 0x10ffff (17 planes, where each plane holds 65536 code points).
70+
+ *
71+
+ * The original decision to represent Unicode characters as 16-bit
72+
+ * wchar_t values is now outdated. But plane 0 still includes the
73+
+ * most commonly used characters, so we will retain it. The newer
74+
+ * 32-bit unicode_t type can be used when it is necessary to
75+
+ * represent the full Unicode character set.
76+
+ */
77+
+
78+
+/* Plane-0 Unicode character */
79+
+typedef u16 wchar_t;
80+
+#define MAX_WCHAR_T 0xffff
81+
+
82+
+/* Arbitrary Unicode character */
83+
+typedef u32 unicode_t;
84+
+
85+
+#endif /* _LINUX_NLS_TYPES_H */
86+
--
87+
2.49.0
88+
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
From git@z Thu Jan 1 00:00:00 1970
2+
Subject: [PATCH v3 2/2] lib/string.c: Add wcslen()
3+
From: Nathan Chancellor <[email protected]>
4+
Date: Fri, 28 Mar 2025 12:26:32 -0700
5+
Message-Id: <20250328-string-add-wcslen-for-llvm-opt-v3-2-a180b4c0c1c4@kernel.org>
6+
MIME-Version: 1.0
7+
Content-Type: text/plain; charset="utf-8"
8+
Content-Transfer-Encoding: 7bit
9+
10+
A recent optimization change in LLVM [1] aims to transform certain loop
11+
idioms into calls to strlen() or wcslen(). This change transforms the
12+
first while loop in UniStrcat() into a call to wcslen(), breaking the
13+
build when UniStrcat() gets inlined into alloc_path_with_tree_prefix():
14+
15+
ld.lld: error: undefined symbol: wcslen
16+
>>> referenced by nls_ucs2_utils.h:54 (fs/smb/client/../../nls/nls_ucs2_utils.h:54)
17+
>>> vmlinux.o:(alloc_path_with_tree_prefix)
18+
>>> referenced by nls_ucs2_utils.h:54 (fs/smb/client/../../nls/nls_ucs2_utils.h:54)
19+
>>> vmlinux.o:(alloc_path_with_tree_prefix)
20+
21+
The kernel does not build with '-ffreestanding' (which would avoid this
22+
transformation) because it does want libcall optimizations in general
23+
and turning on '-ffreestanding' disables the majority of them. While
24+
'-fno-builtin-wcslen' would be more targeted at the problem, it does not
25+
work with LTO.
26+
27+
Add a basic wcslen() to avoid this linkage failure. While no
28+
architecture or FORTIFY_SOURCE overrides this, add it to string.c
29+
instead of string_helpers.c so that it is built with '-ffreestanding',
30+
otherwise the compiler might transform it into a call to itself.
31+
32+
33+
Link: https://github.com/llvm/llvm-project/commit/9694844d7e36fd5e01011ab56b64f27b867aa72d [1]
34+
Link: https://lore.kernel.org/r/20250328-string-add-wcslen-for-llvm-opt-v3-2-a180b4c0c1c4@kernel.org
35+
Signed-off-by: Nathan Chancellor <[email protected]>
36+
---
37+
include/linux/string.h | 2 ++
38+
lib/string.c | 11 +++++++++++
39+
2 files changed, 13 insertions(+)
40+
41+
diff --git a/include/linux/string.h b/include/linux/string.h
42+
index 0cef345a6e87..8fd28541abac 100644
43+
--- a/include/linux/string.h
44+
+++ b/include/linux/string.h
45+
@@ -3,6 +3,7 @@
46+
#define _LINUX_STRING_H_
47+
48+
#include <linux/compiler.h> /* for inline */
49+
+#include <linux/nls_types.h> /* for wchar_t */
50+
#include <linux/types.h> /* for size_t */
51+
#include <linux/stddef.h> /* for NULL */
52+
#include <stdarg.h>
53+
@@ -89,6 +90,7 @@ extern __kernel_size_t strlen(const char *);
54+
#ifndef __HAVE_ARCH_STRNLEN
55+
extern __kernel_size_t strnlen(const char *,__kernel_size_t);
56+
#endif
57+
+__kernel_size_t wcslen(const wchar_t *s);
58+
#ifndef __HAVE_ARCH_STRPBRK
59+
extern char * strpbrk(const char *,const char *);
60+
#endif
61+
diff --git a/lib/string.c b/lib/string.c
62+
index 4288e0158d47..3cd867819198 100644
63+
--- a/lib/string.c
64+
+++ b/lib/string.c
65+
@@ -27,6 +27,7 @@
66+
#include <linux/export.h>
67+
#include <linux/bug.h>
68+
#include <linux/errno.h>
69+
+#include <linux/nls_types.h>
70+
#include <linux/slab.h>
71+
72+
#include <asm/byteorder.h>
73+
@@ -589,6 +590,16 @@ size_t strnlen(const char *s, size_t count)
74+
EXPORT_SYMBOL(strnlen);
75+
#endif
76+
77+
+size_t wcslen(const wchar_t *s)
78+
+{
79+
+ const wchar_t *sc;
80+
+
81+
+ for (sc = s; *sc != '\0'; ++sc)
82+
+ /* nothing */;
83+
+ return sc - s;
84+
+}
85+
+EXPORT_SYMBOL(wcslen);
86+
+
87+
#ifndef __HAVE_ARCH_STRSPN
88+
/**
89+
* strspn - Calculate the length of the initial substring of @s which only contain letters in @accept
90+
--
91+
2.49.0
92+

patches/5.15/series

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
v3_20250328_nathan_include_move_typedefs_in_nls_h_to_their_own_header.patch
2+
v3_20250328_nathan_lib_string_c_add_wcslen.patch
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
From git@z Thu Jan 1 00:00:00 1970
2+
Subject: [PATCH v3 1/2] include: Move typedefs in nls.h to their own header
3+
From: Nathan Chancellor <[email protected]>
4+
Date: Fri, 28 Mar 2025 12:26:31 -0700
5+
Message-Id: <20250328-string-add-wcslen-for-llvm-opt-v3-1-a180b4c0c1c4@kernel.org>
6+
MIME-Version: 1.0
7+
Content-Type: text/plain; charset="utf-8"
8+
Content-Transfer-Encoding: 7bit
9+
10+
In order to allow commonly included headers such as string.h to access
11+
typedefs such as wchar_t without running into issues with the rest of
12+
the NLS library, refactor the typedefs out into their own header that
13+
can be included in a much safer manner.
14+
15+
16+
Reviewed-by: Andy Shevchenko <[email protected]>
17+
Link: https://lore.kernel.org/r/20250328-string-add-wcslen-for-llvm-opt-v3-1-a180b4c0c1c4@kernel.org
18+
Signed-off-by: Nathan Chancellor <[email protected]>
19+
---
20+
include/linux/nls.h | 19 +------------------
21+
include/linux/nls_types.h | 26 ++++++++++++++++++++++++++
22+
2 files changed, 27 insertions(+), 18 deletions(-)
23+
24+
diff --git a/include/linux/nls.h b/include/linux/nls.h
25+
index e0bf8367b274..3d416d1f60b6 100644
26+
--- a/include/linux/nls.h
27+
+++ b/include/linux/nls.h
28+
@@ -3,24 +3,7 @@
29+
#define _LINUX_NLS_H
30+
31+
#include <linux/init.h>
32+
-
33+
-/* Unicode has changed over the years. Unicode code points no longer
34+
- * fit into 16 bits; as of Unicode 5 valid code points range from 0
35+
- * to 0x10ffff (17 planes, where each plane holds 65536 code points).
36+
- *
37+
- * The original decision to represent Unicode characters as 16-bit
38+
- * wchar_t values is now outdated. But plane 0 still includes the
39+
- * most commonly used characters, so we will retain it. The newer
40+
- * 32-bit unicode_t type can be used when it is necessary to
41+
- * represent the full Unicode character set.
42+
- */
43+
-
44+
-/* Plane-0 Unicode character */
45+
-typedef u16 wchar_t;
46+
-#define MAX_WCHAR_T 0xffff
47+
-
48+
-/* Arbitrary Unicode character */
49+
-typedef u32 unicode_t;
50+
+#include <linux/nls_types.h>
51+
52+
struct nls_table {
53+
const char *charset;
54+
diff --git a/include/linux/nls_types.h b/include/linux/nls_types.h
55+
new file mode 100644
56+
index 000000000000..9479df1016da
57+
--- /dev/null
58+
+++ b/include/linux/nls_types.h
59+
@@ -0,0 +1,26 @@
60+
+/* SPDX-License-Identifier: GPL-2.0 */
61+
+#ifndef _LINUX_NLS_TYPES_H
62+
+#define _LINUX_NLS_TYPES_H
63+
+
64+
+#include <linux/types.h>
65+
+
66+
+/*
67+
+ * Unicode has changed over the years. Unicode code points no longer
68+
+ * fit into 16 bits; as of Unicode 5 valid code points range from 0
69+
+ * to 0x10ffff (17 planes, where each plane holds 65536 code points).
70+
+ *
71+
+ * The original decision to represent Unicode characters as 16-bit
72+
+ * wchar_t values is now outdated. But plane 0 still includes the
73+
+ * most commonly used characters, so we will retain it. The newer
74+
+ * 32-bit unicode_t type can be used when it is necessary to
75+
+ * represent the full Unicode character set.
76+
+ */
77+
+
78+
+/* Plane-0 Unicode character */
79+
+typedef u16 wchar_t;
80+
+#define MAX_WCHAR_T 0xffff
81+
+
82+
+/* Arbitrary Unicode character */
83+
+typedef u32 unicode_t;
84+
+
85+
+#endif /* _LINUX_NLS_TYPES_H */
86+
--
87+
2.49.0
88+
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
From git@z Thu Jan 1 00:00:00 1970
2+
Subject: [PATCH v3 2/2] lib/string.c: Add wcslen()
3+
From: Nathan Chancellor <[email protected]>
4+
Date: Fri, 28 Mar 2025 12:26:32 -0700
5+
Message-Id: <20250328-string-add-wcslen-for-llvm-opt-v3-2-a180b4c0c1c4@kernel.org>
6+
MIME-Version: 1.0
7+
Content-Type: text/plain; charset="utf-8"
8+
Content-Transfer-Encoding: 7bit
9+
10+
A recent optimization change in LLVM [1] aims to transform certain loop
11+
idioms into calls to strlen() or wcslen(). This change transforms the
12+
first while loop in UniStrcat() into a call to wcslen(), breaking the
13+
build when UniStrcat() gets inlined into alloc_path_with_tree_prefix():
14+
15+
ld.lld: error: undefined symbol: wcslen
16+
>>> referenced by nls_ucs2_utils.h:54 (fs/smb/client/../../nls/nls_ucs2_utils.h:54)
17+
>>> vmlinux.o:(alloc_path_with_tree_prefix)
18+
>>> referenced by nls_ucs2_utils.h:54 (fs/smb/client/../../nls/nls_ucs2_utils.h:54)
19+
>>> vmlinux.o:(alloc_path_with_tree_prefix)
20+
21+
The kernel does not build with '-ffreestanding' (which would avoid this
22+
transformation) because it does want libcall optimizations in general
23+
and turning on '-ffreestanding' disables the majority of them. While
24+
'-fno-builtin-wcslen' would be more targeted at the problem, it does not
25+
work with LTO.
26+
27+
Add a basic wcslen() to avoid this linkage failure. While no
28+
architecture or FORTIFY_SOURCE overrides this, add it to string.c
29+
instead of string_helpers.c so that it is built with '-ffreestanding',
30+
otherwise the compiler might transform it into a call to itself.
31+
32+
33+
Link: https://github.com/llvm/llvm-project/commit/9694844d7e36fd5e01011ab56b64f27b867aa72d [1]
34+
Link: https://lore.kernel.org/r/20250328-string-add-wcslen-for-llvm-opt-v3-2-a180b4c0c1c4@kernel.org
35+
Signed-off-by: Nathan Chancellor <[email protected]>
36+
---
37+
include/linux/string.h | 2 ++
38+
lib/string.c | 11 +++++++++++
39+
2 files changed, 13 insertions(+)
40+
41+
diff --git a/include/linux/string.h b/include/linux/string.h
42+
index 3b9f5abe5ee8..492d2bb6ef05 100644
43+
--- a/include/linux/string.h
44+
+++ b/include/linux/string.h
45+
@@ -7,6 +7,7 @@
46+
#include <linux/stddef.h> /* for NULL */
47+
#include <linux/err.h> /* for ERR_PTR() */
48+
#include <linux/errno.h> /* for E2BIG */
49+
+#include <linux/nls_types.h> /* for wchar_t */
50+
#include <linux/overflow.h> /* for check_mul_overflow() */
51+
#include <linux/stdarg.h>
52+
#include <uapi/linux/string.h>
53+
@@ -130,6 +131,7 @@ extern __kernel_size_t strlen(const char *);
54+
#ifndef __HAVE_ARCH_STRNLEN
55+
extern __kernel_size_t strnlen(const char *,__kernel_size_t);
56+
#endif
57+
+__kernel_size_t wcslen(const wchar_t *s);
58+
#ifndef __HAVE_ARCH_STRPBRK
59+
extern char * strpbrk(const char *,const char *);
60+
#endif
61+
diff --git a/lib/string.c b/lib/string.c
62+
index b2de45a581f4..7d2fded115f6 100644
63+
--- a/lib/string.c
64+
+++ b/lib/string.c
65+
@@ -27,6 +27,7 @@
66+
#include <linux/export.h>
67+
#include <linux/bug.h>
68+
#include <linux/errno.h>
69+
+#include <linux/nls_types.h>
70+
#include <linux/slab.h>
71+
72+
#include <asm/unaligned.h>
73+
@@ -587,6 +588,16 @@ size_t strnlen(const char *s, size_t count)
74+
EXPORT_SYMBOL(strnlen);
75+
#endif
76+
77+
+size_t wcslen(const wchar_t *s)
78+
+{
79+
+ const wchar_t *sc;
80+
+
81+
+ for (sc = s; *sc != '\0'; ++sc)
82+
+ /* nothing */;
83+
+ return sc - s;
84+
+}
85+
+EXPORT_SYMBOL(wcslen);
86+
+
87+
#ifndef __HAVE_ARCH_STRSPN
88+
/**
89+
* strspn - Calculate the length of the initial substring of @s which only contain letters in @accept
90+
--
91+
2.49.0
92+

patches/5.4/series

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
v3_20250328_nathan_include_move_typedefs_in_nls_h_to_their_own_header.patch
2+
v3_20250328_nathan_lib_string_c_add_wcslen.patch

0 commit comments

Comments
 (0)