This is one of many potential static linking problems in uClibc. Last time, I 
reported a bug on sigaction and submitted a patch, but similar multiple 
definition error could happen to any function that was defined as GLOBAL in 
both libc.a and libpthread.a while certain runtime supporting function from 
libc, like abort(), also call it. 

For example, sigprocmask-test.c is a simple testing program and

$ gcc sigprocmask-test.c -o sigprocmask-test -static -lpthread

Since sigprocmask is GLOBAL in both libc.a and libpthread.a, sigprocmask called 
in main function will pull in pt-sigprocmask.os from libpthread.a, but later, 
another sigprocmask called in abort (part of libc) will pull in sigprocmask.os 
from libc.a and leads to multiple definition error.

To fix it, sigprocmask has to be defined as weak symbol. The same solution 
could be applied to other functions in libc/sysdeps/linux/common that will be 
called in both main and runtime supporting function in libc. I will identify 
them and post patch later.

Here is my patch to fix sigprocmask, and it was tested on gcc-4.5.2 based 
toolchain on MIPS.

>From 2e435b037624eff8c0daaa146d6feca57ce1eecf Mon Sep 17 00:00:00 2001
From: Jian Peng <[email protected]>
Date: Sat, 26 Mar 2011 23:44:52 -0700
Subject: [PATCH 1/1] common: fix sigprocmask static linking bug

simple sigprocmask testing program will fail to be compiled due to multiple 
definition of sigprocmask in libpthread.a and libc.a

mipsel-linux-gcc sigprocmask-test.c -o sigprocmask-test -static -lpthread

sigprocmask.c:(.text+0x0): multiple definition of `sigprocmask'

The solution is to define sigprocmask as weak symbol.

Signed-off-by: Jian Peng <[email protected]>
---
 libc/sysdeps/linux/common/sigprocmask.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libc/sysdeps/linux/common/sigprocmask.c 
b/libc/sysdeps/linux/common/sigprocmask.c
index 011d7b3..35fa6df 100644
--- a/libc/sysdeps/linux/common/sigprocmask.c
+++ b/libc/sysdeps/linux/common/sigprocmask.c
@@ -23,7 +23,7 @@ static __always_inline
 _syscall4(int, __rt_sigprocmask, int, how, const sigset_t *, set,
                  sigset_t *, oldset, size_t, size)

-int sigprocmask(int how, const sigset_t * set, sigset_t * oldset)
+int __attribute__((weak)) sigprocmask(int how, const sigset_t * set, sigset_t 
* oldset)
 {
 #ifdef SIGCANCEL
        sigset_t local_newmask;
@@ -58,7 +58,7 @@ static __always_inline
 _syscall3(int, __syscall_sigprocmask, int, how, const sigset_t *, set,
                  sigset_t *, oldset)

-int sigprocmask(int how, const sigset_t * set, sigset_t * oldset)
+int __attribute__((weak)) sigprocmask(int how, const sigset_t * set, sigset_t 
* oldset)
 {
 #ifdef SIGCANCEL
        sigset_t local_newmask;
--
1.7.4.1


_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to