* [PATCH] fix string inlines on s390-{32,64} and i486+
2007-11-22 16:43 [PATCH] string inlines on s390-{32,64} Martin Schwidefsky
@ 2007-12-12 13:13 ` Jakub Jelinek
0 siblings, 0 replies; 2+ messages in thread
From: Jakub Jelinek @ 2007-12-12 13:13 UTC (permalink / raw)
To: Ulrich Drepper, Martin Schwidefsky; +Cc: Glibc hackers
On Thu, Nov 22, 2007 at 05:43:48PM +0100, Martin Schwidefsky wrote:
> one of the reasons why the current CVS doesn't compile on s390-{32,64}
> is because of conflicting definitions for strlen, strcpy, strncpy, strcat
> and strncat e.g. for compiling debug/warning-nop.c. On x86 this doesn't
> seem to happen because the five function are defined as macros. The
> easiest way to fix this on s390 is to define these five functions as
> macros as well.
I don't see how this can work if GCC decides not to inline these and
-D_FORTIFY_SOURCE is not used. strlen will expand to __strlen_g,
__strlen_g extern inline not inlined, but libc.so.6 doesn't export __strlen_g
(see the !defined _FORCE_INLINES guards). Rather than exporting these
it is IMHO better to add __asm magic (these headers are only used with
GCC, so I don't think we need to bother with
__STRING_INLINE size_t __REDIRECT (__strlen_g, (__const char *), strlen);
and can use __asm__ directly, but if you want, I can change that to
__REDIRECT.
i486+ has the same problem, see
https://bugzilla.redhat.com/show_bug.cgi?id=408731
https://bugzilla.redhat.com/show_bug.cgi?id=371711
I've verified on:
#define foo(x) __foo(x)
extern inline __attribute__((__gnu_inline__)) int __foo (int) __asm ("foo");
extern inline __attribute__((__gnu_inline__)) int __foo (int x) { return x + 1; }
#ifdef FS
#undef foo
extern inline __attribute__((__gnu_inline__)) int foo (int x) { return x + 2; }
#endif
int bar (void)
{
return foo (2);
}
that this works fine with -O2{, -fno-inline}{, -DFS} even with much older GCC
versions, e.g. 3.2.
2007-12-12 Jakub Jelinek <jakub@redhat.com>
* sysdeps/i386/i486/bits/string.h (memmove): Define as macro.
(memmove): Rename to __memmove_g, with __asm__ ("memmove").
* sysdeps/s390/bits/string.h (__strlen_g, __strcpy_g, __strncpy_g,
__strcat_g, __strncat_g): Add __asm__.
--- libc/sysdeps/i386/i486/bits/string.h.jj 2007-09-18 21:33:32.000000000 +0200
+++ libc/sysdeps/i386/i486/bits/string.h 2007-12-12 13:42:01.000000000 +0100
@@ -145,8 +145,13 @@ __memcpy_g (void *__dest, __const void *
#ifndef _FORCE_INLINES
/* Copy N bytes of SRC to DEST, guaranteeing
correct behavior for overlapping strings. */
+#define memmove(dest, src, n) __memmove_g (dest, src, n)
+
+__STRING_INLINE void *__memmove_g (void *, __const void *, size_t)
+ __asm__ ("memmove");
+
__STRING_INLINE void *
-memmove (void *__dest, __const void *__src, size_t __n)
+__memmove_g (void *__dest, __const void *__src, size_t __n)
{
register unsigned long int __d0, __d1, __d2;
register void *__tmp = __dest;
--- libc/sysdeps/s390/bits/string.h.jj 2007-12-12 11:54:36.000000000 +0100
+++ libc/sysdeps/s390/bits/string.h 2007-12-12 13:55:48.000000000 +0100
@@ -42,6 +42,8 @@
#ifndef _FORCE_INLINES
#define strlen(str) __strlen_g ((str))
+__STRING_INLINE size_t __strlen_g (__const char *) __asm__ ("strlen");
+
__STRING_INLINE size_t
__strlen_g (__const char *__str)
{
@@ -63,6 +65,8 @@ __strlen_g (__const char *__str)
#ifndef _FORCE_INLINES
#define strcpy(dest, src) __strcpy_g ((dest), (src))
+__STRING_INLINE char *__strcpy_g (char *, __const char *) __asm ("strcpy");
+
__STRING_INLINE char *
__strcpy_g (char *__dest, __const char *__src)
{
@@ -81,6 +85,9 @@ __strcpy_g (char *__dest, __const char *
#ifndef _FORCE_INLINES
#define strncpy(dest, src, n) __strncpy_g ((dest), (src), (n))
+__STRING_INLINE char *__strncpy_g (char *, __const char *, size_t)
+ __asm__ ("strncpy");
+
__STRING_INLINE char *
__strncpy_g (char *__dest, __const char *__src, size_t __n)
{
@@ -122,8 +129,10 @@ __strncpy_g (char *__dest, __const char
#ifndef _FORCE_INLINES
#define strcat(dest, src) __strcat_g ((dest), (src))
+__STRING_INLINE char *__strcat_g (char *, __const char *) __asm__ ("strcat");
+
__STRING_INLINE char *
-__strcat_g(char *__dest, const char *__src)
+__strcat_g (char *__dest, __const char *__src)
{
char *__ret = __dest;
char *__ptr, *__tmp;
@@ -152,6 +161,9 @@ __strcat_g(char *__dest, const char *__s
#ifndef _FORCE_INLINES
#define strncat(dest, src, n) __strncat_g ((dest), (src), (n))
+__STRING_INLINE char *__strncat_g (char *, __const char *, size_t)
+ __asm__ ("strncat");
+
__STRING_INLINE char *
__strncat_g (char *__dest, __const char *__src, size_t __n)
{
Jakub
^ permalink raw reply [flat|nested] 2+ messages in thread