__uc_malloc hooks
Mike Frysinger
vapier at gentoo.org
Sat Sep 15 19:03:40 UTC 2007
On Saturday 15 September 2007, Denys Vlasenko wrote:
> On Saturday 15 September 2007 09:19, Mike Frysinger wrote:
> > On Monday 30 July 2007, Denis Vlasenko wrote:
> >/* The following macros are used for PLT bypassing within libc.so
> > (and if needed other libraries similarly).
> > First of all, you need to have the function prototyped somewhere,
> > say in foo/foo.h:
> >
> > int foo (int __bar);
> >
> > If calls to foo within libc.so should always go to foo defined in
> > libc.so, then in include/foo.h you add:
> >
> > libc_hidden_proto (foo)
> >
> > line and after the foo function definition:
> >
> > int foo (int __bar)
> > {
> > return __bar;
> > }
> > libc_hidden_def (foo)
> >
> > or
> >
> > int foo (int __bar)
> > {
> > return __bar;
> > }
> > libc_hidden_weak (foo)
>
> I have several questions. first one:
>
> libc_hidden_def (foo) /* whan to use this?... */
> libc_hidden_weak (foo) /* ...and when this? */
it depends on how you want the global symbol defined ... historically, glibc
has had some exported symbols defined as weak (like the string symbols or the
malloc api) so that users can override those symbols. unless you know for
sure you want the exported symbol a weak one, use libc_hidden_def()
> Next. In actual uclibc code, usage is different. For example,
> libc_hidden_proto(mmap) and libc_hidden_def(mmap) are scattered in 16
> files. 15 of them .c files and remaining one is malloc.h. Why?
there should only be one libc_hidden_def(mmap) per build ... grepping ... yep,
that's the case
the abundance of libc_hidden_proto() in files is because we havent done what
glibc has (and we really should transition to) by creating local copies of
headers which simply contain libc_hidden_proto() decls so that individual
files dont need them.
think of libc_hidden_proto() as a function prototype and libc_hidden_def() as
the function definition ... the proto makes sure everyone who calls said
function uses the internal hidden version while the def creates that internal
hidden version. thus you should see libc_hidden_proto(mmap) in every file
that calls mmap() while you should see libc_hidden_proto(mmap) in every file
that defines mmap().
> Next. The names of thse macros are not decriptive. "libc_hidden_def(foo)".
> Hmmm. It must be a "hidden definition of foo"?
all the indirection is so that certain features can control minute behaviors
in visibility and across libraries (doing symbol hidding in libm or libc or
librt or ...). yes it can get pretty crazy, but it's to prevent duplication.
> What is __USER_LABEL_PREFIX__? It is never defined.
gcc defines it for some ports to the ABI prefix (most likely an underscore).
on pretty much every Linux arch out there, it'll be:
#define __USER_LABEL_PREFIX__
but on say Blackfin, it'll be:
#define __USER_LABEL_PREFIX__ _
since all C symbols in Blackfin have an underscore prefix
> So it is converted into
>
> extern __typeof (foo) __EI_foo __asm__(__USER_LABEL_PREFIX__"foo");
> extern __typeof (foo) __EI_foo __attribute__((alias ("__GI_foo")));
>
> Hrm, so __USER_LABEL_PREFIX__ will vanish? Why? Oh well...
>
> Ok, googling...
> So "__EI_foo" in C will be equivalent to "foo" in asm. Why is this needed?
this is the hidden direction alluded to at the begginning of the file to avoid
going through the PLT. libc_hidden_proto(mmap) pretty much expands into:
extern __typeof(mmap) mmap asm("__GI_mmap")
__attribute__((visibility("hidden")));
this tells anyone who wishes to call mmap() to use the hidden ELF symbol
__GI_mmap instead of the global ELF symbol mmap. at link time, all hidden
ELF relocs get processed and dropped while at run time, all global ELF relocs
get processed. we put a lot more overhead into the source code so that at
runtime, the overhead (speed/size) is significantly decreased.
now consider libc_hidden_proto(mmap) which expands to:
extern __typeof(mmap) __EI_mmap asm("mmap");
extern __typeof(mmap) __EI_mmap __attribute__((alias("__GI_mmap")));
this goes in the file where the mmap symbol is defined and creates the actual
binding between the global mmap ELF symbol and the hidden __GI_mmap ELF
symbol.
pretty simple eh ? :)
> Anyway I have a feeling that I am lost in the #define maze
> and the only thing which I understand is that
>
> libc_hidden_def(foo)
>
> is not a "hidden definition of foo", it's a "definition of hidden symbol
> _MAGIC_JUNK_foo which is aliased to foo", and
correct
> libc_hidden_proto(foo)
>
> is not a "hidden prototype of foo" but rather "please make all references
> to foo in this .c file refer to _MAGIC_JUNK_foo".
correct
> Which is utterly confusing.
not really ... you cant combine the symbols since they have conflicting
visibility, so you need to create a little bit of indirection
> Can I have macro names which do not lie to me?
>
> libc_define_internal_alias(foo)
> [or libc_define_internal_name(foo) or libc_define_internal(foo) or...]
> and
> libc_use_internal_alias(foo)
*shrug* we took it from glibc so changing the names would just put an annoying
support burden on us
> > more to the point ... how exactly would __uc_malloc be useful ? i dont
> > think ive ever seen malloc() return NULL as the kernel is the first to
> > find out about the OOM situation and properly nukes any userspace app
> > before it ever sees the relevant NULL ...
>
> malloc may fail because this particular process has memory limits set:
>
> softlimit -m 300000 passwd
>
> (softlimit is a busybox applet)
softlimit is just a cheesy interface to rlimits then ?
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: This is a digitally signed message part.
Url : http://lists.busybox.net/pipermail/uclibc/attachments/20070915/5e4374d3/attachment-0002.pgp
More information about the uClibc
mailing list