From c75712b15a5e0655c15707e1e1340da9d5e2646a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 5 Apr 2010 01:31:27 +0200 Subject: getutid is not used internally, removing hidden_proto Signed-off-by: Denys Vlasenko --- libc/misc/utmp/utent.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'libc') diff --git a/libc/misc/utmp/utent.c b/libc/misc/utmp/utent.c index 336c0239b..254040fed 100644 --- a/libc/misc/utmp/utent.c +++ b/libc/misc/utmp/utent.c @@ -88,7 +88,7 @@ void endutent(void) struct utmp *getutent(void) { - struct utmp *ret = NULL; + struct utmp *ret; __UCLIBC_MUTEX_LOCK(utmplock); ret = __getutent(); @@ -125,18 +125,17 @@ static struct utmp *__getutid(const struct utmp *utmp_entry) struct utmp *getutid(const struct utmp *utmp_entry) { - struct utmp *ret = NULL; + struct utmp *ret; __UCLIBC_MUTEX_LOCK(utmplock); ret = __getutid(utmp_entry); __UCLIBC_MUTEX_UNLOCK(utmplock); return ret; } -libc_hidden_def(getutid) struct utmp *getutline(const struct utmp *utmp_entry) { - struct utmp *lutmp = NULL; + struct utmp *lutmp; __UCLIBC_MUTEX_LOCK(utmplock); while ((lutmp = __getutent()) != NULL) { -- cgit v1.2.3 From 10f19b4565a82a9fb2ebb7bf938154afb4e09ad6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 5 Apr 2010 01:32:19 +0200 Subject: regex_old: convert static flag variable to smallint Signed-off-by: Denys Vlasenko --- libc/misc/fnmatch/fnmatch.c | 8 +------- libc/misc/regex/regex_old.c | 6 +++--- 2 files changed, 4 insertions(+), 10 deletions(-) (limited to 'libc') diff --git a/libc/misc/fnmatch/fnmatch.c b/libc/misc/fnmatch/fnmatch.c index d25619b34..0fa043bad 100644 --- a/libc/misc/fnmatch/fnmatch.c +++ b/libc/misc/fnmatch/fnmatch.c @@ -21,13 +21,7 @@ # include #endif -/* include unistd.h before we undefine _LIBC - * because smallint is defined in unistd.h based - * on _LIBC. For architectures that dont define - * smallint of there own and rely upon the definition - * from unistd.h will not build this file otherwise - */ - +/* unistd.h must be included with _LIBC defined: we need smallint */ #include #include #ifdef __UCLIBC__ diff --git a/libc/misc/regex/regex_old.c b/libc/misc/regex/regex_old.c index bc2ad6cb8..a3c30b51a 100644 --- a/libc/misc/regex/regex_old.c +++ b/libc/misc/regex/regex_old.c @@ -23,7 +23,8 @@ /* To exclude some unwanted junk.... */ #undef emacs #include - +/* unistd.h must be included with _LIBC defined: we need smallint */ +#include #ifdef __UCLIBC__ # undef _LIBC # define _REGEX_RE_COMP @@ -33,7 +34,6 @@ #include #include #include -#include #include /* AIX requires this to be the first thing in the file. */ @@ -263,7 +263,7 @@ static void init_syntax_once (void) { register int c; - static int done = 0; + static smallint done = 0; if (done) return; -- cgit v1.2.3 From 56f80b6cb62323fbaf0fc8620d10fc242e136ee6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 5 Apr 2010 19:25:54 +0200 Subject: utent: do not create extra static functions if !THREADS text data bss dec hex filename 547 8 384 939 3ab libc/misc/utmp/utent.o 519 8 384 911 38f libc/misc/utmp/utent.o Signed-off-by: Denys Vlasenko --- libc/misc/utmp/utent.c | 86 ++++++++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 37 deletions(-) (limited to 'libc') diff --git a/libc/misc/utmp/utent.c b/libc/misc/utmp/utent.c index 254040fed..c83f45e73 100644 --- a/libc/misc/utmp/utent.c +++ b/libc/misc/utmp/utent.c @@ -24,14 +24,26 @@ __UCLIBC_MUTEX_STATIC(utmplock, PTHREAD_MUTEX_INITIALIZER); +/* Do not create extra unlocked functions if no locking is needed */ +#if defined __UCLIBC_HAS_THREADS__ +# define static_if_threaded static +#else +# define static_if_threaded /* nothing */ +# define __setutent setutent +# define __getutent getutent +# define __getutid getutid +#endif + + /* Some global crap */ static int static_fd = -1; static struct utmp static_utmp; static const char default_file_name[] = _PATH_UTMP; static const char *static_ut_name = default_file_name; + /* This function must be called with the LOCK held */ -static void __setutent(void) +static_if_threaded void __setutent(void) { if (static_fd < 0) { static_fd = open(static_ut_name, O_RDWR | O_CLOEXEC); @@ -49,20 +61,19 @@ static void __setutent(void) } lseek(static_fd, 0, SEEK_SET); } - +#if defined __UCLIBC_HAS_THREADS__ void setutent(void) { __UCLIBC_MUTEX_LOCK(utmplock); __setutent(); __UCLIBC_MUTEX_UNLOCK(utmplock); } +#endif libc_hidden_def(setutent) /* This function must be called with the LOCK held */ -static struct utmp *__getutent(void) +static_if_threaded struct utmp *__getutent(void) { - struct utmp *ret = NULL; - if (static_fd < 0) { __setutent(); if (static_fd < 0) { @@ -71,11 +82,22 @@ static struct utmp *__getutent(void) } if (read(static_fd, &static_utmp, sizeof(static_utmp)) == sizeof(static_utmp)) { - ret = &static_utmp; + return &static_utmp; } + return NULL; +} +#if defined __UCLIBC_HAS_THREADS__ +struct utmp *getutent(void) +{ + struct utmp *ret; + + __UCLIBC_MUTEX_LOCK(utmplock); + ret = __getutent(); + __UCLIBC_MUTEX_UNLOCK(utmplock); return ret; } +#endif void endutent(void) { @@ -86,43 +108,31 @@ void endutent(void) __UCLIBC_MUTEX_UNLOCK(utmplock); } -struct utmp *getutent(void) -{ - struct utmp *ret; - - __UCLIBC_MUTEX_LOCK(utmplock); - ret = __getutent(); - __UCLIBC_MUTEX_UNLOCK(utmplock); - return ret; -} - /* This function must be called with the LOCK held */ -static struct utmp *__getutid(const struct utmp *utmp_entry) +static_if_threaded struct utmp *__getutid(const struct utmp *utmp_entry) { struct utmp *lutmp; + unsigned type; + + /* We use the fact that constants we are interested in are: */ + /* RUN_LVL=1, ... OLD_TIME=4; INIT_PROCESS=5, ... USER_PROCESS=8 */ + type = utmp_entry->ut_type - 1; + type /= 4; while ((lutmp = __getutent()) != NULL) { - if ( (utmp_entry->ut_type == RUN_LVL || - utmp_entry->ut_type == BOOT_TIME || - utmp_entry->ut_type == NEW_TIME || - utmp_entry->ut_type == OLD_TIME) && - lutmp->ut_type == utmp_entry->ut_type) - { - return lutmp; - } - if ( (utmp_entry->ut_type == INIT_PROCESS || - utmp_entry->ut_type == DEAD_PROCESS || - utmp_entry->ut_type == LOGIN_PROCESS || - utmp_entry->ut_type == USER_PROCESS) && - !strncmp(lutmp->ut_id, utmp_entry->ut_id, sizeof(lutmp->ut_id))) - { - return lutmp; - } + if (type == 0 && lutmp->ut_type == utmp_entry->ut_type) { + /* one of RUN_LVL, BOOT_TIME, NEW_TIME, OLD_TIME */ + return lutmp; + } + if (type == 1 && strncmp(lutmp->ut_id, utmp_entry->ut_id, sizeof(lutmp->ut_id)) == 0) { + /* INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, DEAD_PROCESS */ + return lutmp; + } } return NULL; } - +#if defined __UCLIBC_HAS_THREADS__ struct utmp *getutid(const struct utmp *utmp_entry) { struct utmp *ret; @@ -132,6 +142,7 @@ struct utmp *getutid(const struct utmp *utmp_entry) __UCLIBC_MUTEX_UNLOCK(utmplock); return ret; } +#endif struct utmp *getutline(const struct utmp *utmp_entry) { @@ -139,9 +150,10 @@ struct utmp *getutline(const struct utmp *utmp_entry) __UCLIBC_MUTEX_LOCK(utmplock); while ((lutmp = __getutent()) != NULL) { - if ((lutmp->ut_type == USER_PROCESS || lutmp->ut_type == LOGIN_PROCESS) && - !strcmp(lutmp->ut_line, utmp_entry->ut_line)) { - break; + if (lutmp->ut_type == USER_PROCESS || lutmp->ut_type == LOGIN_PROCESS) { + if (strncmp(lutmp->ut_line, utmp_entry->ut_line, sizeof(lutmp->ut_line)) == 0) { + break; + } } } __UCLIBC_MUTEX_UNLOCK(utmplock); -- cgit v1.2.3 From eefaf06888e3dcbc410b4cc2d231035f4400c7ac Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 6 Apr 2010 05:28:29 +0200 Subject: i386/bits/syscalls.h: explain how it works. no code changes Signed-off-by: Denys Vlasenko --- libc/sysdeps/linux/i386/bits/syscalls.h | 216 +++++++++++++++++--------------- 1 file changed, 116 insertions(+), 100 deletions(-) (limited to 'libc') diff --git a/libc/sysdeps/linux/i386/bits/syscalls.h b/libc/sysdeps/linux/i386/bits/syscalls.h index 23d872a29..46c2d9962 100644 --- a/libc/sysdeps/linux/i386/bits/syscalls.h +++ b/libc/sysdeps/linux/i386/bits/syscalls.h @@ -1,128 +1,144 @@ #ifndef _BITS_SYSCALLS_H #define _BITS_SYSCALLS_H + #ifndef _SYSCALL_H # error "Never use directly; include instead." #endif /* - Some of the sneaky macros in the code were taken from - glibc-2.2.5/sysdeps/unix/sysv/linux/i386/sysdep.h -*/ + * Some of the sneaky macros in the code were taken from + * glibc-2.2.5/sysdeps/unix/sysv/linux/i386/sysdep.h + */ #ifndef __ASSEMBLER__ #include -/* We need some help from the assembler to generate optimal code. We - define some macros here which later will be used. */ +/* We need some help from the assembler to generate optimal code. + * We define some macros here which later will be used. */ -#if defined __SUPPORT_LD_DEBUG__ && defined __DOMULTI__ +#if defined __SUPPORT_LD_DEBUG__ && defined __DOMULTI__ #error LD debugging and DOMULTI are incompatible #endif #ifdef __DOMULTI__ -__asm__ (".L__X'%ebx = 1\n\t" - ".L__X'%ecx = 2\n\t" - ".L__X'%edx = 2\n\t" - ".L__X'%eax = 3\n\t" - ".L__X'%esi = 3\n\t" - ".L__X'%edi = 3\n\t" - ".L__X'%ebp = 3\n\t" - ".L__X'%esp = 3\n\t" - ".ifndef _BITS_SYSCALLS_ASM\n\t" - ".set _BITS_SYSCALLS_ASM,1\n\t" - ".macro bpushl name reg\n\t" - ".if 1 - \\name\n\t" - ".if 2 - \\name\n\t" - "pushl %ebx\n\t" - ".else\n\t" - "xchgl \\reg, %ebx\n\t" - ".endif\n\t" - ".endif\n\t" - ".endm\n\t" - ".macro bpopl name reg\n\t" - ".if 1 - \\name\n\t" - ".if 2 - \\name\n\t" - "popl %ebx\n\t" - ".else\n\t" - "xchgl \\reg, %ebx\n\t" - ".endif\n\t" - ".endif\n\t" - ".endm\n\t" - ".macro bmovl name reg\n\t" - ".if 1 - \\name\n\t" - ".if 2 - \\name\n\t" - "movl \\reg, %ebx\n\t" - ".endif\n\t" - ".endif\n\t" - ".endm\n\t" - ".endif\n\t"); +__asm__ ( + ".L__X'%ebx = 1\n\t" + ".L__X'%ecx = 2\n\t" + ".L__X'%edx = 2\n\t" + ".L__X'%eax = 3\n\t" + ".L__X'%esi = 3\n\t" + ".L__X'%edi = 3\n\t" + ".L__X'%ebp = 3\n\t" + ".L__X'%esp = 3\n\t" + + ".ifndef _BITS_SYSCALLS_ASM\n\t" + ".set _BITS_SYSCALLS_ASM,1\n\t" + + /* Loading param #1 (ebx) is done by loading it into + * another register, and then performing bpushl+bmovl, + * since we must preserve ebx */ + + ".macro bpushl name reg\n\t" + ".if 1 - \\name\n\t" /* if reg!=ebx... */ + ".if 2 - \\name\n\t" /* if reg can't be clobbered... */ + "pushl %ebx\n\t" /* save ebx on stack */ + ".else\n\t" + "xchgl \\reg, %ebx\n\t" /* else save ebx in reg, and load reg to ebx */ + ".endif\n\t" + ".endif\n\t" + ".endm\n\t" + + ".macro bmovl name reg\n\t" + ".if 1 - \\name\n\t" + ".if 2 - \\name\n\t" /* if reg can't be clobbered... */ + "movl \\reg, %ebx\n\t" /* load reg to ebx */ + ".endif\n\t" + ".endif\n\t" + ".endm\n\t" + + ".endif\n\t" /* _BITS_SYSCALLS_ASM */ + + ".macro bpopl name reg\n\t" + ".if 1 - \\name\n\t" + ".if 2 - \\name\n\t" /* if reg can't be clobbered... */ + "popl %ebx\n\t" /* restore ebx from stack */ + ".else\n\t" + "xchgl \\reg, %ebx\n\t" /* else restore ebx from reg */ + ".endif\n\t" + ".endif\n\t" + ".endm\n\t" +); #else -__asm__ (".L__X'%ebx = 1\n\t" - ".L__X'%ecx = 2\n\t" - ".L__X'%edx = 2\n\t" - ".L__X'%eax = 3\n\t" - ".L__X'%esi = 3\n\t" - ".L__X'%edi = 3\n\t" - ".L__X'%ebp = 3\n\t" - ".L__X'%esp = 3\n\t" - ".macro bpushl name reg\n\t" - ".if 1 - \\name\n\t" - ".if 2 - \\name\n\t" - "pushl %ebx\n\t" - ".else\n\t" - "xchgl \\reg, %ebx\n\t" - ".endif\n\t" - ".endif\n\t" - ".endm\n\t" - ".macro bpopl name reg\n\t" - ".if 1 - \\name\n\t" - ".if 2 - \\name\n\t" - "popl %ebx\n\t" - ".else\n\t" - "xchgl \\reg, %ebx\n\t" - ".endif\n\t" - ".endif\n\t" - ".endm\n\t" - ".macro bmovl name reg\n\t" - ".if 1 - \\name\n\t" - ".if 2 - \\name\n\t" - "movl \\reg, %ebx\n\t" - ".endif\n\t" - ".endif\n\t" - ".endm\n\t"); +__asm__ ( + ".L__X'%ebx = 1\n\t" + ".L__X'%ecx = 2\n\t" + ".L__X'%edx = 2\n\t" + ".L__X'%eax = 3\n\t" + ".L__X'%esi = 3\n\t" + ".L__X'%edi = 3\n\t" + ".L__X'%ebp = 3\n\t" + ".L__X'%esp = 3\n\t" + + ".macro bpushl name reg\n\t" + ".if 1 - \\name\n\t" + ".if 2 - \\name\n\t" + "pushl %ebx\n\t" + ".else\n\t" + "xchgl \\reg, %ebx\n\t" + ".endif\n\t" + ".endif\n\t" + ".endm\n\t" + + ".macro bmovl name reg\n\t" + ".if 1 - \\name\n\t" + ".if 2 - \\name\n\t" + "movl \\reg, %ebx\n\t" + ".endif\n\t" + ".endif\n\t" + ".endm\n\t" + + ".macro bpopl name reg\n\t" + ".if 1 - \\name\n\t" + ".if 2 - \\name\n\t" + "popl %ebx\n\t" + ".else\n\t" + "xchgl \\reg, %ebx\n\t" + ".endif\n\t" + ".endif\n\t" + ".endm\n\t" +); #endif #define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ - ({ \ - register unsigned int resultvar; \ - __asm__ __volatile__ ( \ - LOADARGS_##nr \ - "movl %1, %%eax\n\t" \ - "int $0x80\n\t" \ - RESTOREARGS_##nr \ - : "=a" (resultvar) \ - : "i" (name) ASMFMT_##nr(args) : "memory", "cc"); \ - (int) resultvar; }) +({ \ + register unsigned int resultvar; \ + __asm__ __volatile__ ( \ + LOADARGS_##nr \ + "movl %1, %%eax\n\t" \ + "int $0x80\n\t" \ + RESTOREARGS_##nr \ + : "=a" (resultvar) \ + : "i" (name) ASMFMT_##nr(args) : "memory", "cc" \ + ); \ + (int) resultvar; \ +}) #define LOADARGS_0 -#define LOADARGS_1 \ - "bpushl .L__X'%k2, %k2\n\t" \ - "bmovl .L__X'%k2, %k2\n\t" -#define LOADARGS_2 LOADARGS_1 -#define LOADARGS_3 LOADARGS_1 -#define LOADARGS_4 LOADARGS_1 -#define LOADARGS_5 LOADARGS_1 -#define LOADARGS_6 LOADARGS_1 "push %%ebp ; movl %7, %%ebp\n\t" +#define LOADARGS_1 "bpushl .L__X'%k2, %k2\n\t" "bmovl .L__X'%k2, %k2\n\t" +#define LOADARGS_2 LOADARGS_1 +#define LOADARGS_3 LOADARGS_1 +#define LOADARGS_4 LOADARGS_1 +#define LOADARGS_5 LOADARGS_1 +#define LOADARGS_6 LOADARGS_1 "push %%ebp\n\t" "movl %7, %%ebp\n\t" #define RESTOREARGS_0 -#define RESTOREARGS_1 \ - "bpopl .L__X'%k2, %k2\n\t" -#define RESTOREARGS_2 RESTOREARGS_1 -#define RESTOREARGS_3 RESTOREARGS_1 -#define RESTOREARGS_4 RESTOREARGS_1 -#define RESTOREARGS_5 RESTOREARGS_1 -#define RESTOREARGS_6 "pop %%ebp\n\t" RESTOREARGS_1 +#define RESTOREARGS_1 "bpopl .L__X'%k2, %k2\n\t" +#define RESTOREARGS_2 RESTOREARGS_1 +#define RESTOREARGS_3 RESTOREARGS_1 +#define RESTOREARGS_4 RESTOREARGS_1 +#define RESTOREARGS_5 RESTOREARGS_1 +#define RESTOREARGS_6 "pop %%ebp\n\t" RESTOREARGS_1 #define ASMFMT_0() #define ASMFMT_1(arg1) \ -- cgit v1.2.3 From d82f29cd593e371acb3a6f11656543cf2e6e2421 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 6 Apr 2010 05:29:26 +0200 Subject: i386/bits/syscalls.h: generate better code using more restrictive asm constraints Example: time() doesn't push/pop two registers now, and is smaller: <__GI_time>: -57 push %edi -8b 7c 24 08 mov 0x8(%esp),%edi -53 push %ebx -89 fb mov %edi,%ebx +8b 4c 24 04 mov 0x4(%esp),%ecx +87 cb xchg %ecx,%ebx b8 0d 00 00 00 mov $0xd,%eax cd 80 int $0x80 -5b pop %ebx -5f pop %edi +87 cb xchg %ecx,%ebx c3 ret Signed-off-by: Denys Vlasenko --- libc/sysdeps/linux/i386/bits/syscalls.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'libc') diff --git a/libc/sysdeps/linux/i386/bits/syscalls.h b/libc/sysdeps/linux/i386/bits/syscalls.h index 46c2d9962..a6e26d7ec 100644 --- a/libc/sysdeps/linux/i386/bits/syscalls.h +++ b/libc/sysdeps/linux/i386/bits/syscalls.h @@ -141,14 +141,21 @@ __asm__ ( #define RESTOREARGS_6 "pop %%ebp\n\t" RESTOREARGS_1 #define ASMFMT_0() +/* "acdSD" constraint would work too, but "SD" would use esi/edi and cause + * them to be pushed/popped by compiler, "a" would use eax and cause ebx + * to be saved/restored on stack, not in register. Narrowing choice down + * to "ecx or edx" results in smaller and faster code: */ #define ASMFMT_1(arg1) \ - , "acdSD" (arg1) + , "cd" (arg1) +/* Can use "adSD" constraint here: */ #define ASMFMT_2(arg1, arg2) \ - , "adSD" (arg1), "c" (arg2) + , "d" (arg1), "c" (arg2) +/* Can use "aSD" constraint here: */ #define ASMFMT_3(arg1, arg2, arg3) \ - , "aSD" (arg1), "c" (arg2), "d" (arg3) + , "a" (arg1), "c" (arg2), "d" (arg3) +/* Can use "aD" constraint here: */ #define ASMFMT_4(arg1, arg2, arg3, arg4) \ - , "aD" (arg1), "c" (arg2), "d" (arg3), "S" (arg4) + , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4) #define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \ , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5) #define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \ -- cgit v1.2.3 From dbdd8b059520baa371de611a21d7d1a2b250b250 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 6 Apr 2010 05:32:09 +0200 Subject: i386/bits/syscalls.h: explain _BITS_SYSCALLS_ASM Signed-off-by: Denys Vlasenko --- libc/sysdeps/linux/i386/bits/syscalls.h | 54 ++++++--------------------------- 1 file changed, 9 insertions(+), 45 deletions(-) (limited to 'libc') diff --git a/libc/sysdeps/linux/i386/bits/syscalls.h b/libc/sysdeps/linux/i386/bits/syscalls.h index a6e26d7ec..09d48a2ff 100644 --- a/libc/sysdeps/linux/i386/bits/syscalls.h +++ b/libc/sysdeps/linux/i386/bits/syscalls.h @@ -21,8 +21,13 @@ #error LD debugging and DOMULTI are incompatible #endif -#ifdef __DOMULTI__ __asm__ ( +#ifdef __DOMULTI__ + /* Protect against asm macro redefinition (happens in __DOMULTI__ mode). + * Unfortunately, it ends up visible in .o files. */ + ".ifndef _BITS_SYSCALLS_ASM\n\t" + ".set _BITS_SYSCALLS_ASM,1\n\t" +#endif ".L__X'%ebx = 1\n\t" ".L__X'%ecx = 2\n\t" ".L__X'%edx = 2\n\t" @@ -32,9 +37,6 @@ __asm__ ( ".L__X'%ebp = 3\n\t" ".L__X'%esp = 3\n\t" - ".ifndef _BITS_SYSCALLS_ASM\n\t" - ".set _BITS_SYSCALLS_ASM,1\n\t" - /* Loading param #1 (ebx) is done by loading it into * another register, and then performing bpushl+bmovl, * since we must preserve ebx */ @@ -57,8 +59,6 @@ __asm__ ( ".endif\n\t" ".endm\n\t" - ".endif\n\t" /* _BITS_SYSCALLS_ASM */ - ".macro bpopl name reg\n\t" ".if 1 - \\name\n\t" ".if 2 - \\name\n\t" /* if reg can't be clobbered... */ @@ -68,47 +68,11 @@ __asm__ ( ".endif\n\t" ".endif\n\t" ".endm\n\t" -); -#else -__asm__ ( - ".L__X'%ebx = 1\n\t" - ".L__X'%ecx = 2\n\t" - ".L__X'%edx = 2\n\t" - ".L__X'%eax = 3\n\t" - ".L__X'%esi = 3\n\t" - ".L__X'%edi = 3\n\t" - ".L__X'%ebp = 3\n\t" - ".L__X'%esp = 3\n\t" - ".macro bpushl name reg\n\t" - ".if 1 - \\name\n\t" - ".if 2 - \\name\n\t" - "pushl %ebx\n\t" - ".else\n\t" - "xchgl \\reg, %ebx\n\t" - ".endif\n\t" - ".endif\n\t" - ".endm\n\t" - - ".macro bmovl name reg\n\t" - ".if 1 - \\name\n\t" - ".if 2 - \\name\n\t" - "movl \\reg, %ebx\n\t" - ".endif\n\t" - ".endif\n\t" - ".endm\n\t" - - ".macro bpopl name reg\n\t" - ".if 1 - \\name\n\t" - ".if 2 - \\name\n\t" - "popl %ebx\n\t" - ".else\n\t" - "xchgl \\reg, %ebx\n\t" - ".endif\n\t" - ".endif\n\t" - ".endm\n\t" -); +#ifdef __DOMULTI__ + ".endif\n\t" /* _BITS_SYSCALLS_ASM */ #endif +); #define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ ({ \ -- cgit v1.2.3 From cd50d9a1c93bf1e02f4d4e2df4ece6c881f24719 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 6 Apr 2010 05:33:01 +0200 Subject: i386/bits/syscalls.h: more compact, but stack-hungry syscall code. disabled so far Signed-off-by: Denys Vlasenko --- libc/sysdeps/linux/i386/bits/syscalls.h | 96 ++++++++++++++++++++++++++------- 1 file changed, 78 insertions(+), 18 deletions(-) (limited to 'libc') diff --git a/libc/sysdeps/linux/i386/bits/syscalls.h b/libc/sysdeps/linux/i386/bits/syscalls.h index 09d48a2ff..0427d91cd 100644 --- a/libc/sysdeps/linux/i386/bits/syscalls.h +++ b/libc/sysdeps/linux/i386/bits/syscalls.h @@ -14,13 +14,36 @@ #include +#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ +({ \ + register unsigned int resultvar; \ + __asm__ __volatile__ ( \ + LOADARGS_##nr \ + "movl %1, %%eax\n\t" \ + "int $0x80\n\t" \ + RESTOREARGS_##nr \ + : "=a" (resultvar) \ + : "i" (name) ASMFMT_##nr(args) : "memory", "cc" \ + ); \ + (int) resultvar; \ +}) + + +#if 1 /* defined __PIC__ || defined __pic__ */ + +/* This code avoids pushing/popping ebx as much as possible. + * I think the main reason was that older GCCs had problems + * with proper saving/restoring of ebx if "b" constraint was used, + * which was breaking -fPIC code really badly. + * At least gcc 4.2.x seems to not need these tricks anymore, + * but this code is still useful because it often avoids + * using stack for saving ebx. + * Keeping it unconditionally enabled for now. + */ + /* We need some help from the assembler to generate optimal code. * We define some macros here which later will be used. */ -#if defined __SUPPORT_LD_DEBUG__ && defined __DOMULTI__ -#error LD debugging and DOMULTI are incompatible -#endif - __asm__ ( #ifdef __DOMULTI__ /* Protect against asm macro redefinition (happens in __DOMULTI__ mode). @@ -74,20 +97,6 @@ __asm__ ( #endif ); -#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ -({ \ - register unsigned int resultvar; \ - __asm__ __volatile__ ( \ - LOADARGS_##nr \ - "movl %1, %%eax\n\t" \ - "int $0x80\n\t" \ - RESTOREARGS_##nr \ - : "=a" (resultvar) \ - : "i" (name) ASMFMT_##nr(args) : "memory", "cc" \ - ); \ - (int) resultvar; \ -}) - #define LOADARGS_0 #define LOADARGS_1 "bpushl .L__X'%k2, %k2\n\t" "bmovl .L__X'%k2, %k2\n\t" #define LOADARGS_2 LOADARGS_1 @@ -125,5 +134,56 @@ __asm__ ( #define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \ , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "m" (arg6) +#else /* !PIC */ + +/* Simpler code which just uses "b" constraint to load ebx. + * Seems to work with gc 4.2.x, and generates slightly smaller, + * but slightly slower code. Example (time syscall): + * + * - 8b 4c 24 04 mov 0x4(%esp),%ecx + * - 87 cb xchg %ecx,%ebx + * + 53 push %ebx + * + 8b 5c 24 08 mov 0x8(%esp),%ebx + * b8 0d 00 00 00 mov $0xd,%eax + * cd 80 int $0x80 + * - 87 cb xchg %ecx,%ebx + * + 5b pop %ebx + * c3 ret + * + * 2 bytes smaller, but uses stack via "push/pop ebx" + */ + +#define LOADARGS_0 +#define LOADARGS_1 +#define LOADARGS_2 +#define LOADARGS_3 +#define LOADARGS_4 +#define LOADARGS_5 +#define LOADARGS_6 "push %%ebp\n\t" "movl %7, %%ebp\n\t" + +#define RESTOREARGS_0 +#define RESTOREARGS_1 +#define RESTOREARGS_2 +#define RESTOREARGS_3 +#define RESTOREARGS_4 +#define RESTOREARGS_5 +#define RESTOREARGS_6 "pop %%ebp\n\t" + +#define ASMFMT_0() +#define ASMFMT_1(arg1) \ + , "b" (arg1) +#define ASMFMT_2(arg1, arg2) \ + , "b" (arg1), "c" (arg2) +#define ASMFMT_3(arg1, arg2, arg3) \ + , "b" (arg1), "c" (arg2), "d" (arg3) +#define ASMFMT_4(arg1, arg2, arg3, arg4) \ + , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4) +#define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \ + , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5) +#define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \ + , "b" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "m" (arg6) + +#endif /* !PIC */ + #endif /* __ASSEMBLER__ */ #endif /* _BITS_SYSCALLS_H */ -- cgit v1.2.3 From fd8991cc59305a071e9f1765b3e1e09de9339bc3 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 6 Apr 2010 09:55:19 +0200 Subject: Fix use-after-free bug in __dns_lookup If the type of the first answer does not match with the requested type, then the dotted name was freed. If there are no further answers in the DNS reply, this pointer was used later on in the same function. Additionally it is passed to the caller, and caused strange behaviour. Signed-off-by: Gabor Juhos Signed-off-by: Bernhard Reutner-Fischer --- libc/inet/resolv.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'libc') diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c index 056539f6e..9459199da 100644 --- a/libc/inet/resolv.c +++ b/libc/inet/resolv.c @@ -1517,10 +1517,8 @@ int attribute_hidden __dns_lookup(const char *name, memcpy(a, &ma, sizeof(ma)); if (a->atype != T_SIG && (NULL == a->buf || (type != T_A && type != T_AAAA))) break; - if (a->atype != type) { - free(a->dotted); + if (a->atype != type) continue; - } a->add_count = h.ancount - j - 1; if ((a->rdlength + sizeof(struct in_addr*)) * a->add_count > a->buflen) break; -- cgit v1.2.3 From 384a55ef9f3387ed33eadab3eefe5057b4daeadb Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Tue, 6 Apr 2010 17:17:30 +0200 Subject: getconf: print arbitrary GNU_LIBPTHREAD_VERSION string the NPTL should probably print the version-string of the glibc it's compatible with and not the uClibc version (check what mysql expects). Signed-off-by: Bernhard Reutner-Fischer --- libc/unistd/confstr.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'libc') diff --git a/libc/unistd/confstr.c b/libc/unistd/confstr.c index 16b57bee9..957ee4d27 100644 --- a/libc/unistd/confstr.c +++ b/libc/unistd/confstr.c @@ -42,6 +42,24 @@ size_t confstr (int name, char *buf, size_t len) string_len = sizeof (cs_path); } break; +#ifdef __UCLIBC_HAS_THREADS__ + case _CS_GNU_LIBPTHREAD_VERSION: +# if defined __LINUXTHREADS_OLD__ + string = "linuxthreads-0.01"; + string_len = sizeof("linuxthreads-x.xx"); +# elif defined __LINUXTHREADS_NEW__ + string = "linuxthreads-0.10"; + string_len = sizeof("linuxthreads-x.xx"); +# elif defined __UCLIBC_HAS_THREADS_NATIVE__ +# define __NPTL_VERSION ("NPTL " \ + #__UCLIBC_MAJOR__ "." \ + #__UCLIBC_MINOR__ "." \ + #__UCLIBC_SUBLEVEL__) + string = __NPTL_VERSION; + string_len = sizeof(__NPTL_VERSION); +# endif + break; +#endif default: __set_errno (EINVAL); return 0; -- cgit v1.2.3