Question on internal functions.

Peter S. Mazinger ps.m at gmx.net
Thu Mar 9 21:58:32 UTC 2006


On Thu, 9 Mar 2006 sjhill at realitydiluted.com wrote:

> Peter,
> 
> I am still missing some understanding on these libc_hidden_ macros. I
> think I am seeing some problem with regards to NPTL. The situation is
> that for a lot of functions like:
> 
>    open, close, write, waitpid, read, fcntl, fstat, lseek, llseek
> 
> and about 20 others, they have a version both in libc and libpthread.
> They are asynchronous cancellation points, so if open is being called
> by an application where only the C library is linked against, the
> functions '__libc_[enable|disable]_asynchronous' are called. If the
> application is linked against libpthread, then '__libpthread_XXX'
> functions have to be called instead. What I am seeing is that for test
> applications linked against libpthread, the C version functions for
> open, close, etc. are being called and not the libpthread ones. I
> should note that the with the exception of waitpid and fcntl above,
> all of those functions are autogenerated assembly code files. Do you
> have any ideas what may be going on?
> 
> -Steve

Well, I have asked many things on ml regarding cancellation/weak versus 
strong alias and the like, even provided some sort of mini-doc how glibc 
does it, but haven't gotten any sort of answer/opinion (it would be good 
if you would read that too, although maybe outdated slightly).

So I "decided" that it works as follows:

a. we have __libc_x in libc.so as not cancellable, and use internally  
this if we are sure that it has to be not cancellable 
(libc/misc/internals/__uClibc_main.c and some other makes use of it)
b. we create weak_alias(__libc_x,x) in libc.
c. if we have a jump relocation due to __libc_x, we do 
hidden_proto(__libc_x)/hidden_def(__libc_x) and add to each .c file where 
__libc_x is used hidden_proto(__libc_x) after header/prototype of __libc_x
d. we do the same for internally used x
	c. and d. create the hidden functions prefixed w/ __GI_
e. if we have an own (cancellable) version of x() in libpthread, then 
define __x in libpthread and do strong_alias(__x,x)
f. if you want to use within libpthread x but it produces within 
libpthread jump relocation, then do c./d. (using libpthread_hidden_proto/def)
g. if you need to use a non-cancellable version of x within libpthread, 
use __libc_x (is exported by libc.so)
h. if you have the same file in libc and libpthread and you need hidden 
versions only in one of them you use libc_hidden_* resp. 
libpthread_hidden_*, if you want hidden counterparts in both, use 
unprefixed hidden_proto/def(x)

Due to changes how the cancellation is done in nptl compared to 
linuxthreads, my idea is to do:

Create only 1 version of x() that does:
x() {
	handle_start();
	real_x();
	handle_stop();
}

where handle_* can change error code, cancel, whatever (maybe some 
internal hooks that can be used within real_x are also good to have).

if libc is on it's own handle_*() are noop, else it does what nptl 
expects. Maybe it needs also specifics for 1 thread/more threads case, 
don't know.

Your problem is probably the generated assembler code (I have looked at it 
and you can make only use of it in uClibc, if you import all those arch  
specific header files into uClibc, I can't say I am fond of it due to the 
"recursive" definitions, to find anything you have to dig through many 
headers that redefine and redefine ...)

I know that Erik wanted to generate the syscalls automagically ...

Peter

-- 
Peter S. Mazinger <ps dot m at gmx dot net>           ID: 0xA5F059F2
Key fingerprint = 92A4 31E1 56BC 3D5A 2D08  BB6E C389 975E A5F0 59F2




More information about the uClibc mailing list