[PATCH] ldso: fix dlsym hang when reloading DSOs

2013-06-27 Thread Timo Teräs
It can happen under certain cases that the DSO had refcount 0,
but was already loaded. (NODELETE flag is set, or it is pulled
in via both NEEDED dependency and explicit dlopen()).

In these cases we must not re-add the DSO to the global symbol
scope as it is already there. Or we end up corrupting the linked
list and further dlsym lookups will hang.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 ldso/libdl/libdl.c | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index c451b63..c901512 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -543,15 +543,23 @@ static void *do_dlopen(const char *libname, int flag, 
ElfW(Addr) from)
 
 #ifdef SHARED
/*
-* Get the tail of the list.
 * In the static case doesn't need to extend the global scope, it is
 * ready to be used as it is, because _dl_loaded_modules already points
 * to the dlopened library.
+*
+* Extend the global scope by adding the local scope of the dlopened 
DSO.
+* But only if it's not there. It can happen under certain cases that 
the
+* DSO had refcount = 0, but was already loaded. (NODELETE flag is set, 
or
+* it is pulled in via both NEEDED dependency and explicit dlopen()).
 */
-   for (ls = _dl_loaded_modules-symbol_scope; ls  ls-next; ls = 
ls-next);
-
-   /* Extend the global scope by adding the local scope of the dlopened 
DSO. */
-   ls-next = dyn_chain-dyn-symbol_scope;
+   for (ls = _dl_loaded_modules-symbol_scope; ; ls = ls-next) {
+   if (ls == dyn_chain-dyn-symbol_scope)
+   break;
+   if (ls-next == NULL) {
+   ls-next = dyn_chain-dyn-symbol_scope;
+   break;
+   }
+   }
 #endif
 #ifdef __mips__
/*
-- 
1.8.3.1

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

[PATCH] dl: fix dlsym lookups with RTLD_NEXT

2013-01-08 Thread Timo Teräs
The current code for dlsym() when invoked with RTLD_NEXT lookup
searches for the module where it's being called from, and executes the
_dl_find_hash only for the next module in the chain. However, if the
looked symbol is not there, the rest of the modules are not checked.

Generally this is not a problem as symbols are merged for the parent
modules; so this affects only RTLD_NEXT.

This patch adds a loop iterating through all the following modules.

Signed-off-by: Timo Teräs timo.te...@iki.fi
Reviewed-by: Filippo ARCIDIACONO filippo.arcidiac...@st.com
Tested-by: Florian Fainelli flor...@openwrt.org
---
 ldso/libdl/libdl.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index af632dd..95a0650 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -671,7 +671,7 @@ static void *do_dlsym(void *vhandle, const char *name, void 
*caller_address)
 {
struct elf_resolve *tpnt, *tfrom;
struct dyn_elf *handle;
-   ElfW(Addr) from;
+   ElfW(Addr) from = 0;
struct dyn_elf *rpnt;
void *ret;
struct symbol_ref sym_ref = { NULL, NULL };
@@ -729,7 +729,13 @@ static void *do_dlsym(void *vhandle, const char *name, 
void *caller_address)
tpnt = NULL;
if (handle == _dl_symbol_tables)
tpnt = handle-dyn; /* Only search RTLD_GLOBAL objs if global 
object */
-   ret = _dl_find_hash(name2, handle-dyn-symbol_scope, tpnt, 
ELF_RTYPE_CLASS_DLSYM, sym_ref);
+
+   do {
+   ret = _dl_find_hash(name2, handle-dyn-symbol_scope, tpnt, 
ELF_RTYPE_CLASS_DLSYM, sym_ref);
+   if (ret != NULL)
+   break;
+   handle = handle-next;
+   } while (from  handle);
 
 #if defined(USE_TLS)  USE_TLS  defined SHARED
if (sym_ref.sym  (ELF_ST_TYPE(sym_ref.sym-st_info) == STT_TLS)  
(sym_ref.tpnt)) {
-- 
1.8.1

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

[PATCH 2/3] libc/x86: add dwarf-2 cfi unwinding information to clone()

2011-11-20 Thread Timo Teräs
Copied mostly from glibc. Adds proper information for unwinding application
created threads. Without the proper unwind information the stack trace is
considered as incomplete or corrupted after clone(). This adds the proper
end-of-stack markers and thus removes gdb errors.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 libc/sysdeps/linux/i386/clone.S |   17 +
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/libc/sysdeps/linux/i386/clone.S b/libc/sysdeps/linux/i386/clone.S
index a7de3fe..cf6cd35 100644
--- a/libc/sysdeps/linux/i386/clone.S
+++ b/libc/sysdeps/linux/i386/clone.S
@@ -25,6 +25,7 @@
 
 #define _ERRNO_H   1
 #include bits/errno.h
+#include sysdep.h
 #include sys/syscall.h
 
 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
@@ -45,6 +46,7 @@
 .global clone
 .type   clone,%function
 clone:
+   cfi_startproc;
/* Sanity check arguments.  */
movl$-EINVAL,%eax
 
@@ -86,17 +88,28 @@ clone:
 
/* Do the system call */
pushl   %ebx
+   cfi_adjust_cfa_offset (4)
pushl   %esi
+   cfi_adjust_cfa_offset (4)
pushl   %edi
+   cfi_adjust_cfa_offset (4)
+
movlTLS+12(%esp),%esi
+   cfi_rel_offset (esi, 4)
movlPTID+12(%esp),%edx
movlFLAGS+12(%esp),%ebx
+   cfi_rel_offset (ebx, 8)
movlCTID+12(%esp),%edi
+   cfi_rel_offset (edi, 0)
movl$__NR_clone,%eax
 #ifdef RESET_PID
/* Remember the flag value.  */
movl%ebx, (%ecx)
 #endif
+   /* End FDE now, because in the child the unwind info will be
+  wrong.  */
+   cfi_endproc
+
int $0x80
popl%edi
popl%esi
@@ -108,6 +121,9 @@ clone:
ret
 
 .Lthread_start:
+   cfi_startproc;
+   /* Clearing frame pointer is insufficient, use CFI.  */
+   cfi_undefined (eip);
/* Note: %esi is zero.  */
movl%esi,%ebp   /* terminate the stack frame */
call*%ebx
@@ -120,6 +136,7 @@ clone:
movl%eax, %ebx
movl$__NR_exit, %eax
int $0x80
+   cfi_endproc;
 
 /* Need to indirect jump to syscall error 
  * or we end up with TEXTREL's
-- 
1.7.7.1

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

[PATCH 1/3] libc/x86: add dwarf-2 cfi unwinding information to syscalls

2011-11-20 Thread Timo Teräs
Fixes unwinding of stack traces across system calls. Thus debuggers can show
proper backtrace when inside a syscall.

Additionally, this fixes a race condition: if a signal happens while inside
syscall, and the signal handler aborts the thread, we would have been unable
to unwind the stack and run the proper error handler.

This patch also removes the xchg ebx, register trickery - it's very hard
to add proper CFI info within macroes.  It apparently never worked 100%
reliably, and the speed gain is probably insignificant on modern processors.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 libc/sysdeps/linux/i386/bits/syscalls.h |   82 +++
 1 files changed, 7 insertions(+), 75 deletions(-)

diff --git a/libc/sysdeps/linux/i386/bits/syscalls.h 
b/libc/sysdeps/linux/i386/bits/syscalls.h
index eeafb3a..1f60a44 100644
--- a/libc/sysdeps/linux/i386/bits/syscalls.h
+++ b/libc/sysdeps/linux/i386/bits/syscalls.h
@@ -13,6 +13,7 @@
 #ifndef __ASSEMBLER__
 
 #include errno.h
+#include common/sysdep.h
 
 #define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
 ({ \
@@ -31,90 +32,21 @@
 
 #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.  */
-/* gcc=4.6 with LTO need the same guards as IMA (a.k.a --combine) did.
- * See gcc.gnu.org/PR47577  */
-/* FIXME: drop these b* macros! */
-
-__asm__ (
-#if defined __DOMULTI__ || __GNUC_PREREQ (4, 6)
-   /* 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
-   .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
-
-   /* 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
-
-   .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
-
-#if defined __DOMULTI__ || __GNUC_PREREQ (4, 6)
-   .endif\n\t /* _BITS_SYSCALLS_ASM */
-#endif
-);
-
 #define LOADARGS_0
-#define LOADARGS_1  bpushl .L__X'%k2, %k2\n\t bmovl .L__X'%k2, %k2\n\t
+#define LOADARGS_1  push %%ebx\n\t CFI_ADJUST_CFA_OFFSET(4) \n\t 
CFI_REL_OFFSET(ebx, 0) \n\t movl %k2, %%ebx\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 LOADARGS_6  LOADARGS_1 push %%ebp\n\t CFI_ADJUST_CFA_OFFSET(4) 
\n\t CFI_REL_OFFSET(ebp, 0) \n\t movl %7, %%ebp\n\t
 
 #define RESTOREARGS_0
-#define RESTOREARGS_1  bpopl .L__X'%k2, %k2\n\t
+#define RESTOREARGS_1  pop %%ebx\n\t CFI_ADJUST_CFA_OFFSET(-4) \n\t 
CFI_RESTORE(ebx) \n\t RESTOREARGS_0
 #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_6  pop %%ebp\n\t CFI_ADJUST_CFA_OFFSET(-4) \n\t 
CFI_RESTORE(ebp) \n\t RESTOREARGS_1
 
 #define ASMFMT_0()
 /* acdSD constraint would work too, but SD would use esi/edi and cause
@@ -162,7 +94,7 @@ __asm__ (
 #define LOADARGS_3
 #define LOADARGS_4
 #define LOADARGS_5
-#define LOADARGS_6  push %%ebp\n\t movl %7, %%ebp\n\t
+#define LOADARGS_6  push %%ebp\n\t CFI_ADJUST_CFA_OFFSET(4) \n\t 
CFI_REL_OFFSET(ebp, 0) \n\t movl %7, %%ebp\n\t
 
 #define RESTOREARGS_0
 #define RESTOREARGS_1

[PATCH 3/3] libc/x86: pad signal return code on isolated area

2011-11-20 Thread Timo Teräs
If dwarf-2 cfi info was found for signal return code (which seems to happen
if it's located right after a valid function), it will not be recognized as
signal trampoline (gcc unwinder and gdb check first cfi info, and only if it
does not exists it compares the exact opcode sequence to see if we are at
signal return code block).

This fixes a real crash if thread is cancelled and the cancellation handler
fails to detect the signal return frame (common case if pthread_cancel is
used as threads are often cancelled by sending a signal to them).

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 libc/sysdeps/linux/i386/sigaction.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/libc/sysdeps/linux/i386/sigaction.c 
b/libc/sysdeps/linux/i386/sigaction.c
index de0c75d..f9af3f7 100644
--- a/libc/sysdeps/linux/i386/sigaction.c
+++ b/libc/sysdeps/linux/i386/sigaction.c
@@ -112,6 +112,9 @@ libc_hidden_weak(sigaction)
 #define RESTORE2(name, syscall) \
 __asm__(   \
.text\n   \
+   .align 8\n\
+  nop\n  \
+   .align 16\n   \
__ #name :\n\
   movl$ #syscall , %eax\n  \
   int $0x80\n\
@@ -128,6 +131,7 @@ RESTORE(restore_rt, __NR_rt_sigreturn)
 # define RESTORE2(name, syscall) \
 __asm__ (  \
.text\n   \
+   .align 8\n\
__ #name :\n\
   popl%eax\n \
   movl$ #syscall , %eax\n  \
-- 
1.7.7.1

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

Re: [PATCH] libc/x86: fix stack unwinding and backtrace information

2011-11-11 Thread Timo Teräs
On 11/10/2011 10:21 AM, Timo Teräs wrote:
 When compiled without framepointer, the DWARF-2 CFI data is required
 for proper stack unwinding.
 
 This patch adds the CFI information to:
  * syscalls (so we get proper backtrace even for release builds)
  * new thread stub function (so the backtrace is clean for user
created threads)
 
 Also pads the signal return trampolines separate from other functions.
 If CFI info was found for signal return code (which seems to happen if
 it's located right next a valid function), it will not be recognized
 as signal trampoline (gcc unwinder and gdb check first CFI info, and
 only if it does not exists it compares the exact opcode sequence to
 see if we are at signal return code block). This fixes a real crash
 if thread is cancelled and the cancellation handler fails to detect the
 signal return frame.
 
 Signed-off-by: Timo Teräs timo.te...@iki.fi

 @@ -71,6 +72,8 @@ __asm__ (
   .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 */
 + CFI_ADJUST_CFA_OFFSET(4) \n\t
 + CFI_REL_OFFSET(ebx, 0) \n\t
   .else\n\t
   xchgl \\reg, %ebx\n\t /* else save ebx in reg, and load reg to ebx */
   .endif\n\t
 @@ -89,6 +92,8 @@ __asm__ (
   .if 1 - \\name\n\t
   .if 2 - \\name\n\t/* if reg can't be clobbered... */
   popl %ebx\n\t /* restore ebx from stack */
 + CFI_ADJUST_CFA_OFFSET(-4) \n\t
 + CFI_RESTORE(ebx) \n\t
   .else\n\t
   xchgl \\reg, %ebx\n\t /* else restore ebx from reg */
   .endif\n\t

Actually, this bit does not work. The problems to be that the
CFI_ADJUST_CFA_OFFSET() stuff emits assembler directives, which get
interpreted regardless of the .if block we are at. Or something like
that. In any case, some syscalls would not get the info right.

I'm now wondering if actually need the whole bpush/bpop/bmov hackery
(even the comment suggests to remove it).

For CFI generation, it'd be a lot better if we could just do push/pop of
ebx always (for PIC builds) and leave it as-is for non-PIC builds.

I'll send a corrected patch doing that soon.
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

Re: [PATCH] libc/x86: fix stack unwinding and backtrace information

2011-11-11 Thread Timo Teräs
On 11/11/2011 03:31 PM, Peter Mazinger wrote:
 
  Original-Nachricht 
 Datum: Fri, 11 Nov 2011 13:30:27 +0200
 Von: Timo Teräs timo.te...@iki.fi
 An: 
 CC: uclibc@uclibc.org
 Betreff: Re: [PATCH] libc/x86: fix stack unwinding and backtrace information
 
 On 11/10/2011 10:21 AM, Timo Teräs wrote:
 When compiled without framepointer, the DWARF-2 CFI data is required
 for proper stack unwinding.

 This patch adds the CFI information to:
  * syscalls (so we get proper backtrace even for release builds)
  * new thread stub function (so the backtrace is clean for user
created threads)

 Also pads the signal return trampolines separate from other functions.
 If CFI info was found for signal return code (which seems to happen if
 it's located right next a valid function), it will not be recognized
 as signal trampoline (gcc unwinder and gdb check first CFI info, and
 only if it does not exists it compares the exact opcode sequence to
 see if we are at signal return code block). This fixes a real crash
 if thread is cancelled and the cancellation handler fails to detect the
 signal return frame.

 Signed-off-by: Timo Teräs timo.te...@iki.fi

 @@ -71,6 +72,8 @@ __asm__ (
 .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 */
 +   CFI_ADJUST_CFA_OFFSET(4) \n\t
 +   CFI_REL_OFFSET(ebx, 0) \n\t
 .else\n\t
 xchgl \\reg, %ebx\n\t /* else save ebx in reg, and load reg to ebx
 */
 .endif\n\t
 @@ -89,6 +92,8 @@ __asm__ (
 .if 1 - \\name\n\t
 .if 2 - \\name\n\t/* if reg can't be clobbered... */
 popl %ebx\n\t /* restore ebx from stack */
 +   CFI_ADJUST_CFA_OFFSET(-4) \n\t
 +   CFI_RESTORE(ebx) \n\t
 .else\n\t
 xchgl \\reg, %ebx\n\t /* else restore ebx from reg */
 .endif\n\t
 
 IIRC the two if's are anyway a bit wrong (looked into it when I added
 DOMULTI config option), I wanted some time ago to convert these to
 the current usage in glibc (where for less arguments the content is
 only exchanged), the only stopper was how to implement _syscall6 for
 PIC code I do not know how much the way of this implementation will
 influence the speed of execution, I can remember someone saying, that
 it is negligible. If so, the way the _syscall5 is done in glibc would
 be a way to implement _syscall6 as well.

Syscalls are *slow*. Whether we do push/pop or 2*xchg sounds very
insignificant to me. My feeling is that on modern CPUs the speed impact
goes exactly the opposite way.

I think *much* greater performance improvement can be achieved if we
implement SYSENTER support instead of the currently hardcoded int 0x80.

I haven't done any benchmarks about these though...

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

[PATCHv2] libc/x86: fix stack unwinding and backtrace information

2011-11-11 Thread Timo Teräs
When compiled without framepointer, the DWARF-2 CFI data is required
for proper stack unwinding.

This patch adds the CFI information to:
 * syscalls (so we get proper backtrace even for release builds)
   the ebx hack was removed as it would complicate the CFI generation
 * new thread stub function (so the backtrace is clean for user
   created threads)

Also pads the signal return trampolines separate from other functions.
If CFI info was found for signal return code (which seems to happen if
it's located right next a valid function), it will not be recognized
as signal trampoline (gcc unwinder and gdb check first CFI info, and
only if it does not exists it compares the exact opcode sequence to
see if we are at signal return code block). This fixes a real crash
if thread is cancelled and the cancellation handler fails to detect the
signal return frame.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 libc/sysdeps/linux/i386/bits/syscalls.h |   82 +++
 libc/sysdeps/linux/i386/clone.S |   17 ++
 libc/sysdeps/linux/i386/sigaction.c |4 ++
 3 files changed, 28 insertions(+), 75 deletions(-)

diff --git a/libc/sysdeps/linux/i386/bits/syscalls.h 
b/libc/sysdeps/linux/i386/bits/syscalls.h
index eeafb3a..1f60a44 100644
--- a/libc/sysdeps/linux/i386/bits/syscalls.h
+++ b/libc/sysdeps/linux/i386/bits/syscalls.h
@@ -13,6 +13,7 @@
 #ifndef __ASSEMBLER__
 
 #include errno.h
+#include common/sysdep.h
 
 #define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
 ({ \
@@ -31,90 +32,21 @@
 
 #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.  */
-/* gcc=4.6 with LTO need the same guards as IMA (a.k.a --combine) did.
- * See gcc.gnu.org/PR47577  */
-/* FIXME: drop these b* macros! */
-
-__asm__ (
-#if defined __DOMULTI__ || __GNUC_PREREQ (4, 6)
-   /* 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
-   .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
-
-   /* 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
-
-   .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
-
-#if defined __DOMULTI__ || __GNUC_PREREQ (4, 6)
-   .endif\n\t /* _BITS_SYSCALLS_ASM */
-#endif
-);
-
 #define LOADARGS_0
-#define LOADARGS_1  bpushl .L__X'%k2, %k2\n\t bmovl .L__X'%k2, %k2\n\t
+#define LOADARGS_1  push %%ebx\n\t CFI_ADJUST_CFA_OFFSET(4) \n\t 
CFI_REL_OFFSET(ebx, 0) \n\t movl %k2, %%ebx\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 LOADARGS_6  LOADARGS_1 push %%ebp\n\t CFI_ADJUST_CFA_OFFSET(4) 
\n\t CFI_REL_OFFSET(ebp, 0) \n\t movl %7, %%ebp\n\t
 
 #define RESTOREARGS_0
-#define RESTOREARGS_1  bpopl .L__X'%k2, %k2\n\t
+#define RESTOREARGS_1  pop %%ebx\n\t CFI_ADJUST_CFA_OFFSET(-4) \n\t 
CFI_RESTORE(ebx) \n\t RESTOREARGS_0
 #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_6  pop %%ebp\n\t CFI_ADJUST_CFA_OFFSET(-4) \n\t

[PATCH] libc/x86: fix stack unwinding and backtrace information

2011-11-10 Thread Timo Teräs
When compiled without framepointer, the DWARF-2 CFI data is required
for proper stack unwinding.

This patch adds the CFI information to:
 * syscalls (so we get proper backtrace even for release builds)
 * new thread stub function (so the backtrace is clean for user
   created threads)

Also pads the signal return trampolines separate from other functions.
If CFI info was found for signal return code (which seems to happen if
it's located right next a valid function), it will not be recognized
as signal trampoline (gcc unwinder and gdb check first CFI info, and
only if it does not exists it compares the exact opcode sequence to
see if we are at signal return code block). This fixes a real crash
if thread is cancelled and the cancellation handler fails to detect the
signal return frame.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 libc/sysdeps/linux/i386/bits/syscalls.h |   13 +
 libc/sysdeps/linux/i386/clone.S |   17 +
 libc/sysdeps/linux/i386/sigaction.c |4 
 3 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/libc/sysdeps/linux/i386/bits/syscalls.h 
b/libc/sysdeps/linux/i386/bits/syscalls.h
index eeafb3a..47d0b4c 100644
--- a/libc/sysdeps/linux/i386/bits/syscalls.h
+++ b/libc/sysdeps/linux/i386/bits/syscalls.h
@@ -13,6 +13,7 @@
 #ifndef __ASSEMBLER__
 
 #include errno.h
+#include common/sysdep.h
 
 #define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
 ({ \
@@ -71,6 +72,8 @@ __asm__ (
.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 */
+   CFI_ADJUST_CFA_OFFSET(4) \n\t
+   CFI_REL_OFFSET(ebx, 0) \n\t
.else\n\t
xchgl \\reg, %ebx\n\t /* else save ebx in reg, and load reg to ebx */
.endif\n\t
@@ -89,6 +92,8 @@ __asm__ (
.if 1 - \\name\n\t
.if 2 - \\name\n\t/* if reg can't be clobbered... */
popl %ebx\n\t /* restore ebx from stack */
+   CFI_ADJUST_CFA_OFFSET(-4) \n\t
+   CFI_RESTORE(ebx) \n\t
.else\n\t
xchgl \\reg, %ebx\n\t /* else restore ebx from reg */
.endif\n\t
@@ -106,7 +111,7 @@ __asm__ (
 #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 LOADARGS_6  LOADARGS_1 push %%ebp\n\t CFI_ADJUST_CFA_OFFSET(4) 
\n\t CFI_REL_OFFSET(ebp, 0) \n\t movl %7, %%ebp\n\t
 
 #define RESTOREARGS_0
 #define RESTOREARGS_1  bpopl .L__X'%k2, %k2\n\t
@@ -114,7 +119,7 @@ __asm__ (
 #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_6  pop %%ebp\n\t CFI_ADJUST_CFA_OFFSET(-4) \n\t 
CFI_RESTORE(ebp) \n\t RESTOREARGS_1
 
 #define ASMFMT_0()
 /* acdSD constraint would work too, but SD would use esi/edi and cause
@@ -162,7 +167,7 @@ __asm__ (
 #define LOADARGS_3
 #define LOADARGS_4
 #define LOADARGS_5
-#define LOADARGS_6  push %%ebp\n\t movl %7, %%ebp\n\t
+#define LOADARGS_6  push %%ebp\n\t CFI_ADJUST_CFA_OFFSET(4) \n\t 
CFI_REL_OFFSET(ebp, 0) \n\t movl %7, %%ebp\n\t
 
 #define RESTOREARGS_0
 #define RESTOREARGS_1
@@ -170,7 +175,7 @@ __asm__ (
 #define RESTOREARGS_3
 #define RESTOREARGS_4
 #define RESTOREARGS_5
-#define RESTOREARGS_6  pop %%ebp\n\t
+#define RESTOREARGS_6  pop %%ebp\n\t CFI_ADJUST_CFA_OFFSET(-4) \n\t 
CFI_RESTORE(ebp) \n\t
 
 #define ASMFMT_0()
 #define ASMFMT_1(arg1) \
diff --git a/libc/sysdeps/linux/i386/clone.S b/libc/sysdeps/linux/i386/clone.S
index a7de3fe..cf6cd35 100644
--- a/libc/sysdeps/linux/i386/clone.S
+++ b/libc/sysdeps/linux/i386/clone.S
@@ -25,6 +25,7 @@
 
 #define _ERRNO_H   1
 #include bits/errno.h
+#include sysdep.h
 #include sys/syscall.h
 
 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
@@ -45,6 +46,7 @@
 .global clone
 .type   clone,%function
 clone:
+   cfi_startproc;
/* Sanity check arguments.  */
movl$-EINVAL,%eax
 
@@ -86,17 +88,28 @@ clone:
 
/* Do the system call */
pushl   %ebx
+   cfi_adjust_cfa_offset (4)
pushl   %esi
+   cfi_adjust_cfa_offset (4)
pushl   %edi
+   cfi_adjust_cfa_offset (4)
+
movlTLS+12(%esp),%esi
+   cfi_rel_offset (esi, 4)
movlPTID+12(%esp),%edx
movlFLAGS+12(%esp),%ebx
+   cfi_rel_offset (ebx, 8)
movlCTID+12(%esp),%edi
+   cfi_rel_offset (edi, 0)
movl$__NR_clone,%eax
 #ifdef RESET_PID
/* Remember the flag value.  */
movl%ebx, (%ecx)
 #endif
+   /* End FDE now, because in the child the unwind info will be
+  wrong.  */
+   cfi_endproc
+
int $0x80
popl%edi
popl%esi
@@ -108,6 +121,9 @@ clone:
ret
 
 .Lthread_start:
+   cfi_startproc;
+   /* Clearing frame pointer is insufficient, use CFI

[PATCH] resolv: fix resolver to return TRY_AGAIN on timeout

2011-07-07 Thread Timo Teräs
This fixes the internal __dns_lookup to get a h_errno pointer so
it works nicely with the _r variants. Additionally the function is
modified to permanent error if the static buffer lengths are not
enough. And finally it fixed to return TRY_AGAIN if the nameservers
timeout.

res_search is fixed to continue searching if we receive TRY_AGAIN.
It could be a problem with the specific search domain's server
and not necessarily a problem in the recursive resolver we are
querying. For same reason, it does not make sense to differentiate
timeout or SERVFAIL error reply.

The biggest issue this fixes is that we now properly set h_errno
to TRY_AGAIN if upstream nameserver(s) timed out. Previously we
would have returned NETDB_INTERNAL.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 libc/inet/resolv.c |   95 +++-
 1 files changed, 49 insertions(+), 46 deletions(-)

diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index dc8a752..90ba31c 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -456,7 +456,8 @@ extern int __read_etc_hosts_r(parser_t *parser,
 extern int __dns_lookup(const char *name,
int type,
unsigned char **outpacket,
-   struct resolv_answer *a) attribute_hidden;
+   struct resolv_answer *a,
+   int *h_errnop) attribute_hidden;
 extern int __encode_dotted(const char *dotted,
unsigned char *dest,
int maxlen) attribute_hidden;
@@ -1233,7 +1234,8 @@ static int __decode_answer(const unsigned char *message, 
/* packet */
 int attribute_hidden __dns_lookup(const char *name,
int type,
unsigned char **outpacket,
-   struct resolv_answer *a)
+   struct resolv_answer *a,
+   int *h_errnop)
 {
/* Protected by __resolv_lock: */
static int last_ns_num = 0;
@@ -1265,11 +1267,15 @@ int attribute_hidden __dns_lookup(const char *name,
fd = -1;
lookup = NULL;
name_len = strlen(name);
-   if ((unsigned)name_len = MAXDNAME - MAXLEN_searchdomain - 2)
-   goto fail; /* paranoia */
+   if ((unsigned)name_len = MAXDNAME - MAXLEN_searchdomain - 2) {
+   *h_errnop = NO_RECOVERY;
+   goto fail1; /* paranoia */
+   }
lookup = malloc(name_len + 1/*for '.'*/ + MAXLEN_searchdomain + 1);
-   if (!packet || !lookup || !name[0])
-   goto fail;
+   if (!packet || !lookup || !name[0]) {
+   *h_errnop = NO_RECOVERY;
+   goto fail1;
+   }
ends_with_dot = (name[name_len - 1] == '.');
/* no strcpy! paranoia, user might change name[] under us */
memcpy(lookup, name, name_len);
@@ -1337,8 +1343,10 @@ int attribute_hidden __dns_lookup(const char *name,
h.rd = 1;
DPRINTF(encoding header\n, h.rd);
i = __encode_header(h, packet, PACKETSZ);
-   if (i  0)
-   goto fail;
+   if (i  0) {
+   *h_errnop = NO_RECOVERY;
+   goto fail1;
+   }
 
/* encode question */
DPRINTF(lookup name: %s\n, lookup);
@@ -1346,8 +1354,10 @@ int attribute_hidden __dns_lookup(const char *name,
q.qtype = type;
q.qclass = C_IN; /* CLASS_IN */
j = __encode_question(q, packet+i, PACKETSZ-i);
-   if (j  0)
-   goto fail;
+   if (j  0) {
+   *h_errnop = NO_RECOVERY;
+   goto fail1;
+   }
packet_len = i + j;
 
/* send packet */
@@ -1473,7 +1483,7 @@ int attribute_hidden __dns_lookup(const char *name,
/* no more search domains to try */
}
/* dont loop, this is no such host situation */
-   h_errno = HOST_NOT_FOUND;
+   *h_errnop = HOST_NOT_FOUND;
goto fail1;
}
/* Insert other non-fatal errors here, which do not warrant
@@ -1485,7 +1495,7 @@ int attribute_hidden __dns_lookup(const char *name,
 
/* Code below won't work correctly with h.ancount == 0, so... */
if (h.ancount = 0) {
-   h_errno = NO_DATA; /* [is this correct code to check 
for?] */
+   *h_errnop = NO_DATA; /* [is this correct code to check 
for?] */
goto fail1;
}
pos = HFIXEDSZ;
@@ -1562,8 +1572,7 @@ int attribute_hidden __dns_lookup(const char *name,
variant = -1;
} while (retries_left  0);
 
- fail:
-   h_errno = NETDB_INTERNAL;
+   *h_errnop = TRY_AGAIN;
  fail1:
if (fd != -1)
close(fd);
@@ -2104,9 +2113,8 @@ int gethostbyname_r

[PATCH] posix_fadvise64: fix x86 implementation

2011-04-20 Thread Timo Teräs
Commit 73d59554144f429b1cf0d4d7fa7de42bdf59ad92 completely broke
the x86 implementation of posix_fadvise64. It moved the first
the assembly code retn instruction gets missing depending on the

Technically the file has two implementaions for posix_fadvise64,
one when __NR_fadvise64_64 is available, and second one if only
__NR_fadvise64 is there. Fix the #ifdef's to be proper for that.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 libc/sysdeps/linux/i386/posix_fadvise64.S |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/libc/sysdeps/linux/i386/posix_fadvise64.S 
b/libc/sysdeps/linux/i386/posix_fadvise64.S
index b4aeff1..8a8947d 100644
--- a/libc/sysdeps/linux/i386/posix_fadvise64.S
+++ b/libc/sysdeps/linux/i386/posix_fadvise64.S
@@ -22,7 +22,7 @@
 #include bits/errno.h
 #include sys/syscall.h
 
-#if defined __NR_fadvise64_64
+#if defined __NR_fadvise64_64 || defined __NR_fadvise64
 
 /* Was named __libc_posix_fadvise64 for some inexplicable reason.
 ** google says only uclibc has *__libc*_posix_fadviseXXX,
@@ -35,6 +35,7 @@
 .global posix_fadvise64
 .type   posix_fadvise64,%function
 posix_fadvise64:
+#if defined __NR_fadvise64_64
/* Save regs  */
pushl   %ebp
pushl   %ebx
@@ -91,6 +92,7 @@ overflow:
 
/* Returns 0 on success, else an error code.  */
negl%eax
+#endif
 
/* Successful; return the syscall's value.  */
ret
-- 
1.7.1

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

[PATCH] resolv: fix res_close not to hang with ipv6

2011-04-08 Thread Timo Teräs
The memory release loop is missing an obvious counter increment.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 libc/inet/resolv.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index 47bab75..1e394d4 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -3006,9 +3006,9 @@ void res_close(void)
 #ifdef __UCLIBC_HAS_IPV6__
{
char *p1 = (char*) (_res.nsaddr_list[0]);
-   int m = 0;
+   int m;
/* free nsaddrs[m] if they do not point to nsaddr_list[x] */
-   while (m  ARRAY_SIZE(_res._u._ext.nsaddrs)) {
+   for (m = 0; m  ARRAY_SIZE(_res._u._ext.nsaddrs); m++) {
char *p2 = (char*)(_res._u._ext.nsaddrs[m]);
if (p2  p1 || (p2 - p1)  sizeof(_res.nsaddr_list))
free(p2);
-- 
1.7.1

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

Re: ldd segfaults on libdl.so for 0.9.32-rc3 because of if (*tmp)

2011-03-30 Thread Timo Teräs
On 03/30/2011 01:24 PM, Peter Mazinger wrote:
 how is HARDWIRED_ABSPATH config option set?

I'd say that most likely yes. :)

But the fix below is still valid and should be applied, IMHO.

 
 Thanks, Peter
  Original-Nachricht 
 Datum: Tue, 29 Mar 2011 23:15:18 -0500
 Von: Kevin Day thekevin...@gmail.com
 An: uClibc uClibc@uclibc.org
 Betreff: ldd segfaults on libdl.so for 0.9.32-rc3 because of if (*tmp)
 
 The problem happens around utils/ldd.c:555:
 tmp = strrchr(interp_dir, '/');
 if (*tmp)
 *tmp = '\0';
 else {
 free(interp_dir);
 interp_dir = interp_name;
 }

 The *tmp is the culprit.
 If NULL is returned by strrchr(), then a segfault happens.

 Perhaps the following is what is intended?
 tmp = strrchr(interp_dir, '/');
 if (tmp)
 *tmp = '\0';
 else {
 free(interp_dir);
 interp_dir = interp_name;
 }

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: [PATCH] malloc-standard: synchronize on fork

2011-03-28 Thread Timo Teräs
On 03/28/2011 06:15 PM, Rich Felker wrote:
 On Sun, Mar 27, 2011 at 10:47:10PM +0300, Timo Teräs wrote:
 On 03/27/2011 10:21 PM, Rich Felker wrote:
 On Sat, Mar 26, 2011 at 08:28:04PM +0200, Timo Teräs wrote:
 Otherwise other threads can leave malloc state locked, and the child
 will hang indefinitely if it tries to malloc something.

 This change by itself breaks as much as it fixes, unless the mutex
 implementation is reentrant and recursive. fork() is specified to be
 async-signal-safe, which means it's legal for a signal handler to call
 fork() while malloc() is being executed. With your patch, this will
 hang the program.

 It is recursive mutex. It's works perfectly fine if same thread locks
 that mutex multiple times.
 
 But not from a signal handler. There's almost surely a race between
 locking the mutex and having it in the right state so that the signal
 handler sees it's the owner.

Oh. That's right. There's a race for that. I've been trying to figure
how glibc handles that, but it'd seem that it does not. Hmmh.

Not sure what to do here. Need to think about it. Any great ideas?

-Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

Re: [PATCH] malloc-standard: synchronize on fork

2011-03-28 Thread Timo Teräs
On 03/29/2011 01:06 AM, Rich Felker wrote:
 On Mon, Mar 28, 2011 at 11:43:00PM +0300, Timo Teräs wrote:
 It is recursive mutex. It's works perfectly fine if same thread locks
 that mutex multiple times.

 But not from a signal handler. There's almost surely a race between
 locking the mutex and having it in the right state so that the signal
 handler sees it's the owner.

 Oh. That's right. There's a race for that. I've been trying to figure
 how glibc handles that, but it'd seem that it does not. Hmmh.

 Not sure what to do here. Need to think about it. Any great ideas?
 
 You could enhance the recursive mutex implementation to be reentrant -
 having a single atomic int that serves as both the lock status and the
 owner and updating it with an atomic compare-and-swap should be one
 way to do this.

Yes, I got the same idea too. Looking at the code, it might be easier to
do a specific lock implementation for this. It'd be nice, if we had a
general purpose re-entrant mutex implementation, though.

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

Re: [PATCH] malloc-standard: synchronize on fork

2011-03-27 Thread Timo Teräs
On 03/27/2011 10:21 PM, Rich Felker wrote:
 On Sat, Mar 26, 2011 at 08:28:04PM +0200, Timo Teräs wrote:
 Otherwise other threads can leave malloc state locked, and the child
 will hang indefinitely if it tries to malloc something.

 This change by itself breaks as much as it fixes, unless the mutex
 implementation is reentrant and recursive. fork() is specified to be
 async-signal-safe, which means it's legal for a signal handler to call
 fork() while malloc() is being executed. With your patch, this will
 hang the program.

It is recursive mutex. It's works perfectly fine if same thread locks
that mutex multiple times.

Doing fork from signal handler seems utterly stupid. That would need
extra precautions to work properly, because the malloc code is not
re-entrant.

But this is not the case I'm fixing. It's thread A doing malloc while
thread B is forking.

As such, this does not break anything. Or could you provide example code
on scenario that this breaks (and which was not broken before this)?

 I ran into the same issue developing musl's implementation of malloc,
 and for now I have left it alone. POSIX 2008 (SUSv4) went back on some
 of the promises of previous versions, and has now declared that it's
 UB to call any async-signal-unsafe functions (such as malloc()) after
 fork() in a multi-threaded program, so your patch is not needed to
 conform to the current standard, only to previous versions (and even
 then it's not clear that the older standard required malloc() after
 fork() to work in a threaded program).

Yes. I agree, it's bad practice do things like that. But it just so
happens, that there are programs doing this. This can also happen
indirectly in certain scenarios: e.g. using opendir/readdir of
/proc/self/fd to close open fd's. (opendir in uclibc seems ot use
malloc). This patch is intended to provide glibc compatibility with the
more or less broken programs.

 I may later revisit this issue and fix it, but the fix is not simply
 using locks. I would either need to ignore locking and actively repair
 all the potentially-corrupted malloc structures in the child process,
 or selectively determine which locks are held by the current thread
 (due to having interrupted malloc() with a signal handler) and only
 attempt to lock the other locks before forking. For uClibc which only
 has one big malloc() lock, it may be easier, but I think you'll at
 least need to fix the lock to be reentrant and either recursive or
 error-checking. And that of course has a cost...

This prevents other threads not to execute malloc while we are forking.
Thus assuring that we have consistent malloc-state for the child
process. Since the thread doing fork has malloc-lock, it will own the
lock, thus the lock can be safely reinitialized in the child (we need to
reinitilize it since TID change on fork). When the parent continues, the
lock is unlocked regularly and memory allocation can continue as normal.
This exactly what glibc does and it works.

This does not address the case that the thread forking is doing malloc
and forks from signal handler. That case is just utterly broken and not
worth fixing IMHO.

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

[PATCH] malloc-standard: synchronize on fork

2011-03-26 Thread Timo Teräs
Otherwise other threads can leave malloc state locked, and the child
will hang indefinitely if it tries to malloc something.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 libc/stdlib/malloc-standard/free.c |   17 +
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/libc/stdlib/malloc-standard/free.c 
b/libc/stdlib/malloc-standard/free.c
index 39e54d6..df512cc 100644
--- a/libc/stdlib/malloc-standard/free.c
+++ b/libc/stdlib/malloc-standard/free.c
@@ -118,6 +118,21 @@ int malloc_trim(size_t pad)
   to inline it at all call points, which turns out not to be an
   optimization at all. (Inlining it in __malloc_consolidate is fine though.)
 */
+static void _malloc_lock(void)
+{
+__UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(__malloc_lock);
+}
+
+static void _malloc_unlock(void)
+{
+__UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(__malloc_lock);
+}
+
+static void _malloc_reset(void)
+{
+__UCLIBC_MUTEX_INIT_VAR(__malloc_lock);
+}
+
 static void malloc_init_state(mstate av)
 {
 int i;
@@ -145,6 +160,8 @@ static void malloc_init_state(mstate av)
 
 av-top= initial_top(av);
 av-pagesize   = malloc_getpagesize;
+
+__libc_atfork(_malloc_lock, _malloc_unlock, _malloc_reset);
 }
 
 
-- 
1.7.1

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

Re: [PATCH] malloc-standard: synchronize on fork

2011-03-26 Thread Timo Teräs
On 03/26/2011 08:38 PM, Roman I Khimov wrote:
 В сообщении от 26 марта 2011 21:28:04 автор Timo Teräs написал:
 Otherwise other threads can leave malloc state locked, and the child
 will hang indefinitely if it tries to malloc something.

 Signed-off-by: Timo Teräs timo.te...@iki.fi
 
 FYI: https://bugs.busybox.net/show_bug.cgi?id=2341

Ah, didn't know there was a bug for this. But yes, the same bug happens
with NPTL too. And this patch fixes it. Tested it locally here. I have a
test program too if needed.

- Timo

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

Re: dlopen/dlclose thread safety

2011-03-24 Thread Timo Teräs
On 03/24/2011 12:27 AM, Mike Frysinger wrote:
 2011/3/23 Timo Teräs:
 On 03/23/2011 06:33 PM, Mike Frysinger wrote:
 On Wed, Mar 23, 2011 at 12:29 PM, Carmelo AMOROSO wrote:
 indeed we have seen also some issue with dlopen, when TLS variables were
 involved. One suspect we have is actually thread-safety. glibc use some
 locking primitives to access TLS block, while we don't.
 Not yet had a free time slot to look at this deeply.

 i'm not sure how thread safety would play a role with TLS variables.
 TLS, by definition, is per-thread and that is guaranteed by the
 ABI/compiler/C lib/kernel down to the variable level, and that whole
 stack shouldnt be poking into any shared state (beyond shared .text).

 ldso needs to allocate each global TLS variable from globally single
 place. That's how it organises the per-thread data area. So yes, when dl
 allocates the TLS variables it needs to go fiddle global variables.
 
 mmm my understanding was that each thread got its own chunk of TLS
 area at thread creation time, and after that the ldso only existed
 when the thread needed to know the address of its TLS.  what port are
 you talking about exactly ?

Using TLS variables is safe obviously.

But if after startup, someone does dlopen(libfoo.so) and libfoo defines
global TLS variables, those variables need to be allocated from the
global TLS tables. I believe that's mostly done in _dl_add_to_slotinfo.

However, I think this is not my problem.

I think the problem is _dl_loaded_modules as suspected first. What
happens likely is (foo.so and bar.so both depend on same module):
 Thread A   Thread B
 dlopen(foo.so)
   loads zap.so
 dlclose(foo.so)
   start unloading zap.so
   (finds it refcount=0)
dlopen(bar.so)
finds zap.so from _dl_loaded_modules
refcount not checked, it's just referenced
unconditionally
   unmaps zap.so
goes along with reference to module being
  unloaded
- BOOM

So yes, we seem to have bunch of globals unprotected. _dl_loaded_modules
and _dl_symbol_tables amongst others. (BTW. Singly linked list for
loaded_modules is really inefficient, we should probably make it a
hash table (indexed with st_dev and st_ino) so we can search it fast in
_dl_load_elf_shared_library().

So. As immediate bandage aid, we probably need to add rwlock (or just
regular mutex) to dlopen (rw)/dlsym (ro)/dlclose (rw). That should at
least prevent crashes. But yes, more fine grained locking (or even RCU)
would be preferable.

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


[PATCH] libdl: rudimentary locking for dlopen/dlsym/dlclose

2011-03-24 Thread Timo Teräs
This implements big-dlfcn lock to allow multithreaded usage of
dlopen/dlsym/dlclose. We should really clean up the dl code so
we can use more fine grained locking or even RCU where appropriate.
But at least we won't crash now.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 TODO   |1 +
 ldso/libdl/libdl.c |   54 +++
 2 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/TODO b/TODO
index ae305a5..95cabd5 100644
--- a/TODO
+++ b/TODO
@@ -101,6 +101,7 @@ TODO list for AFTER the uClibc 1.0.0 release:
 *) run 'nm -D --size-sort -t d libuClibc-0.9.26.so' and work on the
biggest things (i.e. stuff at the end of the list) to make
them smaller.
+*) Fix dlopen/dlsym/dlclose locking to more fine grained or use RCU
 more wishlist items here
 
 
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index 68cd579..e007f54 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -34,6 +34,7 @@
 #include stdio.h
 #include string.h /* Needed for 'strstr' prototype' */
 #include stdbool.h
+#include bits/uClibc_mutex.h
 
 #ifdef __UCLIBC_HAS_TLS__
 #include tls.h
@@ -44,6 +45,10 @@
 extern void _dl_add_to_slotinfo(struct link_map  *l);
 #endif
 
+/* TODO: get rid of global lock and use more finegrained locking, or
+ * perhaps RCU for the global structures */
+__UCLIBC_MUTEX_STATIC(_dl_mutex, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
+
 #ifdef SHARED
 # if defined(USE_TLS)  USE_TLS
 # include dl-tls.h
@@ -271,7 +276,7 @@ void dl_cleanup(void)
}
 }
 
-void *dlopen(const char *libname, int flag)
+static void *do_dlopen(const char *libname, int flag)
 {
struct elf_resolve *tpnt, *tfrom;
struct dyn_elf *dyn_chain, *rpnt = NULL, *dyn_ptr, *relro_ptr, *handle;
@@ -605,7 +610,18 @@ oops:
return NULL;
 }
 
-void *dlsym(void *vhandle, const char *name)
+void *dlopen(const char *libname, int flag)
+{
+   void *ret;
+
+   __UCLIBC_MUTEX_CONDITIONAL_LOCK(_dl_mutex, 1);
+   ret = do_dlopen(libname, flag);
+   __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(_dl_mutex, 1);
+
+   return ret;
+}
+
+static void *do_dlsym(void *vhandle, const char *name, void *caller_address)
 {
struct elf_resolve *tpnt, *tfrom;
struct dyn_elf *handle;
@@ -653,7 +669,7 @@ void *dlsym(void *vhandle, const char *name)
 * dynamic loader itself, as it doesn't know
 * how to properly treat it.
 */
-   from = (ElfW(Addr)) __builtin_return_address(0);
+   from = (ElfW(Addr)) caller_address;
 
tfrom = NULL;
for (rpnt = _dl_symbol_tables; rpnt; rpnt = rpnt-next) {
@@ -690,6 +706,17 @@ out:
return ret;
 }
 
+void *dlsym(void *vhandle, const char *name)
+{
+   void *ret;
+
+   __UCLIBC_MUTEX_CONDITIONAL_LOCK(_dl_mutex, 1);
+   ret = do_dlsym(vhandle, name, __builtin_return_address(0));
+   __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(_dl_mutex, 1);
+
+   return ret;
+}
+
 #if 0
 void *dlvsym(void *vhandle, const char *name, const char *version)
 {
@@ -957,7 +984,13 @@ static int do_dlclose(void *vhandle, int need_fini)
 
 int dlclose(void *vhandle)
 {
-   return do_dlclose(vhandle, 1);
+   int ret;
+
+   __UCLIBC_MUTEX_CONDITIONAL_LOCK(_dl_mutex, 1);
+   ret = do_dlclose(vhandle, 1);
+   __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(_dl_mutex, 1);
+
+   return ret;
 }
 
 char *dlerror(void)
@@ -1004,7 +1037,7 @@ int dlinfo(void)
return 0;
 }
 
-int dladdr(const void *__address, Dl_info * __info)
+static int do_dladdr(const void *__address, Dl_info * __info)
 {
struct elf_resolve *pelf;
struct elf_resolve *rpnt;
@@ -1108,3 +1141,14 @@ int dladdr(const void *__address, Dl_info * __info)
}
 }
 #endif
+
+int dladdr(const void *__address, Dl_info * __info)
+{
+   int ret;
+
+   __UCLIBC_MUTEX_CONDITIONAL_LOCK(_dl_mutex, 1);
+   ret = do_dladdr(__address, __info);
+   __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(_dl_mutex, 1);
+
+   return ret;
+}
-- 
1.7.1

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

Re: [PATCH] libdl: rudimentary locking for dlopen/dlsym/dlclose

2011-03-24 Thread Timo Teräs
On 03/24/2011 04:58 PM, Mike Frysinger wrote:
 2011/3/24 Timo Teräs:
 This implements big-dlfcn lock to allow multithreaded usage of
 dlopen/dlsym/dlclose. We should really clean up the dl code so
 we can use more fine grained locking or even RCU where appropriate.
 But at least we won't crash now.
 
 looks straight forward enough ... i'm assuming it actually fixes the
 crashes you were seeing ?

Yes. No crashes on my box anymore. Valgrind is happy too.
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


dlopen/dlclose thread safety

2011-03-23 Thread Timo Teräs
Hi all,

Is uclibc dlopen/dlclose thread safe? It looks like not. I'm currently
trouble shooting issue where I needed to make debug build of uclibc+vlc
and figure the issue out. Turned out that debug build of these very
randomly crashes in dlopen(). gdb says that this happens when two
threads are doing dlopen() and/or dlclose() simultaneously. So I have a
feeling that our implementation is not thread safe.

Valgrind says that we always do bad things at:
 ldso/libdl/libdl.c:453: if (!(runp-tpnt-rtld_flags  RTLD_GLOBAL)) {
accessing uninitialized (or unmapped) memory.

VLC does lot of loads/unloads to figure out which .so's it wants to use.
So I'd assume this is crashing when one thread is dlopening.

SUPPORT_LD_DEBUG is also garbled because it's printing stuff from two
dlopen() calls from two different threads. What I make of it, we are
completely borked if we try to use dl* multithreadedly. Could someone
with some ld knowledge at least add very basic mutexes to essential
parts so that we do not crash?

And yes, in libdl.so we should be able to use mutexes at least in NPTL
as the main libc.so provides pthread_mutex_* symbols, and forwards them
to libpthread if it's loaded. Though depending on how the code is
shared, we might need extra care to make sure that the loader .so does
not use those (as it can't depend on anything).

Cheers,
 Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


ldd broken with HARDWIRED_ABSPATH=n

2011-03-23 Thread Timo Teräs
Hi Peter,

Your commit 5dffed7dd1a413f3965af702fa7ecd79809d1988 removed absolute
path from the interpreter binary name embedded in ELF files.

This makes ldd seg.fault as it seems to assume absolute paths.

gdb sayeth:

(gdb) where
 #0  0x00111ae3 in find_elf_interpreter (ehdr=0xb7a74000) at
../utils/ldd.c:556
 #1  0x00111f2a in find_dependencies (filename=0x114910
/home/fabled/aports/main/libc0.9.32/src/uClibc-0.9.32-rc3/lib/librt.so.0.9.32)
at ../utils/ldd.c:676
 #2  0x0011228e in main (argc=1, argv=0xb6e8) at ../utils/ldd.c:777
(gdb) p tmp
tmp = NULL
(gdb) p interp_dir
$1 = 0x116660 ld-uClibc.so.0.9.32

Care to fix?

Thanks,
  Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: dlopen/dlclose thread safety

2011-03-23 Thread Timo Teräs
On 03/23/2011 06:33 PM, Mike Frysinger wrote:
 On Wed, Mar 23, 2011 at 12:29 PM, Carmelo AMOROSO wrote:
 indeed we have seen also some issue with dlopen, when TLS variables were
 involved. One suspect we have is actually thread-safety. glibc use some
 locking primitives to access TLS block, while we don't.
 Not yet had a free time slot to look at this deeply.
 
 i'm not sure how thread safety would play a role with TLS variables.
 TLS, by definition, is per-thread and that is guaranteed by the
 ABI/compiler/C lib/kernel down to the variable level, and that whole
 stack shouldnt be poking into any shared state (beyond shared .text).

ldso needs to allocate each global TLS variable from globally single
place. That's how it organises the per-thread data area. So yes, when dl
allocates the TLS variables it needs to go fiddle global variables.

I was worried if the dlopen searching of already loaded modules is safe.
Since dlopen first checks if the module has been already loaded or not,
which also touches global variables.

So there's multiple places where dlopen/dlclose need to touch global
data and requires mutexes.

- Timo

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


[PATCH 2/3] stdlib: fix arc4random return type to u_int32_t

2011-03-18 Thread Timo Teräs
It's documented to be u_int32_t and not uint32_t:
 http://www.manpagez.com/man/3/arc4random/

This also fixes a major bug that stdlib.h includes stdint.h. Things
might go very wrong because stdint.h has conditional defines and
if stdlib.h is included before #define's for stdint.h we end up
missing things and breaking builds (e.g. openjdk).

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 include/stdlib.h |4 ++--
 libc/stdlib/arc4random.c |3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/include/stdlib.h b/include/stdlib.h
index e9a8b84..7b35840 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -902,8 +902,8 @@ extern int getloadavg (double __loadavg[], int __nelem)
 #endif
 
 #ifdef __UCLIBC_HAS_ARC4RANDOM__
-#include stdint.h
-extern uint32_t arc4random(void);
+# include sys/types.h
+extern u_int32_t arc4random(void);
 extern void arc4random_stir(void);
 extern void arc4random_addrandom(unsigned char *, int);
 #endif
diff --git a/libc/stdlib/arc4random.c b/libc/stdlib/arc4random.c
index c7aed66..7b9b12d 100644
--- a/libc/stdlib/arc4random.c
+++ b/libc/stdlib/arc4random.c
@@ -30,6 +30,7 @@
 #include fcntl.h
 #include stdlib.h
 #include unistd.h
+#include stdint.h
 #include sys/types.h
 #include sys/param.h
 #include sys/time.h
@@ -175,7 +176,7 @@ arc4random_addrandom(u_char *dat, int datlen)
arc4_addrandom(rs, dat, datlen);
 }
 
-uint32_t
+u_int32_t
 arc4random(void)
 {
if (!rs_initialized)
-- 
1.7.1

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

[PATCH 1/3] ldso: limited support for $ORIGIN in rpath

2011-03-18 Thread Timo Teräs
Handle it if it's in the beginning of the rpath entry as it
should be.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 ldso/ldso/dl-elf.c |   80 ---
 ldso/ldso/ldso.c   |   18 ++--
 2 files changed, 59 insertions(+), 39 deletions(-)

diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 505247e..2b2d429 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -133,53 +133,60 @@ _dl_protect_relro (struct elf_resolve *l)
  * in uClibc/ldso/util/ldd.c */
 static struct elf_resolve *
 search_for_named_library(const char *name, int secure, const char *path_list,
-   struct dyn_elf **rpnt)
+   struct dyn_elf **rpnt, const char *origin)
 {
-   char *path, *path_n, *mylibname;
+   char *mylibname;
+   const char *p, *pn;
struct elf_resolve *tpnt;
-   int done;
+   int plen;
 
if (path_list==NULL)
return NULL;
 
-   /* We need a writable copy of this string, but we don't
-* need this allocated permanently since we don't want
-* to leak memory, so use alloca to put path on the stack */
-   done = _dl_strlen(path_list);
-   path = alloca(done + 1);
-
/* another bit of local storage */
mylibname = alloca(2050);
 
-   _dl_memcpy(path, path_list, done+1);
-
/* Unlike ldd.c, don't bother to eliminate double //s */
 
/* Replace colons with zeros in path_list */
/* : at the beginning or end of path maps to CWD */
/* :: anywhere maps CWD */
/*  maps to CWD */
-   done = 0;
-   path_n = path;
-   do {
-   if (*path == 0) {
-   *path = ':';
-   done = 1;
-   }
-   if (*path == ':') {
-   *path = 0;
-   if (*path_n)
-   _dl_strcpy(mylibname, path_n);
-   else
-   _dl_strcpy(mylibname, .); /* Assume current 
dir if empty path */
-   _dl_strcat(mylibname, /);
-   _dl_strcat(mylibname, name);
-   if ((tpnt = _dl_load_elf_shared_library(secure, rpnt, 
mylibname)) != NULL)
-   return tpnt;
-   path_n = path+1;
+   for (p = path_list; p != NULL; p = pn) {
+   pn = _dl_strchr(p + 1, ':');
+   if (pn != NULL) {
+   plen = pn - p;
+   pn++;
+   } else
+   plen = _dl_strlen(p);
+
+   if (plen = 7  _dl_memcmp(p, $ORIGIN, 7) == 0) {
+   int olen;
+   if (secure  plen != 7)
+   continue;
+   if (origin == NULL)
+   continue;
+   for (olen = _dl_strlen(origin) - 1; olen = 0  
origin[olen] != '/'; olen--)
+   ;
+   if (olen = 0)
+   continue;
+   _dl_memcpy(mylibname[0], origin, olen);
+   _dl_memcpy(mylibname[olen], p + 7, plen - 7);
+   mylibname[olen + plen - 7] = 0;
+   } else if (plen != 0) {
+   _dl_memcpy(mylibname, p, plen);
+   mylibname[plen] = 0;
+   } else {
+   _dl_strcpy(mylibname, .);
}
-   path++;
-   } while (!done);
+   _dl_strcat(mylibname, /);
+   _dl_strcat(mylibname, name);
+
+   tpnt = _dl_load_elf_shared_library(secure, rpnt, mylibname);
+   if (tpnt != NULL)
+   return tpnt;
+   }
+
return NULL;
 }
 
@@ -231,7 +238,8 @@ struct elf_resolve *_dl_load_shared_library(int secure, 
struct dyn_elf **rpnt,
if (pnt) {
pnt += (unsigned long) tpnt-dynamic_info[DT_STRTAB];
_dl_if_debug_dprint(\tsearching RPATH='%s'\n, pnt);
-   if ((tpnt1 = search_for_named_library(libname, secure, pnt, 
rpnt)) != NULL)
+   if ((tpnt1 = search_for_named_library(libname, secure, pnt, 
rpnt,
+ tpnt-libname)) != NULL)
return tpnt1;
}
 #endif
@@ -239,7 +247,7 @@ struct elf_resolve *_dl_load_shared_library(int secure, 
struct dyn_elf **rpnt,
/* Check in LD_{ELF_}LIBRARY_PATH, if specified and allowed */
if (_dl_library_path) {
_dl_if_debug_dprint(\tsearching LD_LIBRARY_PATH='%s'\n, 
_dl_library_path);
-   if ((tpnt1 = search_for_named_library(libname, secure, 
_dl_library_path, rpnt)) != NULL)
+   if ((tpnt1 = search_for_named_library(libname, secure, 
_dl_library_path, rpnt, NULL)) != NULL)
{
return tpnt1

[PATCH 3/3] ldso: support RTLD_NOLOAD

2011-03-18 Thread Timo Teräs
So application query if specified modile is loaded or not with
dlopen.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 ldso/include/dl-elf.h  |6 --
 ldso/ldso/dl-elf.c |   30 +-
 ldso/ldso/ldso.c   |4 +++-
 ldso/libdl/libdl.c |5 +++--
 libc/sysdeps/linux/common/bits/dlfcn.h |4 ++--
 5 files changed, 29 insertions(+), 20 deletions(-)

diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h
index 7fbb373..7102351 100644
--- a/ldso/include/dl-elf.h
+++ b/ldso/include/dl-elf.h
@@ -25,16 +25,18 @@ static __inline__ void _dl_map_cache(void) { }
 static __inline__ void _dl_unmap_cache(void) { }
 #endif
 
+#define DL_RESOLVE_SECURE  0x0001
+#define DL_RESOLVE_NOLOAD  0x0002
 
 /* Function prototypes for non-static stuff in readelflib1.c */
 extern void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
unsigned long rel_addr, unsigned long rel_size);
 extern int _dl_parse_relocation_information(struct dyn_elf *rpnt,
unsigned long rel_addr, unsigned long rel_size);
-extern struct elf_resolve * _dl_load_shared_library(int secure,
+extern struct elf_resolve * _dl_load_shared_library(int resolve_flags,
struct dyn_elf **rpnt, struct elf_resolve *tpnt, char *full_libname,
int trace_loaded_objects);
-extern struct elf_resolve * _dl_load_elf_shared_library(int secure,
+extern struct elf_resolve * _dl_load_elf_shared_library(int resolve_flags,
struct dyn_elf **rpnt, char *libname);
 extern struct elf_resolve *_dl_check_if_named_library_is_loaded(const char 
*full_libname,
int trace_loaded_objects);
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index 2b2d429..6d35bf2 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -132,7 +132,7 @@ _dl_protect_relro (struct elf_resolve *l)
 /* This function's behavior must exactly match that
  * in uClibc/ldso/util/ldd.c */
 static struct elf_resolve *
-search_for_named_library(const char *name, int secure, const char *path_list,
+search_for_named_library(const char *name, int resolve_flags, const char 
*path_list,
struct dyn_elf **rpnt, const char *origin)
 {
char *mylibname;
@@ -162,7 +162,7 @@ search_for_named_library(const char *name, int secure, 
const char *path_list,
 
if (plen = 7  _dl_memcmp(p, $ORIGIN, 7) == 0) {
int olen;
-   if (secure  plen != 7)
+   if ((resolve_flags  DL_RESOLVE_SECURE)  plen != 7)
continue;
if (origin == NULL)
continue;
@@ -182,7 +182,7 @@ search_for_named_library(const char *name, int secure, 
const char *path_list,
_dl_strcat(mylibname, /);
_dl_strcat(mylibname, name);
 
-   tpnt = _dl_load_elf_shared_library(secure, rpnt, mylibname);
+   tpnt = _dl_load_elf_shared_library(resolve_flags, rpnt, 
mylibname);
if (tpnt != NULL)
return tpnt;
}
@@ -194,7 +194,7 @@ search_for_named_library(const char *name, int secure, 
const char *path_list,
 unsigned long _dl_error_number;
 unsigned long _dl_internal_error_number;
 
-struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
+struct elf_resolve *_dl_load_shared_library(int resolve_flags, struct dyn_elf 
**rpnt,
struct elf_resolve *tpnt, char *full_libname, int attribute_unused 
trace_loaded_objects)
 {
char *pnt;
@@ -223,7 +223,7 @@ struct elf_resolve *_dl_load_shared_library(int secure, 
struct dyn_elf **rpnt,
 
if (libname != full_libname) {
_dl_if_debug_dprint(\ttrying file='%s'\n, full_libname);
-   tpnt1 = _dl_load_elf_shared_library(secure, rpnt, full_libname);
+   tpnt1 = _dl_load_elf_shared_library(resolve_flags, rpnt, 
full_libname);
if (tpnt1) {
return tpnt1;
}
@@ -238,7 +238,7 @@ struct elf_resolve *_dl_load_shared_library(int secure, 
struct dyn_elf **rpnt,
if (pnt) {
pnt += (unsigned long) tpnt-dynamic_info[DT_STRTAB];
_dl_if_debug_dprint(\tsearching RPATH='%s'\n, pnt);
-   if ((tpnt1 = search_for_named_library(libname, secure, pnt, 
rpnt,
+   if ((tpnt1 = search_for_named_library(libname, resolve_flags, 
pnt, rpnt,
  tpnt-libname)) != NULL)
return tpnt1;
}
@@ -247,7 +247,7 @@ struct elf_resolve *_dl_load_shared_library(int secure, 
struct dyn_elf **rpnt,
/* Check in LD_{ELF_}LIBRARY_PATH, if specified and allowed */
if (_dl_library_path) {
_dl_if_debug_dprint(\tsearching LD_LIBRARY_PATH='%s'\n, 
_dl_library_path);
-   if ((tpnt1 = search_for_named_library(libname

Re: getcontext

2011-03-16 Thread Timo Teräs
On 03/17/2011 01:06 AM, Rich Felker wrote:
 On Wed, Mar 16, 2011 at 09:16:48PM +0100, Joakim Tjernlund wrote:
 Impl. of portable CoRoutines, http://en.wikipedia.org/wiki/Coroutine ,
 likes to use get/setcontext. Don't think there is anything else these
 can use.
 
 Coroutines can be implemented portably on top of pthreads and
 condition variables, barriers, or semaphores.

But that's making the coroutines pointless. Their idea is to be light
weight. And you can achieve that only with get/setcontext. We'll one
could do setjmp hacks too. Or write one's own context changing things in
assembler.

But those are useful still today. E.g. the new Google Go language has
coroutines built-in into it. The language runtime implements them with
native assembler.
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: -lc -lpthread link order works on x86_64 glibc-2.9, but cause hang on uClibc-0.9.32-rc1 on mipsel with NPTL

2011-01-11 Thread Timo Teräs
On 01/11/2011 10:03 AM, Jian Peng wrote:
 -lc -lpthread link order works on Linux with glibc-2.9 on x86_64, but cause 
 hang on uClibc-0.9.32-rc1 on mipsel with NPTL

Would be because uclibc on mipsel does not support protected symbols.

uclibc on x86 and some other platforms works too. I believe someone
should be working on making the protected symbol support generic.

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


nptl_db not working

2010-12-31 Thread Timo Teräs
Hi all,

I was trying to debug a multithreaded program in uclibc, but ntpl_db was
not working at all.

I hunted down the problem the fact that we are doing strip -x to the
libpthread: it removes all non-global symbols.

However, nptl_db inspects the local system, and uses them to verify
libpthread (looks for static/local nptl_version symbol) and also to
hook into libpthread (it uses certain local symbols to find libpthread
event structures and modifies them). Thus gdb + uclibc nptl is broke.

I'm not sure how to modify makefiles so that we do *not* do strip -x
on libpthread, but this should be fixed. I removed the -x on global
STRIP_FLAGS from Rules.mak, recompiled and then gdb was much more
happier with ntpl_db.

Cheers,
  Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


[PATCH] nptl: fix Unwind_Resume PLT calls

2010-12-07 Thread Timo Teräs
My change a49b3a18e463cbe8c94c41501e386e7f4c61609e fixed two
Unwind_Resume calls to go via PLT to avoid text relocations for PIC
builds. However, it looks the reason for upstream not using PLT calls
is that ebx gets clobbered. So we need to reload it.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 .../sysv/linux/i386/i486/pthread_cond_timedwait.S  |4 
 .../unix/sysv/linux/i386/i486/pthread_cond_wait.S  |   18 +++---
 2 files changed, 15 insertions(+), 7 deletions(-)

diff --git 
a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S 
b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
index ac7983c..3b61367 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
@@ -648,6 +648,10 @@ __condvar_tw_cleanup:
 
movl%esi, (%esp)
 .LcallUR:
+#ifdef __PIC__
+   call__i686.get_pc_thunk.bx
+   addl$_GLOBAL_OFFSET_TABLE_, %ebx
+#endif
call_unwind_res...@plt
hlt
 .LENDCODE:
diff --git 
a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S 
b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
index abc963f..a1294c5 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
@@ -535,6 +535,10 @@ __condvar_w_cleanup:
 
movl%esi, (%esp)
 .LcallUR:
+#ifdef __PIC__
+   call__i686.get_pc_thunk.bx
+   addl$_GLOBAL_OFFSET_TABLE_, %ebx
+#endif
call_unwind_res...@plt
hlt
 .LENDCODE:
@@ -569,14 +573,14 @@ __condvar_w_cleanup:
 .Lcstend:
 
 #ifdef __PIC__
-   .section .gnu.linkonce.t.__i686.get_pc_thunk.cx,ax,@progbits
-   .globl  __i686.get_pc_thunk.cx
-   .hidden __i686.get_pc_thunk.cx
-   .type   __i686.get_pc_thunk.cx,@function
-__i686.get_pc_thunk.cx:
-   movl (%esp), %ecx;
+   .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,ax,@progbits
+   .globl  __i686.get_pc_thunk.bx
+   .hidden __i686.get_pc_thunk.bx
+   .type   __i686.get_pc_thunk.bx,@function
+__i686.get_pc_thunk.bx:
+   movl (%esp), %ebx;
ret
-   .size   __i686.get_pc_thunk.cx,.-__i686.get_pc_thunk.cx
+   .size   __i686.get_pc_thunk.bx,.-__i686.get_pc_thunk.bx
 #endif
 
 #ifdef SHARED
-- 
1.7.1

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

Re: [PATCH] libm/x86: use call instead of jump for wrappers

2010-11-01 Thread Timo Teräs
On 11/01/2010 03:16 AM, Denys Vlasenko wrote:
 On Sunday 31 October 2010 23:07, Timo Teräs wrote:
 On 10/31/2010 05:10 PM, Denys Vlasenko wrote:
 Since by breaking long double wrappers I proved that no one actually
 runs math testsuite (does anyone runs ANY part of testsuite?),
 I decided that now it is my obligation to fix math testsuite first,
 so that in the future it will be easier to catch breakatge.

 I fixed it to a certain degree already.

 Then I reverted your fix, and _verified_ that it works with both
 static and shared build.

 Your code crashed. Mine version did not. I did not run the test suite
 
 I think we all neglected testsuite for too long. It has bit rotted.
 Needs work to restore to runnable state...
 
 nor test the call thingy. Sorry about that. Just build failed by
 segfault vs. succeed was enough for me.
 
 Yes, I know how the failure must have looked on your side.
 What is unclear is what caused gcc to emit a prologue
 with some stack pushes...
 
 
 It needs to be saved/restored *if ebx is used*. In these stubs it is
 not used, thus it is not saved by gcc, and therefore tail jump is ok
 even with __PIC__.

 I do not merely think so. I tested it. Try in the directory
 where you successfully built shared uclibc using PIC:

 I remember that the original crash I fixed was caused by PIC and not
 SSP. The issue is that the jmp target name is outside __asm__  and
 translated by gcc to ebx+xxx. So you use implicitly ebx in your __asm__
 block. And thus gcc will save/restore and calculate the local ebx for
 you automatically.
 
 Uhhuh... so it will happen only if function gets called through
 inter-library stub. This should not happen with __GI_foo symbols, though -
 those are hidden and should be linked directly intra-library.
 
 BTW, there were no __GI_foo calls originally, I just called foo directly
 at first. Then affed __GI_ prefix. Maybe *that* fixed the problem.

I think you had __GI_ prefix all the time. I rebuilt again with the
original buggy config. It had both PIC and SSP enabled. The SSP abort
__stack_chk_fail is called via plt and causes the ebx load. So using
__SSP_ALL__ fixed this specific build.

 Thanks, replaced:

 -#if defined __i386__  defined __OPTIMIZE__  !defined __UCLIBC_HAS_SSP__
 +#if defined __i386__  defined __OPTIMIZE__  !defined __SSP_ALL__

 and pushed to git.

 Please add __PIC__ test.
 
 Do you see the failure with current git? I did __PIC__ test, it wroks for 
 me...

Yes, regular PIC and PIC+SSP now works. BUT, several other features do not.

If I'm building with -fPIC -pg it instruments all C functions with
profiler stuff which is called via PLT and causes EBX reloads
 -- crash

-fno-omit-frame-pointer is sometimes useful for profiling too
 -- crash

Also the upcoming -fsplit-stack will be broken by this too (that might
need additional uclibc support though).

And I'm pretty sure there's also other similar compiler features.
There's no predefined #defines in gcc for any of these.

What I'm trying to say that there are *numerous* situations when the
compiler can create stack frame for you without you ever knowing it. And
if you want to do a tail jump, you really should be doing it from .S
file where you control fully the prologue/epilogue code. (GCC naked
attribute does not seem to work on x86.)
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: [PATCH] libm/x86: use call instead of jump for wrappers

2010-10-31 Thread Timo Teräs
On 10/31/2010 08:57 AM, Timo Teräs wrote:
 Alternatively we could write the wrappers to cope with PIC properly and
 use the GCC attribute naked. Or write the wrappers as .S file.

Or write the current assembly part correctly to use call:

 @@ -69,7 +71,7 @@ long double func##l(long double x) \
__asm ( \
   fldt%1\n \
   fstpl   %1\n \

(Duh. Should have read this part to see that the floating point stuff is
written back to stack and not just modified in ST(0)).

So fix fstpl to push it proper position in stack.

 -  jmp  __stringify(__GI_##func) \n \
 +  call __stringify(__GI_##func) \n \

And add the stack pop here.

: =t (st_top) \
: m (x) \
); \

Assembly tail jump in middle of the code simply makes too many
assumptions on how gcc works IMHO.

The assembly block can make gcc generate all kind of interesting things
depending on what the modifiers it has and what else the function is doing.

My suggestion is: never do that. If you want to do it, use pure
assembler function (in .S) then you control the full function. Otherwise
it's bound to break someone's build because GCC assumes that execution
returns to function after the assembly block.
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: Troubles with nptl on Geode

2010-08-16 Thread Timo Teräs
On 08/16/2010 04:00 PM, Pirmin Walthert wrote:
 I'll send more information as soon as I've collected them, what may take
 a few days as I'm quite busy this week. 
 
 I've cross-compiled gdb now (and what I get is:
 
 #0  0xb7607343 in __pthread_mutex_cond_lock () from /lib/libpthread.so.0
 #1  0x in ?? ()

Try the patch I sent earlier:
http://lists.uclibc.org/pipermail/uclibc/2010-August/044250.html

Someone should apply it.

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


[PATCH] nptl: fix calling convention for __pthread_mutex_cond_lock

2010-08-06 Thread Timo Teräs
The assembly versions of pthread_cond_wait calls
__pthread_mutex_cond_lock and __pthread_mutex_cond_lock_adjust
using internal calling convention (which differs from default
calling convention at least on x86). Thus these two functions
must be defined with internal_function or the call sequence goes
wrong.

__pthread_mutex_cond_lock resides in
sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c, but it does
evil macro definitions and includes pthread_mutex_lock.c, so
we need to add some extra kludge to pthread_mutex_lock.c to get
the prototypes correctly.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 libpthread/nptl/pthreadP.h   |6 --
 libpthread/nptl/pthread_mutex_lock.c |7 ++-
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/libpthread/nptl/pthreadP.h b/libpthread/nptl/pthreadP.h
index 85601d4..c45bd11 100644
--- a/libpthread/nptl/pthreadP.h
+++ b/libpthread/nptl/pthreadP.h
@@ -414,8 +414,10 @@ extern int __pthread_mutex_trylock (pthread_mutex_t 
*_mutex);
 extern int __pthread_mutex_lock (pthread_mutex_t *__mutex);
 extern int __pthread_mutex_lock_internal (pthread_mutex_t *__mutex)
  attribute_hidden;
-extern int __pthread_mutex_cond_lock (pthread_mutex_t *__mutex);
-extern void __pthread_mutex_cond_lock_adjust (pthread_mutex_t *__mutex);
+extern int __pthread_mutex_cond_lock (pthread_mutex_t *__mutex)
+ attribute_hidden internal_function;
+extern void __pthread_mutex_cond_lock_adjust (pthread_mutex_t *__mutex)
+ attribute_hidden internal_function;
 extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex);
 extern int __pthread_mutex_unlock_internal (pthread_mutex_t *__mutex)
  attribute_hidden;
diff --git a/libpthread/nptl/pthread_mutex_lock.c 
b/libpthread/nptl/pthread_mutex_lock.c
index 78b6671..77147db 100644
--- a/libpthread/nptl/pthread_mutex_lock.c
+++ b/libpthread/nptl/pthread_mutex_lock.c
@@ -42,7 +42,11 @@ static int __pthread_mutex_lock_full (pthread_mutex_t *mutex)
 
 
 int
+#ifdef NO_INCR
+attribute_hidden internal_function
+#else
 attribute_protected
+#endif
 __pthread_mutex_lock (
  pthread_mutex_t *mutex)
 {
@@ -477,7 +481,8 @@ strong_alias (__pthread_mutex_lock, 
__pthread_mutex_lock_internal)
 
 
 #ifdef NO_INCR
-void attribute_protected
+void
+attribute_hidden internal_function
 __pthread_mutex_cond_lock_adjust (
  pthread_mutex_t *mutex)
 {
-- 
1.7.0.4

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

[PATCH] nptl: fix x86 assembly PIC relocations

2010-08-05 Thread Timo Teräs
Unwind_Resume needs to be called via PLT. Most calls are already proper,
this fix the remaining two problems.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 .../sysv/linux/i386/i486/pthread_cond_timedwait.S  |2 +-
 .../unix/sysv/linux/i386/i486/pthread_cond_wait.S  |2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git 
a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S 
b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
index 8a0c3fb..ac7983c 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
@@ -648,7 +648,7 @@ __condvar_tw_cleanup:
 
movl%esi, (%esp)
 .LcallUR:
-   call_Unwind_Resume
+   call_unwind_res...@plt
hlt
 .LENDCODE:
cfi_endproc
diff --git 
a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S 
b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
index 006fc51..abc963f 100644
--- a/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+++ b/libpthread/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
@@ -535,7 +535,7 @@ __condvar_w_cleanup:
 
movl%esi, (%esp)
 .LcallUR:
-   call_Unwind_Resume
+   call_unwind_res...@plt
hlt
 .LENDCODE:
cfi_endproc
-- 
1.7.0.4

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

[PATCH] more workarounds for GCC PR32219

2010-06-30 Thread Timo Teräs
Commit 2e53dd645d5348f207cec7f8595969dc566c5a55 workarounds GCC
bug when accessing _locale_init and _stdio_init. We need the same
fix for __errno_location and __h_errno_location otherwise we crash
calling null with static and non-threaded builds.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 libc/misc/internals/__uClibc_main.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libc/misc/internals/__uClibc_main.c 
b/libc/misc/internals/__uClibc_main.c
index 44d1620..e8c470b 100644
--- a/libc/misc/internals/__uClibc_main.c
+++ b/libc/misc/internals/__uClibc_main.c
@@ -447,11 +447,11 @@ void __uClibc_main(int (*main)(int, char **, char **), 
int argc,
  * have resulted in errno being set nonzero, so set it to 0 before
  * we call main.
  */
-if (likely(__errno_location!=NULL))
+if (likely(not_null_ptr(__errno_location)))
*(__errno_location()) = 0;
 
 /* Set h_errno to 0 as well */
-if (likely(__h_errno_location!=NULL))
+if (likely(not_null_ptr(__h_errno_location)))
*(__h_errno_location()) = 0;
 
 #if defined HAVE_CLEANUP_JMP_BUF  defined __UCLIBC_HAS_THREADS_NATIVE__
-- 
1.7.0.4

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

Re: resolver broken in NPTL build

2010-05-16 Thread Timo Teräs
On 05/16/2010 07:00 AM, Denys Vlasenko wrote:
 On Wednesday 12 May 2010 09:32, Timo Teräs wrote:
 The combination of

 commit aab4df0fb51660300559f5f29290709db2f7bfee
   resolv.c: add support for per thread res_state

 commit cca45baf8353d1e338d232f5bdb2d1d6b357f1da
   /etc/resolv.conf: support timeout:n and attempts:n options

 .. and NPTL results in broken resolver in very annoying ways.

 Now, it seems that most of the uclibc code does not work well
 if res_state is TLS variable. Technically, this is the correct thing
 to do since this gives proper per-thread resolving behavior, and
 it also makes the config options overridable per thread. This
 probably what apps expect as glibc does it too.
 
 Do you have an example where per-threadness is used?

I cannot really give any example immediately. But I still think
we should stick to the per-threaded behavior. That is what the
specifications say, and if we want to be specs compliant, _res
needs to be in TLS.

 But alas, most places use _res to sync up static global variables
 which results in breakage. It gets more or less randomly selected
 which threads options get applied. Also in case of multiple servers
 it looks like the retry logic is shared between all threads, e.g.
 two concurrent resolutions can make other resolvers skip nameservers
 due to shared last_ns_num.
 
 I see.

But still having the last_ns_num et al. as global, shared vars
would probably be okay.

 And finally the timeout/attempts commit breaks the accumulated stuff
 horribly. What happens is:
  1. multithreaded application startups, initializes resolver,
 resolves things just fine
  2. resolv.conf gets changed, application calls res_init
 after res_init uclibc will call res_sync on all resolver functions
 to refresh globals from the TLS variable _res
  3. res_init was called only in one thread, so other thread's
 _res contains all zeroes (yes, this is correct app usage:
 res_init should be called only from one thread)
  4. threads not calling res_init get broken resolver due to timeout
 being set to zero

 Now, one proper solution would be to:
  1. make __open_nameservers return the configuration options
  2. pass the config options struct to res_sync_func so it can do
 the proper overrides from per-thread _res
  3. remove the related globals and use locally config options from
 __open_nameservers

 But technically, the correct thing (as in glibc does this) is:
  - res_init increases global res_init timestamp
  - use _res (or pointer within there) for resolver retries etc.
get proper per-thread behavior
  - resolvers functions call maybe_init which reinitialize the
TLS'ed resolver state (e.g. reload resolv.conf) if their res_init
timestamp is out dated
 
 It looks very complex. Can we just use a shared structure?
 That will be simple and small.
 
 Anyone objects to this?

See above. I object having _res a global. Having the other stuff
shared is ok.

 As an immediate emergency kludge fix, the following might do:

 resolv: fix options handling for TLS _res

 If _res is in TLS (NPTL), it might not get initialized. Assume
 zeroes mean default values.

 Signed-off-by: Timo Teräs timo.te...@iki.fi

 diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
 index 320aec4..f8066d2 100644
 --- a/libc/inet/resolv.c
 +++ b/libc/inet/resolv.c
 @@ -2916,8 +2916,8 @@ static void res_sync_func(void)
 __nameserver[n].sa4 = rp-nsaddr_list[n]; /*
 struct copy
  #endif
 }
 -   __resolv_timeout = rp-retrans;
 -   __resolv_attempts = rp-retry;
 +   __resolv_timeout = rp-retrans ?: RES_TIMEOUT;
 +   __resolv_attempts = rp-retry ?: RES_DFLRETRY;
 /* Extend and comment what program is known
  * to use which _res.XXX member(s).
 
 Comment why this is needed might be good.

Isn't the commit log description enough?

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: [PATCH 1/2] static build: fix internal locking weaks to get pulled in always

2010-05-16 Thread Timo Teräs
On 05/16/2010 07:46 AM, Denys Vlasenko wrote:
 On Fri, May 7, 2010 at 4:19 PM, Timo Teras timo.te...@iki.fi wrote:
 Linker is smart and does not pull in weaks.os, ever. This happens
 because that compilation unit does not get strong references and
 ld eliminates dead code. We really need the weaks for static build
 in a compilation unit that is always there, otherwise it won't work.

 Signed-off-by: Timo Teras timo.te...@iki.fi
 
 Broke the build with attached .config:

Bummer, I'll take a look at this first thing tomorrow.

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


resolver broken in NPTL build

2010-05-12 Thread Timo Teräs
The combination of

commit aab4df0fb51660300559f5f29290709db2f7bfee
  resolv.c: add support for per thread res_state

commit cca45baf8353d1e338d232f5bdb2d1d6b357f1da
  /etc/resolv.conf: support timeout:n and attempts:n options

.. and NPTL results in broken resolver in very annoying ways.

Now, it seems that most of the uclibc code does not work well
if res_state is TLS variable. Technically, this is the correct thing
to do since this gives proper per-thread resolving behavior, and
it also makes the config options overridable per thread. This
probably what apps expect as glibc does it too.

But alas, most places use _res to sync up static global variables
which results in breakage. It gets more or less randomly selected
which threads options get applied. Also in case of multiple servers
it looks like the retry logic is shared between all threads, e.g.
two concurrent resolutions can make other resolvers skip nameservers
due to shared last_ns_num.

And finally the timeout/attempts commit breaks the accumulated stuff
horribly. What happens is:
 1. multithreaded application startups, initializes resolver,
resolves things just fine
 2. resolv.conf gets changed, application calls res_init
after res_init uclibc will call res_sync on all resolver functions
to refresh globals from the TLS variable _res
 3. res_init was called only in one thread, so other thread's
_res contains all zeroes (yes, this is correct app usage:
res_init should be called only from one thread)
 4. threads not calling res_init get broken resolver due to timeout
being set to zero

Now, one proper solution would be to:
 1. make __open_nameservers return the configuration options
 2. pass the config options struct to res_sync_func so it can do
the proper overrides from per-thread _res
 3. remove the related globals and use locally config options from
__open_nameservers

But technically, the correct thing (as in glibc does this) is:
 - res_init increases global res_init timestamp
 - use _res (or pointer within there) for resolver retries etc.
   get proper per-thread behavior
 - resolvers functions call maybe_init which reinitialize the
   TLS'ed resolver state (e.g. reload resolv.conf) if their res_init
   timestamp is out dated

As an immediate emergency kludge fix, the following might do:

resolv: fix options handling for TLS _res

If _res is in TLS (NPTL), it might not get initialized. Assume
zeroes mean default values.

Signed-off-by: Timo Teräs timo.te...@iki.fi

diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index 320aec4..f8066d2 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -2916,8 +2916,8 @@ static void res_sync_func(void)
__nameserver[n].sa4 = rp-nsaddr_list[n]; /*
struct copy
 #endif
}
-   __resolv_timeout = rp-retrans;
-   __resolv_attempts = rp-retry;
+   __resolv_timeout = rp-retrans ?: RES_TIMEOUT;
+   __resolv_attempts = rp-retry ?: RES_DFLRETRY;
/* Extend and comment what program is known
 * to use which _res.XXX member(s).




___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


[PATCH] libm/x86: use call instead of jump for wrappers

2010-05-11 Thread Timo Teräs
GCC can emit prologue/epilogue code for the functions in various
different cases:
 - frame pointers
 - PIC build (to load ebx for indirect calls/jumps)
 - forced stack smashing protection

If we used jump in such cases, we'd corrupt the call stack and
crash.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 libm/ldouble_wrappers.c |   12 +++-
 1 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/libm/ldouble_wrappers.c b/libm/ldouble_wrappers.c
index 7d5af90..5b424dc 100644
--- a/libm/ldouble_wrappers.c
+++ b/libm/ldouble_wrappers.c
@@ -60,7 +60,9 @@ long long func##l(long double x) \
  * The return value is returned in st(0) per ABI in both cases (returning
  * a long double or returning a double). So we can simply jump to func.
  * Using __GI_func in jump to make optimized intra-library jump.
- * gcc will still generate a useless ret after asm. Oh well...
+ *
+ * We do need to use call (instead of tail jump) as gcc can create
+ * stack frame, and push/modify/pop ebx during PIC build.
  */
 # define WRAPPER1(func) \
 long double func##l(long double x) \
@@ -69,7 +71,7 @@ long double func##l(long double x) \
__asm ( \
   fldt%1\n \
   fstpl   %1\n \
-  jmp  __stringify(__GI_##func) \n \
+  call __stringify(__GI_##func) \n \
: =t (st_top) \
: m (x) \
); \
@@ -82,7 +84,7 @@ int func##l(long double x) \
__asm ( \
   fldt%1\n \
   fstpl   %1\n \
-  jmp  __stringify(__GI_##func) \n \
+  call __stringify(__GI_##func) \n \
: =a (ret) \
: m (x) \
); \
@@ -95,7 +97,7 @@ long func##l(long double x) \
__asm ( \
   fldt%1\n \
   fstpl   %1\n \
-  jmp  __stringify(__GI_##func) \n \
+  call __stringify(__GI_##func) \n \
: =a (ret) \
: m (x) \
); \
@@ -108,7 +110,7 @@ long long func##l(long double x) \
__asm ( \
   fldt%1\n \
   fstpl   %1\n \
-  jmp  __stringify(__GI_##func) \n \
+  call __stringify(__GI_##func) \n \
: =A (ret) \
: m (x) \
); \
-- 
1.7.0.4

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

Re: alpine linux now officially uses uclibc with nptl

2010-05-05 Thread Timo Teräs

Carmelo AMOROSO wrote:

On 5/5/2010 3:48 PM, Natanael Copa wrote:

Last night we rebuild basicly all packages against uclibc with nptl
which means that alpine linux (x86) now officially run uclibc with
nptl. (first distro that does?)


STLinux distro (www.stlinux.com) for SH4 from STMicroelectronics
is running with uclibc-nptl since more than 2 years ;-)


Emphasis was on *x86*.

- Timo

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: [PATCH] nptl: proper soname handling

2010-05-02 Thread Timo Teräs

Rob Landley wrote:
You're saying you want to support having two installations of uClibc the same 
system.  Starting from separate dynamic linkers, and going through segregated 
library search paths.  Because nothing says lightweight and embedded like 
installing two or three complete copies of your entire library search path 
side by side.


What are you going to do about things like X11's libraries?  Build that twice 
too?  Along with zlib and openssl and whatever else the system needs?  
(Because it seems like you'd have to; how is shared library code calling into 
libc any different than an executable calling into libc?  Either you have a 
stable ABI with glue code and a collection of version-annotated obsolete 
symbols to bind against, or you don't.  When sizeof(sigset_t) changes, or you 
flip a config switch like UCLIBC_HAS_COMPAT_RES_STATE or 
UCLIBC_HAS_TM_EXTENSIONS or ipv6 or internationalization support...  Well 
libSDL.so depends on libc (and librt, libpthread, libm...) just as much as 
/bin/ls does.


It sonds like you're inviting users to experience the joy of _subtle_ bugs 
caused by library version skew.  (And, of course, to post them to this mailing 
list...)


Why are we opening this can of worms again?  I missed a curve...


No, the idea is not to have two versions installed all the time. The idea
is to allow the coexistance temporarily while package manager is upgrading
system. If we targeted flashable upgrade, then this would not be needed as
everything would be updated in one go.

If stuff is upgraded package at time, where libc is in one packages, and
e.g. busybox in separate package, we do need temporarily to have two
libc's if the ABI is incompatible. Otherwise the package manager would
have to have lots of extra kludge for libc upgrade. After full dist upgrade
the old libc should be gone, and new in place. But temporarily it needs to
work so e.g. perl/bb/shells/whatever works while their libc is mismatching.

And yes, it's not full solution. Deep library wise dependencies can be
temporarily broken. And yes, we do need stable API for uclibc at some point.
But since we don't have that yet, the temporary install of two libraries
during upgrade is the best option.

As conclusion was previously, it does not make sense to set ABI_VERSION
due to gcc dynamic-linker issues. But it'll help distro which tries to
keep compatibility on packages level (sets the dependencies right and
wants to perform clean upgrades).
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: [PATCH] nptl: proper soname handling

2010-05-02 Thread Timo Teräs

Rob Landley wrote:

No, the idea is not to have two versions installed all the time. The idea
is to allow the coexistance temporarily while package manager is upgrading
system.


Isn't this what static linking is for?


If we targeted flashable upgrade, then this would not be needed as
everything would be updated in one go.


Or the package manager would have to be statically linked?  (Yeah there's some 
implementation details making sure the stuff it calls during its operation 
still works, too, changing the $PATH to point to a static busybox covers a 
multitude of sins...)



And yes, it's not full solution. Deep library wise dependencies can be
temporarily broken. And yes, we do need stable API for uclibc at some
point. But since we don't have that yet, the temporary install of two
libraries during upgrade is the best option.


Or you could just statically link the package manager?


Yes, static linking would be more bullet proof. But either the user, or
the package manager needs jump through hoops in this case. There needs to
be the static versions compiled, they need to get installed, then finally
replaced with dynamic versions, etc.


As conclusion was previously, it does not make sense to set ABI_VERSION
due to gcc dynamic-linker issues. But it'll help distro which tries to
keep compatibility on packages level (sets the dependencies right and
wants to perform clean upgrades).


*shrug*


I'm not saying everyone needs to use this. I'm not asking support for this.
I'm not even recommending this for anyone.

I only want to do it myself, because it solves my immediate problems
with less work and more user friendly way than static linking. The package
manager is there to handle the other issues.
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: NPTL MIPS, current git head, programs block on startup

2010-04-27 Thread Timo Teräs

Andreas Schultz wrote:

With the current git head (00891d9cf07efd992023f255164bba93d657ece4)
NPTL no longer works on MIPS. It did work with
a501a33e9761f32b3d38ab9f113892abe7cef3f1.

The problem is somewhere in the _pthread_cleanup_push_defer:

Program terminated with signal 5, Trace/breakpoint trap.
#0  _pthread_cleanup_push_defer (buffer=value optimized out,
routine=value optimized out, arg=value optimized out) at
libpthread/nptl/forward.c:148
148 FORWARD2(_pthread_cleanup_push_defer,
(gdb) bt
#0  _pthread_cleanup_push_defer (buffer=value optimized out,
routine=value optimized out, arg=value optimized out) at
libpthread/nptl/forward.c:148
#1  0x2ac90ef0 in *__GI_openlog (ident=0x7fc74f48 hotplug,
logstat=3, logfac=24) at libc/misc/syslog/syslog.c:176
#2  0x004027cc in main (argc=2, argv=0x7fc74454) at ctrl.c:932

It seems that it is stuck in a endless loop, where the FORWARD2
wrapper calls itself instead of the real implementation.


Uh. Is the application linked against libc before libpthread?
Check with ldd the order of how libraries are pulled in.


Looking at init.c my best guess would be that
.ptr__pthread_cleanup_push_defer should be initialized with
__pthread_cleanup_push_defer and not with _pthread_cleanup_push_defer
(two undelines instead of one).


It's because MIPS ld.so is not supporting protected symbols yet.
Mmm... Using the two underscore variant might help for immediate
problems, but other things will broken unless protected symbols
are implemented.

Changing linking order of application to pull in libpthread first
should fix it too.
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: NPTL MIPS, current git head, programs block on startup

2010-04-27 Thread Timo Teräs

Andreas Schultz wrote:

2010/4/27 Timo Teräs timo.te...@iki.fi:

Andreas Schultz wrote:

[...]


Uh. Is the application linked against libc before libpthread?


The application is not directly linked against libpthread, but one of
the other libraries pulls it in.


This has never worked on MIPS. Someone needs to implement the
protected symbol support for mips ld.so.


Check with ldd the order of how libraries are pulled in.


Looking at init.c my best guess would be that
.ptr__pthread_cleanup_push_defer should be initialized with
__pthread_cleanup_push_defer and not with _pthread_cleanup_push_defer
(two undelines instead of one).

It's because MIPS ld.so is not supporting protected symbols yet.
Mmm... Using the two underscore variant might help for immediate
problems, but other things will broken unless protected symbols
are implemented.


The two underscore change alone is not sufficient, i have now managed
to get it working with the attached patch. Everything seems to fine so
far.


Forgot to attach the patch?

I learned the hard way that it's not easily doable without the
protected symbols. Otherwise you easily mess up one of the weird
linking scenarios or how libc-libpthread interacts.


Changing linking order of application to pull in libpthread first
should fix it too.


I'll try that...


Hacky solution for you is to add -lpthread for your main application.
Proper solution is protected symbol support in ld.so.
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: NPTL MIPS, current git head, programs block on startup

2010-04-27 Thread Timo Teräs

Andreas Schultz wrote:

2010/4/27 Timo Teräs timo.te...@iki.fi:

Andreas Schultz wrote:

2010/4/27 Timo Teräs timo.te...@iki.fi:

Andreas Schultz wrote:

[...]


Uh. Is the application linked against libc before libpthread?

The application is not directly linked against libpthread, but one of
the other libraries pulls it in.

This has never worked on MIPS. Someone needs to implement the
protected symbol support for mips ld.so.


Check with ldd the order of how libraries are pulled in.


Looking at init.c my best guess would be that
.ptr__pthread_cleanup_push_defer should be initialized with
__pthread_cleanup_push_defer and not with _pthread_cleanup_push_defer
(two undelines instead of one).

It's because MIPS ld.so is not supporting protected symbols yet.
Mmm... Using the two underscore variant might help for immediate
problems, but other things will broken unless protected symbols
are implemented.

The two underscore change alone is not sufficient, i have now managed
to get it working with the attached patch. Everything seems to fine so
far.

Forgot to attach the patch?


ups, yes...


This as such, will not fix all problems. All the symbols in the
forwarding table need special attention. Currently all those symbols
are marked with attribute_protected and it's expected that ld.so makes
sure the libc counter parts do not override the libpthread internals.
This currently works only on x86.


I learned the hard way that it's not easily doable without the
protected symbols. Otherwise you easily mess up one of the weird
linking scenarios or how libc-libpthread interacts.


mhh, there seem to be lots of protected symbols :-(


Yes. I recently added those. Each function in the struct you are
modifying is attribute_protected to make sure libpthread and libc
interact properly under various circumstances.

We could get away from using protected symbols if we renamed all
those symbols to follow some rules. But attribute_hidden for easier
at the time for me.

Basically, all libpthread exported function would need to have
internal libpthread used in the struct there, and then aliased to
the exported name.

Looking at the code, some of the symbols are done like that:
- many pthread_* functions are referring to __pthread_*
- many __pthread_* functions are referring to __pthread_*_internal

BUT, some are just referring to the symbol with same name. This
will break things without attribute_protected and ld.so support for
it.

Sadly, this has never worked properly. I may have renamed the
two symbols involved for symmetry before fully understanding how
the beast worked. But now it gives a good indication that there's
a problem instead of breaking in subtle ways later.

Also, using protected symbols is slightly better since it produces
smaller libraries. It generates less symbols.


Changing linking order of application to pull in libpthread first
should fix it too.

I'll try that...

Hacky solution for you is to add -lpthread for your main application.
Proper solution is protected symbol support in ld.so.


Does linking the main binary to -lpthread fix the problem?
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: [PATCH] ldso/x86_64: support protected symbols

2010-04-27 Thread Timo Teräs

Roman I Khimov wrote:

Fixes dltest with NPTL.

Signed-off-by: Roman I Khimov khi...@altell.ru
---
 ldso/ldso/x86_64/elfinterp.c |   10 --
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/ldso/ldso/x86_64/elfinterp.c b/ldso/ldso/x86_64/elfinterp.c
index 54528d3..ec53c48 100644
--- a/ldso/ldso/x86_64/elfinterp.c
+++ b/ldso/ldso/x86_64/elfinterp.c
@@ -172,7 +172,9 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf 
*scope,
symbol_addr = 0;
symname = strtab + sym-st_name;
 
-	if (symtab_index) {

+   if (symtab_index 
+   (ELF64_ST_VISIBILITY(symtab[symtab_index].st_other)
+!= STV_PROTECTED)) {
symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt,
elf_machine_type_class(reloc_type), tls_tpnt);
/*
@@ -189,7 +191,11 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf 
*scope,
/* Relocs against STN_UNDEF are usually treated as using a
 * symbol value of zero, and using the module containing the
 * reloc itself. */
-   symbol_addr = sym-st_value;
+   if (symtab_index)
+   symbol_addr = DL_FIND_HASH_VALUE(tpnt, 
elf_machine_type_class(reloc_type),
+sym);
+   else
+   symbol_addr = sym-st_value;
tls_tpnt = tpnt;
}
 


Joakim had a clean up patch for the above construct. See patch 1/2 of:
 http://lists.uclibc.org/pipermail/uclibc/2010-April/043840.html
(patch 2/2 there is wrong). See also rest of the thread.

For some reason that did not got merged yet. Austin, care to merge
that?

But otherwise looks good.

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: various nptl patches

2010-04-25 Thread Timo Teräs

Joakim Tjernlund wrote:

Timo Teräs timo.te...@gmail.com wrote on 2010/04/17 12:09:22:

Joakim Tjernlund wrote:

Finally looked at the ldso patch and I am not entirely happy with it.
I think the general structure should be different to make it easier
to follow the code and port it to other archs. I can probably
take a stab at it during the weekend but I have no env. to test in
so I will have to do it blindly.

So this is what I came up with. I do wonder if not linux_resolver
need PROTECTED support too? Have you tested with LAZY relocation too?

Have not tested lazy yet.


The LAZY relocs is a bigger problem though. That has to work so it would be 
great if
you could test that too.


Hi Timo, did you get a chance to test LAZY relocs too? Now that
NPTL is in main line it would be good to know if PROTECTED works
as is or if more work is needed.


Tested them now. LAZY works as expected too.

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: [PATCH] nptl: proper soname handling

2010-04-23 Thread Timo Teräs

Austin Foxley wrote:

On 04/20/2010 07:49 AM, Natanael Copa wrote:

Since sublevel releases are not ABI compatible we need to adjust
the soname to include the sublevel version.

This makes it possible to install ABI incompatible versions of the
library side by side so clean upgrades are possible.


Applied, minus the mistaken LDFLAGS hunk


It might be useful to do:

-ABI_VERSION   := $(VERSION)
+ABI_VERSION   := $(MAJOR_VERSION)

Since it seems that ld.so soname is hardcoded in GCC. If you want to
use something else than /lib/ld-uClibc.so.0 as dynamic linker, you also
need to update GCC default configration, create alternate specfile
overriding the hardcoded -dynamic-linker, or pass-in -Wl,-dynamic-linker,...
when compiling.

Otherwise you end up with broken stuff. I'm thinking it might be
better if the distro maintainer overrides ABI_VERSION and gcc together
so gcc with default options will produce working binaries.

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: [PATCH] nptl: proper soname handling

2010-04-23 Thread Timo Teräs

Austin Foxley wrote:

On 04/23/2010 07:18 AM, Timo Teräs wrote:

Austin Foxley wrote:

On 04/20/2010 07:49 AM, Natanael Copa wrote:

Since sublevel releases are not ABI compatible we need to adjust
the soname to include the sublevel version.

This makes it possible to install ABI incompatible versions of the
library side by side so clean upgrades are possible.

Applied, minus the mistaken LDFLAGS hunk

It might be useful to do:

-ABI_VERSION   := $(VERSION)
+ABI_VERSION   := $(MAJOR_VERSION)

Since it seems that ld.so soname is hardcoded in GCC. If you want to
use something else than /lib/ld-uClibc.so.0 as dynamic linker, you also
need to update GCC default configration, create alternate specfile
overriding the hardcoded -dynamic-linker, or pass-in
-Wl,-dynamic-linker,...
when compiling.


Hmm, I didn't realize GCC hardcoded that. I'll push a fix.


Me neither. Actually the dynamic section is generated properly. It's
the .interp section that goes wrong. And I didn't notice that until
trying to run things side-by-side where ld-uClibc.so.0 and
ld-uClibc.so.0.9.32 did not refer to same file.
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: [PATCH] nptl: proper soname handling

2010-04-22 Thread Timo Teräs

Michael Deutschmann wrote:

On Tue, 20 Apr 2010, Natanael Copa wrote:

Since sublevel releases are not ABI compatible we need to adjust
the soname to include the sublevel version.


I see two reasons that this would be pointless.

First, you'd need more than a more precise statement of the uClibc source
version, because with uClibc, a single version of the source can produce
many different ABI-incompatible libc.so.0 files.


Yes, this does not help on building universal side-by-side thing.

But within one distribution you generally want to keep the ABI compatible.
This really is configuration management issue, and doable inside a single 
distribution.



Second, sonames don't really help with the C library, because every other
shared library on a system is linked to the C library.  The differences in
the C library often distort the ABI of these other libraries.  It's very
complicated to keep appropriate versions side-by-side because the soname
of the other shared libraries does not change.

In the case where the C library change doesn't outright break the other
shared libraries, changing the soname makes it worse because an
application can end up loading two different C libraries at once -- one
through it's own DT_NEEDED, and one through the DT_NEEDED on another
shared library.


Again. This is configuration management issue. The distribution build system
and package manager need to take special precaution here to not create
binary packages ultimately depending on two different ABI versions of same
package.

The patch is still useful, as it makes ABI_VERSION configurable so each
builder can define their ABI_VERSION something that makes sense to them.

This is not a universal solution for all, but a step to right direction
and helps a lot of distribution maintainer who would like to have a clean
upgrade path. So IMHO the soname makes sense.
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: [PATCH] nptl: proper soname handling

2010-04-22 Thread Timo Teräs

Michael Deutschmann wrote:

On Thu, 22 Apr 2010, Natanael Copa wrote:

Do you have any better suggestions how to upgrade a running system?


First, build the new uClibc, but don't install it yet.

Build a customized ld-uclibc.so.0, from the previous uClibc source, that
looks in a different place for shared libraries and ignores the
/etc/ld.so.* files.  Install it under a different filename.


So for each transition X - Y you need both X and Y versions recompiled.
If you want upgrade from n+1 different versions, you need to do work n
times.


Write a utility to modify the INTERP filename specified in an executable
from /lib/ld-uclibc.so.0 to the filename of the special ld.so.  (This is
much simpler if the temporary ld.so filename is the same length as the
original.)

Hardlink the existing shared libraries into the alternate position, then
hack every existing installed executable in this way.


This means you need to mangle existing binaries?! This invalidates lot
of package manager features. It also means that the running system cannot
be reproduced from packages.


Then, delete all the old libraries in /usr/lib and the include files. The
shared libraries will be preserved by the hardlink, while everything else
is dispensible.  The system should still work for everything except
compilation.

Now, install the new uClibc.  Unless the ABI is so thoroughly broken as
to invalidate the old specs or libgcc.a, you should now be able to compile
new binaries.

I intend to do something like this for my 0.9.30.3 to 0.9.31 rollover,
but I haven't finished writing the necessary utilities yet.


Honestly. I still think it's less work to track the config, change
ABI_VERSION when the ABI breaks, and make binary packages in a way that
it depends only on packages using same libc ABI.

This is fairly easily scriptable on any sane build system.

You also get more or less free the fact that you can upgrade from any
previous version.

But as mentioned, it works only when making sure that the ABI_VERSION
is maintained properly. Since uclibc provides currently no ABI stability
the distribution maintainers can ensure that this holds true.

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


another set of nptl patches

2010-04-22 Thread Timo Teräs

This should make things work even if application not using libpthread
dlopen():s a library pulling in libpthread.

Also some minor other fixes.

From 73e70c465830884b98d5036cee0f47b8c77ba07e Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Timo=20Ter=C3=A4s?= timo.te...@iki.fi
Date: Thu, 22 Apr 2010 05:41:17 +
Subject: [PATCH 1/5] nptl: fix malloc library locking
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

Update malloc library to use internal uclibc locking primitives
to get the libpthread calls correct.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 libc/stdlib/malloc/heap.h   |7 +++
 libc/stdlib/malloc/malloc.h |   11 +--
 2 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/libc/stdlib/malloc/heap.h b/libc/stdlib/malloc/heap.h
index c0c5df8..3038079 100644
--- a/libc/stdlib/malloc/heap.h
+++ b/libc/stdlib/malloc/heap.h
@@ -16,11 +16,10 @@
 
 /* On multi-threaded systems, the heap includes a lock.  */
 #ifdef __UCLIBC_HAS_THREADS__
-# include pthread.h
-# include bits/uClibc_pthread.h
+# include bits/uClibc_mutex.h
 # define HEAP_USE_LOCKING
-# define __heap_lock(heap_lock) __pthread_mutex_lock (heap_lock)
-# define __heap_unlock(heap_lock) __pthread_mutex_unlock (heap_lock)
+# define __heap_lock(heap_lock) __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(*(heap_lock))
+# define __heap_unlock(heap_lock) __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(*(heap_lock))
 #else
 # define __heap_lock(heap_lock)
 # define __heap_unlock(heap_lock)
diff --git a/libc/stdlib/malloc/malloc.h b/libc/stdlib/malloc/malloc.h
index 2afc3a8..0a4b43b 100644
--- a/libc/stdlib/malloc/malloc.h
+++ b/libc/stdlib/malloc/malloc.h
@@ -132,13 +132,12 @@ extern int __malloc_mmb_debug;
 /* Locking for multithreaded apps.  */
 #ifdef __UCLIBC_HAS_THREADS__
 
-# include pthread.h
-# include bits/uClibc_pthread.h
+# include bits/uClibc_mutex.h
 
 # define MALLOC_USE_LOCKING
 
-typedef pthread_mutex_t malloc_mutex_t;
-# define MALLOC_MUTEX_INIT	PTHREAD_MUTEX_INITIALIZER
+typedef __UCLIBC_MUTEX_TYPE malloc_mutex_t;
+# define MALLOC_MUTEX_INIT	__UCLIBC_MUTEX_INITIALIZER
 
 # ifdef MALLOC_USE_SBRK
 /* This lock is used to serialize uses of the `sbrk' function (in both
@@ -146,8 +145,8 @@ typedef pthread_mutex_t malloc_mutex_t;
things will break if these multiple calls are interleaved with another
thread's use of sbrk!).  */
 extern malloc_mutex_t __malloc_sbrk_lock;
-#  define __malloc_lock_sbrk()	__pthread_mutex_lock (__malloc_sbrk_lock)
-#  define __malloc_unlock_sbrk() __pthread_mutex_unlock (__malloc_sbrk_lock)
+#  define __malloc_lock_sbrk()	__UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE (__malloc_sbrk_lock)
+#  define __malloc_unlock_sbrk() __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE (__malloc_sbrk_lock)
 # endif /* MALLOC_USE_SBRK */
 
 #else /* !__UCLIBC_HAS_THREADS__ */
-- 
1.6.3.3

From 0c701f4fcdda60b7abd5e02c74d35dd7127ff773 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Timo=20Ter=C3=A4s?= timo.te...@iki.fi
Date: Thu, 22 Apr 2010 05:43:00 +
Subject: [PATCH 2/5] nptl: fix warnings of shadowing __self
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

Stdio locking macroes do:
  void *__self = THREAD_SELF;

But THREAD_SELF uses __self also internally which causes shadowing
warnings. Just rename the outer variable for now. Might be an idea
to convert the macroes to static inline functions.

Signed-off-by: Timo Teräs timo.te...@iki.fi
---
 libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h |   12 ++--
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h b/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h
index b8efdd8..3437e61 100644
--- a/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h
+++ b/libpthread/nptl/sysdeps/pthread/bits/stdio-lock.h
@@ -39,11 +39,11 @@ typedef struct { int lock; int cnt; void *owner; } _IO_lock_t;
 
 #define _IO_lock_lock(_name) \
   do {	  \
-void *__self = THREAD_SELF;		  \
-if ((_name).owner != __self)	  \
+void *__meself = THREAD_SELF;		  \
+if ((_name).owner != __meself)	  \
   {	  \
 	lll_lock ((_name).lock, LLL_PRIVATE);  \
-(_name).owner = __self;		  \
+(_name).owner = __meself;		  \
   }	  \
 ++(_name).cnt;			  \
   } while (0)
@@ -51,12 +51,12 @@ typedef struct { int lock; int cnt; void *owner; } _IO_lock_t;
 #define _IO_lock_trylock(_name) \
   ({	  \
 int __result = 0;			  \
-void *__self = THREAD_SELF;		  \
-if ((_name).owner != __self)	  \
+void *__meself = THREAD_SELF;		  \
+if ((_name).owner != __meself)	  \
   {	  \
 if (lll_trylock ((_name).lock) == 0)  \
   {  \
-(_name).owner = __self;	  \
+(_name).owner = __meself;	  \
 

Re: [PATCH] nptl: proper soname handling

2010-04-22 Thread Timo Teräs

Michael Deutschmann wrote:

On Thu, 22 Apr 2010, Timo wrote:

This really is configuration management issue, and doable inside a single
distribution.


I don't understand what configuration management means.  Perhaps this
is why I don't quite get you and Natanael...


It means the system used to build all packages, is aware of the multiple
versions of libc it has had. It means it also makes sure the produced
binaries are only linked against one version of libc, and marks the 
binary package dependencies so that the package manager can ensure that

all dependency libraries depend on same version of libc. Thus producing
a runnable application.


Basically, my point is that in general, changing the soname is only of
value to enable side-by-side.  But in the case of the C library itself,
changing the soname is far from sufficent, because there is no easy way to
modify the sonames of every dependent shared library (ncurses, readline,
bfd) so as to avoid collision.


You are right. It is the package managers responsibility to make sure
that there is no such conflicts.


The distinction between libc.so.6 (Glibc) and libc.so.0 just barely
works, and only because of special magic in ldconfig.  If you want to
support a libc.so.0 to libc.so.0.1 rollover in the same way, you'll need
to also add LIB_ELF_LIBC0_1 to ldso/include/dl-defs.h, and then ring the
changes through ld.so and ldconfig.


Why? This only needed for ldso cache. It would seem that these magics
are only used to see if the application is incorrectly linked against
different libc versions. It is probably mostly needed for the multilib
stuff where you have 32- and 64-bit libraries installed on same system.

I don't see any immediate problem with mapping libc.so.0* to LIB_ELF_LIBC0
because in addition to the flag field also the soname is compared. If
the package manager / build system ensures proper dependencies, the
soname is sufficient.

If ldso cache is turned off, this stuff is not even used at all.

But yes, the ld cache is not working exactly right now. It maps the
libc with long soname now to LIB_ELF. Everything will work, it just
will not emit the warning if linked against e.g. libc0 and libc6.


(Seeing as uClibc fans usually compile everything locally, and only need
side-by-side at the moment of rollover, I'd add a single LIB_ELF_OLD_UC
flags, and provide a utility to mark every binary on a system as OLD to
ld.so and ldconfig.  Rather than an endless LIB_ELF_LIBC0_1,
LIB_ELF_LIBC0_2, ... until the type field overflows  This would
suffice so long as every old-ABI program gets recompiled before the next
ABI break)

It occurs to me that what you might want is not side-by-side, but
self-identification of executables.  So that if you run into some old
forgotten binaries, you can guess what version of uClibc they were meant
for.  But that can be dealt with in other ways, such as the ABI tag note
that glibc uses.


Well, ABI tag would be useful to double check that the build system
produced valid dependencies.

But changing soname in controlled manner should suffice.

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


[patch] nptl: remove unneeded libc-lock.h include

2010-04-20 Thread Timo Teräs

I semi-accidentally added include for libc-lock.h because the intention
was to use locking macroes from there. However, we ended up using using
the weak alias stuff. This is additionally good since now this can result
in compile errors like:

In file included from /toolchain/include/bits/uClibc_mutex.h:16,
from /toolchain/include/bits/uClibc_stdio.h:107,
from /toolchain/include/stdio.h:72,
from 
/work/freetype-2.3.11/include/freetype/config/ftstdlib.h:100,
from ./builds/unix/ftconfig.h:43,
from builds/unix/ftsystem.c:21:
/toolchain/include/bits/libc-lock.h:309: error: expected '=', ',',
';', 'asm' or '__attribute__' before 'void'

Remove the unneeded include causing breakage.

Reported-by: Kevin Day thekevin...@gmail.com
Signed-off-by: Timo Teräs timo.te...@iki.fi

diff --git a/libc/sysdeps/linux/common/bits/uClibc_mutex.h b/libc/sysdeps/linux
/common/bits/uClibc_mutex.h
index 02bcc72..6d004bb 100644
--- a/libc/sysdeps/linux/common/bits/uClibc_mutex.h
+++ b/libc/sysdeps/linux/common/bits/uClibc_mutex.h
@@ -13,7 +13,6 @@
#ifdef __UCLIBC_HAS_THREADS__

#include pthread.h
-#include bits/libc-lock.h
#include bits/uClibc_pthread.h

#define __uclibc_maybe_call(FUNC, ARGS) \
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: [patch] nptl: remove unneeded libc-lock.h include

2010-04-20 Thread Timo Teräs

Carmelo AMOROSO wrote:

On 4/20/2010 10:59 AM, Timo Teräs wrote:

Remove the unneeded include causing breakage.

-#include bits/libc-lock.h


I guess this is required for STDIO_FUTEXES, or am I wrong ?


Not needed. If STDIO_FUTEXES is defined, the file includes
later on bits/stdio-lock.h which ends up including the
libc-lock.h.
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: [patch] nptl: remove unneeded libc-lock.h include

2010-04-20 Thread Timo Teräs

Laurent Bercot wrote:

-#include bits/libc-lock.h

I guess this is required for STDIO_FUTEXES, or am I wrong ?

Not needed. If STDIO_FUTEXES is defined, the file includes
later on bits/stdio-lock.h which ends up including the
libc-lock.h.


ok, that's fine.


 Not wanting to interfere, but shouldn't including an unneeded
.h file be totally harmless? Shouldn't .h files be independent,
self-contained entities that declare certain symbol and macros
and don't break, just declare too much, if you include more than
is necessary?

 Or should this only be guaranteed only for public .h files
designed to be used by applications, while internal libc headers
can do some black voodoo?
 Sounds kinda brittle and hard to maintain if it's the case.


Yes, that's what I was assuming too. But it looks like libc-lock.h
is taken from glibc, and never really ported to uclibc properly.
In matter of fact, many sysdeps headers are like that. Some are
even in uclibc, but never used.

Some should clean up the headers. But it's slightly complicated.
Especially if you want some easy way to sync with glibc. This
patch just reverts the immediate damage I introduced. But yes,
someone should fix up the headers properly.

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: uClibc_mutex.h and libc-lock.h

2010-04-18 Thread Timo Teräs

Kevin Day wrote:

Apparently with freetype, including #include bits/libc-lock.h causes
compile time errors.
The error has something to do with line 309 of bits/libc-lock.h where
the function __libc_cleanup_routine gets defined.
I simply commented out #include bits/libc-lock.h from
uClibc_mutex.h and freetype compiled properly.

I had related problems with compiling gettext as well but was able to
work around that.

The commit is: 
http://git.uclibc.org/uClibc/commit/?h=nptlid=0eadd98d30c51d26fde4062e6b8c48f3c9b5148d

The error was:

In file included from /toolchain/include/bits/uClibc_mutex.h:16,
 from /toolchain/include/bits/uClibc_stdio.h:107,
 from /toolchain/include/stdio.h:72,
 from
/work/freetype-2.3.11/include/freetype/config/ftstdlib.h:100,
 from ./builds/unix/ftconfig.h:43,
 from builds/unix/ftsystem.c:21:
/toolchain/include/bits/libc-lock.h:309: error: expected '=', ',',
';', 'asm' or '__attribute__' before 'void'


Hmmh. Seems like I added that semi-incidentally. I was thinking of using
the glibc used libc locking macroes from libc-lock.h, but ended up using
the weak definitions. I think the whole uClibc_mutex.h should not be included
(or ifdeffed out) if we are not building libc. I guess the lock definition
defines are needed in public, headers; but at least the function macroes
should not be visible to applications.

Just removing the include should be ok though. But I suspect you might
get similar errors if you have the __USE_STDIO_FUTEXES__ defined, which
you probably should have enabled if you are using nptl.

Seems like we need to sprinkle some #ifdef _LIBC's.

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: various nptl patches

2010-04-17 Thread Timo Teräs

Joakim Tjernlund wrote:

Austin Foxley wrote:

On 04/16/2010 07:37 AM, Timo Teräs wrote:
We'll need to patch all the other arch's ldso as well to handle
protected symbols, but I'll apply this for now. If I'm not mistaken,
other archs will be no worse off than they are now in this situation.
Right?

Right. It makes things slightly better for other archs too, but
in practice it won't work until they support protected symbols too.


Finally looked at the ldso patch and I am not entirely happy with it.
I think the general structure should be different to make it easier
to follow the code and port it to other archs. I can probably
take a stab at it during the weekend but I have no env. to test in
so I will have to do it blindly.


Ok. I'm not too familiar with the ldso internals and structure,
so that was just the immediate fix I came up with.

I can test whatever you come up with on x86.

Thanks!
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: various nptl patches

2010-04-17 Thread Timo Teräs

Joakim Tjernlund wrote:

Finally looked at the ldso patch and I am not entirely happy with it.
I think the general structure should be different to make it easier
to follow the code and port it to other archs. I can probably
take a stab at it during the weekend but I have no env. to test in
so I will have to do it blindly.


So this is what I came up with. I do wonder if not linux_resolver
need PROTECTED support too? Have you tested with LAZY relocation too?


Have not tested lazy yet.


--- a/ldso/ldso/i386/elfinterp.c
+++ b/ldso/ldso/i386/elfinterp.c
@@ -175,11 +175,16 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf 
*scope,
symbol_addr = 0;
symname = strtab + symtab[symtab_index].st_name;

-   if (symtab_index 
-   (ELF32_ST_VISIBILITY(symtab[symtab_index].st_other)
-!= STV_PROTECTED)) {
-   symbol_addr = (unsigned long)_dl_find_hash(symname, scope, tpnt,
-  
elf_machine_type_class(reloc_type), tls_tpnt);
+   if (symtab_index) {
+   if (ELF32_ST_VISIBILITY(symtab[symtab_index].st_other)
+   != STV_PROTECTED)
+   symbol_addr = (unsigned long)_dl_find_hash(symname, scope,
+  tpnt,
+  
elf_machine_type_class(reloc_type),
+  tls_tpnt);
+   else
+   symbol_addr = DL_FIND_HASH_VALUE(tpnt, 
elf_machine_type_class(reloc_type),
+symtab[symtab_index]);

/*
 * We want to allow undefined references to weak symbols - this
@@ -190,11 +195,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf 
*scope,
 
ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK))
return 1;
} else {
-   if (symtab_index)
-   symbol_addr = DL_FIND_HASH_VALUE(tpnt, 
elf_machine_type_class(reloc_type),
-symtab[symtab_index]);
-   else
-   symbol_addr = symtab[symtab_index].st_value;
+   symbol_addr = symtab[symtab_index].st_value;
tls_tpnt = tpnt;
}


This looks functionally equivalent. And yes, looks like this is more consistent
approach.

Related, I noticed that _dl_lookup_hash that uses DL_FIND_HASH_VALUE does 
actually
first a check for TLS symbols: if ELF_ST_TYPE(sym-st_info) == STT_TLS the
DL_FIND_HASH_VALUE is never called. I would suspect that protected TLS symbols
are broken currently.

Maybe all this should be split into some new function?


diff --git a/ldso/ldso/i386/elfinterp.c b/ldso/ldso/i386/elfinterp.c
index 7e05c14..b04febc 100644
--- a/ldso/ldso/i386/elfinterp.c
+++ b/ldso/ldso/i386/elfinterp.c
@@ -194,11 +194,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf 
*scope,
if (unlikely(!symbol_addr  
(ELF_ST_TYPE(symtab[symtab_index].st_info) != STT_TLS)
 
ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK))
return 1;
-   } else {
-   symbol_addr = symtab[symtab_index].st_value;
-   tls_tpnt = tpnt;
}
-


This part was added as part of support for TLS symbols. Other parts of dlso
doing the same thing have comment such as:
   /* Relocs against STN_UNDEF are usually treated as using a
  symbol value of zero, and using the module containing the
  reloc itself.  */

Austin, since you did 534661b9 adding this, could you explain why this is
needed?

Looking also */elfinterp.c, there seems to be a lot of common code. I wonder
if these could be merged somehow.
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: various nptl patches

2010-04-17 Thread Timo Teräs

Timo Teräs wrote:

The whole __GI_ aliasing thingy on libc side is a bit weird still.
I wonder if we could remove all that and just use the proper
visibility attributes. But I guess that's another story.

Oh well. At least nptl on x86 is starting to get to usable state
now. There will be still problems application without libpthread
goes and dlopen()'s a library loading libpthread. But that's
easily fixable by just linking the main app to libpthread.


I was thinking about how glibc gets away with this. Apparently
libc-lock.h does some deep voodoo on what kind of locking primitives
it chooses for each library.

It looks like libc and libpthread end up always using the low level
lock stuff directly lll_*. And for the remaining libpthread entries
the libc ends up calling libpthread always via the ptf (the pthread
function pointers struct). Thus libc should not be using the weak
symbol magic at all. This seems to be the only way to make libc
call the actual libpthread functions if it's dlopen()'ed later.

Also, it would appear that libpthread needs additional fixing to
initialize itself in case it's dlopen loaded. I also remember there's
some ldso flags that make libpthread permanent so it won't get
unloaded when the last library requiring it gets dlclosed.

So I guess we need another stab on fixing libc-lock for uclibc.
I might take a look at this next week if there's nothing else
strange in the current tree.

The previous patches are still needed though. Otherwise the
main application can get wrong symbols depending on various things.
The protected patches especially are important as some of the
forwarding stubs have same name as the pthread implementation it
forwards to (the actual name used in ptf struct initialization).

This whole libc-libpthread interdependency and making libc run
without libpthread seems pretty complicated, and misunderstood
previously. Especially since the normal symbol vs. weak symbol
semantics have changed (do note: it seems that strong symbol as
concept seems to have been deprecated; apparently the consensus is
that even if it sounds good idea, it's bound to cause more confusion
and mistakes and non-consistent behaviour than solving problems).

I guess we need a document, or at least some comments on how all
this is supposed to be working.
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: nptl: mark symbols with libc forwarder hidden

2010-04-16 Thread Timo Teräs

Austin Foxley wrote:

On 04/14/2010 10:01 AM, Timo Teräs wrote:

Add attribute_hidden to all symbols having libc forwarder. This prevents
recursive self calls which would happen if libc is before libpthread in
linking order: the forwarder functions would call itself via the function
table, since the libpthread symbols would get overwritten with libc ones.
This has not been a problem in glibc since there these symbols are marked
hidden with linker version-script. Since we don't use one, we need to mark
these explicitly.

Signed-off-by: Timo Teräs timo.te...@iki.fi


This looks like what we want. I'll apply this.


Hum. Actually looks like this is not right either. It appears that there's
several different ways how the pthreads mutexes are called from libc.

Previously uclibc had these:
1. internal libc locking:
seems to resolve to use the internal __pthread_mutex_*
weaks defined for__pthread_* in libc/misc/pthread/weaks.c to give
dummy functions if linked statically or without libpthread
2. pthread_* forwarding for applications
so single/multithread libs can link to basic pthreads stuff without
libpthread; it uses the pthread_functions forwarding stubs in thread
implementation specific forwarders.c
3. stdio locking
that uses futexes (from nptl headers), or revers to #1 style locking

However, (1) will never work properly. The reason is that weak vs. strong
aliases are not resolved dynamically. If ld.so picks the weak definition from
libc first (e.g. -lc before -lpthread), you end up using the libc version.
(Only glibc ever had dynamic weak resolution, meaning strong alias from later
library would override weak alias; but this behaviour was reverted as it
was considered bad. It's still doable by setting LD_DYNAMIC_WEAK=1).

Now, glibc seems to do (1) as follows:
1. define *protected* versions of __pthread_* from libpthread, so libpthread
   will use them always, but also exports (at least subset of them)
2. libc has *weak definition in headers* of __pthread_* causing the
   references to be weak, and linking succeed even if __pthread_* symbols
   are not present
3. it uses __libc_maybe_call to first check if the function symbol is null,
   and if not then calls it

I think we should the same as glibc, by converting uClibc_mutex.h to use
libc-lock.h from threading implementation.

Sounds reasonable?
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: nptl: mark symbols with libc forwarder hidden

2010-04-16 Thread Timo Teräs

Joakim Tjernlund wrote:

Austin Foxley wrote:

On 04/14/2010 10:01 AM, Timo Teräs wrote:

Hum. Actually looks like this is not right either. It appears that there's
several different ways how the pthreads mutexes are called from libc.

Previously uclibc had these:
 1. internal libc locking:
   seems to resolve to use the internal __pthread_mutex_*
   weaks defined for__pthread_* in libc/misc/pthread/weaks.c to give
   dummy functions if linked statically or without libpthread
 2. pthread_* forwarding for applications
   so single/multithread libs can link to basic pthreads stuff without
   libpthread; it uses the pthread_functions forwarding stubs in thread
   implementation specific forwarders.c
 3. stdio locking
   that uses futexes (from nptl headers), or revers to #1 style locking

However, (1) will never work properly. The reason is that weak vs. strong
aliases are not resolved dynamically. If ld.so picks the weak definition from
libc first (e.g. -lc before -lpthread), you end up using the libc version.


Is this a big problem? To me this looks like an error in the app and the
link order should be fixed there.


It just isn't possible always easily. This also hits the case if libpthread
gets pulled in by dependency library and not by the main app.


(Only glibc ever had dynamic weak resolution, meaning strong alias from later
 library would override weak alias; but this behaviour was reverted as it
 was considered bad. It's still doable by setting LD_DYNAMIC_WEAK=1).

Now, glibc seems to do (1) as follows:
 1. define *protected* versions of __pthread_* from libpthread, so libpthread
will use them always, but also exports (at least subset of them)
 2. libc has *weak definition in headers* of __pthread_* causing the
references to be weak, and linking succeed even if __pthread_* symbols
are not present
 3. it uses __libc_maybe_call to first check if the function symbol is null,
and if not then calls it

I think we should the same as glibc, by converting uClibc_mutex.h to use
libc-lock.h from threading implementation.


I don't think ld.so supports PROTECTED syms yet(unless someone added these 
lately)
Shouldn't be too hard to add I guess.


Isn't protected: define symbol as global, but generate local
non-overridable relocations. Thus it's just code generation change
compared to hidden visibility. Not entirely sure about this, though.
But I think it should just work.

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: nptl: mark symbols with libc forwarder hidden

2010-04-16 Thread Timo Teräs

Joakim Tjernlund wrote:

Timo Teräs timo.te...@gmail.com wrote on 2010/04/16 10:00:59:

Joakim Tjernlund wrote:

Austin Foxley wrote:

On 04/14/2010 10:01 AM, Timo Teräs wrote:

Hum. Actually looks like this is not right either. It appears that there's
several different ways how the pthreads mutexes are called from libc.

Previously uclibc had these:
 1. internal libc locking:
   seems to resolve to use the internal __pthread_mutex_*
   weaks defined for__pthread_* in libc/misc/pthread/weaks.c to give
   dummy functions if linked statically or without libpthread
 2. pthread_* forwarding for applications
   so single/multithread libs can link to basic pthreads stuff without
   libpthread; it uses the pthread_functions forwarding stubs in thread
   implementation specific forwarders.c
 3. stdio locking
   that uses futexes (from nptl headers), or revers to #1 style locking

However, (1) will never work properly. The reason is that weak vs. strong
aliases are not resolved dynamically. If ld.so picks the weak definition from
libc first (e.g. -lc before -lpthread), you end up using the libc version.

Is this a big problem? To me this looks like an error in the app and the
link order should be fixed there.

It just isn't possible always easily.

That can't be a big deal, feels like a bug in the app that should/could be
fixed.


This also hits the case if libpthread
gets pulled in by dependency library and not by the main app.

But this is a bigger concern. Is this supposed to work or is it an glibc
extension?


Both of the cases work on glibc, because it sets the symbol visibility
correctly, and also uses the weak symbols in correct way.

We would not even need to whole 'forwarding' stuff at all if could trust
that libpthread was always linked before libc. The sole purpose of forwarders
is to have strongs versions of these symbols in libpthread, and weak ones
in libc. It may have been doable before via strongs/weak alias thingy. But
it's not doable anymore since LD_DYNAMIC_WEAK is off by default.

The other part is how the internatl __pthread_* is handled. And glibc
does this right by using weak references from libc, and defining them
only in libpthread. This way libc gets null pointers if libpthread is
not pulled in. And this is what we should do too.


(Only glibc ever had dynamic weak resolution, meaning strong alias from later
 library would override weak alias; but this behaviour was reverted as it
 was considered bad. It's still doable by setting LD_DYNAMIC_WEAK=1).

Now, glibc seems to do (1) as follows:
 1. define *protected* versions of __pthread_* from libpthread, so libpthread
will use them always, but also exports (at least subset of them)
 2. libc has *weak definition in headers* of __pthread_* causing the
references to be weak, and linking succeed even if __pthread_* symbols
are not present
 3. it uses __libc_maybe_call to first check if the function symbol is null,
and if not then calls it

I think we should the same as glibc, by converting uClibc_mutex.h to use
libc-lock.h from threading implementation.

I don't think ld.so supports PROTECTED syms yet(unless someone added these 
lately)
Shouldn't be too hard to add I guess.

Isn't protected: define symbol as global, but generate local
non-overridable relocations. Thus it's just code generation change
compared to hidden visibility. Not entirely sure about this, though.
But I think it should just work.


Ah, like LD option -Bsymbolic does? That is library wide so one has to find
some __attribute__ that operates on a single symbol.


Yes. Exactly that. It's __attribute__(( visibility(protected) )).
Or .protected for asm. I'm doing a patch on this right now.
http://www.ohse.de/uwe/articles/gcc-attributes.html#func-visibility
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: nptl: mark symbols with libc forwarder hidden

2010-04-16 Thread Timo Teräs

Joakim Tjernlund wrote:

Yes. Exactly that. It's __attribute__(( visibility(protected) )).
Or .protected for asm. I'm doing a patch on this right now.
http://www.ohse.de/uwe/articles/gcc-attributes.html#func-visibility

But this is PROTECTED and you might need to impl. STB_PROTECTED in ldso

That should be STV_PROTECTED


to support it. I once looked at that when I was hacking ldso in uClibc
some years ago but I don't remember the details any more.


Ah, you're right. It does need ld.so support. I'll try to figure out
if it's easy to implement, or if we get away with some linker flags.
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: nptl: mark symbols with libc forwarder hidden

2010-04-16 Thread Timo Teräs

Timo Teräs wrote:

Joakim Tjernlund wrote:

Yes. Exactly that. It's __attribute__(( visibility(protected) )).
Or .protected for asm. I'm doing a patch on this right now.
http://www.ohse.de/uwe/articles/gcc-attributes.html#func-visibility

But this is PROTECTED and you might need to impl. STB_PROTECTED in ldso

That should be STV_PROTECTED


to support it. I once looked at that when I was hacking ldso in uClibc
some years ago but I don't remember the details any more.


Ah, you're right. It does need ld.so support. I'll try to figure out
if it's easy to implement, or if we get away with some linker flags.


Huh. Actually, I think we can keep attribute hidden, and just make
the uclibc use internally the public pthread_* function that are
being forwarded anyway. Duh. I'll try this.
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: nptl: mark symbols with libc forwarder hidden

2010-04-16 Thread Timo Teräs

Joakim Tjernlund wrote:

Timo Teräs timo.te...@gmail.com wrote on 2010/04/16 11:39:00:

Joakim Tjernlund wrote:

Yes. Exactly that. It's __attribute__(( visibility(protected) )).
Or .protected for asm. I'm doing a patch on this right now.
http://www.ohse.de/uwe/articles/gcc-attributes.html#func-visibility

But this is PROTECTED and you might need to impl. STB_PROTECTED in ldso

That should be STV_PROTECTED


to support it. I once looked at that when I was hacking ldso in uClibc
some years ago but I don't remember the details any more.

Ah, you're right. It does need ld.so support. I'll try to figure out
if it's easy to implement, or if we get away with some linker flags.



This MIGHT do it(completely untested):

diff --git a/ldso/ldso/i386/elfinterp.c b/ldso/ldso/i386/elfinterp.c
index a01c1d0..7f1b408 100644
--- a/ldso/ldso/i386/elfinterp.c
+++ b/ldso/ldso/i386/elfinterp.c
@@ -175,7 +175,9 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf 
*scope,
symbol_addr = 0;
symname = strtab + symtab[symtab_index].st_name;

-   if (symtab_index) {
+   if (symtab_index 
+   (ELF32_ST_VISIBILITY(symtab[symtab_index].st_other)
+!= STV_PROTECTED)) {
symbol_addr = (unsigned long)_dl_find_hash(symname, scope, tpnt,
   
elf_machine_type_class(reloc_type), tls_tpnt);




Does not seem to work as expected. When using this, and getting the
case when pthread_self is being forwarded via libc (so we end up using
relocation of protected __pthread_self in nptl).

where
#0  0x964d in ?? ()
#1  0xb785302f in pthread_self () at libpthread/nptl/forward.c:137
#2  0xb77b66be in plugin_main () from ./plugin.so
#3  0xb7876672 in main () from /home/ncopa/pthread/test

But the symbol should is actually located at:

(gdb) p __pthread_self
$3 = {pthread_t (void)} 0xb77c264d __pthread_self

Smells like we did not add the base address.

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: nptl: mark symbols with libc forwarder hidden

2010-04-16 Thread Timo Teräs

Timo Teräs wrote:

Joakim Tjernlund wrote:

Timo Teräs timo.te...@gmail.com wrote on 2010/04/16 11:39:00:

Joakim Tjernlund wrote:

Yes. Exactly that. It's __attribute__(( visibility(protected) )).
Or .protected for asm. I'm doing a patch on this right now.
http://www.ohse.de/uwe/articles/gcc-attributes.html#func-visibility
But this is PROTECTED and you might need to impl. STB_PROTECTED in 
ldso

That should be STV_PROTECTED


to support it. I once looked at that when I was hacking ldso in uClibc
some years ago but I don't remember the details any more.

Ah, you're right. It does need ld.so support. I'll try to figure out
if it's easy to implement, or if we get away with some linker flags.



This MIGHT do it(completely untested):

diff --git a/ldso/ldso/i386/elfinterp.c b/ldso/ldso/i386/elfinterp.c
index a01c1d0..7f1b408 100644
--- a/ldso/ldso/i386/elfinterp.c
+++ b/ldso/ldso/i386/elfinterp.c
@@ -175,7 +175,9 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct 
dyn_elf *scope,

 symbol_addr = 0;
 symname = strtab + symtab[symtab_index].st_name;

-if (symtab_index) {
+if (symtab_index 
+(ELF32_ST_VISIBILITY(symtab[symtab_index].st_other)
+ != STV_PROTECTED)) {
 symbol_addr = (unsigned long)_dl_find_hash(symname, scope, tpnt,
elf_machine_type_class(reloc_type), 
tls_tpnt);





Does not seem to work as expected. When using this, and getting the
case when pthread_self is being forwarded via libc (so we end up using
relocation of protected __pthread_self in nptl).

where
#0  0x964d in ?? ()
#1  0xb785302f in pthread_self () at libpthread/nptl/forward.c:137
#2  0xb77b66be in plugin_main () from ./plugin.so
#3  0xb7876672 in main () from /home/ncopa/pthread/test

But the symbol should is actually located at:

(gdb) p __pthread_self
$3 = {pthread_t (void)} 0xb77c264d __pthread_self

Smells like we did not add the base address.


We are missing a:
DL_FIND_HASH_VALUE(tpnt, type_class, sym);
that turns into:
DL_RELOC_ADDR ((SYM)-st_value, (TPNT)-loadaddr)

# define DL_RELOC_ADDR(LOADADDR, ADDR) \
   ((LOADADDR) + (ADDR))

That is done implicitly by the _dl_find_hash.

I wonder if we can just simply add this to the else
block, or if need to make the protected symbol case
separate.
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: various nptl patches

2010-04-16 Thread Timo Teräs

Austin Foxley wrote:

On 04/16/2010 07:37 AM, Timo Teräs wrote:

Ok, second try on getting the libc - libpthread interactions right.


This includes the Joakim's patch for protected symbols, with a
little fix from me.


I thought the hidden symbol thing would work, because I thought when
you turned on stdio-futexes, everywhere used futexes. I didn't
realize other places were using __pthread* symbols directly...


Yeah, that was my impression too. But it turns out to work
differently :/


We'll need to patch all the other arch's ldso as well to handle
protected symbols, but I'll apply this for now. If I'm not mistaken,
other archs will be no worse off than they are now in this situation.
Right?


Right. It makes things slightly better for other archs too, but
in practice it won't work until they support protected symbols too.


These patches finally cleaned up the _pthread_cleanup* mess for me
though. Thanks!


Yes, it's a bit better now.

The whole __GI_ aliasing thingy on libc side is a bit weird still.
I wonder if we could remove all that and just use the proper
visibility attributes. But I guess that's another story.

Oh well. At least nptl on x86 is starting to get to usable state
now. There will be still problems application without libpthread
goes and dlopen()'s a library loading libpthread. But that's
easily fixable by just linking the main app to libpthread.

Will continue testing next week.
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


nptl: fix libc sigtimedwait

2010-04-15 Thread Timo Teräs

It seems that 57e8823548ad6e65d33b2153edeb18fb0edc20e6 removed completely
sigtimedwait symbol from libc which is wrong. I hope there is not too
many other things like this.

Apparently the libc_hidden_* macros actually make previously hidden
symbols visible globally (creates alias from __GI_* to *). This is
probably ancient confusion from times when gcc did not support
visibility attribute and hiding symbols was done using hacks like
this.

This also adds attribute_hidden to the internal __sigtimedwait for
nptl case.

Signed-off-by: Timo Teräs timo.te...@iki.fi

diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c 
b/libc/sysdeps/linux/common/__rt_sigtimedwait.c
index 554c6b9..79b94ad 100644
--- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c
+++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c
@@ -60,8 +60,8 @@ static int do_sigtimedwait(const sigset_t *set, siginfo_t 
*info,
}

/* Return any pending signal or wait for one for the given time.  */
-int __sigtimedwait(const sigset_t *set, siginfo_t *info,
-  const struct timespec *timeout)
+int attribute_hidden __sigtimedwait(const sigset_t *set, siginfo_t *info,
+   const struct timespec *timeout)
{
if(SINGLE_THREAD_P)
return do_sigtimedwait(set, info, timeout);
@@ -102,3 +102,4 @@ int attribute_hidden __sigtimedwait(const sigset_t * set, 
siginfo_t * info,
}
#endif
weak_alias(__sigtimedwait,sigtimedwait)
+libc_hidden_weak(sigtimedwait)
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: nptl: fix libc nptl forwarding stubs

2010-04-14 Thread Timo Teräs

Timo Teräs wrote:
The attribute_hidden is added to all forward stubs, to avoid self 
recursion. If libc and libpthread linking order is reversed, the libc

stub would end up being used in the libpthread side struct
pthread_functions. Apparently glibc side is doing linker magic to
avoid this. I don't think it really makes sense for libc to export
pthreads symbols, so I'm using attribute_hidden there. Alternatively
we could use protected visibility on libpthread side to make sure
it's using it's own symbols.
diff --git a/libpthread/nptl/forward.c b/libpthread/nptl/forward.c
index 8f528d0..e9a2a0b 100644
--- a/libpthread/nptl/forward.c
+++ b/libpthread/nptl/forward.c
@@ -32,6 +32,7 @@ int __libc_pthread_functions_init attribute_hidden;


#define FORWARD2(name, rettype, decl, params, defaction) \
+rettype name decl attribute_hidden;  \
rettype  \
name decl  \
{  \


We can't really do this part. Turns out that some wacko libraries
such as libX11 test if libc has pthread_self and do funny stuff it
it doesn't.

The really proper thing is to go libpthread symbol by symbol and
hide the non-exported ones. Glibc does this with linker version-script.
Not sure if we want to do the same, or sprinkle hidden/protected
definitions around the place.

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


nptl: mark symbols with libc forwarder hidden

2010-04-14 Thread Timo Teräs

Add attribute_hidden to all symbols having libc forwarder. This prevents
recursive self calls which would happen if libc is before libpthread in
linking order: the forwarder functions would call itself via the function
table, since the libpthread symbols would get overwritten with libc ones.
This has not been a problem in glibc since there these symbols are marked
hidden with linker version-script. Since we don't use one, we need to mark
these explicitly.

Signed-off-by: Timo Teräs timo.te...@iki.fi

diff --git a/libpthread/nptl/cleanup_defer_compat.c 
b/libpthread/nptl/cleanup_defer_compat.c
index 8fd9b54..cc68893 100644
--- a/libpthread/nptl/cleanup_defer_compat.c
+++ b/libpthread/nptl/cleanup_defer_compat.c
@@ -21,6 +21,7 @@


void
+attribute_hidden
_pthread_cleanup_push_defer (
 struct _pthread_cleanup_buffer *buffer,
 void (*routine) (void *),
@@ -60,6 +61,7 @@ strong_alias (_pthread_cleanup_push_defer, 
__pthread_cleanup_push_defer)


void
+attribute_hidden
_pthread_cleanup_pop_restore (
 struct _pthread_cleanup_buffer *buffer,
 int execute)
diff --git a/libpthread/nptl/init.c b/libpthread/nptl/init.c
index b651a3e..87c08fa 100644
--- a/libpthread/nptl/init.c
+++ b/libpthread/nptl/init.c
@@ -111,8 +111,8 @@ static const struct pthread_functions pthread_functions =
.ptr___pthread_key_create = __pthread_key_create_internal,
.ptr___pthread_getspecific = __pthread_getspecific_internal,
.ptr___pthread_setspecific = __pthread_setspecific_internal,
-.ptr__pthread_cleanup_push_defer = __pthread_cleanup_push_defer,
-.ptr__pthread_cleanup_pop_restore = __pthread_cleanup_pop_restore,
+.ptr__pthread_cleanup_push_defer = _pthread_cleanup_push_defer,
+.ptr__pthread_cleanup_pop_restore = _pthread_cleanup_pop_restore,
.ptr_nthreads = __nptl_nthreads,
.ptr___pthread_unwind = __pthread_unwind,
.ptr__nptl_deallocate_tsd = __nptl_deallocate_tsd,
diff --git a/libpthread/nptl/pt-cleanup.c b/libpthread/nptl/pt-cleanup.c
index f72ea26..619eb8b 100644
--- a/libpthread/nptl/pt-cleanup.c
+++ b/libpthread/nptl/pt-cleanup.c
@@ -23,6 +23,7 @@
#include jmpbuf-unwind.h

void
+attribute_hidden
__pthread_cleanup_upto (__jmp_buf target, char *targetframe)
{
  struct pthread *self = THREAD_SELF;
diff --git a/libpthread/nptl/pthread_attr_destroy.c 
b/libpthread/nptl/pthread_attr_destroy.c
index b8e6a37..16b7164 100644
--- a/libpthread/nptl/pthread_attr_destroy.c
+++ b/libpthread/nptl/pthread_attr_destroy.c
@@ -24,6 +24,7 @@
#include pthreadP.h

int
+attribute_hidden
__pthread_attr_destroy (
 pthread_attr_t *attr)
{
diff --git a/libpthread/nptl/pthread_attr_getdetachstate.c 
b/libpthread/nptl/pthread_attr_getdetachstate.c
index 5f549ba..14b91df 100644
--- a/libpthread/nptl/pthread_attr_getdetachstate.c
+++ b/libpthread/nptl/pthread_attr_getdetachstate.c
@@ -22,6 +22,7 @@


int
+attribute_hidden
__pthread_attr_getdetachstate (
 const pthread_attr_t *attr,
 int *detachstate)
diff --git a/libpthread/nptl/pthread_attr_getinheritsched.c 
b/libpthread/nptl/pthread_attr_getinheritsched.c
index 3ff3040..8ab8657 100644
--- a/libpthread/nptl/pthread_attr_getinheritsched.c
+++ b/libpthread/nptl/pthread_attr_getinheritsched.c
@@ -22,6 +22,7 @@


int
+attribute_hidden
__pthread_attr_getinheritsched (
 const pthread_attr_t *attr,
 int *inherit)
diff --git a/libpthread/nptl/pthread_attr_getschedparam.c 
b/libpthread/nptl/pthread_attr_getschedparam.c
index 82b2371..ee1d513 100644
--- a/libpthread/nptl/pthread_attr_getschedparam.c
+++ b/libpthread/nptl/pthread_attr_getschedparam.c
@@ -23,6 +23,7 @@


int
+attribute_hidden
__pthread_attr_getschedparam (
const pthread_attr_t *attr,
struct sched_param *param)
diff --git a/libpthread/nptl/pthread_attr_getschedpolicy.c 
b/libpthread/nptl/pthread_attr_getschedpolicy.c
index 7b8f1de..54666da 100644
--- a/libpthread/nptl/pthread_attr_getschedpolicy.c
+++ b/libpthread/nptl/pthread_attr_getschedpolicy.c
@@ -22,6 +22,7 @@


int
+attribute_hidden
__pthread_attr_getschedpolicy (
 const pthread_attr_t *attr,
 int *policy)
diff --git a/libpthread/nptl/pthread_attr_getscope.c 
b/libpthread/nptl/pthread_attr_getscope.c
index 9b05ffa..ccbebfa 100644
--- a/libpthread/nptl/pthread_attr_getscope.c
+++ b/libpthread/nptl/pthread_attr_getscope.c
@@ -22,6 +22,7 @@


int
+attribute_hidden
__pthread_attr_getscope (
 const pthread_attr_t *attr,
 int *scope)
diff --git a/libpthread/nptl/pthread_attr_init.c 
b/libpthread/nptl/pthread_attr_init.c
index 65ce4e5..d019514 100644
--- a/libpthread/nptl/pthread_attr_init.c
+++ b/libpthread/nptl/pthread_attr_init.c
@@ -29,6 +29,7 @@ int __attr_list_lock = LLL_LOCK_INITIALIZER;


int
+attribute_hidden
__pthread_attr_init_2_1 (
 pthread_attr_t *attr)
{
diff --git a/libpthread/nptl/pthread_attr_setdetachstate.c 
b/libpthread/nptl/pthread_attr_setdetachstate.c
index b6d9bb5..d72fd83 100644
--- a/libpthread/nptl/pthread_attr_setdetachstate.c
+++ b/libpthread/nptl

linuxthreads.new: initialize stdio locking

2010-04-13 Thread Timo Teräs

uClibc requires the threading library to enable locking for
stdio, or the locking is not done at all.

Signed-off-by: Timo Teräs timo.te...@iki.fi
--
Not compile tested either. Natanael, maybe you could test this too
since you are using linuxthreads.new too.

diff --git a/libpthread/linuxthreads/pthread.c 
b/libpthread/linuxthreads/pthread.c
index 6ae9a10..614cad1 100644
--- a/libpthread/linuxthreads/pthread.c
+++ b/libpthread/linuxthreads/pthread.c
@@ -613,6 +613,17 @@ static void pthread_initialize(void)
#ifdef USE_TLS
  GL(dl_init_static_tls) = __pthread_init_static_tls;
#endif
+
+  /* uClibc-specific stdio initialization for threads. */
+  {
+FILE *fp;
+_stdio_user_locking = 0;   /* 2 if threading not initialized */
+for (fp = _stdio_openlist; fp != NULL; fp = fp-__nextopen) {
+  if (fp-__user_locking != 1) {
+fp-__user_locking = 0;
+  }
+}
+  }
}

void __pthread_initialize(void)
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: problems with gnu make and stdout with uclibc nptl

2010-04-12 Thread Timo Teräs

Peter Kjellerstedt wrote:
Unless it has changed in the last years, there are no expressed 
guarantees regarding API and ABI stability for the 0.x.y releases of 
uClibc. AFAIK the stable API/ABI is intended for the 1.0.0 release. 
And with the upcoming integration of the NPTL support, I do not see 
this as the right time to go to 1.0.0 and lock down the API/ABI... 


Could the uclibc project then start using appropriate soname, so
we can install multiple versions of the library if needed (e.g.
when doing package based upgrade).

# objdump -p /lib/libuClibc-0.9.30.1.so  |grep SONAME
 SONAME   libc.so.0

Would indicate that all 0.x are compatible. Basically, soname
should be 0.x.y if all 0.x.y.z are supposed to be ABI compatible.

Currently it seems that link.so and linkm.so macros explicitly
set soname according to $(2).

define link.so
   $(Q)$(INSTALL) -d $(dir $@)
   $(Q)$(RM) $@ $...@.$(2) $(dir $@)$(1)
   @$(disp_ld)
   $(Q)$(CC) $(LDFLAGS-$(notdir $@)) -Wl,-soname=$(notdir $@).$(2) \
   $(NOSTDLIB_CFLAGS) -o $(dir $@)$(1) $(START_FILE-$(notdir $@)) \
   -Wl,--whole-archive $(firstword $^) -Wl,--no-whole-archive \
   $(LIBS-$(notdir $@)) $(LIBGCC) $(END_FILE-$(notdir $@))
   $(Q)$(LN) -sf $(1) $...@.$(2)
   $(Q)$(LN) -sf $(1) $@
endef

Those get called like:

./libc/Makefile.in: $(call linkm.so,$(libc_FULL_NAME),$(MAJOR_VERSION))

And that's defined like:

Rules.mak:MAJOR_VERSION := 0

Resulting in above mentioned soname, which is completely broken regarding
to how shared object ABI compatibility should be handled.

Please fix soname.

Thanks,
 Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: [nptl] more stdout issues

2010-04-12 Thread Timo Teräs

Austin Foxley wrote:

On 04/12/2010 12:21 PM, Natanael Copa wrote:

Smells like stdio is not threads safe?


Interesting. I supposed there could be an issue with the libc internal futex
code that replaces the old use of pthread mutexes directly. We could verify this
with a bit of work by getting the old style mutexes to compile correctly with
nptl enabled. If that fixes it, then it narrows down somewhat...

The other thing is that this might just be x86, as there haven't been reports on
other archs of these problems. Although maybe nobody else has tried it on
multi-core?


It looks like no one bothered to implement the uClibc needed stdio
locking initialization. It seems that only linuxthreads.old does this.
So both linuxthreads.new and nptl seem to be broken wrt. stdio locking.

I did not even try compile testing the below, but something like
this should help. Could you test this?

nptl: initialize stdio locking

uClibc requires the threading library to enable locking for
stdio, or the locking is not done at all.

Signed-off-by: Timo Teräs timo.te...@iki.fi

diff --git a/libpthread/nptl/init.c b/libpthread/nptl/init.c
index b651a3e..16f62f6 100644
--- a/libpthread/nptl/init.c
+++ b/libpthread/nptl/init.c
@@ -35,6 +35,7 @@
#include lowlevellock.h
#include bits/kernel-features.h

+#include uClibc_stdio.h

/* Size and alignment of static TLS block.  */
size_t __static_tls_size;
@@ -423,6 +424,17 @@ __pthread_initialize_minimal_internal (void)

  /* Determine whether the machine is SMP or not.  */
  __is_smp = is_smp_system ();
+
+  /* uClibc-specific stdio initialization for threads. */
+  {
+FILE *fp;
+_stdio_user_locking = 0;   /* 2 if threading not initialized */
+for (fp = _stdio_openlist; fp != NULL; fp = fp-__nextopen) {
+  if (fp-__user_locking != 1) {
+fp-__user_locking = 0;
+  }
+}
+  }
}
strong_alias (__pthread_initialize_minimal_internal,
  __pthread_initialize_minimal)
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: uClibc-0.9.31 symbol table oddities

2010-04-09 Thread Timo Teräs

Michael Deutschmann wrote:

On a related note, is there ABI breakage in 0.9.31 aside from dropped
symbols?


Yes, ABI is broken regarding to signal handling.

struct sigaction fields were reordered at 
885f507317b6c8576ba2e298c2249d27ea6f8404.

sigset_t size was also changed in 35ae1599438a15568818bf09b493d7b49039d452.

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: [branch] nptl_merge

2009-10-18 Thread Timo Teräs

Hi,

Austin Foxley wrote:

I've created a branch based on current master that has the entirety of the work
done so far on nptl integrated. I attempted to break up into separate commits,
related kinds of changes. Hopefully this well help in reviewing...

My thought was that people could review each commit and either reply to this
email for discussion, or simply commit fixes for any issues directly to the
nptl_merge branch. I'm going to start fixing up obvious style issues now to
preempt some comments :)

I've tried hard to avoid reverting anybody's work, please let me know where I
missed anything. Remember...I obviously didn't write most of this code...

Let's get this beast merged already!


This is something I've been waiting for a long time! Thanks!

I will definitely try to get the i386 side up and running. uClibc NPTL is one
of the things we listed for Alpine Linux (www.alpinelinux.org) to be in it's
next major release. I already earlier did some work earlier to see how far
away it is and got it working to some degree.

I did very quick test just now, but it did not compile; there was some issues
with stack protector support. But I'm sure I'll work on this with Natanael
Copa in the upcoming weeks.

Are there any known issues or things that still needs implementing?

Though, I guess we'll just go along and see what needs to be done to get the
usual stuff working we run on our boxes.

Thanks,
Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


fstatat is broke

2009-09-06 Thread Timo Teräs

Hi all,

I'm using the *at stuff and noticed that fstatat is broke.
fstatat is a bit different since that syscall is not really
available.

Glibc makes fstatat do fstatat64 syscall and converts the
struct kernel_stat64 to struct stat. I think that is what
was also intended in uclibc case, but someone left the work
halfway. Now it badly uses struct kernel_stat with fstatat64
syscall. We need to use the struct kernel_stat64 and implement
the new conversion case.

- Timo

___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: linuxthreads/signals question

2009-07-07 Thread Timo Teräs

GoatZilla wrote:

I'm using the linuxthreads.old version of the threading code in uClibc, and
I seem to be getting a hang when using semaphores.

What appears to be happening is one thread is reaching __new_sem_wait, but
gets preempted between line 86 and when the actual system call to suspend
actually occurs (line 97).  By that point, it has checked the semaphore and
found that it's not available, and added itself as waiting for the
semaphore.

http://git.uclibc.org/uClibc/tree/libpthread/linuxthreads.old/semaphore.c#n59

The other thread then hits __new_sem_post, discovers another thread is
waiting for the semaphore and sends the signal to it.

The 'wait' thread then wakes up, but hasn't hit the suspend call yet.  It
eventually gets there, but then sleeps indefinitely because I guess the
previous signal, which was apparently an RT signal, was eaten or something.

Is this what's supposed to happen in this circumstance?  What should to
happen to the RT signal that goes to a thread before it's actually reached
its suspend call?  Or is this a bug with uClibc?


The signal is masked out by linuxthreads. It is kept pending until the
suspend() call and the signal is delivered at that time.

Is perhaps your program using the same signals that the linuxthreads uses
to synchronize?

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: nptl branch with i386

2009-06-29 Thread Timo Teräs

Matteo Petracca wrote:

Hello,
I am trying to use the nptl branch with i386 support
added by Timo through the patch:

http://solidboot.com/~fabled/uclibc-nptl-i386.diff

It works and the system compiles, but I am having
some issues in using the lrintf function which gives
segmentation fault.

Thank you very much for any possible help.


Could you provide a simple test program that crashes?
Or a gdb backtrace of your program while it crashes?

Looks like lrintf is just a simple inline function
that executes a specific fpu instructions. The only
way it can be nptl/i386 specific is that the fpu
instruction is mangling some TLS specific variable.
Do you know if it works with nptl branch on some other
architecture?

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: NPTL on x86, anyone?

2009-06-23 Thread Timo Teräs

Cristi Magherusan wrote:

Sorry for reviving this forgotten thread, but I'm really interested
about this topic. 


I have set up a uClibc git branch that aims for proper x86 NPTL support,
that I need for my GSoC project.

Currently it only contains Timo's patches, applied on top of the current
nptl branch, but I'm willing to shape it and make it properly work so
that it finally can be merged back in the main uClibc repo.

Feel free to test it, any contributions/feedback/hints are welcome.

The code is stored at
http://cristi.indefero.net/p/uClibc-cristi/source/changes/nptl/


While fixing the bugs (I sent earlier patches) in linuxthreads.new
I got a better understanding how the libc and libpthreads integration
works. When I get some extra jiffies I could revisit this patch
and fix the blockers that prevent it from inclusion upstream
(mainly the modifications to non-nptl parts).

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


res_query for CNAMEs

2009-06-18 Thread Timo Teräs

Hi,

I had postfix failing for domains with MX-CNAME-A chain. In glibc it works.
I tracked it to be a problem in uclibc res_query. It returns bogus data
for CNAME entries, apparently intentionally, which is wrong.

glibc return CNAME entries even for CNAME queries and most applications rely
on this. So we should do the same in uclibc.

Please apply.

- Timo
--- libc/inet/resolv.c.orig	2009-06-18 09:38:26.0 +0300
+++ libc/inet/resolv.c	2009-06-18 09:38:32.0 +0300
@@ -1337,10 +1337,9 @@ int res_query(const char *dname, int cla
 
 	free(a.dotted);
 
-	if (a.atype == type) { /* CNAME */
-		i = MIN(anslen, i);
-		memcpy(answer, packet, i);
-	}
+	i = MIN(anslen, i);
+	memcpy(answer, packet, i);
+
 	free(packet);
 	return i;
 }
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index 109ae02..3e9f9f4 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -3016,11 +3016,10 @@ int res_query(const char *dname, int class, int type,
 
 	free(a.dotted);
 
-	if (a.atype == type) { /* CNAME */
-		if (i  anslen)
-			i = anslen;
-		memcpy(answer, packet, i);
-	}
+	if (i  anslen)
+		i = anslen;
+	memcpy(answer, packet, i);
+
 	free(packet);
 	return i;
 }
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

linuxthreads.new aliases

2009-06-17 Thread Timo Teräs

Hi,

It looks like the aliases in linuxthreads.new are a bit off.
If the main binary pulls in libc before libpthread, because of
some other dependent .so, you end up using the aliases from
libc and not libpthread.

This causes forward.c definitions to call themselves recursively
for the pthread_mutex_* where forward.c has strong_alias for the
internal variants. Similar loop would occur for _pthread_cleanup_*
since the libc implementation would take preference from the
libpthread one.

I fixed this for me by:
1. renaming the internal _pthread_cleanup_* to __pthread_cleanup_*
  and alias them properly
2. making the pthread_mutex_* aliases hidden. you should really
  have the hidden_strong_alias in some global header and do
  the compiler checking properly.

As a side note, I tried making the forward.c aliases weak, but
that did not fix the problem. Either there is a bug in the linker.
Or when the first dependent .so is linked in and it pulls in the
libc, the symbols that are resolved there are not looked up
from libpthread.so. Might need a bit of further investigation
if it's actually ld.so problem.

But having the strong_aliases in forward.c is definitely wrong.

- Timo

diff --git a/libpthread/linuxthreads/cancel.c b/libpthread/linuxthreads/cancel.c
index 3435680..1412b57 100644
--- a/libpthread/linuxthreads/cancel.c
+++ b/libpthread/linuxthreads/cancel.c
@@ -152,8 +152,8 @@ void pthread_testcancel(void)
__pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
}

-void _pthread_cleanup_push(struct _pthread_cleanup_buffer * buffer,
-  void (*routine)(void *), void * arg)
+void __pthread_cleanup_push(struct _pthread_cleanup_buffer * buffer,
+   void (*routine)(void *), void * arg)
{
  pthread_descr self = thread_self();
  buffer-__routine = routine;
@@ -163,17 +163,19 @@ void _pthread_cleanup_push(struct _pthread_cleanup_buffer 
* buffer,
buffer-__prev = NULL;
  THREAD_SETMEM(self, p_cleanup, buffer);
}
+strong_alias(__pthread_cleanup_push, _pthread_cleanup_push);

-void _pthread_cleanup_pop(struct _pthread_cleanup_buffer * buffer,
- int execute)
+void __pthread_cleanup_pop(struct _pthread_cleanup_buffer * buffer,
+  int execute)
{
  pthread_descr self = thread_self();
  if (execute) buffer-__routine(buffer-__arg);
  THREAD_SETMEM(self, p_cleanup, buffer-__prev);
}
+strong_alias(__pthread_cleanup_pop, _pthread_cleanup_pop);

-void _pthread_cleanup_push_defer(struct _pthread_cleanup_buffer * buffer,
-void (*routine)(void *), void * arg)
+void __pthread_cleanup_push_defer(struct _pthread_cleanup_buffer * buffer,
+ void (*routine)(void *), void * arg)
{
  pthread_descr self = thread_self();
  buffer-__routine = routine;
@@ -185,9 +187,10 @@ void _pthread_cleanup_push_defer(struct 
_pthread_cleanup_buffer * buffer,
  THREAD_SETMEM(self, p_canceltype, PTHREAD_CANCEL_DEFERRED);
  THREAD_SETMEM(self, p_cleanup, buffer);
}
+strong_alias(__pthread_cleanup_push_defer, _pthread_cleanup_push_defer);

-void _pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer * buffer,
- int execute)
+void __pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer * buffer,
+  int execute)
{
  pthread_descr self = thread_self();
  if (execute) buffer-__routine(buffer-__arg);
@@ -198,6 +201,7 @@ void _pthread_cleanup_pop_restore(struct 
_pthread_cleanup_buffer * buffer,
  THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS)
__pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
}
+strong_alias(__pthread_cleanup_pop_restore, _pthread_cleanup_pop_restore);

extern void __rpc_thread_destroy(void);
void __pthread_perform_cleanup(char *currentframe)
diff --git a/libpthread/linuxthreads/forward.c 
b/libpthread/linuxthreads/forward.c
index f9f8ea1..385e79f 100644
--- a/libpthread/linuxthreads/forward.c
+++ b/libpthread/linuxthreads/forward.c
@@ -24,6 +24,10 @@
/* psm: keep this before internals.h */
/* libc_hidden_proto(exit) */

+#define hidden_strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name), \
+   visibility (hidden)));
+
#include internals.h

/* Pointers to the libc functions.  */
@@ -104,8 +108,7 @@ FORWARD (pthread_equal, (pthread_t thread1, pthread_t 
thread2),

/* Use an alias to avoid warning, as pthread_exit is declared noreturn.  */
FORWARD2 (__pthread_exit, void, (void *retval), (retval), exit (EXIT_SUCCESS))
-strong_alias (__pthread_exit, pthread_exit)
-
+hidden_strong_alias (__pthread_exit, pthread_exit)

FORWARD (pthread_getschedparam,
 (pthread_t target_thread, int *policy, struct sched_param *param),
@@ -120,16 +123,16 @@ FORWARD (pthread_mutex_destroy, (pthread_mutex_t *mutex), 
(mutex), 0)
FORWARD (pthread_mutex_init,
 (pthread_mutex_t *mutex, const 

[patch nptl] i386 support somewhat usable

2009-04-09 Thread Timo Teräs
Hi,

I took a quick stab at making i386 work on the nptl branch.

What is done:
1. i386 specific makefiles
2. uclibc headers providing the syscall wrappers were updated
3. updated some files from newer nptl snapshot
4. added ld.so support for tls relocations
5. tried to clean up some files for not defining duplicate symbols

What I'm not all sure about:
1. if e.g. clone.S update is correct; didn't see what where the
   original modifications for uclibc, just overwrote it with
   a new version
2. if libc is built properly with all the right objects from nptl

Basic stuff seems to work for me. A large portion of the nptl
test cases also run. But e.g. cancellations do not work.

Patch is at:
http://solidboot.com/~fabled/uclibc-nptl-i386.diff

And updates to test cases at:
http://solidboot.com/~fabled/uclibc-nptl-test.diff

Cheers,
  Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: NPTL on x86, anyone?

2009-04-09 Thread Timo Teräs
Mike Frysinger wrote:
 On Friday 10 April 2009 01:07:52 Timo Teräs wrote:
 Mike Frysinger wrote:
 On Thursday 09 April 2009 10:24:53 Cristi Magherusan wrote:
 Is there anyone interested in porting the NPTL branch to x86/x86-64?
 always interested in accepting patches, but no one appears to be
 interested in doing the porting work atm
 Did you all miss the mail I sent yesterday?

 http://lists.uclibc.org/pipermail/uclibc/2009-April/042289.html
 
 i saw it, but i generally skim over things that make me go to an external 
 location

The patch is about 70 kB. I find it good practice to send large
(as in over 40-50kB) patches as URLs instead of as attachment/inline.

But I can send it as attachment too if wanted.

I just noticed that some changes there are probably not right
based on the recent MIPS patch discussion.
E.g. pthread_cleanup_push_defer related things.

Also wondering if the NPTL version is planned for update? The
nptl branch is based on pretty old snapshot.

- Timo
___
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc


Re: [PATCH] splice, vmsplice and tee for i386

2008-04-22 Thread Timo Teräs
Peter Kjellerstedt wrote:
 I'll apply this patch in a few days unless i hear something
 controversial.
 
 Any particular reason to uncomment sync_file_range() in fcntl.h? 
 It does not seem to be part of the patch.
 
 Also, you might as well take the latest fcntl.h from glibc while at
 it to get a couple of missing defines (unrelated to splice).

Updated to latest fcntl.h with sync_file_range in #if 0. Also updated
to have errno = ENOSYS, return -1 wrappers if the syscall numbers
are not defined.

Cheers,
  Timo

Index: libc/sysdeps/linux/common/vmsplice.c
===
--- libc/sysdeps/linux/common/vmsplice.c	(revision 0)
+++ libc/sysdeps/linux/common/vmsplice.c	(revision 0)
@@ -0,0 +1,28 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * vmsplice() for uClibc
+ *
+ * Copyright (C) 2000-2006 Erik Andersen [EMAIL PROTECTED]
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include sys/syscall.h
+#include fcntl.h
+
+libc_hidden_proto(vmsplice)
+
+#ifdef __NR_vmsplice
+_syscall4(ssize_t, vmsplice, int, __fdout, const struct iovec *, __iov,
+	size_t, __count, unsigned int, __flags);
+#else
+ssize_t vmsplice(int __fdout, const struct iovec *__iov, size_t __count,
+	unsigned int __flags)
+{
+	__set_errno(ENOSYS);
+	return -1;
+}
+#endif
+
+libc_hidden_def(vmsplice)
+
Index: libc/sysdeps/linux/common/tee.c
===
--- libc/sysdeps/linux/common/tee.c	(revision 0)
+++ libc/sysdeps/linux/common/tee.c	(revision 0)
@@ -0,0 +1,28 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * tee() for uClibc
+ *
+ * Copyright (C) 2000-2006 Erik Andersen [EMAIL PROTECTED]
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include sys/syscall.h
+#include fcntl.h
+
+libc_hidden_proto(tee)
+
+#ifdef __NR_tee
+_syscall4(ssize_t, tee, int, __fdin, int, __fdout, size_t, __len,
+	unsigned int, __flags);
+#else
+ssize_t tee(int __fdin, int __fdout, size_t __len, unsigned int __flags)
+{
+	__set_errno(ENOSYS);
+	return -1;
+}
+#endif
+
+libc_hidden_def(tee)
+
+
Index: libc/sysdeps/linux/common/splice.c
===
--- libc/sysdeps/linux/common/splice.c	(revision 0)
+++ libc/sysdeps/linux/common/splice.c	(revision 0)
@@ -0,0 +1,28 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * splice() for uClibc
+ *
+ * Copyright (C) 2000-2006 Erik Andersen [EMAIL PROTECTED]
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include sys/syscall.h
+#include fcntl.h
+
+libc_hidden_proto(splice)
+
+#ifdef __NR_splice
+_syscall6(ssize_t, splice, int, __fdin, __off64_t *, __offin, int, __fdout,
+	__off64_t *, __offout, size_t, __len, unsigned int, __flags);
+#else
+ssize_t splice(int __fdin, __off64_t *__offin, int __fdout,
+	__off64_t *__offout, size_t __len, unsigned int __flags)
+{
+	__set_errno(ENOSYS);
+	return -1;
+}
+#endif
+
+libc_hidden_def(splice)
+
Index: libc/sysdeps/linux/i386/bits/fcntl.h
===
--- libc/sysdeps/linux/i386/bits/fcntl.h	(revision 21789)
+++ libc/sysdeps/linux/i386/bits/fcntl.h	(working copy)
@@ -1,5 +1,5 @@
 /* O_*, F_*, FD_* bit values for Linux.
-   Copyright (C) 1995, 1996, 1997, 1998, 2000, 2004, 2006
+   Copyright (C) 1995, 1996, 1997, 1998, 2000, 2004, 2006, 2007
Free Software Foundation, Inc.
This file is part of the GNU C Library.
 
@@ -50,6 +50,7 @@
 # define O_DIRECTORY	020	/* Must be a directory.	 */
 # define O_NOFOLLOW	040	/* Do not follow links.	 */
 # define O_NOATIME 0100 /* Do not set atime.  */
+# define O_CLOEXEC 0200 /* Set close_on_exec.  */
 #endif
 
 /* For now Linux has synchronisity options for data and read operations.
@@ -97,9 +98,11 @@
 # define F_SETLEASE	1024	/* Set a lease.	 */
 # define F_GETLEASE	1025	/* Enquire what lease is active.  */
 # define F_NOTIFY	1026	/* Request notfications on a directory.	 */
+# define F_DUPFD_CLOEXEC 1030	/* Duplicate file descriptor with
+   close-on-exit set.  */
 #endif
 
-/* For F_[GET|SET]FL.  */
+/* For F_[GET|SET]FD.  */
 #define FD_CLOEXEC	1	/* actually anything with low bit set goes */
 
 /* For posix fcntl() and `l_type' field of a `struct flock' for lockf().  */
@@ -185,6 +188,7 @@
 
 
 #ifdef __USE_GNU
+/* Flags for SYNC_FILE_RANGE.  */
 # define SYNC_FILE_RANGE_WAIT_BEFORE	1 /* Wait upon writeout of all pages
 	 in the range before performing the
 	 write.  */
@@ -194,6 +198,14 @@
 # define SYNC_FILE_RANGE_WAIT_AFTER	4 /* Wait upon writeout of all pages in
 	 the range after performing the
 	 write.  */
+
+/* Flags for SPLICE and VMSPLICE.  */
+# define SPLICE_F_MOVE		1	/* Move pages instead of copying.  */
+# define SPLICE_F_NONBLOCK	2	/* Don't block on the pipe splicing
+	   (but we may still block on the fd
+	   we splice from/to).  */
+# define SPLICE_F_MORE		4	/* Expect more 

[PATCH] splice, vmsplice and tee for i386

2008-04-21 Thread Timo Teräs
Hi,

splice et al for i386. Against svn trunk.

Cheers,
  Timo
Index: libc/sysdeps/linux/common/vmsplice.c
===
--- libc/sysdeps/linux/common/vmsplice.c	(revision 0)
+++ libc/sysdeps/linux/common/vmsplice.c	(revision 0)
@@ -0,0 +1,21 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * vmsplice() for uClibc
+ *
+ * Copyright (C) 2000-2006 Erik Andersen [EMAIL PROTECTED]
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include sys/syscall.h
+#include fcntl.h
+
+#ifdef __NR_vmsplice
+
+libc_hidden_proto(vmsplice)
+
+_syscall4(ssize_t, vmsplice, int, __fdout, const struct iovec *, __iov,
+	size_t, __count, unsigned int, __flags);
+libc_hidden_def(vmsplice)
+
+#endif
Index: libc/sysdeps/linux/common/tee.c
===
--- libc/sysdeps/linux/common/tee.c	(revision 0)
+++ libc/sysdeps/linux/common/tee.c	(revision 0)
@@ -0,0 +1,21 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * tee() for uClibc
+ *
+ * Copyright (C) 2000-2006 Erik Andersen [EMAIL PROTECTED]
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include sys/syscall.h
+#include fcntl.h
+
+#ifdef __NR_tee
+
+libc_hidden_proto(tee)
+
+_syscall4(ssize_t, tee, int, __fdin, int, __fdout, size_t, __len,
+	unsigned int, __flags);
+libc_hidden_def(tee)
+
+#endif
Index: libc/sysdeps/linux/common/splice.c
===
--- libc/sysdeps/linux/common/splice.c	(revision 0)
+++ libc/sysdeps/linux/common/splice.c	(revision 0)
@@ -0,0 +1,22 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * splice() for uClibc
+ *
+ * Copyright (C) 2000-2006 Erik Andersen [EMAIL PROTECTED]
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include sys/syscall.h
+#include fcntl.h
+
+#ifdef __NR_splice
+
+libc_hidden_proto(splice)
+
+_syscall6(ssize_t, splice, int, __fdin, __off64_t *, __offin, int, __fdout,
+	__off64_t *, __offout, size_t, __len, unsigned int, __flags);
+
+libc_hidden_def(splice)
+
+#endif
Index: libc/sysdeps/linux/i386/bits/fcntl.h
===
--- libc/sysdeps/linux/i386/bits/fcntl.h	(revision 21789)
+++ libc/sysdeps/linux/i386/bits/fcntl.h	(working copy)
@@ -194,6 +194,14 @@
 # define SYNC_FILE_RANGE_WAIT_AFTER	4 /* Wait upon writeout of all pages in
 	 the range after performing the
 	 write.  */
+
+/* Flags for SPLICE and VMSPLICE.  */
+# define SPLICE_F_MOVE		1	/* Move pages instead of copying.  */
+# define SPLICE_F_NONBLOCK	2	/* Don't block on the pipe splicing
+	   (but we may still block on the fd
+	   we splice from/to).  */
+# define SPLICE_F_MORE		4	/* Expect more data.  */
+# define SPLICE_F_GIFT		8	/* Pages passed in are a gift.  */
 #endif
 
 __BEGIN_DECLS
@@ -205,24 +213,25 @@
 __THROW;
 
 
-#if 0
 /* Selective file content synch'ing.  */
 extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
 			unsigned int __flags);
 
 
 /* Splice address range into a pipe.  */
-extern int vmsplice (int __fdout, const struct iovec *__iov, size_t __count,
-		 unsigned int __flags);
+extern ssize_t vmsplice (int __fdout, const struct iovec *__iov,
+			 size_t __count, unsigned int __flags);
 
 /* Splice two files together.  */
-extern int splice (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+extern ssize_t splice (int __fdin, __off64_t *__offin, int __fdout,
+		   __off64_t *__offout, size_t __len,
+		   unsigned int __flags)
 __THROW;
 
 /* In-kernel implementation of tee for pipe buffers.  */
-extern int tee (int __fdin, int __fdout, size_t __len, unsigned int __flags)
+extern ssize_t tee (int __fdin, int __fdout, size_t __len,
+		unsigned int __flags)
 __THROW;
-#endif
 
 #endif
 
___
uClibc mailing list
uClibc@uclibc.org
http://busybox.net/cgi-bin/mailman/listinfo/uclibc