diff mbox

[PATCH/RFC] m68k: Add -ffreestanding to KBUILD_CFLAGS

Message ID 20130410152229.GC17541@sepie.suse.cz (mailing list archive)
State New, archived
Headers show

Commit Message

Michal Marek April 10, 2013, 3:22 p.m. UTC
On Wed, Apr 10, 2013 at 04:19:14PM +0200, Geert Uytterhoeven wrote:
> Thanks for the patch, but modpost still fails with
> 
> ERROR: "strlen" [net/ipv4/ip_tunnel.ko] undefined!

OK OK, I am convinced. Then how about this? If you prefer speed over
size, the the other option is to add

size_t strlen(const char *s)
{
       return __kernel_strlen(s);
}
EXPORT_SYMBOL(strlen);

to arch/m68k/lib/string.c. On a related note, arch/m68k/lib/string.c is
built only in the CONFIG_MMU case, whereas asm/string.h is shared.

Michal


From 1b89666d246bcc2bfc4c9e1bdfd1dbd1dafe2e2f Mon Sep 17 00:00:00 2001
From: Michal Marek <mmarek@suse.cz>
Date: Wed, 10 Apr 2013 16:45:21 +0200
Subject: [PATCH] m68k: Remove inline strlen() implementation

GCC can replace a strncat() call with constant second argument into a
strlen + store, which results in a link error:

ERROR: "strlen" [net/ipv4/ip_tunnel.ko] undefined!

The inline function is a simple for loop in C. Other architectures
either use an asm optimized variant, or use the generic function from
lib/string.c.

Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Michal Marek <mmarek@suse.cz>
---
 arch/m68k/include/asm/string.h |   14 --------------
 arch/m68k/lib/string.c         |    2 +-
 2 files changed, 1 insertion(+), 15 deletions(-)

Comments

Geert Uytterhoeven April 11, 2013, 6:04 p.m. UTC | #1
On Wed, Apr 10, 2013 at 5:22 PM, Michal Marek <mmarek@suse.cz> wrote:
> Subject: [PATCH] m68k: Remove inline strlen() implementation
>
> GCC can replace a strncat() call with constant second argument into a
> strlen + store, which results in a link error:
>
> ERROR: "strlen" [net/ipv4/ip_tunnel.ko] undefined!
>
> The inline function is a simple for loop in C. Other architectures
> either use an asm optimized variant, or use the generic function from
> lib/string.c.
>
> Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
> Signed-off-by: Michal Marek <mmarek@suse.cz>

Thanks, this one works. Let me do some measurements...

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Geert Uytterhoeven April 12, 2013, 7:47 p.m. UTC | #2
On Thu, Apr 11, 2013 at 8:04 PM, Geert Uytterhoeven
<geert@linux-m68k.org> wrote:
> On Wed, Apr 10, 2013 at 5:22 PM, Michal Marek <mmarek@suse.cz> wrote:
>> Subject: [PATCH] m68k: Remove inline strlen() implementation
>>
>> GCC can replace a strncat() call with constant second argument into a
>> strlen + store, which results in a link error:
>>
>> ERROR: "strlen" [net/ipv4/ip_tunnel.ko] undefined!
>>
>> The inline function is a simple for loop in C. Other architectures
>> either use an asm optimized variant, or use the generic function from
>> lib/string.c.
>>
>> Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
>> Signed-off-by: Michal Marek <mmarek@suse.cz>
>
> Thanks, this one works. Let me do some measurements...

No visible impact on size for a typical build; the increase in .text
is offset by
the decrease in .data:

-      .text : 0x00001000 - 0x002aab64   (2727 KiB)
-      .data : 0x002ad938 - 0x00392148   ( 915 KiB)
+      .text : 0x00001000 - 0x002aac74   (2728 KiB)
+      .data : 0x002ada48 - 0x00392148   ( 914 KiB)

On Wed, Apr 10, 2013 at 5:22 PM, Michal Marek <mmarek@suse.cz> wrote:
> On Wed, Apr 10, 2013 at 04:19:14PM +0200, Geert Uytterhoeven wrote:
>> Thanks for the patch, but modpost still fails with
>>
>> ERROR: "strlen" [net/ipv4/ip_tunnel.ko] undefined!
>
> OK OK, I am convinced. Then how about this? If you prefer speed over
> size, the the other option is to add
>
> size_t strlen(const char *s)
> {
>        return __kernel_strlen(s);
> }
> EXPORT_SYMBOL(strlen);
>
> to arch/m68k/lib/string.c.

Interestingly, this also doesn't work. It turns out none of the
symbols defined in
this file (currently strcpy and strcat) end up in vmlinux.

As we've been stripping code from string.c, we've been left with just
a few symbols
that are typically never referenced, so the whole string.o in
arch/m68k/lib/lib.a
is not included in the final vmlinux.

So more stringectomy to do...

> On a related note, arch/m68k/lib/string.c is
> built only in the CONFIG_MMU case, whereas asm/string.h is shared.

So due to the above, this difference is mostly moot ;-)

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/m68k/include/asm/string.h b/arch/m68k/include/asm/string.h
index 3219845..9aea9f1 100644
--- a/arch/m68k/include/asm/string.h
+++ b/arch/m68k/include/asm/string.h
@@ -4,15 +4,6 @@ 
 #include <linux/types.h>
 #include <linux/compiler.h>
 
-static inline size_t __kernel_strlen(const char *s)
-{
-	const char *sc;
-
-	for (sc = s; *sc++; )
-		;
-	return sc - s - 1;
-}
-
 static inline char *__kernel_strcpy(char *dest, const char *src)
 {
 	char *xdest = dest;
@@ -27,11 +18,6 @@  static inline char *__kernel_strcpy(char *dest, const char *src)
 
 #ifndef __IN_STRING_C
 
-#define __HAVE_ARCH_STRLEN
-#define strlen(s)	(__builtin_constant_p(s) ?	\
-			 __builtin_strlen(s) :		\
-			 __kernel_strlen(s))
-
 #define __HAVE_ARCH_STRNLEN
 static inline size_t strnlen(const char *s, size_t count)
 {
diff --git a/arch/m68k/lib/string.c b/arch/m68k/lib/string.c
index b9a57ab..4d61fa8 100644
--- a/arch/m68k/lib/string.c
+++ b/arch/m68k/lib/string.c
@@ -17,6 +17,6 @@  EXPORT_SYMBOL(strcpy);
 
 char *strcat(char *dest, const char *src)
 {
-	return __kernel_strcpy(dest + __kernel_strlen(dest), src);
+	return __kernel_strcpy(dest + strlen(dest), src);
 }
 EXPORT_SYMBOL(strcat);