From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5810 invoked by alias); 7 Nov 2006 17:02:33 -0000 Received: (qmail 5741 invoked by uid 22791); 7 Nov 2006 17:02:31 -0000 X-Spam-Check-By: sourceware.org Received: from sunsite.ms.mff.cuni.cz (HELO sunsite.mff.cuni.cz) (195.113.15.26) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 07 Nov 2006 17:02:21 +0000 Received: from sunsite.mff.cuni.cz (sunsite.mff.cuni.cz [127.0.0.1]) by sunsite.mff.cuni.cz (8.13.1/8.13.1) with ESMTP id kA7H12Pd030334; Tue, 7 Nov 2006 18:01:02 +0100 Received: (from jj@localhost) by sunsite.mff.cuni.cz (8.13.1/8.13.1/Submit) id kA7H12rt030333; Tue, 7 Nov 2006 18:01:02 +0100 Date: Tue, 07 Nov 2006 17:02:00 -0000 From: Jakub Jelinek To: Ulrich Drepper Cc: Glibc hackers Subject: [PATCH] Fix errlist and siglist Message-ID: <20061107170101.GH5868@sunsite.mff.cuni.cz> Reply-To: Jakub Jelinek Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.1i Mailing-List: contact libc-hacker-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sourceware.org X-SW-Source: 2006-11/txt/msg00002.txt.bz2 Hi! When testing GCC 4.3 compiled glibc for ABI changes, I discovered that _sys_errlist etc. compatibility symbols all have wrong sizes (the same as the largest, default symver). The thing is that if GCC supports -fno-toplevel-reorder, we don't compile with -fno-unit-at-a-time and while -fno-toplevel-reorder results in quite similar behavior to -fno-unit-at-a-time wrt. reordering stuff, it is not 100% and what we do in errlist-compat.c and siglist.c is very fragile. Basically, we have to ensure that the associated .set comes before the .size directive, not after it (as .set copies also the symbol size). So, char bar [512]; asm (".set foo, bar\n\t.size foo, 256"); results in 256 byte foo symbol, while char bar [512]; asm (".size foo, 256\n\t.set foo, bar"); results in 512 byte foo symbol. The following patch introduces declare_symbol_alias macro instead of declare_symbol and makes it to act as strong_alias followed by declare_symbol, but always in the right order. This seems to work fine with both -fno-unit-at-a-time (tested GCC 4.1.x) and -fno-toplevel-reorder (tested GCC trunk). 2006-11-07 Jakub Jelinek * include/libc-symbols.h (declare_symbol): Rename to... (declare_symbol_alias): ... this. Add ORIGINAL argument, imply strong_alias (ORIGINAL, SYMBOL) in asm to make sure it preceedes .size directive. * sysdeps/gnu/errlist-compat.awk: Adjust for declare_symbol_alias changes. * sysdeps/gnu/siglist.c: Likewise. --- libc/include/libc-symbols.h.jj 2006-10-31 23:05:31.000000000 +0100 +++ libc/include/libc-symbols.h 2006-10-31 23:05:31.000000000 +0100 @@ -294,27 +294,42 @@ requires at runtime the shared libraries for linking") #endif -/* Declare SYMBOL to be TYPE (`function' or `object') and of SIZE bytes, - when the assembler supports such declarations (such as in ELF). +/* Declare SYMBOL to be TYPE (`function' or `object') of SIZE bytes + alias to ORIGINAL, when the assembler supports such declarations + (such as in ELF). This is only necessary when defining something in assembly, or playing funny alias games where the size should be other than what the compiler thinks it is. */ -#define declare_symbol(symbol, type, size) \ - declare_symbol_1 (symbol, type, size) +#define declare_symbol_alias(symbol, original, type, size) \ + declare_symbol_alias_1 (symbol, original, type, size) #ifdef ASM_TYPE_DIRECTIVE_PREFIX # ifdef __ASSEMBLER__ -# define declare_symbol_1(symbol, type, size) \ +# define declare_symbol_alias_1(symbol, original, type, size) \ + strong_alias (original, symbol); \ .type C_SYMBOL_NAME (symbol), \ - declare_symbol_1_paste (ASM_TYPE_DIRECTIVE_PREFIX, type), size -# define declare_symbol_1_paste(a, b) declare_symbol_1_paste_1 (a,b) -# define declare_symbol_1_paste_1(a,b) a##b + declare_symbol_alias_1_paste (ASM_TYPE_DIRECTIVE_PREFIX, type); \ + .size C_SYMBOL_NAME (symbol), size +# define declare_symbol_alias_1_paste(a, b) \ + declare_symbol_alias_1_paste_1 (a,b) +# define declare_symbol_alias_1_paste_1(a,b) a##b # else /* Not __ASSEMBLER__. */ -# define declare_symbol_1(symbol, type, size) \ - asm (".type " __SYMBOL_PREFIX #symbol ", " \ - declare_symbol_1_stringify (ASM_TYPE_DIRECTIVE_PREFIX) #type \ +# define declare_symbol_alias_1(symbol, original, type, size) \ + asm (declare_symbol_alias_1_stringify (ASM_GLOBAL_DIRECTIVE) \ + " " __SYMBOL_PREFIX #symbol \ + "\n\t" declare_symbol_alias_1_alias (symbol, original) \ + "\n\t.type " __SYMBOL_PREFIX #symbol ", " \ + declare_symbol_alias_1_stringify (ASM_TYPE_DIRECTIVE_PREFIX) #type \ "\n\t.size " __SYMBOL_PREFIX #symbol ", " #size); -# define declare_symbol_1_stringify(x) declare_symbol_1_stringify_1 (x) -# define declare_symbol_1_stringify_1(x) #x +# define declare_symbol_alias_1_stringify(x) \ + declare_symbol_alias_1_stringify_1 (x) +# define declare_symbol_alias_1_stringify_1(x) #x +# ifdef HAVE_ASM_SET_DIRECTIVE +# define declare_symbol_alias_1_alias(symbol, original) \ + ".set " __SYMBOL_PREFIX #symbol ", " __SYMBOL_PREFIX #original +# else +# define declare_symbol_alias_1_alias(symbol, original) \ + __SYMBOL_PREFIX #symbol " = " __SYMBOL_PREFIX #original +# endif /* HAVE_ASM_SET_DIRECTIVE */ # endif /* __ASSEMBLER__ */ #else # define declare_symbol_1(symbol, type, size) /* Nothing. */ --- libc/sysdeps/gnu/errlist-compat.awk.jj 2006-01-23 22:26:20.000000000 +0100 +++ libc/sysdeps/gnu/errlist-compat.awk 2006-11-07 17:30:25.000000000 +0100 @@ -1,5 +1,5 @@ # awk script to generate errlist-compat.c -# Copyright (C) 2002, 2004 Free Software Foundation, Inc. +# Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -92,16 +92,18 @@ END { printf "# include \n"; printf "extern const char *const __sys_errlist_%s[NERR];\n", old; printf "const int __sys_nerr_%s = %d;\n", old, n; - printf "strong_alias (_sys_errlist_internal, __sys_errlist_%s)\n", old; - printf "declare_symbol (__sys_errlist_%s, object, __WORDSIZE/8*%d)\n", \ - old, n; + printf "declare_symbol_alias (__sys_errlist_%s, _sys_errlist_internal,", \ + old; + printf " object, __WORDSIZE/8*%d)\n", n; printf "compat_symbol (libc, __sys_errlist_%s, sys_errlist, %s);\n", \ old, old; printf "compat_symbol (libc, __sys_nerr_%s, sys_nerr, %s);\n", old, old; printf "extern const char *const ___sys_errlist_%s[NERR];\n", old; printf "extern const int __sys_nerr_%s;\n", old; - printf "strong_alias (__sys_errlist_%s, ___sys_errlist_%s)\n", old, old; + printf "declare_symbol_alias (___sys_errlist_%s, _sys_errlist_internal,", \ + old; + printf " object, __WORDSIZE/8*%d)\n", n; printf "strong_alias (__sys_nerr_%s, ___sys_nerr_%s)\n", old, old; printf "compat_symbol (libc, ___sys_errlist_%s, _sys_errlist, %s);\n", \ old, old; --- libc/sysdeps/gnu/siglist.c.jj 2003-04-01 07:51:02.000000000 +0200 +++ libc/sysdeps/gnu/siglist.c 2006-11-07 17:23:58.000000000 +0100 @@ -1,5 +1,5 @@ /* Define list of all signal numbers and their names. - Copyright (C) 1997-2000, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1997-2000, 2002, 2003, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -40,11 +40,11 @@ const char *const __new_sys_sigabbrev[NS strong_alias (__new_sys_sigabbrev, _sys_sigabbrev_internal) #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) -strong_alias (_sys_siglist_internal, __old_sys_siglist) -declare_symbol (__old_sys_siglist, object, OLD_SIGLIST_SIZE * __WORDSIZE / 8) +declare_symbol_alias (__old_sys_siglist, _sys_siglist_internal, object, + OLD_SIGLIST_SIZE * __WORDSIZE / 8) -strong_alias (_sys_sigabbrev_internal, __old_sys_sigabbrev) -declare_symbol (__old_sys_sigabbrev, object, OLD_SIGLIST_SIZE * __WORDSIZE / 8) +declare_symbol_alias (__old_sys_sigabbrev, _sys_sigabbrev_internal, object, + OLD_SIGLIST_SIZE * __WORDSIZE / 8) strong_alias (__old_sys_siglist, _old_sys_siglist) compat_symbol (libc, __old_sys_siglist, _sys_siglist, GLIBC_2_0); @@ -53,14 +53,15 @@ compat_symbol (libc, __old_sys_sigabbrev #endif #if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3) && defined OLD2_SIGLIST_SIZE -strong_alias (_sys_siglist_internal, __old2_sys_siglist) -declare_symbol (__old2_sys_siglist, object, OLD2_SIGLIST_SIZE * __WORDSIZE / 8) +declare_symbol_alias (__old2_sys_siglist, __new_sys_siglist, object, + OLD2_SIGLIST_SIZE * __WORDSIZE / 8) -strong_alias (_sys_sigabbrev_internal, __old2_sys_sigabbrev) -declare_symbol (__old2_sys_sigabbrev, object, - OLD2_SIGLIST_SIZE * __WORDSIZE / 8) +declare_symbol_alias (__old2_sys_sigabbrev, __new_sys_sigabbrev, object, + OLD2_SIGLIST_SIZE * __WORDSIZE / 8) + +declare_symbol_alias (_old2_sys_siglist, __new_sys_siglist, object, + OLD2_SIGLIST_SIZE * __WORDSIZE / 8) -strong_alias (__old2_sys_siglist, _old2_sys_siglist) compat_symbol (libc, __old2_sys_siglist, _sys_siglist, GLIBC_2_1); compat_symbol (libc, _old2_sys_siglist, sys_siglist, GLIBC_2_1); compat_symbol (libc, __old2_sys_sigabbrev, sys_sigabbrev, GLIBC_2_1); Jakub