This is the mail archive of the libc-hacker@sourceware.org mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] fix string inlines on s390-{32,64} and i486+


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]